Skip to content
Areia
Esc
navigateopen⌘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?