Skip to content

Commit f51f3e6

Browse files
Split the toast docs into how-to and concept guides
Following review feedback on #118, separate the explanation content from task-oriented guidance per Diátaxis: - Add docs/conceptual-guides/toasts.md covering the architecture (queue, registry utilities, region, and CSS), the countdown bar behavior, and where the region is mounted. Link it from the conceptual-guides toctree. - Trim docs/how-to-guides/show-toasts.md to show, customize timeout, dismiss, surface route errors, and render your own region. Add a cross-reference to the new concept page at the top. Apply the inline rewrites in their final files: {file} role for file paths, definition lists for the registry utilities and mount points, "React Aria" terminology, one-sentence-per-line phrasing, and the Storybook demo link near the top of both pages. Backtick cmsui and publicui in the three news entries.
1 parent 6c69017 commit f51f3e6

6 files changed

Lines changed: 107 additions & 59 deletions

File tree

docs/conceptual-guides/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ add-on-driven-configuration
2424
cookieplone-frontend-add-on
2525
routing
2626
slots
27+
toasts
2728
```

docs/conceptual-guides/toasts.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
myst:
3+
html_meta:
4+
"description": "An explanation of the toast notification framework in Plone Aurora, including its architecture, visual variants, and the countdown bar."
5+
"property=og:description": "An explanation of the toast notification framework in Plone Aurora, including its architecture, visual variants, and the countdown bar."
6+
"property=og:title": "Toast notifications"
7+
"keywords": "Plone Aurora, Plone, toast, notification, React Aria, @plone/layout"
8+
---
9+
10+
# Toast notifications
11+
12+
Plone Aurora ships a global toast framework based on the `UNSTABLE_Toast` primitives from React Aria Components.
13+
It is registered by `@plone/layout` and reachable from anywhere in the app via `@plone/registry`, so add-ons can confirm successful actions, surface route errors, or report background task progress without each one having to mount its own region.
14+
15+
See a [demo of toasts](https://plone-storybook.readthedocs.io/?path=/docs/layout_toast--docs).
16+
17+
For task-oriented guidance, see {doc}`../how-to-guides/show-toasts`.
18+
19+
20+
## Architecture
21+
22+
The framework has three layers: a single shared queue, three registry utilities that wrap it, and a visual region that subscribes to the queue and renders each toast.
23+
24+
25+
### The queue and registry utilities
26+
27+
In the package `@plone/layout`, its file {file}`packages/layout/config/toast.ts` exports a module-level `ToastQueue<ToastItem>` and an `install()` function.
28+
29+
The queue wraps state updates with the function `document.startViewTransition` when the browser supports it, falling back to a plain update otherwise.
30+
Enter and exit animations stay in sync with React.
31+
32+
The `install()` function registers three utilities in `@plone/registry` for working with toasts:
33+
34+
`{ type: 'toast', name: 'queue' }`
35+
: Returns the queue itself.
36+
This is useful to subscribe or render a custom region.
37+
38+
`{ type: 'toast', name: 'show' }`
39+
: Adds a `ToastItem` to the queue and returns its key.
40+
41+
`{ type: 'toast', name: 'dismiss' }`
42+
: Closes the toast identified by a key returned from `show`.
43+
44+
45+
### The region and CSS
46+
47+
The visual `<Toast>` region is defined in {file}`packages/layout/components/Toast/Toast.tsx`.
48+
It's mounted once per layout, so toasts appear regardless of which route the user is on.
49+
50+
The shared CSS lives in {file}`components/src/styles/basic/Toast.css`.
51+
It defines:
52+
53+
- The region anchor (`.react-aria-ToastRegion`) and base toast container (`.react-aria-Toast`).
54+
- Four visual variants picked up from the toast's `className`: the default (Quanta `denim`), `.success` (`turtle`), `.info` (`royal`), and `.error` (`wine`).
55+
All colors reference Quanta tokens with hexadecimal fallbacks, so the styles render correctly outside a Quanta theme.
56+
- The countdown bar (`.react-aria-Toast-progress`) rendered along the bottom edge of every timed toast.
57+
58+
59+
## Countdown bar
60+
61+
Every timed toast renders a thin progress bar pinned to its bottom edge.
62+
The bar shrinks from full width to empty over the toast's `timeout` duration, giving the user a visual cue for how long the toast will remain on screen.
63+
64+
A toast appears and behaves as described below.
65+
66+
- Drawn as a single absolutely-positioned `<div>` inside the toast, clipped to the toast's rounded corners.
67+
- Background color is a lightening overlay, implemented with (`rgba(255, 255, 255, 0.35)`).
68+
It works against every variant background without per-variant styling.
69+
- Pauses on hover or focus, mirroring React Aria's own pause-timers behavior.
70+
- Never renders for sticky toasts, either declared with `timeout: null` or when the caller sets `showProgress: false` on the item.
71+
- Marked `aria-hidden`, because it's decorative, not announced.
72+
73+
74+
## Where toasts appear today
75+
76+
The region is mounted in the following files.
77+
78+
{file}`packages/cmsui/routes/layout.tsx`
79+
: every editor route
80+
81+
{file}`packages/publicui/routes/index.tsx`
82+
: every visitor-facing page
83+
84+
{file}`packages/contents/routes/layout.tsx`
85+
: the `/contents` UI
86+
87+
`@plone/layout` is installed by `@plone/aurora`, so the queue and utilities are available in any package that depends on it.

docs/how-to-guides/show-toasts.md

Lines changed: 16 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,18 @@ myst:
44
"description": "How to show toast notifications in Plone Aurora using the @plone/layout toast framework."
55
"property=og:description": "How to show toast notifications in Plone Aurora using the @plone/layout toast framework."
66
"property=og:title": "Show toast notifications"
7-
"keywords": "Plone Aurora, Plone, toast, notification, react-aria-components, @plone/layout"
7+
"keywords": "Plone Aurora, Plone, toast, notification, React Aria, @plone/layout"
88
---
99

1010
# Show toast notifications
1111

12-
Plone Aurora ships a global toast framework based on the `UNSTABLE_Toast` primitives from `react-aria-components`.
12+
Plone Aurora ships a global toast framework based on the `UNSTABLE_Toast` primitives from React Aria Components.
1313
It is registered by `@plone/layout` and reachable from anywhere in the app via `@plone/registry`.
14-
Use it to confirm successful actions, surface route errors, or report background-task progress.
14+
Use it to confirm successful actions, surface route errors, or report background task progress.
1515

16+
See a [demo of toasts](https://plone-storybook.readthedocs.io/?path=/docs/layout_toast--docs).
1617

17-
## How the framework is wired
18-
19-
`@plone/layout/config/toast.ts` exports a module-level `ToastQueue<ToastItem>` and an `install()` function.
20-
The queue wraps state updates in `document.startViewTransition` when the browser supports it, falling back to a plain update otherwise, so enter/exit animations stay in sync with React.
21-
`install()` registers three utilities on `@plone/registry`:
22-
23-
- `{ type: 'toast', name: 'queue' }` returns the queue itself (useful when you need to subscribe or render your own region).
24-
- `{ type: 'toast', name: 'show' }` adds a `ToastItem` to the queue and returns its key.
25-
- `{ type: 'toast', name: 'dismiss' }` closes the toast identified by a key returned from `show`.
26-
27-
The visual `<Toast>` region is `@plone/layout/components/Toast/Toast.tsx`.
28-
It is mounted once per layout, next to `<ScrollRestoration />` / `<Scripts />`, so toasts appear regardless of which route the user is on.
29-
The shared CSS lives in `@plone/components/styles/basic/Toast.css`.
30-
It defines:
31-
32-
- The region anchor (`.react-aria-ToastRegion`) and base toast container (`.react-aria-Toast`).
33-
- Four visual variants picked up from the toast's `className`: the default (Quanta `denim`), `.success` (`turtle`), `.info` (`royal`), and `.error` (`wine`). All colors reference Quanta tokens with hex fallbacks so the styles render correctly outside a Quanta theme.
34-
- The countdown bar (`.react-aria-Toast-progress`) rendered along the bottom edge of every timed toast.
18+
For an explanation of how the framework is wired and where the region is mounted, see {doc}`../conceptual-guides/toasts`.
3519

3620

3721
## Show a toast
@@ -59,8 +43,8 @@ The fields on `ToastItem` are:
5943

6044
`className`
6145
: Optional modifier class.
62-
Pass `'success'`, `'info'`, or `'error'` to use one of the variants that ship in `Toast.css`.
63-
Project add-ons can register their own classes for additional severities.
46+
Pass `'success'`, `'info'`, or `'error'` to use one of the variants that ship in {file}`Toast.css`.
47+
Project add-ons can register their own classes for additional toast alert styles.
6448

6549
`showProgress`
6650
: Whether to render the auto-dismiss countdown bar at the bottom of the toast.
@@ -81,27 +65,13 @@ config.getUtility({ type: 'toast', name: 'show' }).method(
8165
```
8266

