react-select-virtualized

react-select v3 + react-virtualized + react hooks!

This project came up after hours of trying to find an autocomplete component that supports large sets of data to be displayed and searched for while maintain performance. The only libraries out there that allow this functionality are either not maintained anymore, use outdated libraries or are poorly performant.
I created a component that uses the Airbnb library called react-virtualized
for the virtual data loading of elements and plugged it to the react-select
(the most used autocomplete library for react) menu list.

Note
The select component will be the same from react-select v3
so you will be able to use it with any select you already have.
IMPORTANT
For using the react version grater than 16.8, please use react-select
v 3.0.8 and the latest version of this library. If you are using react 16.8 please use the latest version but with react-select
v 3.0.4.
Install
npm install --save react-select-virtualized
Peer Dependencies
remember to install them also if they are not already in your project.
{
"react": "^16.8.x || 16.9.x || 16.10.x || 16.11.x",
"react-dom": "^16.8.x || 16.9.x || 16.10.x || || 16.11.x",
"react-virtualized": "^9.21.1",
"react-select": "^3.0.x"
}
Try It!!!
https://codesandbox.io/s/vigilant-mclean-wpbk7
Storybook
Do you want to see it working? -> https://serene-hawking-021d7a.netlify.com/
Roadmap
-- v 1.0.0 --
-- v 1.1.0 --
-- v 1.2.0 --
-- v 2.0.0 --
-- v 2.1.0 --
-- v 2.2.0 --
-- v 2.3.0 --
-- v 2.4.0 --
A WORD ABOUT CONTROLLED/UNCONTROLLED
When you use the defaultValue
you will be using the component as uncontrolled and the state will be managed for you internally. There are some prop that cannot be mixed and the component will let you know when that is the case. Same happens when you use value
, but will render the component as a controlled component where you will be in charge of the component internal state.
Documentation - Select Component - this are special to this library none is required
Props | Type | Default | Description |
---|
grouped | boolean | false | specify if options are grouped |
formatGroupHeaderLabel | function({ label, options}) => component | | will render a custom component in the popup grouped header (only for grouped) |
formatOptionLabel (coming from react-select) | function(option, { context }) => component | | will render a custom component in the label |
optionHeight | number | 31 | height of each option |
groupHeaderHeight | number | | header row height in the popover list |
maxHeight (coming from react-select) | number | auto | max height popover list |
defaultValue | option | | will set default value and set the component as an uncontrolled component |
value | option | | will set the value and the component will be a controlled component |
onCreateOption (Only for Creatable) | function(option) => nothing | | will be executed when a new option is created , it is only for controlled components |
What we do support and don't from react-select
Usage without group
check storybook for more examples, it can be used controlled/uncontrolled.
const options = [
{
value: 1,
label: `guiyep`,
},
...
];
import React, { Component } from 'react';
import Select from 'react-select-virtualized';
const Example extends Component {
render() {
return <Select options={options}/>;
}
}
const Example2 = () => <Select options={options}/>
const Example3 = () => <Select options={options} {..ANY_REACT_SELECT_V2_PROP}/>
Usage with group - tooooo easy!!!
check storybook for more examples, it can be used controlled/uncontrolled.
const options = [
{
value: 1,
label: `guiyep`,
},
...
];
const opsGroup = [
{ label: `Group Name Header`, options },
...
]
import React, { Component } from 'react';
import Select from 'react-select-virtualized';
const Example extends Component {
render() {
return <Select options={options} grouped/>;
}
}
const Example2 = () => <Select options={options} grouped/>
const Example3 = () => <Select options={options} {..ANY_REACT_SELECT_V2_PROP} grouped/>
Usage Async Loading!!!! also with group :)
check storybook for more examples, it can be used controlled/uncontrolled.
CLARIFICATION: filtering happens in the server.
import React, { Component } from 'react';
import { Async } from 'react-select-virtualized';
const loadOptions = (input, callback) => {...};
const Example extends Component {
render() {
return <Async defaultOptions={options} loadOptions={loadOptions}/>;
}
}
const Example2 = () => <Async loadOptions={loadOptions}/>
const Example3 = () => <Async defaultOptions={options} {..ANY_REACT_ASYNC_SELECT_V2_PROP} loadOptions={loadOptions}/>
const Example4 = () => <Async defaultOptions={opsGroup} {..ANY_REACT_ASYNC_SELECT_V2_PROP} loadOptions={loadOptions} grouped/>
Usage Creatable
check storybook for more examples, it can be used controlled/uncontrolled.
UNCONTROLLED:
import React, { Component } from 'react';
import { Creatable } from 'react-select-virtualized';
const Example1 = () => <Creatable options={options} />;
CONTROLLED:
import React, { Component } from 'react';
import { Creatable } from 'react-select-virtualized';
const onCreateOption = (newItem) => {
store.set({ options: store.state.options.concat([newItem]) });
store.set({ selected: newItem });
};
const onChange = (item) => {
store.set({ selected: item });
action(`onChange`)(item);
};
const Example1 = () => (
<Creatable
options={store.state.options}
value={store.state.selected}
onCreateOption={onCreateOption}
onChange={onChange}
/>
);
Usage Creatable (With Group)
NOT YET DONE.
License
MIT © guiyep