An open API service indexing awesome lists of open source software.

https://github.com/manifoldco/react-select-zero

Zero-dependency alternative to react-select
https://github.com/manifoldco/react-select-zero

Last synced: 3 months ago
JSON representation

Zero-dependency alternative to react-select

Awesome Lists containing this project

README

          

# 🥢 React Select Zero


Demo

Lightweight, accessible, zero-dependency combobox alternative to
[react-select][react-select]. Supports single selection, multiselection,
search, and full keyboard controls in a handsome `5 KB` component (`1.8 KB`
gzipped).

### Comparison

react-select-zero sheds most of its weight through zero dependencies, but it
also gets a boost from React Hooks, modern JS, and leveraging HTML and
browser functionality wherever possible rather than JS logic (e.g.:
``s are used in many places, which don’t require enter and
space keybindings—only an `onClick` callback).

| Name | Minified | Minified + gzip |
| :------------------------------------- | ---------: | --------------: |
| `@manifoldco/react-select-zero` | 🔥`5 KB`🔥 | `1.8 KB` |
| `@zendeskgarden/react-selection@6.0.1` | `26.6 KB` | `6.6 KB` |
| `downshift` | `21.9 KB` | `7.1 KB` |
| `rc-select` | `164.3 KB` | `46.3 KB` |
| `react-select` | `86.6 KB` | `26.1 KB` |

## 🍚 Usage

```bash
npm i @manifoldco/react-select-zero
```

### Basic usage

```jsx
const [selection, setSelection] = useState([]);

return (

Select a Pokémon

);
```

_Note: `onChange` always returns an array, even in single selection mode._

### Multi selection

```jsx
const [selection, setSelection] = useState([]);

return (

Select a Pokémon

);
```

### Set initial selection

```jsx
const [selection, setSelection] = useState(['Bulbasaur']);

return (

Select a Pokémon

);
```

### Hide search (shown by default)

```jsx
const [selection, setSelection] = useState([]);

return (

Select a Pokémon

);
```

_Note: search won’t appear if there are fewer than 5 items_

### Allow creation of new entry (works for single and multi)

```jsx
const [selection, setSelection] = useState([]);

return (

Select a Pokémon

);
```

User-created values will appear in the same array. To determine new from
existing, you’ll have to scan the `options` you passed for any differences,
e.g.:

```js
onChange={
(newVal) => {
const created = newVal.filter(val => !options.includes(val));
const existing = newVal.filter(val => options.includes(val));
setCreated(created);
setExisting(existing);
}
}
```

### All Props

| Name | Type | Default | Description |
| :------------- | :------------------- | :--------- | :---------------------------------------------------------------------------------------------- |
| **`name`** | `string` | | **Required** Form name of this input. Query this like a normal form input. Also assits in a11y. |
| **`onChange`** | `(string[]) => void` | | **Required** Form callback called when state changes |
| **`options`** | `string[]` | | **Required** Array of strings to display as options |
| **`value`** | `string[]` | | **Required** Set selected values |
| `allowCreate` | `boolean` | `false` | Set `` to allow creating new entries (note: `noSearch` can’t be set) |
| `max` | `number` | `Infinity` | Set maximum number of items (only works with `multi`) |
| `multi` | `boolean` | `false` | Set `` to allow multiple selection |
| `noSearch` | `boolean` | `false` | Set `` to hide searching (by default shows with > 5 options) |
| `placeholder` | `string` | | Specify placeholder text |

## đź’… Styling

This component ships with some lightweight styles to extend. Either import
them like so:

```js
import '@manifoldco/react-select-zero/assets/react-select-zero.css';
```

Or copy the [CSS][styles] directly, and modify as you wish. There are some
CSS variables you can overwrite to control colors & background images.

Alternatively, you can also use [Styled Components][styled-components] or
your favorite CSS-in-JS solution to extend the existing styles:

```jsx
import styled from 'styled-components';
import Select from '@manifoldco/react-select-zero';

const StyledSelect = styled(Select)`
/* overrides go here */
`;

;
```

## Accessibility

This component ships with the following accessibility features out-of-box:

- [x] [listbox][listbox] role with `aria-expanded`, `aria-haspopup`, and `aria-multiselectable` properties
- [x] Focusable main input
- [x] Keyboard ↓ opens dropdown when focused
- [x] Keyboard ↑/↓ navigation through items
- [x] Keyboard enter to select items
- [x] Keyboard Home/End to jump to beginning/end of list
- [x] Keyboard esc to close the combo box
- [x] Searchable items
- [x] Removal of multiselect items also fully keyboard-navigable

### Using labels

This component doesn’t come with a label, but you can add one yourself! This
component will pass through any additional properties to the root element
that also has `[role="listbox"]`.

```jsx
import React from 'react';
import Select from '@manifoldco/react-select-zero';

const MySelect = () => (
<>


>
);
```

[listbox]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role
[styles]: ./src/styles.css
[react-select]: https://github.com/JedWatson/react-select
[styled-components]: https://www.styled-components.com/