Search palette: calendar item preview has no padding; time range wraps without a dash; odd date #1139

Open
opened 2026-10-05 11:45:33 +00:00 by kayg · 5 comments
Owner

Owner report (2026-10-05, production, desktop): "where's the padding?"

Search palette (⌘K) → a calendar result (a Journal entry, "Working on and off on calternal cloud") → right preview pane. The preview content (Journal label, title, date row, time chips, tag, action capsule) sits almost flush against the pane divider: ~5 px leading inset, no top inset matching the other previews. Note and Mail previews got proper insets in #1123 (batch 11); the calendar item preview (packages/ui/src/components/calendar/ItemPreview.svelte as used by apps/web/src/lib/search/SearchPreview.svelte) did not.

Also in the same screenshot:

  1. Time range breaks badly: "🕒 11:00" then "15:00" wraps to the next line with no "–" between the two chips. A range is one unit: "11:00–15:00" (one chip or two chips joined by an en dash), wrapping as a whole.
  2. Date reads oddly: "Monday, 2026 September 28". Use the shared date formatter with the User's locale and the same style as the hover card ("Monday, 28 September 2026" for en-GB, "Monday, September 28, 2026" for en-US), never year-first long form unless the locale says so.

Expected

One preview inset for every result kind (Note, Mail, Event, Journal entry, Task, File, Photo): the same token-based padding as the Note preview, top and leading. Reuse the shared preview container; do not add per-kind padding.

Evidence

Screenshots of the palette preview for an Event, a Journal entry and a Task at 1440 and 820, light + dark, with 4x crops of the divider/inset and the time range. e2e asserts the preview content's left edge has the same inset for all kinds.

## Owner report (2026-10-05, production, desktop): "where's the padding?" Search palette (⌘K) → a calendar result (a Journal entry, "Working on and off on calternal cloud") → right preview pane. The preview content (Journal label, title, date row, time chips, tag, action capsule) sits almost flush against the pane divider: ~5 px leading inset, no top inset matching the other previews. Note and Mail previews got proper insets in #1123 (batch 11); the calendar item preview (packages/ui/src/components/calendar/ItemPreview.svelte as used by apps/web/src/lib/search/SearchPreview.svelte) did not. Also in the same screenshot: 1. **Time range breaks badly:** "🕒 11:00" then "15:00" wraps to the next line with no "–" between the two chips. A range is one unit: "11:00–15:00" (one chip or two chips joined by an en dash), wrapping as a whole. 2. **Date reads oddly:** "Monday, 2026 September 28". Use the shared date formatter with the User's locale and the same style as the hover card ("Monday, 28 September 2026" for en-GB, "Monday, September 28, 2026" for en-US), never year-first long form unless the locale says so. ## Expected One preview inset for every result kind (Note, Mail, Event, Journal entry, Task, File, Photo): the same token-based padding as the Note preview, top and leading. Reuse the shared preview container; do not add per-kind padding. ## Evidence Screenshots of the palette preview for an Event, a Journal entry and a Task at 1440 and 820, light + dark, with 4x crops of the divider/inset and the time range. e2e asserts the preview content's left edge has the same inset for all kinds.
Author
Owner

Starting #1139 as part of the shared preview fix with #1137 on branch job/palfoot-1137, based at current origin/dev 04afb0043c559c59084e4ec12609bb9fe679cbf6. The Search preview reuses ItemPreview, but its wrapper currently removes the shared inset; it also uses separate time chips for ranges. I will fix the shared owners and attach the requested real-build evidence.

Starting #1139 as part of the shared preview fix with #1137 on branch `job/palfoot-1137`, based at current `origin/dev` `04afb0043c559c59084e4ec12609bb9fe679cbf6`. The Search preview reuses `ItemPreview`, but its wrapper currently removes the shared inset; it also uses separate time chips for ranges. I will fix the shared owners and attach the requested real-build evidence.
Author
Owner

