Monet
@etched/monet 0.0.1

Toggle

Ported

A button that stays pressed until it is pressed again, for a view setting such as "Show archived" or bold text. Screen readers hear it as a pressed or not pressed button (aria-pressed). For a setting saved with a form, use a Switch or Checkbox. In a Toolbar, it joins the toolbar's arrow keys.

import { ArchiveIcon, PushPinIcon } from "@phosphor-icons/react";
import { Toggle } from "@etched/monet/toggle";

export function Preview() {
  return (
    <div className="row">
      <Toggle defaultPressed icon={<ArchiveIcon />}>
        Show archived
      </Toggle>
      <Toggle shape="square" aria-label="Pin run" icon={<PushPinIcon />} />
    </div>
  );
}

Installation

import { Toggle } from "@etched/monet/toggle";

Examples

Looks

Button's secondary, ghost and outline looks. Pressed adds the highlight fill and strong text.

import { Toggle } from "@etched/monet/toggle";

export function Looks() {
  return (
    <div className="rows">
      {(["secondary", "ghost", "outline"] as const).map((variant) => (
        <div key={variant} className="row">
          <Toggle variant={variant}>Show archived</Toggle>
          <Toggle variant={variant} defaultPressed>
            Mine only
          </Toggle>
        </div>
      ))}
    </div>
  );
}

Sizes

import { ArchiveIcon } from "@phosphor-icons/react";
import { Toggle } from "@etched/monet/toggle";

export function Sizes() {
  return (
    <div className="row">
      <Toggle size="sm" defaultPressed icon={<ArchiveIcon />}>
        Archived
      </Toggle>
      <Toggle defaultPressed icon={<ArchiveIcon />}>
        Archived
      </Toggle>
    </div>
  );
}

Icon only

shape="square" and an aria-label. The label stays the same; screen readers hear "pressed". Phosphor's fill weight marks the pressed icon.

Starred
import { StarIcon } from "@phosphor-icons/react";
import { useState } from "react";
import { Toggle } from "@etched/monet/toggle";

export function IconOnly() {
  const [starred, setStarred] = useState(true);

  return (
    <div className="row">
      <Toggle
        shape="square"
        aria-label="Star candidate"
        pressed={starred}
        onPressedChange={setStarred}
        icon={<StarIcon weight={starred ? "fill" : "regular"} />}
      />
      <span>{starred ? "Starred" : "Not starred"}</span>
    </div>
  );
}

Disabled

import { Toggle } from "@etched/monet/toggle";

export function Disabled() {
  return (
    <div className="row">
      <Toggle disabled>Show archived</Toggle>
      <Toggle disabled defaultPressed>
        Mine only
      </Toggle>
    </div>
  );
}

Accessibility

  • A native button: Space or Enter switches it on or off.
  • Its text names it. An icon-only toggle (shape="square") needs aria-label or aria-labelledby; the types require it.
  • Screen readers hear "pressed" or "not pressed" from aria-pressed. A disabled toggle keeps its pressed state.
  • In a Toolbar, it joins the toolbar's arrow keys; a disabled one leaves that order.
  • Keep the name the same in both states, such as "Show archived". For a setting saved with a form, use a Switch or Checkbox.

API reference

PropTypeDefaultDescription
variant"secondary" | "ghost" | "outline""secondary"In a ToggleGroup or a Toolbar, the toggle is always ghost.
size"sm" | "base""base"In a ToggleGroup or a Toolbar, theirs.
iconReactNode–Icon element before the label, for example <TextBIcon />. Phosphor's fill weight can mark the pressed state.
classNamestring–
shape"base" | "square""base"As wide as it is high.
aria-labelstring–
aria-labelledbystring–