Table

Lists records that share the same fields.

Examples

Runs with actions

Runs48
Worst first
Actions
run_8f29c8triageFailedfast-small22.6s22.0k
5m ago
run_8f2982triageFailedfast-small19.8s13.2k
11m ago
run_8f293ctriageFailedvision-medium17.0s4.5k
17m ago
run_8f28f6triageFailedvision-medium14.2s19.8k
23m ago
run_8f29e4escalationSlowvision-medium31.9s11.0k
2m ago
run_8f299eescalationSlowvision-medium29.1s2.3k
8m ago
run_8f2958escalationSlowreasoning-large26.3s17.6k
15m ago
run_8f2912escalationSlowreasoning-large23.5s8.9k
21m ago
run_8f28ccescalationSlowfast-small20.7s0.2k
27m ago
run_8f29f2eval-runnerRunningvision-medium16.1s17.6k
1m ago
run_8f29aceval-runnerRunningreasoning-large13.3s8.9k
7m ago
run_8f2966eval-runnerRunningreasoning-large10.5s0.2k
13m ago
run_8f2920eval-runnerRunningfast-small7.6s15.4k
20m ago
run_8f28daeval-runnerRunningfast-small4.8s6.7k
26m ago
run_8f29c1escalationQueuedvision-medium30.5s6.7k
6m ago
run_8f297bescalationQueuedvision-medium27.7s22.0k
11m ago
run_8f2935escalationQueuedreasoning-large24.9s13.3k
18m ago
run_8f28efescalationQueuedreasoning-large22.1s4.6k
24m ago
run_8f2a00support-agentOKreasoning-large0.2s0.1k
0s ago
run_8f29f9refund-agentOKfast-small8.2s8.8k
50s ago
run_8f29ddsupport-agentOKreasoning-large39.8s19.8k
3m ago
run_8f29d6refund-agentOKfast-small6.8s4.5k
4m ago
run_8f29cfeval-runnerOKvision-medium14.7s13.2k
4m ago
run_8f29basupport-agentOKreasoning-large38.4s15.4k
6m ago
run_8f29b3refund-agentOKfast-small5.3s0.1k
7m ago
run_8f2997support-agentOKreasoning-large37.0s11.1k
9m ago
run_8f2990refund-agentOKvision-medium3.9s19.8k
10m ago
run_8f2989eval-runnerOKreasoning-large11.9s4.5k
10m ago
run_8f2974support-agentOKfast-small35.6s6.7k
12m ago
run_8f296drefund-agentOKvision-medium2.5s15.4k
13m ago
run_8f2951support-agentOKfast-small34.2s2.3k
15m ago
run_8f294arefund-agentOKvision-medium1.1s11.1k
16m ago
run_8f2943eval-runnerOKreasoning-large9.1s19.8k
17m ago
run_8f292esupport-agentOKfast-small32.8s22.0k
18m ago
run_8f2927refund-agentOKvision-medium40.7s6.7k
19m ago
run_8f290bsupport-agentOKfast-small31.4s17.6k
21m ago
run_8f2904refund-agentOKreasoning-large39.3s2.4k
22m ago
run_8f28fdeval-runnerOKfast-small6.2s11.1k
22m ago
run_8f28e8support-agentOKvision-medium30.0s13.3k
24m ago
run_8f28e1refund-agentOKreasoning-large37.9s22.0k
25m ago
run_8f28c5support-agentOKvision-medium28.6s8.9k
28m ago
run_8f28berefund-agentOKreasoning-large36.5s17.7k
28m ago
run_8f28b7eval-runnerOKfast-small3.4s2.4k
29m ago
run_8f29ebtriageIdlereasoning-large24.0s2.3k
2m ago
run_8f29a5triageIdlefast-small21.2s17.6k
8m ago
run_8f295ftriageIdlefast-small18.4s8.9k
14m ago
run_8f2919triageIdlevision-medium15.6s0.2k
20m ago
run_8f28d3triageIdlevision-medium12.8s15.5k
26m ago

48 rows, sorted by Status worst first

A plain table

Recent runs3
RunAgentDurationStatus
run_8f2asupport-agent0.9sFailed
run_8f29triage41.0sSlow
run_8f28refund-agent12.8sRunning

Waiting on a person

Approvals5
3 waiting on you
run_3b19d2refund-agentRefund $184.20Waiting on you
run_51aa07support-agentClose 12 ticketsWaiting on you
run_77c0e4escalationEmail a customerWaiting on you
run_9c04e8triageReroute 40 ticketsApproved
run_0d7f3arefund-agentRefund $22.00Idle

