# Toggle

> Two-state button carrying aria-pressed, for a single on/off option like a formatting mark or a filter.

- Package: `fancy-ui-svelte` (Svelte 5 + Tailwind CSS v4)
- Category: Actions
- Tags: toggle, button, pressed, formatting, switch
- Docs: https://fancy-ui.rama.app/docs/components/toggle
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/src/lib/fancy-ui/toggle

## Import

```svelte
<script lang="ts">
  import { Toggle } from 'fancy-ui-svelte';
</script>
```

Setup (once per project): `npm install fancy-ui-svelte`, then add `@import "fancy-ui-svelte/tailwind.css";` after `@import "tailwindcss";` in your main CSS file. Full guide: https://fancy-ui.rama.app/llms.txt

React: `import { Toggle } from 'fancy-ui-react';` (same prop names; `class` becomes `className`, snippets become `ReactNode`).

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `pressed` | `boolean` | `false` | Whether the toggle is currently pressed (active); bindable |
| `onPressedChange` | `(pressed: boolean) => void` | — | Called with the new pressed state whenever the toggle is activated |
| `disabled` | `boolean` | `false` | Disables the toggle; blocks both the state change and the callback |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Visual size of the control |
| `variant` | `"ghost" \| "outline"` | `"ghost"` | "ghost" has no resting border, "outline" keeps one at rest |
| `label` | `string` | — | Accessible name — required when children is icon-only |
| `class` | `string` | — | Additional CSS classes |
| `ref` | `HTMLButtonElement \| null` | `null` | Bindable element reference |
| `sound` | `boolean` | `false` | Plays toggle-on or toggle-off on activation, once the user has enabled sound |

## Snippets

| Snippet | Description |
| --- | --- |
| `children` | Toggle content, typically a single glyph or a short label |

## Examples

### Basic Usage

A single icon-only toggle with a bound pressed state.

```svelte
<script lang="ts">
	import { Toggle } from "fancy-ui-svelte";

	let muted = $state(false);
</script>

<Toggle sound bind:pressed={muted} label={muted ? "Unmute" : "Mute"}>
	{#if muted}
		<svg
			class="size-4"
			viewBox="0 0 24 24"
			fill="none"
			stroke="currentColor"
			stroke-width="2"
			stroke-linecap="round"
			stroke-linejoin="round"
			aria-hidden="true"
		>
			<path d="M11 5 6 9H2v6h4l5 4V5Z" />
			<line x1="23" y1="9" x2="17" y2="15" />
			<line x1="17" y1="9" x2="23" y2="15" />
		</svg>
	{:else}
		<svg
			class="size-4"
			viewBox="0 0 24 24"
			fill="none"
			stroke="currentColor"
			stroke-width="2"
			stroke-linecap="round"
			stroke-linejoin="round"
			aria-hidden="true"
		>
			<path d="M11 5 6 9H2v6h4l5 4V5Z" />
			<path d="M15.54 8.46a5 5 0 0 1 0 7.07" />
			<path d="M19.07 4.93a10 10 0 0 1 0 14.14" />
		</svg>
	{/if}
</Toggle>
```

### Sizes

The three available sizes, sm/md/lg.

```svelte
<script lang="ts">
	import { Toggle, type ToggleSize } from "fancy-ui-svelte";

	const sizes: ToggleSize[] = ["sm", "md", "lg"];
</script>

<div class="flex flex-wrap items-center gap-3">
	{#each sizes as size (size)}
		<Toggle sound {size} pressed label={`Size ${size}`}>
			<strong>B</strong>
		</Toggle>
	{/each}
</div>
```

### Variants

Ghost vs. outline, resting and pressed.

```svelte
<script lang="ts">
	import { Toggle, type ToggleVariant } from "fancy-ui-svelte";

	const variants: ToggleVariant[] = ["ghost", "outline"];
</script>

<div class="flex flex-wrap items-center gap-6">
	{#each variants as variant (variant)}
		<div class="flex items-center gap-2">
			<Toggle sound {variant} label={`${variant}, resting`}>
				<strong>B</strong>
			</Toggle>
			<Toggle sound {variant} pressed label={`${variant}, pressed`}>
				<strong>B</strong>
			</Toggle>
		</div>
	{/each}
</div>
```

### Text Formatting

A bold/italic/underline row with a live preview.

```svelte
<script lang="ts">
	import { Toggle } from "fancy-ui-svelte";

	let bold = $state(false);
	let italic = $state(true);
	let underline = $state(false);
</script>

<div class="flex flex-col gap-3">
	<div class="flex gap-2">
		<Toggle sound bind:pressed={bold} label="Bold">
			<strong>B</strong>
		</Toggle>
		<Toggle sound bind:pressed={italic} label="Italic">
			<em>I</em>
		</Toggle>
		<Toggle sound bind:pressed={underline} label="Underline">
			<span class="underline">U</span>
		</Toggle>
	</div>

	<p class="text-sm" class:font-bold={bold} class:italic class:underline>
		Toggle the marks above to preview how this sentence would look.
	</p>
</div>
```
