Code Tabs
betaTabs of code snippets — pnpm, npm, yarn, bun — with a springing indicator, a blur cross-fade, a panel that eases to each snippet's height, and a syncKey that switches every instance on the page together and remembers the choice.
- Data
- 1 file
- 2 npm packages
- Accessibility notes
- Animates with motion
Loading the example…
pnpm dlx @dowel-ui/cli add code-tabsnpm packages installed: class-variance-authority, motion.
import { CodeTabs } from "@/components/ui/code-tabs";Default
Underline
Synced
Languages
<CodeTabs>
| Prop | Type | Default |
|---|---|---|
tabs (required) | CodeTab[] | — |
copyLabelNames the copy button. | string | "Copy code" |
defaultValueThe tab active at first render (uncontrolled). Defaults to the first. | string | — |
dir | "ltr" | "rtl" | — |
hideCopyHides the copy button. | boolean | false |
indicator | "pill" | "underline" | "pill" |
listLabelNames the tab list. | string | "Code variants" |
onValueChange | (value: string) => void | — |
syncKeyInstances sharing a key switch together and remember the choice in localStorage. A remembered value this instance does not offer is ignored. | string | — |
valueThe active tab's value (controlled). | string | — |
Plus every attribute of <div> except defaultValue, dir.
Built on Dowel's Tabs, so it is the WAI-ARIA tabs pattern: a named tablist (listLabel), arrows and Home/End move between tabs, and only the active tab is in the tab sequence. The panel itself is not a tab stop; the code region inside it is — a focusable pre named by the tab's label, so horizontally overflowing code is reachable by keyboard. The copy button always copies the visible snippet and announces success or failure through a polite status region. The travelling indicator and tab glyphs are aria-hidden; selection is conveyed by aria-selected. A synced change from another instance or browser tab moves the selection without moving focus. Nothing animates on first paint, and under reduced motion the indicator, cross-fade and height change are instant.
9/9
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — passes
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — passes
- className merged — passes
- Visible focus — does not apply
- No fixed widths — passes