Skip to content

ui_table: card-stack mobile variant #29

Description

@pachev

Problem

ui_table is currently mobile-aware via overflow-x-auto only. That works for short, dense tables (e.g. proc tables on the Application detail page), but it's a weak experience for tables where each row represents a distinct entity people actually read — SSH keys, available package updates, audit events. Users have to swipe to see most of the data, and row-to-row comparison breaks because columns slide off-screen independently.

Different tables want different mobile behavior. Rather than picking one, give ui_table a mobile variant attr so each callsite chooses what suits its data.

Proposed API

attr :mobile, :string, default: "scroll", values: ~w(scroll stack priority)

Three named modes, all on the same component, all opt-in per callsite. Same desktop render across all of them.

mobile="scroll" (default — current behavior)

overflow-x-auto wrapper, full table preserved. Best for short, dense, numeric tables where row-to-row comparison across columns is the actual job (proc tables, anything with tabular-nums).

mobile="stack"

Each <tr> collapses into a card below md. Column headers become field labels inside the card. Best for tables where each row is a distinct entity people read (SSH keys, audit events, updates).

Shape:

  • bg-card block, radius-box, padding 16
  • Vertical layout, ~12px gap between fields
  • Each field is label left (text-tertiary, text-xs uppercase), value right (text-primary, font-mono where appropriate)
  • Unlabeled action column docks bottom-right

mobile="priority"

Only the first 1–2 cols + the action col render on mobile; the rest hide behind an expand chevron. Best for wide tables where there's a clear "primary identity" column and the rest is detail (think a list of servers with status badge + name visible, everything else collapsed).

We can ship scroll (default — already works) and stack first, then add priority later if a callsite actually needs it. The values: whitelist makes adding a fourth variant trivial.

Callsite plan (after we ship stack)

Table Variant Why
Settings → SSH keys stack One row per key, mostly identifiers, reads naturally as cards
Updates tab → packages stack Each row is a distinct package decision (Apply/skip), card per row clearer than horizontal scroll
Application → top by memory/msgq scroll (default) Dense numeric, comparison matters more than per-row identity
Future: server list, audit log stack likely

Design check (per CLAUDE.md)

This adds a new layout primitive per the issue-26 protocol — a card-stack mobile row pattern that doesn't exist in components.pen yet. Block on a pen update before implementing.

Suggested pen addition: a Table/Row/Mobile/Stacked reusable in the existing Table Components frame (ff0zV), capturing the shape above. If we ship priority later, it gets its own pen entry too (Table/Row/Mobile/Priority or similar).

Open design/engineering questions

  1. Action column placement in stack mode. Unlabeled right-aligned cols (delete, Apply) need a defined slot in the mobile card. Options: top-right corner, bottom of card, or an opt-in mobile_action: true flag on the :col slot to control placement.
  2. Breakpoint. md is the natural default but worth confirming with how the rest of the layout shifts (sidebar collapse, page padding).
  3. Implementation strategy. Pure-CSS via display: table-row toggling vs. two parallel renders (<table class="hidden md:table"> + <div class="md:hidden">). Two renders is more DOM but keeps semantics clean and is easier to style; CSS-only is leaner but fights <table> defaults. Leaning two-render.
  4. Future sorting. Out of scope now, but worth flagging: column sorting affordances live in <th> and don't translate cleanly to label-value cards. A sortable column attr would need a mobile presentation too.
  5. Migration plan. Default stays scroll so nothing changes on merge. Per-table opt-in to stack happens in a follow-up PR per the callsite table above.

Acceptance

  • Pen file has a stacked-mobile-row reusable in ff0zV that callers/reviewers can point at
  • ui_table accepts mobile="scroll" | "stack" (priority deferred unless a callsite needs it)
  • Default mobile="scroll" preserves current behavior — no existing callsite changes
  • A second PR flips stack on for the SSH keys table and the updates tab and visually verifies at 375 / 768 / 1024
  • mix precommit clean

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions