Skip to content

ToggleChip

A chip that toggles, such as a resource filter or a frequency choice. It only holds and reports its own state: what it changes is the page’s to do.

import { ToggleChip } from '@zitdevs/ui';

These demos are server HTML; the page runs enhanceToggleChips(document) from @zitdevs/ui/enhance, and prints each zd:toggle it hears.

Press a chip.

Press a chip.

<ToggleChip label="Guides" value="guides" count="8" defaultPressed />
import { TOGGLE_EVENT, type ToggleDetail } from '@zitdevs/ui/enhance';
document.addEventListener(TOGGLE_EVENT, (event) => {
const { value, pressed } = (event as CustomEvent<ToggleDetail>).detail;
// show or hide the cards of `value`
});

A caller that holds the state passes pressed and onPressedChange: a press asks, and the chip changes when pressed does, announcing nothing — the caller already knows.

'use client';
const [monthly, setMonthly] = useState(true);
<ToggleChip
label="Monthly"
value="monthly"
variant="pill"
pressed={monthly}
onPressedChange={setMonthly}
/>;
Prop Type Default Notes
label string required
value string required Reported in zd:toggle, so a listener need not parse the label.
variant 'filter' | 'pill' 'filter' The square resource chip, or the rounded choice chip.
count string — After the label, and read as part of the name.
defaultPressed boolean false The state it starts in. A new one starts the chip over.
pressed boolean — The state, for a caller that holds it.
onPressedChange (pressed: boolean) => void — The state the reader asks for. Controlled, it asks; uncontrolled, it reports.
disabled boolean false
ref Ref<HTMLButtonElement> —
className string — Placement. Merged last.
anything else <button> attributes —

Exported types: ToggleChipProps, ToggleChipVariant. From @zitdevs/ui/enhance: enhanceToggleChips, TOGGLE_EVENT, ToggleDetail, ToggleChipOptions, ToggleChipEnhancement.

  • A toggle button: a <button type="button"> whose aria-pressed always says true or false. Enter, Space and a click flip it.
  • The count is part of the name (“Guides 8”), so the number is never read out of context.
  • It draws the kit’s focus ring and its own type family.
  • A pressed filter’s count is on-primary: the lighter blue it replaces was 4.19:1.

It renders its first state and does nothing: never make it the only way to reach content. Flipping it needs the enhancer:

  • React: nothing to do. The button is a small client part that runs the enhancer once it has hydrated.
  • No React: load @zitdevs/ui/enhance and call enhanceToggleChips(document). Chips added later work once it runs again; a chip already enhanced is left as it is.

surface-raised, border-default and ink at rest, surface-hover on hover; pressed, primary with on-primary (filter) or ink with on-inverse (pill); muted, on-primary and on-inverse-muted for the count; the focus ring.