Forms

MultiSelect

Multi-value dropdown with checkbox options, optional filtering, and count-summary trigger text.

import { MultiSelect } from '@lostgradient/cinder';
formselectionmultiselect
01

Overview

Reference usage

Multi-value dropdown that presents checkbox options inside an anchored floating list.

Usage

svelte
<script lang="ts">
  import { MultiSelect } from '@lostgradient/cinder';

  const items = [
    { id: 'apple', label: 'Apple' },
    { id: 'banana', label: 'Banana' },
    { id: 'cherry', label: 'Cherry' },
    { id: 'mango', label: 'Mango' },
    { id: 'orange', label: 'Orange' },
  ] as const;

  let selected = $state<Array<(typeof items)[number]['id']>>(['banana']);
</script>

<MultiSelect id="fruit" label="Fruits" {items} bind:selectedIds={selected} />

Grouped items

Give items a group name to render them under headings. Ungrouped items come first without a heading, and groups follow in order of first appearance. Each heading shows the group name and how many of its items are listed. With filterable, typing filters across every group, keeps the headings of groups that still match, and hides the rest. A selectionFeedback that moves selected items to the top does so within each group.

svelte
<script lang="ts">
  import { MultiSelect } from '@lostgradient/cinder';

  const tools = [
    { id: 'read', label: 'Read file', group: 'Built in' },
    { id: 'write', label: 'Write file', group: 'Built in' },
    { id: 'search', label: 'Search the web', group: 'Search server' },
  ];

  let selected = $state<string[]>([]);
</script>

<MultiSelect id="tools" label="Tools" items={tools} filterable bind:selectedIds={selected} />
Live preview

Basic multi-select

02

When to use

Use when
  • Selecting multiple values from a fixed option list while preserving compact form layout.
  • Showing many options in an anchored picker instead of a permanently-expanded checkbox group.
Avoid when
  • Selecting a single value from a short fixed list — use select instead.
  • Moving items between available/selected panes — use transfer-list instead.
03

Examples

Basic multi-select

Pick multiple values and show the selected count on the trigger.

Filterable with warning

Enable filtering, warning helper text, and top-after-reopen selection feedback.

Grouped items

Give items a group to render them under headings with counts. Filtering keeps the headings of groups that still match.

04

Props

Props for multi-select
Name
Type
Default
Description
id required text Unique identifier — required for label association and ARIA wiring.
items required MultiSelectItem<T>[] Full option set. The sole inference source for T.
selectedIds bindable NoInfer<T>[] Bindable selected IDs.
name text Native form field name. Emits one hidden input per selected id.
label text Visible label rendered in a <label> associated via for.
placeholder text 'Select options' Placeholder text when nothing is selected.
description text Helper text displayed below the trigger; wired via aria-describedby.
error text Validation error message; sets aria-invalid="true".
warning text Warning text rendered below the control and included in aria-describedby.
disabled boolean Disables the control. Inherited from a wrapping FormField when unset.
readonly boolean false Prevents changing selection while still allowing viewing current selections.
required boolean Marks the field required and shows the required marker on the label.
filterable boolean false Enables the filter input rendered above the options list.
filter (item: MultiSelectItem<T>, query: string) => boolean Custom option filter callback. Defaults to case-insensitive label/description matching.
selectionFeedback 'top' | 'fixed' | 'top-after-reopen' 'fixed' Selected-option ordering behavior when the menu is open.
direction 'down' | 'up' 'down' Open direction for the floating panel.
sheetBelow text Viewport width below which the options panel docks to the bottom edge as a sheet, with the bottom Drawer's geometry, instead of anchoring to the trigger. Filtering, keyboard, and dismissal behave exactly as when anchored. A simple CSS length such as '640px', or false to always anchor. Default '640px'.
size 'sm' | 'md' | 'lg' 'md' Height step from the shared --cinder-control-height-* scale: sm 28px, md 32px, lg 40px, the same heights as a Button of that size.