Sidebar section headers: + and ⋯ actions float loose; put them in a right-aligned PillGroup (all sidebars) #660

Open
opened 2026-10-02 04:26:38 +00:00 by kayg · 11 comments
Owner

Owner report (2026-10-02)

In the Notes sidebar, the section header actions "+" and "⋯" float loose next to the "Notes" title. They are not in a toolbar pill and not right-aligned (they end well before the rows' right edge).

Expected

Every sidebar section header (Notes, Files, Calendar views, Tags, Mail accounts, Money…) uses one shared header: the title on the left, and the actions in a small glass PillGroup aligned to the row's right edge. It has the same height and centre line as the title, warm tooltips with shortcuts ("New note ⌘N", "More"), keyboard reachable, and hover/focus states. Reuse SidebarSectionHeader + Pill/PillGroup. Do not add a new component. Check every sidebar at 390/820/1440 in both themes, zoomed 3×.

Also seen in the same sidebar: Daily notes (2026-09-28 …) and Task notes appear in the Notes list. #606 (job notesfilter-606) owns filtering them out; do not change filtering here.

## Owner report (2026-10-02) In the Notes sidebar, the section header actions "+" and "⋯" float loose next to the "Notes" title. They are not in a toolbar pill and not right-aligned (they end well before the rows' right edge). ## Expected Every sidebar section header (Notes, Files, Calendar views, Tags, Mail accounts, Money…) uses one shared header: the title on the left, and the actions in a small glass **PillGroup aligned to the row's right edge**. It has the same height and centre line as the title, warm tooltips with shortcuts ("New note ⌘N", "More"), keyboard reachable, and hover/focus states. Reuse SidebarSectionHeader + Pill/PillGroup. Do not add a new component. Check every sidebar at 390/820/1440 in both themes, zoomed 3×. Also seen in the same sidebar: Daily notes (2026-09-28 …) and Task notes appear in the Notes list. #606 (job notesfilter-606) owns filtering them out; do not change filtering here.
Author
Owner

Starting #660 on branch job/sidehdr-660, based on origin/dev at c4a61e8cf090170f35b1bed3350d9de20c83ecd5. I’ve read the binding repo instructions, design context and issue. I’m tracing all sidebar headers and will apply the shared component consistently without changing Notes filtering (#606).

Starting #660 on branch `job/sidehdr-660`, based on `origin/dev` at `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. I’ve read the binding repo instructions, design context and issue. I’m tracing all sidebar headers and will apply the shared component consistently without changing Notes filtering (#606).
Author
Owner

Finding: the worktree had no installed web dependencies. The first focused test returned /usr/bin/bash: line 1: vitest: command not found (exit 127). bun install --frozen-lockfile installed the pinned packages; the focused SidebarSectionHeader.svelte.test.ts then passed (1 file, 5 tests).

Decision for the New note tooltip: the app shortcut registry maps composer.open to plain N. DESIGN §34 and the registry comment prohibit Cmd+N because browsers reserve it. The action uses the registered shortcut hint; it does not claim Cmd+N.

Finding: the worktree had no installed web dependencies. The first focused test returned `/usr/bin/bash: line 1: vitest: command not found` (exit 127). `bun install --frozen-lockfile` installed the pinned packages; the focused `SidebarSectionHeader.svelte.test.ts` then passed (1 file, 5 tests). Decision for the New note tooltip: the app shortcut registry maps `composer.open` to plain `N`. DESIGN §34 and the registry comment prohibit Cmd+N because browsers reserve it. The action uses the registered shortcut hint; it does not claim Cmd+N.
Author
Owner

Progress on job/sidehdr-660 (base c4a61e8cf090170f35b1bed3350d9de20c83ecd5, current feature commit 9eceeb18f727167f04b370ec07d460119fffc908): bun run check and bun run test passed, and the production SPA build completed. I am building the local server for the required macOS-emulated screenshots at 390, 820 and 1440 px in both themes. The screenshot matrix covers all 15 rendered shared section headers, including Mail account headings from the existing test-only fixture. No app code changed after the web gates.

Progress on `job/sidehdr-660` (base `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`, current feature commit `9eceeb18f727167f04b370ec07d460119fffc908`): `bun run check` and `bun run test` passed, and the production SPA build completed. I am building the local server for the required macOS-emulated screenshots at 390, 820 and 1440 px in both themes. The screenshot matrix covers all 15 rendered shared section headers, including Mail account headings from the existing test-only fixture. No app code changed after the web gates.
Author
Owner

Progress: the production UI change is commit 9eceeb18f727167f04b370ec07d460119fffc908; the local Notes section-action profile and docs/perf/README.md instructions are committed as c56ba69f8c46c0f92569a72c20371424aeba2904. The production SPA build is complete. The four-job local cargo build -p calternal-server is still compiling native and Mail dependencies with no errors; I need its binary to run the requested authenticated Playwright captures. Web gates remain passing, and no application source changed after them.

Progress: the production UI change is commit `9eceeb18f727167f04b370ec07d460119fffc908`; the local Notes section-action profile and `docs/perf/README.md` instructions are committed as `c56ba69f8c46c0f92569a72c20371424aeba2904`. The production SPA build is complete. The four-job local `cargo build -p calternal-server` is still compiling native and Mail dependencies with no errors; I need its binary to run the requested authenticated Playwright captures. Web gates remain passing, and no application source changed after them.
Author
Owner

Screenshot matrix update: the existing local Mail fixture exposes two account section headers in addition to Categories. The final matrix is 17 section headers × 390/820/1440 px × light/dark (102 captured variants), plus two Notes shortcut-tooltip captures. This updates the earlier 15-header estimate. Current head is c56ba69f8c46c0f92569a72c20371424aeba2904; the local server build is still active with no errors.

Screenshot matrix update: the existing local Mail fixture exposes two account section headers in addition to Categories. The final matrix is 17 section headers × 390/820/1440 px × light/dark (102 captured variants), plus two Notes shortcut-tooltip captures. This updates the earlier 15-header estimate. Current head is `c56ba69f8c46c0f92569a72c20371424aeba2904`; the local server build is still active with no errors.
Author
Owner

Progress: c56ba69f8c46c0f92569a72c20371424aeba2904 is current. The local server build has reached nom-exif and related media dependencies; it is still active with no errors. The production SPA and web gates are complete. The macOS-emulated real-server screenshots and the local menu benchmark are the remaining work before cleanup and the final report.

Progress: `c56ba69f8c46c0f92569a72c20371424aeba2904` is current. The local server build has reached `nom-exif` and related media dependencies; it is still active with no errors. The production SPA and web gates are complete. The macOS-emulated real-server screenshots and the local menu benchmark are the remaining work before cleanup and the final report.
Author
Owner

Finding for screenshot setup: the E2E harness refused its media-runtime staging because ps -L -u kayg reported 6,298 threads (the helper stops at 4,090). It created the local wrapper binaries before stopping. This UI-only matrix does not call media endpoints, so I will point the harness at those wrappers with its 4,096 process ceiling. The real local server and API remain in use.

Finding for screenshot setup: the E2E harness refused its media-runtime staging because `ps -L -u kayg` reported 6,298 threads (the helper stops at 4,090). It created the local wrapper binaries before stopping. This UI-only matrix does not call media endpoints, so I will point the harness at those wrappers with its 4,096 process ceiling. The real local server and API remain in use.
Author
Owner

Screenshot finding: /settings/account renders the Settings detail view at 390 px and does not contain the FloatingSidebar. The sidebar is in the /settings list view below 1024 px; 1440 px retains the wide /settings/account rail. I updated the evidence script to capture the visible rail at each width. The first pass stopped at this point; no app source change was needed.

Screenshot finding: `/settings/account` renders the Settings detail view at 390 px and does not contain the FloatingSidebar. The sidebar is in the `/settings` list view below 1024 px; 1440 px retains the wide `/settings/account` rail. I updated the evidence script to capture the visible rail at each width. The first pass stopped at this point; no app source change was needed.
Author
Owner

Screenshot capture finding: one 1440 px dark Photos route did not expose #route-content within the harness's 20 second readiness bound. The run had written 91 of 102 expected header captures before stopping. This is a SLOW host-load issue; I resumed only missing cells, raised the readiness bound to 60 seconds, and skip existing captures. No application endpoint or UI action returned an error.

Screenshot capture finding: one 1440 px dark Photos route did not expose `#route-content` within the harness's 20 second readiness bound. The run had written 91 of 102 expected header captures before stopping. This is a SLOW host-load issue; I resumed only missing cells, raised the readiness bound to 60 seconds, and skip existing captures. No application endpoint or UI action returned an error.
Author
Owner

Local performance profile finding: the disposable profile Instance returned HTTP 503 on its 14th sequential POST /api/v1/notes; the preceding 13 creates returned 201. The profile stopped before the 500-Note load and burst samples, so it emitted no valid measurements. It used the prebuilt local server from the calsidebar-638 job. Several Cargo builds were active on the shared host at the time, but the failed run did not preserve the response body or server log, so I cannot attribute the 503 to host load or a server limit. No API or server source changed in #660.

Local performance profile finding: the disposable profile Instance returned HTTP 503 on its 14th sequential `POST /api/v1/notes`; the preceding 13 creates returned 201. The profile stopped before the 500-Note load and burst samples, so it emitted no valid measurements. It used the prebuilt local server from the `calsidebar-638` job. Several Cargo builds were active on the shared host at the time, but the failed run did not preserve the response body or server log, so I cannot attribute the 503 to host load or a server limit. No API or server source changed in #660.
Author
Owner

#660 complete

Built a shared right-aligned PillGroup for sidebar section actions and moved the Notes header actions into it. New note uses the registered composer.open shortcut in the warm tooltip. The More button reports aria-expanded; the section group has an accessible name; collapse stays inside the same group. Every sidebar section uses the shared header.

Files

  • packages/ui/src/components/SidebarSectionHeader.svelte
  • apps/web/src/lib/notes/NotesExplorer.svelte
  • apps/web/src/lib/components/SidebarSectionHeader.svelte.test.ts
  • bench/sidebar-section-header-660.mjs
  • docs/perf/README.md

Head: c56ba69f8c

Screenshot evidence

Each sheet contains the 390, 820 and 1440 px header crops in Light and Dark. The captures use a Mac user agent/platform. The two Notes tooltip captures show the registered shortcut.

UX gaps closed

  • Shared headers expose a named actions group; caller buttons and collapse are keyboard focusable.
  • New note exposes its registered shortcut to the warm tooltip and assistive technology.
  • The touch More menu opened and closed with Escape.
  • Notes filtering #606 was not changed.

UX gaps left

  • The final temporary keyboard check used three Tab presses and stopped when it found Notes actions. This shows New note is the preceding tab stop, but that run did not reach its Enter assertion. New note remains a native button with its existing click action.
  • The visual reviewer should review the attached screenshots.

Performance profile

Added bench/sidebar-section-header-660.mjs and documented it in docs/perf/README.md. The baseline has no sidebar action metric. A local attempt returned HTTP 503 on the 14th sequential POST /api/v1/notes during the 500-Note setup (the first 13 returned 201), so the profile emitted no valid average or burst measurements. The disposable local server used the prebuilt calsidebar-638 binary. The run did not preserve the response body or server log, so I cannot attribute the 503 to host load or a server limit. No API/server source changed in #660.

Decisions

  • Use the registered composer.open shortcut for New note (N); do not map browser-reserved Cmd+N. More and collapse have warm tooltips but have no registered shortcut to display.
  • At widths below 1024 px, capture Settings at /settings; /settings/account does not render the FloatingSidebar there.
  • Use the existing PillGroup tint-only glass treatment because the sidebar supplies the blurred glass plane behind it.

Gates

bun run check:

$ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
User browser caches use userStorage; only documented device/public-link exceptions remain.
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/sidehdr-660/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bun run test:

$ vitest run

 RUN  v5.0.1 /home/kayg/Developer/calternal-wt/sidehdr-660/apps/web

Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Could not parse CSS stylesheet
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method
Not implemented: Window's scrollTo() method

 Test Files  153 passed (153)
      Tests  1054 passed (1054)
   Start at  14:42:22
   Duration  170.24s (transform 68%, environment 11%, import 11%, tests 7%, setup 2%)

  Transform  |component| transforming modules took 742.31s · 65% of tracked time, re-done on every run
             persist transforms across runs with fsModuleCache: true
             learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns

Production bun run build completed with non-fatal vendor use client warnings. No Rust files changed, so Rust gates were not run. cargo clean output: Removed 5476 files, 2.5GiB total. Web build output was deleted after verification.

Integration note

The required pre-gate git fetch origin && git merge origin/dev was already up to date. The cached origin/dev now has one newer commit, 440e19dce fix(test): let local media sandbox start on a busy shared host; this branch was not merged again. No push, deploy or merge was made.

## #660 complete Built a shared right-aligned PillGroup for sidebar section actions and moved the Notes header actions into it. New note uses the registered composer.open shortcut in the warm tooltip. The More button reports aria-expanded; the section group has an accessible name; collapse stays inside the same group. Every sidebar section uses the shared header. ### Files - packages/ui/src/components/SidebarSectionHeader.svelte - apps/web/src/lib/notes/NotesExplorer.svelte - apps/web/src/lib/components/SidebarSectionHeader.svelte.test.ts - bench/sidebar-section-header-660.mjs - docs/perf/README.md Head: c56ba69f8c46c0f92569a72c20371424aeba2904 ### Screenshot evidence Each sheet contains the 390, 820 and 1440 px header crops in Light and Dark. The captures use a Mac user agent/platform. The two Notes tooltip captures show the registered shortcut. - [Notes / Notes](https://git.kayg.org/attachments/22fc6f0c-2163-4c16-a446-5a461125f4c2) - [Files / Pinned](https://git.kayg.org/attachments/2e069cf1-100d-4a6b-b4a2-f79414f33957) - [Files / Smart folders](https://git.kayg.org/attachments/8c8b2552-a88a-4480-86f4-975940165be2) - [Calendar / Calendar views](https://git.kayg.org/attachments/1f4636f2-fbb6-4dff-bb52-f6f5a96ed50a) - [Calendar / Tags](https://git.kayg.org/attachments/3b9d99e9-12d5-48aa-857a-ffe22210ebcb) - [Calendar / Saved searches](https://git.kayg.org/attachments/d76c61fd-ce8f-4528-b43f-4bf2b7fc3c05) - [Photos / Library](https://git.kayg.org/attachments/02193334-64b9-4339-adcb-2d79cc07ae95) - [Photos / Library folders](https://git.kayg.org/attachments/9f26b672-80ba-449f-bc6f-ac5d19ce9957) - [Mail / Categories](https://git.kayg.org/attachments/e90ab079-1c29-4176-803e-921a46e0bb59) - [Mail / reader@example.test](https://git.kayg.org/attachments/cadece4e-62fa-47d9-9cc1-7b3dffe4a32e) - [Mail / reader-two@example.test](https://git.kayg.org/attachments/b38eb962-7f85-4218-ad07-f273d1f4fd53) - [Analytics / Periods](https://git.kayg.org/attachments/31af8a97-0bbd-4b24-b556-bc0ed9d05fd7) - [Analytics / Ranges](https://git.kayg.org/attachments/c9e74b95-9d9f-4fe8-bad1-762a1c8bf97e) - [Money / Accounts](https://git.kayg.org/attachments/b4193e11-88f9-44d2-9a42-194ef53ed1ca) - [Money / Tracking](https://git.kayg.org/attachments/d8031dbc-c735-4c43-9bb5-3810908b6fa0) - [Settings / User](https://git.kayg.org/attachments/25952bc3-fa9e-4a52-99ba-3ce6cbd7c6d8) - [Settings / Admin](https://git.kayg.org/attachments/b5a9f2be-23e1-445a-b9cf-824ae439ce6b) - [New note tooltip / Light](https://git.kayg.org/attachments/7036a8f3-f0e2-4079-9044-7e87604f6412) - [New note tooltip / Dark](https://git.kayg.org/attachments/fa7c91e1-a03e-485d-b6b8-ba61ba259046) ### UX gaps closed - Shared headers expose a named actions group; caller buttons and collapse are keyboard focusable. - New note exposes its registered shortcut to the warm tooltip and assistive technology. - The touch More menu opened and closed with Escape. - Notes filtering #606 was not changed. ### UX gaps left - The final temporary keyboard check used three Tab presses and stopped when it found Notes actions. This shows New note is the preceding tab stop, but that run did not reach its Enter assertion. New note remains a native button with its existing click action. - The visual reviewer should review the attached screenshots. ### Performance profile Added bench/sidebar-section-header-660.mjs and documented it in docs/perf/README.md. The baseline has no sidebar action metric. A local attempt returned HTTP 503 on the 14th sequential POST /api/v1/notes during the 500-Note setup (the first 13 returned 201), so the profile emitted no valid average or burst measurements. The disposable local server used the prebuilt calsidebar-638 binary. The run did not preserve the response body or server log, so I cannot attribute the 503 to host load or a server limit. No API/server source changed in #660. ### Decisions - Use the registered composer.open shortcut for New note (N); do not map browser-reserved Cmd+N. More and collapse have warm tooltips but have no registered shortcut to display. - At widths below 1024 px, capture Settings at /settings; /settings/account does not render the FloatingSidebar there. - Use the existing PillGroup tint-only glass treatment because the sidebar supplies the blurred glass plane behind it. ### Gates bun run check: ~~~text $ node scripts/check-user-storage.mjs && node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json User browser caches use userStorage; only documented device/public-link exceptions remain. Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/sidehdr-660/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ~~~ bun run test: ~~~text $ vitest run RUN v5.0.1 /home/kayg/Developer/calternal-wt/sidehdr-660/apps/web Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Could not parse CSS stylesheet Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Not implemented: Window's scrollTo() method Test Files 153 passed (153) Tests 1054 passed (1054) Start at 14:42:22 Duration 170.24s (transform 68%, environment 11%, import 11%, tests 7%, setup 2%) Transform |component| transforming modules took 742.31s · 65% of tracked time, re-done on every run persist transforms across runs with fsModuleCache: true learn more: https://vitest.dev/guide/improving-performance#caching-between-reruns ~~~ Production bun run build completed with non-fatal vendor use client warnings. No Rust files changed, so Rust gates were not run. cargo clean output: Removed 5476 files, 2.5GiB total. Web build output was deleted after verification. ### Integration note The required pre-gate git fetch origin && git merge origin/dev was already up to date. The cached origin/dev now has one newer commit, 440e19dce fix(test): let local media sandbox start on a busy shared host; this branch was not merged again. No push, deploy or merge was made.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#660
No description provided.