Accent Components

Data table

THE listing — tree icons, search, per-column sort, selection with bulk verbs; folders interleave by name.


The list a CMS lives in, as a component: CmsDataTable (src/components/CmsDataTable.tsx) is the system data table. Container contents, the media library, Site Info's inventory, and the Fields, Content Types, and Layouts registries all render through it, so every listing in the admin has the same anatomy: tree icons on names, a search filter, per-column sorting, and a selection column whose bulk verbs appear when a caller wires them. The markup underneath is the mk-table grammar — this component is that grammar with the behavior attached.

Rows

A row is data, not markup:

Field Says
key Stable identity for React and selection.
title The Name cell. Sorting and search read it.
typeId The row's kind in the lane's own words — a content-type id, folder, a media kind. Search reads it too.
icon Tree icon id (page, folder, container, …) — the same vocabulary the site tree uses.
leading Custom leading visual (a media thumbnail); wins over icon.
status / updated Feed the default asset columns.
cells Values for custom columns, keyed by column key.
onOpen What clicking the row does. Omit it and the row renders inert — a trashed asset, say.

The row opens the entity; verbs ride in a trailing column. A row is not a place for five buttons — actions go in a custom column marked interactive: true, so clicks inside it do not also open the row.

Columns

The default trailing columns describe assets: Type, Last modified, Status. A lane whose rows are not assets replaces them wholesale with columns — Site Info passes a Count column, Fields passes Key and Type. A column with a sortValue opts into header sorting; without one it is display-only.

Ordering

Rows sort by the active column across all rows — folders interleave with everything else by name rather than pinning to the top. That is a ruling, not an accident: every folder view runs through this one table, and a folders-first exception would fork the listing again. If grouping is ever wanted, it arrives as a sortable kind column, not a pin rule.

Selection

Wire onSelectionChange and the checkbox column appears; bulkActions renders the verbs beside the selection count while something is selected. The checkboxes exist to facilitate bulk actions — no verbs, no checkboxes.