@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,434 @@
1
+ # Frame
2
+
3
+ Lays out a header, body, and footer in a column.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Frame.tsx)
6
+
7
+ ## Overview
8
+
9
+ A frame lays out a header, body, and footer in a column with no fill. Wrap it in a [Surface](surface.md) for a card, or put it in a [Dialog](dialog.md) or [Drawer](drawer.md) popup.
10
+
11
+ The actions share the width of the footer equally.
12
+
13
+ ## Examples
14
+
15
+ ### Basic
16
+
17
+ ```tsx
18
+ import { Button, Frame, ListGroup, Surface } from '@tempoxyz/ds'
19
+
20
+ export function Demo() {
21
+ return (
22
+ <Surface>
23
+ <Frame.Root onDismiss={() => {}}>
24
+ <Frame.Header>
25
+ <Frame.Title>Review request</Frame.Title>
26
+ <Frame.Description>Review the details before continuing.</Frame.Description>
27
+ <Frame.Close />
28
+ </Frame.Header>
29
+ <Frame.Body>
30
+ <ListGroup>
31
+ <ListGroup.Row>
32
+ <ListGroup.Label>Network</ListGroup.Label>
33
+ Tempo
34
+ </ListGroup.Row>
35
+ <ListGroup.Row>
36
+ <ListGroup.Label>Amount</ListGroup.Label>
37
+ $50.00
38
+ </ListGroup.Row>
39
+ </ListGroup>
40
+ </Frame.Body>
41
+ <Frame.Footer>
42
+ <Frame.Actions>
43
+ <Button variant="secondary">Cancel</Button>
44
+ <Button>Approve</Button>
45
+ </Frame.Actions>
46
+ </Frame.Footer>
47
+ </Frame.Root>
48
+ </Surface>
49
+ )
50
+ }
51
+ ```
52
+
53
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Frame/Basic.tsx)
54
+
55
+ ### OnDismiss
56
+
57
+ Set `onDismiss` on the frame or a surrounding `Frame.Provider` to show `Frame.Close`.
58
+
59
+ ```tsx
60
+ import { Button, Frame, ListGroup, style, Surface } from '@tempoxyz/ds'
61
+
62
+ export function Demo() {
63
+ return (
64
+ <Frame.Provider onDismiss={() => {}}>
65
+ <div {...styles.grid()}>
66
+ <Surface>
67
+ <Review />
68
+ </Surface>
69
+ <Review />
70
+ <Surface>
71
+ <Review onDismiss={null} />
72
+ </Surface>
73
+ </div>
74
+ </Frame.Provider>
75
+ )
76
+ }
77
+
78
+ function Review(props: Frame.Root.Props) {
79
+ return (
80
+ <Frame.Root {...props}>
81
+ <Frame.Header>
82
+ <Frame.Title>Review request</Frame.Title>
83
+ <Frame.Description>Review the details before continuing.</Frame.Description>
84
+ <Frame.Close />
85
+ </Frame.Header>
86
+ <Frame.Body>
87
+ <ListGroup>
88
+ <ListGroup.Row>
89
+ <ListGroup.Label>Network</ListGroup.Label>
90
+ Tempo
91
+ </ListGroup.Row>
92
+ <ListGroup.Row>
93
+ <ListGroup.Label>Amount</ListGroup.Label>
94
+ $50.00
95
+ </ListGroup.Row>
96
+ </ListGroup>
97
+ </Frame.Body>
98
+ <Frame.Footer>
99
+ <Frame.Actions>
100
+ <Button variant="secondary">Cancel</Button>
101
+ <Button>Approve</Button>
102
+ </Frame.Actions>
103
+ </Frame.Footer>
104
+ </Frame.Root>
105
+ )
106
+ }
107
+
108
+ namespace styles {
109
+ export const grid = style({
110
+ backgroundColor: 'background.primary',
111
+ display: 'grid',
112
+ gap: '16',
113
+ padding: '16',
114
+ gridTemplateColumns: 'repeat(auto-fill, minmax(20rem, 1fr)) !custom',
115
+ })
116
+ }
117
+ ```
118
+
119
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Frame/OnDismiss.tsx)
120
+
121
+ ## Anatomy
122
+
123
+ Import the component and assemble its parts.
124
+
125
+ ```tsx
126
+ import { Frame } from '@tempoxyz/ds'
127
+
128
+ <Frame />
129
+
130
+ <Frame.Provider>
131
+ <Frame.Root>
132
+ <Frame.Header>
133
+ <Frame.Title />
134
+ <Frame.Description />
135
+ <Frame.Close />
136
+ </Frame.Header>
137
+ <Frame.Body />
138
+ <Frame.Footer>
139
+ <Frame.Actions />
140
+ </Frame.Footer>
141
+ </Frame.Root>
142
+ </Frame.Provider>
143
+ ```
144
+
145
+ ## Guidelines
146
+
147
+ ### When to Use
148
+
149
+ * Give a card, dialog, or drawer a title, content, and a row of actions.
150
+ * Share one dismiss handler across nested panels with `Frame.Provider`, such as the steps of a dialog.
151
+
152
+ ### When Not to Use
153
+
154
+ * Use [Surface](surface.md) with `Surface.Header` and `Surface.Title` for a card with only a heading and content.
155
+ * Use [AppShell](app-shell.md) for the frame of a whole page.
156
+ * Use [Stack](stack.md) for a plain column without a header or footer.
157
+
158
+ ### Put Actions in the Footer
159
+
160
+ Put `Frame.Actions` inside `Frame.Footer`, in the [Button](button.md) order. `Frame.Body` grows to fill the frame, so the footer stays at the bottom of a tall container, such as a dialog popup. The body never scrolls, so let the container handle overflow.
161
+
162
+ **Do:** Keep the actions in `Frame.Footer`, at the bottom of the frame.
163
+
164
+ ```tsx
165
+ /**
166
+ * Do example for "Put Actions in the Footer" on the Frame page.
167
+ * Keep the actions in `Frame.Footer`, at the bottom of the frame.
168
+ * @module
169
+ */
170
+ import { Amount, Button, Frame, ListGroup, style, Surface } from '@tempoxyz/ds'
171
+
172
+ const payments = [
173
+ ['Alice', '25.00'],
174
+ ['Bob', '120.00'],
175
+ ] as const
176
+
177
+ /** Renders the static preview, which the guideline card shows inert. */
178
+ export function Demo() {
179
+ return (
180
+ <div {...styles.canvas()}>
181
+ <Surface size="medium" {...styles.card()}>
182
+ <Frame {...styles.frame()}>
183
+ <Frame.Header>
184
+ <Frame.Title>Review batch</Frame.Title>
185
+ </Frame.Header>
186
+ <Frame.Body>
187
+ <ListGroup>
188
+ {payments.map(([name, amount]) => (
189
+ <ListGroup.Row key={name}>
190
+ <ListGroup.Label>{name}</ListGroup.Label>
191
+ <Amount symbol="USDC" value={amount} />
192
+ </ListGroup.Row>
193
+ ))}
194
+ </ListGroup>
195
+ </Frame.Body>
196
+ <Frame.Footer>
197
+ <Frame.Actions>
198
+ <Button size="small" variant="secondary">
199
+ Cancel
200
+ </Button>
201
+ <Button size="small">Send 2 payments</Button>
202
+ </Frame.Actions>
203
+ </Frame.Footer>
204
+ </Frame>
205
+ </Surface>
206
+ </div>
207
+ )
208
+ }
209
+
210
+ namespace styles {
211
+ export const canvas = style({
212
+ backgroundColor: 'background.primary',
213
+ borderRadius: 'sm',
214
+ boxSizing: 'border-box',
215
+ padding: '12',
216
+ width: '100% !custom',
217
+ })
218
+
219
+ export const card = style({ height: '240' })
220
+
221
+ export const frame = style({ height: '100% !custom', rowGap: '16' })
222
+ }
223
+ ```
224
+
225
+ **Don't:** Put the actions at the end of `Frame.Body`, directly against the content.
226
+
227
+ ```tsx
228
+ /**
229
+ * Don't example for "Put Actions in the Footer" on the Frame page.
230
+ * Don't put the actions at the end of `Frame.Body`, directly against the content.
231
+ * @module
232
+ */
233
+ import { Amount, Button, Frame, ListGroup, style, Surface } from '@tempoxyz/ds'
234
+
235
+ const payments = [
236
+ ['Alice', '25.00'],
237
+ ['Bob', '120.00'],
238
+ ] as const
239
+
240
+ /** Renders the static preview, which the guideline card shows inert. */
241
+ export function Demo() {
242
+ return (
243
+ <div {...styles.canvas()}>
244
+ <Surface size="medium" {...styles.card()}>
245
+ <Frame {...styles.frame()}>
246
+ <Frame.Header>
247
+ <Frame.Title>Review batch</Frame.Title>
248
+ </Frame.Header>
249
+ <Frame.Body>
250
+ <ListGroup>
251
+ {payments.map(([name, amount]) => (
252
+ <ListGroup.Row key={name}>
253
+ <ListGroup.Label>{name}</ListGroup.Label>
254
+ <Amount symbol="USDC" value={amount} />
255
+ </ListGroup.Row>
256
+ ))}
257
+ </ListGroup>
258
+ <Frame.Actions>
259
+ <Button size="small" variant="secondary">
260
+ Cancel
261
+ </Button>
262
+ <Button size="small">Send 2 payments</Button>
263
+ </Frame.Actions>
264
+ </Frame.Body>
265
+ </Frame>
266
+ </Surface>
267
+ </div>
268
+ )
269
+ }
270
+
271
+ namespace styles {
272
+ export const canvas = style({
273
+ backgroundColor: 'background.primary',
274
+ borderRadius: 'sm',
275
+ boxSizing: 'border-box',
276
+ padding: '12',
277
+ width: '100% !custom',
278
+ })
279
+
280
+ export const card = style({ height: '240' })
281
+
282
+ export const frame = style({ height: '100% !custom', rowGap: '16' })
283
+ }
284
+ ```
285
+
286
+ ### Show Close Only When It Dismisses
287
+
288
+ If a nested frame can't be dismissed, such as a confirmation step, pass `onDismiss={null}` to drop the inherited handler and hide `Frame.Close`.
289
+
290
+ **Do:** Pass `onDismiss={null}` on a step that must finish.
291
+
292
+ ```tsx
293
+ /**
294
+ * Do example for "Show Close Only When It Dismisses" on the Frame page.
295
+ * Pass `onDismiss={null}` on a step that must finish.
296
+ * @module
297
+ */
298
+ import { Button, Frame, style, Surface } from '@tempoxyz/ds'
299
+
300
+ /** Renders the static preview, which the guideline card shows inert. */
301
+ export function Demo() {
302
+ return (
303
+ <Frame.Provider onDismiss={() => {}}>
304
+ <div {...styles.canvas()}>
305
+ <Surface size="medium">
306
+ <Frame onDismiss={null}>
307
+ <Frame.Header>
308
+ <Frame.Title>Sending payment</Frame.Title>
309
+ <Frame.Description>Keep this window open until 25.00 USDC settles.</Frame.Description>
310
+ <Frame.Close />
311
+ </Frame.Header>
312
+ <Frame.Footer>
313
+ <Frame.Actions>
314
+ <Button loading size="small">
315
+ Send
316
+ </Button>
317
+ </Frame.Actions>
318
+ </Frame.Footer>
319
+ </Frame>
320
+ </Surface>
321
+ </div>
322
+ </Frame.Provider>
323
+ )
324
+ }
325
+
326
+ namespace styles {
327
+ export const canvas = style({
328
+ backgroundColor: 'background.primary',
329
+ borderRadius: 'sm',
330
+ boxSizing: 'border-box',
331
+ padding: '12',
332
+ width: '100% !custom',
333
+ })
334
+ }
335
+ ```
336
+
337
+ **Don't:** Leave an inherited close button on a step that can't be dismissed.
338
+
339
+ ```tsx
340
+ /**
341
+ * Don't example for "Show Close Only When It Dismisses" on the Frame page.
342
+ * Don't leave an inherited close button on a step that can't be dismissed.
343
+ * @module
344
+ */
345
+ import { Button, Frame, style, Surface } from '@tempoxyz/ds'
346
+
347
+ /** Renders the static preview, which the guideline card shows inert. */
348
+ export function Demo() {
349
+ return (
350
+ <Frame.Provider onDismiss={() => {}}>
351
+ <div {...styles.canvas()}>
352
+ <Surface size="medium">
353
+ <Frame>
354
+ <Frame.Header>
355
+ <Frame.Title>Sending payment</Frame.Title>
356
+ <Frame.Description>Keep this window open until 25.00 USDC settles.</Frame.Description>
357
+ <Frame.Close />
358
+ </Frame.Header>
359
+ <Frame.Footer>
360
+ <Frame.Actions>
361
+ <Button loading size="small">
362
+ Send
363
+ </Button>
364
+ </Frame.Actions>
365
+ </Frame.Footer>
366
+ </Frame>
367
+ </Surface>
368
+ </div>
369
+ </Frame.Provider>
370
+ )
371
+ }
372
+
373
+ namespace styles {
374
+ export const canvas = style({
375
+ backgroundColor: 'background.primary',
376
+ borderRadius: 'sm',
377
+ boxSizing: 'border-box',
378
+ padding: '12',
379
+ width: '100% !custom',
380
+ })
381
+ }
382
+ ```
383
+
384
+ ### Check the Heading Level
385
+
386
+ `Frame.Title` always renders an `h2`.
387
+
388
+ * **Dialog or Card (h2):** Use `Frame.Title` in a dialog, or in a card below the page `h1`.
389
+ * **Inside an h2 Section (h3):** Render your own `h3` in the header in place of `Frame.Title`.
390
+
391
+ ## Content
392
+
393
+ * **Title:** Name the task, such as Review request or Send USDC.
394
+ * **Description:** In one sentence, state what happens next.
395
+ * **Primary action:** Repeat the title's verb, such as Approve request.
396
+
397
+ ## Accessibility
398
+
399
+ A frame adds headings and an optional close button. It doesn't move or trap focus, so other semantics and focus management come from its container.
400
+
401
+ ### Semantics
402
+
403
+ * **Frame.Title (h2):** The frame's heading, rendered at the top of its header.
404
+ * **Frame.Description (p):** Supporting text below the title, which describes the frame's content.
405
+ * **Frame.Close (button):** Announced as "Close", with its icon hidden. Its target exceeds the WCAG 2.2 minimum.
406
+ * **No Inert Close Button:** The close button renders nothing without a dismiss handler or `onClick`.
407
+
408
+ ### Keyboard
409
+
410
+ * **Move Through the Frame (Tab):** Moves focus to the close button and the controls, in source order.
411
+ * **Activate Close (Enter or Space):** Calls the close button's `onClick`, then the dismiss handler.
412
+
413
+ ### Your Responsibilities
414
+
415
+ * **Name the Close Button (aria-label):** If ambiguous, name what it closes: "Close send payment".
416
+ * **Label the Dialog (aria-labelledby):** Point a dialog's `aria-labelledby` at the title.
417
+
418
+ ## Related
419
+
420
+ [Surface](surface.md)
421
+
422
+ Use for the card around a frame.
423
+
424
+ [Dialog](dialog.md)
425
+
426
+ Use for frames that open over the page.
427
+
428
+ [Drawer](drawer.md)
429
+
430
+ Use for side panels.
431
+
432
+ [Button](button.md)
433
+
434
+ Use for ordering actions.