@tempoxyz/ds 0.3.10 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/docs/AGENTS.md +9 -0
  2. package/dist/docs/components/accordion.md +489 -0
  3. package/dist/docs/components/address-card.md +147 -0
  4. package/dist/docs/components/agent-logo.md +194 -0
  5. package/dist/docs/components/alert-dialog.md +631 -0
  6. package/dist/docs/components/alert.md +448 -0
  7. package/dist/docs/components/amount-input.md +305 -0
  8. package/dist/docs/components/amount.md +794 -0
  9. package/dist/docs/components/app-shell.md +559 -0
  10. package/dist/docs/components/asset-chip.md +294 -0
  11. package/dist/docs/components/autocomplete.md +619 -0
  12. package/dist/docs/components/avatar.md +321 -0
  13. package/dist/docs/components/badge.md +339 -0
  14. package/dist/docs/components/badged-logo.md +116 -0
  15. package/dist/docs/components/banner.md +379 -0
  16. package/dist/docs/components/bar-chart.md +208 -0
  17. package/dist/docs/components/breadcrumbs.md +380 -0
  18. package/dist/docs/components/button-group.md +286 -0
  19. package/dist/docs/components/button.md +650 -0
  20. package/dist/docs/components/calendar.md +375 -0
  21. package/dist/docs/components/callout.md +96 -0
  22. package/dist/docs/components/checkbox-group.md +521 -0
  23. package/dist/docs/components/checkbox.md +467 -0
  24. package/dist/docs/components/choice-group.md +516 -0
  25. package/dist/docs/components/choicebox.md +641 -0
  26. package/dist/docs/components/code.md +100 -0
  27. package/dist/docs/components/combobox.md +939 -0
  28. package/dist/docs/components/container.md +257 -0
  29. package/dist/docs/components/copy-button.md +642 -0
  30. package/dist/docs/components/date-picker.md +514 -0
  31. package/dist/docs/components/dialog.md +1332 -0
  32. package/dist/docs/components/drawer.md +966 -0
  33. package/dist/docs/components/empty.md +340 -0
  34. package/dist/docs/components/field.md +570 -0
  35. package/dist/docs/components/fieldset.md +398 -0
  36. package/dist/docs/components/frame.md +434 -0
  37. package/dist/docs/components/gauge.md +299 -0
  38. package/dist/docs/components/get-started-visual.md +117 -0
  39. package/dist/docs/components/grid.md +288 -0
  40. package/dist/docs/components/hero-visual.md +155 -0
  41. package/dist/docs/components/hex.md +487 -0
  42. package/dist/docs/components/icon-tile.md +292 -0
  43. package/dist/docs/components/identicon.md +371 -0
  44. package/dist/docs/components/inline.md +233 -0
  45. package/dist/docs/components/inset.md +225 -0
  46. package/dist/docs/components/kbd.md +423 -0
  47. package/dist/docs/components/list-group.md +981 -0
  48. package/dist/docs/components/loading-dots.md +237 -0
  49. package/dist/docs/components/menu.md +934 -0
  50. package/dist/docs/components/native-select.md +204 -0
  51. package/dist/docs/components/network-logo.md +248 -0
  52. package/dist/docs/components/number-field.md +543 -0
  53. package/dist/docs/components/otp-field.md +616 -0
  54. package/dist/docs/components/pagination.md +516 -0
  55. package/dist/docs/components/popover.md +544 -0
  56. package/dist/docs/components/progress.md +388 -0
  57. package/dist/docs/components/qr.md +314 -0
  58. package/dist/docs/components/radio-group.md +528 -0
  59. package/dist/docs/components/secret-value.md +406 -0
  60. package/dist/docs/components/select.md +751 -0
  61. package/dist/docs/components/separator.md +379 -0
  62. package/dist/docs/components/sidebar-menu.md +922 -0
  63. package/dist/docs/components/skeleton.md +517 -0
  64. package/dist/docs/components/slider.md +539 -0
  65. package/dist/docs/components/snippet.md +424 -0
  66. package/dist/docs/components/spinner.md +216 -0
  67. package/dist/docs/components/split-bar.md +139 -0
  68. package/dist/docs/components/split-button.md +464 -0
  69. package/dist/docs/components/stack.md +299 -0
  70. package/dist/docs/components/status-chip.md +226 -0
  71. package/dist/docs/components/status-indicator.md +119 -0
  72. package/dist/docs/components/status-row.md +174 -0
  73. package/dist/docs/components/stepper.md +451 -0
  74. package/dist/docs/components/success-hero.md +157 -0
  75. package/dist/docs/components/surface.md +639 -0
  76. package/dist/docs/components/switch.md +472 -0
  77. package/dist/docs/components/table.md +967 -0
  78. package/dist/docs/components/tabs.md +627 -0
  79. package/dist/docs/components/tempo-logo.md +185 -0
  80. package/dist/docs/components/text-input.md +624 -0
  81. package/dist/docs/components/textarea.md +352 -0
  82. package/dist/docs/components/toast.md +535 -0
  83. package/dist/docs/components/token-logo.md +371 -0
  84. package/dist/docs/components/token.md +247 -0
  85. package/dist/docs/components/tooltip.md +490 -0
  86. package/dist/docs/components/verification-code.md +116 -0
  87. package/dist/docs/components/visual.md +249 -0
  88. package/dist/docs/components.md +203 -0
  89. package/dist/docs/foundations/accessibility.md +377 -0
  90. package/dist/docs/foundations/agents.md +150 -0
  91. package/dist/docs/foundations/color.md +522 -0
  92. package/dist/docs/foundations/content/tone.md +194 -0
  93. package/dist/docs/foundations/content/voice.md +194 -0
  94. package/dist/docs/foundations/content/writing-style.md +406 -0
  95. package/dist/docs/foundations/iconography.md +282 -0
  96. package/dist/docs/foundations/intent.md +360 -0
  97. package/dist/docs/foundations/layout.md +508 -0
  98. package/dist/docs/foundations/linter.md +296 -0
  99. package/dist/docs/foundations/motion.md +151 -0
  100. package/dist/docs/foundations/radius-and-padding.md +86 -0
  101. package/dist/docs/foundations/typography.md +266 -0
  102. package/dist/docs/index.md +137 -0
  103. package/dist/docs/introduction/faq.md +132 -0
  104. package/dist/docs/introduction/getting-started.md +377 -0
  105. package/dist/docs/patterns/blockchain-values.md +709 -0
  106. package/dist/docs/patterns/dashboards.md +638 -0
  107. package/dist/docs/patterns/destructive-actions.md +626 -0
  108. package/dist/docs/patterns/empty-states.md +612 -0
  109. package/dist/docs/patterns/errors-and-validation.md +808 -0
  110. package/dist/docs/patterns/feedback-and-status.md +518 -0
  111. package/dist/docs/patterns/forms.md +679 -0
  112. package/dist/docs/patterns/loading.md +630 -0
  113. package/dist/docs/patterns/navigation.md +397 -0
  114. package/dist/docs/patterns/payments.md +765 -0
  115. package/dist/docs/patterns/responsive-layout.md +997 -0
  116. package/dist/docs/patterns/tables-and-lists.md +964 -0
  117. package/dist/docs/products/tempo-console.md +671 -0
  118. package/dist/docs/products/tempo-performance.md +437 -0
  119. package/dist/docs/products/tempo-wallet.md +438 -0
  120. package/package.json +1 -1
