feat(ui): hold header rows and page sections to rearrange or hide them #1

Open
gabrielvidal wants to merge 5 commits from navbar-hold into main

5 Commits

Author SHA1 Message Date
dc458dc11c feat(pages): hold a section to rearrange or hide it
Project, Service and Settings render their bodies through SectionStack, so
the page is arrangeable the same way its header row is: hold a card, drop it
on the stash to bench it. A Service page is twelve sections deep and most
visits care about two of them; Settings is mostly write-once. Sections a
page cannot render (no GOAL.md, no commits) are filtered inside the stack,
so a section that comes back later returns to its saved slot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 17:23:39 +02:00
6e481ef61a feat(nav): hold the header icon buttons to rearrange or hide them
Every header action row goes through HeaderActions: the conversation header
(interrupt, expand-all, visibility, details), the drawer header, and the
page headers on Notifications home, All conversations, Notifications and
Goals. Hold one for a moment and the row starts jumping; drop a button on
the stash popover to bench it, drag its tag back to bring it home. Goals'
running-agents badge rides in the row so it can be benched too.

The drawer's close button now renders conditionally instead of via
`md:hidden` — a display:none slot measures zero, which would leave the drag
a dead gap to hit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 17:23:39 +02:00
d6d4786dd1 feat(ui): HeaderActions and SectionStack — reorderable, stashable groups
Two thin wrappers over HoldEditable + useListArrangement, one per shape the
app repeats: a header's icon-button row, and a page's stack of sections.
Both floor the group at one slotted item — a group is only reachable through
its own members, so an empty one could never be held again to reopen its
stash — and HeaderActions adds `pinned` for the controls whose absence would
strand the user (a back link, a mobile close, Interrupt on a live session).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 17:23:28 +02:00
e740b202bf feat(settings): persist a stash alongside each list's order
useListOrder makes a hard-coded list rearrangeable; useListArrangement adds
the other half — which of its entries are benched out of the group entirely
— and hands both straight to HoldEditable. Stashed ids live in their own
`listStashes` bag next to `listOrders`, reconciled the same way: unknown ids
are dropped, and an entry the saved state never heard of is slotted rather
than benched, so shipping a new one always shows it. The order bag keeps
benched items too, so a tag dragged back lands in its old slot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 17:23:28 +02:00
24106acb12 refactor(ui): drop the local HoldEditable fork for @gabvdl/ui's
The app shipped its own copy of HoldEditable, frozen at the version that
predates the stash. @gabvdl/ui's is a strict superset — stash, grid reflow,
two-stage holds, per-item itemClassName — so keeping the fork is 767 lines
of drift waiting to happen. Point the call sites at the package (0.30.3,
which also keeps the stash popover on screen for tall groups) and delete it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 17:23:17 +02:00