Skip to content

Commit

Permalink
Merge pull request #167 from picninim/main
Browse files Browse the repository at this point in the history
feat: Adds Variant prop that reflects chackra-ui variants
  • Loading branch information
csandman authored Sep 1, 2022
2 parents cba2df5 + 5738fa9 commit 9f90db5
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 11 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Check out these demos:
- [`useBasicStyles`](#usebasicstyles--default-false)
- [`selectedOptionStyle`](#selectedoptionstyle--options-color--check--default-color)
- [`selectedOptionColor`](#selectedoptioncolor--default-blue)
- [`variant`](#variant--options-outline--filled--flushed--unstyled--default-outline)
- [`hasStickyGroupHeaders`](#hasstickygroupheaders--default-false)
- [`isFixed`](#isfixed)
- [Styling](#styling)
Expand Down Expand Up @@ -270,6 +271,35 @@ return (

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

#### `variant` — Options: `outline` | `filled` | `flushed` | `unstyled` — Default: `outline`

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).

```js
return (
<>
<Select variant="outline" /> {/* Default */}
<Select variant="filled" />
<Select variant="flushed" />
<Select variant="unstyled" />
</>
);
```

![variant in light mode](./github/variant-light.png)

![variant in dark mode](./github/variant-dark.png)

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).

![variant with useBasicStyles](./github/variant-use-basic-styles.png)

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.

![variant with useBasicStyles](./github/filled-variant.png)

[![CS-JS]](https://codesandbox.io/s/chakra-react-select-variant-5cf755?file=/example.js)

#### `hasStickyGroupHeaders` — Default: `false`

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.
Expand Down
Binary file added github/filled-variant.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added github/variant-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added github/variant-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added github/variant-use-basic-styles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 10 additions & 8 deletions src/chakra-components/containers.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";
import { Box } from "@chakra-ui/layout";
import type { CSSObject } from "@chakra-ui/system";
import { useMultiStyleConfig } from "@chakra-ui/system";
import type {
ContainerProps,
GroupBase,
IndicatorsContainerProps,
ValueContainerProps,
} from "react-select";
import type { SizeProps } from "../types";

export const SelectContainer = <
Option,
Expand Down Expand Up @@ -69,20 +69,22 @@ export const ValueContainer = <
isMulti,
hasValue,
innerProps,
selectProps: { size, chakraStyles },
selectProps: { size, chakraStyles, variant },
} = props;

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

const initialSx: CSSObject = {
display: "flex",
alignItems: "center",
flex: 1,
padding: `0.125rem ${px[size || "md"]}`,
paddingY: "2px",
paddingX: inputStyles.field.px,
flexWrap: "wrap",
WebkitOverflowScrolling: "touch",
position: "relative",
Expand Down
6 changes: 4 additions & 2 deletions src/chakra-components/control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ const Control = <
chakraStyles,
focusBorderColor,
errorBorderColor,
variant,
},
} = props;

const inputStyles = useMultiStyleConfig("Input", {
focusBorderColor,
errorBorderColor,
size,
variant,
});

const heights: SizeProps = {
Expand Down Expand Up @@ -100,12 +102,12 @@ export const IndicatorSeparator = <
const {
className,
cx,
selectProps: { chakraStyles, useBasicStyles },
selectProps: { chakraStyles, useBasicStyles, variant },
} = props;

const initialSx: CSSObject = {
opacity: 1,
...(useBasicStyles && { display: "none" }),
...(useBasicStyles || variant !== "outline" ? { display: "none" } : {}),
};

const sx = chakraStyles?.indicatorSeparator
Expand Down
12 changes: 12 additions & 0 deletions src/module-augmentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
SelectedOptionStyle,
Size,
TagVariant,
Variant,
} from "./types";

/**
Expand Down Expand Up @@ -157,6 +158,17 @@ declare module "react-select/dist/declarations/src/Select" {
* @see {@link https://chakra-ui.com/docs/components/select}
*/
useBasicStyles?: boolean;

/**
* The main style variant of the `Select` component
*
* Options: `outline` | `filled` | `flushed` | `unstyled`
*
* @defaultValue `outline`
* @see {@link https://chakra-ui.com/docs/components/select#changing-the-appearance}
* @see {@link https://github.com/csandman/chakra-react-select#variant--options-outline--filled--flushed--unstyled--default-outline}
*/
variant?: Variant;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export type TagVariant = "subtle" | "solid" | "outline";

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

export type Variant = "outline" | "filled" | "flushed" | "unstyled";

export type StylesFunction<ComponentProps> = (
provided: CSSObject,
state: ComponentProps
Expand Down
15 changes: 14 additions & 1 deletion src/use-chakra-select-props.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useFormControl } from "@chakra-ui/form-control";
import type { GroupBase, Props } from "react-select";
import chakraComponents from "./chakra-components";
import type { SelectedOptionStyle, Size, TagVariant } from "./types";
import type { SelectedOptionStyle, Size, TagVariant, Variant } from "./types";

const useChakraSelectProps = <
Option,
Expand All @@ -21,6 +21,7 @@ const useChakraSelectProps = <
hasStickyGroupHeaders = false,
selectedOptionStyle = "color",
selectedOptionColor = "blue",
variant = "outline",
focusBorderColor,
errorBorderColor,
chakraStyles = {},
Expand Down Expand Up @@ -75,6 +76,17 @@ const useChakraSelectProps = <
realSelectedOptionColor = "blue";
}

let realVariant: Variant = variant;
const variantOptions: Variant[] = [
"outline",
"filled",
"flushed",
"unstyled",
];
if (!variantOptions.includes(variant)) {
realVariant = "outline";
}

const select: Props<Option, IsMulti, Group> = {
// Allow overriding of custom components
components: {
Expand All @@ -87,6 +99,7 @@ const useChakraSelectProps = <
tagVariant: realTagVariant,
selectedOptionStyle: realSelectedOptionStyle,
selectedOptionColor: realSelectedOptionColor,
variant: realVariant,
hasStickyGroupHeaders,
chakraStyles,
focusBorderColor,
Expand Down

0 comments on commit 9f90db5

Please sign in to comment.