Toasts: hug their content, centred text, action on the right; same glass as menus #206

Closed
opened 2026-09-26 18:23:33 +00:00 by kayg · 11 comments
Owner

Owner 2026-09-26 (screenshot: a 'Link copied' toast stretched across the full width with left-aligned text).

  • A toast is as wide as its content plus padding (min and max width, max ≈ the tray width; long text wraps within the max). Sonner-style adaptive sizing (check what svelte-sonner supports; our toaster is custom-ported, keep one toaster component).
  • Text-only toasts: text centred. Toasts with an action (Undo on delete, Open, Retry): message left, action right, one row when it fits.
  • Keep the docking rule (bottom edge on the tray centre line, DESIGN §34), 30 s auto-dismiss, pause on hover/focus, stacking, reduced motion, screen-reader live region.
  • Material: the same shared glass as dropdowns and menus (#157); no separate, more opaque toast surface.
    Screenshots (short text, long text, with action, stacked; light and dark; 1440 and 390) for Claude's review. Do after #157 lands (merge dev first).
Owner 2026-09-26 (screenshot: a 'Link copied' toast stretched across the full width with left-aligned text). - A toast is as wide as its content plus padding (min and max width, max ≈ the tray width; long text wraps within the max). Sonner-style adaptive sizing (check what svelte-sonner supports; our toaster is custom-ported, keep one toaster component). - Text-only toasts: text centred. Toasts with an action (Undo on delete, Open, Retry): message left, action right, one row when it fits. - Keep the docking rule (bottom edge on the tray centre line, DESIGN §34), 30 s auto-dismiss, pause on hover/focus, stacking, reduced motion, screen-reader live region. - Material: the same shared glass as dropdowns and menus (#157); no separate, more opaque toast surface. Screenshots (short text, long text, with action, stacked; light and dark; 1440 and 390) for Claude's review. Do after #157 lands (merge dev first).
Author
Owner

Starting #206 on branch job/toasts, based on 19676b443485821c2df96e03f8f0e357cf32ee74 (the #157 overlay-glass merge). I will merge current dev before final gates as requested.

Starting #206 on branch `job/toasts`, based on `19676b443485821c2df96e03f8f0e357cf32ee74` (the #157 overlay-glass merge). I will merge current `dev` before final gates as requested.
Author
Owner

Finding: AppToaster.svelte sets the toaster to min(480px, viewport - margins) and forces each [data-sonner-toast] to width: 100%. A short toast therefore fills the full slot. I will size the list and toast intrinsically, with the 480 px cap retained for wrapping long messages.

Finding: `AppToaster.svelte` sets the toaster to `min(480px, viewport - margins)` and forces each `[data-sonner-toast]` to `width: 100%`. A short toast therefore fills the full slot. I will size the list and toast intrinsically, with the 480 px cap retained for wrapping long messages.
Author
Owner

Resuming after the VM restart on job/toasts at 9f15a5352093f2cd19f85e5531d858846be5264a. The branch base is 19676b443485821c2df96e03f8f0e357cf32ee74; current dev is f6418fc72d750d941f23554ad16381f6dd400fd6. I am reviewing the checkpointed toast probes and will finish the implementation, production screenshots, merge dev, and run the required gates.

Resuming after the VM restart on `job/toasts` at `9f15a5352093f2cd19f85e5531d858846be5264a`. The branch base is `19676b443485821c2df96e03f8f0e357cf32ee74`; current `dev` is `f6418fc72d750d941f23554ad16381f6dd400fd6`. I am reviewing the checkpointed toast probes and will finish the implementation, production screenshots, merge `dev`, and run the required gates.
Author
Owner

Finding after merging dev: the shared production e2e stops before the toast assertions because its Search setup still presses Control+/. Current apps/web/src/lib/shortcuts/registry.ts binds app.search to cmd+k; current sibling e2e flows use Control+k. Evidence: bun e2e/popovers.mjs passed the Calendar and Files checks, then timed out waiting for .surface.search-window input[role="combobox"]. I will align the two Search callers in this job's e2e and screenshot scripts, then rerun.

Finding after merging `dev`: the shared production e2e stops before the toast assertions because its Search setup still presses `Control+/`. Current `apps/web/src/lib/shortcuts/registry.ts` binds `app.search` to `cmd+k`; current sibling e2e flows use `Control+k`. Evidence: `bun e2e/popovers.mjs` passed the Calendar and Files checks, then timed out waiting for `.surface.search-window input[role="combobox"]`. I will align the two Search callers in this job's e2e and screenshot scripts, then rerun.
Author
Owner

Investigation finding: e2e/harness.mjs starts the production server from apps/web/build and does not rebuild it. The run after the CSS edit still served build/index.html timestamped 2026-09-27 00:35, while AppToaster.svelte was edited at 06:56; that explains why the rendered width stayed 480 px. I will build the production web app before rerunning the probe and screenshot capture.

Investigation finding: `e2e/harness.mjs` starts the production server from `apps/web/build` and does not rebuild it. The run after the CSS edit still served `build/index.html` timestamped `2026-09-27 00:35`, while `AppToaster.svelte` was edited at `06:56`; that explains why the rendered width stayed 480 px. I will build the production web app before rerunning the probe and screenshot capture.
Author
Owner

Resolution evidence: the local install was also stale after the dev merge. apps/web/package.json and bun.lock both pin torph@0.1.3; bun install --frozen-lockfile installed the missing package without lockfile changes. bun run build then completed, bun e2e/popovers.mjs passed the toast sizing/alignment checks, and the production screenshot run wrote 108 screenshots. The 16 requested toast screenshots are listed in artifacts/overlay-glass-screens/manifest.txt.

Resolution evidence: the local install was also stale after the `dev` merge. `apps/web/package.json` and `bun.lock` both pin `torph@0.1.3`; `bun install --frozen-lockfile` installed the missing package without lockfile changes. `bun run build` then completed, `bun e2e/popovers.mjs` passed the toast sizing/alignment checks, and the production screenshot run wrote 108 screenshots. The 16 requested toast screenshots are listed in `artifacts/overlay-glass-screens/manifest.txt`.
Author
Owner

Full workspace test finding after the required dev merge: cargo test failed only in calternal-plugin-files::media::tests::timeout_kills_the_whole_media_process_group. The panic at crates/plugins/files/src/media.rs:674 says timed-out decoder descendant is still running: Some("R"); that crate reported 98 passed; 1 failed. I am rerunning this test alone to distinguish a repeatable process-group bug from host load. This is outside the toast implementation scope.

Full workspace test finding after the required `dev` merge: `cargo test` failed only in `calternal-plugin-files::media::tests::timeout_kills_the_whole_media_process_group`. The panic at `crates/plugins/files/src/media.rs:674` says `timed-out decoder descendant is still running: Some("R")`; that crate reported `98 passed; 1 failed`. I am rerunning this test alone to distinguish a repeatable process-group bug from host load. This is outside the toast implementation scope.
Author
Owner

The isolated rerun passed: test media::tests::timeout_kills_the_whole_media_process_group ... ok and test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 98 filtered out. I have not changed the media code. I am running the files crate suite alone before retrying the full workspace gate.

The isolated rerun passed: `test media::tests::timeout_kills_the_whole_media_process_group ... ok` and `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 98 filtered out`. I have not changed the media code. I am running the files crate suite alone before retrying the full workspace gate.
Author
Owner

Follow-up evidence: cargo test -p calternal-plugin-files --lib reproduced the same failure in the default parallel test run (98 passed; 1 failed). The full crate suite passed when serialized: test result: ok. 99 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 148.53s. The toast work does not touch this crate; I am leaving the media implementation unchanged and recording this as an unrelated parallel-test failure for follow-up.

Follow-up evidence: `cargo test -p calternal-plugin-files --lib` reproduced the same failure in the default parallel test run (`98 passed; 1 failed`). The full crate suite passed when serialized: `test result: ok. 99 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 148.53s`. The toast work does not touch this crate; I am leaving the media implementation unchanged and recording this as an unrelated parallel-test failure for follow-up.
Author
Owner

Finished #206

Built intrinsic toast sizing in the existing AppToaster: short messages hug their content, text-only messages are centered, long text stays within the 480 px cap, and action messages keep their action on the right. Updated the Search key in both related e2e callers to match the current Ctrl/⌘K shortcut.

Files: apps/web/src/lib/components/AppToaster.svelte, apps/web/e2e/popovers.mjs, apps/web/e2e/popover-screenshots.mjs.

Production evidence: bun run build completed (✓ built in 25.20s; Wrote site to "build"; ✔ done). bun e2e/popovers.mjs passed the Calendar, Files, Search, short toast sizing/centering, long toast wrapping, and action alignment checks. The screenshot script wrote 108 production screenshots; the 16 toast variants (4 states × 2 themes × 2 viewport sizes) are listed in artifacts/overlay-glass-screens/manifest.txt.

Commits: merged current dev at 94acd11d; toast change at 892e6e46.
Head: 892e6e4637c02e9a393b9adb147f556fb68fb01c (job/toasts).

Final gates

$ cargo fmt --check
(no output; exit 0)

$ cargo clippy --all-targets -- -D warnings
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 10m 53s

$ cargo test
test media::tests::timeout_kills_the_whole_media_process_group ... FAILED
thread 'media::tests::timeout_kills_the_whole_media_process_group' panicked at crates/plugins/files/src/media.rs:674:9:
timed-out decoder descendant is still running: Some("R")
test result: FAILED. 98 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 30.96s
error: test failed, to rerun pass `-p calternal-plugin-files --lib`

$ bun run check
svelte-check found 0 errors and 0 warnings

$ bun run test
 Test Files  68 passed (68)
      Tests  534 passed (534)
   Duration  36.33s (transform 64%, environment 14%, import 13%, tests 7%, setup 2%)

Known gap: the unrelated media process-group test also failed in the default parallel calternal-plugin-files suite (98 passed; 1 failed), but passed alone and in the serialized suite (99 passed; 0 failed in 148.53s). I did not change media behavior in this toast job; this parallel-test failure needs follow-up. The web unit output includes jsdom Not implemented: Window's scrollTo() method messages despite exit 0.

Decision where DESIGN was silent: use CSS intrinsic sizing (fit-content, capped by the existing 480 px toaster) and :has(.cal-toast-action) to distinguish centered text-only toasts from action toasts. This keeps the single Toaster and adds no runtime measurement.

## Finished #206 Built intrinsic toast sizing in the existing `AppToaster`: short messages hug their content, text-only messages are centered, long text stays within the 480 px cap, and action messages keep their action on the right. Updated the Search key in both related e2e callers to match the current `Ctrl/⌘K` shortcut. Files: `apps/web/src/lib/components/AppToaster.svelte`, `apps/web/e2e/popovers.mjs`, `apps/web/e2e/popover-screenshots.mjs`. Production evidence: `bun run build` completed (`✓ built in 25.20s`; `Wrote site to "build"`; `✔ done`). `bun e2e/popovers.mjs` passed the Calendar, Files, Search, short toast sizing/centering, long toast wrapping, and action alignment checks. The screenshot script wrote 108 production screenshots; the 16 toast variants (4 states × 2 themes × 2 viewport sizes) are listed in `artifacts/overlay-glass-screens/manifest.txt`. Commits: merged current `dev` at `94acd11d`; toast change at `892e6e46`. Head: `892e6e4637c02e9a393b9adb147f556fb68fb01c` (`job/toasts`). ## Final gates ```text $ cargo fmt --check (no output; exit 0) $ cargo clippy --all-targets -- -D warnings Finished `dev` profile [unoptimized + debuginfo] target(s) in 10m 53s $ cargo test test media::tests::timeout_kills_the_whole_media_process_group ... FAILED thread 'media::tests::timeout_kills_the_whole_media_process_group' panicked at crates/plugins/files/src/media.rs:674:9: timed-out decoder descendant is still running: Some("R") test result: FAILED. 98 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 30.96s error: test failed, to rerun pass `-p calternal-plugin-files --lib` $ bun run check svelte-check found 0 errors and 0 warnings $ bun run test Test Files 68 passed (68) Tests 534 passed (534) Duration 36.33s (transform 64%, environment 14%, import 13%, tests 7%, setup 2%) ``` Known gap: the unrelated media process-group test also failed in the default parallel `calternal-plugin-files` suite (`98 passed; 1 failed`), but passed alone and in the serialized suite (`99 passed; 0 failed` in 148.53s). I did not change media behavior in this toast job; this parallel-test failure needs follow-up. The web unit output includes jsdom `Not implemented: Window's scrollTo() method` messages despite exit 0. Decision where DESIGN was silent: use CSS intrinsic sizing (`fit-content`, capped by the existing 480 px toaster) and `:has(.cal-toast-action)` to distinguish centered text-only toasts from action toasts. This keeps the single Toaster and adds no runtime measurement.
Author
Owner

Merged into dev at b176b4c3 after Claude's review (toasts hug content, centred text, action right, shared glass). Deploy status on #203.

Merged into dev at b176b4c3 after Claude's review (toasts hug content, centred text, action right, shared glass). Deploy status on #203.
kayg referenced this issue from a commit 2026-09-27 05:52:14 +00:00
kayg closed this issue 2026-09-27 05:52:14 +00:00
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#206
No description provided.