Skip to content

Commit f9e87a0

Browse files
authored
feat: Change selectedOptionColorPalette values pulled from the theme (#364)
* Change selectedOptionColorPalette selected values * Add consistent-type-imports eslint rule
1 parent 9dc874b commit f9e87a0

14 files changed

+106
-57
lines changed
36.1 KB
Loading
38.7 KB
Loading

README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,13 @@ If you choose to stick with the default `selectedOptionStyle="color"`, you have
344344
one additional styling option. If you do not like the default of blue for the
345345
highlight color, you can pass the `selectedOptionColorPalette` prop to change
346346
it. This prop will accept any named color from your theme's color palette, and
347-
it will use the `500` value in light mode or the `300` value in dark mode.
347+
it will use `colorPalette.solid` for the background, and `colorPalette.contrast`
348+
for the text.
349+
350+
If you'd like to use a custom color palette for this prop, ensure that you have
351+
properly set up the custom color, including the `solid` and `contrast` semantic
352+
tokens, accoring to
353+
[the official guide](https://www.chakra-ui.com/guides/theming-custom-colors).
348354

349355
> [!NOTE]
350356
>

demo/eslint.config.js

+7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ const eslintConfig = tseslint.config(
2525
...react.configs.recommended.rules,
2626
...react.configs["jsx-runtime"].rules,
2727
...reactHooks.configs.recommended.rules,
28+
"@typescript-eslint/consistent-type-imports": [
29+
"warn",
30+
{
31+
prefer: "type-imports",
32+
disallowTypeAnnotations: true,
33+
},
34+
],
2835
"react/prop-types": "off",
2936
"react-refresh/only-export-components": [
3037
"warn",

demo/src/app.tsx

+14-3
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ import {
1010
Stack,
1111
Text,
1212
} from "@chakra-ui/react";
13+
import type { GroupBase, LoadingIndicatorProps } from "chakra-react-select";
1314
import {
1415
AsyncSelect,
1516
CreatableSelect,
16-
GroupBase,
17-
LoadingIndicatorProps,
1817
Select,
1918
chakraComponents,
2019
} from "chakra-react-select";
2120
import ConnectedSelectMenuExample from "./components/advanced-examples/connected-select-menu-example";
2221
import CustomIndicatorIconsExample from "./components/advanced-examples/custom-indicator-icons-example";
22+
import DynamicSelectedOptionColorExample from "./components/advanced-examples/dynamic-selected-option-color-example";
2323
import MenuPortalTargetExample from "./components/advanced-examples/menu-portal-target-example";
2424
import OptionsWithIconsExample from "./components/advanced-examples/options-with-icons-example";
2525
import SelectPopoverExample from "./components/advanced-examples/select-popover-example";
@@ -35,7 +35,8 @@ import {
3535
SelectValueText,
3636
} from "./components/ui/select";
3737
import animeMovies from "./data/anime-movies";
38-
import { ColorOption, colorOptions, groupedOptions } from "./data/options";
38+
import type { ColorOption } from "./data/options";
39+
import { colorOptions, groupedOptions } from "./data/options";
3940

4041
const mappedColorOptions = colorOptions.map((option) => ({
4142
...option,
@@ -354,6 +355,16 @@ const App = () => {
354355
/>
355356
</Field>
356357

358+
<Field
359+
label={
360+
<Span>
361+
Single Select with dynamic <Code>selectedOptionColorPalette</Code>
362+
</Span>
363+
}
364+
>
365+
<DynamicSelectedOptionColorExample />
366+
</Field>
367+
357368
<Field
358369
label={
359370
<Span>

demo/src/components/advanced-examples/custom-indicator-icons-example.tsx

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
import {
2-
GroupBase,
3-
Select,
4-
SelectComponentsConfig,
5-
chakraComponents,
6-
} from "chakra-react-select";
1+
import type { GroupBase, SelectComponentsConfig } from "chakra-react-select";
2+
import { Select, chakraComponents } from "chakra-react-select";
73
import { LuArrowDown, LuCircleX } from "react-icons/lu";
84
import { groupedOptions } from "../../data/options";
95

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useState } from "react";
2+
import { Select } from "chakra-react-select";
3+
import type { ColorOption } from "../../data/options";
4+
import { colorOptions } from "../../data/options";
5+
6+
const DynamicSelectedOptionColorExample = () => {
7+
const [selectedOptionColorPalette, setSelectedOptionColorPalette] =
8+
useState<ColorOption | null>(colorOptions[0]);
9+
10+
return (
11+
<Select
12+
name="colors"
13+
options={colorOptions}
14+
placeholder="Select a color..."
15+
closeMenuOnSelect={false}
16+
value={selectedOptionColorPalette}
17+
onChange={setSelectedOptionColorPalette}
18+
selectedOptionColorPalette={selectedOptionColorPalette?.value}
19+
/>
20+
);
21+
};
22+
23+
export default DynamicSelectedOptionColorExample;

demo/src/components/advanced-examples/menu-portal-target-example.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useState } from "react";
22
import { Stack } from "@chakra-ui/react";
3-
import { Select, Props as SelectProps } from "chakra-react-select";
3+
import type { Props as SelectProps } from "chakra-react-select";
4+
import { Select } from "chakra-react-select";
45
import { colorOptions } from "../../data/options";
56
import { Button } from "../ui/button";
67
import {

demo/src/components/advanced-examples/select-popover-example.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { useRef, useState } from "react";
22
import { Icon } from "@chakra-ui/react";
3-
import {
3+
import type {
44
ChakraStylesConfig,
5-
Select,
65
SelectInstance,
76
SingleValue,
87
} from "chakra-react-select";
8+
import { Select } from "chakra-react-select";
99
import { LuChevronDown, LuSearch } from "react-icons/lu";
10-
import { StateOption, stateOptions } from "../../data/options";
10+
import type { StateOption } from "../../data/options";
11+
import { stateOptions } from "../../data/options";
1112
import { Button } from "../ui/button";
1213
import {
1314
PopoverBody,

demo/src/data/countries.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { GroupBase, OptionBase } from "chakra-react-select";
1+
import type { GroupBase, OptionBase } from "chakra-react-select";
22

33
export interface CountryOption extends OptionBase {
44
label: string;

demo/src/data/options.ts

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
import { OptionBase } from "chakra-react-select";
1+
import type { ColorPalette } from "@chakra-ui/react";
2+
import type { OptionBase } from "chakra-react-select";
23

34
export interface ColorOption extends OptionBase {
45
label: string;
5-
value: string;
6-
color: string;
6+
value: ColorPalette;
77
}
88

99
export const colorOptions: ColorOption[] = [
10-
{ value: "blue", label: "Blue", color: "#0052CC" },
11-
{ value: "purple", label: "Purple", color: "#5243AA" },
12-
{ value: "red", label: "Red", color: "#FF5630" },
13-
{ value: "orange", label: "Orange", color: "#FF8B00" },
14-
{ value: "yellow", label: "Yellow", color: "#FFC400" },
15-
{ value: "green", label: "Green", color: "#36B37E" },
10+
{ value: "gray", label: "Gray" },
11+
{ value: "red", label: "Red" },
12+
{ value: "pink", label: "Pink" },
13+
{ value: "purple", label: "Purple" },
14+
{ value: "cyan", label: "Cyan" },
15+
{ value: "blue", label: "Blue" },
16+
{ value: "teal", label: "Teal" },
17+
{ value: "green", label: "Green" },
18+
{ value: "yellow", label: "Yellow" },
19+
{ value: "orange", label: "Orange" },
20+
{ value: "brand", label: "Brand" },
1621
];
1722

1823
export interface FlavorOption extends OptionBase {

demo/src/theme/index.ts

+27
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,33 @@ const config = defineConfig({
4646
button: { value: "pointer" },
4747
option: { value: "pointer" },
4848
},
49+
colors: {
50+
brand: {
51+
50: { value: "#f3f8fd" },
52+
100: { value: "#d1e2f8" },
53+
200: { value: "#a9c8f2" },
54+
300: { value: "#77a8eb" },
55+
400: { value: "#5a96e7" },
56+
500: { value: "#327ce1" },
57+
600: { value: "#0b63dc" },
58+
700: { value: "#004eb9" },
59+
800: { value: "#00429d" },
60+
900: { value: "#003072" },
61+
},
62+
},
63+
},
64+
semanticTokens: {
65+
colors: {
66+
brand: {
67+
solid: { value: "{colors.brand.500}" },
68+
contrast: { value: "white" },
69+
fg: { value: "{colors.brand.700}" },
70+
muted: { value: "{colors.brand.100}" },
71+
subtle: { value: "{colors.brand.200}" },
72+
emphasized: { value: "{colors.brand.300}" },
73+
focusRing: { value: "{colors.brand.500}" },
74+
},
75+
},
4976
},
5077
},
5178
});

src/chakra-components/menu.tsx

+5-15
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type {
1010
OptionProps,
1111
} from "react-select";
1212
import type { SizeProps } from "../types";
13-
import { cleanCommonProps, useColorModeValue, useSize } from "../utils";
13+
import { cleanCommonProps, useSize } from "../utils";
1414
import { CheckIcon } from "./icons";
1515

1616
export const Menu = <
@@ -314,17 +314,6 @@ export const Option = <
314314

315315
const selectStyles = useSlotRecipe({ key: "select" })({ size, variant });
316316

317-
/**
318-
* Use the same selected color as the border/shadow of the select/input components
319-
*
320-
* @see {@link https://github.com/chakra-ui/chakra-ui/blob/61f965a/packages/components/theme/src/components/input.ts#L92-L93}
321-
*/
322-
const selectedBg = useColorModeValue(
323-
`${selectedOptionColorPalette}.500`,
324-
`${selectedOptionColorPalette}.300`
325-
);
326-
const selectedColor = useColorModeValue("white", "black");
327-
328317
// Don't create exta space for the checkmark if using a multi select with
329318
// options that dissapear when they're selected
330319
const showCheckIcon =
@@ -337,9 +326,9 @@ export const Option = <
337326
...selectStyles.item,
338327
...(shouldHighlight
339328
? {
340-
bg: selectedBg,
341-
color: selectedColor,
342-
_active: { bg: selectedBg },
329+
color: "colorPalette.contrast",
330+
bg: "colorPalette.solid",
331+
_active: { bg: "colorPalette.solid" },
343332
}
344333
: {}),
345334
};
@@ -351,6 +340,7 @@ export const Option = <
351340
return (
352341
<Box
353342
{...innerProps}
343+
colorPalette={selectedOptionColorPalette}
354344
className={cx(
355345
{
356346
option: true,

src/utils.ts

-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useBreakpointValue, useChakraContext } from "@chakra-ui/react";
2-
import { useTheme } from "next-themes";
32
import type { CommonPropsAndClassName, GroupBase } from "react-select";
43
import type { Size, SizeProp } from "./types";
54

@@ -80,20 +79,3 @@ export const useSize = (size: SizeProp | undefined): Size => {
8079

8180
return useBreakpointValue(responsiveSize) ?? defaultSize;
8281
};
83-
84-
export function useColorMode() {
85-
const { resolvedTheme, setTheme } = useTheme();
86-
const toggleColorMode = () => {
87-
setTheme(resolvedTheme === "light" ? "dark" : "light");
88-
};
89-
return {
90-
colorMode: resolvedTheme,
91-
setColorMode: setTheme,
92-
toggleColorMode,
93-
};
94-
}
95-
96-
export function useColorModeValue<T>(light: T, dark: T) {
97-
const { colorMode } = useColorMode();
98-
return colorMode === "light" ? light : dark;
99-
}

0 commit comments

Comments
 (0)