Theme: Smoke
Background: Field
Theme: Smoke
Background: Field
System

Thread tabs

The open sessions, one strip

Thread tabs is the top edge of a chat or agent product: every open session as a pill tab, the active one filled the way Thread panel fills its active row, with a hover-revealed close button and a trailing new-tab action. It is fully controlled and surface-less (the host owns which tabs exist and which is active), while the strip owns the choreography of a tab arriving and leaving.

Selection

Clicking a tab moves the controlled selection; the active pill fills and announces aria-current. Arrow keys, Home and End move focus along the strip.

Opening and closing

The strip animates its own changes: a new tab glides open in place, and a closed one folds away while its neighbours slide over. No measurement, just a grid track collapsing. The close button always holds its seat and only fades in on hover, keyboard focus, or the active tab, so revealing it never shifts the label; Delete closes the focused tab too. Try it: open a few sessions with the plus, then close them.

Status

A tab leads its label with the same status dot Thread panel's rows carry: a pulsing neutral dot while the session is working, then a solid dot in the info colour for unseen activity, the warning colour when it needs input, and the error colour when it failed. An idle tab draws no dot. Here, selecting a tab clears its dot.

Long labels

A long session title caps the tab's width and dissolves under a trailing mask rather than clipping to an ellipsis; the full text stays in the tab's tooltip. A crowded strip scrolls sideways.

tsx
// From the npm package
import { ThreadTabs } from 'rift-ds/components/ThreadTabs/ThreadTabs';

// Or as source you own, via the shadcn CLI
npx shadcn@latest add https://rift-ds.com/r/thread-tabs.json