2.3.0 • Published 5 years ago

material-multi-picker v2.3.0

Weekly downloads
4
License
MIT
Repository
github
Last release
5 years ago

npm package npm downloads licence codecov CircleCI bundlephobia LGTM alerts LGTM grade

Typeahead multipicker component, uses React 16, Material-UI 3 or 4, and downshift.

This component allows users to pick multiple items from a typeahead dropdown. It's easy to use straight out-of-the-box, but allows visual customisation while remaining within the Material Design universe.

Check out the live demos in the documentation.

Animated image of picker component in being used to select multiple fruits from a dropdown list

Features

  • Functional and aesthetic with minimal configuration
  • Typeahead suggestions can be provided synchronously or asynchronously
  • Good keyboard and screenreader accessibility (due to being build on PayPal's downshift primitive)
  • Handles most errors and edge cases gracefully
  • Conforms to Material Design guidelines (due to using components from the Material UI library)
  • Key visual aspects are customisable

Usage

Install with npm install material-multi-picker or yarn add material-multi-picker. Make sure you have React (16+) and Material UI (3+) installed!

import MultiPicker from 'material-multi-picker';
import React, { useState } from 'react';

const favoriteThings = [
    "raindrops on roses",
    "whiskers on kittens",
    "bright copper kettles",
    "warm woolen mittens"
]

function getSuggestions(inputValue) {
    return favoriteThings.filter(
        thing => thing.includes(inputValue.toLowerCase())
    );
}

function FavouriteThingPicker() {
    //use React hooks for state (React 16.8+ only)
    const  [myThings, setMyThings ] = useState([]);

    return (
        <MultiPicker
            value={ myThings }
            onChange={ setMyThings }
            getSuggestedItems={ getSuggestions }
            itemToString={ item => item }
        />
    );
}

Props

Note that the picker can only be used as a Controlled Component.

Prop nameTypeRequired?Description
valuearrayyesThe items currently displayed as "selected" in the picker. They will appear as a series of Chips.
onChangefunction(newValue)yesCallback fired by the component when the user changes the selected items.
getSuggestedItemsfunction(inputValue, selectedItems)yesUsed by the picker to get the suggestions that will appear in the dropdown. Return an array of items, a promise that resolves to an array of items, or the special NOT_ENOUGH_CHARACTERS symbol (see below).
itemToStringfunction(item)yesUsed by the picker to extract a unique identifer string for an item (must return a string).
namestringnoIf set, the same name will be applied to the input field
disabledbooleannoIf true, prevents all interaction with the component (chip popovers will still appear if configured)
errorbooleannoIf true, the picker will display in an errored state (using theme colors)
requiredbooleannoIf true, the picker will indicate that the value is required
variant'standard', 'filled', or 'outlined'noSets the display style of the field (as with the Material UI text field). Defaults to 'standard'.
maxDropdownHeightnumbernoMaximum height of the dropdown element (in pixels). If there are too many suggestions, the dropdown will become scrollable. Defaults to unlimited height.
itemToLabelfunction(item)noUsed by the picker to populate the chip labels. If not supplied, the results of itemToString will be used.
itemToAvatarfunction(item)noUsed by the picker to add material <Avatar /> icons into the chips. If not supplied, chips will have no icon.
itemToPopoverfunction(item)noUsed by the picker to add material Popovers to chips, activated on hover. If not supplied, chips will have no popover.
chipColor'primary', 'secondary' or 'default'noWhich theme color to use for the chips. By default this is undefined, which in most themes will lead to chips being light grey.
fullWidthbooleannoAs in Material UI, determines whether the picker will grow to fill available horizontal space. Defaults to false
autoFocusbooleannoAs in Material UI, when true this causes the picker to get the focus when it mounts. Defaults to false
showDropdownOnFocusbooleannoWhen true, causes the picker to show the suggestions dropdown whenever the picker gets the focus, even if the user has not typed anything. Defaults to false.
labelstringnoThe label applied to the input field. Defaults to "".
helperTextstringnoThe helper text applied to the field (rendered below the picker). Defaults to "".
fetchDelaynumbernoThe delay between the last keypress and the picker fetching suggestions. Useful to avoid spamming a service! Defaults to 0.
SuggestionComponentReact componentnoCustom component used to render suggestions in the picker dropdown (see below for a list of supplied props). Defaults to the result of itemToString.
ErrorComponentReact componentnoCustom component used to indicate a loading error in the picker dropdown (see below for a list of supplied props). Default just shows a generic error message.
useGlobalCachestringnoIf set, this causes the picker to use a global in-memory suggestions cache with the given ID, improving performance across multiple instances
clearInputOnBlurbooleannoDefault to false. If set to true, the typeahead input will be cleared whenever the picker loses the focus. This can be useful to avoid confusing users who move on from the picker without selecting anything from the dropdown.
disablePortalsbooleannoDefaults to false. If set to true, the dropdown will be rendered inline in the DOM instead of using <body> as the parent (can be useful for testing or limiting CSS scope)

Requiring a minimum number of characters in the input

Sometimes you may want to wait for the user to enter several characters before doing a suggestions lookup - this can reduce load on APIs and avoids bringing back unhelpful results. You can do this just by testing the length of the input in your getSuggestedItems() function and returning an empty array, but this doesn't tell the users that they need to enter more characters. Instead, return the special NOT_ENOUGH_CHARACTERS symbol, and a dropdown message will be displayed to users explaining that they need to type more characters.

import { NOT_ENOUGH_CHARACTERS } from 'material-multi-picker';

Customising suggestions in the dropdown

The default suggestion component just displays the id of the item (extracted with itemToString()) in a plain format. You can supply a React component as the SuggestionComponent prop, which will have access to the following props:

Prop nameTypeDescription
itemIdstringThe unique ID of the item (from itemToString)
itemanyThe suggestion generated by your getSuggestedItems function
isHighlightedbooleantrue if the user is currently highlighting this suggestion (either with keyboard navigation, or by hovering over with the mouse)
inputValuestringThe string currently entered in the text input field. Useful for highlighting portions of text to indicate matches.

It's a good idea to avoid interactive or clickable elements in your component, as they may interfere with the picker's event handling.

Handling errors

If your getSuggestedItems() function throws an error, or if it returns a Promise that fails, the picker will show an Error dropdown. You can override the default appearance and behaviour of this dropdown using the ErrorComponent. Your custom ErrorComponent, you will have access to the following props:

Prop nameTypeDescription
errorErrorThe error encountered while loading suggestions
inputValuestringThe search string entered by the user

Migration

1.x => 2.x

  • Make sure you're using React 16.8 or better (both react and react-dom)
2.3.0

5 years ago

2.2.0

5 years ago

2.1.1

5 years ago

2.1.0

5 years ago

2.0.1

5 years ago

2.0.0

5 years ago

1.8.5

5 years ago

1.8.4

5 years ago

1.8.3

5 years ago

1.8.2

5 years ago

1.8.1

5 years ago

1.8.0

5 years ago

1.7.0

5 years ago

1.6.0

5 years ago

1.5.2

5 years ago

1.5.1

5 years ago

1.5.0

5 years ago

1.4.1

5 years ago

1.4.0

5 years ago

1.3.0

5 years ago

1.2.0

5 years ago

1.1.0

5 years ago

1.0.0

5 years ago

0.4.0

5 years ago

0.3.0

5 years ago

0.2.2

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago

0.1.0

5 years ago