PixelToggle

Two-state toggle button with aria-pressed semantics. Works standalone or as a child of PixelToggleGroup for single/multi-select toolbars.

  • Standalone — pressed + onPressedChange (React), v-model:pressed (Vue), [(pressed)] (Angular) — or composed inside PixelToggleGroup
  • Inherits size, variant, and surface from a parent PixelToggleGroup
  • Cyan tone pressed state with surface-aware borders, radius, and transitions
  • Renders as role="radio" with aria-checked inside a single-select group, aria-pressed otherwise
  • Registers with the group for roving-tabindex keyboard navigation
Status
stable
Category
forms
Since
v1.9.0

API

import { PixelToggle } from '@pxlkit/ui-kit';
PropTypeDefaultDescription
value (required)string—Identifies the toggle within its group; also exposed as data-pxl-toggle-value.
pressedboolean—Standalone (uncontrolled) toggle: pressed state.
onPressedChange(next: boolean) => void—Standalone (uncontrolled) toggle: notified on press change.
surface'pixel' | 'linear'—Surface override; defaults to the group's, then to the nearest provider.

Also takes the native attributes and event handlers of <button> (ButtonHTMLAttributes<HTMLButtonElement>).

ref points to <button>.

Accessibility

WCAG target: 2.1 AA

  • button

Standalone toggle exposes aria-pressed reflecting the boolean state. When wrapped by a single-select PixelToggleGroup the role is overridden to "radio" with aria-checked so screen readers announce "one of N" semantics. Data attributes data-state and data-pxl-toggle-value support styling and testing hooks.

Keyboard

KeyActionWhen
SpaceToggles the pressed state (native button activation).—
EnterToggles the pressed state (native button activation).—
ArrowRight / ArrowDownMoves focus to the next item.Inside a PixelToggleGroup with rovingFocus enabled.
ArrowLeft / ArrowUpMoves focus to the previous item.Inside a PixelToggleGroup with rovingFocus enabled.
Home / EndMoves focus to the first or last item.Inside a PixelToggleGroup with rovingFocus enabled.

Usage

import { useState } from 'react';
import { PixelToggle } from '@pxlkit/ui-kit';

export function Default() {
  const [pressed, setPressed] = useState(false);
  return (
    <PixelToggle value="bold" pressed={pressed} onPressedChange={setPressed}>
      Bold
    </PixelToggle>
  );
}

Examples

Default

import { useState } from 'react';
import { PixelToggle } from '@pxlkit/ui-kit';

export function Default() {
  const [pressed, setPressed] = useState(false);
  return (
    <PixelToggle value="bold" pressed={pressed} onPressedChange={setPressed}>
      Bold
    </PixelToggle>
  );
}

Pressed

import { useState } from 'react';
import { PixelToggle } from '@pxlkit/ui-kit';

export function Pressed() {
  const [pressed, setPressed] = useState(true);
  return (
    <PixelToggle value="italic" pressed={pressed} onPressedChange={setPressed}>
      Italic
    </PixelToggle>
  );
}

Surfaces

import { useState } from 'react';
import { PixelToggle } from '@pxlkit/ui-kit';

export function Surfaces() {
  const [pixel, setPixel] = useState(true);
  const [linear, setLinear] = useState(true);
  return (
    <div className="flex items-center gap-2">
      <PixelToggle
        value="pixel"
        surface="pixel"
        pressed={pixel}
        onPressedChange={setPixel}
      >
        Pixel
      </PixelToggle>
      <PixelToggle
        value="linear"
        surface="linear"
        pressed={linear}
        onPressedChange={setLinear}
      >
        Linear
      </PixelToggle>
    </div>
  );
}

Disabled

import { PixelToggle } from '@pxlkit/ui-kit';

export function Disabled() {
  return (
    <div className="flex items-center gap-2">
      <PixelToggle value="off" disabled pressed={false} onPressedChange={() => {}}>
        Disabled off
      </PixelToggle>
      <PixelToggle value="on" disabled pressed={true} onPressedChange={() => {}}>
        Disabled on
      </PixelToggle>
    </div>
  );
}

Related