feat(data-table): add reusable card/table view toggle

Add an opt-in card view to the shared data-table stack (DataTablePage),
toggled via a segmented control in the toolbar with per-table localStorage
persistence. Cards render generically from column meta by default, with an
optional renderCard slot. Defaults to table-only so existing pages are
unchanged.

Wire it into the channels page with a bespoke ChannelCard that reuses every
column's cell renderer, preserving all table information and interactions
(selection, inline priority/weight, balance refresh, status, actions, tag
expand).
This commit is contained in:
CaIon
2026-06-19 17:43:11 +08:00
parent 3fcd741c6e
commit 68585568d6
11 changed files with 908 additions and 188 deletions
@@ -115,6 +115,12 @@ export type DataTableToolbarProps<TData> = {
* Hide the View Options (column visibility) dropdown.
*/
hideViewOptions?: boolean
/**
* Optional view-mode toggle (e.g. table vs. card) rendered in the right
* action cluster, before the View Options dropdown. Typically a
* {@link DataTableViewModeToggle}. Omitted by default.
*/
viewToggle?: ReactNode
/**
* Content rendered on the LEFT side of the secondary action row. When
* provided the toolbar splits into two visual rows:
@@ -302,6 +308,8 @@ export function DataTableToolbar<TData>(props: DataTableToolbarProps<TData>) {
<DataTableViewOptions table={props.table} />
) : null
const viewToggleNode = props.viewToggle ?? null
const expandToggle = hasExpandable ? (
<Button
variant='ghost'
@@ -350,6 +358,7 @@ export function DataTableToolbar<TData>(props: DataTableToolbarProps<TData>) {
{props.preActions}
{resetButton}
{searchButton}
{viewToggleNode}
{viewOptionsNode}
</div>
</div>
@@ -373,6 +382,7 @@ export function DataTableToolbar<TData>(props: DataTableToolbarProps<TData>) {
{props.preActions}
{resetButton}
{searchButton}
{viewToggleNode}
{viewOptionsNode}
{expandToggle}
</div>