Noctis

A two-state button that is either off or pressed. Every variant is quiet when off and fills only when pressed — ghost neutral, accent the indigo accent, primary the bold primary. Its variants and xslg sizes mirror Button, so the two action controls feel identical under the finger.

Basic

A standalone toggle flips between off and pressed on click or with the keyboard, announcing its state through aria-pressed. Drive it with pressed + onPressedChange, or let it own its state with defaultPressed.

Variants

Four looks, named to match Button — each quiet when off, each lighting a different fill when pressed. ghost (the default, for dense toolbars) fills neutral; accent fills the indigo accent for a prominent, signalling on/off; primary fills the bold primary; outline carries a resting border so a single toggle reads as a control on bare ground, then fills primary when pressed.

Sizes

Four heights — xs, sm, md, and lg — sharing the control type and spacing rhythm with Button. Reach for xs in a dense toolbar; keep sm as the floor for touch targets.

Single-select group

Without attached, ToggleGroup is a separated row sharing its variant and size. By default it is single-select — pressing one releases the others. Each toggle takes a value; the group's value is the array of pressed values.

Multiple-select group

Set multiple to let several toggles be pressed at once — the pattern for independent formatting controls like bold, italic, and underline.

Select-all (mixed)

A composite "select all" toggle that drives several children reads as mixed when only some are pressed — a half-state fill between rest and pressed. Set aria-pressed="mixed" on that toggle yourself; it is a documented pattern, not a prop. Never swap the toggle's label between states.

Icon-only toggles

Square a toggle with iconOnly for a single glyph, and always give it an aria-label — there is no visible text to name it. For sighted discoverability, pair it with a Tooltip so its purpose is revealed on hover and focus. Don't mix icon-only and text toggles within one group, and don't change a toggle's icon between pressed states (that's an action button, not a toggle).

Keyboard

A standalone toggle is a button; a group adds roving arrow-key navigation between its toggles.

KeyAction
Space / EnterToggle the focused button's pressed state.
Arrow Right / Arrow LeftMove focus to the next / previous toggle in a horizontal group. In RTL the directions mirror.
Arrow Down / Arrow UpMove focus to the next / previous toggle in a vertical group.
Home / EndMove focus to the first / last toggle in a group.
TabMove focus into and out of the group (the group is a single tab stop).

Accessibility

  • Pressed state — each toggle is a native <button> carrying aria-pressed; Base UI keeps it in sync. Space and Enter activate it.
  • Group role — a ToggleGroup becomes a role="toolbar" once it holds three or more toggles, per the APG, and stays role="group" below that. A toolbar requires an aria-label (or aria-labelledby) — an unlabeled one is an axe finding. You can override the computed role by passing your own.
  • Orientation — set orientation="vertical" and the arrow keys and aria-orientation follow; in RTL the horizontal arrow directions mirror automatically.
  • Group disableddisabled on the group cascades to every toggle inside.
  • Icon-only — supply an aria-label; pair with a Tooltip for sighted discoverability. Never change the label or icon on toggle.
  • Mixed — reserve aria-pressed="mixed" for a composite "select all" toggle whose children don't all share a value.

Anatomy

Compose a single toggle directly, or wrap several in a group.

  • Toggle — one two-state button. Pass pressed / defaultPressed standalone, or a value inside a group. Takes a variant (ghost / accent / primary / outline), size (xslg), optional startIcon / endIcon glyphs, and iconOnly to square it for a single glyph. variant, size, and iconOnly are inherited from an enclosing group when unset.
  • ToggleGroup — the container. Owns the pressed set (controlled via value / onValueChange, or uncontrolled via defaultValue), shares its variant / size / iconOnly with the toggles, and switches between single- and multiple-select with multiple.

Each part carries a data-slot (toggle, toggle-group) for host-side styling — pair it with the data attributes (data-pressed, data-disabled, data-orientation, data-multiple). The group is fully keyboard-operable and RTL-aware.

On surfaces

The same control re-tuned across the elevation scopes — the root canvas, an elevated panel, a menu, and a sunken well. It stays legible on every layer.

root
elevated
menu
sunken

Theme scope

ThemeScope re-tunes a whole region's shape — corner radius, density, and type scale — through the cascade, with no per-component prop and without touching the app-wide theme. Tweak the knobs below and watch every toggle inside the scope retune together. See Customization for nesting, reset, and the portal caveat.

Design tokens

Generated from the component's declaration — the same graph that mints the CSS, so a variable name or its resolution default can't drift. The minted tokens are the public override seam: set one on any ancestor and every toggle in that region retunes — e.g. .toolbar { --noctis-toggle-border-radius: var(--noctis-radius-sm); } softens the corners. See Customization for the full override ladder and Tokens for the whole graph.

Token

API reference

Generated from the component's types — every prop, type, default, and description comes straight from the source.

Prop

AttributeDescription
data-slotThe rendered toggle (or group) element.
data-variantThe visual emphasis — `ghost` (transparent) | `primary` (primary-filled pressed) | `outline` (bordered).
data-sizeThe size scale — `xs` | `sm` | `md` | `lg`; the generated layer keys the per-size internals off it.
data-pressedPresent on a pressed (on) toggle.
data-disabledPresent on a disabled toggle or group.
data-attachedPresent on a group drawing the recessed segmented/connected track.
data-multiplePresent on a group that allows several toggles pressed at once.
data-orientation`horizontal` | `vertical` — the group's orientation.
Prop