Dashboard table

Dashboard Table

Markdown

A tested composition for summary metrics, filtering, sorting, pagination, row actions, and complete data-request states.

Use this pattern for operational dashboards where people need both a quick summary and a detailed, actionable data set.

Workflow runs dashboard

This is composition guidance, not a registry item. Copy the example, replace loadRuns with an application request, and connect onViewRun to your router or detail panel.

Structure and surfaces

page canvas (base)
├── page heading and description
├── metric Card objects (layer-1)
└── Recent runs Section (layer-1)
    ├── section heading
    ├── search and status controls
    ├── loading, error, empty, or populated content
    │   └── Scroller
    │       └── semantic Table
    └── result count and Pagination

Use Card for each summary metric because each metric is a discrete content object. Use one Section for the table workflow because its heading, filters, results, and pagination operate on the same data set. Do not place the Table inside another Card.

Data and request states

Keep one owner for the request state. Set aria-busy on the dashboard region while summary metrics and rows are loading, keep the page heading mounted, and render decorative Skeleton placeholders inside the affected surfaces.

When loading fails, replace the table content with an inline error and Retry action. Do not use Toast as the only failure message because the empty table still needs an explanation.

Distinguish an initial empty data set from an empty filtered result:

  • An initial empty data set should explain how to create the first record.
  • A filtered empty result should keep the controls available and offer Clear filters.

Announce the filtered result count through a polite status region without moving visible content.

Filtering, sorting, and pagination

Treat search, status, sort direction, and page as one view state. Reset to page one whenever search or status changes so a valid filter cannot appear empty only because the previous page is out of range.

When Clear filters removes an empty-result action, return focus to the search field so keyboard users can immediately begin a new query.

Put sorting inside the relevant column header with TableSortButton. Update aria-sort on the header itself, and preserve the native table structure.

Use the full Pagination on wider screens. On narrow screens, switch to compact Pagination so the current page remains clear without forcing a long row of page numbers.

Table actions

Keep ordinary data tables native. Put a real link or Button inside the final cell instead of making the entire TableRow appear clickable.

Give every icon-only action a row-specific accessible name, such as View Production deploy. In an application, prefer a link when the action navigates and a Button when it updates local state or opens a detail panel.

Responsive behavior

  • Stack metric cards and filter controls before their contents become cramped.
  • Give the table a deliberate minimum width and wrap it in Scroller for narrow viewports.
  • Let Scroller own horizontal overflow, and set scrollable={false} on Table to avoid nested scroll containers.
  • Keep the action column within the same scroll region as its row.
  • Preserve the visible control order in the DOM at every breakpoint.
  • Verify the table at 200% zoom as well as common mobile widths.