Skip to content
Areia
Esc
↑↓navigate↵open⌘Jpreview
On this page

Toggle

A two-state button that can be either on or off.

A pressable button that toggles between pressed and unpressed states.

Source Code

Toggle is backed by @areia/slots and wires aria-pressed, data-state, and toggle change events.

import { ilha } from "ilha";
import { Toggle } from "areia";

export default ilha.render(() => (
  <Toggle variant="outline">Bold</Toggle>
));

Import

import { Toggle, ToggleGroup } from "areia";

Usage

Use Toggle with optional variant, size, and defaultPressed. It is a single-element primitive — a <button> with data-slot="toggle".

import { ilha } from "ilha";
import { Toggle } from "areia";

export default ilha.render(() => (
  <Toggle variant="outline">Italic</Toggle>
));

Examples

Variants

import { ilha } from "ilha";
import { Toggle } from "areia";

export default ilha.render(() => (
  <div class="flex items-center gap-2">
    <Toggle>Default</Toggle>
    <Toggle variant="outline">Outline</Toggle>
  </div>
));

Sizes

import { ilha } from "ilha";
import { Toggle } from "areia";

export default ilha.render(() => (
  <div class="flex items-center gap-2">
    <Toggle size="sm" variant="outline">
      Small
    </Toggle>
    <Toggle size="default" variant="outline">
      Default
    </Toggle>
    <Toggle size="lg" variant="outline">
      Large
    </Toggle>
  </div>
));

Disabled

import { ilha } from "ilha";
import { Toggle } from "areia";

export default ilha.render(() => (
  <div class="flex items-center gap-2">
    <Toggle disabled>Disabled</Toggle>
    <Toggle variant="outline" disabled>
      Disabled
    </Toggle>
  </div>
));

Pressed State

Use defaultPressed to set the initial pressed state.

import { ilha } from "ilha";
import { Toggle } from "areia";

export default ilha.render(() => (
  <div class="flex items-center gap-2">
    <Toggle defaultPressed>Pressed</Toggle>
    <Toggle variant="outline" defaultPressed>
      Pressed
    </Toggle>
  </div>
));

Toggle Group

Use ToggleGroup when multiple toggles belong together as a single control.

import { ilha } from "ilha";
import { ToggleGroup } from "areia";

export default ilha.render(() => (
  <ToggleGroup type="single" defaultValue="center">
    <ToggleGroup.Item value="left" variant="outline">
      Left
    </ToggleGroup.Item>
    <ToggleGroup.Item value="center" variant="outline">
      Center
    </ToggleGroup.Item>
    <ToggleGroup.Item value="right" variant="outline">
      Right
    </ToggleGroup.Item>
  </ToggleGroup>
));

Use type="multiple" to allow more than one item to be pressed at a time.

import { ilha } from "ilha";
import { ToggleGroup } from "areia";

export default ilha.render(() => (
  <ToggleGroup type="multiple" defaultValue={["bold"]}>
    <ToggleGroup.Item value="bold" variant="outline">
      Bold
    </ToggleGroup.Item>
    <ToggleGroup.Item value="italic" variant="outline">
      Italic
    </ToggleGroup.Item>
    <ToggleGroup.Item value="underline" variant="outline">
      Underline
    </ToggleGroup.Item>
  </ToggleGroup>
));

Change Events

Use onPressedChange to respond to state changes.

import { ilha } from "ilha";
import { Toggle } from "areia";

export default ilha.state("bold", false).render(({ state }) => (
  <div class="flex flex-col items-start gap-3">
    <Toggle
      variant="outline"
      onPressedChange={(pressed) => {
        state.bold(pressed);
      }}
    >
      Bold
    </Toggle>
    <p class="text-sm text-areia-subtle">
      Bold is:{" "}
      <span class="font-medium text-areia-default">
        {state.bold() ? "On" : "Off"}
      </span>
    </p>
  </div>
));

API Reference

Toggle

Root component that manages the toggle state.

Prop Type Default Description
children unknown — Content rendered inside the toggle button.
variant "default" | "outline" "default" Visual variant. default is filled, outline is bordered.
size "sm" | "default" | "lg" "default" Size of the toggle.
defaultPressed boolean false Initial pressed state.
disabled boolean false Disables interaction and applies muted styling.
onPressedChange (pressed: boolean) => void — Called when the pressed state changes.

ToggleGroup

Prop Type Default Description
type "single" | "multiple" "single" Selection mode.
defaultValue string | string[] — Initial selected value(s).
orientation "horizontal" | "vertical" "horizontal" Layout direction for keyboard navigation.
loop boolean true Wrap keyboard focus at ends.
disabled boolean false Disable the entire group.
onValueChange (value: string[]) => void — Called when the selection changes.
children unknown — ToggleGroup.Item children.
class string — Additional CSS classes.
className string — Alias for class.

ToggleGroup.Item

Prop Type Default Description
value string — Unique item value.
variant "default" | "outline" "default" Visual variant.
size "sm" | "default" | "lg" "default" Size of the item.
disabled boolean false Disables this item.
children unknown — Content rendered inside the item.
class string — Additional CSS classes.
className string — Alias for class.

ToggleGroup.Separator

Visual divider between toggle items. Accepts standard div attributes plus class and className.

Slots

Toggle renders a single data slot:

  • toggle

The root receives state attributes from the slot controller:

Attribute Element Description
data-state toggle "on" when pressed, "off" when not pressed.
data-disabled toggle Present when toggle is disabled.
aria-pressed toggle "true" or "false".

Events

The toggle emits custom DOM events from the root element.

Outbound

Event Detail Description
toggle:change { pressed: boolean } Fired when the pressed state changes.

Inbound

Event Detail Description
toggle:set { value: boolean } Set the pressed state programmatically.
const toggle = document.querySelector('[data-slot="toggle"]')!;

toggle.addEventListener("toggle:change", (e) => {
  console.log("Pressed:", e.detail.pressed);
});

// Set pressed state programmatically
toggle.dispatchEvent(
  new CustomEvent("toggle:set", { detail: { value: true } }),
);

Was this page helpful?