# Toggle Group

Single or multiple-select toggle group with bindable value (string or string[]).

- Package: `@mielui/svelte`
- Component version: `1.2.1`
- Depends on Mielui components: _internal/utils
- Shared utilities: utils.cn, utils.createContext, utils.travelingHighlight

## Install

~~~~sh
pnpm dlx @mielui/svelte add toggle-group
~~~~

## 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.


### Item

| Prop | Type | Default | Required | Bindable | Description |
| --- | --- | --- | --- | --- | --- |
| value | string | - | Yes | No | Value this item selects. |
| disabled | boolean \| undefined | - | No | No | Prevents interaction and dims the control. |
| children | Snippet<[]> \| undefined | - | No | No | Content rendered inside. |
| class | (string & (ClassValue \| null)) \| undefined | - | No | No | Classes added to the element. |

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

### Root

| Prop | Type | Default | Required | Bindable | Description |
| --- | --- | --- | --- | --- | --- |
| class | string \| undefined | - | No | No | Classes added to the element. |
| children | Snippet<[]> \| undefined | - | No | No | Content rendered inside. |
| disabled | boolean \| undefined | false | No | No | Prevents interaction and dims the control. |
| size | ToggleGroupSize \| undefined | 'sm' | No | No | Control height of the items. |
| aria-label | string \| undefined | - | No | No | Accessible name when there is no visible label. |
| aria-labelledby | string \| undefined | - | No | No | Id of the element that labels it. |
| type | "single" \| "multiple" \| undefined | - | No | No | `single` keeps one value. `multiple` allows several and makes `value` an array. |
| value | string \| string[] \| undefined | - | No | Yes | Selected value, or an array in multiple mode. Bindable. |
| onValueChange | ((value: string \| undefined) => void) \| ((value: string[]) => void) \| undefined | - | No | No | Called with the new value when it changes. |



### Public types

~~~~ts
import type { DefaultProps } from '@mielui/svelte/utils';
import type { Snippet } from 'svelte';
import type { HTMLButtonAttributes } from 'svelte/elements';
import Root from './toggle-group.svelte';
import Item from './toggle-group-item.svelte';

export type ToggleGroupSize = 'sm' | 'md' | 'lg';

export type ToggleGroupProps = DefaultProps & {
    /** Prevents interaction and dims the control. */
    disabled?: boolean;
    /** Control height of the items. */
    size?: ToggleGroupSize;
    /** Accessible name when there is no visible label. */
    'aria-label'?: string;
    /** Id of the element that labels it. */
    'aria-labelledby'?: string;
} & (
        | {
              /** `single` keeps one value. `multiple` allows several and makes `value` an array. */
              type?: 'single';
              /** Selected value, or an array in multiple mode. Bindable. */
              value?: string;
              /** Called with the new value when it changes. */
              onValueChange?: (value: string | undefined) => void;
          }
        | {
              /** `single` keeps one value. `multiple` allows several and makes `value` an array. */
              type: 'multiple';
              /** Selected value, or an array in multiple mode. Bindable. */
              value?: string[];
              /** Called with the new value when it changes. */
              onValueChange?: (value: string[]) => void;
          }
    );

export type ToggleGroupItemProps = {
    /** Value this item selects. */
    value: string;
    /** Prevents interaction and dims the control. */
    disabled?: boolean;
    /** Content rendered inside. */
    children?: Snippet;
} & DefaultProps &
    Omit<HTMLButtonAttributes, 'onclick' | 'children' | 'disabled' | 'value'>;

export { Item, Root };
~~~~

## Examples

### Hero

~~~~svelte
<script lang="ts">
    import {
        TextAlignCenterIcon as AlignCenter,
        TextAlignLeftIcon as AlignLeft,
        TextAlignRightIcon as AlignRight
    } from '@hugeicons/core-free-icons';
    import * as ToggleGroup from '@mielui/svelte/components/toggle-group';
    import HugeiconsIcon from '@mielui/svelte/hugeicons-icon';

    let alignment = $state<string | undefined>('center');
</script>

<div class="flex w-full max-w-sm flex-col items-center gap-5">
    <ToggleGroup.Root bind:value={alignment} aria-label="Text alignment">
        <ToggleGroup.Item value="left" aria-label="Align left">
            <HugeiconsIcon icon={AlignLeft} size={14} />
        </ToggleGroup.Item>
        <ToggleGroup.Item value="center" aria-label="Align center">
            <HugeiconsIcon icon={AlignCenter} size={14} />
        </ToggleGroup.Item>
        <ToggleGroup.Item value="right" aria-label="Align right">
            <HugeiconsIcon icon={AlignRight} size={14} />
        </ToggleGroup.Item>
    </ToggleGroup.Root>

    <p
        class={[
            'w-full text-sm',
            {
                'text-left': alignment === 'left',
                'text-center': alignment === 'center',
                'text-right': alignment === 'right'
            }
        ]}
    >
        Choose an alignment to change how this paragraph sits in its column.
    </p>
</div>
~~~~

### Multiple

~~~~svelte
<script lang="ts">
    import * as ToggleGroup from '@mielui/svelte/components/toggle-group';

    let formatting = $state(['bold', 'italic']);
</script>

<ToggleGroup.Root type="multiple" bind:value={formatting} aria-label="Text formatting">
    <ToggleGroup.Item value="bold">Bold</ToggleGroup.Item>
    <ToggleGroup.Item value="italic">Italic</ToggleGroup.Item>
    <ToggleGroup.Item value="underline">Underline</ToggleGroup.Item>
</ToggleGroup.Root>
~~~~

### Single

~~~~svelte
<script lang="ts">
    import {
        TextAlignCenterIcon as AlignCenter,
        TextAlignLeftIcon as AlignLeft,
        TextAlignRightIcon as AlignRight
    } from '@hugeicons/core-free-icons';
    import * as ToggleGroup from '@mielui/svelte/components/toggle-group';
    import HugeiconsIcon from '@mielui/svelte/hugeicons-icon';
</script>

<ToggleGroup.Root value="center" aria-label="Text alignment">
    <ToggleGroup.Item value="left" aria-label="Align left">
        <HugeiconsIcon icon={AlignLeft} size={14} />
    </ToggleGroup.Item>
    <ToggleGroup.Item value="center" aria-label="Align center">
        <HugeiconsIcon icon={AlignCenter} size={14} />
    </ToggleGroup.Item>
    <ToggleGroup.Item value="right" aria-label="Align right">
        <HugeiconsIcon icon={AlignRight} size={14} />
    </ToggleGroup.Item>
</ToggleGroup.Root>
~~~~

### Sizes

~~~~svelte
<script lang="ts">
    import * as ToggleGroup from '@mielui/svelte/components/toggle-group';

    const sizes = ['sm', 'md', 'lg'] as const;
</script>

<div class="flex flex-col items-center gap-4">
    {#each sizes as size (size)}
        <ToggleGroup.Root value="week" {size} aria-label={`Range, ${size}`}>
            <ToggleGroup.Item value="day">Day</ToggleGroup.Item>
            <ToggleGroup.Item value="week">Week</ToggleGroup.Item>
            <ToggleGroup.Item value="month">Month</ToggleGroup.Item>
        </ToggleGroup.Root>
    {/each}
</div>
~~~~

For the rendered reference, visit [/docs/components/toggle-group](/docs/components/toggle-group).
