XDSMultiSelector@xds/core · MultiSelector
Preview coming soon
Usage
A checkbox dropdown for selecting multiple values from a list. Selected items can display as a count, labels, or badges. Use it for filtering or when presenting a finite set of options where multiple choices are needed.Best practices
| Guidance | Practices |
|---|---|
| Do | Use for a moderate, finite set of options where multiple choices are needed. |
| Do | Enable search filtering when the list exceeds ~15 options. |
| Do | Enable select-all when most users will want all or nearly all options selected. |
| Don't | Use for single-value selection — use Selector instead. |
| Don't | Show more than ~20 options without enabling search. |
Import
tsimport {XDSMultiSelector} from '@xds/core/MultiSelector'
Props
| Prop | Type | Description |
|---|---|---|
labelrequired | string | Label text for accessibility. |
optionsrequired | XDSMultiSelectorOptionType[] | Array of items — strings, objects with value/label/icon/disabled, dividers, or sections. |
valuerequired | string[] | Currently selected values. |
onChangerequired | (value: string[]) => void | Callback fired when the selection changes. |
changeAction | (value: string[]) => void | Promise<void> | Async action on change. Fires after onChange. |
placeholder | string (default: 'Select...') | Placeholder text shown when no value is selected. |
size | 'sm' | 'md' | 'lg' (default: 'md') | Size variant for the selector. |
triggerDisplay | 'count' | 'labels' | 'badges' (default: 'count') | How to display selected items in the trigger. |
maxBadges | number (default: 3) | Maximum badges to show before "+N". Only for triggerDisplay="badges". |
hasSelectAll | boolean | Whether to show a select-all checkbox. |
selectAllLabel | string (default: 'Select all') | Label for the select-all checkbox. |
hasSearch | boolean | Whether to show a search input for filtering options. |
searchPlaceholder | string (default: 'Search...') | Placeholder text for the search input. |
isDisabled | boolean | Disables the selector. |
isLabelHidden | boolean | Visually hides the label while keeping it accessible. |
description | string | Helper text displayed below the label. |
isOptional | boolean | Marks the field as optional. |
isRequired | boolean | Marks the field as required. |
isLoading | boolean | Shows a loading spinner in the trigger. |
status | {type: 'error' | 'warning' | 'success', message?: string} | Validation status with an optional message. |
children | (option: XDSMultiSelectorOptionData) => ReactNode | Custom render function for each option in the dropdown. |
xstyle | StyleXStyles | StyleX styles for layout customization. Must be a stylex.create() value. |
Sub-components
MultiSelector is a compound component with 1 sub-component.XDSMultiSelector
Multi-select dropdown with checkboxes for choosing multiple items.| Prop | Type | Description |
|---|---|---|
labelrequired | string | Label text for accessibility. |
optionsrequired | XDSMultiSelectorOptionType[] | Array of items — strings, objects with value/label/icon/disabled, dividers, or sections. |
valuerequired | string[] | Currently selected values. |
onChangerequired | (value: string[]) => void | Callback fired when the selection changes. |
changeAction | (value: string[]) => void | Promise<void> | Async action on change. Fires after onChange. |
placeholder | string (default: 'Select...') | Placeholder text shown when no value is selected. |
size | 'sm' | 'md' | 'lg' (default: 'md') | Size variant for the selector. |
triggerDisplay | 'count' | 'labels' | 'badges' (default: 'count') | How to display selected items in the trigger. |
maxBadges | number (default: 3) | Maximum badges to show before "+N". Only for triggerDisplay="badges". |
hasSelectAll | boolean | Whether to show a select-all checkbox. |
selectAllLabel | string (default: 'Select all') | Label for the select-all checkbox. |
hasSearch | boolean | Whether to show a search input for filtering options. |
searchPlaceholder | string (default: 'Search...') | Placeholder text for the search input. |
isDisabled | boolean | Disables the selector. |
isLabelHidden | boolean | Visually hides the label while keeping it accessible. |
description | string | Helper text displayed below the label. |
isOptional | boolean | Marks the field as optional. |
isRequired | boolean | Marks the field as required. |
isLoading | boolean | Shows a loading spinner in the trigger. |
status | {type: 'error' | 'warning' | 'success', message?: string} | Validation status with an optional message. |
children | (option: XDSMultiSelectorOptionData) => ReactNode | Custom render function for each option in the dropdown. |
xstyle | StyleXStyles | StyleX styles for layout customization. Must be a stylex.create() value. |
Examples
Common configurations, variations, and states.MultiSelector — Column VisibilityColumn visibility toggle with hidden label, search, select-all, and selection count.
tsx'use client';import {useState} from 'react';import {XDSMultiSelector} from '@xds/core/MultiSelector';import {XDSCenter} from '@xds/core/Center';const allColumns = [{value: 'name', label: 'Name'},{value: 'email', label: 'Email'},{value: 'role', label: 'Role'},{value: 'status', label: 'Status'},{value: 'created', label: 'Created'},{value: 'updated', label: 'Updated'},{value: 'actions', label: 'Actions'},];export default function MultiSelectorColumnVisibilitySelector() {const [visible, setVisible] = useState<string[]>(['name','email','role','status',]);return (<XDSCenter width={300}><XDSMultiSelectorlabel="Columns"isLabelHiddenoptions={allColumns}value={visible}onChange={setVisible}hasSelectAllhasSearchtriggerDisplay="count"placeholder="Columns"/></XDSCenter>);}
MultiSelector — Form CompositionTwo multi-selectors in a form with required/optional states.
tsx'use client';import {useState} from 'react';import {XDSMultiSelector} from '@xds/core/MultiSelector';import {XDSVStack} from '@xds/core/Layout';import {XDSCenter} from '@xds/core/Center';export default function MultiSelectorForm() {const [columns, setColumns] = useState<string[]>(['name', 'email']);const [filters, setFilters] = useState<string[]>([]);return (<XDSCenter width={300}><XDSVStack gap={4}><XDSMultiSelectorlabel="Visible columns"description="Choose which columns to display in the table"options={[{value: 'name', label: 'Name'},{value: 'email', label: 'Email'},{value: 'role', label: 'Role'},{value: 'status', label: 'Status'},{value: 'created', label: 'Created at'},]}value={columns}onChange={setColumns}hasSelectAllisRequiredtriggerDisplay="labels"/><XDSMultiSelectorlabel="Status filter"description="Filter by status"options={['Active', 'Inactive', 'Pending', 'Archived']}value={filters}onChange={setFilters}isOptionaltriggerDisplay="badges"placeholder="All statuses"/></XDSVStack></XDSCenter>);}
MultiSelector — SearchableMulti-select with search filtering and select-all.
tsx'use client';import {useState} from 'react';import {XDSMultiSelector} from '@xds/core/MultiSelector';import {XDSCenter} from '@xds/core/Center';const countries = ['United States','United Kingdom','Canada','Australia','Germany','France','Japan','Brazil','India','Mexico',];export default function MultiSelectorSearchableMultiSelector() {const [value, setValue] = useState<string[]>([]);return (<XDSCenter width={300}><XDSMultiSelectorlabel="Countries"options={countries}value={value}onChange={setValue}hasSearchhasSelectAllplaceholder="Select countries..."/></XDSCenter>);}
MultiSelector — Sectioned PermissionsMulti-select with options grouped into labeled sections.
tsx'use client';import {useState} from 'react';import {XDSMultiSelector} from '@xds/core/MultiSelector';import {XDSCenter} from '@xds/core/Center';export default function MultiSelectorSectionedMultiSelector() {const [value, setValue] = useState<string[]>([]);return (<XDSCenter width={300}><XDSMultiSelectorlabel="Permissions"options={[{type: 'section',title: 'Read',options: [{value: 'read_posts', label: 'Read posts'},{value: 'read_comments', label: 'Read comments'},{value: 'read_users', label: 'Read users'},],},{type: 'section',title: 'Write',options: [{value: 'write_posts', label: 'Write posts'},{value: 'write_comments', label: 'Write comments'},],},]}value={value}onChange={setValue}placeholder="Select permissions..."/></XDSCenter>);}
Showcase source
tsximport {XDSMultiSelector} from '@xds/core/MultiSelector';export default function MultiSelectorShowcase() {return (<div style={{width: 300}}><XDSMultiSelectorlabel="Columns"isDefaultOpenoptions={['Name', 'Email', 'Role', 'Status', 'Created']}value={[]}onChange={() => {}}placeholder="Select columns..."/></div>);}