8367
`timeout`
84-
: Auto-dismiss after `n` milliseconds.
85-
Defaults to `DEFAULT_TOAST_TIMEOUT_MS` (currently 6 seconds), exported from `@plone/layout/config/toast`.
86-
Pass `null` to require manual dismissal useful for long-running operations that resolve via {ref}`dismiss <show-toasts-dismiss>`.
87-
react-aria-components recommends a minimum of 5 seconds so screen-reader users have time to read the announcement.
68+
: An integer representing the duration in milliseconds after which a toast will be auto-dismissed.
69+
Defaults to the value set by `DEFAULT_TOAST_TIMEOUT_MS`, currently 6000 milliseconds, exported from {file}`layout/config/toast.ts`.
70+
Pass `null` to require manual dismissal, which is useful for long-running operations that resolve via {ref}`dismiss <show-toasts-dismiss>`.
71+
React Aria recommends a minimum of 5 seconds, so people who use a screen reader have time to read the announcement.
8872

8973
`onClose`
90-
: Fires when the toast is removed for any reason (auto-dismiss, close button, programmatic dismiss).
91-
92-
93-
## Countdown bar
94-
95-
Every timed toast renders a thin progress bar pinned to its bottom edge.
96-
The bar shrinks from full width to empty over the toast's `timeout`, giving the user a visual cue for how long the toast will remain on screen.
97-
98-
Behavior:
99-
100-
- Drawn as a single absolutely-positioned `<div>` inside the toast, clipped to the toast's rounded corners.
101-
- Color is a lightening overlay (`rgba(255, 255, 255, 0.35)`) so it works against every variant background without per-variant styling.
102-
- **Pauses on hover or focus**, mirroring react-aria's own pause-timers behavior.
103-
- Never renders for sticky toasts (`timeout: null`) or when the caller sets `showProgress: false` on the item.
104-
- Marked `aria-hidden` — it is decorative, not announced.
74+
: Fires when the toast is removed for any reason, including auto-dismiss, close button, and programmatic dismiss.
10575

