React Selectize
ReactSelectize
is a stateless Select component for ReactJS, that provides a platform for the more developer friendly SimpleSelect
& MultiSelect
components.
Both SimpleSelect
& MultiSelect
have been designed to work as drop in replacement for the built-in React.DOM.Select
component.
styles & features inspired by React Select & Selectize.
DEMO / Examples: furqanZafar.github.io/react-selectize
- Changelog (last updated on 29th July 2017)
- API Reference
Motivation
- existing components do not behave like built-in React.DOM.* components.
- existing components synchronize props with state an anti pattern, which makes them prone to bugs & difficult for contributers to push new features without breaking something else.
- more features.
Features
- Drop in replacement for React.DOM.Select
- Customizable themes
- Stateless, therefore extremely flexible & extensible
- Clean and compact API fully documented on GitHub
- Multiselect support
- Option groups
- Custom filtering & option object
- Search highlighting
- Custom option & value rendering
- Animated dropdown
- Remote data loading
- Tagging or item creation
- Restore on backspace
- Editable value
- Caret between items
- Customizable dropdown direction
- Mark options as unselectable
- Disable selected values
- Absolute positioned overlay, "Tether"ed to the search field
Deps
Peer Deps
- create-react-class
- react
- react-dom
- react-transition-group
- react-dom-factories
Install
- npm:
npm install react-selectize
your package.json must look like this
{ "dependencies": { "react": "^16.0.0-beta.2", "react-addons-css-transition-group": "^15.6.0", "react-addons-shallow-compare": "^15.6.0", "react-dom": "^16.0.0-beta.2", "react-dom-factories": "^1.0.0", "react-selectize": "^3.0.1", "react-transition-group": "^1.1.2" } }
to include the default styles add the following import statement to your stylus file: @import 'node_modules/react-selectize/themes/index.css'
-
bower:
bower install https://unpkg.com/[email protected]/bower.zip
-
1998 script tag:
<html> <head> <!-- PRELUDE --> <script src="http://www.preludels.com/prelude-browser-min.js" type="text/javascript" ></script> <script src="https://unpkg.com/[email protected]/dist/index.min.js" type="text/javascript" ></script> <!-- REACT --> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-with-addons.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script> <script type="text/javascript" src="https://unpkg.com/[email protected]"></script> <!-- optional dependency (only required with using the tether prop) --> <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.1.1/js/tether.min.js" type="text/javascript" ></script> <!-- REACT SELECTIZE --> <script src="https://unpkg.com/[email protected]/dist/index.min.js" type="text/javascript" ></script> <!-- THEMES (default, bootstrap3, material) --> <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/index.min.css"/> </head> <body> <div id="mount-node"></div> <script type="text/javascript"> ReactDOM.render( React.createElement(reactSelectize.SimpleSelect, { style: {width: 300}, tether: true, placeholder: "Select fruit", options: [{label: "apple", value: "apple"}, {label: "banana", value: "banana"}] }), document.getElementById("mount-node") ); </script> </body> </html>
Usage (jsx)
import React, {Component} from 'react'; import {ReactSelectize, SimpleSelect, MultiSelect} from 'react-selectize'; . . . <SimpleSelect placeholder="Select a fruit" onValueChange={value => alert(value)}> <option value = "apple">apple</option> <option value = "mango">mango</option> <option value = "orange">orange</option> <option value = "banana">banana</option> </SimpleSelect> . . . // Note: options can be passed as props as well, for example <MultiSelect placeholder = "Select fruits" options = {["apple", "mango", "orange", "banana"].map( fruit => ({label: fruit, value: fruit}) )} onValuesChange = {value => alert(value)} />
Usage (livescript)
{create-factory}:React = require \react {SimpleSelect, MultiSelect, ReactSelectize} = require \react-selectize SimpleSelect = create-factory SimpleSelect MultiSelect = create-factory MultiSelect . . . SimpleSelect do placeholder: 'Select a fruit' options: <[apple mango orange banana]> |> map ~> label: it, value: it on-value-change: (value) ~> alert value . . . MultiSelect do placeholder: 'Select fruits' options: <[apple mango orange banana]> |> map ~> label: it, value: it on-values-change: (values) ~> alert values
Gotchas
-
the default structure of an option object is
{label: String, value :: a}
wherea
implies thatvalue
property can be of any equatable type -
SimpleSelect notifies change via
onValueChange
prop whereas MultiSelect notifies change viaonValuesChange
prop -
the onValueChange callback for SimpleSelect is passed 1 parameter. the
selected option object
(instead of the value property of the option object) -
the onValuesChange callback for MultiSelect is passed 1 parameter an Array of selected option objects (instead of a collection of the value properties or a comma separated string of value properties)
-
both the SimpleSelect & MultiSelect will manage the
open
,search
,value
&anchor
props using internal state, if they are not provided via props: when passingopen
,search
,value
oranchor
via props, you must update them on*Change (just like in the case of standard react html input components)
value = {state.selectedValue} onValueChange = {function(value){ self.setState({selectedValue: value}); }} search = {state.search} onSearchChange = {function(value){ self.setState({search: value}); }}
- when using custom option object, you should implement the
uid
function which accepts an option object and returns a unique id, for example:
// assuming the type of our option object is: // {firstName :: String, lastName :: String, age :: Int} uid = {function(item){ return item.firstName + item.lastName; }}
the uid
function is used internally for performance optimization.
Development
npm install
npm start
- visit
localhost:8000
npm test
,npm run coverage
for unit tests & coverage- for production build/test run
MINIFY=true gulp