Finding: Search reused formatLongDate, but numeric date preferences also forced a year-first month-name display. The result was labels such as “Monday, 2026 September 28” even when the User locale expects “Monday, 28 September 2026” or “Monday, September 28, 2026”. Commit 6e108f862 adds a locale-order option for long dates and applies it to Search rows and previews.

Focused verification passed:

Test Files  2 passed (2)
      Tests  42 passed (42)
   Start at  14:59:55
   Duration  41.54s (transform 86%, tests 5%, import 4%, environment 3%, setup 1%)

  Transform  |component| transforming modules took 33.36s · 81% 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
Finding: Search reused `formatLongDate`, but numeric date preferences also forced a year-first month-name display. The result was labels such as “Monday, 2026 September 28” even when the User locale expects “Monday, 28 September 2026” or “Monday, September 28, 2026”. Commit `6e108f862` adds a locale-order option for long dates and applies it to Search rows and previews. Focused verification passed: ``` Test Files 2 passed (2) Tests 42 passed (42) Start at 14:59:55 Duration 41.54s (transform 86%, tests 5%, import 4%, environment 3%, setup 1%) Transform |component| transforming modules took 33.36s · 81% 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 ```
Author
Owner

Finding: bun run check from apps/web stops before Svelte validation because the existing origin/dev performance exception ledger is larger than its ratchet: contracts/perf/exceptions.json has 21,977 entries while contracts/perf/ratchet.json allows 21,964. Thirteen rule ceilings are each exceeded by one. Neither file is changed in this job. I will run the TypeScript/Svelte checker and focused tests separately and report this gate result for merge-round reconciliation.

Exact output:

perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964
Finding: `bun run check` from `apps/web` stops before Svelte validation because the existing `origin/dev` performance exception ledger is larger than its ratchet: `contracts/perf/exceptions.json` has 21,977 entries while `contracts/perf/ratchet.json` allows 21,964. Thirteen rule ceilings are each exceeded by one. Neither file is changed in this job. I will run the TypeScript/Svelte checker and focused tests separately and report this gate result for merge-round reconciliation. Exact output: ``` perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964 ```
Author
Owner

Owner screenshot (2026-10-05, Calendar Week hover card): the same defects appear in the event hover card, which renders the shared ItemPreview: the time range wraps ("17:13" then "19:00" on the next line, no dash, the zone chip "Asia/Kolkata" after it) and the date reads "Sunday, 2026 October 4". Fix in the shared component so the hover card, palette preview and Agenda all get it; include hover-card screenshots (Week view, narrow and wide cards) in the evidence.

Owner screenshot (2026-10-05, Calendar Week hover card): the same defects appear in the event hover card, which renders the shared ItemPreview: the time range wraps ("17:13" then "19:00" on the next line, no dash, the zone chip "Asia/Kolkata" after it) and the date reads "Sunday, 2026 October 4". Fix in the shared component so the hover card, palette preview and Agenda all get it; include hover-card screenshots (Week view, narrow and wide cards) in the evidence.
Author
Owner

Built

The shared Search preview now uses one token inset for Note, Mail, Journal, Event and Task results. The Calendar card no longer expands into the pane divider. Calendar time ranges stay together with an en dash, and long dates follow the User's locale order. Mail uses the same sanitized HTML reader and safe link controls as the Mail view, with the date and sender under the title. The preview icon centers on the title line.

The production macOS review set covers the Event, Journal and Task previews at 1440 and 820 px in light and dark modes, with native 4× divider and range crops:

Download the 84-PNG production review set

UX gaps closed

All reported preview insets, date ordering, time-range wrapping and header alignment gaps are closed. UX gaps left: none found.

Files

apps/web/src/lib/search/SearchPreview.svelte, apps/web/src/lib/search/SearchResultRow.svelte, apps/web/src/lib/search/server.ts, packages/ui/src/components/calendar/ItemPreview.svelte, packages/ui/src/time.ts, apps/web/src/lib/time.test.ts, apps/web/src/lib/calendar/ItemPreview.svelte.test.ts, apps/web/e2e/search.mjs, and docs/DESIGN.md.

