# Native Select

A styled native select with option groups, forms, and multiple selection.

- Package: `@mielui/svelte`
- Component version: `1.0.0`
- Depends on Mielui components: _internal/utils
- Shared utilities: hugeicons-icon, utils.cn

## Install

~~~~sh
pnpm dlx @mielui/svelte add native-select
~~~~

## API

This reference is generated at build time from the component manifest, public `index.ts`, and documentation examples below. Changes to those source files are reflected here in the published Markdown. Standard Svelte and HTML attributes accepted by the exported prop types are supported.


### OptGroup

| Prop | Type | Default | Required | Bindable | Description |
| --- | --- | --- | --- | --- | --- |

Also accepts the native HTML attributes and events listed in the rendered API reference.

### Option

| Prop | Type | Default | Required | Bindable | Description |
| --- | --- | --- | --- | --- | --- |
| value | string \| undefined | - | No | No | Value submitted when this option is selected. |

Also accepts the native HTML attributes and events listed in the rendered API reference.

### Root

| Prop | Type | Default | Required | Bindable | Description |
| --- | --- | --- | --- | --- | --- |
| multiple | false \| true \| undefined | false | No | No | Allows several options to be selected and makes `value` an array. |
| value | string \| string[] \| undefined | - | No | Yes | Selected value, or an array when `multiple` is set. Bindable. |

Also accepts the native HTML attributes and events listed in the rendered API reference.

### Public types

~~~~ts
import type {
    HTMLOptgroupAttributes,
    HTMLOptionAttributes,
    HTMLSelectAttributes
} from 'svelte/elements';
import Root from './native-select.svelte';
import OptGroup from './native-select-opt-group.svelte';
import Option from './native-select-option.svelte';

export type NativeSelectProps = Omit<HTMLSelectAttributes, 'value' | 'multiple'> &
    (
        | {
              /** Allows several options to be selected and makes `value` an array. */
              multiple?: false;
              /** Selected value, or an array when `multiple` is set. Bindable. */
              value?: string;
          }
        | {
              /** Allows several options to be selected and makes `value` an array. */
              multiple: true;
              /** Selected value, or an array when `multiple` is set. Bindable. */
              value?: string[];
          }
    );

export type NativeSelectOptGroupProps = HTMLOptgroupAttributes;

export type NativeSelectOptionProps = Omit<HTMLOptionAttributes, 'value'> & {
    /** Value submitted when this option is selected. */
    value?: string;
};

export { OptGroup, Option, Root };
~~~~

## Examples

### Form

~~~~svelte
<script lang="ts">
    import { Button } from '@mielui/svelte/components/button';
    import { Label } from '@mielui/svelte/components/label';
    import * as NativeSelect from '@mielui/svelte/components/native-select';

    const id = $props.id();
    let plan = $state('');
    let saved = $state('');

    function savePlan(event: SubmitEvent & { currentTarget: HTMLFormElement }) {
        event.preventDefault();
        saved = String(new FormData(event.currentTarget).get('plan'));
    }
</script>

<form class="flex w-full max-w-xs flex-col gap-3" onsubmit={savePlan}>
    <Label for={id}>Plan</Label>
    <NativeSelect.Root {id} name="plan" required bind:value={plan}>
        <NativeSelect.Option value="" disabled>Choose a plan</NativeSelect.Option>
        <NativeSelect.Option value="personal">Personal</NativeSelect.Option>
        <NativeSelect.Option value="team">Team</NativeSelect.Option>
        <NativeSelect.Option value="enterprise" disabled>
            Enterprise, coming soon
        </NativeSelect.Option>
    </NativeSelect.Root>
    <Button type="submit">Save plan</Button>
    <p role="status" class="min-h-5 text-sm text-foreground-muted">
        {saved ? `Saved ${saved} plan.` : ''}
    </p>
</form>
~~~~

### Multiple

~~~~svelte
<script lang="ts">
    import { numberShuffle } from '@mielui/svelte/actions/number-shuffle';
    import { Label } from '@mielui/svelte/components/label';
    import * as NativeSelect from '@mielui/svelte/components/native-select';

    const id = $props.id();
    let days = $state(['monday', 'wednesday']);
</script>

<div class="flex w-full max-w-xs flex-col gap-2">
    <Label for={id}>Office days</Label>
    <NativeSelect.Root {id} name="days" multiple size={4} bind:value={days}>
        <NativeSelect.Option value="monday">Monday</NativeSelect.Option>
        <NativeSelect.Option value="tuesday">Tuesday</NativeSelect.Option>
        <NativeSelect.Option value="wednesday">Wednesday</NativeSelect.Option>
        <NativeSelect.Option value="thursday">Thursday</NativeSelect.Option>
    </NativeSelect.Root>
    <p class="text-sm text-foreground-muted">
        <span use:numberShuffle={{ value: days.length }}>{days.length}</span>
        days selected. Use your platform's modifier keys to select several options.
    </p>
</div>
~~~~

### Usage

~~~~svelte
<script lang="ts">
    import * as NativeSelect from '@mielui/svelte/components/native-select';

    let timezone = $state('Europe/Paris');
</script>

<NativeSelect.Root name="timezone" bind:value={timezone} aria-label="Time zone">
    <NativeSelect.Option value="Europe/Paris">Paris</NativeSelect.Option>
    <NativeSelect.Option value="Europe/London">London</NativeSelect.Option>
</NativeSelect.Root>
~~~~

For the rendered reference, visit [/docs/components/native-select](/docs/components/native-select).
