Skip to content

feat(react): add the Tabs primitive#9

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

feat(react): add the Tabs primitive#9
ivanbanov wants to merge 2 commits into
mainfrom
feat/tabs

Conversation

@ivanbanov

Copy link
Copy Markdown
Member

Summary

Adds the Tabs primitive across two packages:

  • @dunky.dev/tabs — the framework-free core: a state machine (built on @dunky.dev/state-machine) that owns selection, focus movement, and activation behavior, plus a connect exposing the bindings.
  • @dunky.dev/react-tabs — the thin React binding: a compound <Tabs> component that renders the machine's bindings, adding no behavior of its own.

The primitive implements the WAI-ARIA APG tabs pattern: a set of layered content sections (panels) where exactly one panel is shown at a time, selected via its tab.

Anatomy

  • Tabs — root; owns the machine, wires controlled/uncontrolled value.
  • Tabs.List — the role="tablist" container for triggers.
  • Tabs.Trigger — a role="tab" button; value links it to its content panel.
  • Tabs.Content — a role="tabpanel" shown when its value is selected.

Behavior

  • Controlled (value + onValueChange) and uncontrolled (defaultValue) selection.
  • Roving tabindex: only the current tab is in the tab sequence.
  • Arrow-key navigation with wrap-around and disabled-tab skipping; Home/End jump to the first/last enabled tab.
  • orientation="horizontal" | "vertical" switches the active arrow axis and aria-orientation.
  • activationMode="automatic" | "manual": automatic selects on focus; manual selects on Enter/Space/click.
  • ARIA wiring: aria-selected, aria-controls, and aria-labelledby link tabs and panels; disabled tabs are skipped, not focus-trapped.

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:54
Anatomy: Tabs (root) with Tabs.List, Tabs.Trigger, and Tabs.Content,
backed by an agnostic core machine (@dunky.dev/tabs) and a React
binding (@dunky.dev/react-tabs).

WAI-ARIA APG tabs: controlled/uncontrolled selection, roving tabindex,
arrow-key navigation with wrap and disabled-tab skipping, horizontal or
vertical orientation, automatic or manual activation.

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 Tabs primitive feat(react): add the Tabs 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