Swipe tabs
FreeTabs for touch: swipe the content and the next panel follows the finger while the indicator slides in step.
pnpm dlx shadcn@latest add https://caliperui.site/r/swipe-tabs.json- Ostra: security review
- Kestrel: DPA signed
- Tide Physio: demo booked
- Priya mentioned you in Halberd renewal
- Tomás mentioned you in Q4 forecast
- Price the second Palisade property
- Send Lumen the annual quote
- Ostra order form sent
When to use #
Use it for
- Phone screens with a few sibling views.
- Feeds and filters people flick between.
Skip it when
- Desktop settings with many tabs; use tabs.
Installation #
terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/swipe-tabs.json
Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
example.tsx
import { SwipeTabs } from "@/components/ui/swipe-tabs" export function SwipeTabsDemo() { const card = (rows: string[]) => ( <ul className="grid gap-2 p-1"> {rows.map((row) => <li key={row} className="rounded-[10px] px-3 py-3 text-sm shadow-[inset_0_0_0_1px_var(--border)]">{row}</li>)} </ul> ); return ( <SwipeTabs className="w-full max-w-sm" label="Inbox views" tabs={[ { id: "all", label: "All", content: card(["Ostra: security review", "Kestrel: DPA signed", "Tide Physio: demo booked"]) }, { id: "mentions", label: "Mentions", content: card(["Priya mentioned you in Halberd renewal", "Tomás mentioned you in Q4 forecast"]) }, { id: "assigned", label: "Assigned", content: card(["Price the second Palisade property", "Send Lumen the annual quote"]) }, { id: "done", label: "Done", content: card(["Ostra order form sent"]) }, ]} /> ); }
API reference #
SwipeTabs
component
PropTypeDefault
tabs *readonly SwipeTab[]—
label *string—
defaultValuestring—
onValueChange((id: string) => void)—
classNamestring—
Accessibility #
It exposes tab, tablist and tabpanel semantics, with aria-label, aria-selected, aria-controls, aria-hidden and aria-labelledby kept in step with state.
KeyBehaviour
→Moves to the next item or value.
←Moves to the previous item or value.
HomeJumps to the first item or the minimum.
EndJumps to the last item or the maximum.
Motion #
It checks prefers-reduced-motion itself and settles immediately instead of travelling. Every state is still reachable.