Multi Select
View in LexiconMulti select is the field type that allows writing text to create “tags” that are represented in the shape of labels.
| install | yarn add @clayui/multi-select |
|---|---|
| version | |
| use | import MultiSelect from '@clayui/multi-select'; |
Table of Contents
Multi Select is an aggregate component of the @clayui/form package, consisting of a high-level written above a <ClayInput /> that provides the ability to create tags.
import {Provider} from '@clayui/core'; import MultiSelect from '@clayui/multi-select'; import React from 'react'; export default function App() { const [value, setValue] = React.useState(''); const [items, setItems] = React.useState([ { label: 'one', value: '1', }, ]); return ( <Provider spritemap="/icons.svg"> <div className="p-4"> <MultiSelect inputName="myInput" items={items} onChange={setValue} onItemsChange={setItems} value={value} /> </div> </Provider> ); }
Composing
<ClayMultiSelect /> enables you to make compositions to achieve your expected results, as this component is distributed only in a low level component, this increases flexibility and you can create many possibilities but it comes with a price tag… you may want to get close to the Lexicon specifications and will have to compose with some of the other components to get there, let’s detail it further below.
Autocomplete
Usually a MultiSelect has an autocomplete to help the user choose existing tags. You can use the sourceItems API to achieve this result.
import {Provider} from '@clayui/core'; import MultiSelect from '@clayui/multi-select'; import React from 'react'; export default function App() { const [value, setValue] = React.useState(''); const [items, setItems] = React.useState([ { label: 'one', value: '1', }, ]); const sourceItems = [ { label: 'one', value: '1', }, { label: 'two', value: '2', }, { label: 'three', value: '3', }, { label: 'four', value: '4', }, ]; return ( <Provider spritemap="/icons.svg"> <div className="p-4"> <MultiSelect inputName="myInput" items={items} onChange={setValue} onItemsChange={setItems} sourceItems={sourceItems} value={value} /> </div> </Provider> ); }
Select Button
According to the Lexicon specification a Select button can be grouped with MultiSelect to allow tag data to come from elsewhere. You can achieve this result by composing with <ClayForm.Group />, <ClayInput.GroupItem /> and <ClayButton /> .
import {Provider} from '@clayui/core'; import MultiSelect from '@clayui/multi-select'; import ClayForm, {ClayInput} from '@clayui/form'; import Button from '@clayui/button'; import React from 'react'; export default function App() { const [value, setValue] = React.useState(''); const [items, setItems] = React.useState([ { label: 'one', value: '1', }, ]); const sourceItems = [ { label: 'one', value: '1', }, { label: 'two', value: '2', }, { label: 'three', value: '3', }, { label: 'four', value: '4', }, ]; return ( <Provider spritemap="/icons.svg"> <div className="p-4"> <ClayForm.Group> <ClayInput.Group> <ClayInput.GroupItem> <MultiSelect inputName="myInput" items={items} onChange={setValue} onItemsChange={setItems} sourceItems={sourceItems} value={value} /> </ClayInput.GroupItem> <ClayInput.GroupItem shrink> <Button displayType="secondary" onClick={() => alert('Click')}> {'Select'} </Button> </ClayInput.GroupItem> </ClayInput.Group> </ClayForm.Group> </div> </Provider> ); }
Validation
An input needs validation so you can add some composition props with <ClayInput /> and <ClayForm /> to get the result.
import {Provider} from '@clayui/core'; import MultiSelect from '@clayui/multi-select'; import ClayForm, {ClayInput} from '@clayui/form'; import Button from '@clayui/button'; import React from 'react'; export default function App() { const [value, setValue] = React.useState(''); const [items, setItems] = React.useState([ { label: 'one', value: '1', }, ]); const sourceItems = [ { label: 'one', value: '1', }, { label: 'two', value: '2', }, { label: 'three', value: '3', }, { label: 'four', value: '4', }, ]; return ( <Provider spritemap="/icons.svg"> <div className="p-4"> <ClayForm.Group className="has-error"> <label>{'MultiSelect'}</label> <ClayInput.Group> <ClayInput.GroupItem> <MultiSelect inputName="myInput" items={items} onChange={setValue} onItemsChange={setItems} sourceItems={sourceItems} value={value} /> <ClayForm.FeedbackGroup> <ClayForm.FeedbackItem> <ClayForm.FeedbackIndicator symbol="info-circle" /> {'You made an error'} </ClayForm.FeedbackItem> </ClayForm.FeedbackGroup> </ClayInput.GroupItem> <ClayInput.GroupItem shrink> <Button displayType="secondary" onClick={() => alert('Click')}> {'Select'} </Button> </ClayInput.GroupItem> </ClayInput.Group> </ClayForm.Group> </div> </Provider> ); }
Custom Autocomplete
To customize Autocomplete content to stylize to your needs and also have filter control, you can use the menuRenderer API.
import {Provider} from '@clayui/core'; import MultiSelect from '@clayui/multi-select'; import Icon from '@clayui/icon'; import React from 'react'; export default function App() { const [value, setValue] = React.useState(''); const [items, setItems] = React.useState([ { email: 'one@example.com', label: 'One', value: '1', }, ]); const sourceItems = [ { email: 'one@example.com', label: 'One', value: '1', }, { email: 'two@example.com', label: 'Two', value: '2', }, ]; return ( <Provider spritemap="/icons.svg"> <div className="p-4"> <MultiSelect inputName="myInput" items={items} onChange={setValue} onItemsChange={setItems} sourceItems={sourceItems} value={value} > {(item) => ( <MultiSelect.Item key={item.value} textValue={item.label}> <div className="autofit-row autofit-row-center"> <div className="autofit-col mr-3"> <Sticker className="sticker-user-icon" size="lg"> <Icon symbol="user" /> </Sticker> </div> <div className="autofit-col"> <strong>{item.label}</strong> <span>{item.email}</span> </div> </div> </MultiSelect.Item> )} </MultiSelect> </div> </Provider> ); }
Sizes
The size property on ClayMultiSelect only modifies the size of the input.
Small
Render a smaller ClayMultiSelect input by setting the size property to sm.
import {Provider} from '@clayui/core'; import MultiSelect from '@clayui/multi-select'; import React from 'react'; export default function App() { const [value, setValue] = React.useState(''); const [items, setItems] = React.useState([ { label: 'one', value: '1', }, ]); return ( <Provider spritemap="/icons.svg"> <div className="p-4"> <MultiSelect inputName="multiSelectSmallInput" items={items} onChange={setValue} onItemsChange={setItems} size="sm" value={value} /> </div> </Provider> ); }
ClayMultiSelect’s with the Select Button should use the modifier class input-group-sm on input-group or form-group-sm on form-group.
import {Provider} from '@clayui/core'; import MultiSelect from '@clayui/multi-select'; import ClayForm, {ClayInput} from '@clayui/form'; import Button from '@clayui/button'; import React from 'react'; export default function App() { const [value, setValue] = React.useState(''); const [items, setItems] = React.useState([ { label: 'one', value: '1', }, ]); const sourceItems = [ { label: 'one', value: '1', }, { label: 'two', value: '2', }, { label: 'three', value: '3', }, { label: 'four', value: '4', }, ]; return ( <Provider spritemap="/icons.svg"> <div className="p-4"> <ClayForm.Group> <ClayInput.Group className="input-group-sm"> <ClayInput.GroupItem> <MultiSelect inputName="myInput" items={items} onChange={setValue} onItemsChange={setItems} sourceItems={sourceItems} value={value} /> </ClayInput.GroupItem> <ClayInput.GroupItem shrink> <Button displayType="secondary" onClick={() => alert('Click')}> {'Select'} </Button> </ClayInput.GroupItem> </ClayInput.Group> </ClayForm.Group> </div> </Provider> ); }
API Reference
MultiSelect
ComponentParameters
props *
IProps<T> & React.RefAttributes<HTMLInputElement>active
boolean | undefinedFlag to indicate if menu is showing or not.
allowsCustomLabel
boolean | undefinedWhether MultiSelect allows an input value not corresponding to an item to be added.
alignmentByViewport
boolean | undefinedFlag to align the Autocomplete within the viewport.
clearAllTitle
string | undefinedTitle for the Clear All button.
closeButtonAriaLabel
string | undefinedAria label for the Close button of the labels.
defaultActive
boolean | undefinedThe initial value of the active state (uncontrolled).
defaultValue
string | undefinedProperty to set the default value (uncontrolled).
defaultItems
Array<T> | undefinedSet the default value of label items (uncontrolled).
direction
"bottom" | "top" | undefinedDirection the menu will render relative to the Autocomplete.
menuRenderer
MenuRenderer | undefinedAdds a component to replace the default component that renders
the content of the <ClayDropDown /> component.
disabled
boolean | undefinedFlag that indicates to disable all features of the component.
disabledClearAll
boolean | undefinedFlag to disabled Clear All functionality.
hotkeysDescription
string | undefinedDefines the description of hotkeys for the component, use this to handle internationalization.
inputName
string | undefinedValue used for each selected item’s hidden input name attribute
inputValue
string | undefinedValue of input
isLoading
boolean | undefinedFlag to indicate if loading icon should be rendered
isValid
boolean | undefinedFlag to indicate if input is valid or not
items
Array<T> | undefinedValues that display as label items (controlled).
liveRegion
{ added: string; removed: string; } | undefinedThe off-screen live region informs screen reader users the result of removing or adding a label.
locator
Locator | undefinedSets the name of the field to map the value/label of the item
messages
{ listCount?: string; listCountPlural?: string; loading: string; notFound: string; hotkeys: string; labelAdded: string; labelRemoved: string; } | undefinedMessages for autocomplete.
onActiveChange
InternalDispatch<boolean> | undefinedCallback for when the active state changes (controlled).
onClearAllButtonClick
(() => void) | undefinedCallback for when the clear all button is clicked
onChange
InternalDispatch<string> | undefinedCallback for when the input value changes (controlled).
onItemsChange
InternalDispatch<Array<T>> | undefinedCallback for when items are added or removed (controlled).
onLoadMore
(() => Promise<any> | null) | undefinedCallback is called when more items need to be loaded when the scroll reaches the bottom.
size
"sm" | null | undefinedDetermines the size of the Multi Select component.
sourceItems
Array<T> | null | undefinedList of pre-populated items that will show up in a dropdown menu
spritemap
string | undefinedPath to spritemap for clay icons
value
string | undefinedThe value property sets the current value (controlled).
loadingState
number | undefinedThe current state of Autocomplete current loading. Determines whether the loading indicator should be shown or not.
children *
React.ReactNode | ((item: T, index?: number) => React.ReactElement)Children content to render a dynamic or static content.
Returns
ReactElement<any, string | JSXElementConstructor<any>> | nullitemLabelFilter
(items: Array<Item>, _value: string, _locator?: string) => Array<Item>Utility used for filtering an array of items based off the locator which
is set to label by default.
Parameters
items *
Array<Item>_value *
string_locator *
string= "label"Returns
Item[]Item
React.ForwardRefExoticComponent<IProps & React.RefAttributes<HTMLLIElement>>Parameters
active
boolean | undefinedFlag that indicates if item is selected.
disabled
boolean | undefinedFlag that indicates if item is disabled or not.
href
string | undefinedPath for item to link to.
roleItem
string | undefinedSets the role accessibility property of the item. Set the item’s container (
) role use the role="" prop instead of roleItem="".spritemap
string | undefinedPath to icon spritemap from clay-css.
symbolLeft
string | undefinedFlag that indicates if there is an icon symbol on the left side.
symbolRight
string | undefinedFlag that indicates if there is an icon symbol on the right side.
children
React.ReactNodeThe item content.
innerRef
React.Ref<HTMLAnchorElement> | undefinedmatch
string | undefinedMatch is the string that will be compared with value.
value
string | undefinedValue is the string that will be compared to the characters of the match property.
textValue
string | undefinedSets a text value if the component’s content is not plain text. This value is used in the combobox element to show the selected option.
Returns
ReactElement<any, string | JSXElementConstructor<any>> | nullContributors
Last edited May 11, 2025 at 5:57:01 PM