diff --git a/openspec/changes/ui-polish/design.md b/openspec/changes/ui-polish/design.md index 1d8b4e4..e39a14c 100644 --- a/openspec/changes/ui-polish/design.md +++ b/openspec/changes/ui-polish/design.md @@ -53,8 +53,10 @@ shipping everything else — chrome is severable. ### D2 — Icons: bundle only the Tabler glyphs we use Tabler icons are MIT (license file ships alongside). Bundle just the needed -SVGs (arrow-left, arrow-right, calendar, sidebar toggle, chevron for -collapse, window caption glyphs if D1 wants them) under +SVGs (arrow-left, arrow-right, calendar, the sidebar toggle pair — +`layout-sidebar-right-collapse` / `layout-sidebar-right-expand`, so the +button's icon reflects the sidebar's current state — chevron for fold +affordances, window caption glyphs if D1 wants them) under `crates/trawler/assets/icons/`, exposed through an `AssetSource` registered at app start (the same bundling spirit as the fonts — no system deps, identical everywhere), rendered via gpui's `svg()` and tinted with the text @@ -66,9 +68,10 @@ color so they follow the palette. No icon-font, no full icon set (Tabler is A right-hand sidebar host owning: collapsed flag, width (drag-handle resize with min/max clamps), and an ordered set of panels, each a title + render function — Calendar and Similar are the two initial registrations. Toggle via -a titlebar button and a keybinding (`Ctrl+Shift+B`, matching the -sidebar-toggle convention elsewhere; final binding checked against the keymap -at implementation). Collapsed/width state persists in memory for the session; +a dedicated Tabler icon button in the titlebar/header row (the icon swaps +between the collapse/expand variants so it reflects current state) and a +keybinding (`Ctrl+Shift+B`, matching the sidebar-toggle convention elsewhere; +final binding checked against the keymap at implementation). Collapsed/width state persists in memory for the session; on-disk persistence (a small local ui-state file — explicitly *not* in the Loro doc, it's device state not graph data) is a stretch task. The calendar keeps its popup behavior when invoked from `Ctrl+Shift+C` semantics — opening @@ -110,9 +113,10 @@ The heading remains the same one-hot editable block it is today (editing it is still how a page rename works; journal date titles keep whatever non-editable treatment they have now). Focus navigation (Up from the first child) lands on the heading exactly as it lands on the root bullet today — -only rendering changes, no tree or focus-model changes. This is the severable -item: it touches row rendering and the UI tests' depth assertions, and can be -split into its own change at implementation time if it grows. +only rendering changes, no tree or focus-model changes. Decided in-change +(originally flagged severable): it lands *before* bullet threading in the +task order so guide visuals are built and verified once against the final +indent geometry, and so the UI tests' depth/layout assertions churn once. ## Risks / Trade-offs diff --git a/openspec/changes/ui-polish/proposal.md b/openspec/changes/ui-polish/proposal.md index 0e8dff4..823a10e 100644 --- a/openspec/changes/ui-polish/proposal.md +++ b/openspec/changes/ui-polish/proposal.md @@ -20,19 +20,20 @@ and "feels finished." calendar and sidebar-toggle affordances. Presentation only. - **Right-hand sidebar**: collapsible, resizable, hosting registered panels — the calendar picker and the Similar panel move into it (Backlinks stays put - for now, an obvious future panel). Keyboard toggle; state remembered. + for now, an obvious future panel). Collapse/expand via a dedicated Tabler + icon button in the header/titlebar row plus a keyboard toggle; state + remembered. - **Bullet threading**: Logseq-style vertical guide lines in the indent columns connecting each parent bullet to its children, making hierarchical position legible at depth. - **Smooth scrolling**: programmatic scrolls (navigation restore, follow-ref, zoom, scroll-to-focus) animate with a short ease instead of jumping; wheel input stays native. -- **Page title as heading** (severable — flagged by the proposer as possibly - its own change; kept here since it's pure rendering, but cleanly splittable - at implementation time): page roots render as a large heading instead of a - top-level bullet, with the page's children starting at the first indent - level — the Logseq treatment. Applies to journal date pages and named pages - alike. +- **Page title as heading** (decided in-change; ordered *before* threading so + guide visuals are verified once against final indent geometry): page roots + render as a large heading instead of a top-level bullet, with the page's + children starting at the first indent level — the Logseq treatment. Applies + to journal date pages and named pages alike. ## Capabilities diff --git a/openspec/changes/ui-polish/specs/app-chrome/spec.md b/openspec/changes/ui-polish/specs/app-chrome/spec.md index 8f7b2d8..f5d7191 100644 --- a/openspec/changes/ui-polish/specs/app-chrome/spec.md +++ b/openspec/changes/ui-polish/specs/app-chrome/spec.md @@ -18,10 +18,12 @@ double-click to maximize/restore) MUST keep working. ### Requirement: Collapsible right sidebar hosting panels The application SHALL provide a right-hand sidebar that hosts named panels — initially the calendar picker and the Similar-blocks panel — and SHALL be -collapsible via a visible control and a keyboard shortcut, and resizable by -dragging its edge within clamped bounds. Collapsing the sidebar MUST NOT -discard panel state. Sidebar visibility and width SHALL be remembered for at -least the duration of the session. +collapsible via a dedicated sidebar-toggle icon button in the header/titlebar +row and a keyboard shortcut, and resizable by dragging its edge within +clamped bounds. The toggle icon MUST reflect the sidebar's current state +(collapsed vs. expanded). Collapsing the sidebar MUST NOT discard panel +state. Sidebar visibility and width SHALL be remembered for at least the +duration of the session. #### Scenario: Panels live in the sidebar - **WHEN** the sidebar is open with a block focused diff --git a/openspec/changes/ui-polish/tasks.md b/openspec/changes/ui-polish/tasks.md index fc87255..c82d586 100644 --- a/openspec/changes/ui-polish/tasks.md +++ b/openspec/changes/ui-polish/tasks.md @@ -1,7 +1,7 @@ ## 1. Icons and asset plumbing - [ ] 1.1 Add `AssetSource` registration at app start; bundle selected Tabler SVGs under `crates/trawler/assets/icons/` with the MIT license file -- [ ] 1.2 Replace the ◀/▶ header glyphs with Tabler arrow icons (tinted via text color); add calendar and sidebar-toggle icons +- [ ] 1.2 Replace the ◀/▶ header glyphs with Tabler arrow icons (tinted via text color); add the calendar icon and the sidebar-toggle pair (`layout-sidebar-right-collapse` / `layout-sidebar-right-expand`) ## 2. Window chrome (design D1) @@ -10,31 +10,31 @@ ## 3. Sidebar (design D3) -- [ ] 3.1 Sidebar host: collapsed flag, clamped drag-resize width, ordered panel registrations (title + render fn); session-persistent state +- [ ] 3.1 Sidebar host: collapsed flag, clamped drag-resize width, ordered panel registrations (title + render fn); session-persistent state; collapsing never discards panel state - [ ] 3.2 Move the calendar picker into a sidebar panel; calendar invocation (shortcut/button) opens the sidebar and reveals it; day-click behavior unchanged - [ ] 3.3 Move the Similar panel from the bottom dock into the sidebar; remove the bottom-dock rendering; Backlinks stays put -- [ ] 3.4 Toggle keybinding (check keymap for conflicts; design suggests Ctrl+Shift+B) + titlebar toggle button +- [ ] 3.4 Dedicated sidebar-toggle Tabler icon button in the titlebar/header row, icon swapping between collapse/expand variants to reflect current state, plus the toggle keybinding (check keymap for conflicts; design suggests Ctrl+Shift+B) - [ ] 3.5 Extend the devtools `dump` with sidebar state (open/width/panels) — additive field -- [ ] 3.6 UI tests: toggle preserves panel state and editor focus; calendar invocation reveals panel; similar panel renders in sidebar +- [ ] 3.6 UI tests: toggle preserves panel state and editor focus; toggle-button icon state matches sidebar state; calendar invocation reveals panel; similar panel renders in sidebar -## 4. Bullet threading (design D4) +## 4. Page title as heading (design D6) -- [ ] 4.1 Per-row ancestor-guide computation (segment per indent column where the chain continues below) and rendering in the indent columns; named knobs for guide color/width; innermost segment meets the parent bullet position -- [ ] 4.2 UI test / dump-based assertions over a fixture page with known nesting; visual check via dev-loop screenshots at several depths +- [ ] 4.1 Render page roots as heading rows (no bullet/fold affordance; heading-scale named knobs); children start at indent level 0 +- [ ] 4.2 Preserve focus/edit/rename behavior on the heading row (Up from first child lands on it; editing = root-block editing) +- [ ] 4.3 Update UI-test layout assertions for the shallower indent; confirm devtools dump depth semantics unchanged; dev-loop screenshot of a journal page before/after -## 5. Smooth scrolling (design D5) +## 5. Bullet threading (design D4) — after the heading change, so guides are built against final indent geometry -- [ ] 5.1 Scroll animator over `ListState` logical offsets: ease-out over `SCROLL_ANIMATION_MS` (named knob, 0 = disabled), cancelled by wheel input or a superseding programmatic scroll -- [ ] 5.2 Route back/forward restore, follow-reference, zoom, and scroll-to-focus through the animator; leave edit-time scroll preservation as a hard set -- [ ] 5.3 UI tests run with the knob at 0; add one animation test asserting the offset converges to target and wheel cancels +- [ ] 5.1 Per-row ancestor-guide computation (segment per indent column where the chain continues below) and rendering in the indent columns; named knobs for guide color/width; innermost segment meets the parent bullet position +- [ ] 5.2 UI test / dump-based assertions over a fixture page with known nesting; visual check via dev-loop screenshots at several depths -## 6. Page title as heading (design D6 — severable) +## 6. Smooth scrolling (design D5) -- [ ] 6.1 Render page roots as heading rows (no bullet/fold affordance; heading-scale named knobs); children start at indent level 0 -- [ ] 6.2 Preserve focus/edit/rename behavior on the heading row (Up from first child lands on it; editing = root-block editing) -- [ ] 6.3 Update UI-test layout assertions for the shallower indent; confirm devtools dump depth semantics unchanged; dev-loop screenshot of a journal page before/after +- [ ] 6.1 Scroll animator over `ListState` logical offsets: ease-out over `SCROLL_ANIMATION_MS` (named knob, 0 = disabled), cancelled by wheel input or a superseding programmatic scroll +- [ ] 6.2 Route back/forward restore, follow-reference, zoom, and scroll-to-focus through the animator; leave edit-time scroll preservation as a hard set +- [ ] 6.3 UI tests run with the knob at 0; add one animation test asserting the offset converges to target and wheel cancels ## 7. Verification and docs - [ ] 7.1 `cargo clippy --workspace --all-targets -- -D warnings` and `cargo test --workspace` pass -- [ ] 7.2 Full dev-loop pass: screenshots of chrome, sidebar open/collapsed, threading at depth, journal heading; README keyboard-reference table updated (sidebar toggle, calendar behavior) +- [ ] 7.2 Full dev-loop pass: screenshots of chrome, sidebar open/collapsed (toggle icon state visible), threading at depth over heading-layout pages, journal heading; README keyboard-reference table updated (sidebar toggle, calendar behavior)