Skip to content

Commit 9f90db5

Browse files
authored
Merge pull request #167 from picninim/main
feat: Adds Variant prop that reflects chackra-ui variants
2 parents cba2df5 + 5738fa9 commit 9f90db5

File tree

10 files changed

+72
-11
lines changed

10 files changed

+72
-11
lines changed

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Check out these demos:
4040
- [`useBasicStyles`](#usebasicstyles--default-false)
4141
- [`selectedOptionStyle`](#selectedoptionstyle--options-color--check--default-color)
4242
- [`selectedOptionColor`](#selectedoptioncolor--default-blue)
43+
- [`variant`](#variant--options-outline--filled--flushed--unstyled--default-outline)
4344
- [`hasStickyGroupHeaders`](#hasstickygroupheaders--default-false)
4445
- [`isFixed`](#isfixed)
4546
- [Styling](#styling)
@@ -270,6 +271,35 @@ return (
270271

271272
[![CS-JS]](https://codesandbox.io/s/chakra-react-select-border-selectedoptioncolor-yyd321?file=/example.js)
272273

274+
#### `variant` — Options: `outline` | `filled` | `flushed` | `unstyled` — Default: `outline`
275+
276+
You can pass the `variant` prop with any of `outline`, `filled`, `flushed`, or `unstyled` to change the overall styling of the `Select`. These will reflect the various appearances available for [Chakra's `<Input />` component](https://chakra-ui.com/docs/components/input#changing-the-size-of-the-input).
277+
278+
```js
279+
return (
280+
<>
281+
<Select variant="outline" /> {/* Default */}
282+
<Select variant="filled" />
283+
<Select variant="flushed" />
284+
<Select variant="unstyled" />
285+
</>
286+
);
287+
```
288+
289+
![variant in light mode](./github/variant-light.png)
290+
291+
![variant in dark mode](./github/variant-dark.png)
292+
293+
By default, the `flushed` and `unstyled` variants look a bit strange in combination with the `DropdownIndicator`. An easy way to make these styles look more natural is to pass the [`useBasicStyles`](#usebasicstyles--default-false) prop along with them to remove the background from the indicator. Or alternatively, you could hide the indicator completely using [`chakraStyles`](#chakrastyles).
294+
295+
![variant with useBasicStyles](./github/variant-use-basic-styles.png)
296+
297+
Another thing to note is that the default styling for `variant="filled"` and `isMulti` results in the select and selected option tags having the same background color when the select is not focused. The easiest solution for this is to pass the [`tagVariant`](#tagvariant--options-subtle--solid--outline--default-subtle) or [`colorScheme`](#colorscheme) prop to add some contrast between the two elements.
298+
299+
![variant with useBasicStyles](./github/filled-variant.png)
300+
301+
[![CS-JS]](https://codesandbox.io/s/chakra-react-select-variant-5cf755?file=/example.js)
302+
273303
#### `hasStickyGroupHeaders` — Default: `false`
274304

275305
One additional feature which isn’t specific to Chakra or react-select is sticky group headers. It adds a border to the bottom of the header and keeps it in view while its corresponding group of options is visible. This can be very nice for when you have long lists of grouped options so you can always tell which group of options you're looking at. To add it, pass the `hasStickyGroupHeaders` prop to the select component.

github/filled-variant.png

128 KB
Loading

github/variant-dark.png

128 KB
Loading

github/variant-light.png

57 KB
Loading
85.8 KB
Loading

src/chakra-components/containers.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React from "react";
22
import { Box } from "@chakra-ui/layout";
33
import type { CSSObject } from "@chakra-ui/system";
4+
import { useMultiStyleConfig } from "@chakra-ui/system";
45
import type {
56
ContainerProps,
67
GroupBase,
78
IndicatorsContainerProps,
89
ValueContainerProps,
910
} from "react-select";
10-
import type { SizeProps } from "../types";
1111

1212
export const SelectContainer = <
1313
Option,
@@ -69,20 +69,22 @@ export const ValueContainer = <
6969
isMulti,
7070
hasValue,
7171
innerProps,
72-
selectProps: { size, chakraStyles },
72+
selectProps: { size, chakraStyles, variant },
7373
} = props;
7474

75-
const px: SizeProps = {
76-
sm: "0.75rem",
77-
md: "1rem",
78-
lg: "1rem",
79-
};
75+
// Getting the css from input instead of select
76+
// to fit better with each of the variants
77+
const inputStyles = useMultiStyleConfig("Input", {
78+
size,
79+
variant,
80+
});
8081

8182
const initialSx: CSSObject = {
8283
display: "flex",
8384
alignItems: "center",
8485
flex: 1,
85-
padding: `0.125rem ${px[size || "md"]}`,
86+
paddingY: "2px",
87+
paddingX: inputStyles.field.px,
8688
flexWrap: "wrap",
8789
WebkitOverflowScrolling: "touch",
8890
position: "relative",

src/chakra-components/control.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,15 @@ const Control = <
3737
chakraStyles,
3838
focusBorderColor,
3939
errorBorderColor,
40+
variant,
4041
},
4142
} = props;
4243

4344
const inputStyles = useMultiStyleConfig("Input", {
4445
focusBorderColor,
4546
errorBorderColor,
4647
size,
48+
variant,
4749
});
4850

4951
const heights: SizeProps = {
@@ -100,12 +102,12 @@ export const IndicatorSeparator = <
100102
const {
101103
className,
102104
cx,
103-
selectProps: { chakraStyles, useBasicStyles },
105+
selectProps: { chakraStyles, useBasicStyles, variant },
104106
} = props;
105107

106108
const initialSx: CSSObject = {
107109
opacity: 1,
108-
...(useBasicStyles && { display: "none" }),
110+
...(useBasicStyles || variant !== "outline" ? { display: "none" } : {}),
109111
};
110112

111113
const sx = chakraStyles?.indicatorSeparator

src/module-augmentation.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
SelectedOptionStyle,
77
Size,
88
TagVariant,
9+
Variant,
910
} from "./types";
1011

1112
/**
@@ -157,6 +158,17 @@ declare module "react-select/dist/declarations/src/Select" {
157158
* @see {@link https://chakra-ui.com/docs/components/select}
158159
*/
159160
useBasicStyles?: boolean;
161+
162+
/**
163+
* The main style variant of the `Select` component
164+
*
165+
* Options: `outline` | `filled` | `flushed` | `unstyled`
166+
*
167+
* @defaultValue `outline`
168+
* @see {@link https://chakra-ui.com/docs/components/select#changing-the-appearance}
169+
* @see {@link https://github.com/csandman/chakra-react-select#variant--options-outline--filled--flushed--unstyled--default-outline}
170+
*/
171+
variant?: Variant;
160172
}
161173
}
162174

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export type TagVariant = "subtle" | "solid" | "outline";
4444

4545
export type SelectedOptionStyle = "color" | "check";
4646

47+
export type Variant = "outline" | "filled" | "flushed" | "unstyled";
48+
4749
export type StylesFunction<ComponentProps> = (
4850
provided: CSSObject,
4951
state: ComponentProps

src/use-chakra-select-props.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useFormControl } from "@chakra-ui/form-control";
22
import type { GroupBase, Props } from "react-select";
33
import chakraComponents from "./chakra-components";
4-
import type { SelectedOptionStyle, Size, TagVariant } from "./types";
4+
import type { SelectedOptionStyle, Size, TagVariant, Variant } from "./types";
55

66
const useChakraSelectProps = <
77
Option,
@@ -21,6 +21,7 @@ const useChakraSelectProps = <
2121
hasStickyGroupHeaders = false,
2222
selectedOptionStyle = "color",
2323
selectedOptionColor = "blue",
24+
variant = "outline",
2425
focusBorderColor,
2526
errorBorderColor,
2627
chakraStyles = {},
@@ -75,6 +76,17 @@ const useChakraSelectProps = <
7576
realSelectedOptionColor = "blue";
7677
}
7778

79+
let realVariant: Variant = variant;
80+
const variantOptions: Variant[] = [
81+
"outline",
82+
"filled",
83+
"flushed",
84+
"unstyled",
85+
];
86+
if (!variantOptions.includes(variant)) {
87+
realVariant = "outline";
88+
}
89+
7890
const select: Props<Option, IsMulti, Group> = {
7991
// Allow overriding of custom components
8092
components: {
@@ -87,6 +99,7 @@ const useChakraSelectProps = <
8799
tagVariant: realTagVariant,
88100
selectedOptionStyle: realSelectedOptionStyle,
89101
selectedOptionColor: realSelectedOptionColor,
102+
variant: realVariant,
90103
hasStickyGroupHeaders,
91104
chakraStyles,
92105
focusBorderColor,

0 commit comments

Comments
 (0)