Import
import { Field } from '@dnb/eufemia/extensions/forms'render(<Field.MultiSelection />)
Description
Field.MultiSelection is a component for selecting multiple items from a fixed set with a confirmation flow. The selection interface appears in a popover overlay, keeping your form layout clean.
This is ideal when users need to:
- Browse and filter through many options.
- See their selections clearly before confirming.
- Cancel and discard changes without applying them.
- Work with structured data beyond simple strings.
import { Field } from '@dnb/eufemia/extensions/forms'const data = [{value: 'option1',title: 'Option 1',text: 'Text',description: 'Description',},{ value: 'option2', title: 'Option 2', text: 'Text' },{ value: 'option3', title: 'Option 3', description: 'Description' },]render(<Field.MultiSelectionlabel="Select items"data={data}showSearchFieldshowSelectedTags/>)
Using with dataPath
You can also use the dataPath property to provide the data from the Form context:
import { Field, Form } from '@dnb/eufemia/extensions/forms'render(<Form.Handlerdata={{myItems: [{ value: 'oslo', title: 'Oslo', text: 'Capital of Norway' },{value: 'stockholm',title: 'Stockholm',text: 'Capital of Sweden',},{value: 'copenhagen',title: 'Copenhagen',text: 'Capital of Denmark',},],}}><Field.MultiSelectionlabel="Select cities"dataPath="/myItems"showSearchFieldshowSelectedTags/></Form.Handler>)
Features
Popover Interface
The selection interface appears in a popover overlay, keeping your form clean and maintaining focus on the current field. Click the trigger button to open the selection interface, showing the search field, items list, and action buttons.
Selected Items Display
Shows currently selected items as removable tags when showSelectedTags is enabled.
Collapsible Selected Items (selectedItemsCollapsibleThreshold)
When showSelectedTags is enabled and the total number of available items exceeds selectedItemsCollapsibleThreshold (default: 20), the selected items are hidden by default and a collapsible header appears with two controls:
- Toggle button: Shows the count of selected items relative to the total (e.g. "22 of 30 selected") with a rotating chevron icon. Announces its state to screen readers via
aria-expanded. Click to expand or collapse the tag list. - Clear all button: A tertiary button with a close icon that deselects all items at once. Hidden when nothing is selected.
The tag list expands and collapses with a smooth height animation.
Set selectedItemsCollapsibleThreshold to a custom number to control when the collapsible header kicks in:
<Field.MultiSelectionshowSelectedTagsselectedItemsCollapsibleThreshold={10}{/* ... */}/>
Search Functionality
When showSearchField is enabled, users can filter through items by typing in the search field. The filtering applies to both the item title and text and description.
Item Details
Each item can include optional text and description content below the main title. text renders as black primary lines, while description renders as grey secondary lines.
Disabled Items
Individual items can be disabled by setting their disabled property to true.
Confirmation Flow
When showConfirmButton is enabled, users must click "Confirm selection" to apply changes, or "Cancel" to discard them without modifying the form value.
Accessibility
Keyboard interaction
| Key | Behavior |
|---|---|
Enter / Space | Opens or closes the popover when the trigger button is focused. Toggles an item when a checkbox is focused. |
ArrowDown | When the trigger is focused: opens the popover and moves focus to the first checkbox. When inside the popover: moves focus to the next checkbox. |
ArrowUp | When the trigger is focused: opens the popover and moves focus to the last checkbox. When inside the popover: moves focus to the previous checkbox. |
Escape | Closes the popover and discards any pending changes (same as Cancel). |
Tab | Moves focus through the interactive elements inside the popover (search field, checkboxes, confirm/cancel buttons). |
Screen reader announcements
- The trigger button exposes the current selection count via
aria-describedby. Screen readers will read e.g. "2 of 5 selected" when the button receives focus. - After each checkbox toggle (or tag removal), a live region (
aria-live="assertive") announces the updated count, e.g. "3 of 5 selected". This announcement does not fire when the popover is closed via Cancel, since changes are discarded. - The trigger button uses
role="combobox"witharia-haspopup="listbox"so assistive technologies describe it as a combobox that opens a list. - Each checkbox announces its own checked/unchecked state natively. No duplicate descriptions are added.
- Nested item groups are rendered as sibling
<ul>elements after their parent<li>, so assistive technologies announce them as a new list level (e.g. "list, 3 items, level 2").
Focus management
- Opening the popover with the mouse moves focus to the popover content area so arrow-key navigation works immediately.
- Opening the popover with
ArrowDownmoves focus directly to the first checkbox;ArrowUpmoves focus to the last checkbox. - During keyboard navigation inside the popover, the focused item is automatically scrolled into view.
- Closing the popover (confirm, cancel, or Escape) returns focus to the trigger button.
Semantic structure
- The item list is rendered as a
<ul>with each option as an<li>, giving assistive technologies correct list semantics. - Nested item groups use a child
<ul>inside the parent<li>. - The field label is linked to the trigger button via a
<label for="…">relationship provided byFieldBlock.
Relevant links
Demos
Basic
const cities = [ { value: 'oslo', title: 'Oslo', description: 'Capital of Norway', }, { value: 'stockholm', title: 'Stockholm', description: 'Capital of Sweden', }, { value: 'copenhagen', title: 'Copenhagen', description: 'Capital of Denmark', }, { value: 'helsinki', title: 'Helsinki', description: 'Capital of Finland', }, { value: 'reykjavik', title: 'Reykjavik', description: 'Capital of Iceland', }, ] render(<Field.MultiSelection label="Select cities" data={cities} />)
With Select all
This example uses field width medium.
const cities = [ { value: 'oslo', title: 'Oslo', text: 'Capital of Norway', }, { value: 'stockholm', title: 'Stockholm', text: 'Capital of Sweden', }, { value: 'copenhagen', title: 'Copenhagen', text: 'Capital of Denmark', }, { value: 'helsinki', title: 'Helsinki', text: 'Capital of Finland', }, { value: 'reykjavik', title: 'Reykjavik', text: 'Capital of Iceland', }, ] render( <Field.MultiSelection label="Select cities" data={cities} showSelectAll width="medium" /> )
With search
render( <Field.MultiSelection label="Select fruits" data={fruits} showSearchField /> )
With confirm and cancel
const cities = [ { value: 'oslo', title: 'Oslo', text: 'Capital of Norway', }, { value: 'stockholm', title: 'Stockholm', text: 'Capital of Sweden', }, { value: 'copenhagen', title: 'Copenhagen', text: 'Capital of Denmark', }, { value: 'helsinki', title: 'Helsinki', text: 'Capital of Finland', }, { value: 'reykjavik', title: 'Reykjavik', text: 'Capital of Iceland', }, ] render( <Field.MultiSelection label="Select cities" data={cities} showSearchField showSelectAll showConfirmButton /> )
With nested items
<Field.MultiSelection label="Select regions" showSelectAll data={[ { value: 'scandinavia', title: 'Scandinavia', children: [ { value: 'oslo', title: 'Oslo', text: 'Capital of Norway', }, { value: 'stockholm', title: 'Stockholm', text: 'Capital of Sweden', }, { value: 'copenhagen', title: 'Copenhagen', text: 'Capital of Denmark', }, ], }, { value: 'nordic', title: 'Other Nordic', children: [ { value: 'helsinki', title: 'Helsinki', text: 'Capital of Finland', }, { value: 'reykjavik', title: 'Reykjavik', text: 'Capital of Iceland', }, ], }, ]} />
With selected item tags
const cities = [ { value: 'oslo', title: 'Oslo', text: 'Capital of Norway', }, { value: 'stockholm', title: 'Stockholm', text: 'Capital of Sweden', }, { value: 'copenhagen', title: 'Copenhagen', text: 'Capital of Denmark', }, { value: 'helsinki', title: 'Helsinki', text: 'Capital of Finland', }, { value: 'reykjavik', title: 'Reykjavik', text: 'Capital of Iceland', }, ] render( <Field.MultiSelection label="Select cities" data={cities} value={['stockholm']} showSelectedTags /> )
With many selected items
When showSelectedTags is enabled and the number of items exceeds the selectedItemsCollapsibleThreshold (default: 10), an accordion appears to collapse/expand the selected items. A "Clear all" button also appears to the right for quickly deselecting all items.
const items = Array.from( { length: 30, }, (_, i) => ({ value: `item${i + 1}`, title: `Item ${i + 1}`, description: `Description for item ${i + 1}`, }) ) render( <Field.MultiSelection label="Select items" data={items} value={items.slice(0, 25).map((item) => item.value)} showSelectedTags showSelectAll showSearchField /> )
With disabled items
<Field.MultiSelection label="Select available languages" data={[ { value: 'nodejs', title: 'Node.js', text: 'JavaScript runtime', }, { value: 'python', title: 'Python', text: 'General purpose language', disabled: true, }, { value: 'rust', title: 'Rust', text: 'Systems programming language', }, { value: 'golang', title: 'Go', text: 'Compiled language', disabled: true, }, { value: 'java', title: 'Java', text: 'Enterprise language', }, ]} />
Inline variant
The inline variant renders the item list inline without a popover. This is useful when you want the options to be always visible.
const cities = [ { value: 'oslo', title: 'Oslo', }, { value: 'stockholm', title: 'Stockholm', }, { value: 'copenhagen', title: 'Copenhagen', }, { value: 'helsinki', title: 'Helsinki', }, { value: 'reykjavik', title: 'Reykjavik', }, ] render( <Field.MultiSelection label="Select cities" variant="inline" value={['stockholm']} data={cities} showSelectAll showSearchField showSelectedTags /> )
Using dataPath from Form context
<Form.Handler data={{ colors: [ { value: 'red', title: 'Red', text: 'Primary color', }, { value: 'green', title: 'Green', text: 'Secondary color', }, { value: 'blue', title: 'Blue', text: 'Tertiary color', }, { value: 'yellow', title: 'Yellow', text: 'Accent color', }, ], }} > <Field.MultiSelection label="Select colors" dataPath="/colors" value={['red']} help={{ title: 'Help text', content: 'Additional information about this field', }} /> </Form.Handler>
Disabled field
const cities = [ { value: 'oslo', title: 'Oslo', text: 'Capital of Norway', }, { value: 'stockholm', title: 'Stockholm', text: 'Capital of Sweden', }, { value: 'copenhagen', title: 'Copenhagen', text: 'Capital of Denmark', }, { value: 'helsinki', title: 'Helsinki', text: 'Capital of Finland', }, { value: 'reykjavik', title: 'Reykjavik', text: 'Capital of Iceland', }, ] render( <Field.MultiSelection label="Disabled field" disabled data={cities} /> )
With minimum required items
const cities = [ { value: 'oslo', title: 'Oslo', text: 'Capital of Norway', }, { value: 'stockholm', title: 'Stockholm', text: 'Capital of Sweden', }, { value: 'copenhagen', title: 'Copenhagen', text: 'Capital of Denmark', }, { value: 'helsinki', title: 'Helsinki', text: 'Capital of Finland', }, { value: 'reykjavik', title: 'Reykjavik', text: 'Capital of Iceland', }, ] render( <Form.Handler> <Form.Card> <Field.MultiSelection label="Select cities" path="/cities" required minItems={2} data={cities} showSearchField showSelectedTags /> <Form.SubmitButton /> </Form.Card> </Form.Handler> )