Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adds Variant prop that reflects chackra-ui variants #167

Merged
merged 4 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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