Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelogApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UIARC Radiant Components
v4.9DocsComponentsTokensSynthesizer
Getting StartedFrameworksServer RenderingDesign TokensThemingTheme SynthesizerTypographyUtilitiesAll ComponentsAccessibilityBrowser SupportChangelogContributingStatsApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Multi Select

Multi-value select with tag chips, inline search filtering, and keyboard navigation.

ComponentsMulti Select
inputinteractive
<arc-multi-select>

Overview

MultiSelect is a form control that allows users to choose multiple values from a predefined list of options. Selected items appear as removable tag chips inside the control, showing what has been chosen. The inline text input doubles as a filter: typing narrows the dropdown to matching options, so it stays quick to use with large option sets. Options are provided declaratively using `<arc-option>` child elements, each with a `value` and visible label. The dropdown opens on focus and filters in real time as the user types. Items can be toggled on and off by clicking or via keyboard navigation with ArrowUp/ArrowDown and Enter. Pressing Backspace when the text input is empty removes the last selected tag, providing a natural editing flow. MultiSelect fires an `arc-change` event whenever the selection changes, with the current value array in the event detail. The component handles outside-click dismissal automatically and exposes CSS parts for `control`, `tag`, `input`, `dropdown`, and `option` to support targeted style customisation.

Guidelines

When to use

  • Always provide a `label` so the field is accessible to screen readers
  • Use a descriptive `placeholder` to hint at expected input, such as "Choose languages..."
  • Keep option labels concise so they display well as tags inside the control
  • Listen to `arc-change` to react to selection changes and keep external state in sync
  • Pre-populate the `value` array when editing existing records to show current selections

When not to use

  • Do not use MultiSelect when only a single value is needed. Use Select instead
  • Do not provide more than ~50 options without also considering server-side filtering via arc-change
  • Do not use extremely long option labels. They will overflow the tag chips and the dropdown
  • Do not set both `disabled` and a pre-selected `value` without a clear visual explanation of why editing is blocked
  • Avoid nesting MultiSelect inside a popover or modal without testing z-index stacking for the dropdown

Features

  • Selected values rendered as removable pill-shaped tag chips inside the control area
  • Inline type-ahead filtering that narrows the dropdown options in real time
  • Full keyboard navigation: ArrowUp/Down to move, Enter to select, Escape to close, Backspace to remove the last tag
  • Check marks next to already-selected options in the dropdown for clear state indication
  • Declarative options via `<arc-option>` child elements with `value` and `label` attributes
  • Automatic outside-click dismissal of the dropdown panel
  • Focus glow on the control using the shared `--focus-glow` design token
  • "No results found" empty state when the filter query matches no options

Preview

React Vue Angular Svelte Lit

Usage

This component requires JavaScript. No pure HTML/CSS version is available. Use the Web Component directly or a framework wrapper.

<arc-multi-select label="Languages" placeholder="Choose...">
  <arc-option value="js">JavaScript</arc-option>
  <arc-option value="ts">TypeScript</arc-option>
  <arc-option value="py">Python</arc-option>
</arc-multi-select>

API

placeholderstring''
Hint text shown inside the control when no items are selected and the input is empty.
labelstring''
Visible label rendered above the control in a small uppercase style.
namestring''
disabledbooleanfalse
Disables the control, preventing interaction and reducing opacity to 50%.
valuestring[][]
Array of selected option values. Updated when items are toggled and emitted via arc-change.
readonlybooleanfalse
Prevents toggling options or removing chips while the control stays focusable; the dropdown can still be opened for viewing and the values still submit.
size'sm' | 'md' | 'lg''md'
Control size. md is the default; sm and lg scale the control height and padding.
formAssociatedbooleantrue
propertiesobject{ // flag(), unlike `disabled`. The exclusion in props.js is specifically // about form-associated *platform* semantics: a `disabled` content // attribute that is merely present makes the element actually disabled // per the HTML spec, and formDisabledCallback assigns the property back, // so no converter can win. Neither of these is platform-mapped: // `required` is enforced by _computeValidity() below and `readonly` by // each component's own interaction handlers, so the stock converter buys // nothing here and costs the usual bug: `required="false"` read as true, // blocking submission of a form the author meant to leave optional. // Finding #48's shape, across all 26 form controls at once. required: flag(false), readonly: flag(false), }
Lit merges static properties up the prototype chain, so every consumer gets these without declaring them. required participates in constraint validation below; readonly reflects for styling and is enforced by each component's interaction handlers (the mixin can't know which gestures mutate state).
autoValidatesbooleantrue
Components that run their own constraint-validation logic (pattern checks, range checks) opt out of the automatic required sync by overriding this to false, and own the whole validity flag set instead.
form
validity
validationMessage
requiredbooleanfalse

Methods

checkValidity()boolean
Whether the control currently satisfies its constraints, per the native constraint-validation API. Fires invalid on the element when it does not, and reports nothing to the user.
reportValidity()boolean
As checkValidity(), but also shows the browser's validation message against the control when it fails.

Events

arc-changedetail:{ value: string[] }
Fired when the selected values change
arc-inputdetail:{ value: string }
Fired on every keystroke in the filter input. event.detail.value contains the current query text.

See Also