component · 40/108
Page Tabs
Primary tabs with counts, page actions, and horizontal overflow.
Install
Install manuallyView source on GitHub
Anatomy
- PageTabs
- PageTabsBar
- PageTabsList
- PageTabsTab
- PageTabsActions
- PageTabsPanel
Accessibility4 checks
- Implements the WAI-ARIA tabs pattern with tablist, tab, and tabpanel roles linked by generated ids.
- Arrow keys move and activate tabs automatically, Home and End jump to the ends, and disabled tabs are skipped.
- Only the selected tab is in the tab order. Page actions sit outside the tab list and keep normal tab order.
- The tab list scrolls horizontally and keeps the selected tab in view.
Navigation and layout
24 open issues across checkout and onboarding.
6 issues are waiting for design review.
2 issues are blocked by the payments migration.
Closed issues from the last 30 days.
Code example
usage.tsx"use client";import { Plus, Settings2 } from "lucide-react";import { PageTabs, PageTabsActions, PageTabsBar, PageTabsCount, PageTabsList, PageTabsPanel, PageTabsTab, type PageTabsVariant,} from "@/components/ui/uai/page-tabs";const actionStyle = { display: "inline-flex", alignItems: "center", gap: 6, height: 28, padding: "0 12px", border: 0, borderRadius: 999, background: "var(--uai-surface-raised)", color: "var(--uai-text)", font: "inherit", fontSize: 12.5, fontWeight: 500, cursor: "pointer",} as const;export function PageTabsPreview({ variant = "underline" }: { variant?: PageTabsVariant }) { return ( <PageTabs variant={variant} defaultValue="open"> <PageTabsBar> <PageTabsList aria-label="Issues"> <PageTabsTab value="open"> Open <PageTabsCount>24</PageTabsCount> </PageTabsTab> <PageTabsTab value="review"> In review <PageTabsCount>6</PageTabsCount> </PageTabsTab> <PageTabsTab value="blocked"> Blocked <PageTabsCount>2</PageTabsCount> </PageTabsTab> <PageTabsTab value="closed">Closed</PageTabsTab> <PageTabsTab value="archived" disabled> Archived </PageTabsTab> </PageTabsList> <PageTabsActions> <button type="button" aria-label="View options" style={{ ...actionStyle, padding: 0, width: 28, justifyContent: "center", borderRadius: 8, background: "transparent", color: "var(--uai-muted)", }} > <Settings2 size={14} aria-hidden="true" /> </button> <button type="button" style={{ ...actionStyle, background: "var(--uai-accent)", color: "var(--uai-accent-foreground)", }} > <Plus size={14} aria-hidden="true" /> New issue </button> </PageTabsActions> </PageTabsBar> <PageTabsPanel value="open">24 open issues across checkout and onboarding.</PageTabsPanel> <PageTabsPanel value="review">6 issues are waiting for design review.</PageTabsPanel> <PageTabsPanel value="blocked">2 issues are blocked by the payments migration.</PageTabsPanel> <PageTabsPanel value="closed">Closed issues from the last 30 days.</PageTabsPanel> </PageTabs> );}Manual installation
page-tabs.tsxLoading component source…