@tempoxyz/ds 0.3.9 → 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 (128) 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/dist/web/components/OtpField.css +1 -1
  121. package/dist/web/components/OtpField.d.ts +1 -1
  122. package/dist/web/components/OtpField.d.ts.map +1 -1
  123. package/dist/web/components/OtpField.js +3 -4
  124. package/dist/web/components/OtpField.js.map +1 -1
  125. package/dist/web/components/OtpField.js.zyzz.json +1 -1
  126. package/dist/web/index.js.zyzz.json +1 -1
  127. package/package.json +1 -1
  128. package/src/web/components/OtpField.tsx +2 -24
@@ -0,0 +1,518 @@
1
+ # Feedback and Status
2
+
3
+ Name each system state once, and choose [Toast](/docs/components/toast), [Alert](/docs/components/alert), or [Banner](/docs/components/banner) by urgency.
4
+
5
+ ## Overview
6
+
7
+ Every action needs a response, and every change of state needs a visible result. Two questions pick the component: what the message describes (one action, one section, or the whole product), and how soon the reader must act. Match the weight of the message to the weight of the event, since overused loud feedback trains people to ignore it.
8
+
9
+ [Loading](/docs/patterns/loading) and [Empty States](/docs/patterns/empty-states) cover the states before content arrives.
10
+
11
+ ## Components
12
+
13
+ | Component | Scope | Lifetime | Typical use |
14
+ | --- | --- | --- | --- |
15
+ | [Field](/docs/components/field) `Field.Error` | One value | Until corrected | Enter 1,250.00 USDC or less |
16
+ | [Badge](/docs/components/badge), or `status` on a [Table](/docs/components/table) cell | One record | While the state holds | A transaction or a webhook delivery |
17
+ | [Toast](/docs/components/toast) | One action | Seconds | The result of an action the reader started |
18
+ | [Alert](/docs/components/alert) | One section | Until resolved | Couldn't load older activity |
19
+ | [Banner](/docs/components/banner) | Whole product | Until resolved or dismissed | Testnet faucets are paused for maintenance |
20
+ | [AlertDialog](/docs/components/alert-dialog) | One decision | Until answered | Revoke this API key? |
21
+
22
+ * **Toast:** Dismisses itself after five seconds by default, so never put information in it that the reader must keep or act on. Offer its action elsewhere too. Set `timeout: 0` for a toast with Undo, and show critical errors inline instead.
23
+ * **Alert:** Sits beside the decision it affects, with one action at most. Do not use it for a passing confirmation such as Address copied.
24
+ * **Banner:** Describes the product, not one piece of content. Show at most one at a time, and never for a routine confirmation.
25
+
26
+ ## State Vocabulary
27
+
28
+ Each state has one word, one component, and one icon.
29
+
30
+ * **Unavailable (No icon):** The value does not exist now, such as a missing price. Show Unavailable in gray in its place.
31
+ * **Couldn't Load (AlertCircle):** A request for the region's content failed. Use a negative [Alert](/docs/components/alert) or an [Empty](/docs/components/empty) state, with a retry.
32
+ * **Pending (Pending):** Submitted and waiting for inclusion in a block. Use a [Badge](/docs/components/badge) with the icon.
33
+ * **Confirmed (CheckCircle):** Included in a block. Use a [Badge](/docs/components/badge) with the icon.
34
+ * **Failed (AlertCircle):** Rejected or reverted by the network. Use a [Badge](/docs/components/badge) with the icon, and the reason nearby.
35
+ * **Amount Hidden (EyeOff):** The reader hid amounts on this device. Show a fixed mask, read aloud as Amount hidden.
36
+
37
+ In a [Table](/docs/components/table), set `status` on `Table.Cell` to `warning`, `positive`, or `negative` for Pending, Confirmed, and Failed. The cell colors its text, so keep the same word.
38
+
39
+ ```tsx
40
+ import { Alert, Badge, ListGroup, style, Surface } from '@tempoxyz/ds'
41
+ import { AlertCircle, CheckCircle, Pending } from '@tempoxyz/ds/icons'
42
+
43
+ export const fill = true
44
+ function Balances() {
45
+ return (
46
+ <Surface>
47
+ <Surface.Header>
48
+ <Surface.Title>Balances</Surface.Title>
49
+ </Surface.Header>
50
+ <ListGroup.Root>
51
+ <ListGroup.Row>
52
+ <ListGroup.Info>
53
+ <ListGroup.Title>USDC</ListGroup.Title>
54
+ <ListGroup.Description>1,000.00 USDC</ListGroup.Description>
55
+ </ListGroup.Info>
56
+ $1,000.00
57
+ </ListGroup.Row>
58
+ <ListGroup.Row>
59
+ <ListGroup.Info>
60
+ <ListGroup.Title>EURC</ListGroup.Title>
61
+ <ListGroup.Description>500.00 EURC</ListGroup.Description>
62
+ </ListGroup.Info>
63
+ <span {...styles.muted()}>Unavailable</span>
64
+ </ListGroup.Row>
65
+ </ListGroup.Root>
66
+ </Surface>
67
+ )
68
+ }
69
+
70
+ function Activity() {
71
+ return (
72
+ <Surface>
73
+ <Surface.Header>
74
+ <Surface.Title>Activity</Surface.Title>
75
+ </Surface.Header>
76
+ <ListGroup.Root>
77
+ <ListGroup.Row>
78
+ <ListGroup.Info>
79
+ <ListGroup.Title>Sent 25.00 USDC</ListGroup.Title>
80
+ <ListGroup.Description>To 0x71C7…976F</ListGroup.Description>
81
+ </ListGroup.Info>
82
+ <Badge>
83
+ <Pending />
84
+ Pending
85
+ </Badge>
86
+ </ListGroup.Row>
87
+ <ListGroup.Row>
88
+ <ListGroup.Info>
89
+ <ListGroup.Title>Received 120.00 USDC</ListGroup.Title>
90
+ <ListGroup.Description>From 0x3C44…93BC</ListGroup.Description>
91
+ </ListGroup.Info>
92
+ <Badge>
93
+ <CheckCircle />
94
+ Confirmed
95
+ </Badge>
96
+ </ListGroup.Row>
97
+ <ListGroup.Row>
98
+ <ListGroup.Info>
99
+ <ListGroup.Title>Sent 40.00 USDC</ListGroup.Title>
100
+ <ListGroup.Description>
101
+ Not enough USDC left to cover the network fee
102
+ </ListGroup.Description>
103
+ </ListGroup.Info>
104
+ <Badge>
105
+ <AlertCircle />
106
+ Failed
107
+ </Badge>
108
+ </ListGroup.Row>
109
+ </ListGroup.Root>
110
+ <Alert intent="negative" {...styles.alert()}>
111
+ <Alert.Icon />
112
+ <Alert.Content>
113
+ Couldn't load older activity.
114
+ <Alert.Action>Try again</Alert.Action>
115
+ </Alert.Content>
116
+ </Alert>
117
+ </Surface>
118
+ )
119
+ }
120
+
121
+ export function Demo() {
122
+ return (
123
+ <div {...styles.grid()}>
124
+ <Balances />
125
+ <Activity />
126
+ </div>
127
+ )
128
+ }
129
+
130
+ namespace styles {
131
+ export const alert = style({ marginBlockStart: '16' })
132
+
133
+ export const grid = style({
134
+ alignItems: 'start',
135
+ backgroundColor: 'background.primary',
136
+ display: 'grid',
137
+ gap: '16',
138
+ gridTemplateColumns: 'repeat(auto-fill, minmax(18rem, 1fr)) !custom',
139
+ padding: '16',
140
+ })
141
+
142
+ export const muted = style({ color: 'content.secondary', typography: 'body.b2' })
143
+ }
144
+ ```
145
+
146
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Patterns/StatusVocabulary.tsx)
147
+
148
+ This reference layout shows five of the states, built from [Surface](/docs/components/surface), [ListGroup](/docs/components/list-group), [Badge](/docs/components/badge), and [Alert](/docs/components/alert).
149
+
150
+ * **Unavailable:** Keep the rest of the row, since the token balance is still known. If the reason helps the reader act, state it nearby.
151
+ * **Couldn't load:** Name the content, such as Couldn't load activity. If part of a region failed, keep what loaded and use an alert. If all of it failed, use an [empty state](/docs/patterns/empty-states) with Try again.
152
+ * **Pending:** Keep the transaction in activity with its amount and recipient, from submission until inclusion in a block (see [Loading](/docs/patterns/loading#show-pending-transactions)).
153
+ * **Failed:** Keep the row in activity and state the reason (see [Errors and Validation](/docs/patterns/errors-and-validation#explain-transaction-failures)).
154
+ * **Amount hidden:** Mask every amount, as [Blockchain Values](/docs/patterns/blockchain-values#hidden-amounts) describes.
155
+
156
+ ## Urgency
157
+
158
+ Rank each message before you choose how to show it.
159
+
160
+ * **Low (Toast):** An expected confirmation, such as Address copied.
161
+ * **Medium (Alert):** Information that affects a decision. Place it beside the decision.
162
+ * **High (Banner or Alert):** A condition that blocks work or puts funds at risk. Keep it until the condition clears.
163
+ * **Critical (AlertDialog):** A decision the reader must make first (see [Destructive Actions](/docs/patterns/destructive-actions)).
164
+
165
+ ## Intent
166
+
167
+ Choose the intent from the meaning of the message. Keep it consistent across [Toast](/docs/components/toast), [Alert](/docs/components/alert), and [Banner](/docs/components/banner).
168
+
169
+ * **Neutral (neutral):** General information with no judgment.
170
+ * **Tip (tip):** Helpful context that does not need action.
171
+ * **Positive (positive):** A successful result, such as Confirmed.
172
+ * **Warning (warning):** A risk to weigh before continuing, and Pending.
173
+ * **Negative (negative):** A failure or a blocked task.
174
+
175
+ ## Guidelines
176
+
177
+ ### Choose a Channel by Scope
178
+
179
+ Show each message in the smallest region it describes, from the [Components](#components) table.
180
+
181
+ **Do:** Report a problem with one section in an alert inside that section.
182
+
183
+ ```tsx
184
+ /**
185
+ * Do example for "Choose a Channel by Scope" on the Feedback and Status page.
186
+ * Report a problem with one section in an alert inside that section.
187
+ * @module
188
+ */
189
+ import { Alert, ListGroup, Stack, style, Surface } from '@tempoxyz/ds'
190
+
191
+ /** Renders the static preview, which the guideline card shows inert. */
192
+ export function Demo() {
193
+ return (
194
+ <Surface size="small" {...styles.fill()}>
195
+ <Stack gap="12">
196
+ <Surface.Title>Activity</Surface.Title>
197
+ <ListGroup.Root>
198
+ <ListGroup.Row>
199
+ <ListGroup.Info>
200
+ <ListGroup.Title>Received 120.00 USDC</ListGroup.Title>
201
+ <ListGroup.Description>From 0x8f3a…12c4</ListGroup.Description>
202
+ </ListGroup.Info>
203
+ </ListGroup.Row>
204
+ </ListGroup.Root>
205
+ <Alert intent="negative">
206
+ <Alert.Icon />
207
+ <Alert.Content>
208
+ Couldn't load older activity.
209
+ <Alert.Action>Try again</Alert.Action>
210
+ </Alert.Content>
211
+ </Alert>
212
+ </Stack>
213
+ </Surface>
214
+ )
215
+ }
216
+
217
+ namespace styles {
218
+ export const fill = style({ width: '100% !custom' })
219
+ }
220
+ ```
221
+
222
+ **Don't:** Use a page-wide banner for a problem with one section.
223
+
224
+ ```tsx
225
+ /**
226
+ * Don't example for "Choose a Channel by Scope" on the Feedback and Status page.
227
+ * Don't use a page-wide banner for a problem with one section.
228
+ * @module
229
+ */
230
+ import { Banner, ListGroup, Stack, style, Surface } from '@tempoxyz/ds'
231
+
232
+ /** Renders the static preview, which the guideline card shows inert. */
233
+ export function Demo() {
234
+ return (
235
+ <Stack gap="16" {...styles.fill()}>
236
+ <Banner intent="negative">
237
+ <Banner.Content>Couldn't load older activity.</Banner.Content>
238
+ <Banner.Action>Try again</Banner.Action>
239
+ </Banner>
240
+ <Surface size="small">
241
+ <Stack gap="12">
242
+ <Surface.Title>Activity</Surface.Title>
243
+ <ListGroup.Root>
244
+ <ListGroup.Row>
245
+ <ListGroup.Info>
246
+ <ListGroup.Title>Received 120.00 USDC</ListGroup.Title>
247
+ <ListGroup.Description>From 0x8f3a…12c4</ListGroup.Description>
248
+ </ListGroup.Info>
249
+ </ListGroup.Row>
250
+ </ListGroup.Root>
251
+ </Stack>
252
+ </Surface>
253
+ </Stack>
254
+ )
255
+ }
256
+
257
+ namespace styles {
258
+ export const fill = style({ width: '100% !custom' })
259
+ }
260
+ ```
261
+
262
+ ### Pair Color With Text and an Icon
263
+
264
+ Each state has a word and an icon as well as a color, so it reads the same in grayscale, in high contrast, and on a screen reader.
265
+
266
+ **Do:** Show the state's word, with its icon before the text.
267
+
268
+ ```tsx
269
+ /**
270
+ * Do example for "Pair Color With Text and an Icon" on the Feedback and Status page.
271
+ * Show the state's word, with its icon before the text.
272
+ * @module
273
+ */
274
+ import { Badge, style } from '@tempoxyz/ds'
275
+ import { AlertCircle, CheckCircle, Pending } from '@tempoxyz/ds/icons'
276
+
277
+ /** Renders the static preview, which the guideline card shows inert. */
278
+ export function Demo() {
279
+ return (
280
+ <div {...styles.row()}>
281
+ <Badge>
282
+ <Pending />
283
+ Pending
284
+ </Badge>
285
+ <Badge>
286
+ <CheckCircle />
287
+ Confirmed
288
+ </Badge>
289
+ <Badge>
290
+ <AlertCircle />
291
+ Failed
292
+ </Badge>
293
+ </div>
294
+ )
295
+ }
296
+
297
+ namespace styles {
298
+ export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '8' })
299
+ }
300
+ ```
301
+
302
+ **Don't:** Use colored dots or tints alone to show a state.
303
+
304
+ ```tsx
305
+ /**
306
+ * Don't example for "Pair Color With Text and an Icon" on the Feedback and Status page.
307
+ * Don't use colored dots or tints alone to show a state.
308
+ * @module
309
+ */
310
+ import { Alert, style } from '@tempoxyz/ds'
311
+
312
+ /** Renders the static preview, which the guideline card shows inert. */
313
+ export function Demo() {
314
+ return (
315
+ <div {...styles.row()}>
316
+ {(['warning', 'positive', 'negative'] as const).map((intent) => (
317
+ <Alert intent={intent} key={intent}>
318
+ <Alert.Icon />
319
+ </Alert>
320
+ ))}
321
+ </div>
322
+ )
323
+ }
324
+
325
+ namespace styles {
326
+ export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '8' })
327
+ }
328
+ ```
329
+
330
+ ### Use the Same Word Everywhere
331
+
332
+ Use the vocabulary words for every product and transaction type, including payments, deposits, and swaps. Do not swap in synonyms such as Success, Settled, Complete, Processing, or Error.
333
+
334
+ **Do:** Use Pending and Confirmed for every transaction type.
335
+
336
+ ```tsx
337
+ /**
338
+ * Do example for "Use the Same Word Everywhere" on the Feedback and Status page.
339
+ * Use Pending and Confirmed for every transaction type.
340
+ * @module
341
+ */
342
+ import { Badge, ListGroup, style } from '@tempoxyz/ds'
343
+
344
+ /** Renders the static preview, which the guideline card shows inert. */
345
+ export function Demo() {
346
+ return (
347
+ <ListGroup.Root {...styles.fill()}>
348
+ <ListGroup.Row>
349
+ <ListGroup.Label>Payment</ListGroup.Label>
350
+ <Badge>Confirmed</Badge>
351
+ </ListGroup.Row>
352
+ <ListGroup.Row>
353
+ <ListGroup.Label>Deposit</ListGroup.Label>
354
+ <Badge>Confirmed</Badge>
355
+ </ListGroup.Row>
356
+ <ListGroup.Row>
357
+ <ListGroup.Label>Swap</ListGroup.Label>
358
+ <Badge>Pending</Badge>
359
+ </ListGroup.Row>
360
+ </ListGroup.Root>
361
+ )
362
+ }
363
+
364
+ namespace styles {
365
+ export const fill = style({ width: '100% !custom' })
366
+ }
367
+ ```
368
+
369
+ **Don't:** Describe the same state with different words and colors.
370
+
371
+ ```tsx
372
+ /**
373
+ * Don't example for "Use the Same Word Everywhere" on the Feedback and Status page.
374
+ * Don't describe the same state with different words and colors.
375
+ * @module
376
+ */
377
+ import { Badge, ListGroup, style } from '@tempoxyz/ds'
378
+
379
+ /** Renders the static preview, which the guideline card shows inert. */
380
+ export function Demo() {
381
+ return (
382
+ <ListGroup.Root {...styles.fill()}>
383
+ <ListGroup.Row>
384
+ <ListGroup.Label>Payment</ListGroup.Label>
385
+ <Badge>Success!</Badge>
386
+ </ListGroup.Row>
387
+ <ListGroup.Row>
388
+ <ListGroup.Label>Deposit</ListGroup.Label>
389
+ <Badge>Settled</Badge>
390
+ </ListGroup.Row>
391
+ <ListGroup.Row>
392
+ <ListGroup.Label>Swap</ListGroup.Label>
393
+ <Badge>Processing</Badge>
394
+ </ListGroup.Row>
395
+ </ListGroup.Root>
396
+ )
397
+ }
398
+
399
+ namespace styles {
400
+ export const fill = style({ width: '100% !custom' })
401
+ }
402
+ ```
403
+
404
+ ### Never Show a Stand-In as a Real Value
405
+
406
+ A zero, a dash, or a stale number reads as a real measurement. If there is no value, show Unavailable. If the request failed, show Couldn't load.
407
+
408
+ **Do:** Show Unavailable when a value has no source.
409
+
410
+ ```tsx
411
+ /**
412
+ * Do example for "Never Show a Stand-In as a Real Value" on the Feedback and Status page.
413
+ * Show Unavailable when a value has no source.
414
+ * @module
415
+ */
416
+ import { ListGroup, style } from '@tempoxyz/ds'
417
+
418
+ /** Renders the static preview, which the guideline card shows inert. */
419
+ export function Demo() {
420
+ return (
421
+ <ListGroup.Root {...styles.fill()}>
422
+ <ListGroup.Row>
423
+ <ListGroup.Info>
424
+ <ListGroup.Title>EURC</ListGroup.Title>
425
+ <ListGroup.Description>500.00 EURC</ListGroup.Description>
426
+ </ListGroup.Info>
427
+ <span {...styles.muted()}>Unavailable</span>
428
+ </ListGroup.Row>
429
+ </ListGroup.Root>
430
+ )
431
+ }
432
+
433
+ namespace styles {
434
+ export const fill = style({ width: '100% !custom' })
435
+
436
+ export const muted = style({ color: 'content.secondary', typography: 'body.b2' })
437
+ }
438
+ ```
439
+
440
+ **Don't:** Show $0.00 for a price you don't know.
441
+
442
+ ```tsx
443
+ /**
444
+ * Don't example for "Never Show a Stand-In as a Real Value" on the Feedback and Status page.
445
+ * Don't show $0.00 for a price you don't know.
446
+ * @module
447
+ */
448
+ import { ListGroup, style } from '@tempoxyz/ds'
449
+
450
+ /** Renders the static preview, which the guideline card shows inert. */
451
+ export function Demo() {
452
+ return (
453
+ <ListGroup.Root {...styles.fill()}>
454
+ <ListGroup.Row>
455
+ <ListGroup.Info>
456
+ <ListGroup.Title>EURC</ListGroup.Title>
457
+ <ListGroup.Description>500.00 EURC</ListGroup.Description>
458
+ </ListGroup.Info>
459
+ $0.00
460
+ </ListGroup.Row>
461
+ </ListGroup.Root>
462
+ )
463
+ }
464
+
465
+ namespace styles {
466
+ export const fill = style({ width: '100% !custom' })
467
+ }
468
+ ```
469
+
470
+ ## States
471
+
472
+ * **Default:** No message. Records show their status badge.
473
+ * **Error:** Couldn't load for a failed request, Failed for a rejected transaction, and a field error for a bad value.
474
+ * **Empty:** An empty state that states the cause (see [Empty States](/docs/patterns/empty-states)).
475
+ * **Success:** Confirmed on the record, and a positive [Toast](/docs/components/toast) for a finished action.
476
+
477
+ ## Content
478
+
479
+ * **Outcome First:** Lead with the result, such as "Payment sent", then add detail.
480
+ * **Tense:** Use the past tense for finished actions and the present tense for ongoing state.
481
+ * **One Sentence:** Keep toasts and alerts to one sentence.
482
+
483
+ ## Accessibility
484
+
485
+ * **Toasts (F6):** Toasts are announced, and hover or focus pauses their timers. Pass `priority: 'high'` only for urgent toasts.
486
+ * **Alerts (alert or status):** Warning and negative alerts interrupt the screen reader. Info and positive alerts announce politely.
487
+ * **Banners (role):** A [Banner](/docs/components/banner) renders no live region. Add `role="status"` or `role="alert"` only if it renders after page load.
488
+ * **Status Changes:** A change from Pending to Confirmed is not announced. If the reader started the transaction in this session, use a [Toast](/docs/components/toast).
489
+
490
+ ## Related
491
+
492
+ [Badge](/docs/components/badge)
493
+
494
+ Use for record status.
495
+
496
+ [Alert](/docs/components/alert)
497
+
498
+ Use for section messages.
499
+
500
+ [Banner](/docs/components/banner)
501
+
502
+ Use for product-wide messages.
503
+
504
+ [Toast](/docs/components/toast)
505
+
506
+ Use for confirmations.
507
+
508
+ [SecretValue](/docs/components/secret-value)
509
+
510
+ Use for masked secrets.
511
+
512
+ [Loading](/docs/patterns/loading)
513
+
514
+ Covers Pending transactions.
515
+
516
+ [Blockchain Values](/docs/patterns/blockchain-values)
517
+
518
+ Covers amounts and addresses.