Add the dashboard table framework design and Codex briefs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Dashboard tables
|
||||
|
||||
How every data table on the dashboard is laid out, and the rules a new table
|
||||
must follow so it never grows a horizontal scrollbar on a desktop screen.
|
||||
Everything here is plain CSS in `src/web/tailwind.css` plus four cell classes;
|
||||
there is no table library and no JavaScript involved.
|
||||
|
||||
## The problem this solves
|
||||
|
||||
A table used to be `min-width: max-content` inside a `.scroll-x` wrapper, and
|
||||
most cells were `white-space: nowrap`. Any table whose natural width exceeded
|
||||
the page column (80rem, ~1355px at the site's 110% scale) became a horizontal
|
||||
scroller, even on a 2560px monitor, and the columns that mattered were hidden
|
||||
behind the scrollbar. Wrapping columns were squeezed to their minimum while the
|
||||
nowrap ones kept everything.
|
||||
|
||||
## The three rules
|
||||
|
||||
1. **Tables get the whole viewport, everything else keeps the page column.**
|
||||
`.dashboard` is a CSS grid with two named column spans: `content` (at most
|
||||
80rem minus the page gutters, exactly what the header uses) and `wide` (the
|
||||
viewport minus the same gutters). Every direct child sits in `content`; a
|
||||
direct-child `.scroll-x` sits in `wide`. The table inside a wide wrapper is
|
||||
`width: auto` (shrink-to-fit) with `min-width` equal to the content column
|
||||
and `max-width: 100%`, centred. A table that fits the page column therefore
|
||||
looks exactly as before; a table that needs more grows, centred, up to the
|
||||
viewport edge; the page itself never scrolls sideways.
|
||||
|
||||
2. **Columns wrap before the table scrolls.** The `min-width: max-content` rule
|
||||
is gone. A table shrinks by wrapping its text columns down to their floors,
|
||||
and only when the floors alone no longer fit (phones, mostly) does the
|
||||
`.scroll-x` wrapper scroll. Headers always wrap.
|
||||
|
||||
3. **A cell declares what it holds, and nothing else decides its width.**
|
||||
There are exactly four cell classes:
|
||||
|
||||
| class | use it for | behaviour |
|
||||
| ------------ | -------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| *(none)* | short prose, names, tokens, badges | wraps at spaces |
|
||||
| `num` | numbers, money, counts | right-aligned tabular figures; `td.num` never wraps, `th.num` may |
|
||||
| `cell-tight` | timestamps, dates, ids, a single short token that must not split | `white-space: nowrap`. Nothing longer than ~20 characters |
|
||||
| `cell-wrap` | titles, URLs, notes, messages, badge lists, anything free-form | floor 10rem, ceiling 32rem, `overflow-wrap: anywhere` |
|
||||
|
||||
Anything long that must not wrap gets an inner block with a Tailwind clamp
|
||||
(`<div class="line-clamp-2" title="…">`) inside a `cell-wrap` cell; the cell
|
||||
ceiling bounds the column, the clamp bounds the row height. Do not put
|
||||
`truncate`/`line-clamp-*` on a `td` itself (a table cell cannot be a
|
||||
`-webkit-box`), and do not use `table-fixed` on a page-level table (fixed
|
||||
layout needs a definite width and is silently ignored with `width: auto`).
|
||||
|
||||
## Checklist for a new table
|
||||
|
||||
- Wrap it in `<div class="scroll-x">` (add `tall` for a 70vh vertical cap) and
|
||||
make that wrapper a **direct child** of `<section class="dashboard">` if the
|
||||
table has more than a handful of columns. Tables inside `.card`, `.cards` or
|
||||
`details` stay inside their box and just wrap/scroll there.
|
||||
- Give every `td` one of the four classes above according to its content.
|
||||
When in doubt, leave it unclassed: wrapping is the safe default.
|
||||
- Never `cell-tight` a name, a title, a reason sentence or a free-text field.
|
||||
- Check the page at 390, 1280 and 2560px. At 1280 and above the wrapper's
|
||||
`scrollWidth` must equal its `clientWidth`; at 390 a wide table is allowed to
|
||||
scroll.
|
||||
|
||||
## Measuring
|
||||
|
||||
`docs/plans/briefs/dashboard-tables/measure.mjs` logs in as the dev-seed admin,
|
||||
visits every dashboard page at several widths and prints, per page, whether the
|
||||
document overflows and which table wrappers scroll. Run it against a seeded
|
||||
dev server (`cargo run --example seed_dev_db -- ./dev`) before and after a CSS
|
||||
change; the "scrolling" count for widths ≥ 1280 should be zero.
|
||||
Reference in New Issue
Block a user