Skip to content

Multiselect

Usage

Multiselect allows users to make a single selection or multiple selections from a list of options. This component is generic and can be used with text or number values.

Types

Multiselect consists of two independently configurable dimensions: Selection display types and Dropdown types.

  1. Selection display types
    Define how selected options are displayed inside the component:
  • Chips
    • Each selected option is represented as an individual chip (lozenge).
    • If all selected options fit, they are displayed in full inside the container.
    • If they do not fit, the overflow is represented by an additional indicator chip (e.g. “+3”), showing the number of hidden selections.
    • The content of the container remains unchanged when the dropdown is opened.
  • Searchable Counter
    • When the component is collapsed (closed), it displays a single lozenge summarizing the number of selected options (e.g. “3 item(s) selected”).
    • When the component is expanded (open), the summary lozenge is replaced by a Search input. Users can type into this field to filter the options visible in the dropdown.
    • Individual selections are not displayed in the container, only in the dropdown.
  1. Dropdown types
    Define how the list of options behaves and is displayed:
  • Checkbox position
    • Leading – Checkboxes appear at the start (leading side) of each option row.
    • Trailing – Checkboxes appear at the end (trailing side) of each option row.
  • Selection behavior
    • Static – selected options remain in their original position in the list.
    • Selected on top – selected options are automatically moved to the top of the list, separated from unselected ones by a Divider. Both groups are sorted alphabetically.
  1. Combinations Selection display types and dropdown types can be freely combined. Examples:
  • Chips + Leading checkbox + Static dropdown
  • Chips + Trailing checkbox + Reordered dropdown
  • Searchable Counter + Leading checkbox + Reordered dropdown
  • Searchable Counter + Trailing checkbox + Static dropdown

Form Label (compact) in Select component can be placed either Label Up or Label Left, creating two variations of component usage.

Anatomy and Behavior

  1. Container - the clickable area of the component. When empty, it displays a placeholder with helper text. Once the user interacts, the container either shows selected items (Chips type) or a counter (Searchable Counter type). Clicking the container opens the dropdown.

  2. Label - Is a Form label (compact) component nested inside Select component. It can be positioned above (Label Up) or to the left (Label Left) of the container.

  3. Selected option/s display

    • Chips - Selected options are displayed as individual lozenges without icons. Each lozenge represents one selected item. When nothing is selected, a placeholder is shown with helper text describing the expected input. If a lozenge is too long for the container, its text is truncated. If too many lozenges are selected and they cannot all fit into the container, the overflow is represented by an additional indicator lozenge (e.g. “+3”), showing the number of hidden selections.
    • Searchable Counter - When the component is collapsed, the container shows a single lozenge summarizing the number of selected options (e.g. “3 selected”). When expanded, the lozenge is replaced by a Search input that allows users to filter options in the dropdown. Individual selections are not displayed in the container but remain visible in the dropdown.
  4. Arrow - Is a nested Icon component (chevron).

  5. Additional selected options - When there are more options selected than fit in the container, view-only text is displayed indicating the number of selected options that are hidden (Chips type only).

  6. Dropdown menu - the dropdown displays the list of available options. As a general rule, only 6–10 options are visible at once; additional items can be accessed by scrolling. The dropdown can behave in different ways depending on configuration:

    • Selection behavior
      • Static – selected options remain in their original position in the list.
      • Selected on top – selected options are automatically moved to the top of the list, separated from unselected options by a Divider. Both groups are sorted alphabetically.
    • Checkbox position
      • Leading – checkboxes are placed on the leading side (start of each row).
      • Trailing – checkboxes are placed on the trailing side (end of each row).
    • Search filtering (only with Searchable Counter)
      • When the component is expanded, the counter lozenge in the container is replaced with a Search input.
      • Typing into this field filters the options shown in the dropdown in real time.
  7. Option - an option is one of the items in the dropdown menu. It is built using a Checkbox with text component.

    • Behavior
      • Clicking on an option toggles its state between selected (checked) and unselected (unchecked).
      • If the option label is longer than the available width, the text is truncated. The full label is available through the native Title attribute.
    • Configuration
      • Checkbox position – the checkbox can be displayed on either the leading or the trailing side of the option row, depending on the dropdown type.
      • Selection behavior –
        • Static: the option remains in its original place after being selected.
        • Selected on top: when selected, the option moves into the top group of the list; when deselected, it returns to the unselected group. The groups are separated by a Divider and sorted alphabetically.
  8. Scrollbar - Is a Scrollbar (tiny) component nested inside Select component. Scrollbar is used only when we have more options than those visible in in a dropdown menu.

