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
Component
Parameters
props *
IProps<T> & React.RefAttributes<HTMLInputElement>
active
boolean | undefined
Flag to indicate if menu is showing or not.
allowsCustomLabel
boolean | undefined
Whether MultiSelect allows an input value not corresponding to an item to be added.
alignmentByViewport
boolean | undefined
Flag to align the Autocomplete within the viewport.
clearAllTitle
string | undefined
Title for the Clear All
button.
closeButtonAriaLabel
string | undefined
Aria label for the Close button of the labels.
defaultActive
boolean | undefined
The initial value of the active state (uncontrolled).
defaultValue
string | undefined
Property to set the default value (uncontrolled).
defaultItems
Array<T> | undefined
Set the default value of label items (uncontrolled).
direction
"bottom" | "top" | undefined
Direction the menu will render relative to the Autocomplete.
menuRenderer
MenuRenderer | undefined
Adds a component to replace the default component that renders
the content of the <ClayDropDown />
component.
disabled
boolean | undefined
Flag that indicates to disable all features of the component.
disabledClearAll
boolean | undefined
Flag to disabled Clear All functionality.
hotkeysDescription
string | undefined
Defines the description of hotkeys for the component, use this to handle internationalization.
inputName
string | undefined
Value used for each selected item’s hidden input name attribute
inputValue
string | undefined
Value of input
isLoading
boolean | undefined
Flag to indicate if loading icon should be rendered
isValid
boolean | undefined
Flag to indicate if input is valid or not
items
Array<T> | undefined
Values that display as label items (controlled).
liveRegion
{ added: string; removed: string; } | undefined
The off-screen live region informs screen reader users the result of removing or adding a label.
locator
Locator | undefined
Sets 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; } | undefined
Messages for autocomplete.
onActiveChange
InternalDispatch<boolean> | undefined
Callback for when the active state changes (controlled).
onClearAllButtonClick
(() => void) | undefined
Callback for when the clear all button is clicked
onChange
InternalDispatch<string> | undefined
Callback for when the input value changes (controlled).
onItemsChange
InternalDispatch<Array<T>> | undefined
Callback for when items are added or removed (controlled).
onLoadMore
(() => Promise<any> | null) | undefined
Callback is called when more items need to be loaded when the scroll reaches the bottom.
size
"sm" | null | undefined
Determines the size of the Multi Select component.
sourceItems
Array<T> | null | undefined
List of pre-populated items that will show up in a dropdown menu
spritemap
string | undefined
Path to spritemap for clay icons
value
string | undefined
The value property sets the current value (controlled).
loadingState
number | undefined
The 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 | undefined
Flag that indicates if item is selected.
disabled
boolean | undefined
Flag that indicates if item is disabled or not.
href
string | undefined
Path for item to link to.
roleItem
string | undefined
Sets the role accessibility property of the item. Set the item’s container (
) role use the role="" prop instead of roleItem="".spritemap
string | undefined
Path to icon spritemap from clay-css.
symbolLeft
string | undefined
Flag that indicates if there is an icon symbol on the left side.
symbolRight
string | undefined
Flag that indicates if there is an icon symbol on the right side.
children
React.ReactNode
The item content.
innerRef
React.Ref<HTMLAnchorElement> | undefined
match
string | undefined
Match is the string that will be compared with value.
value
string | undefined
Value is the string that will be compared to the characters of the match property.
textValue
string | undefined
Sets 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