Tags: hover-only row actions on desktop; no raw file paths in Tag results #1166

Open
opened 2026-10-06 00:29:56 +00:00 by kayg · 5 comments
Owner

Follow-ups from the #1110 visual review (orchestrator, 2026-10-06)

  1. Sidebar Tag rows show the ⋯ button on EVERY row permanently (dark-1440-results.png). On fine pointers show ⋯ only on row hover/focus (keyboard focus and touch keep it reachable: touch uses long-press/swipe per the item-action rules); the count stays visible.
  2. The Tag results card lists an item with its raw file path ("Notes/20261006-tag-rename-seed-e0282286.md"). Show the item title with a folder breadcrumb in plain words (e.g. "Notes"), never a raw path or file name with a hash suffix, consistent with search rows.
## Follow-ups from the #1110 visual review (orchestrator, 2026-10-06) 1. Sidebar Tag rows show the ⋯ button on EVERY row permanently (dark-1440-results.png). On fine pointers show ⋯ only on row hover/focus (keyboard focus and touch keep it reachable: touch uses long-press/swipe per the item-action rules); the count stays visible. 2. The Tag results card lists an item with its raw file path ("Notes/20261006-tag-rename-seed-e0282286.md"). Show the item title with a folder breadcrumb in plain words (e.g. "Notes"), never a raw path or file name with a hash suffix, consistent with search rows.
Author
Owner

Starting fu-1166 on branch job/fu-1166, based on origin/dev at f5fbced3c7. I am tracing the existing Tag sidebar actions and search result title/breadcrumb patterns before changing them.

Starting fu-1166 on branch job/fu-1166, based on origin/dev at f5fbced3c733370b5b37544d7816732628be2fd0. I am tracing the existing Tag sidebar actions and search result title/breadcrumb patterns before changing them.
Author
Owner