Head and decision

Head: c01abaef8550aa46c5efd3062006530b07b46e25.

The split preview starts at 768 px so the required 820 px tablet screenshot has a real preview. This is recorded in docs/DESIGN.md §32.

Verification

Focused production e2e:

PASS #1137/#1139 native 4x sticky, footer, preview and scrim crops at required widths and themes
PASS #1123 rows, no query ring, Recent icons, Mail/Note previews and footer at 1440px/820px/390px in mono/noir/tokyo-night; #1137/#1139 edge and preview evidence captured
CSP REPORTS search: 0 across 4 pages

Focused Vitest:

Test Files  3 passed (3)
      Tests  27 passed (27)
   Start at  17:11:15
   Duration  13.24s (transform 72%, environment 11%, import 8%, tests 6%, setup 3%)

Direct Svelte diagnostics: svelte-check found 0 errors and 4 warnings in 3 files.

bun run check remains blocked by the unchanged perf-lint exception ratchet. Its output was:

perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964

No Rust code changed, so Rust gates were not run.

For the merge round

From apps/web, run bun run test for the full web test suite and bun run test:e2e:search for the complete Search flows. Run bun run test:e2e for the full application e2e gate.

## Built The shared Search preview now uses one token inset for Note, Mail, Journal, Event and Task results. The Calendar card no longer expands into the pane divider. Calendar time ranges stay together with an en dash, and long dates follow the User's locale order. Mail uses the same sanitized HTML reader and safe link controls as the Mail view, with the date and sender under the title. The preview icon centers on the title line. The production macOS review set covers the Event, Journal and Task previews at 1440 and 820 px in light and dark modes, with native 4× divider and range crops: [Download the 84-PNG production review set](https://git.kayg.org/attachments/677f4401-9c69-4d5e-9c19-610f9725cae5) ## UX gaps closed All reported preview insets, date ordering, time-range wrapping and header alignment gaps are closed. UX gaps left: none found. ## Files `apps/web/src/lib/search/SearchPreview.svelte`, `apps/web/src/lib/search/SearchResultRow.svelte`, `apps/web/src/lib/search/server.ts`, `packages/ui/src/components/calendar/ItemPreview.svelte`, `packages/ui/src/time.ts`, `apps/web/src/lib/time.test.ts`, `apps/web/src/lib/calendar/ItemPreview.svelte.test.ts`, `apps/web/e2e/search.mjs`, and `docs/DESIGN.md`. ## Head and decision Head: `c01abaef8550aa46c5efd3062006530b07b46e25`. The split preview starts at 768 px so the required 820 px tablet screenshot has a real preview. This is recorded in `docs/DESIGN.md` §32. ## Verification Focused production e2e: ```text PASS #1137/#1139 native 4x sticky, footer, preview and scrim crops at required widths and themes PASS #1123 rows, no query ring, Recent icons, Mail/Note previews and footer at 1440px/820px/390px in mono/noir/tokyo-night; #1137/#1139 edge and preview evidence captured CSP REPORTS search: 0 across 4 pages ``` Focused Vitest: ```text Test Files 3 passed (3) Tests 27 passed (27) Start at 17:11:15 Duration 13.24s (transform 72%, environment 11%, import 8%, tests 6%, setup 3%) ``` Direct Svelte diagnostics: `svelte-check found 0 errors and 4 warnings in 3 files`. `bun run check` remains blocked by the unchanged perf-lint exception ratchet. Its output was: ```text perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964 ``` No Rust code changed, so Rust gates were not run. ## For the merge round From `apps/web`, run `bun run test` for the full web test suite and `bun run test:e2e:search` for the complete Search flows. Run `bun run test:e2e` for the full application e2e gate.
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#1139
No description provided.