Getting started
Foundations
Integrations
Form19
Display5
Layout4
Navigation4
Overlay8
Feedback4
Motion19
#Installation
npx @dinachi/cli@latest add animated-tabs#Usage
tsx
import {
AnimatedTabs,
AnimatedTabsList,
AnimatedTabsTrigger,
AnimatedTabsContent,
} from "@/components/ui/animated-tabs"tsx
<AnimatedTabs defaultValue="overview">
<AnimatedTabsList>
<AnimatedTabsTrigger value="overview">Overview</AnimatedTabsTrigger>
<AnimatedTabsTrigger value="activity">Activity</AnimatedTabsTrigger>
</AnimatedTabsList>
<AnimatedTabsContent value="overview">Overview panel</AnimatedTabsContent>
<AnimatedTabsContent value="activity">Activity panel</AnimatedTabsContent>
</AnimatedTabs>#Examples
#When to use it
The travel carries the eye from the old selection to the new one, so it earns its place on a small, stable strip and loses it on a long one.
| Use it for | Not for |
|---|---|
| A settings pane, a profile, a chart's time range. | A strip long enough to scroll. The pill will travel somewhere off screen. |
| Three to five tabs. | A dozen entries. The further the pill goes, the more it reads as a delay. |
Reach for the core Tabs in the cases on the right.
#Styling
- The pill takes its own class.
indicatorClassNamethemes it without touching the tab, so a coloured pill does not mean restyling the label too. - The selected tab is
data-[active], the attribute Base UI sets. Recolour the label withdata-[active]:text-primary-foregroundwhen the pill is dark. - Labels can be any width. The pill is measured, not calculated, so a strip of uneven labels needs no offsets.
#Behaviour
- Pointer changes travel, keyboard changes cut. Arrow keys repeat far more often than clicks, and animating them puts the pill between the keypress and the answer.
- No overshoot. The spring is critically damped: a click carries no momentum, so a bounce on arrival is motion the gesture never asked for.
- Reduced motion cuts too, matching the keyboard path.
#Accessibility
- Roving focus and
aria-controlscome from Base UI's Tabs, not from this component. - Arrow keys move focus, Enter or Space selects. Pass
activateOnFocusto select on arrow instead. - The pill is
aria-hidden. A screen reader hears the selection once, fromaria-selected, and never as a stray element.
#API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| value | any | — | Selected tab, controlled |
| defaultValue | any | — | Initially selected tab, uncontrolled |
| onValueChange | (value, details) => void | — | Fired when the selection changes |
| activateOnFocus | boolean | false | Select on arrow key rather than on Enter or Space |
| transition | Transition | spring, 0.3s | Overrides the indicator spring |
| indicatorClassName | string | — | On AnimatedTabsTrigger. Class applied to the travelling pill |