5 rows, sorted by Status worst first

Live tickets

Tickets0Live

No rows.

0 rows

Open a run

run_8f2a00support-agentOKreasoning-large0.2s0.1k
run_8f29f9refund-agentOKfast-small8.2s8.8k
run_8f29f2eval-runnerRunningvision-medium16.1s17.6k
run_8f29ebtriageIdlereasoning-large24.0s2.3k
run_8f29e4escalationSlowvision-medium31.9s11.0k
run_8f29ddsupport-agentOKreasoning-large39.8s19.8k
run_8f29d6refund-agentOKfast-small6.8s4.5k
run_8f29cfeval-runnerOKvision-medium14.7s13.2k

8 rows

Actions for selected rows

Runs8
run_8f2a00support-agentOKreasoning-large0.2s0.1k
run_8f29f9refund-agentOKfast-small8.2s8.8k
run_8f29f2eval-runnerRunningvision-medium16.1s17.6k
run_8f29ebtriageIdlereasoning-large24.0s2.3k
run_8f29e4escalationSlowvision-medium31.9s11.0k
run_8f29ddsupport-agentOKreasoning-large39.8s19.8k
run_8f29d6refund-agentOKfast-small6.8s4.5k
run_8f29cfeval-runnerOKvision-medium14.7s13.2k

8 rows, 3 selected

Sizes

  • RunAgentDurationStatus
    run_8f2asupport-agent0.9sFailed
    run_8f29triage41.0sSlow

    sm

  • RunAgentDurationStatus
    run_8f2asupport-agent0.9sFailed
    run_8f29triage41.0sSlow

    defaultdefault

  • RunAgentDurationStatus
    run_8f2asupport-agent0.9sFailed
    run_8f29triage41.0sSlow

    lg

Kind

  • run_8f2asupport-agent0.9sFailed
    run_8f29triage41.0sSlow

    plaindefault

  • run_8f2asupport-agent0.9sFailed
    run_8f29triage41.0sSlow

    run

States

  • run_8f28Running

    rest

  • run_8f28Running
    4m ago

    hover

  • run_8f28Running

    focus

  • run_8f28Running

    selected

  • run_8f28Running

    open

  • run_8f29f9Running

    1 rows

    disabled

  • Loading rows

    loading

  • No runs yet

    Runs show up here when an agent starts one.

    0 rows

    empty

Usage

When to use it
Use
Many records with the same fields that a person compares across columns: runs, prompt releases, keys.
Use
A list the person sorts, filters or acts on in bulk.
Use
Exact values that need to line up: durations, counts, costs.
Not for
Each row is one line of mixed content and no columns compare. Use Item.

Rules

11 rules
Must
Give every table aria-label or a TableCaption. Because a screen reader announces an unnamed "table", and a page with two cannot be told apart in the tables list.
Must
Set meta.severity on a status column and open with defaultSorting={[{id: 'status', desc: true}]}. Because sorted by the alphabet, warn lands at the bottom below ok and idle, where an operator scanning for trouble misses it.
Must
Render a status cell with Status, which prints the word, not a colored dot or tint. Because hue alone vanishes in forced colors and grayscale, and a screen reader reads an empty cell.
Must
Set meta.unit to duration or count; never format each cell by hand. Because per-cell units put 950ms above 1.2s in one column, so the bigger-looking number is the smaller one.
Must
Open details with onRowClick and activeRowId; keep checkboxes for selection. The open row gets aria-current and the neutral grey, a selected row a ticked checkbox and the kind wash. Because opening by selection ticks a checkbox the person never pressed, so a bulk action then hits that row.
Must
Give a table that can pass 200 rows a maxHeight so it windows. Because without maxHeight DataTable renders every row, and 10,000 rows stall the page on each sort and filter.
Never
Wrap a Table in a Card or a second frame. Because the table is already one frame, and a second edge around it reads as two components.
Should
Pass title rather than writing a heading above the table.
Should
Say why in empty, top-left, with the query in a CodeTag, and name the way out; under a FilterBar its Clear all owns the reset.
Never
Stripe rows, add vertical cell borders, or color row text; the status word carries fail. Because stripes and red row text compete with the status word, the one place a failed run is meant to show.
Should
Fit seven columns in the 980px a list gets at 1280: size time with meta.time, give one name or ID column the rest with Truncate, and give every column but name, status and actions meta.hideBelow: 768.

Accessibility

