@tempoxyz/ds 0.3.10 → 0.3.13

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 (210) hide show
  1. package/README.md +7 -6
  2. package/dist/docs/AGENTS.md +12 -0
  3. package/dist/docs/index.md +145 -0
  4. package/dist/docs/marketing/introduction/getting-started.md +241 -0
  5. package/dist/docs/product/components/accordion.md +489 -0
  6. package/dist/docs/product/components/address-card.md +147 -0
  7. package/dist/docs/product/components/agent-logo.md +194 -0
  8. package/dist/docs/product/components/alert-dialog.md +631 -0
  9. package/dist/docs/product/components/alert.md +448 -0
  10. package/dist/docs/product/components/amount-input.md +305 -0
  11. package/dist/docs/product/components/amount.md +794 -0
  12. package/dist/docs/product/components/app-shell.md +559 -0
  13. package/dist/docs/product/components/asset-chip.md +294 -0
  14. package/dist/docs/product/components/autocomplete.md +620 -0
  15. package/dist/docs/product/components/avatar.md +321 -0
  16. package/dist/docs/product/components/badge.md +339 -0
  17. package/dist/docs/product/components/badged-logo.md +116 -0
  18. package/dist/docs/product/components/banner.md +379 -0
  19. package/dist/docs/product/components/bar-chart.md +208 -0
  20. package/dist/docs/product/components/breadcrumbs.md +380 -0
  21. package/dist/docs/product/components/button-group.md +286 -0
  22. package/dist/docs/product/components/button.md +650 -0
  23. package/dist/docs/product/components/calendar.md +375 -0
  24. package/dist/docs/product/components/callout.md +96 -0
  25. package/dist/docs/product/components/checkbox-group.md +521 -0
  26. package/dist/docs/product/components/checkbox.md +467 -0
  27. package/dist/docs/product/components/choice-group.md +516 -0
  28. package/dist/docs/product/components/choicebox.md +641 -0
  29. package/dist/docs/product/components/code.md +100 -0
  30. package/dist/docs/product/components/combobox.md +939 -0
  31. package/dist/docs/product/components/container.md +257 -0
  32. package/dist/docs/product/components/copy-button.md +642 -0
  33. package/dist/docs/product/components/date-picker.md +514 -0
  34. package/dist/docs/product/components/dialog.md +1332 -0
  35. package/dist/docs/product/components/drawer.md +966 -0
  36. package/dist/docs/product/components/empty.md +340 -0
  37. package/dist/docs/product/components/field.md +570 -0
  38. package/dist/docs/product/components/fieldset.md +398 -0
  39. package/dist/docs/product/components/frame.md +434 -0
  40. package/dist/docs/product/components/gauge.md +299 -0
  41. package/dist/docs/product/components/get-started-visual.md +117 -0
  42. package/dist/docs/product/components/grid.md +288 -0
  43. package/dist/docs/product/components/hero-visual.md +155 -0
  44. package/dist/docs/product/components/hex.md +487 -0
  45. package/dist/docs/product/components/icon-tile.md +292 -0
  46. package/dist/docs/product/components/identicon.md +371 -0
  47. package/dist/docs/product/components/inline.md +233 -0
  48. package/dist/docs/product/components/inset.md +225 -0
  49. package/dist/docs/product/components/kbd.md +423 -0
  50. package/dist/docs/product/components/list-group.md +981 -0
  51. package/dist/docs/product/components/loading-dots.md +237 -0
  52. package/dist/docs/product/components/menu.md +934 -0
  53. package/dist/docs/product/components/native-select.md +204 -0
  54. package/dist/docs/product/components/network-logo.md +248 -0
  55. package/dist/docs/product/components/number-field.md +543 -0
  56. package/dist/docs/product/components/otp-field.md +616 -0
  57. package/dist/docs/product/components/pagination.md +516 -0
  58. package/dist/docs/product/components/popover.md +544 -0
  59. package/dist/docs/product/components/progress.md +388 -0
  60. package/dist/docs/product/components/qr.md +314 -0
  61. package/dist/docs/product/components/radio-group.md +528 -0
  62. package/dist/docs/product/components/secret-value.md +406 -0
  63. package/dist/docs/product/components/select.md +751 -0
  64. package/dist/docs/product/components/separator.md +379 -0
  65. package/dist/docs/product/components/sidebar-menu.md +922 -0
  66. package/dist/docs/product/components/skeleton.md +517 -0
  67. package/dist/docs/product/components/slider.md +539 -0
  68. package/dist/docs/product/components/snippet.md +424 -0
  69. package/dist/docs/product/components/spinner.md +216 -0
  70. package/dist/docs/product/components/split-bar.md +139 -0
  71. package/dist/docs/product/components/split-button.md +464 -0
  72. package/dist/docs/product/components/stack.md +299 -0
  73. package/dist/docs/product/components/status-chip.md +226 -0
  74. package/dist/docs/product/components/status-indicator.md +119 -0
  75. package/dist/docs/product/components/status-row.md +174 -0
  76. package/dist/docs/product/components/stepper.md +451 -0
  77. package/dist/docs/product/components/success-hero.md +157 -0
  78. package/dist/docs/product/components/surface.md +639 -0
  79. package/dist/docs/product/components/switch.md +472 -0
  80. package/dist/docs/product/components/table.md +967 -0
  81. package/dist/docs/product/components/tabs.md +627 -0
  82. package/dist/docs/product/components/tempo-logo.md +185 -0
  83. package/dist/docs/product/components/text-input.md +624 -0
  84. package/dist/docs/product/components/textarea.md +352 -0
  85. package/dist/docs/product/components/toast.md +535 -0
  86. package/dist/docs/product/components/token-logo.md +371 -0
  87. package/dist/docs/product/components/token.md +247 -0
  88. package/dist/docs/product/components/tooltip.md +490 -0
  89. package/dist/docs/product/components/verification-code.md +116 -0
  90. package/dist/docs/product/components/visual.md +249 -0
  91. package/dist/docs/product/components.md +203 -0
  92. package/dist/docs/product/foundations/accessibility.md +377 -0
  93. package/dist/docs/product/foundations/agents.md +150 -0
  94. package/dist/docs/product/foundations/color.md +522 -0
  95. package/dist/docs/product/foundations/content/tone.md +194 -0
  96. package/dist/docs/product/foundations/content/voice.md +194 -0
  97. package/dist/docs/product/foundations/content/writing-style.md +406 -0
  98. package/dist/docs/product/foundations/iconography.md +282 -0
  99. package/dist/docs/product/foundations/intent.md +360 -0
  100. package/dist/docs/product/foundations/layout.md +508 -0
  101. package/dist/docs/product/foundations/linter.md +496 -0
  102. package/dist/docs/product/foundations/motion.md +151 -0
  103. package/dist/docs/product/foundations/radius-and-padding.md +86 -0
  104. package/dist/docs/product/foundations/typography.md +266 -0
  105. package/dist/docs/product/introduction/faq.md +133 -0
  106. package/dist/docs/product/introduction/getting-started.md +377 -0
  107. package/dist/docs/product/patterns/blockchain-values.md +709 -0
  108. package/dist/docs/product/patterns/dashboards.md +638 -0
  109. package/dist/docs/product/patterns/destructive-actions.md +626 -0
  110. package/dist/docs/product/patterns/empty-states.md +612 -0
  111. package/dist/docs/product/patterns/errors-and-validation.md +808 -0
  112. package/dist/docs/product/patterns/feedback-and-status.md +518 -0
  113. package/dist/docs/product/patterns/forms.md +679 -0
  114. package/dist/docs/product/patterns/loading.md +630 -0
  115. package/dist/docs/product/patterns/navigation.md +397 -0
  116. package/dist/docs/product/patterns/payments.md +765 -0
  117. package/dist/docs/product/patterns/responsive-layout.md +997 -0
  118. package/dist/docs/product/patterns/tables-and-lists.md +964 -0
  119. package/dist/docs/product/products/tempo-console.md +671 -0
  120. package/dist/docs/product/products/tempo-performance.md +437 -0
  121. package/dist/docs/product/products/tempo-wallet.md +438 -0
  122. package/dist/marketing/index.d.ts +4 -0
  123. package/dist/marketing/index.d.ts.map +1 -0
  124. package/dist/marketing/index.js +4 -0
  125. package/dist/marketing/index.js.map +1 -0
  126. package/dist/marketing/index.js.zyzz.json +1 -0
  127. package/dist/marketing/vars.d.ts +907 -0
  128. package/dist/marketing/vars.d.ts.map +1 -0
  129. package/dist/marketing/vars.js +15 -0
  130. package/dist/marketing/vars.js.map +1 -0
  131. package/dist/marketing/vars.js.zyzz.json +1 -0
  132. package/dist/marketing/zyzz.config.d.ts +4512 -0
  133. package/dist/marketing/zyzz.config.d.ts.map +1 -0
  134. package/dist/marketing/zyzz.config.js +63 -0
  135. package/dist/marketing/zyzz.config.js.map +1 -0
  136. package/dist/marketing/zyzz.config.js.zyzz.json +1 -0
  137. package/dist/oxlint/index.d.ts +12 -1
  138. package/dist/oxlint/index.d.ts.map +1 -1
  139. package/dist/oxlint/index.js +39 -1
  140. package/dist/oxlint/index.js.map +1 -1
  141. package/dist/oxlint/internal/Docs.d.ts +9 -0
  142. package/dist/oxlint/internal/Docs.d.ts.map +1 -0
  143. package/dist/oxlint/internal/Docs.js +15 -0
  144. package/dist/oxlint/internal/Docs.js.map +1 -0
  145. package/dist/oxlint/internal/Imports.d.ts +1 -1
  146. package/dist/oxlint/internal/Imports.d.ts.map +1 -1
  147. package/dist/oxlint/internal/Imports.js +2 -0
  148. package/dist/oxlint/internal/Imports.js.map +1 -1
  149. package/dist/oxlint/internal/Styles.d.ts +40 -0
  150. package/dist/oxlint/internal/Styles.d.ts.map +1 -0
  151. package/dist/oxlint/internal/Styles.js +194 -0
  152. package/dist/oxlint/internal/Styles.js.map +1 -0
  153. package/dist/oxlint/internal/Tokens.d.ts +16 -0
  154. package/dist/oxlint/internal/Tokens.d.ts.map +1 -0
  155. package/dist/oxlint/internal/Tokens.js +39 -0
  156. package/dist/oxlint/internal/Tokens.js.map +1 -0
  157. package/dist/oxlint/rules/NoCrossSurface.d.ts +2 -2
  158. package/dist/oxlint/rules/NoCrossSurface.js +3 -3
  159. package/dist/oxlint/rules/NoCrossSurface.js.map +1 -1
  160. package/dist/oxlint/rules/NoCustomValues.d.ts +11 -0
  161. package/dist/oxlint/rules/NoCustomValues.d.ts.map +1 -0
  162. package/dist/oxlint/rules/NoCustomValues.js +150 -0
  163. package/dist/oxlint/rules/NoCustomValues.js.map +1 -0
  164. package/dist/oxlint/rules/NoSingleKeyShortcuts.d.ts +11 -0
  165. package/dist/oxlint/rules/NoSingleKeyShortcuts.d.ts.map +1 -0
  166. package/dist/oxlint/rules/NoSingleKeyShortcuts.js +158 -0
  167. package/dist/oxlint/rules/NoSingleKeyShortcuts.js.map +1 -0
  168. package/dist/oxlint/rules/PreferComponent.d.ts +3 -2
  169. package/dist/oxlint/rules/PreferComponent.d.ts.map +1 -1
  170. package/dist/oxlint/rules/PreferComponent.js +11 -4
  171. package/dist/oxlint/rules/PreferComponent.js.map +1 -1
  172. package/dist/oxlint/rules/PreferLayout.d.ts +9 -0
  173. package/dist/oxlint/rules/PreferLayout.d.ts.map +1 -0
  174. package/dist/oxlint/rules/PreferLayout.js +90 -0
  175. package/dist/oxlint/rules/PreferLayout.js.map +1 -0
  176. package/dist/oxlint/rules/PreferProgress.d.ts +9 -0
  177. package/dist/oxlint/rules/PreferProgress.d.ts.map +1 -0
  178. package/dist/oxlint/rules/PreferProgress.js +43 -0
  179. package/dist/oxlint/rules/PreferProgress.js.map +1 -0
  180. package/dist/oxlint/rules/PreferSurface.d.ts +9 -0
  181. package/dist/oxlint/rules/PreferSurface.d.ts.map +1 -0
  182. package/dist/oxlint/rules/PreferSurface.js +55 -0
  183. package/dist/oxlint/rules/PreferSurface.js.map +1 -0
  184. package/dist/oxlint/rules/RequireAccessibleName.d.ts.map +1 -1
  185. package/dist/oxlint/rules/RequireAccessibleName.js +3 -1
  186. package/dist/oxlint/rules/RequireAccessibleName.js.map +1 -1
  187. package/dist/oxlint/rules/RequireScrollRegion.d.ts +11 -0
  188. package/dist/oxlint/rules/RequireScrollRegion.d.ts.map +1 -0
  189. package/dist/oxlint/rules/RequireScrollRegion.js +71 -0
  190. package/dist/oxlint/rules/RequireScrollRegion.js.map +1 -0
  191. package/dist/web/icons/index.js.zyzz.json +1 -0
  192. package/package.json +6 -1
  193. package/src/marketing/README.md +21 -0
  194. package/src/marketing/index.ts +3 -0
  195. package/src/marketing/vars.ts +751 -0
  196. package/src/marketing/zyzz.config.ts +376 -0
  197. package/src/oxlint/index.ts +40 -1
  198. package/src/oxlint/internal/Docs.ts +18 -0
  199. package/src/oxlint/internal/Imports.ts +2 -1
  200. package/src/oxlint/internal/Styles.ts +240 -0
  201. package/src/oxlint/internal/Tokens.ts +43 -0
  202. package/src/oxlint/rules/NoCrossSurface.ts +3 -3
  203. package/src/oxlint/rules/NoCustomValues.ts +170 -0
  204. package/src/oxlint/rules/NoSingleKeyShortcuts.ts +190 -0
  205. package/src/oxlint/rules/PreferComponent.ts +11 -4
  206. package/src/oxlint/rules/PreferLayout.ts +96 -0
  207. package/src/oxlint/rules/PreferProgress.ts +49 -0
  208. package/src/oxlint/rules/PreferSurface.ts +70 -0
  209. package/src/oxlint/rules/RequireAccessibleName.ts +3 -1
  210. package/src/oxlint/rules/RequireScrollRegion.ts +92 -0
@@ -0,0 +1,380 @@
1
+ # Breadcrumbs
2
+
3
+ Shows where the current page sits in the site hierarchy.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Breadcrumbs.tsx)
6
+
7
+ ## Overview
8
+
9
+ A trail of links from the current page back to its ancestors.
10
+
11
+ ## Examples
12
+
13
+ ### Basic
14
+
15
+ ```tsx
16
+ import { Breadcrumbs } from '@tempoxyz/ds'
17
+
18
+ export function Demo() {
19
+ return (
20
+ <Breadcrumbs>
21
+ <Breadcrumbs.Item href="#">Home</Breadcrumbs.Item>
22
+ <Breadcrumbs.Item href="#">Payments</Breadcrumbs.Item>
23
+ <Breadcrumbs.Item current>Invoices</Breadcrumbs.Item>
24
+ </Breadcrumbs>
25
+ )
26
+ }
27
+ ```
28
+
29
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Breadcrumbs/Basic.tsx)
30
+
31
+ ### Separator
32
+
33
+ Set `separator` to any node to place between items. It defaults to a right chevron.
34
+
35
+ ```tsx
36
+ import { Breadcrumbs } from '@tempoxyz/ds'
37
+
38
+ export function Demo() {
39
+ return (
40
+ <Breadcrumbs separator="/">
41
+ <Breadcrumbs.Item href="#">Docs</Breadcrumbs.Item>
42
+ <Breadcrumbs.Item current>Guides</Breadcrumbs.Item>
43
+ </Breadcrumbs>
44
+ )
45
+ }
46
+ ```
47
+
48
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Breadcrumbs/Separator.tsx)
49
+
50
+ ## Anatomy
51
+
52
+ Import the component and assemble its parts.
53
+
54
+ ```tsx
55
+ import { Breadcrumbs } from '@tempoxyz/ds'
56
+
57
+ <Breadcrumbs>
58
+ <Breadcrumbs.Item />
59
+ </Breadcrumbs>
60
+ ```
61
+
62
+ ## Guidelines
63
+
64
+ ### When to Use
65
+
66
+ * Mark pages three or more levels deep, such as a webhook endpoint inside a project in Tempo Console.
67
+ * Mark detail pages that people reach from a list and return to often, such as one API key under Checkout › API keys.
68
+
69
+ ### When Not to Use
70
+
71
+ * Use [SidebarMenu](sidebar-menu.md) to move between top-level sections.
72
+ * Use [Stepper](stepper.md) to show progress through a flow, such as Send payment.
73
+ * Use [Tabs](tabs.md) to switch between views of the same page.
74
+ * Use `Button.Link` from [Button](button.md) with `variant="tertiary"` for a single Back link in a two-level product.
75
+
76
+ ### Reserve Breadcrumbs for Deep Hierarchies
77
+
78
+ Add a trail only at three or more levels deep. On shallower pages, a trail repeats the sidebar and the page title.
79
+
80
+ **Do:** Show a trail on a page nested under a project and a section.
81
+
82
+ ```tsx
83
+ /**
84
+ * Do example for "Reserve Breadcrumbs for Deep Hierarchies" on the Breadcrumbs page.
85
+ * Show a trail on a page nested under a project and a section.
86
+ * @module
87
+ */
88
+ import { Breadcrumbs, style } from '@tempoxyz/ds'
89
+
90
+ /** Renders the static preview, which the guideline card shows inert. */
91
+ export function Demo() {
92
+ return (
93
+ <div {...styles.page()}>
94
+ <Breadcrumbs>
95
+ <Breadcrumbs.Item href="#">Checkout</Breadcrumbs.Item>
96
+ <Breadcrumbs.Item href="#">API keys</Breadcrumbs.Item>
97
+ <Breadcrumbs.Item current>Production</Breadcrumbs.Item>
98
+ </Breadcrumbs>
99
+ <span {...styles.title()}>Production</span>
100
+ </div>
101
+ )
102
+ }
103
+
104
+ namespace styles {
105
+ export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '8' })
106
+
107
+ export const title = style({ color: 'content.primary', typography: 'heading.h2' })
108
+ }
109
+ ```
110
+
111
+ **Don't:** Add a trail to a top-level page, where it repeats the sidebar.
112
+
113
+ ```tsx
114
+ /**
115
+ * Don't example for "Reserve Breadcrumbs for Deep Hierarchies" on the Breadcrumbs page.
116
+ * Don't add a trail to a top-level page, where it repeats the sidebar.
117
+ * @module
118
+ */
119
+ import { Breadcrumbs, style } from '@tempoxyz/ds'
120
+
121
+ /** Renders the static preview, which the guideline card shows inert. */
122
+ export function Demo() {
123
+ return (
124
+ <div {...styles.page()}>
125
+ <Breadcrumbs>
126
+ <Breadcrumbs.Item href="#">Home</Breadcrumbs.Item>
127
+ <Breadcrumbs.Item current>Activity</Breadcrumbs.Item>
128
+ </Breadcrumbs>
129
+ <span {...styles.title()}>Activity</span>
130
+ </div>
131
+ )
132
+ }
133
+
134
+ namespace styles {
135
+ export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '8' })
136
+
137
+ export const title = style({ color: 'content.primary', typography: 'heading.h2' })
138
+ }
139
+ ```
140
+
141
+ ### Reflect the Hierarchy, Not History
142
+
143
+ Build the trail from the product's structure. A transaction page shows the same trail from Activity, a search result, or a shared link. The browser's Back button covers history.
144
+
145
+ **Do:** Show the pages that contain the current page.
146
+
147
+ ```tsx
148
+ /**
149
+ * Do example for "Reflect the Hierarchy, Not History" on the Breadcrumbs page.
150
+ * Show the pages that contain the current page.
151
+ * @module
152
+ */
153
+ import { Breadcrumbs, style } from '@tempoxyz/ds'
154
+
155
+ /** Renders the static preview, which the guideline card shows inert. */
156
+ export function Demo() {
157
+ return (
158
+ <div {...styles.page()}>
159
+ <Breadcrumbs>
160
+ <Breadcrumbs.Item href="#">Checkout</Breadcrumbs.Item>
161
+ <Breadcrumbs.Item href="#">Activity</Breadcrumbs.Item>
162
+ <Breadcrumbs.Item current>0x8f3a…c21d</Breadcrumbs.Item>
163
+ </Breadcrumbs>
164
+ <span {...styles.title()}>0x8f3a…c21d</span>
165
+ </div>
166
+ )
167
+ }
168
+
169
+ namespace styles {
170
+ export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '8' })
171
+
172
+ export const title = style({ color: 'content.primary', typography: 'heading.h2' })
173
+ }
174
+ ```
175
+
176
+ **Don't:** List the pages someone visited on the way.
177
+
178
+ ```tsx
179
+ /**
180
+ * Don't example for "Reflect the Hierarchy, Not History" on the Breadcrumbs page.
181
+ * Don't list the pages someone visited on the way.
182
+ * @module
183
+ */
184
+ import { Breadcrumbs, style } from '@tempoxyz/ds'
185
+
186
+ /** Renders the static preview, which the guideline card shows inert. */
187
+ export function Demo() {
188
+ return (
189
+ <div {...styles.page()}>
190
+ <Breadcrumbs>
191
+ <Breadcrumbs.Item href="#">Search</Breadcrumbs.Item>
192
+ <Breadcrumbs.Item href="#">Wallets</Breadcrumbs.Item>
193
+ <Breadcrumbs.Item current>0x8f3a…c21d</Breadcrumbs.Item>
194
+ </Breadcrumbs>
195
+ <span {...styles.title()}>0x8f3a…c21d</span>
196
+ </div>
197
+ )
198
+ }
199
+
200
+ namespace styles {
201
+ export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '8' })
202
+
203
+ export const title = style({ color: 'content.primary', typography: 'heading.h2' })
204
+ }
205
+ ```
206
+
207
+ ### Place the Trail Above the Title
208
+
209
+ Put breadcrumbs at the start of the content column, in the same position on every page.
210
+
211
+ **Do:** Place the trail directly above the page title.
212
+
213
+ ```tsx
214
+ /**
215
+ * Do example for "Reserve Breadcrumbs for Deep Hierarchies" on the Breadcrumbs page.
216
+ * Show a trail on a page nested under a project and a section.
217
+ * @module
218
+ */
219
+ import { Breadcrumbs, style } from '@tempoxyz/ds'
220
+
221
+ /** Renders the static preview, which the guideline card shows inert. */
222
+ export function Demo() {
223
+ return (
224
+ <div {...styles.page()}>
225
+ <Breadcrumbs>
226
+ <Breadcrumbs.Item href="#">Checkout</Breadcrumbs.Item>
227
+ <Breadcrumbs.Item href="#">API keys</Breadcrumbs.Item>
228
+ <Breadcrumbs.Item current>Production</Breadcrumbs.Item>
229
+ </Breadcrumbs>
230
+ <span {...styles.title()}>Production</span>
231
+ </div>
232
+ )
233
+ }
234
+
235
+ namespace styles {
236
+ export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '8' })
237
+
238
+ export const title = style({ color: 'content.primary', typography: 'heading.h2' })
239
+ }
240
+ ```
241
+
242
+ **Don't:** Place the trail below the title.
243
+
244
+ ```tsx
245
+ /**
246
+ * Don't example for "Place the Trail Above the Title" on the Breadcrumbs page.
247
+ * Don't place the trail below the title.
248
+ * @module
249
+ */
250
+ import { Breadcrumbs, style } from '@tempoxyz/ds'
251
+
252
+ /** Renders the static preview, which the guideline card shows inert. */
253
+ export function Demo() {
254
+ return (
255
+ <div {...styles.page()}>
256
+ <span {...styles.title()}>Production</span>
257
+ <Breadcrumbs>
258
+ <Breadcrumbs.Item href="#">Checkout</Breadcrumbs.Item>
259
+ <Breadcrumbs.Item href="#">API keys</Breadcrumbs.Item>
260
+ <Breadcrumbs.Item current>Production</Breadcrumbs.Item>
261
+ </Breadcrumbs>
262
+ </div>
263
+ )
264
+ }
265
+
266
+ namespace styles {
267
+ export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '8' })
268
+
269
+ export const title = style({ color: 'content.primary', typography: 'heading.h2' })
270
+ }
271
+ ```
272
+
273
+ ### Keep the Default Separator
274
+
275
+ The default right chevron reads as one step down the hierarchy. Set `separator` only if the product already uses another convention, such as `/` for documentation paths, and use one separator across the product.
276
+
277
+ **Do:** Keep the default chevron.
278
+
279
+ ```tsx
280
+ /** Do example for "Keep the Default Separator" on the Breadcrumbs page: keep the default chevron. @module */
281
+ import { Breadcrumbs, style } from '@tempoxyz/ds'
282
+
283
+ /** Renders the static preview, which the guideline card shows inert. */
284
+ export function Demo() {
285
+ return (
286
+ <div {...styles.page()}>
287
+ <Breadcrumbs>
288
+ <Breadcrumbs.Item href="#">Checkout</Breadcrumbs.Item>
289
+ <Breadcrumbs.Item href="#">Webhooks</Breadcrumbs.Item>
290
+ <Breadcrumbs.Item current>Deliveries</Breadcrumbs.Item>
291
+ </Breadcrumbs>
292
+ <span {...styles.title()}>Deliveries</span>
293
+ </div>
294
+ )
295
+ }
296
+
297
+ namespace styles {
298
+ export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '8' })
299
+
300
+ export const title = style({ color: 'content.primary', typography: 'heading.h2' })
301
+ }
302
+ ```
303
+
304
+ **Don't:** Swap in another separator, such as an arrow, without a product convention.
305
+
306
+ ```tsx
307
+ /**
308
+ * Don't example for "Keep the Default Separator" on the Breadcrumbs page.
309
+ * Don't swap in another separator, such as an arrow, without a product convention.
310
+ * @module
311
+ */
312
+ import { Breadcrumbs, style } from '@tempoxyz/ds'
313
+
314
+ /** Renders the static preview, which the guideline card shows inert. */
315
+ export function Demo() {
316
+ return (
317
+ <div {...styles.page()}>
318
+ <Breadcrumbs separator="→">
319
+ <Breadcrumbs.Item href="#">Checkout</Breadcrumbs.Item>
320
+ <Breadcrumbs.Item href="#">Webhooks</Breadcrumbs.Item>
321
+ <Breadcrumbs.Item current>Deliveries</Breadcrumbs.Item>
322
+ </Breadcrumbs>
323
+ <span {...styles.title()}>Deliveries</span>
324
+ </div>
325
+ )
326
+ }
327
+
328
+ namespace styles {
329
+ export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '8' })
330
+
331
+ export const title = style({ color: 'content.primary', typography: 'heading.h2' })
332
+ }
333
+ ```
334
+
335
+ ## Content
336
+
337
+ * **Labels:** Use each page's title, such as API keys.
338
+ * **Addresses and hashes:** Shorten to the first and last characters, such as 0x71C7…976F. Show the full value on the page.
339
+ * **Length:** The list wraps instead of truncating, so keep labels short.
340
+
341
+ ## Accessibility
342
+
343
+ Renders a navigation landmark with an ordered list of links, following the [WAI-ARIA breadcrumb pattern](https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/).
344
+
345
+ ### Semantics
346
+
347
+ * **Root (nav):** A navigation landmark named "Breadcrumb".
348
+ * **List (ol):** Screen readers announce the number of levels.
349
+ * **Breadcrumbs.Item (li):** Wraps a link. The current item is plain text marked as the current page.
350
+ * **Separators (aria-hidden):** Hidden. Screen readers announce only the pages.
351
+
352
+ ### Keyboard
353
+
354
+ * **Move Between Links (Tab):** Moves focus to each link in order, skipping the current item.
355
+ * **Follow a Link (Enter):** Follows the focused link.
356
+
357
+ ### Your Responsibilities
358
+
359
+ * **Mark the Current Page (current):** Set it on the last item. It is announced as the current page and takes no focus.
360
+ * **Keep the Landmark Distinct (SC 2.4.1):** Keep the "Breadcrumb" name, or pass a distinct `aria-label`.
361
+ * **Use Real Links (render):** Pass your router's link so each item stays a real link with the same styles.
362
+ * **Keep the Default Gaps (20px):** Links are under the 24px minimum, which WCAG 2.2 accepts if targets are spaced apart.
363
+
364
+ ## Related
365
+
366
+ [SidebarMenu](sidebar-menu.md)
367
+
368
+ Use for top-level navigation.
369
+
370
+ [AppShell](app-shell.md)
371
+
372
+ Use for the page frame that holds the trail.
373
+
374
+ [Tabs](tabs.md)
375
+
376
+ Use for switching views within a page.
377
+
378
+ [Navigation](../patterns/navigation.md)
379
+
380
+ Covers choosing between navigation components.
@@ -0,0 +1,286 @@
1
+ # ButtonGroup
2
+
3
+ Lays out the actions at the foot of a dialog or focused flow.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/ButtonGroup.tsx)
6
+
7
+ Figma: [Button Group](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=1269-1089)
8
+
9
+ ## Overview
10
+
11
+ A button group places [Buttons](button.md) side by side at equal widths, or stacks them at full width.
12
+
13
+ ## Examples
14
+
15
+ ### Basic
16
+
17
+ ```tsx
18
+ import { Button, ButtonGroup, style } from '@tempoxyz/ds'
19
+
20
+ export const fill = true
21
+ export function Demo() {
22
+ return (
23
+ <ButtonGroup {...styles.group()}>
24
+ <Button size="large" variant="secondary">
25
+ Cancel
26
+ </Button>
27
+ <Button size="large">Confirm</Button>
28
+ </ButtonGroup>
29
+ )
30
+ }
31
+
32
+ namespace styles {
33
+ export const group = style({ maxWidth: '360', width: '100% !custom' })
34
+ }
35
+ ```
36
+
37
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ButtonGroup/Basic.tsx)
38
+
39
+ ### Orientation
40
+
41
+ Set `orientation` to `horizontal` (default) or `vertical`. Both place the buttons 8px apart.
42
+
43
+ ```tsx
44
+ import { Button, ButtonGroup, style } from '@tempoxyz/ds'
45
+
46
+ export const fill = true
47
+ export function Demo() {
48
+ return (
49
+ <ButtonGroup orientation="vertical" {...styles.group()}>
50
+ <Button size="large">Get started</Button>
51
+ <Button size="large" variant="tertiary">
52
+ Not now
53
+ </Button>
54
+ </ButtonGroup>
55
+ )
56
+ }
57
+
58
+ namespace styles {
59
+ export const group = style({ maxWidth: '360', width: '100% !custom' })
60
+ }
61
+ ```
62
+
63
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ButtonGroup/Orientation.tsx)
64
+
65
+ ## Anatomy
66
+
67
+ Import the component and assemble its parts.
68
+
69
+ ```tsx
70
+ import { Button, ButtonGroup } from '@tempoxyz/ds'
71
+
72
+ <ButtonGroup>
73
+ <Button />
74
+ </ButtonGroup>
75
+ ```
76
+
77
+ ## Guidelines
78
+
79
+ ### When to Use
80
+
81
+ * Close a dialog with two actions of equal weight, such as Cancel and Confirm.
82
+ * Stack a main action above a dismiss action in an intro or announcement, such as Get started and Not now.
83
+
84
+ ### When Not to Use
85
+
86
+ * Use a [SplitButton](split-button.md) for a main action with related alternatives.
87
+ * Use an [Inline](inline.md) row for actions at their natural width, such as a toolbar.
88
+ * Use a [Menu](menu.md) for more than three actions.
89
+
90
+ ### Put the Primary Action Last
91
+
92
+ Place the `primary` action on the right of a pair. Keep the source order the same as the visual order, so focus reaches the main action last.
93
+
94
+ **Do:** Put the `secondary` action first and the `primary` action last.
95
+
96
+ ```tsx
97
+ /**
98
+ * Do example for "Put the Primary Action Last" on the ButtonGroup page.
99
+ * Put the `secondary` action first and the `primary` action last.
100
+ * @module
101
+ */
102
+ import { Button, ButtonGroup, style } from '@tempoxyz/ds'
103
+
104
+ /** Renders the static preview, which the guideline card shows inert. */
105
+ export function Demo() {
106
+ return (
107
+ <ButtonGroup {...styles.group()}>
108
+ <Button size="large" variant="secondary">
109
+ Cancel
110
+ </Button>
111
+ <Button size="large">Confirm</Button>
112
+ </ButtonGroup>
113
+ )
114
+ }
115
+
116
+ namespace styles {
117
+ export const group = style({ maxWidth: '320', width: '100% !custom' })
118
+ }
119
+ ```
120
+
121
+ **Don't:** Put the `primary` action on the left of a pair.
122
+
123
+ ```tsx
124
+ /**
125
+ * Don't example for "Put the Primary Action Last" on the ButtonGroup page.
126
+ * Don't put the `primary` action on the left of a pair.
127
+ * @module
128
+ */
129
+ import { Button, ButtonGroup, style } from '@tempoxyz/ds'
130
+
131
+ /** Renders the static preview, which the guideline card shows inert. */
132
+ export function Demo() {
133
+ return (
134
+ <ButtonGroup {...styles.group()}>
135
+ <Button size="large">Confirm</Button>
136
+ <Button size="large" variant="secondary">
137
+ Cancel
138
+ </Button>
139
+ </ButtonGroup>
140
+ )
141
+ }
142
+
143
+ namespace styles {
144
+ export const group = style({ maxWidth: '320', width: '100% !custom' })
145
+ }
146
+ ```
147
+
148
+ ### Keep Every Button the Same Size
149
+
150
+ Give every button in a dialog footer the `large` size. In a stack, the `tertiary` dismiss action keeps that size.
151
+
152
+ **Do:** Give the dismiss action the same `large` size as the `primary` action.
153
+
154
+ ```tsx
155
+ /**
156
+ * Do example for "Keep Every Button the Same Size" on the ButtonGroup page.
157
+ * Give the dismiss action the same `large` size as the `primary` action.
158
+ * @module
159
+ */
160
+ import { Button, ButtonGroup, style } from '@tempoxyz/ds'
161
+
162
+ /** Renders the static preview, which the guideline card shows inert. */
163
+ export function Demo() {
164
+ return (
165
+ <ButtonGroup orientation="vertical" {...styles.group()}>
166
+ <Button size="large">Get started</Button>
167
+ <Button size="large" variant="tertiary">
168
+ Not now
169
+ </Button>
170
+ </ButtonGroup>
171
+ )
172
+ }
173
+
174
+ namespace styles {
175
+ export const group = style({ maxWidth: '320', width: '100% !custom' })
176
+ }
177
+ ```
178
+
179
+ **Don't:** Shrink the dismiss action below the `primary` action.
180
+
181
+ ```tsx
182
+ /**
183
+ * Don't example for "Keep Every Button the Same Size" on the ButtonGroup page.
184
+ * Don't shrink the dismiss action below the `primary` action.
185
+ * @module
186
+ */
187
+ import { Button, ButtonGroup, style } from '@tempoxyz/ds'
188
+
189
+ /** Renders the static preview, which the guideline card shows inert. */
190
+ export function Demo() {
191
+ return (
192
+ <ButtonGroup orientation="vertical" {...styles.group()}>
193
+ <Button size="large">Get started</Button>
194
+ <Button size="small" variant="tertiary">
195
+ Not now
196
+ </Button>
197
+ </ButtonGroup>
198
+ )
199
+ }
200
+
201
+ namespace styles {
202
+ export const group = style({ maxWidth: '320', width: '100% !custom' })
203
+ }
204
+ ```
205
+
206
+ ## Content
207
+
208
+ ### Name the Destructive Action
209
+
210
+ If the action destroys data or removes access, name what it does on the `primary` button, such as Revoke all.
211
+
212
+ **Do:** Name both outcomes, such as Keep keys and Revoke all.
213
+
214
+ ```tsx
215
+ /**
216
+ * Do example for "Name the Destructive Action" on the ButtonGroup page.
217
+ * Name both outcomes, such as Keep keys and Revoke all.
218
+ * @module
219
+ */
220
+ import { Button, ButtonGroup, style } from '@tempoxyz/ds'
221
+
222
+ /** Renders the static preview, which the guideline card shows inert. */
223
+ export function Demo() {
224
+ return (
225
+ <ButtonGroup {...styles.group()}>
226
+ <Button size="large" variant="secondary">
227
+ Keep keys
228
+ </Button>
229
+ <Button size="large">Revoke all</Button>
230
+ </ButtonGroup>
231
+ )
232
+ }
233
+
234
+ namespace styles {
235
+ export const group = style({ maxWidth: '320', width: '100% !custom' })
236
+ }
237
+ ```
238
+
239
+ **Don't:** Label a destructive action OK.
240
+
241
+ ```tsx
242
+ /**
243
+ * Don't example for "Name the Destructive Action" on the ButtonGroup page.
244
+ * Don't label a destructive action OK.
245
+ * @module
246
+ */
247
+ import { Button, ButtonGroup, style } from '@tempoxyz/ds'
248
+
249
+ /** Renders the static preview, which the guideline card shows inert. */
250
+ export function Demo() {
251
+ return (
252
+ <ButtonGroup {...styles.group()}>
253
+ <Button size="large" variant="secondary">
254
+ Cancel
255
+ </Button>
256
+ <Button size="large">OK</Button>
257
+ </ButtonGroup>
258
+ )
259
+ }
260
+
261
+ namespace styles {
262
+ export const group = style({ maxWidth: '320', width: '100% !custom' })
263
+ }
264
+ ```
265
+
266
+ ## Accessibility
267
+
268
+ `ButtonGroup` renders a `div` with `role="group"` around native buttons. See [Accessibility](../foundations/accessibility.md) for the baseline.
269
+
270
+ * **Group (group):** Groups the actions. Name it with `aria-label` when the dialog title does not.
271
+ * **Focus Order (Tab):** Follows the source order, which matches the visual order in both orientations.
272
+ * **Target Size (48px):** Large buttons stretch to the full width, which leaves a wide target on touch screens.
273
+
274
+ ## Related
275
+
276
+ [Button](button.md)
277
+
278
+ Use for each action in the group.
279
+
280
+ [Dialog](dialog.md)
281
+
282
+ Use for the focused task that the group closes.
283
+
284
+ [AlertDialog](alert-dialog.md)
285
+
286
+ Use for confirming a destructive action.