Components

Tabs

Glass tabs with a lifting, magnifying lens you can drag across tabs, keeping the keyboard navigation of shadcn Tabs.

Press and drag across the tabs. The lens lifts, magnifies what is under it, and lands.

All your moments.

Installation

pnpm dlx shadcn@latest add https://liquidcn.snmandela.com/r/liquid-tabs.json

The command copies these files into your project:

  • components/ui/liquid/tabs.tsx
  • components/ui/liquid/liquid.css
  • lib/liquid/motion.ts
  • lib/liquid/lens.ts
  • lib/liquid/lens-parts.ts
  • lib/liquid/refraction.ts

It extends the shadcn tabs component, whichever primitive library yours is built on. If your project doesn't have it yet, the CLI adds it from shadcn's registry; if it does, yours stays as it is, and the CLI asks before replacing it.

Usage

import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/liquid/tabs"

<Tabs defaultValue="photos">
  <TabsList aria-label="Library">
    <TabsTrigger value="photos">Photos</TabsTrigger>
    <TabsTrigger value="albums">Albums</TabsTrigger>
  </TabsList>
  <TabsContent value="photos">Your photos</TabsContent>
  <TabsContent value="albums">Your albums</TabsContent>
</Tabs>

Examples

Tab bar

Add liquid-tabbar to the list to stack icons over labels, as in iOS apps.

Keypad

Neutral lens

Set --liquid-lens-ink to var(--liquid-ink) when blue labels would compete with the content.

This week

API reference

TabsList

Adds the lens. Every prop of the shadcn TabsList is forwarded; Tabs, TabsTrigger, and TabsContent are the shadcn parts with liquid styles.

PropTypeDefault
className

Add liquid-tabbar for an iOS tab bar with icons over labels.

stringNone
--liquid-lens-ink

Color of the labels under the lens.

CSS colorvar(--liquid-accent)

Motion

ParameterValue
Bar pressThe whole bar grows to 1.025
Lens lift+16% along the bar, +34% across it, 12% magnification
Lens stretchAlong the direction of travel, up to 24% at 5200 px/s
Scrub start6 px of pointer travel
LandingLift returns to 0 once within 15% of the target

Springs keep their velocity when interrupted, and every value here is removed under reduced motion. How the motion works

Accessibility

  • Tabs semantics from the base component: tablist, tab, and tabpanel roles, with arrow keys, Home, and End.
  • The lens shows an inert, aria-hidden copy of the list. Screen readers only meet the real tabs.
  • A drag selects the tab where it is released and moves focus with it, so the roving tab stop stays in sync.