UNPKG

@kovalskiy_dmitriy/react-multi-select

Version:
308 lines (212 loc) 12.7 kB
# Multi select [![Build Status](https://travis-ci.org/kenshoo/react-multi-select.svg?branch=master)](https://travis-ci.org/kenshoo/react-multi-select) [![npm version](https://badge.fury.io/js/%40kenshooui%2Freact-multi-select.svg)](https://badge.fury.io/js/%40kenshooui%2Freact-multi-select) [![Test Coverage](https://api.codeclimate.com/v1/badges/6242f7063a82be5a265e/test_coverage)](https://codeclimate.com/github/kenshoo/react-multi-select/test_coverage) **Kenshoo multi select component** **[react-multi-select demo](https://kenshoo.github.io/react-multi-select)** Multi select is a straight forward component that helps a user select multiple items in a clear and filterable way. <p align="center"> <img src="preview.gif?raw=true" width="600" /> </p> ## Installation **Installation using npm:** ``` npm install @kenshooui/react-multi-select --save ``` **Installation using Yarn:** ``` yarn add @kenshooui/react-multi-select ``` ## Import styles Include the component's css on your app ```jsx import "@kenshooui/react-multi-select/dist/style.css" ``` ## How to use ```jsx import React, { Component } from "react"; import MultiSelect from "@kenshooui/react-multi-select"; class Example extends Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { items: [ { id: 0, label: "item 1" }, { id: 2, label: "item 2", disabled: true }, { id: 3, label: "item 3", disabled: false }, { id: 4, label: "item 4" } ], selectedItems: [] }; } handleChange(selectedItems) { this.setState({ selectedItems }); } render() { const { items, selectedItems } = this.state; return ( <MultiSelect items={items} selectedItems={selectedItems} onChange={this.handleChange} /> ); } } ``` ## Properties | Name | Type | Default | Description | | :---------------------------- | :---------- | :------------- | :------------------------------------------------------------------------------------------------------ | | `items` | `List` | [] | list of items. | | `selectedItems` | `Array` | [] | selected list to start with (subgroup of items). | | `onChange` | `function` | ()=>{} | callback for changed event. | | `loading` | `boolean` | false | toggle to show loading indication. | | `messages` | `Object` | {} | custom messages. Please see below for the availabale messages. | | `showSearch ` | `boolean` | true | toggle to show search option. | | `showSelectAll` | `boolean` | true | toggle to show select all option in list. | | `showSelectedItems` | `boolean` | true | toggle to show selected items right pane. | | `wrapperClassName` | `String` | '' | wrapper class name - Used for customizing the style. | | `height` | `number` | 400 | available items list height. | | `itemHeight` | `number` | 40 | the height of an item in the list. | | `selectedItemHeight` | `number` | `itemHeight` | the height of the selected item in the list. | | `selectAllHeight` | `number` | `itemHeight` | the height of the selectAll component, by default will use the value of the itemHeight. | | `maxSelectedItems` | `number` | | defines the maximum items that can be selected, overrides showSelectAll. | | `filterFunction` | `function` | based on label | The function used to filter items based on the search query. | | `searchRenderer` | `Component` | | Component to replace the default Search component. | | `selectedItemRenderer` | `Component` | | Component to replace the default selected item component in the destination list. | | `loaderRenderer` | `Component` | | Component to replace the default loader component. | | `selectAllRenderer` | `Component` | | Component to replace the default select all component. | | `itemRenderer` | `Component` | | Component to replace the default item component in the source list. | | `selectionStatusRenderer` | `Component` | | Component to replace the default selection status component. | | `noItemsRenderer` | `Component` | | Component to replace the default no items component. | | `searchValue` | `string` | | The value of the search field. | | `searchValueChanged` | `function` | | Function to handle the change of search field. Accepts value as a single argument. | | `responsiveHeight` | `string` | 400px | Responsive height of the wrapping component, can send percent for example: `70%` | | `withGrouping` | `boolean` | false | Your items will be grouped by the group prop values - see "item grouping" section below | | `showSelectedItemsSearch` | `boolean` | false | toggle to show search option in detination list. | | `searchSelectedItemsValue` | `string` | | The value of the search field for destination list. | | `searchSelectedItemsChanged` | `function` | | Function to handle the change of search field for destination list. Accepts value as a single argument. | | `selectedItemsFilterFunction` | `function` | based on label | Is the same as filterFunction by default to filter items based on the search query in destination list. | | `isLocked` | `function` | `item => item.disabled` | Function to be used to define whether item is locked or not| ## Customization #### Renderers You can replace the renderers of the following components: <br/> **Item** Use the `itemRenderer` to replace the default component. Each item receives the following props: `item` - holds your item data `height` - receives the height defined by the list `onClick` - the event to toggle selection on the component `checked` - indicates if the item is selected `indeterminate` - used by the select all component to display indeterminate mode `disabled` - defines if item should be disabled. Item won't be clickable for selection and will be ignored when clicking "Select All". `group` - group item - no checkbox, not clickable, black colored <br/> **Select All** Use the `selectAllRenderer` to replace the default component. The `SelectAll` component receives the following props: `height` - receives the height defined by the parent `onClick` - Triggers the select all/clear all event on click `isAllSelected` - Indicates that all items are selected `selectAllMessage` - Defines the message for the `SelectAll` component `selectedIds` - holds a list of ids of all the selected items <br/> **Selected Item** Use the `selectAllRenderer` to replace the default component. The `SelectedItem` component receives the following props: `item` - holds your item data `height` - receives the height defined by the list You can disable specific selected items by passing `item.disabled: true` or pass `isLocked` function which will be used to define whether the item is disabled. Example (selected & disabled): ```javascript function Exemple(){ const items = [{id:0,label: 'item 0'}, {id:1,label: 'item 1'}]; return ( <MultiSelect isLocked={item => item.label === 'item 0'} items={items} selectedItems={items} /> } ``` <br/> **Search** Use the `searchRenderer` to replace the default component. The `Search` component receives the following props: `searchPlaceholder` - defines the message to display in the search placeholder `onChange` - triggers the action of changing the search value <br/> **Selection Status** Use the `selectionStatusRenderer` to replace the default component. The `SelectionStatus` component receives the following props: `selected` - an array of all the selected ids `clearAll` - callback to clear all selected items `clearAllMessage` - text to display in the clear all text `noneSelectedMessage` - text to display when no items are selected `selectedMessage` - text to display when there are items selected <br/> **Loader** Use the `loaderRenderer` to replace the default component. Does not receive any props. <br/> **No Items** Use the `noItemsRenderer` to replace the default component. Does not receive any props. <br/> #### Search Function In order to accommodate complex item filters, you can provide your own filter method in the `filterFunction` prop. Example (default): ```javascript value => item => String(item.label) .toLowerCase() .includes(value.toLowerCase()) ``` Performs search on server side ```javascript value => { callServer(value).then(items => this.setState({items})); // At the end return the expected method return item => true; } ``` #### Messages You can use your own messages. Here is the default messages object: ```jsx messages: { searchPlaceholder: "Search...", noItemsMessage: "No Items...", noneSelectedMessage: "None Selected", selectedMessage: "delected", selectAllMessage: "Select All", clearAllMessage: "Clear All", disabledItemsTooltip: "You can only select 1 file" } ``` #### Item grouping You can add also grouping to your items - add a group prop with the group name as a value to each of your items and add withGrouping prop as well. ```jsx <MultiSelect items={[{id: 1, label: "item1", group: "group1"}, {id: 2, label: "item2", group: "group1"} {id: 3, label: "item3", group: "group2"}]} withGrouping selectedItems={selectedItems} onChange={this.handleChange} /> ``` ## How to Contribute #### Setting up development environment 1. Fork the repository and create your branch from `master`. 2. Install the project: `yarn install` 3. Run tests: `yarn test` or `yarn test:watch` 4. Run dev environment: `yarn storybook` and head to [https://localhost:6006](https://localhost:6006) #### Issuing a change 1. Push to github. 2. If you’ve fixed a bug or added code that should be tested, add tests. 3. Open a Pull Request with the following guidelines: - Set title prefix to feature/bug and supply a descriptive PR title. - Add description to your Pull Request describing your change. 4. Once your Pull Request is issued, the test suite and build processes will run and your change will be reviewed. ## Compatibility - React 16 or newer