Build Assets
UI Component
Data Table
Structured rows and columns for comparing, scanning, and acting on multiple records.
Platform: webTags: table, data, list, grid, rows
Purpose
Displays structured data where users need to scan, compare, sort, or act on multiple records simultaneously. Not for simple lists — use a list component when rows don't benefit from column alignment.
Anatomy
- Table header: 12px uppercase column labels, sortable columns show sort arrow
- Row: 40–48px height, alternating background optional (prefer row hover instead)
- Cell: 14px text, left-aligned for text, right-aligned for numbers
- Action column: rightmost, contains row-level actions (edit, delete, view)
- Checkbox column: leftmost for bulk selection
- Empty state: centered message when no rows match filters
- Pagination or infinite scroll: below the table
States
- Default: clean rows, no hover
- Row hover: subtle background shift
- Row selected: accent left border or checkbox checked
- Sort active: arrow indicator on header, ascending/descending
- Loading: skeleton rows replacing actual data
- Empty: centered empty state with action
Tokens
spacing
cellPadding: 12px 16pxheaderPadding: 10px 16pxrowHeight: 48px
sizing
minColumnWidth: 120pxactionColumnWidth: 80px
Do
- Freeze the first column (row identifier) when horizontal scroll is needed
- Right-align numeric data so decimal points align vertically
- Show column sort direction and which column is currently sorted
- Provide bulk actions when checkboxes are present
Don't
- Use a table when a card list would serve better (e.g., rich media content)
- Show more than 8–10 columns without column visibility controls
- Use zebra striping AND row hover — pick one
- Truncate important data without a way to see the full value
Accessibility
- <table> with <thead>, <tbody>, proper <th> and <td> elements
- scope="col" on header cells, scope="row" on row headers
- Caption or aria-label describing the table's purpose
- Sortable columns: aria-sort="ascending/descending/none"