Frontend UX: master-detail + sidebar layout has no responsive/small-screen handling #58
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Severity: Medium. From a frontend UX audit.
Problem
The master/detail screens use hardcoded
grid-cols-[20rem_1fr]/[24rem_1fr](objects-page.tsx,vocabularies-page.tsx,fields-page.tsx,search-page.tsx:8) plus a fixedw-44sidebar (app-shell.tsx:20), with no breakpoint variants anywhere. On a smaller laptop / tablet / split-screen window the 20rem list + sidebar leave a cramped detail pane; below ~640px the master + detail can't coexist. The proportions also aren't user-adjustable.Suggested fix
Add responsive breakpoints — collapse the sidebar to icons (or a drawer) and stack master/detail on narrow widths; consider a resizable splitter for the master/detail panes so curators can tune list-vs-detail width.
Source: frontend UX/design audit, 2026-06-06.
Partially addressed in
0a88a86(the #44 milestone). The app shell is now responsive: the sidebar collapses to an icon rail (persisted; auto-collapses on narrow viauseMediaQuery), and the Objects screen's master/detail is responsive — a right pane on wide viewports and a slide-in Base UIDraweron narrow, at canonical/objects/:id. A reusableweb/src/lib/use-media-query.tshook was added.Remaining (keeping this open): the other master/detail screens still use fixed
grid-cols-[20rem_1fr]with no breakpoints — vocabularies (vocabularies-page), fields (fields-page), search (search-page), and the single-pane authorities screen. Apply the same responsive pane/drawer pattern (or stack) there.Remaining half done in merge
a0b7dcd— all master/detail screens are now responsive (the sidebar + Objects were already done in0a88a86).components/detail-drawer.tsx— generalized the objects-specific drawer into a reusable<DetailDrawer open onClose ariaLabel>{children}</DetailDrawer>(Base UI drawer + named dialog + close affordance).object-detail-drawer.tsxdeleted; Objects retrofitted onto it (dropped the now-pointlesslazy/Suspensesince #67 already split@base-ui/reactinto its own app-wide chunk).useMediaQuery("(min-width: 1024px)")+useMatch(":id"): wide keeps the current side-by-side grid (unchanged); narrow (<1024) shows the list/panel full-width and slides the detail into aDetailDrawer(close → index route). Drawer names reusevocab.terms/objects.detailTitle.grid-cols-1 lg:grid-cols-[20rem_1fr], list-above-form on narrow): it'suseState-driven with an always-present create form, so a stack is the right fit (no drawer/new-trigger needed).Breakpoint 1024px throughout, matching Objects. 289 tests pass (existing unchanged + new tests for the drawer + all three pages); typecheck/lint/build clean; check:size 90.2 KB gz (unchanged); check:colors clean; no new dependency; no new i18n keys; no codename.
Out of scope → follow-up: the "resizable splitter" / per-user pane-width preference the issue suggests considering (deferred — the responsive collapse is the actual fix). Authorities is single-pane → no change needed.