Forms
MultiSelect
A fully accessible multi-select component with chips/tags display, following WAI-ARIA 1.2 listbox pattern. Supports searchable options, grouped options, and comprehensive keyboard navigation. Perfect for selecting multiple service types, diagnoses, or medications.
Basic Usage
Select multiple items from a list. Selected items appear as removable chips.
Searchable
Enable search to filter through large option lists. Great for diagnosis codes or medication lookups.
Grouped Options
Organize options into logical groups for better navigation. Ideal for specialty directories or categorized lists.
With Maximum Selections
Limit the number of selections. Useful when only a fixed number of items can be chosen.
With Select All
Add a 'Select All' option for quick bulk selection. Shows count of available options.
Validation States
Display validation feedback with error and success states. Use validateOnMount to show state immediately.
Size Variants
Choose appropriate sizes based on form density and visual hierarchy.
Custom Rendering
Use snippets to customize chip and option appearance. Add icons, badges, or additional metadata.
Hint Visibility
By default, hint text appears only when the component is focused, paired with a ? icon in the label. Use alwaysShowHint to keep the hint permanently visible — the icon is automatically hidden. Ideal for complex fields where users benefit from always-on guidance.
Custom Empty State
Provide helpful empty states when no options match the search.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique identifier for the component |
name | string | — | Form field name |
label * | string | — | Label text for the field |
selected | MultiSelectOption[] | [] | Currently selected options (bindable) |
placeholder | string | 'Select options...' | Placeholder text when no selections |
options | MultiSelectOption[] | MultiSelectOptionGroup[] | [] | Options to display (flat or grouped) |
required | boolean | false | Whether the field is required |
disabled | boolean | false | Whether the field is disabled |
readonly | boolean | false | Whether the field is read-only |
error | string | — | Error message to display |
hint | string | — | Helper text — shown below on focus by default, always visible with alwaysShowHint |
alwaysShowHint | boolean | false | Always show hint text below the component (not just on focus). Hides the ? icon when enabled. |
alwaysShowFooter | boolean | false | Always render the footer area to prevent layout shift when hint or validation messages appear dynamically. |
successMessage | string | — | Success message when valid |
size | 'sm' | 'md' | 'lg' | 'md' | Size of the component |
hideLabel | boolean | false | Hide label visually (still accessible) |
searchable | boolean | false | Enable search/filter functionality |
searchPlaceholder | string | 'Search...' | Search input placeholder text |
maxSelections | number | — | Maximum number of selections allowed |
closeOnSelect | boolean | false | Close dropdown after each selection |
loading | boolean | false | Show loading spinner |
emptyMessage | string | 'No options found' | Message when no options match |
showSelectAll | boolean | false | Show "Select All" option |
selectAllLabel | string | 'Select All' | Label for "Select All" |
showCount | boolean | true | Show selected count badge |
chipContent | Snippet<[MultiSelectOption]> | — | Custom chip rendering |
optionContent | Snippet<[MultiSelectOption]> | — | Custom option rendering |
emptyContent | Snippet | — | Custom empty state content |
onchange | (selected: MultiSelectOption[]) => void | — | Called when selection changes |
onselect | (option: MultiSelectOption) => void | — | Called when option is selected |
ondeselect | (option: MultiSelectOption) => void | — | Called when option is deselected |
onsearch | (query: string) => void | — | Called when search query changes |
testId | string | — | Test ID for e2e testing |
validateOnMount | boolean | false | Show validation state immediately |
Types
interface MultiSelectOption {
value: string; // Unique identifier
label: string; // Display text
disabled?: boolean; // Option disabled state
description?: string; // Secondary text
metadata?: Record<string, unknown>; // Custom data
}
interface MultiSelectOptionGroup {
label: string; // Group header
options: MultiSelectOption[]; // Options in this group
}Keyboard Navigation
| Key | Action |
|---|---|
| ↓ | Open dropdown / Move to next option |
| ↑ | Move to previous option |
| Enter / Space | Toggle selection of highlighted option |
| Escape | Close dropdown |
| Home | Move to first option |
| End | Move to last option |
| ← | Navigate to chips (when in search input) |
| Backspace | Remove last chip (when search is empty) / Remove focused chip |
| Delete | Remove focused chip |
Healthcare Best Practices
- • Use descriptions to show additional context like ICD-10 codes, NDC numbers, or NPI identifiers
- • Enable search for large lists like medications (10,000+ NDCs) or diagnoses (70,000+ ICD-10 codes)
- • Group related options by category (e.g., specialties by type, medications by therapeutic class)
- • Set maxSelections when clinical workflows have limits (e.g., max 3 primary diagnoses)
- • Mark discontinued or unavailable options as disabled with clear visual indication
- • Use Select All carefully - consider if bulk selection makes clinical sense
- • Provide clear validation messages for required selections in clinical forms
- • Consider using closeOnSelect for single-item-at-a-time workflows
Accessibility Features
- • WAI-ARIA Listbox Pattern: Full implementation with aria-multiselectable, aria-selected, and grouped options
- • Keyboard Navigation: Complete arrow key, Home, End, Enter, Space, Escape, and Backspace support
- • Chip Navigation: Arrow keys to move between selected chips, Delete/Backspace to remove
- • Screen Reader Support: Announces selections, removals, option counts, and max limit reached
- • Focus Management: Maintains proper focus when adding/removing chips
- • Reduced Motion: Respects user's motion preferences for animations
- • Clear Labels: Proper labeling for chips, options, and controls