Personal outliner built with Rust.
4

Configure Feed

Select the types of activity you want to include in your feed.

ui-polish: commit heading to this change and order it before threading; make sidebar collapse explicit — dedicated Tabler toggle icon pair in the header reflecting state

graham.systems (Jul 15, 2026, 3:19 PM -0700) 3044ba85 cf43a434

+42 -35
+12 -8
openspec/changes/ui-polish/design.md
··· 53 53 ### D2 — Icons: bundle only the Tabler glyphs we use 54 54 55 55 Tabler icons are MIT (license file ships alongside). Bundle just the needed 56 - SVGs (arrow-left, arrow-right, calendar, sidebar toggle, chevron for 57 - collapse, window caption glyphs if D1 wants them) under 56 + SVGs (arrow-left, arrow-right, calendar, the sidebar toggle pair — 57 + `layout-sidebar-right-collapse` / `layout-sidebar-right-expand`, so the 58 + button's icon reflects the sidebar's current state — chevron for fold 59 + affordances, window caption glyphs if D1 wants them) under 58 60 `crates/trawler/assets/icons/`, exposed through an `AssetSource` registered 59 61 at app start (the same bundling spirit as the fonts — no system deps, 60 62 identical everywhere), rendered via gpui's `svg()` and tinted with the text ··· 66 68 A right-hand sidebar host owning: collapsed flag, width (drag-handle resize 67 69 with min/max clamps), and an ordered set of panels, each a title + render 68 70 function — Calendar and Similar are the two initial registrations. Toggle via 69 - a titlebar button and a keybinding (`Ctrl+Shift+B`, matching the 70 - sidebar-toggle convention elsewhere; final binding checked against the keymap 71 - at implementation). Collapsed/width state persists in memory for the session; 71 + a dedicated Tabler icon button in the titlebar/header row (the icon swaps 72 + between the collapse/expand variants so it reflects current state) and a 73 + keybinding (`Ctrl+Shift+B`, matching the sidebar-toggle convention elsewhere; 74 + final binding checked against the keymap at implementation). Collapsed/width state persists in memory for the session; 72 75 on-disk persistence (a small local ui-state file — explicitly *not* in the 73 76 Loro doc, it's device state not graph data) is a stretch task. The calendar 74 77 keeps its popup behavior when invoked from `Ctrl+Shift+C` semantics — opening ··· 110 113 is still how a page rename works; journal date titles keep whatever 111 114 non-editable treatment they have now). Focus navigation (Up from the first 112 115 child) lands on the heading exactly as it lands on the root bullet today — 113 - only rendering changes, no tree or focus-model changes. This is the severable 114 - item: it touches row rendering and the UI tests' depth assertions, and can be 115 - split into its own change at implementation time if it grows. 116 + only rendering changes, no tree or focus-model changes. Decided in-change 117 + (originally flagged severable): it lands *before* bullet threading in the 118 + task order so guide visuals are built and verified once against the final 119 + indent geometry, and so the UI tests' depth/layout assertions churn once. 116 120 117 121 ## Risks / Trade-offs 118 122
+8 -7
openspec/changes/ui-polish/proposal.md
··· 20 20 calendar and sidebar-toggle affordances. Presentation only. 21 21 - **Right-hand sidebar**: collapsible, resizable, hosting registered panels — 22 22 the calendar picker and the Similar panel move into it (Backlinks stays put 23 - for now, an obvious future panel). Keyboard toggle; state remembered. 23 + for now, an obvious future panel). Collapse/expand via a dedicated Tabler 24 + icon button in the header/titlebar row plus a keyboard toggle; state 25 + remembered. 24 26 - **Bullet threading**: Logseq-style vertical guide lines in the indent 25 27 columns connecting each parent bullet to its children, making hierarchical 26 28 position legible at depth. 27 29 - **Smooth scrolling**: programmatic scrolls (navigation restore, follow-ref, 28 30 zoom, scroll-to-focus) animate with a short ease instead of jumping; wheel 29 31 input stays native. 30 - - **Page title as heading** (severable — flagged by the proposer as possibly 31 - its own change; kept here since it's pure rendering, but cleanly splittable 32 - at implementation time): page roots render as a large heading instead of a 33 - top-level bullet, with the page's children starting at the first indent 34 - level — the Logseq treatment. Applies to journal date pages and named pages 35 - alike. 32 + - **Page title as heading** (decided in-change; ordered *before* threading so 33 + guide visuals are verified once against final indent geometry): page roots 34 + render as a large heading instead of a top-level bullet, with the page's 35 + children starting at the first indent level — the Logseq treatment. Applies 36 + to journal date pages and named pages alike. 36 37 37 38 ## Capabilities 38 39
+6 -4
openspec/changes/ui-polish/specs/app-chrome/spec.md
··· 18 18 ### Requirement: Collapsible right sidebar hosting panels 19 19 The application SHALL provide a right-hand sidebar that hosts named panels — 20 20 initially the calendar picker and the Similar-blocks panel — and SHALL be 21 - collapsible via a visible control and a keyboard shortcut, and resizable by 22 - dragging its edge within clamped bounds. Collapsing the sidebar MUST NOT 23 - discard panel state. Sidebar visibility and width SHALL be remembered for at 24 - least the duration of the session. 21 + collapsible via a dedicated sidebar-toggle icon button in the header/titlebar 22 + row and a keyboard shortcut, and resizable by dragging its edge within 23 + clamped bounds. The toggle icon MUST reflect the sidebar's current state 24 + (collapsed vs. expanded). Collapsing the sidebar MUST NOT discard panel 25 + state. Sidebar visibility and width SHALL be remembered for at least the 26 + duration of the session. 25 27 26 28 #### Scenario: Panels live in the sidebar 27 29 - **WHEN** the sidebar is open with a block focused
+16 -16
openspec/changes/ui-polish/tasks.md
··· 1 1 ## 1. Icons and asset plumbing 2 2 3 3 - [ ] 1.1 Add `AssetSource` registration at app start; bundle selected Tabler SVGs under `crates/trawler/assets/icons/` with the MIT license file 4 - - [ ] 1.2 Replace the ◀/▶ header glyphs with Tabler arrow icons (tinted via text color); add calendar and sidebar-toggle icons 4 + - [ ] 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`) 5 5 6 6 ## 2. Window chrome (design D1) 7 7 ··· 10 10 11 11 ## 3. Sidebar (design D3) 12 12 13 - - [ ] 3.1 Sidebar host: collapsed flag, clamped drag-resize width, ordered panel registrations (title + render fn); session-persistent state 13 + - [ ] 3.1 Sidebar host: collapsed flag, clamped drag-resize width, ordered panel registrations (title + render fn); session-persistent state; collapsing never discards panel state 14 14 - [ ] 3.2 Move the calendar picker into a sidebar panel; calendar invocation (shortcut/button) opens the sidebar and reveals it; day-click behavior unchanged 15 15 - [ ] 3.3 Move the Similar panel from the bottom dock into the sidebar; remove the bottom-dock rendering; Backlinks stays put 16 - - [ ] 3.4 Toggle keybinding (check keymap for conflicts; design suggests Ctrl+Shift+B) + titlebar toggle button 16 + - [ ] 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) 17 17 - [ ] 3.5 Extend the devtools `dump` with sidebar state (open/width/panels) — additive field 18 - - [ ] 3.6 UI tests: toggle preserves panel state and editor focus; calendar invocation reveals panel; similar panel renders in sidebar 18 + - [ ] 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 19 19 20 - ## 4. Bullet threading (design D4) 20 + ## 4. Page title as heading (design D6) 21 21 22 - - [ ] 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 23 - - [ ] 4.2 UI test / dump-based assertions over a fixture page with known nesting; visual check via dev-loop screenshots at several depths 22 + - [ ] 4.1 Render page roots as heading rows (no bullet/fold affordance; heading-scale named knobs); children start at indent level 0 23 + - [ ] 4.2 Preserve focus/edit/rename behavior on the heading row (Up from first child lands on it; editing = root-block editing) 24 + - [ ] 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 24 25 25 - ## 5. Smooth scrolling (design D5) 26 + ## 5. Bullet threading (design D4) — after the heading change, so guides are built against final indent geometry 26 27 27 - - [ ] 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 28 - - [ ] 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 29 - - [ ] 5.3 UI tests run with the knob at 0; add one animation test asserting the offset converges to target and wheel cancels 28 + - [ ] 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 29 + - [ ] 5.2 UI test / dump-based assertions over a fixture page with known nesting; visual check via dev-loop screenshots at several depths 30 30 31 - ## 6. Page title as heading (design D6 — severable) 31 + ## 6. Smooth scrolling (design D5) 32 32 33 - - [ ] 6.1 Render page roots as heading rows (no bullet/fold affordance; heading-scale named knobs); children start at indent level 0 34 - - [ ] 6.2 Preserve focus/edit/rename behavior on the heading row (Up from first child lands on it; editing = root-block editing) 35 - - [ ] 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 33 + - [ ] 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 34 + - [ ] 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 35 + - [ ] 6.3 UI tests run with the knob at 0; add one animation test asserting the offset converges to target and wheel cancels 36 36 37 37 ## 7. Verification and docs 38 38 39 39 - [ ] 7.1 `cargo clippy --workspace --all-targets -- -D warnings` and `cargo test --workspace` pass 40 - - [ ] 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) 40 + - [ ] 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)