Micro-interactions

Segmented

A segmented control whose indicator travels on a shared layout id and smears in the direction it is moving.

Install

bun add motion clsx tailwind-merge

Then copy 2 files into your project:

  • components/registry/segmented/segmented.tsx
  • lib/utils.ts

Props

PropTypeDefaultDescription
indicator"solid" | "outline" | "underline""solid"How the active segment is marked. All three are the same travelling element at different settings — the shared layout id does not change, so switching between them costs no extra animation code.
sizing"auto" | "equal""auto"Auto sizes each segment to its label, so the indicator resizes as well as travels — the half of the FLIP that equal-width tabs never show. Equal splits the row evenly and fills the container.
density"comfortable" | "compact""comfortable"Padding and type size. Compact is the toolbar setting; it shortens the travel too, which is why the smear reads more subtly there.
radiusnumber8Corner radius of the indicator and the segments. motion corrects the radius through the layout animation, so a rounded indicator does not go oval while it is resizing.
stiffnessnumber520Spring tension on the travel. It also drives the proxy spring the deformation is read from, so the smear stays in phase with the movement at every setting rather than at the one it was tuned on.
dampingnumber34Spring friction. Low lets the indicator ring past the segment and come back, which the smear follows in both directions; high arrives dead and barely deforms at all.
smearnumber0.5How hard the travel deforms the indicator. The stretch is along the direction of movement and anchored at the leading edge, so it trails behind rather than running ahead. Zero is a rigid box that slides.
glowbooleantrueAccent bloom under the indicator. It travels with the box and takes the same deformation, so it reads as light coming off the thing rather than a separate shape following it.
accentColorstring (hex)"#a855f7"The indicator, its bloom, and the label of the active segment when the indicator is not filling it.

What It Demonstrates

Direction-aware transition
Content slides one way going forward and the opposite way going back, so navigation has a sense of direction.
Layout animation
When an element's size or position changes, it animates to the new spot instead of snapping.
Squash & stretch
Deforming an element as it moves to convey weight, speed, and flexibility.
Velocity
How fast and in which direction an element is moving. A spring carries it into the next animation when interrupted, so a flicked element keeps its speed.
Spring
Motion driven by physics (tension, mass, damping) rather than a set duration.

Related Components

Appears In