<script>
  import { MultiSelect, InlineNotification } from "carbon-components-svelte";
  import Preview from "../../components/Preview.svelte";
</script>

The `MultiSelect` component provides a dropdown interface for selecting multiple options using checkboxes. It supports filtering, custom formatting, and various states. Each item must have a unique `id` property for proper functionality.

<InlineNotification svx-ignore lowContrast title="Note:" kind="info" hideCloseButton>
  <div class="body-short-01">Every <code>items</code> object must have a unique "id" property.</div>
</InlineNotification>

## Default

Create a basic multi-select dropdown with three contact methods. By default, items are ordered alphabetically.

<MultiSelect titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Format item display text

Format the display text of items using the `itemToString` prop. This example appends the item ID in parentheses.

<MultiSelect itemToString={item => {
  return item.text + ' (' + item.id +')'
}} titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
    sortItem="{() => {}}"
  />

## Custom slot

Override the default slot to customize item rendering. This example shows how to access and use the item and index values.

<FileSource src="/framed/MultiSelect/MultiSelectSlot" />

## No alphabetical ordering

Prevent automatic alphabetical ordering by passing a no-op function to `sortItem`. This maintains the original order of items.

<MultiSelect titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}" 
    sortItem="{() => {}}"
  />

## Filterable

Enable filtering by setting `filterable` to `true`. This example includes a placeholder text for the filter input.

<MultiSelect spellcheck="false" filterable titleText="Contact" placeholder="Filter contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Initial selected items

Pre-select items by passing an array of item IDs to `selectedIds`. This example pre-selects Slack and Email.

<MultiSelect selectedIds="{["0", "1"]}" titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}" 
  />

## Multiple multi-select dropdowns

This example demonstrates how to manage multiple dropdowns in a form with coordinated state.

<FileSource src="/framed/MultiSelect/MultipleMultiSelect" />

## Format checkbox values

Customize checkbox attributes using the `itemToInput` prop. This example sets a consistent name for all checkboxes.

Use the `itemToInput` prop to customize the user-selectable checkbox values.
This will also override the underlying hidden inputs used for form submission.

```js
itemToInput={(item) => {
  return {
    name: `Contact_${item.id}`,
    value: item.id
  }
}}
```

The above function sets the `name` attribute to
`Contact_0` (respective to each item's `id`) for every hidden input that
renders, along with each respective item's `id` set to the `value` attribute.

<MultiSelect
  itemToInput={(item) => ({name: 'contact', value: item.id})}
  titleText="Contact"
  label="Select contact methods..."
  items="{[
    {id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}
  ]}"
/>

## Top direction

Display the dropdown menu above the input by setting `direction` to `"top"`. This is useful when space below is limited.

<MultiSelect direction="top" titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Hidden label

Hide the label visually while maintaining accessibility by setting `hideLabel` to `true`. The label is still available to screen readers.

<MultiSelect titleText="Contact" label="Select contact methods..." hideLabel
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Light variant

Use the light variant for dark backgrounds by setting `light` to `true`. This provides better contrast in dark themes.

<MultiSelect light titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Inline variant

Display the dropdown inline with other content by setting `type` to `"inline"`. This removes the background and border.

<MultiSelect type="inline" titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Extra-large size

Use the extra-large size for prominent selections by setting `size` to `"xl"`. This provides more visual emphasis.

<MultiSelect size="xl" titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Small size

Use the small size for compact layouts by setting `size` to `"sm"`. This is ideal for secondary selections.

<MultiSelect size="sm" titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Invalid state

Indicate an invalid selection by setting `invalid` to `true`. This example shows a required field error.

<MultiSelect invalid invalidText="A contact method is required" titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Warning state

Indicate a warning state by setting `warn` to `true`. This example shows a warning about unassociated accounts.

<MultiSelect warn warnText="One or more contact methods are not associated with your account" titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Disabled state

Disable the entire dropdown by setting `disabled` to `true`. This prevents all user interaction.

<MultiSelect disabled titleText="Contact" label="Select contact methods..."
    items="{[{id: "0", text: "Slack"},
    {id: "1", text: "Email"},
    {id: "2", text: "Fax"}]}"
  />

## Disabled items

Disable specific items using the `disabled` property in the `items` prop. This example disables the Email option.

<MultiSelect
  titleText="Contact"
  label="Select contact methods..."
  items={[
    { id: "0", text: "Slack" },
    { id: "1", text: "Email", disabled: true },
    { id: "2", text: "Fax" },
  ]}
/>
