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
- Host: GitHub
- URL: https://github.com/manifoldco/react-select-zero
- Owner: manifoldco
- License: bsd-3-clause
- Created: 2019-07-01T20:54:34.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2021-05-12T02:37:09.000Z (over 4 years ago)
- Last Synced: 2025-07-06T23:41:04.217Z (3 months ago)
- Language: TypeScript
- Homepage:
- Size: 4.14 MB
- Stars: 18
- Watchers: 12
- Forks: 2
- Open Issues: 27
-
Metadata Files:
- Readme: readme.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# 🥢 React Select Zero
![]()
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/