Glass tab barPro
A floating Liquid Glass tab bar that refracts what scrolls beneath it, with a glass lens that glides, magnifies and can be dragged between tabs, and an optional search bubble; it compacts on scroll down.
Live · keyboard ready
- Mobile web apps and PWAs with three to five top level sections and one global action such as search.
- Content feeds where the bar should step aside while reading and come back on scroll up.
- Desktop layouts with many sections; use a sidebar or morph-nav.
- Switching views inside a card; use segmented-control or tabs.
Installation
Pro source and install commands unlock with a Pro plan.
example.tsx
import { GlassTabBar } from "@/registry/components/glass-tabbar/glass-tabbar";import { Bookmark, Compass, House, Search, UserRound } from "lucide-react"; export function AppShell() { const [tab, setTab] = useState("home"); return ( <GlassTabBar className="tabbar" value={tab} onValueChange={setTab} items={[ { value: "home", label: "Home", icon: <House /> }, { value: "explore", label: "Explore", icon: <Compass /> }, { value: "saved", label: "Saved", icon: <Bookmark />, badge: 3 }, { value: "profile", label: "Profile", icon: <UserRound /> }, ]} action={{ value: "search", label: "Search", icon: <Search /> }} /> );}API reference
2 parts. The first is the root.
GlassTabBar
A floating Liquid Glass tab bar. The bar refracts what scrolls under it, and the selected tab sits under a glass lens that glides, lifts, and magnifies as it moves and can be dragged across the tabs. An optional round action bubble sits beside it, and the bar shrinks to a compact pill of icons on scroll down.
PropTypeDefaultDescription
itemsRequiredGlassTabBarItem[]–Tabs with value, label, icon, and an optional badge.valuestring–Controlled active tab. A value that matches no tab, or the action, hides the lens.defaultValuestring–Initial active tab when uncontrolled. Defaults to the first item.onValueChange(value: string) => void–Called when a tab or the action is chosen by tap, drag, or keyboard.actionGlassTabBarItem–A separate round glass tab beside the bar, such as search. It takes part in selection and keyboard order like any tab.compactboolean–Controlled compact state.defaultCompactbooleanfalseInitial compact state when uncontrolled.onCompactChange(compact: boolean) => void–Called when the bar shrinks or grows.scrollRefRefObject<HTMLElement | null>–Scroll container to watch. Leave it out to watch the window.collapseOnScrollbooleantrueShrink on scroll down and grow on scroll up.labelstring"Tabs"Accessible name of the navigation and its tab list.classNamestring–Extra class on the nav. Position the bar here, usually fixed or absolute at the bottom.styleCSSProperties–Inline style on the nav.GlassTabBarItem
One tab, or the action.
PropTypeDefaultDescription
valueRequiredstring–Unique value.labelRequiredstring–Visible label and accessible name. The action shows only its icon and uses the label as its name.iconRequiredReactNode–Icon at 22px; lucide icons are sized automatically.badgenumber | string–Count shown as an accent badge on the icon. 0 or empty hides it.- Tab
- Moves focus to the selected tab; the tab list is one stop.
- Arrow leftorArrow right
- Moves to and selects the previous or next tab, including the action, wrapping around.
- HomeorEnd
- Selects the first tab or the last one.
- EnterorSpace
- Selects the focused tab and grows the bar if it is compact.
- Renders a nav landmark around a tablist; every tab, including the action, has role="tab" and aria-selected, with a roving tabindex.
- Labels stay in the accessibility tree when the bar is compact, so each tab keeps its name.
- Badges carry hidden text such as "3 new" for screen readers.
- Selection is carried by the lens, the accent tint, and aria-selected, never by color alone.
- Reduced transparency swaps the glass for a solid raised surface; increased contrast strengthens the tint, border, and ink.
- No focus rings are drawn, in line with the library.
- The lens glides on the smooth spring, which never overshoots. Its speed lifts it off the bar: it grows, stretches along the direction of travel, and turns into a clear lens that magnifies the icons under it, then settles back into a soft fill.
- Each tab's tint and icon scale follow the lens position, so the accent glides with it instead of switching.
- Press the selected tab and the lens lifts; drag past a few pixels and it follows the pointer across the bar; release snaps it to the nearest tab and selects it.
- One spring drives the compact morph: slot width, bar height, icon lift, and label fade all read from it, so the lens stays on its tab mid morph.
- Reduced motion moves the lens and the size instantly, with no lift, stretch, or magnification.
- Tabs share the available width, from 78px down to 56px each, so five tabs and an action fit a 390px screen. Compact tabs are 50px.
- The bar and lens take touch with pan-y, so vertical scrolling that starts on the bar still works.
- Motion values drive every frame; React renders only on tab, compact, or size changes. Nothing animates at rest.
- Chromium gets real refraction: an SVG displacement filter inside backdrop-filter bends the backdrop at the rim, with a slight per channel dispersion. Safari and Firefox are detected and keep a blur and saturation glass.
- The lens refraction is a fixed layer clipped to the lens; while it moves, only the clip and the filter's map rectangle update.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use it as the primary navigation of a mobile web app. Keep it to three to five tabs with short labels, plus at most one action.
- Pass the page's scroll container as scrollRef when the app scrolls inside an element instead of the window.
- Place it with position fixed or absolute at the bottom; the component centers itself and only the glass takes pointer events.
- Put photos or colorful content behind it; the material is designed to be seen over real content, not a flat page.
- Leave content room at the bottom (about 110px) so the last item is not hidden behind the bar.
The full library index for assistants is at /llms.txt.











