ComponentsData display

Saved views

Named list configurations — “My open deals”, “Probation ending”, “Partners at risk” — as tabs above any list. A view stores filters, sort, columns and density; edits show a Modified strip with Save, Save as new and Reset. Personal or team scope, a default view, share links with ?sv=, and a dropdown form for narrow headers. Persistence stays in your app.

Tabs pattern (manual activation) + Radix Dropdown Menu + Dialog data-table/saved-views.tsx, data-table/view-state.ts, data-table/types.tstheme · material · accent · density · font

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { SavedViews } from "@vamos-ui/react/data-table";

<SavedViews
  views={views}
  activeId={activeId}
  current={currentViewState}
  onSelect={setActiveId}
  onReset={reset}
  onSave={createView}
  onUpdate={updateView}
/>

// Inside a DataTable the binding is automatic:
<DataTableSavedViews views={views} onSave={createView} onUpdate={updateView} />

The ⋯ actions button sits next to the tablist (not inside it), so the tablist only contains tabs.

Dirty state is announced politely (“View modified.”).

Examples

Team views and permissions (CMS)

canEdit decides who may overwrite or delete; read-only views can be saved as a new personal view.

Dropdown and overflow (PRM)

variant="select" (automatic under 420px) and maxVisible tabs with the rest under More.

Bound to a Data Table

DataTableSavedViews applies the view to the table and computes dirty state with viewStateEqual.

Partners
Ridgeway Logistics
Türkiye
Lead
$31,052.00
Northwind Traders
Spain
Lead
$36,127.00
İstanbul Kahve Co.
Japan
Qualified
$44,518.00
Selvane Bio
Netherlands
Lead
$39,273.00
Kestrel Robotics
Germany
Proposal
$55,554.00
Pemberly Confectionery
Germany
Qualified
$67,674.00
Fernhill Media
Canada
Qualified
$33,294.00
Orchard Systems
United States
Lost
$84,248.00

1–8 of 80

API

SavedViews

PropTypeDefault
views
{ id, name, state: ViewState, scope: personal | team, isDefault?, icon?, ownerId?, system? }.
SavedView[]—
activeId
Active view; null = All (unsaved).
string | null—
current
The live list configuration (from useDataTable().savedViewsBinding or your own list).
ViewState—
isDirty
Default: !viewStateEqual(current, active.state) — order-insensitive, ignores clause ids and page.
boolean—
onSelect
Tabs use manual activation: arrows move focus, Enter / Space switch (switching usually fetches).
(id: string | null) => void—
onSave
Create from the dialog (current state) or Duplicate (state set). Resolve with the stored view to activate it.
({ name, scope, isDefault?, state? }) => SavedView | Promise<SavedView | void>—
onUpdate
Save: overwrite the active view.
(id, state) => void | Promise<void>—
onRename / onDelete / onSetDefault
⋯ menu actions. Delete confirms first; deleting the active view falls back to the default.
(id, …) => void | Promise<void>—
onReset
Drop unsaved changes.
() => void—
getShareUrl
Copy link. Default: the current URL with sv=<id>.
(id) => string—
permissions
Team scope in the dialog; who may save, rename and delete. System views are never editable.
{ canCreateTeam?, canEdit?(view) }—
variant
auto switches to select under 420px of container width.
"auto" | "tabs" | "select""auto"
showAll
Built-in “All” entry.
booleantrue
maxVisible
Tabs before More (the active view always stays visible).
number4
sortByName
Sort with the locale collator (system views first).
booleanfalse
panelId
aria-controls target (the list the tabs drive).
string—
size
Tab height.
"sm" | "md""md"
labels
Built-in strings (savedViews namespace).
Partial<SavedViewsLabels>—

Helpers

PropTypeDefault
viewStateEqual(a, b)
Order-insensitive comparison used for dirty state.
boolean—
toViewState(listState)
What a view stores (no page position; keeps page size).
ViewState—
applyViewState(list, view, id, base?)
Apply a view and reset to the first page.
ListState—
resolveInitialView(views, urlId)
URL sv → the default view → All.
SavedView | null—