@@ -0,0 +1,535 @@
1
+ # Toast
2
+
3
+ Shows a brief notification that dismisses itself.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Toast.tsx)
6
+
7
+ Figma: [Toast](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=1186-3381) (`Toast.Item`)
8
+
9
+ ## Overview
10
+
11
+ Toasts are queued with a hook and render in a live region at the edge of the viewport.
12
+
13
+ ## Examples
14
+
15
+ ### Basic
16
+
17
+ ```tsx
18
+ import { Button, Toast } from '@tempoxyz/ds'
19
+
20
+ function Trigger() {
21
+ const toast = Toast.useToast()
22
+
23
+ return (
24
+ <Button
25
+ onClick={() =>
26
+ toast.add({ description: 'Transfers settle in seconds.', title: 'Payment sent' })
27
+ }
28
+ size="small"
29
+ variant="secondary"
30
+ >
31
+ Show toast
32
+ </Button>
33
+ )
34
+ }
35
+
36
+ export function Demo() {
37
+ return (
38
+ <Toast.Provider>
39
+ <Trigger />
40
+ <Toast.Viewport />
41
+ </Toast.Provider>
42
+ )
43
+ }
44
+ ```
45
+
46
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Toast/Basic.tsx)
47
+
48
+ ### Intent
49
+
50
+ Pass `intent` to `toast.add` as `neutral` (default), `info`, `positive`, `warning`, or `negative`.
51
+
52
+ ```tsx
53
+ import { Button, style, Toast } from '@tempoxyz/ds'
54
+
55
+ const intents = ['neutral', 'info', 'positive', 'warning', 'negative'] as const
56
+
57
+ function Triggers() {
58
+ const toast = Toast.useToast()
59
+
60
+ return (
61
+ <div {...styles.row()}>
62
+ {intents.map((intent) => (
63
+ <Button
64
+ key={intent}
65
+ onClick={() =>
66
+ toast.add({
67
+ description: 'Transfers settle in seconds.',
68
+ intent,
69
+ title: `${intent} toast`,
70
+ })
71
+ }
72
+ size="small"
73
+ variant="secondary"
74
+ >
75
+ {intent}
76
+ </Button>
77
+ ))}
78
+ </div>
79
+ )
80
+ }
81
+
82
+ export function Demo() {
83
+ return (
84
+ <Toast.Provider>
85
+ <Triggers />
86
+ <Toast.Viewport />
87
+ </Toast.Provider>
88
+ )
89
+ }
90
+
91
+ namespace styles {
92
+ export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '12' })
93
+ }
94
+ ```
95
+
96
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Toast/Intent.tsx)
97
+
98
+ ### Action
99
+
100
+ Pass an `action` with a `label` to add a button. Set `timeout: 0` to keep the toast open until dismissed.
101
+
102
+ ```tsx
103
+ import { Button, Toast } from '@tempoxyz/ds'
104
+
105
+ function Trigger() {
106
+ const toast = Toast.useToast()
107
+
108
+ return (
109
+ <Button
110
+ onClick={() =>
111
+ toast.add({
112
+ action: { label: 'Undo' },
113
+ intent: 'positive',
114
+ timeout: 0,
115
+ title: 'Archived',
116
+ })
117
+ }
118
+ size="small"
119
+ variant="secondary"
120
+ >
121
+ With action
122
+ </Button>
123
+ )
124
+ }
125
+
126
+ export function Demo() {
127
+ return (
128
+ <Toast.Provider>
129
+ <Trigger />
130
+ <Toast.Viewport />
131
+ </Toast.Provider>
132
+ )
133
+ }
134
+ ```
135
+
136
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Toast/Action.tsx)
137
+
138
+ ### Item
139
+
140
+ `Toast.Viewport` renders a `Toast.Item` for each queued toast. Render an item yourself only in a custom viewport under `Toast.Provider`, and pass it a toast object, whose `type` sets the intent.
141
+
142
+ ```tsx
143
+ import { style, Toast } from '@tempoxyz/ds'
144
+
145
+ export function Demo() {
146
+ return (
147
+ <Toast.Provider>
148
+ <div {...styles.frame()}>
149
+ <Toast.Item
150
+ toast={{
151
+ description: 'Sent 25.00 USDC to Alice',
152
+ id: 'sent',
153
+ title: 'Payment sent',
154
+ type: 'positive',
155
+ }}
156
+ />
157
+ </div>
158
+ </Toast.Provider>
159
+ )
160
+ }
161
+
162
+ namespace styles {
163
+ // The item sits at the bottom of its containing block, as the viewport places it.
164
+ export const frame = style({ height: '72', position: 'relative', width: '320' })
165
+ }
166
+ ```
167
+
168
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Toast/Item.tsx)
169
+
170
+ ## Anatomy
171
+
172
+ Import the component and assemble its parts.
173
+
174
+ ```tsx
175
+ import { Toast } from '@tempoxyz/ds'
176
+
177
+ <Toast.Provider>
178
+ <Toast.Viewport />
179
+ <Toast.Item />
180
+ </Toast.Provider>
181
+ ```
182
+
183
+ ## Guidelines
184
+
185
+ ### When to Use
186
+
187
+ * Confirm that a user action finished, such as Payment sent or Webhook saved.
188
+ * Report a background event that needs no response, such as a deposit that arrived while the user was on another page.
189
+ * Offer a short Undo after a reversible action, such as Archived, when the same result is reachable elsewhere.
190
+
191
+ ### When Not to Use
192
+
193
+ * Use an [Alert](/docs/components/alert) for an error or warning that must stay beside its content, such as a failed payment.
194
+ * Use a [Banner](/docs/components/banner) for a condition that affects the whole product, such as an outage.
195
+ * Use an [AlertDialog](/docs/components/alert-dialog) for a decision before an action continues.
196
+ * Use `Field.Error` from [Field](/docs/components/field) for validation messages on an input.
197
+ * Use `loading` on a [Button](/docs/components/button), or [Progress](/docs/components/progress), for work that still runs.
198
+
199
+ ### Keep Required Actions Out of Toasts
200
+
201
+ A toast dismisses itself, and keyboard users must press F6 to reach it. Put required steps in the page or in an [AlertDialog](/docs/components/alert-dialog).
202
+
203
+ **Do:** Confirm a finished action and include the detail that identifies it.
204
+
205
+ ```tsx
206
+ /**
207
+ * Do example for "Keep Required Actions Out of Toasts" on the Toast page.
208
+ * Confirm a finished action and include the detail that identifies it.
209
+ * @module
210
+ */
211
+ import { CheckCircle, Close } from '@tempoxyz/ds/icons'
212
+ import { style } from '@tempoxyz/ds'
213
+
214
+ // Toasts render in a portal, so this preview draws one in place with the toast's styles.
215
+ /** Renders the static preview, which the guideline card shows inert. */
216
+ export function Demo() {
217
+ return (
218
+ <div {...styles.toast()}>
219
+ <CheckCircle {...styles.icon()} />
220
+ <div {...styles.body()}>
221
+ <div {...styles.title()}>Payment sent</div>
222
+ <div {...styles.description()}>50.00 USDC to 0x8f3c…a21b</div>
223
+ </div>
224
+ <Close {...styles.close()} />
225
+ </div>
226
+ )
227
+ }
228
+
229
+ namespace styles {
230
+ export const body = style({
231
+ display: 'flex',
232
+ flex: '1 !custom',
233
+ flexDirection: 'column',
234
+ minWidth: '0px !custom',
235
+ rowGap: '4',
236
+ })
237
+
238
+ export const close = style({ color: 'content.tertiary', flexShrink: '0 !custom', fontSize: '16' })
239
+
240
+ export const description = style({ color: 'content.secondary', typography: 'body.b2' })
241
+
242
+ export const icon = style({ color: 'content.positive', flexShrink: '0 !custom', fontSize: '20' })
243
+
244
+ export const title = style({ color: 'content.primary', typography: 'body.b2Strong' })
245
+
246
+ export const toast = style({
247
+ alignItems: 'center',
248
+ backgroundColor: 'background.elevated',
249
+ borderRadius: 'sm',
250
+ boxShadow: 'regular',
251
+ boxSizing: 'border-box',
252
+ columnGap: '12',
253
+ display: 'flex',
254
+ paddingBlock: '16',
255
+ paddingInline: '20',
256
+ width: '100% !custom',
257
+ })
258
+ }
259
+ ```
260
+
261
+ **Don't:** Ask for a confirmation or another required step in a toast.
262
+
263
+ ```tsx
264
+ /**
265
+ * Don't example for "Keep Required Actions Out of Toasts" on the Toast page.
266
+ * Don't ask for a confirmation or another required step in a toast.
267
+ * @module
268
+ */
269
+ import { AlertTriangle, Close } from '@tempoxyz/ds/icons'
270
+ import { style } from '@tempoxyz/ds'
271
+
272
+ // Toasts render in a portal, so this preview draws one in place with the toast's styles.
273
+ /** Renders the static preview, which the guideline card shows inert. */
274
+ export function Demo() {
275
+ return (
276
+ <div {...styles.toast()}>
277
+ <AlertTriangle {...styles.icon()} />
278
+ <div {...styles.body()}>
279
+ <div {...styles.title()}>Confirm payment</div>
280
+ <div {...styles.description()}>50.00 USDC to 0x8f3c…a21b</div>
281
+ </div>
282
+ <span {...styles.action()}>Confirm</span>
283
+ <Close {...styles.close()} />
284
+ </div>
285
+ )
286
+ }
287
+
288
+ namespace styles {
289
+ export const action = style({
290
+ alignItems: 'center',
291
+ backgroundColor: 'container.regular',
292
+ borderRadius: 'full',
293
+ color: 'content.primary',
294
+ cornerShape: 'round',
295
+ display: 'inline-flex',
296
+ flexShrink: '0 !custom',
297
+ height: '32',
298
+ paddingInline: '12',
299
+ typography: 'body.b3Strong',
300
+ })
301
+
302
+ export const body = style({
303
+ display: 'flex',
304
+ flex: '1 !custom',
305
+ flexDirection: 'column',
306
+ minWidth: '0px !custom',
307
+ rowGap: '4',
308
+ })
309
+
310
+ export const close = style({ color: 'content.tertiary', flexShrink: '0 !custom', fontSize: '16' })
311
+
312
+ export const description = style({ color: 'content.secondary', typography: 'body.b2' })
313
+
314
+ export const icon = style({ color: 'content.warning', flexShrink: '0 !custom', fontSize: '20' })
315
+
316
+ export const title = style({ color: 'content.primary', typography: 'body.b2Strong' })
317
+
318
+ export const toast = style({
319
+ alignItems: 'center',
320
+ backgroundColor: 'background.elevated',
321
+ borderRadius: 'sm',
322
+ boxShadow: 'regular',
323
+ boxSizing: 'border-box',
324
+ columnGap: '12',
325
+ display: 'flex',
326
+ paddingBlock: '16',
327
+ paddingInline: '20',
328
+ width: '100% !custom',
329
+ })
330
+ }
331
+ ```
332
+
333
+ An Undo action is fine if the page also reverses the change, such as an Archive tab that restores an archived key.
334
+
335
+ ### Choose an Intent
336
+
337
+ * **Neutral (neutral):** The default, with no icon. Updates with no outcome to judge, such as Signed out.
338
+ * **Info (info):** Events the user didn't start, such as a deposit that arrived.
339
+ * **Positive (positive):** An action that succeeded, such as a confirmation that reads Payment sent.
340
+ * **Warning (warning):** An action that finished with a caveat, such as a test delivery that timed out.
341
+ * **Negative (negative):** A non-critical action that failed and that the user can try again.
342
+
343
+ ### Set Duration by Content
344
+
345
+ * **Short Content (5 seconds):** The default, for a title and a short description.
346
+ * **Longer Description (timeout):** Raise `timeout`, or set it app-wide on `Toast.Provider`.
347
+ * **Action (timeout: 0):** Keeps the toast open until dismissed ([SC 2.2.1](https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html)).
348
+
349
+ ### Send One Toast per Outcome
350
+
351
+ `Toast.Provider` shows up to three toasts by default, and hides older ones past its `limit`. Combine related results into one toast.
352
+
353
+ **Do:** Combine related results into one toast, such as 3 payments sent.
354
+
355
+ ```tsx
356
+ /**
357
+ * Do example for "Send One Toast per Outcome" on the Toast page.
358
+ * Combine related results into one toast, such as 3 payments sent.
359
+ * @module
360
+ */
361
+ import { CheckCircle, Close } from '@tempoxyz/ds/icons'
362
+ import { style } from '@tempoxyz/ds'
363
+
364
+ // Toasts render in a portal, so this preview draws one in place with the toast's styles.
365
+ /** Renders the static preview, which the guideline card shows inert. */
366
+ export function Demo() {
367
+ return (
368
+ <div {...styles.toast()}>
369
+ <CheckCircle {...styles.icon()} />
370
+ <div {...styles.body()}>
371
+ <div {...styles.title()}>3 payments sent</div>
372
+ <div {...styles.description()}>150.00 USDC to 3 recipients</div>
373
+ </div>
374
+ <Close {...styles.close()} />
375
+ </div>
376
+ )
377
+ }
378
+
379
+ namespace styles {
380
+ export const body = style({
381
+ display: 'flex',
382
+ flex: '1 !custom',
383
+ flexDirection: 'column',
384
+ minWidth: '0px !custom',
385
+ rowGap: '4',
386
+ })
387
+
388
+ export const close = style({ color: 'content.tertiary', flexShrink: '0 !custom', fontSize: '16' })
389
+
390
+ export const description = style({ color: 'content.secondary', typography: 'body.b2' })
391
+
392
+ export const icon = style({ color: 'content.positive', flexShrink: '0 !custom', fontSize: '20' })
393
+
394
+ export const title = style({ color: 'content.primary', typography: 'body.b2Strong' })
395
+
396
+ export const toast = style({
397
+ alignItems: 'center',
398
+ backgroundColor: 'background.elevated',
399
+ borderRadius: 'sm',
400
+ boxShadow: 'regular',
401
+ boxSizing: 'border-box',
402
+ columnGap: '12',
403
+ display: 'flex',
404
+ paddingBlock: '16',
405
+ paddingInline: '20',
406
+ width: '100% !custom',
407
+ })
408
+ }
409
+ ```
410
+
411
+ **Don't:** Send a separate toast for each result of one action.
412
+
413
+ ```tsx
414
+ /**
415
+ * Don't example for "Send One Toast per Outcome" on the Toast page.
416
+ * Don't send a separate toast for each result of one action.
417
+ * @module
418
+ */
419
+ import { CheckCircle, Close } from '@tempoxyz/ds/icons'
420
+ import { style } from '@tempoxyz/ds'
421
+
422
+ const payments = ['0x8f3c…a21b', '0x41d0…9c7e', '0xb27a…04f5']
423
+
424
+ // Toasts render in a portal, so this preview draws them in place with the toast's styles.
425
+ /** Renders the static preview, which the guideline card shows inert. */
426
+ export function Demo() {
427
+ return (
428
+ <div {...styles.stack()}>
429
+ {payments.map((address) => (
430
+ <div key={address} {...styles.toast()}>
431
+ <CheckCircle {...styles.icon()} />
432
+ <div {...styles.body()}>
433
+ <div {...styles.title()}>Payment sent</div>
434
+ <div {...styles.description()}>50.00 USDC to {address}</div>
435
+ </div>
436
+ <Close {...styles.close()} />
437
+ </div>
438
+ ))}
439
+ </div>
440
+ )
441
+ }
442
+
443
+ namespace styles {
444
+ export const body = style({
445
+ display: 'flex',
446
+ flex: '1 !custom',
447
+ flexDirection: 'column',
448
+ minWidth: '0px !custom',
449
+ rowGap: '4',
450
+ })
451
+
452
+ export const close = style({ color: 'content.tertiary', flexShrink: '0 !custom', fontSize: '16' })
453
+
454
+ export const description = style({ color: 'content.secondary', typography: 'body.b2' })
455
+
456
+ export const icon = style({ color: 'content.positive', flexShrink: '0 !custom', fontSize: '20' })
457
+
458
+ export const stack = style({
459
+ display: 'flex',
460
+ flexDirection: 'column',
461
+ gap: '8',
462
+ width: '100% !custom',
463
+ })
464
+
465
+ export const title = style({ color: 'content.primary', typography: 'body.b2Strong' })
466
+
467
+ export const toast = style({
468
+ alignItems: 'center',
469
+ backgroundColor: 'background.elevated',
470
+ borderRadius: 'sm',
471
+ boxShadow: 'regular',
472
+ boxSizing: 'border-box',
473
+ columnGap: '12',
474
+ display: 'flex',
475
+ paddingBlock: '16',
476
+ paddingInline: '20',
477
+ width: '100% !custom',
478
+ })
479
+ }
480
+ ```
481
+
482
+ ## Content
483
+
484
+ * Write the title as the result in a few words, usually past tense: Payment sent, Key revoked, Webhook saved.
485
+ * Add a description only for the detail that identifies the action, such as 50.00 USDC to 0x8f3c…a21b.
486
+ * Leave out exclamation marks and filler such as Success or Done.
487
+ * Label the action with one verb, such as Undo or Retry.
488
+
489
+ ## Accessibility
490
+
491
+ Toasts never take focus on their own. Don't move focus to a new toast yourself.
492
+
493
+ ### Semantics
494
+
495
+ * **Toast.Viewport (region):** A landmark named "Notifications". Announces new toasts without moving focus.
496
+ * **Toast (dialog):** A non-modal dialog, named by its title and described by its description.
497
+ * **High Priority (alertdialog):** With `priority: 'high'`, a separate alert interrupts current speech. Intent alone never does.
498
+ * **Action and Dismiss (button):** The action is named by `action.label`. Every toast also has a Dismiss button.
499
+ * **Intent Icon (aria-hidden):** Hidden from assistive technology, so the title must carry the outcome.
500
+
501
+ ### Keyboard
502
+
503
+ * **Reach the Viewport (F6):** Moves focus to the toast viewport from anywhere on the page.
504
+ * **Move Through the Toast (Tab):** Moves focus to the newest toast, then to its action and Dismiss button.
505
+ * **Move Back (Shift+Tab):** Moves focus back. From the viewport, returns focus to where it was before F6.
506
+ * **Activate a Button (Enter or Space):** Activates the action or the Dismiss button that holds focus.
507
+ * **Dismiss the Toast (Escape):** Dismisses the toast that holds focus, the same as its Dismiss button.
508
+
509
+ ### Dismissal
510
+
511
+ * **Pausing:** Hover or focus in the viewport pauses all dismiss timers, as does a background window.
512
+ * **Swiping:** On touch screens, a swipe down or to the right dismisses a toast.
513
+
514
+ ### Your Responsibilities
515
+
516
+ * **Reserve High Priority (priority: 'high'):** Use it only for urgent messages. Show critical errors inline or in a [Dialog](/docs/components/dialog).
517
+ * **Render One Viewport (F6):** Render one viewport per app, so the shortcut always reaches it.
518
+
519
+ ## Related
520
+
521
+ [Alert](/docs/components/alert)
522
+
523
+ Use for messages that stay beside their content.
524
+
525
+ [Banner](/docs/components/banner)
526
+
527
+ Use for messages about the whole product.
528
+
529
+ [AlertDialog](/docs/components/alert-dialog)
530
+
531
+ Use for decisions before an action continues.
532
+
533
+ [Feedback and Status](/docs/patterns/feedback-and-status)
534
+
535
+ Covers choosing a message component.