Same look and behavior as CwDropdown, but with multi-selection. The bound value is an array
of { id, label } entries — easy to send straight to a backend or render as chips.
Options can also be grouped by tagging each one with a group key (string or number) and
passing a groups array that supplies each group's heading label and render order.
A search field appears at the top of the open dropdown by default — typing filters by option label or group label (so typing a group name reveals every option in it). Set dropdownHeight to change the listbox max-height, or pass searchable={false} to hide the filter.
<script lang="ts">
import { CwMultiSelect } from '@cropwatchdevelopment/cwui';
// Each option carries a `group` key (string or number).
const options = [
{ label: 'Apple', value: 'apple', group: 'pome' },
{ label: 'Pear', value: 'pear', group: 'pome' },
{ label: 'Cherry', value: 'cherry', group: 'stone' },
{ label: 'Peach', value: 'peach', group: 'stone' },
{ label: 'Mango', value: 'mango', group: 'tropical' }
];
// Groups define render order and the visible heading label.
const groups = [
{ value: 'pome', label: 'Pome Fruits' },
{ value: 'stone', label: 'Stone Fruits' },
{ value: 'tropical', label: 'Tropical' }
];
let selected = $state<{ id: string; label: string }[]>([]);
</script>
<CwMultiSelect
{options}
{groups}
label="Fruit by category"
bind:value={selected}
/>
<!-- Group keys can also be numbers, e.g. site IDs.
Options whose `group` key isn't in `groups` render ungrouped at the end. -->
Search + dropdownHeight exampleCopy code
<script lang="ts">
import { CwMultiSelect } from '@cropwatchdevelopment/cwui';
let selected = $state<{ id: string; label: string }[]>([]);
</script>
<!-- `dropdownHeight` overrides the listbox max-height (default 15rem).
The search field is on by default — typing filters by option label
OR group label, so typing a group name reveals every option in it. -->
<CwMultiSelect
{options}
{groups}
label="Sensors"
placeholder="Pick sensors…"
dropdownHeight="24rem"
searchPlaceholder="Filter by sensor or site…"
bind:value={selected}
/>
<!-- Opt out of the search field with `searchable={false}`. -->
Documentation Upgrade
Start here
CwMultiSelect mirrors CwDropdown but allows multiple options to be selected at once. The bound `value` is an array of `{ id, label }` entries, ready to send to a backend or render as chips elsewhere in your UI.
How to think about it
Build the option listEach option needs a `label` and `value`. Add `disabled` to make an item visible but not selectable.
Bind an array`value` is an array of `{ id, label }`. Use `bind:value` if the parent owns the selection state, or `onchange` if you only need a callback.
Toggle to select / deselectClicking an option (or pressing Enter/Space while focused in the listbox) toggles its membership in the array. The list stays open so users can pick more than one.
Clear or remove individual chipsA "Clear all" action appears in the listbox while items are selected (`clearable` defaults to true). Individual chips can be dismissed by clicking the small × on the trigger.