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

Fix: Prevent a selected option from being removed when isDisabled is passed #169

Merged
merged 4 commits into from
Aug 31, 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
80 changes: 52 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ Check out these demos:

- [Usage](#usage)
- [Extra Props](#extra-props)
- [`size`](#size--options-sm-md-lg--default-md)
- [`size`](#size--options-sm--md--lg--default-md)
- [`colorScheme`](#colorscheme)
- [`tagVariant`](#tagvariant--options-subtle-solid-outline--default-subtle)
- [`tagVariant`](#tagvariant--options-subtle--solid--outline--default-subtle)
- [`isInvalid`](#isinvalid--default-false)
- [`focusBorderColor` / `errorBorderColor`](#focusbordercolor--default-blue500--errorbordercolor--default-red500)
- [`useBasicStyles`](#usebasicstyles--default-false)
- [`hasStickyGroupHeaders`](#hasstickygroupheaders--default-false)
- [`selectedOptionStyle`](#selectedoptionstyle--options-color-check--default-color)
- [`selectedOptionStyle`](#selectedoptionstyle--options-color--check--default-color)
- [`selectedOptionColor`](#selectedoptioncolor--default-blue)
- [`hasStickyGroupHeaders`](#hasstickygroupheaders--default-false)
- [`isFixed`](#isfixed)
- [Styling](#styling)
- [`chakraStyles`](#chakrastyles)
Expand Down Expand Up @@ -95,13 +95,13 @@ const {
} = require("chakra-react-select");
```

All of the types and other exports from the original `react-select` package are also exported from this package, so you can import any of them if you need them.
All of exports, including types, from the original `react-select` package are also exported from this package, so you can import any of them if you need them. The only exception is the root `Select` components.

In order to use this component, you can implement it and use it like you would normally use [react-select](https://react-select.com/home). It should accept almost all of the props that the original takes, with a few additions and exceptions listed below.
Implementing this component in your application should be almost identical to how you'd normally use [react-select](https://react-select.com/home). It will accept all of the props that the original package does, with a few additions and exceptions listed below. So if you have a question on basic usage, your best bet is to check the original docs or google "How to (some functionality) with react-select" and just swap out `react-select` for `chakra-react-select`.

## Extra Props

#### `size` — Options: `sm`, `md`, `lg` — Default: `md`
#### `size` — Options: `sm` | `md` | `lg` — Default: `md`

You can pass the `size` prop with either `sm`, `md`, or `lg` (default is `md`). These will reflect the sizes available on the [Chakra `<Input />` component](https://chakra-ui.com/docs/components/input#changing-the-size-of-the-input) (with the exception of `xs` because it's too small to work).

Expand All @@ -115,6 +115,8 @@ return (
);
```

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

#### `colorScheme`

You can pass the `colorScheme` prop to the select component to change all of the selected options tags' colors. You can view the whole list of available color schemes in [the Chakra docs](https://chakra-ui.com/docs/components/tag/props), or if you have a custom color palette, any of the custom color names in that will be available instead.
Expand All @@ -141,7 +143,9 @@ return (
);
```

#### `tagVariant` — Options: `subtle`, `solid`, `outline` — Default: `subtle`
[![CS-JS]](https://codesandbox.io/s/chakra-react-select-color-schemes-c38jlo?file=/example.js)

#### `tagVariant` — Options: `subtle` | `solid` | `outline` — Default: `subtle`

You can pass the `tagVariant` prop with either `subtle`, `solid`, or `outline` (default is `subtle`). These will reflect the `variant` prop available on the [Chakra `<Tag />` component](https://chakra-ui.com/docs/components/tag/props).

Expand All @@ -167,6 +171,8 @@ return (
);
```

[![CS-JS]](https://codesandbox.io/s/chakra-react-select-tag-variants-w31gnt?file=/example.js)

#### `isInvalid` — Default: `false`

You can pass `isInvalid` to the select component to style it like the Chakra `<Input />` is styled when it receives the same prop.
Expand All @@ -191,21 +197,25 @@ return (
);
```

[![CS-JS]](https://codesandbox.io/s/chakra-react-select-invalid-disabled-0hyl8l?file=/example.js)

#### `focusBorderColor` — Default: `blue.500` | `errorBorderColor` — Default: `red.500`

The props `focusBorderColor` and `errorBorderColor` can be passed with Chakra color strings which will emulate the respective props being passed to [Chakra's `<Input />` component](https://chakra-ui.com/docs/components/input#changing-the-focus-and-error-border-colors).

```js
return (
<>
<Select errorBorderColor="orange.500" isInvalid />
<Select focusBorderColor="green.500" />
<Select errorBorderColor="orange.500" />
</>
);
```

![Orange errorBorderColor](./github/custom-error-border.png)

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

#### `useBasicStyles` — Default: `false`

If this prop is passed, the dropdown indicator at the right of the component will be styled in the same way [the original Chakra `Select` component](https://chakra-ui.com/docs/components/select) is styled, instead of being styled as an [`InputRightAddon`](https://chakra-ui.com/docs/components/input#left-and-right-addons). The original purpose of styling it as an addon was to create visual separation between the dropdown indicator and the button for clearing the selected options. However, as this button only appears when `isMulti` is passed, using this style could make more sense for a single select.
Expand All @@ -220,23 +230,11 @@ return (

![useBasicStyles dark mode](./github/use-basic-styles-dark.png)

#### `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.

```js
return <Select hasStickyGroupHeaders />;
```

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

**NOTE:** It has recently been discovered that when using this prop, navigating up through the available options with the arrow key will keep the focused option underneath the header, as it will not scroll enough to account for it being there. So if this is an issue for you, avoid this prop. A fix for this is being investigated.

![Sticky Group Headers](./github/sticky-group-headers.png)
[![CS-JS]](https://codesandbox.io/s/chakra-react-select-usebasicstyles-jjnqsd?file=/example.js)

#### `selectedOptionStyle` — Options: `color`, `check` — Default: `color`
#### `selectedOptionStyle` — Options: `color` | `check` — Default: `color`

In `v1.3.0` you can now pass the prop `selectedOptionStyle` with either `"color"` or `"check"` (defaults to `"color"`). The default option `"color"` will style a selected option similar to how react-select does it, by highlighting the selected option in the color blue. Alternatively if you pass `"check"` for the value, the selected option will be styled like the [Chakra UI Menu component](https://chakra-ui.com/docs/components/menu#menu-option-groups) and include a check icon next to the selected option(s). If `isMulti` and `selectedOptionStyle="check"` are passed, space will only be added for the check marks if `hideSelectedOptions={false}` is also passed.
As of `v1.3.0` you can pass the prop `selectedOptionStyle` with either `"color"` or `"check"`. The default option `"color"` will style a selected option similar to how react-select does it, by highlighting the selected option in the color blue. Alternatively if you pass `"check"` for the value, the selected option will be styled like the [Chakra UI Menu component](https://chakra-ui.com/docs/components/menu#menu-option-groups) and include a check icon next to the selected option(s). If `isMulti` and `selectedOptionStyle="check"` are passed, space will only be added for the check marks if `hideSelectedOptions={false}` is also passed.

```js
return (
Expand All @@ -251,6 +249,8 @@ return (

![Check Highlighted Selected Option](./github/check-selected-option.png)

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

#### `selectedOptionColor` — Default: `blue`

If you choose to stick with the default `selectedOptionStyle="color"`, you have one additional styling option. If you do not like the default of blue for the highlight color, you can pass the `selectedOptionColor` prop to change it. This prop will accept any named color from your color theme, and it will use the `500` value in light mode or the `300` value in dark mode.
Expand All @@ -268,6 +268,22 @@ return (

![Purple Selected Option Color (dark mode)](./github/purple-selected-option-dark.png)

[![CS-JS]](https://codesandbox.io/s/chakra-react-select-border-selectedoptioncolor-yyd321?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.

```js
return <Select hasStickyGroupHeaders />;
```

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

**NOTE:** It has recently been discovered that when using this prop, navigating up through the available options with the arrow key will keep the focused option underneath the header, as it will not scroll enough to account for it being there. So if this is an issue for you, avoid this prop. A fix for this is being investigated.

![Sticky Group Headers](./github/sticky-group-headers.png)

#### `isFixed`

In your options objects, you can add the key `isFixed: true` to emulate the example in the [react-select docs](https://react-select.com/home#fixed-options). This will prevent the options which have this flag from having the remove button on its corresponding tag, and it changes the default `tagVariant` for that tag to be solid. This only applies when using `isMulti`.
Expand Down Expand Up @@ -319,7 +335,7 @@ function option(provided, state) {
}
```

All of the style keys offered in the original package can be used here, except for `input` as that does not allow me to use the `chakraStyles` from the select props. The `input` styles are also much more dynamic and should be left alone for the most part.
All of the style keys offered in the original package can be used in the `chakraStyles` prop except for `menuPortal`. Along with [some other caveats](#caveats), this is explained below.

Most of the components rendered by this package use the basic [Chakra `<Box />` component](https://chakra-ui.com/docs/components/box) with a few exceptions. Here are the style keys offered and the corresponding Chakra component that is rendered:

Expand Down Expand Up @@ -696,17 +712,25 @@ Being a wrapper for `react-select`, all of the customizations done to react-sele
To do so, simply import the hook from this package, and call it by passing in any extra custom props you'd like into it and spread it onto a base `react-select` component:

```jsx
import { useState } from "react";
import { useChakraSelectProps } from "chakra-react-select";
import Select from "react-select";
import { options } from "./data";

const CustomSelect = () => {
const [selectedOptions, setSelectedOptions] = useState([]);

const CustomSelect = (customSelectProps) => {
const selectProps = useChakraSelectProps(customSelectProps);
const selectProps = useChakraSelectProps({
isMulti: true,
value: selectedOptions,
onChange: setSelectedOptions,
});

return <Select {...selectProps} />;
};
```

One example of how you might use this is to customize the component `react-google-places-autocomplete`, which is an autocomplete dropdown for Google Places that uses the `AsyncSelect` from `react-select` as it's core. Therefore, it accepts all of the same select props as the core react-select does which means you can use the `useChakraSelectProps` hook to style it:
One example of how you might use this is to customize the component `react-google-places-autocomplete`, which is an autocomplete dropdown for Google Places that uses the `AsyncSelect` from `react-select` as it's core. Therefore, it accepts all of the same select props as the core react-select does meaning you can use the `useChakraSelectProps` hook to style it:

```jsx
import { useState } from "react";
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chakra-react-select",
"version": "4.1.4",
"version": "4.1.5",
"description": "A Chakra UI wrapper for the popular library React Select",
"license": "MIT",
"author": "Chris Sandvik <chris.sandvik@gmail.com>",
Expand Down
5 changes: 1 addition & 4 deletions src/chakra-components/containers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ export const SelectContainer = <
const initialSx: CSSObject = {
position: "relative",
direction: isRtl ? "rtl" : undefined,
// When disabled, react-select sets the pointer-state to none which prevents
// the `not-allowed` cursor style from chakra from getting applied to the
// Control when it is disabled
pointerEvents: "auto",
...(isDisabled ? { cursor: "not-allowed" } : {}),
};

const sx = chakraStyles?.container
Expand Down
1 change: 1 addition & 0 deletions src/chakra-components/control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const Control = <
overflow: "hidden",
height: "auto",
minHeight: heights[size || "md"],
...(isDisabled ? { pointerEvents: "none" } : {}),
};

const sx = chakraStyles?.control
Expand Down
6 changes: 3 additions & 3 deletions src/module-augmentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ declare module "react-select/dist/declarations/src/Select" {
* Options: `sm` | `md` | `lg`
*
* @defaultValue `md`
* @see {@link https://github.com/csandman/chakra-react-select#size--options-sm-md-lg--default-md}
* @see {@link https://github.com/csandman/chakra-react-select#size--options-sm--md--lg--default-md}
* @see {@link https://chakra-ui.com/docs/components/input#changing-the-size-of-the-input}
*/
size?: Size;
Expand Down Expand Up @@ -82,7 +82,7 @@ declare module "react-select/dist/declarations/src/Select" {
* Options: "subtle" | "solid" | "outline"
*
* @defaultValue `subtle`
* @see {@link https://github.com/csandman/chakra-react-select#tagvariant--options-subtle-solid-outline--default-subtle}
* @see {@link https://github.com/csandman/chakra-react-select#tagvariant--options-subtle--solid--outline--default-subtle}
* @see {@link https://chakra-ui.com/docs/data-display/tag#props}
*/
tagVariant?: TagVariant;
Expand All @@ -104,7 +104,7 @@ declare module "react-select/dist/declarations/src/Select" {
* Options: `color` | `check`
*
* @defaultValue `color`
* @see {@link https://github.com/csandman/chakra-react-select#selectedoptionstyle--options-color-check--default-color}
* @see {@link https://github.com/csandman/chakra-react-select#selectedoptionstyle--options-color--check--default-color}
* @see {@link https://chakra-ui.com/docs/components/menu#menu-option-groups}
*/
selectedOptionStyle?: SelectedOptionStyle;
Expand Down