)
}
/** Full column catalog — same HubTable as `/columns` (Column types showcase). */
export function TableColumnsPreview() {
const navigate = useNavigate()
const dashboardHref = useProductDashboardHref()
const columnsHref = `${dashboardHref.replace(/\/dashboard$/, "")}/columns`
return (
Every shipped cell pattern: person identity, status, progress, currency, rating, tags,
attachments, links, and row actions. Preview shows five rows —{" "}
View more opens the Column types hub.
Select rows to open the floating bulk-action bar.
Two rows are pre-selected. The bar is a full-width inverse slab pinned to
the viewport bottom, aligned to the table width. It takes the canvas ink
as its surface, so it reads near-black on a light theme and near-white on
a dark one, and accents keep their own meaning on it. Pass structured{" "}
bulkActions on{" "}
HubTable or a custom{" "}
bulkActionsSlot on{" "}
DataTable. Every action
must declare a shortcut.{" "}
Esc clears selection.
Destructive actions use solid{" "}
destructive fill here, since
the usual tint all but disappears on a slab.
Pass toolbarActions to put a
hub's commands on the toolbar row. They land after{" "}
Properties, behind a
separator, so the row reads as view controls first and commands second.
Three row actions show at most; the rest join anything marked{" "}
placement: "overflow"{" "}
under More. Narrow the window to watch labels drop to glyphs, then
secondaries move into More while the filled primary stays. Every action
needs a shortcut, and it
stays bound from wherever the action currently sits.
These act on the hub, so they never wait for a selection. Commands that
act on selected rows belong
in bulkActions instead. A
page gets one filled primary, so put it here or in{" "}
PageHeader.actionItems, not
both.
row.id}
getRowSelectionLabel={(row) => row.name}
state={state}
defaultSort={{ key: "name", dir: "asc" }}
emptyState="No questions match your filters."
edgeInset={false}
selectable={false}
toolbarActions={toolbarActions}
/>
)
}
const PROGRAM_OPTIONS = [
{ value: "pt", label: "Physical therapy" },
{ value: "ot", label: "Occupational therapy" },
{ value: "nursing", label: "Nursing" },
{ value: "pa", label: "Physician assistant" },
{ value: "slp", label: "Speech language pathology" },
] as const
export function SelectPreview({
position = "item-aligned",
}: {
position?: "item-aligned" | "popper"
}) {
const [value, setValue] = React.useState("pt")
const triggerId = position === "popper" ? "ds-select-popper" : "ds-select"
return (
Program
)
}
/** Groups, labels, and separators. */
export function SelectGroupsPreview() {
const [value, setValue] = React.useState("pt-dpt")
return (
Placement track
)
}
/** Long scrollable list. */
export function SelectScrollablePreview() {
const [value, setValue] = React.useState("site-12")
return (
Clinical site
)
}
/** Invalid + disabled + size variants. */
export function SelectStatesPreview() {
return (
Required programSelect a program to continue.Locked cohortCompact size
)
}
export function CommandPreview() {
return (
No results.Go to LibraryOpen settings
)
}
export function SelectionTileGridPreview() {
const [tile, setTile] = React.useState("csv")
return (
)
}
/** Settings rows — fixed label column prevents wrap in doc examples */
const TOGGLE_SETTINGS_LABEL = "min-w-0 shrink-0 sm:min-w-[9rem]"
export function ToggleSwitchLabelLeftPreview() {
const [on, setOn] = React.useState(true)
return (
Notifications
Email when published
)
}
export function ToggleSwitchLabelRightPreview() {
const [on, setOn] = React.useState(false)
return (
Dark mode
)
}
export function ToggleSwitchGroupPreview() {
const [email, setEmail] = React.useState(true)
const [push, setPush] = React.useState(false)
const [digest, setDigest] = React.useState(true)
return (
Email alerts
Push notifications
Weekly digest
)
}
/** @deprecated Use section-specific previews — kept for catalog re-export. */
export function ToggleSwitchPreview() {
return
}