8 checks
The table is named by aria-label or caption and sets aria-rowcount and aria-busy while loading.
Heads set aria-sort; Enter and Space on a sort button cycle it and Shift adds the column; a status line announces the row count, selection and sort politely.
Rows set aria-selected, aria-current on the open row, and aria-rowindex.
Checkboxes are named Select row n and Select all rows, with mixed for partial; Shift-click applies the anchor row state to the range.
With onRowClick the body is one tab stop; arrows, Home, End, Page Up and Page Down move; Enter opens once.
A resize handle is role="separator"; Left and Right move 16px, Shift 64px, Enter resets; arrows swap in RTL.
Forced colors give selected and open rows a Highlight outline.
BulkActionBar is a toolbar with one tab stop and arrow keys between actions; Escape clears the selection, and a polite status says "3 runs selected" and "Selection cleared".

Edge cases

8 edge cases
120-character agent, 36-character run ID
Cells never wrap; they cut with an ellipsis and keep full text in the DOM.
data=[]
TableEmpty top-left in the visible width.
10,000 rows
With maxHeight 360 about 20 rows stay in the DOM; the sort runs over all.
Narrow pane
hideBelow columns drop first; then the box scrolls sideways, joins the tab order so arrows scroll it, and pins the actions column to the end with a row rule on its edge.
Right to left
Padding, numeric alignment and the resize handle mirror.
Loading
The header stays; after --dur-skeleton-delay placeholder bars fill the real columns and stay at least --dur-skeleton-hold. A reload keeps the rows until then.
Button or checkbox inside a row
Row clicks ignore them, so an action never also opens the row.
Warn, fail and waiting rows
A warn row takes no wash and a fail row a faint 40% one; the status word carries the hue. A waiting status is the plain ink word in a DataTable row; the header holds the one InkSlot count.

API

24 props
columns
ColumnDef<TData, any>[] default required
data
TData[] default required
aria-label
string default required
getRowId
(row, index) => string default index
defaultSorting, sorting, onSortingChange
SortingState default []
rowSelection, onRowSelectionChange, enableRowSelection
RowSelectionState, boolean | (row) => boolean default {}, true
columnVisibility, defaultColumnVisibility
VisibilityState default {}
enableColumnResizing
boolean default true
onRowClick, activeRowId
(row) => void, string
rowActions, rowIndicator, rowActionsWidth
(row) => ReactNode default 72
TableRowActionsMenu label, TableRowActionsItem variant, TableRowActionsSeparator
string, 'default' | 'destructive' default required, 'default'
loading, loadingRows
boolean, number default false, 6
empty
ReactNode default 'No rows.'
title, actions, footer
ReactNode
live, follow, rowStatus
boolean, boolean, (row) => warn | fail default false
maxHeight, virtualizeFrom
number | string, number default 200
size, kind
'sm' | 'default', Kind default 'default'
toolbar
(table) => ReactNode
BulkActionBar count, noun, onClear
number, [string, string], () => void default required, ['item', 'items'], -
BulkActionBar position, BulkAction status
'inline' | 'floating', 'fail' default 'inline'
Table title, count, actions, toolbar, footer, status, live
ReactNode, warn | fail, boolean
meta.severity
boolean default false
meta.unit
'duration' | 'count'
meta.numeric, meta.mono, meta.hideBelow, meta.time
boolean, boolean, number, boolean

Tokens

23 tokens
--line-frame
oklch(var(--ink-c) / var(--line-frame-alpha))
--line-row
oklch(var(--ink-c) / 0.08)
--surface-page
var(--paper)
--surface-hover
oklch(var(--ink-c) / 0.05)
--accent-wash
var(--surface-selected)
--accent-mark
var(--ink)
--ink
oklch(var(--ink-c))
--row-sm
32px
--row
40px
--row-lg
56px
--status-column
128px
--time-column
12ch
--radius-soft
6px
--radius-inner
4px
--radius-frame
10px
--control-sm
28px
--dur-fast
120ms
--ease-step
cubic-bezier(0.2, 0, 0, 1)
--surface-skeleton
color-mix(in oklch, oklch(var(--grey-c)), oklch(var(--ink-c)) var(--skeleton-step))
--type-label-sm
400 12px/16px var(--font-sans)
--type-tag
var(--type-code-sm)
--text-3
oklch(var(--ink-c) / 0.66)
--elev-overlay
0 0 0 1px var(--line-frame), 0 12px 24px -12px oklch(var(--text-on-field-c) / var(--shadow-alpha))

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.