10676

10777
(show-toasts-dismiss)=
@@ -145,8 +115,8 @@ export function ErrorBoundary() {
145115

146116
## Render your own region
147117

148-
The default `<Toast>` region covers the common case (bottom-center, dismissable, view-transition animations).
149-
If you need a different layoutfor example a side-panel region or a region scoped to a specific routerender `UNSTABLE_ToastRegion` directly and pass the shared queue:
118+
The default `<Toast>` region covers the common case, including bottom-center, dismissable, and view-transition animations.
119+
For a different layoutfor example, a side-panel region or a region scoped to a specific routerender `UNSTABLE_ToastRegion` directly, and pass the shared queue:
150120

151121
```tsx
152122
import {
@@ -171,15 +141,5 @@ function MyCustomRegion() {
171141
```
172142

173143
Multiple regions can share the same queue.
174-
Each rendered region receives every queued toast, so use them carefully — typically one global region per layout is enough.
175-
176-
177-
## Where toasts appear today
178-
179-
The region is mounted in:
180-
181-
- `packages/cmsui/routes/layout.tsx` — every editor route
182-
- `packages/publicui/routes/index.tsx` — every visitor-facing page
183-
- `packages/contents/routes/layout.tsx` — the `/contents` UI
184-
185-
`@plone/layout` is installed by `@plone/aurora`, so the queue and utilities are available in any package that depends on it.
144+
Each rendered region receives every queued toast, so use them carefully.
145+
Typically, one global region per layout is enough.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Mounted the global toast region in the cmsui layout so toasts triggered from editor routes render. @InteraktivPreuss
1+
Mounted the global toast region in the `cmsui` layout, so toasts triggered from editor routes render. @InteraktivPreuss
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Added `showProgress` and `dismiss` to the toast framework, made the `show` utility return the toast key and accept a per-call `timeout`/`onClose`, lowered the default timeout to 6 seconds, and wired `Toast.css` into both the publicui and cmsui style bundles. @InteraktivPreuss
1+
Added `showProgress` and `dismiss` to the toast framework, made the `show` utility return the toast key and accept a per-call `timeout`/`onClose`, lowered the default timeout to 6 seconds, and wired `Toast.css` into both the `publicui` and `cmsui` style bundles. @InteraktivPreuss
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Mounted the global toast region in the publicui layout so toasts triggered from visitor-facing routes render. @InteraktivPreuss
1+
Mounted the global toast region in the `publicui` layout so toasts triggered from visitor-facing routes render. @InteraktivPreuss

0 commit comments

Comments
 (0)