Skip to content

feat(react): add the Switch primitive#7

Open
ivanbanov wants to merge 2 commits into
mainfrom
feat/switch
Open

feat(react): add the Switch primitive#7
ivanbanov wants to merge 2 commits into
mainfrom
feat/switch

Conversation

@ivanbanov

Copy link
Copy Markdown
Member

Summary

Adds the Switch primitive as two packages:

  • @dunky.dev/switch — the framework-free core: a state machine (built on @dunky.dev/state-machine) owning the checked/unchecked graph, the disabled guard, and the connect that exposes parts and reactions.
  • @dunky.dev/react-switch — the thin React binding rendering the compound component on top of the core connect.

A switch is a binary on/off control that takes effect immediately (airplane mode, dark theme), following the WAI-ARIA APG switch pattern. Checked state is exposed both controlled and uncontrolled, and every toggle is reported back through onCheckedChange.

Anatomy

<Switch>          - root; owns checked state, renders nothing of its own
  |_ <Control>    - the interactive element: switch role + checked state
  |  |_ <Thumb>   - the knob; purely visual, styled off data-state
  |_ <Label>      - names the control; pressing it toggles

Behavior

  • The Control carries role="switch" with aria-checked always true or false — never mixed.
  • Space toggles (and Enter, via the natively activatable element); control press, label press, and keyboard activation all send the same toggle intent.
  • The Label is not a native <label>: it carries its own press binding and names the control through aria-labelledby, which only ever references a rendered Label.
  • Disabled gates user intent in the machine — control and label alike — and is exposed as aria-disabled; controlled/programmatic changes still apply so consumer state never desyncs.
  • Every part carries data-state="checked" | "unchecked" and data-disabled as styling/animation hooks.

Test plan

  • pnpm test:ci
  • pnpm typecheck
  • pnpm lint
  • pnpm format:check
  • pnpm build

🤖 Generated with Claude Code

ivanbanov and others added 2 commits July 18, 2026 10:29
Adds @dunky.dev/switch (core machine) and @dunky.dev/react-switch
(React binding). Anatomy: Switch root owning checked state, with
Control (switch role) wrapping a visual Thumb, plus a Label whose
press also toggles.

A binary on/off control per the WAI-ARIA APG switch pattern:
controlled/uncontrolled checked state, press/Space toggles, disabled
gates user intent in the machine, and every part carries data-state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ivanbanov ivanbanov changed the title feat: add the Switch primitive feat(react): add the Switch primitive Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant