

# MultiSelector

Dropdown that selects multiple options at once. Always controlled via `value` (option ids) and `onChange`. The trigger summarizes the current selection as a comma-separated label list.

## Examples

### Default

Pass `options` as `{ id, label }[]` and seed `value` with the selected ids.

```tsx
import { MultiSelector } from '@var-ui/react';

<MultiSelector label="Teams" options={options} value={value} onChange={setValue} />
```

```astro
<!-- No Astro binding yet — use @var-ui/react -->
```

```html
<!-- No HTML demo yet — use @var-ui/react -->
```

### Controlled selection

Keep the selected ids in React state and update them from `onChange`. The trigger text and any app UI that depends on the selection stay in sync.

```tsx
import { MultiSelector } from '@var-ui/react';
import { useState } from 'react';

const [value, setValue] = useState(['design', 'ops']);

<MultiSelector
  label="Teams"
  description="Selection stays in React state"
  options={options}
  value={value}
  onChange={setValue}
/>
```

```astro
<!-- No Astro binding yet — use @var-ui/react -->
```

```html
<!-- No HTML demo yet — use @var-ui/react -->
```

## Props

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| onChange | (value: string[]) => void | yes |  | Called with the updated selected option ids whenever selection changes. |
| options | MultiSelectorOption[] | yes |  | Options shown in the dropdown listbox. |
| value | string[] | yes |  | Currently selected option ids. |
| className | string \| undefined | no |  |  |
| description | string \| undefined | no |  | Helper text shown below the control when there is no error. |
| errorMessage | string \| undefined | no |  | Validation message; when set, the field is shown in an error state. |
| isDisabled | boolean \| undefined | no |  |  |
| label | string \| undefined | no |  | Visible label rendered above the control. |
| placeholder | string \| undefined | no | Select… | Placeholder text when no value is selected. |

## Accessibility

The trigger is a button labeled by the field `label` plus the current summary text. The popover listbox uses `selectionMode="multiple"` with checkbox affordances on each item. Keep `label` visible, and use `description` / `errorMessage` (the error message is `role="alert"`) so assistive tech gets the same help and validation copy as sighted users.