Behavior

  • Pressing Tab focuses the component.
  • Pressing Enter when the component is focused opens the dropdown.
  • Arrow keys navigate through the list of options.
  • Pressing Enter while an option is highlighted selects or deselects it, without closing the dropdown.
  • Pressing Tab again moves focus to the next component in the UI.
  • Pressing Shift+Tab when browsing the options returns focus to the container.
  • Chips
    • Selected options remain visible in the container as chips.
    • If overflow occurs, the number of hidden selections is represented by the “+N” indicator.
  • Searchable Counter
    • When expanded, the counter lozenge is replaced by a Search input. Typing in this field dynamically filters the options visible in the dropdown.
  • Dropdown selection behavior (applies to all types)
    • Depending on configuration, selected options either remain in their original place (Static) or are moved to the top group (Selected on top).
    • In the Selected on top mode, selected items are separated from unselected ones by a Divider, and both groups are sorted alphabetically.

States

Multiselect can be Open or Closed and the Container has :hover, :active, :focus, Disabled states. Option within the Dropdown menu can be :hover, :active, :focus, Disabled and Selected.

Gaps and Sizes

  • Container width: Fill the parent container

  • Container height: XL+ (Fixed)

  • Gap between container and dropdown: 2XS

  • Arrow width and height: M

  • Additional selected options width: Hugs text

  • Additional selected options height: M

  • Gap between Arrow and Additional selected options: XS

  • Gap between Lozenge: XS

  • Padding to scrollbar: XS

  • Content vertically center aligned

  • Arrow is right aligned

  • Gap between contents (Placeholder / selected option and Arrow): max. space between, min. XS

  • Container padding horizontal: S

  • Option width: Fills dropdown

  • Option height: L+

  • Gap between options: Null

  • Option Internal vertical padding: XS

  • Option Internal horizontal padding: S

Recommendations for Designers Minimum container width: 5XL

Tokens

SCSS Variable
Value
$multiselect-bgColor
--color-grey-93
$multiselect-placeholder-color
--color-grey-70
$multiselect-placeholder-color--locked
--color-grey-80
$multiselect-selected-color
--color-grey-25
$multiselect-arrow-color
--bds-brand-primary-color
$multiselect-arrow-color--locked
--color-grey-70
$multiselect-outline-color--focus
--color-azure-45
$multiselect-outline-color--locked
--color-grey-86
$multiselect-dropdown-bgColor
--color-grey-93
$multiselect-option-color
--color-grey-25
$multiselect-option-color--locked
--color-grey-70
$multiselect-option-bgColor--locked
--color-grey-90
$multiselect-option-bgColor--hover
--color-grey-90
$multiselect-option-bgColor--selected
--primary-bgColor-selected
$multiselect-divider-color
--color-grey-80
$multiselect-boxShadow
--debossed-1--grey-95
$multiselect-boxShadow--hover
--debossed-2--grey-95
$multiselect-boxShadow--locked
none
$multiselect-dropdown-boxShadow
--elevation-4
$multiselect-padding
--gutter-s

Properties

ts
export interface MultiselectGenericProps<T extends string | number> extends FormLabelOptionalProps {
  modelValue: T[] | null;
  selectionBehavior?: 'static' | 'selectedOnTop';
  options: MultiselectOptionGeneric<T>[];
  placeholder?: string;
  checkboxPosition?: 'leading' | 'trailing';
  disabled?: boolean;
  id?: string;
  icon?: IconName;
  action?: MultiselectActionGeneric<T>;
  // if set to 0, all options will be shown, default: 0
  noOfOptionsToShow?: number;
  // determine to group options by their disabled state or whether they are selected
  groupOptionsBy?: 'disabled' | 'selected';
  animateGrouping?: boolean;
  sortOptions?: MultiSortOptions<'alphabetical' | 'numerical'>;
  searchOptions?: MultiSearchOptions;
}

export interface MultiSortOptions<T extends 'alphabetical' | 'numerical'> {
  type: T;
  order: 'asc' | 'ascending' | 'desc' | 'descending';
  target: 'text' | 'value';
  ignoreCase: T extends 'alphabetical' ? boolean : never;
}

export interface MultiSearchOptions {
  enableSearch: boolean;
  caseSensitive?: boolean;
  placeholder?: string;
}
ts
export interface MultiselectOptionGeneric<T extends string | number> {
  text: string | number;
  value: T;
  isSelected: boolean;
  isDisabled?: boolean;
  hasAction?: boolean;
}
ts
export interface MultiselectActionGeneric<T extends string | number> {
  text: string;
  icon: IconName;
  function: (option: MultiselectOptionGeneric<T>) => Promise<void>;
}

ModelValues

For more information on ModelValues please have a look to the Vue's Data Binding section.

vue
const searchString = defineModel('searchString', { default: '' });