Tabs
Tabs for switching between views within a surface, in three shapes over one mechanism. CSS cannot measure DOM geometry, so the active trigger's box is read in a layout effect and written onto the list as --indicator-x, -y, -w and -h; the indicator draws itself entirely from those four numbers, which is why its position and its width travel on a single transition. A MutationObserver re-measures when the active tab changes, a ResizeObserver catches reflow, and the first placement is flushed before the transition class is attached so the indicator lands on the active tab instead of gliding in from the corner.
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@pestoui/core"Default
Pill
The default track. Click across the row: the indicator's x offset and its width interpolate together on one transition, so the raised surface stretches and shrinks as it travels. Labels of deliberately different lengths make the width half of that visible — with equal-width tabs you would only ever see the slide.
Underline
The track goes away and the indicator becomes a thin bar on the active trigger's bottom edge. The measurement is unchanged — the bar still reads the same four custom properties, it just substitutes a fixed thickness for the measured height and rides the trigger's far edge. Travel and width interpolation are identical to the pill.
Segment
The filled track squared back to the surface radius, with a tighter inset — a segmented control rather than a pill. Same travel, same width interpolation; only the corner and the padding change, and the triggers follow the container's corner so the focus ring traces the shape the indicator does.
Why the indicator overshoots
Almost every travelling indicator in the system uses ease-spring-glide, which is overdamped on purpose: an element that arrives at a known destination and then bounces past it reads as imprecise. The tabs indicator is the one deliberate exception. It moves between two tabs the reader just chose, both of them still on screen, so a small overshoot reads as momentum rather than error — and the longer settle gives the selection some life instead of letting it snap into place. Click any tab: both rows travel at once, the top on the shipped overshoot, the bottom overridden to glide.
ease-spring-overshoot — ζ 0.84, crosses a little past the tab and settles back
ease-spring-glide — ζ 1.09, overdamped, so it never crosses the tab at all
Props
Pesto UI · 117 documented components