refactor(desktop): frame Issues, the issue board and Factory with the toolbar page frame

Merged
CH
7d ago
+310-162

Follow-up to the design-system migration. #3415 (FX1) added PAGE_FRAME.TOOLBAR and PAGE_WIDTH to CollectionPage after D37, D40 and D42 had already shipped their own toolbar-and-scroll frames. This PR moves those three screens onto the shared frame.

What

  • Issues list (issues-page.tsx): CollectionPage with frame={PAGE_FRAME.TOOLBAR} and label="Issues". The existing .desktop-toolbar header is passed in as toolbar. The list stands at the page's measure (PAGE_WIDTH.MEASURE). The page now owns the loading, empty ("No issues yet") and failed (Retry) states, through state/empty/error.
  • Issue board: the same page with PAGE_WIDTH.FULL, so the page scrolls the board sideways. .issue-board-scroll is removed. When the arrow keys move to a column, the code now finds the sideways scroller by its computed overflow-x instead of by a desktop class, and takes the inset from where the board starts.
  • Factory (desktop-factory.tsx): the line is a CollectionPage with PAGE_WIDTH.FULL under the toolbar. .factory-scroll is removed. The stations' factory container query moves to a new .factory-board wrapper. A chosen world still stands in its own .factory-view section under the same toolbar, because a world is a full-bleed scene, not a collection.
  • The arrow keys and row motion are still read against one root: .issues-pages (now held in state) and a new .factory-pages (display: contents).
  • Shared (collection-page.css): with PAGE_WIDTH.FULL, the content now holds to the page's height (flex: 1 1 0; min-height: 0). Without this, the board's columns would grow to fit their cards and the whole page would scroll down. Its bottom inset is now a trailing ::after item instead of padding, so content taller than the page (Factory's line) keeps it. The only other caller is the catalog's board example, whose columns are short.
  • Rows keep line-height: normal inside .issue-groups, .issue-board and .factory-board, as Home draws the same rows, so the page's 13/20 body leading doesn't make them taller.
  • Two empty-state choices: an empty board still shows its columns (READY), and while the read is out the board and Factory show nothing, as before. The shared loading rows are shaped like a list, not like a board or Factory's stations.

Visible changes (contract cleanups)

  • Page inset is the contract's 40px (24px under 480px of room) instead of 20px, on all three screens. As a result, with the sidebar collapsed in a 1280px window, the board's fifth column now runs past the edge and the board scrolls sideways sooner.
  • Bottom inset is 40px instead of 32px (list and Factory) or 16px (board), so the board's columns end 24px higher.
  • The list stands at the page's measure (720px) instead of Home's 600px column.
  • While the issues list is read, it shows the shared loading rows (named "Reading issues") instead of nothing.
  • Factory's summary line starts 16px below the toolbar's hairline instead of 12px. Under a failure banner it keeps its 12px gap.
  • No top fade: the list's and Factory's content no longer fades in at the top edge as it scrolls (.scroll-fade-top), because the shared page draws no fade.
  • Factory's narrow layout (stations stacked) now triggers at 960px of content room measured inside the 40px insets, so it switches 40px of window width earlier.

Tests

  • New: issues-page.test.ts checks that while the issues are read, the list shows the "Reading issues" status and the board shows none. Each then draws its issues. The test fails without this change.
  • Updated: the board's keep-in-view test lays out the page's scroll (.luke-collection-page-scroll, overflow-x: auto via getComputedStyle) instead of .issue-board-scroll. Factory's empty-state test checks that no button stands outside the toolbar. Its unread test reads .factory-board. The world picker's "board stands" helper reads the Factory region with no world drawn.
  • pnpm check:affected exits 0.

Screenshots

Captured on Linux with headless Chrome at 1280Ɨ840, sidebar collapsed, the way #3420 was. A throwaway, uncommitted jsdom test rendered the real pages with synthetic data. Chrome then painted them in .desktop-shell > main.desktop-main with the desktop stylesheet built from main (before) and from this branch (after).

BeforeAfter
Board, light
Board, dark
List, light
List, dark
Factory, light
Factory, dark
Factory empty, light

Not verified on a Mac

  • The toolbar's drag region and no-drag controls inside CollectionPage. The toolbar element is unchanged; only its parent changed.
  • Trackpad sideways scrolling on the board, dragging a card while the page is scrolled sideways, and overlay scrollbars against scrollbar-gutter: stable.
  • A Factory world picked from the toolbar. Its frame is unchanged apart from the wrapper.

šŸ¤– Generated with Claude Code