I no longer have the time nor the energy to maintain Picky. Please fork and improve. For alternatives I suggest:
npm install react-picky-with-clear
"react": "^16.8.0",
"react-dom": "^16.8.0"
`
Installation
Origin:
`
npm install --save react-picky
# or
yarn add react-picky
`
New picky with clear and reset
`
npm install --save react-picky
# or
yarn add react-picky
`
Screenshots
Single Select
!Single select
Multi Select
!Multi select
Usage
Basic example
`javascript
import { Picky } from 'react-picky-with-clear';
import 'react-picky/dist/picky.css'; // Include CSS
id="picky"
options={[1, 2, 3, 4, 5]}
value={[]}
multiple={true}
includeSelectAll={true}
includeFilter={true}
onChange={values => console.log(values)}
dropdownHeight={600}
/>;
`
Examples
- Custom Render: Select All
- Custom Render: List
- Custom Render: Option
Props
`javascript
Picky.defaultProps = {
numberDisplayed: 3,
options: [],
filterDebounce: 150,
dropdownHeight: 300,
onChange: () => {},
tabIndex: 0,
keepOpen: true,
selectAllText: 'Select all',
selectAllMode: 'default',
};
Picky.propTypes = {
id: PropTypes.string.isRequired,
placeholder: PropTypes.string,
value: PropTypes.oneOfType([
PropTypes.array,
PropTypes.string,
PropTypes.number,
PropTypes.object,
]),
numberDisplayed: PropTypes.number,
multiple: PropTypes.bool,
options: PropTypes.array.isRequired,
onChange: PropTypes.func.isRequired,
open: PropTypes.bool,
includeSelectAll: PropTypes.bool,
includeFilter: PropTypes.bool,
filterDebounce: PropTypes.number,
dropdownHeight: PropTypes.number,
onFiltered: PropTypes.func,
onOpen: PropTypes.func,
onClose: PropTypes.func,
valueKey: PropTypes.string,
labelKey: PropTypes.string,
render: PropTypes.func,
tabIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
keepOpen: PropTypes.bool,
manySelectedPlaceholder: PropTypes.string,
allSelectedPlaceholder: PropTypes.string,
selectAllText: PropTypes.string,
renderSelectAll: PropTypes.func,
defaultFocusFilter: PropTypes.bool,
className: PropTypes.string,
renderList: PropTypes.func,
filterPlaceholder: PropTypes.string,
disabled: PropTypes.bool,
getFilterValue: PropTypes.func,
caseSensitiveFilter: PropTypes.bool,
buttonProps: PropTypes.object,
selectAllMode: PropTypes.oneOf(['default', 'filtered']),
clearFilterOnClose: PropTypes.bool,
singleSelectPlaceholder: PropTypes.func,
};
`
$3
- id - HTML id assigned to input. Also used as a base for other elements inside Picky.
- placeholder - Default message when no items are selected.
- value - The selected value(s), array if multiple is true. Not needed if using as an uncontolled component
- numberDisplayed - Then number of selected options displayed until it turns into '(selected count) selected'.
- multiple - Set to true for a multiselect, defaults to false.
- options - Array of possible options.
- onChange - Called whenever selected value(s) have changed. Pass the selected value back into value.
- open - Can open or close the dropdown manually. Defaults to false.
- includeSelectAll - If set to true will add a Select All checkbox at the top of the list.
- includeFilter - If set to true will add an input at the top of the dropdown for filtering the results.
- filterDebounce - Debounce timeout, used to limit the rate the internal onFilterChange gets called. Defaults to 150ms.
- dropdownHeight - The height of the dropdown. Defaults to 300px.
- onFiltered - Called after a filter has been done with the filtered options.
- onOpen - Called after the dropdown has opened.
- onClose - Called after the dropdown has closed.
- valueKey - If supplying an array of objects as options, this is required. It's used to identify which property on the object is the value.
- labelKey - If supplying an array of objects as options, this is required. It's used to identify which property on the object is the label.
- render - Used for custom rendering of items in the dropdown. More info below.
- tabIndex - Pass tabIndex to component for accessibility. Defaults to 0
- keepOpen - Default true. Single selects close automatically when selecting a value unless this is set to true.
- manySelectedPlaceholder - Default "%s selected" where %s is the number of items selected. This gets used when the number if items selected is more than the numberDisplayed prop and when all options are not selected.
- allSelectedPlaceholder - Default "%s selected" where %s is the number of items selected. This gets used when all options are selected.
- selectAllText - Default "Select all", use this to override "Select all" text from top of dropdown when included with includeSelectAll.
- renderSelectAll - Used for rendering a custom select all
- defaultFocusFilter - If set to true, will focus the filter by default when opened.
- renderList - Render prop for whole list, you can use this to add virtualization/windowing if necessary
- filterPlaceholder - Override the filter placeholder. Defaults to 'Filter...'
- getFilterValue - Will provide the input value of filter to the picky dropdown, so that if we have a larger list of options then we can only supply the matching options based on this value.
- caseSensitiveFilter - If true options will be returned when they match case
- buttonProps - Additional props to apply the the button component, useful for supplying class names.
- selectAllMode - default: default. When the mode is filtered the Select All won't be hidden when filtering.
- clearFilterOnClose - When set to true filtered options and filtered state will be cleared on close. Defaults to false.
- filterTermProcessor - A function that takes a string and returns a string. Useful for trimming and processing a filter term before it filters the options. Default: (term) => term
- singleSelectPlaceholder - A function that takes the currently selected value and returns a string. (val: OptionType) => string
Custom rendering
$3
You can render out custom items for the dropdown.
Example
`javascript
id="picky"
value={this.state.arrayValue}
options={bigList}
onChange={this.selectMultipleOption}
open={false}
valueKey="id"
labelKey="name"
multiple={true}
includeSelectAll={true}
includeFilter={true}
getFilterValue={this.getFilterValue}
dropdownHeight={600}
render={({
style,
isSelected,
item,
selectValue,
labelKey,
valueKey,
multiple,
}) => {
return (
style={style} // required
className={isSelected ? 'selected' : ''} // required to indicate is selected
key={item[valueKey]} // required
onClick={() => selectValue(item)}
>
{/ required to select item /}
{item[labelKey]}
);
}}
/>
`
The render callback gets called with the following properties:
style, isSelected, item, labelKey, valueKey, selectValue, multiple
- isSelected - boolean - true if item is selected. Use this for styling accordingly.
- item - object | number | string - The item to render.
- labelKey - Used to get the label if item is an object
- valueKey - Used to get the value if item is an object, good for keys.
- selectValue - function(item) - Selects the item on click
- multiple - boolean - Indicates if is a multiselect.
Note
- If your rendered item affects the height of the item in anyway. Supply itemHeight to Picky.
- If you wish to show a radio button or a checkbox, be sure to add readOnly prop to the input.
$3
`javascript
// ...
renderSelectAll={({
filtered,
tabIndex,
allSelected,
toggleSelectAll,
multiple,
}) => {
// Don't show if single select or items have been filtered.
if (multiple && !filtered) {
return (
tabIndex={tabIndex}
role="option"
className={allSelected ? 'option selected' : 'option'}
onClick={toggleSelectAll}
onKeyPress={toggleSelectAll}
>
SELECT ALL
Gets called with the following properties:
- filtered: boolean - true if items have been filtered.
- allSelected: boolean true if all items are selected.
- toggleSelectAll: function selects or deselects all items.
- tabIndex: number used for specifying tab index.
- multiple: boolean true if multiselect.
$3
`javascript
id="picky"
value={this.state.arrayValue}
options={bigList}
onChange={this.selectMultipleOption}
open={true}
valueKey="id"
labelKey="name"
multiple={true}
includeSelectAll={true}
includeFilter={true}
dropdownHeight={600}
manySelectedPlaceholder={dynamicPlaceholder}
defaultFocusFilter={true}
renderList={({ items, selected, multiple, selectValue, getIsSelected }) =>
items.map(item => (
selectValue(item)}>
{getIsSelected(item) ? {item.name} : item.name}
))
}
/>
`
This is an example of a custom rendered list.
styled-components support
Support is pretty basic by allowing a className prop to , so as a side effect you can add a custom class to the core Picky for easier style overrides.
Usage
`javascript
const Select = styled(Picky)
;
``