Finding: TagRow renders ItemActionMenu in every row without the hover/focus gate already used by SidebarLinks. The count is a separate trailing span, so the existing sidebar rule can be applied without hiding it. The Tag result view already has an indexed-title fallback, but it can trust a path-shaped title and does not show the parent folder; Search uses a separate title line and a plain parent-folder description. The Tag row also reserves a held touch for its existing drag-to-merge gesture (#1111), while ItemActionMenu provides row swipe Copy link and its button remains available on touch. I will keep that touch behavior and gate the visible button only for fine pointers.

Finding: TagRow renders ItemActionMenu in every row without the hover/focus gate already used by SidebarLinks. The count is a separate trailing span, so the existing sidebar rule can be applied without hiding it. The Tag result view already has an indexed-title fallback, but it can trust a path-shaped title and does not show the parent folder; Search uses a separate title line and a plain parent-folder description. The Tag row also reserves a held touch for its existing drag-to-merge gesture (#1111), while ItemActionMenu provides row swipe Copy link and its button remains available on touch. I will keep that touch behavior and gate the visible button only for fine pointers.
Author
Owner

Finding during #1166: scripts/perf-lint --check rejected exact pins for the changed Tag route after the result row markup changed. I refreshed only the route hash and its two live #each hashes in contracts/perf/registry.json, contracts/perf/exceptions.json, and contracts/perf/adoption-1058.json; the exception counts and ratchet values are unchanged. The check then passed with perf-lint: PASS; 0 violations; 22359 scoped exceptions.

Finding during #1166: `scripts/perf-lint --check` rejected exact pins for the changed Tag route after the result row markup changed. I refreshed only the route hash and its two live `#each` hashes in `contracts/perf/registry.json`, `contracts/perf/exceptions.json`, and `contracts/perf/adoption-1058.json`; the exception counts and ratchet values are unchanged. The check then passed with `perf-lint: PASS; 0 violations; 22359 scoped exceptions`.
Author
Owner

Owner update (2026-10-06): remove the per-row ⋯ from sidebar rows entirely on desktop (right-click / context-menu key give the same menu; touch keeps long-press). Applies to all sidebar lists with context menus. Sent to the running job; if it already finished, a follow-up job applies it.

Owner update (2026-10-06): remove the per-row ⋯ from sidebar rows entirely on desktop (right-click / context-menu key give the same menu; touch keeps long-press). Applies to all sidebar lists with context menus. Sent to the running job; if it already finished, a follow-up job applies it.
Author
Owner

#1166 is complete on job/fu-1166.

What changed

  • Fine-pointer Tag rows now hide the ⋯ action slot until hover or keyboard focus. The count remains visible. Keyboard users can Tab to the action; coarse pointers keep the direct action target, and the existing swipe-to-copy and 450 ms drag-to-merge behavior remain available.
  • Tag results now show the indexed item title and a plain folder breadcrumb. Empty or path-shaped legacy titles use a readable filename label; generated date and hash suffixes do not appear. Copy link uses the same readable title.
  • Added component and formatter tests, production-browser assertions, and a local hot-path profile.

UX gaps closed

  • Removed the permanent desktop action slot while keeping the Tag count and keyboard access.
  • Replaced generated file paths and hash tails in Tag results with readable titles and folder breadcrumbs.
  • Captured the Tags list and Tag results at 390, 820, and 1440 px in light and dark themes with macOS platform emulation.

UX gaps left

None found for #1166. On touch, the Tag row's existing 450 ms hold remains reserved for drag-to-merge; the direct menu button stays reachable, and the row swipe still copies the link.

Decisions not stated in DESIGN.md

  • When the index title is empty, path-shaped, or ends in a generated eight-digit identity, use the source filename. For Markdown Notes, remove the canonical YYYYMMDD- prefix, the identity suffix, and .md, then turn - and _ into spaces. Keep other file extensions. Use Search's › separator for folders and Home for a root item.
  • Keep the action button visible on coarse pointers because Tag drag-to-merge owns the existing long press. This preserves the current touch interaction while keeping the action available.
  • No feature-specific performance baseline exists. The added helper-only profile records a local reference and does not claim a like-for-like regression comparison.

Performance profile

Local on calternal-dev, under load average 37.21 / 33.60 / 28.74; baseline is null.

  • Average: 20 items, 1,000 passes, p50 0.034 ms, p95 0.067 ms, CPU 73.281 ms, peak sampled RSS 48,123,904 B.
  • Worst case: 500 items, 256 passes, p50 0.847 ms, p95 9.33 ms, CPU 234.942 ms, peak sampled RSS 49,610,752 B.
  • Burst: 500 items, 16 passes, p50 0.686 ms, p95 6.435 ms, CPU 12.693 ms, peak sampled RSS 49,741,824 B.

Screenshots

Production SPA build ID: 438f1c6f550e8c8db660224fb0b57154623bf122. All 12 review images are attached to this issue.

Theme Width Tags Tag results
Light 390 px Tags Results
Light 820 px Tags Results
Light 1440 px Tags Results
Dark 390 px Tags Results
Dark 820 px Tags Results
Dark 1440 px Tags Results

Files

  • apps/web/src/lib/components/TagRow.svelte and TagRow.svelte.test.ts
  • apps/web/src/lib/tags/tagResultPresentation.ts and its test
  • apps/web/src/routes/tag/[tag]/+page.svelte
  • apps/web/e2e/tags-1110-1111.mjs
  • bench/tag-results-1166.mjs and docs/perf/baseline.json
  • Exact perf pins in contracts/perf/registry.json, exceptions.json, and adoption-1058.json

Gates

cargo fmt --check exited 0 with no output. No Rust files changed, so Rust clippy and tests did not apply. The server build was used for the production-browser run.

Finished `dev` profile [unoptimized + debuginfo] target(s) in 32m 06s
perf-lint: PASS; 0 violations; 22359 scoped exceptions
svelte-check found 0 errors and 2 warnings in 2 files

The two Svelte warnings are existing empty rulesets in packages/ui/src/components/calendar/AttachmentDeck.svelte:1055 and AgendaList.svelte:1277.

 Test Files  275 passed (275)
      Tests  1912 passed (1912)
   Start at  10:05:18
   Duration  544.07s (transform 29%, environment 26%, import 26%, tests 15%, setup 4%, worker 1%)
PASS Tag review screenshots: /home/kayg/Developer/calternal-wt/fu-1166/artifacts/tags-1110-1111-final
CSP REPORTS tags-1110-1111: 0 across 1 pages
Removed 8633 files, 7.3GiB total

git diff --check passed with no output. Generated Cargo, apps/web/build, and apps/web/.svelte-kit output was cleaned.

For the merge round

  • cd apps/web && bun run test:e2e — run the full production-browser suite.
  • With the merged production server binary in CALTERNAL_SERVER_BIN, run cd apps/web && bun e2e/tags-1110-1111.mjs — run the full Tag rename, merge, Undo, keyboard, pointer, and touch flow plus its Tag rewrite boundary probe and screenshot assertions.

Head

c7bc3b41fd668ddd96d2bb9de6a077a5ae50d42f (includes the required clean merge of origin/dev).

#1166 is complete on `job/fu-1166`. ## What changed - Fine-pointer Tag rows now hide the ⋯ action slot until hover or keyboard focus. The count remains visible. Keyboard users can Tab to the action; coarse pointers keep the direct action target, and the existing swipe-to-copy and 450 ms drag-to-merge behavior remain available. - Tag results now show the indexed item title and a plain folder breadcrumb. Empty or path-shaped legacy titles use a readable filename label; generated date and hash suffixes do not appear. Copy link uses the same readable title. - Added component and formatter tests, production-browser assertions, and a local hot-path profile. ## UX gaps closed - Removed the permanent desktop action slot while keeping the Tag count and keyboard access. - Replaced generated file paths and hash tails in Tag results with readable titles and folder breadcrumbs. - Captured the Tags list and Tag results at 390, 820, and 1440 px in light and dark themes with macOS platform emulation. ## UX gaps left None found for #1166. On touch, the Tag row's existing 450 ms hold remains reserved for drag-to-merge; the direct menu button stays reachable, and the row swipe still copies the link. ## Decisions not stated in DESIGN.md - When the index title is empty, path-shaped, or ends in a generated eight-digit identity, use the source filename. For Markdown Notes, remove the canonical `YYYYMMDD-` prefix, the identity suffix, and `.md`, then turn `-` and `_` into spaces. Keep other file extensions. Use Search's ` › ` separator for folders and `Home` for a root item. - Keep the action button visible on coarse pointers because Tag drag-to-merge owns the existing long press. This preserves the current touch interaction while keeping the action available. - No feature-specific performance baseline exists. The added helper-only profile records a local reference and does not claim a like-for-like regression comparison. ## Performance profile Local on `calternal-dev`, under load average `37.21 / 33.60 / 28.74`; baseline is `null`. - Average: 20 items, 1,000 passes, p50 `0.034 ms`, p95 `0.067 ms`, CPU `73.281 ms`, peak sampled RSS `48,123,904 B`. - Worst case: 500 items, 256 passes, p50 `0.847 ms`, p95 `9.33 ms`, CPU `234.942 ms`, peak sampled RSS `49,610,752 B`. - Burst: 500 items, 16 passes, p50 `0.686 ms`, p95 `6.435 ms`, CPU `12.693 ms`, peak sampled RSS `49,741,824 B`. ## Screenshots Production SPA build ID: `438f1c6f550e8c8db660224fb0b57154623bf122`. All 12 review images are attached to this issue. | Theme | Width | Tags | Tag results | | --- | ---: | --- | --- | | Light | 390 px | [Tags](https://git.kayg.org/attachments/69c4dbbf-e2cd-4bec-8f4f-d5fd9ed6a034) | [Results](https://git.kayg.org/attachments/b73eae2b-5845-49c6-97aa-5e4007bbdf18) | | Light | 820 px | [Tags](https://git.kayg.org/attachments/4b85972c-75b0-42b7-a722-f58d00cb54bd) | [Results](https://git.kayg.org/attachments/a30f1b8f-cac4-4d37-bc2c-515025e0132b) | | Light | 1440 px | [Tags](https://git.kayg.org/attachments/a968e508-b019-4989-8e0c-9727adabd0e4) | [Results](https://git.kayg.org/attachments/ad60671b-d982-4593-b852-b85fe831e77b) | | Dark | 390 px | [Tags](https://git.kayg.org/attachments/13289c59-d6d8-4000-a1f3-2ff8fb241914) | [Results](https://git.kayg.org/attachments/887be9be-dace-4842-aa75-b34e47c08360) | | Dark | 820 px | [Tags](https://git.kayg.org/attachments/6f17afdb-89b8-4ce4-b1f4-a89f04248e8b) | [Results](https://git.kayg.org/attachments/e33db073-a96c-430e-a628-67515b25a4bc) | | Dark | 1440 px | [Tags](https://git.kayg.org/attachments/0cf70ad0-93f3-472c-a255-a8c7e79e901b) | [Results](https://git.kayg.org/attachments/89aaff39-91f4-4829-a957-3defd3016698) | ## Files - `apps/web/src/lib/components/TagRow.svelte` and `TagRow.svelte.test.ts` - `apps/web/src/lib/tags/tagResultPresentation.ts` and its test - `apps/web/src/routes/tag/[tag]/+page.svelte` - `apps/web/e2e/tags-1110-1111.mjs` - `bench/tag-results-1166.mjs` and `docs/perf/baseline.json` - Exact perf pins in `contracts/perf/registry.json`, `exceptions.json`, and `adoption-1058.json` ## Gates `cargo fmt --check` exited 0 with no output. No Rust files changed, so Rust clippy and tests did not apply. The server build was used for the production-browser run. ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 32m 06s ``` ```text perf-lint: PASS; 0 violations; 22359 scoped exceptions svelte-check found 0 errors and 2 warnings in 2 files ``` The two Svelte warnings are existing empty rulesets in `packages/ui/src/components/calendar/AttachmentDeck.svelte:1055` and `AgendaList.svelte:1277`. ```text Test Files 275 passed (275) Tests 1912 passed (1912) Start at 10:05:18 Duration 544.07s (transform 29%, environment 26%, import 26%, tests 15%, setup 4%, worker 1%) ``` ```text PASS Tag review screenshots: /home/kayg/Developer/calternal-wt/fu-1166/artifacts/tags-1110-1111-final CSP REPORTS tags-1110-1111: 0 across 1 pages ``` ```text Removed 8633 files, 7.3GiB total ``` `git diff --check` passed with no output. Generated Cargo, `apps/web/build`, and `apps/web/.svelte-kit` output was cleaned. ## For the merge round - `cd apps/web && bun run test:e2e` — run the full production-browser suite. - With the merged production server binary in `CALTERNAL_SERVER_BIN`, run `cd apps/web && bun e2e/tags-1110-1111.mjs` — run the full Tag rename, merge, Undo, keyboard, pointer, and touch flow plus its Tag rewrite boundary probe and screenshot assertions. ## Head `c7bc3b41fd668ddd96d2bb9de6a077a5ae50d42f` (includes the required clean merge of `origin/dev`).
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#1166
No description provided.