View Tabs
A table's saved views as a tab row — shared views, then the reader's own, a lock on locked views, a create menu, and one Select on narrow screens.
- Status
- Since
0.25.71- Accessibility pattern
- tablist with roving focus; a named Select when narrow
Last updated
Install
Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for View Tabs before installation. Retain the digest printed by this command.
pnpm exec vegastack-design verify view-tabsInstall with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.
pnpm dlx shadcn@4.21.0 add @vegastack/view-tabsRun the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.
The same command installs the registry items it composes: @vegastack/button, @vegastack/dropdown-menu, @vegastack/select, @vegastack/tabs, @vegastack/tooltip, @vegastack/use-overflow.
Usage
import { ViewTabs } from "@/components/ui/view-tabs";
<ViewTabs
views={[
{ id: "all", name: "All requests", kind: "grid", scope: "shared" },
{ id: "status", name: "By status", kind: "board", scope: "locked" },
{ id: "mine", name: "My follow-ups", kind: "grid", scope: "personal" },
]}
value={view}
onValueChange={setView}
onCreate={(kind) => openCreateView(kind)}
getViewActions={(view) => (
<DropdownMenuItem onClick={() => rename(view)}>Rename</DropdownMenuItem>
)}
/>;ViewTabs is the row of saved views over a table or a list. Shared views come first (a locked view
carries a lock), then a divider and the reader's own under Mine. Each tab shows the view's kind
— a grid or a board — and its name. onCreate adds a + menu with two items, Grid view and
Board view, and is called with the kind alone: the host's own create step names the view and
decides who sees it (an "Only visible to me" switch), so the menu never asks shared or personal. getViewActions puts the open view's
items (rename, duplicate, delete) in a ⋯ menu after the tabs. A long name ends in an ellipsis; when
it is cut, the full name shows in a tooltip on hover and keyboard focus, and the tab still reads the
whole name to a screen reader. The narrow select's list wraps a long name instead.
It is built on Tabs variant="line", which scrolls and keeps the active
tab in view. Below @3xl of its own container the row becomes one Select with the same two
groups. For a list/grid layout switch over the same data, use
ViewToggle instead.
Scope
| Behaviour | Where it lives |
|---|---|
| Which views exist, their order and who may change them | Host |
| Saving a changed view ("Save for everyone", "Reset") | Host |
| Rename, duplicate, delete | Host — through getViewActions |
| Naming a new view, shared or only visible to the maker | Host — after onCreate(kind) |
Examples
Narrow containers
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
onValueChange* | (id: string) => void | — | Called with the id of the view the reader opens. |
value* | string | — | The open view's id. |
views* | readonly ViewTabsView[] | — | Every view the reader can open, in the host's order within each group. |
aria-label | string | "Views" | Accessible name of the tab row. |
className | string | — | Extra classes for the root. |
getViewActions | ((view: ViewTabsView) => React.ReactNode) | — | The open view's menu items (DropdownMenuItems: rename, duplicate, delete…), shown in a ⋯
menu after the tabs. Return null for none. |
labels | Partial<ViewTabsLabels> | English | The component's words. |
onCreate | ((kind: ViewTabsView["kind"]) => void) | — | Offer the + menu: a grid view or a board view. Called with the kind picked; the host's own
create step names the view and decides whether it is shared or the reader's alone. Omit it
when the reader can't create views. |
ref | React.Ref<HTMLDivElement> | — | Ref to the root. |
Data attributes and CSS variables on ViewTabs
| Attribute | Values |
|---|---|
data-slot | "view-tabs" | "view-tabs-actions" | "view-tabs-create" | "view-tabs-divider" | "view-tabs-list" | "view-tabs-mine" |
View
| Prop | Type | Default | Description |
|---|---|---|---|
id* | string | — | Stable id — the value. |
kind* | "board" | "grid" | — | A table (grid) or a board. |
name* | string | — | The view's name. |
scope* | "locked" | "personal" | "shared" | — | shared and locked views are everyone's; personal ones are the reader's alone. |
Accessibility
- The tab row is a
tablistnamed byaria-label(default "Views"): one tab stop, arrows move, Enter or Space opens a view. A locked view is read as "By status, locked". - The + button is named "New view"; the ⋯ button after the open view's name ("All requests options").
- Narrow, the row is one
Selectwith the same name and the same Shared and Mine groups.
| Key | Action |
|---|---|
| ← → | Move between views. |
| Enter / Space | Open the focused view. |
| Tab | Leave the row for the + and ⋯ buttons. |
| Contract | States tested |
|---|---|
| Behaviour | default, with-personal, locked, create-menu, actions-menu, narrow |
| Accessibility | keyboard, labeled, roving-tabindex |
| Visual | default, active, locked, narrow |