@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,516 @@
1
+ # ChoiceGroup
2
+
3
+ A segmented control for a few mutually exclusive options.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/ChoiceGroup.tsx)
6
+
7
+ Figma: [Base - Segment Item](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=3075-548) (`ChoiceGroup.Item`), [Controls/Segmented Control Item Small](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-5484) (`ChoiceGroup.Item`), [Segmented Control](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=3075-535) (`ChoiceGroup.Root`)
8
+
9
+ ## Overview
10
+
11
+ A single-select control with radio semantics. One option is always selected.
12
+
13
+ ## Examples
14
+
15
+ ### Basic
16
+
17
+ ```tsx
18
+ import { ChoiceGroup } from '@tempoxyz/ds'
19
+
20
+ export function Demo() {
21
+ return (
22
+ <ChoiceGroup.Root aria-label="Amount" defaultValue="50">
23
+ <ChoiceGroup.Item value="20">$20</ChoiceGroup.Item>
24
+ <ChoiceGroup.Item value="50">$50</ChoiceGroup.Item>
25
+ <ChoiceGroup.Item value="100">$100</ChoiceGroup.Item>
26
+ </ChoiceGroup.Root>
27
+ )
28
+ }
29
+ ```
30
+
31
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ChoiceGroup/Basic.tsx)
32
+
33
+ ### Size
34
+
35
+ Set `size` to `small`, `medium` (default), or `large`.
36
+
37
+ ```tsx
38
+ import { ChoiceGroup, style } from '@tempoxyz/ds'
39
+
40
+ export function Demo() {
41
+ return (
42
+ <div {...styles.stack()}>
43
+ {(['small', 'medium', 'large'] as const).map((size) => (
44
+ <ChoiceGroup.Root aria-label={`Amount ${size}`} defaultValue="50" key={size} size={size}>
45
+ <ChoiceGroup.Item value="20">$20</ChoiceGroup.Item>
46
+ <ChoiceGroup.Item value="50">$50</ChoiceGroup.Item>
47
+ <ChoiceGroup.Item value="100">$100</ChoiceGroup.Item>
48
+ </ChoiceGroup.Root>
49
+ ))}
50
+ </div>
51
+ )
52
+ }
53
+
54
+ namespace styles {
55
+ export const stack = style({
56
+ alignItems: 'flex-start',
57
+ display: 'flex',
58
+ flexDirection: 'column',
59
+ gap: '16',
60
+ })
61
+ }
62
+ ```
63
+
64
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ChoiceGroup/Size.tsx)
65
+
66
+ ### Variant
67
+
68
+ Set `variant` to `default` or `chips`. `chips` renders a horizontally scrolling row of chips, with an optional `ChoiceGroup.ItemIcon`.
69
+
70
+ ```tsx
71
+ import { ChoiceGroup, style } from '@tempoxyz/ds'
72
+ import { Coins, Ethereum, Globe } from '@tempoxyz/ds/icons'
73
+
74
+ const networks = [
75
+ { icon: <Coins />, label: 'Tempo' },
76
+ { icon: <Ethereum />, label: 'Ethereum' },
77
+ { icon: <Globe />, label: 'Base' },
78
+ { icon: <Globe />, label: 'Arbitrum' },
79
+ { icon: <Globe />, label: 'Optimism' },
80
+ ]
81
+
82
+ export function Demo() {
83
+ return (
84
+ <div {...styles.stack()}>
85
+ {(['small', 'medium', 'large'] as const).map((size) => (
86
+ <ChoiceGroup.Root
87
+ aria-label={`Network ${size}`}
88
+ defaultValue="Tempo"
89
+ key={size}
90
+ size={size}
91
+ variant="chips"
92
+ >
93
+ {networks.map((network) => (
94
+ <ChoiceGroup.Item key={network.label} value={network.label}>
95
+ <ChoiceGroup.ItemIcon>{network.icon}</ChoiceGroup.ItemIcon>
96
+ {network.label}
97
+ </ChoiceGroup.Item>
98
+ ))}
99
+ </ChoiceGroup.Root>
100
+ ))}
101
+ </div>
102
+ )
103
+ }
104
+
105
+ namespace styles {
106
+ export const stack = style({
107
+ alignItems: 'flex-start',
108
+ display: 'flex',
109
+ flexDirection: 'column',
110
+ gap: '16',
111
+ })
112
+ }
113
+ ```
114
+
115
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ChoiceGroup/Variant.tsx)
116
+
117
+ ### Field
118
+
119
+ Wrap the group in a `Field.Root`. The `Field.Label` names the group, and a `Field.Description` adds a hint below it.
120
+
121
+ ```tsx
122
+ import { ChoiceGroup, Field, style } from '@tempoxyz/ds'
123
+ import { Coins, Ethereum, Globe } from '@tempoxyz/ds/icons'
124
+
125
+ const networks = [
126
+ { icon: <Coins />, label: 'Tempo' },
127
+ { icon: <Ethereum />, label: 'Ethereum' },
128
+ { icon: <Globe />, label: 'Base' },
129
+ ]
130
+
131
+ export function Demo() {
132
+ return (
133
+ <div {...styles.stack()}>
134
+ <Field.Root>
135
+ <Field.Label>Amount</Field.Label>
136
+ <ChoiceGroup.Root defaultValue="50">
137
+ <ChoiceGroup.Item value="20">$20</ChoiceGroup.Item>
138
+ <ChoiceGroup.Item value="50">$50</ChoiceGroup.Item>
139
+ <ChoiceGroup.Item value="100">$100</ChoiceGroup.Item>
140
+ </ChoiceGroup.Root>
141
+ <Field.Description>Charged to your saved card.</Field.Description>
142
+ </Field.Root>
143
+ <Field.Root>
144
+ <Field.Label>Network</Field.Label>
145
+ <ChoiceGroup.Root defaultValue="Tempo" variant="chips">
146
+ {networks.map((network) => (
147
+ <ChoiceGroup.Item key={network.label} value={network.label}>
148
+ <ChoiceGroup.ItemIcon>{network.icon}</ChoiceGroup.ItemIcon>
149
+ {network.label}
150
+ </ChoiceGroup.Item>
151
+ ))}
152
+ </ChoiceGroup.Root>
153
+ </Field.Root>
154
+ </div>
155
+ )
156
+ }
157
+
158
+ namespace styles {
159
+ export const stack = style({
160
+ display: 'flex',
161
+ flexDirection: 'column',
162
+ gap: '24',
163
+ maxWidth: '320px !custom',
164
+ })
165
+ }
166
+ ```
167
+
168
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ChoiceGroup/Field.tsx)
169
+
170
+ ### Disabled
171
+
172
+ Set `disabled` on a `ChoiceGroup.Item` to make one option unavailable.
173
+
174
+ ```tsx
175
+ import { ChoiceGroup } from '@tempoxyz/ds'
176
+
177
+ export function Demo() {
178
+ return (
179
+ <ChoiceGroup.Root aria-label="Amount" defaultValue="50">
180
+ <ChoiceGroup.Item value="20">$20</ChoiceGroup.Item>
181
+ <ChoiceGroup.Item value="50">$50</ChoiceGroup.Item>
182
+ <ChoiceGroup.Item value="100">$100</ChoiceGroup.Item>
183
+ <ChoiceGroup.Item disabled value="other">
184
+ Other
185
+ </ChoiceGroup.Item>
186
+ </ChoiceGroup.Root>
187
+ )
188
+ }
189
+ ```
190
+
191
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ChoiceGroup/Disabled.tsx)
192
+
193
+ ## Anatomy
194
+
195
+ Import the component and assemble its parts.
196
+
197
+ ```tsx
198
+ import { ChoiceGroup } from '@tempoxyz/ds'
199
+
200
+ <ChoiceGroup.Root>
201
+ <ChoiceGroup.Item>
202
+ <ChoiceGroup.ItemIcon />
203
+ </ChoiceGroup.Item>
204
+ </ChoiceGroup.Root>
205
+ ```
206
+
207
+ ## Guidelines
208
+
209
+ ### When to Use
210
+
211
+ * Switch between two to four short options that change a view, such as the 1H, 24H, 7D, and 30D range on a TPS chart.
212
+ * Pick a preset value, such as $20, $50, or $100 on Add funds.
213
+ * Filter by one option from a longer set with `variant="chips"`, such as the network for a deposit.
214
+
215
+ ### When Not to Use
216
+
217
+ * If options need longer labels or are submitted with a form, use [RadioGroup](/docs/components/radio-group).
218
+ * Use [Select](/docs/components/select) for many options, or when space is limited.
219
+ * Use [Tabs](/docs/components/tabs) to switch between panels, such as Overview, Activity, and Settings.
220
+ * If each option needs an icon and a description, use [Choicebox](/docs/components/choicebox).
221
+ * Use [Switch](/docs/components/switch) for an on or off setting, not On and Off segments.
222
+ * Use [Button](/docs/components/button) for actions such as Send, Receive, and Swap.
223
+
224
+ ### Keep Options Few and Short
225
+
226
+ Use two to four options of one or two words each, at similar lengths. Items never wrap.
227
+
228
+ **Do:** Use short, parallel labels that fit side by side.
229
+
230
+ ```tsx
231
+ /**
232
+ * Do example for "Keep Options Few and Short" on the ChoiceGroup page.
233
+ * Use short, parallel labels that fit side by side.
234
+ * @module
235
+ */
236
+ import { ChoiceGroup } from '@tempoxyz/ds'
237
+
238
+ /** Renders the static preview, which the guideline card shows inert. */
239
+ export function Demo() {
240
+ return (
241
+ <ChoiceGroup.Root aria-label="Time range" defaultValue="24h">
242
+ <ChoiceGroup.Item value="1h">1H</ChoiceGroup.Item>
243
+ <ChoiceGroup.Item value="24h">24H</ChoiceGroup.Item>
244
+ <ChoiceGroup.Item value="7d">7D</ChoiceGroup.Item>
245
+ <ChoiceGroup.Item value="30d">30D</ChoiceGroup.Item>
246
+ </ChoiceGroup.Root>
247
+ )
248
+ }
249
+ ```
250
+
251
+ **Don't:** Use phrases that overflow the control.
252
+
253
+ ```tsx
254
+ /**
255
+ * Don't example for "Keep Options Few and Short" on the ChoiceGroup page.
256
+ * Don't use phrases that overflow the control.
257
+ * @module
258
+ */
259
+ import { ChoiceGroup } from '@tempoxyz/ds'
260
+
261
+ /** Renders the static preview, which the guideline card shows inert. */
262
+ export function Demo() {
263
+ return (
264
+ <ChoiceGroup.Root aria-label="Time range" defaultValue="24h">
265
+ <ChoiceGroup.Item value="1h">Last hour</ChoiceGroup.Item>
266
+ <ChoiceGroup.Item value="24h">Last 24 hours</ChoiceGroup.Item>
267
+ <ChoiceGroup.Item value="7d">Last 7 days</ChoiceGroup.Item>
268
+ <ChoiceGroup.Item value="30d">Last 30 days</ChoiceGroup.Item>
269
+ </ChoiceGroup.Root>
270
+ )
271
+ }
272
+ ```
273
+
274
+ ### Always Keep One Option Selected
275
+
276
+ The selection can't be cleared.
277
+
278
+ **Do:** On first render, set `defaultValue`, or `value` with `onValueChange`, to the current mode.
279
+
280
+ ```tsx
281
+ /**
282
+ * Do example for "Always Keep One Option Selected" on the ChoiceGroup page.
283
+ * On first render, set `defaultValue`, or `value` with `onValueChange`, to the current mode.
284
+ * @module
285
+ */
286
+ import { ChoiceGroup } from '@tempoxyz/ds'
287
+
288
+ /** Renders the static preview, which the guideline card shows inert. */
289
+ export function Demo() {
290
+ return (
291
+ <ChoiceGroup.Root aria-label="Amount" defaultValue="50">
292
+ <ChoiceGroup.Item value="20">$20</ChoiceGroup.Item>
293
+ <ChoiceGroup.Item value="50">$50</ChoiceGroup.Item>
294
+ <ChoiceGroup.Item value="100">$100</ChoiceGroup.Item>
295
+ </ChoiceGroup.Root>
296
+ )
297
+ }
298
+ ```
299
+
300
+ **Don't:** Render the group with no option selected.
301
+
302
+ ```tsx
303
+ /**
304
+ * Don't example for "Always Keep One Option Selected" on the ChoiceGroup page.
305
+ * Don't render the group with no option selected.
306
+ * @module
307
+ */
308
+ import { ChoiceGroup } from '@tempoxyz/ds'
309
+
310
+ /** Renders the static preview, which the guideline card shows inert. */
311
+ export function Demo() {
312
+ return (
313
+ <ChoiceGroup.Root aria-label="Amount">
314
+ <ChoiceGroup.Item value="20">$20</ChoiceGroup.Item>
315
+ <ChoiceGroup.Item value="50">$50</ChoiceGroup.Item>
316
+ <ChoiceGroup.Item value="100">$100</ChoiceGroup.Item>
317
+ </ChoiceGroup.Root>
318
+ )
319
+ }
320
+ ```
321
+
322
+ ### Apply the Choice Immediately
323
+
324
+ If the choice waits for a form submit, use [RadioGroup](/docs/components/radio-group).
325
+
326
+ **Do:** Update the view when the selection changes, such as redrawing the chart for 7D.
327
+
328
+ ```tsx
329
+ /**
330
+ * Do example for "Apply the Choice Immediately" on the ChoiceGroup page.
331
+ * Update the view when the selection changes, such as redrawing the chart for 7D.
332
+ * @module
333
+ */
334
+ import { ChoiceGroup } from '@tempoxyz/ds'
335
+
336
+ /** Renders the static preview, which the guideline card shows inert. */
337
+ export function Demo() {
338
+ return (
339
+ <ChoiceGroup.Root aria-label="Time range" defaultValue="24h" size="small">
340
+ <ChoiceGroup.Item value="1h">1H</ChoiceGroup.Item>
341
+ <ChoiceGroup.Item value="24h">24H</ChoiceGroup.Item>
342
+ <ChoiceGroup.Item value="7d">7D</ChoiceGroup.Item>
343
+ <ChoiceGroup.Item value="30d">30D</ChoiceGroup.Item>
344
+ </ChoiceGroup.Root>
345
+ )
346
+ }
347
+ ```
348
+
349
+ **Don't:** Add an Apply button.
350
+
351
+ ```tsx
352
+ /** Don't example for "Apply the Choice Immediately" on the ChoiceGroup page. Don't add an Apply button. @module */
353
+ import { Button, ChoiceGroup, style } from '@tempoxyz/ds'
354
+
355
+ /** Renders the static preview, which the guideline card shows inert. */
356
+ export function Demo() {
357
+ return (
358
+ <div {...styles.row()}>
359
+ <ChoiceGroup.Root aria-label="Time range" defaultValue="24h" size="small">
360
+ <ChoiceGroup.Item value="1h">1H</ChoiceGroup.Item>
361
+ <ChoiceGroup.Item value="24h">24H</ChoiceGroup.Item>
362
+ <ChoiceGroup.Item value="7d">7D</ChoiceGroup.Item>
363
+ <ChoiceGroup.Item value="30d">30D</ChoiceGroup.Item>
364
+ </ChoiceGroup.Root>
365
+ <Button size="small" variant="secondary">
366
+ Apply
367
+ </Button>
368
+ </div>
369
+ )
370
+ }
371
+
372
+ namespace styles {
373
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '8' })
374
+ }
375
+ ```
376
+
377
+ ### Choose a Variant by Option Count
378
+
379
+ * **Few Short Options (default):** Two to four options in one track, marked by a sliding pill.
380
+ * **Longer Filter Sets (chips):** A scrolling row of chips for options that outgrow the width, such as networks for a deposit.
381
+
382
+ ### Match the Height of Nearby Controls
383
+
384
+ `small`, `medium`, and `large` tracks are 32, 48, and 56px tall. A `medium` track fills its row and gives each item an equal width, as tall as [TextInput](/docs/components/text-input).
385
+
386
+ **Do:** Use `small` in a dashboard toolbar beside a small [Select](/docs/components/select).
387
+
388
+ ```tsx
389
+ /**
390
+ * Do example for "Match the Height of Nearby Controls" on the ChoiceGroup page.
391
+ * Use `small` in a dashboard toolbar beside a small Select.
392
+ * @module
393
+ */
394
+ import { ChoiceGroup, Select, style } from '@tempoxyz/ds'
395
+
396
+ const items = { usdc: 'USDC', usdt: 'USDT' }
397
+
398
+ /** Renders the static preview, which the guideline card shows inert. */
399
+ export function Demo() {
400
+ return (
401
+ <div {...styles.toolbar()}>
402
+ <ChoiceGroup.Root aria-label="Time range" defaultValue="24h" size="small">
403
+ <ChoiceGroup.Item value="1h">1H</ChoiceGroup.Item>
404
+ <ChoiceGroup.Item value="24h">24H</ChoiceGroup.Item>
405
+ <ChoiceGroup.Item value="7d">7D</ChoiceGroup.Item>
406
+ </ChoiceGroup.Root>
407
+ <Select.Root aria-label="Asset" defaultValue="usdc" items={items}>
408
+ <Select.Trigger {...styles.select()}>
409
+ <Select.Value />
410
+ <Select.Icon />
411
+ </Select.Trigger>
412
+ </Select.Root>
413
+ </div>
414
+ )
415
+ }
416
+
417
+ namespace styles {
418
+ export const toolbar = style({ alignItems: 'center', display: 'flex', gap: '8' })
419
+
420
+ export const select = style({ width: '7rem !custom' })
421
+ }
422
+ ```
423
+
424
+ **Don't:** Mix sizes in one toolbar.
425
+
426
+ ```tsx
427
+ /**
428
+ * Don't example for "Match the Height of Nearby Controls" on the ChoiceGroup page.
429
+ * Don't mix sizes in one toolbar.
430
+ * @module
431
+ */
432
+ import { ChoiceGroup, Select, style } from '@tempoxyz/ds'
433
+
434
+ const items = { usdc: 'USDC', usdt: 'USDT' }
435
+
436
+ /** Renders the static preview, which the guideline card shows inert. */
437
+ export function Demo() {
438
+ return (
439
+ <div {...styles.toolbar()}>
440
+ <ChoiceGroup.Root aria-label="Time range" defaultValue="24h" size="large">
441
+ <ChoiceGroup.Item value="1h">1H</ChoiceGroup.Item>
442
+ <ChoiceGroup.Item value="24h">24H</ChoiceGroup.Item>
443
+ <ChoiceGroup.Item value="7d">7D</ChoiceGroup.Item>
444
+ </ChoiceGroup.Root>
445
+ <Select.Root aria-label="Asset" defaultValue="usdc" items={items}>
446
+ <Select.Trigger {...styles.select()}>
447
+ <Select.Value />
448
+ <Select.Icon />
449
+ </Select.Trigger>
450
+ </Select.Root>
451
+ </div>
452
+ )
453
+ }
454
+
455
+ namespace styles {
456
+ export const toolbar = style({ alignItems: 'center', display: 'flex', gap: '8' })
457
+
458
+ export const select = style({ width: '7rem !custom' })
459
+ }
460
+ ```
461
+
462
+ ## Content
463
+
464
+ * Write labels as compact units, such as 1H and 7D, or as words. Use one style across all options, and don't mix 1 hour with 7D, or Ethereum with ETH.
465
+ * Use numerals for numbers and amounts, such as $20 and 30D.
466
+
467
+ ## Accessibility
468
+
469
+ Follows the [WAI-ARIA radio group pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/).
470
+
471
+ ### Semantics
472
+
473
+ * **ChoiceGroup.Root (radiogroup):** Groups the items as one set of choices.
474
+ * **ChoiceGroup.Item (radio):** Named by its text. A hidden native radio beside it submits the value.
475
+ * **Decoration (aria-hidden):** The sliding pill and item icons are hidden from screen readers.
476
+ * **Selected (aria-checked):** The selected item sits on a pill or tinted chip, and its text darkens.
477
+ * **Disabled Item (disabled):** Makes the option unavailable and dims it to 32% opacity.
478
+ * **Target Size (28 to 48px):** Small items sit close to the WCAG 2.2 minimum. Avoid them for primary controls.
479
+
480
+ ### Keyboard
481
+
482
+ * **Move into the Group (Tab):** Moves focus onto the checked item. The group is one tab stop.
483
+ * **Move out of the Group (Shift+Tab):** Moves focus out of the group.
484
+ * **Select the Next Item (Right Arrow or Down Arrow):** Moves focus to the next item and selects it, wrapping at the end.
485
+ * **Select the Previous Item (Left Arrow or Up Arrow):** Moves focus to the previous item and selects it, wrapping at the start.
486
+
487
+ ### Motion
488
+
489
+ Under `prefers-reduced-motion: reduce`, the pill moves without sliding and items don't scale when pressed.
490
+
491
+ ### Your Responsibilities
492
+
493
+ * **Name the Group (aria-labelledby):** Use a `Field.Label` in a `Field.Root`, `aria-label`, or a visible question such as "Amount".
494
+ * **Give Every Item Text:** Item icons are hidden, so an icon-only item has no accessible name.
495
+
496
+ ## Related
497
+
498
+ [RadioGroup](/docs/components/radio-group)
499
+
500
+ Use for one choice in a form.
501
+
502
+ [Tabs](/docs/components/tabs)
503
+
504
+ Use for switching between panels.
505
+
506
+ [Select](/docs/components/select)
507
+
508
+ Use for longer lists.
509
+
510
+ [Choicebox](/docs/components/choicebox)
511
+
512
+ Use for options with descriptions.
513
+
514
+ [Dashboards](/docs/patterns/dashboards)
515
+
516
+ Covers filters above charts.