@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.
- package/dist/docs/AGENTS.md +9 -0
- package/dist/docs/components/accordion.md +489 -0
- package/dist/docs/components/address-card.md +147 -0
- package/dist/docs/components/agent-logo.md +194 -0
- package/dist/docs/components/alert-dialog.md +631 -0
- package/dist/docs/components/alert.md +448 -0
- package/dist/docs/components/amount-input.md +305 -0
- package/dist/docs/components/amount.md +794 -0
- package/dist/docs/components/app-shell.md +559 -0
- package/dist/docs/components/asset-chip.md +294 -0
- package/dist/docs/components/autocomplete.md +619 -0
- package/dist/docs/components/avatar.md +321 -0
- package/dist/docs/components/badge.md +339 -0
- package/dist/docs/components/badged-logo.md +116 -0
- package/dist/docs/components/banner.md +379 -0
- package/dist/docs/components/bar-chart.md +208 -0
- package/dist/docs/components/breadcrumbs.md +380 -0
- package/dist/docs/components/button-group.md +286 -0
- package/dist/docs/components/button.md +650 -0
- package/dist/docs/components/calendar.md +375 -0
- package/dist/docs/components/callout.md +96 -0
- package/dist/docs/components/checkbox-group.md +521 -0
- package/dist/docs/components/checkbox.md +467 -0
- package/dist/docs/components/choice-group.md +516 -0
- package/dist/docs/components/choicebox.md +641 -0
- package/dist/docs/components/code.md +100 -0
- package/dist/docs/components/combobox.md +939 -0
- package/dist/docs/components/container.md +257 -0
- package/dist/docs/components/copy-button.md +642 -0
- package/dist/docs/components/date-picker.md +514 -0
- package/dist/docs/components/dialog.md +1332 -0
- package/dist/docs/components/drawer.md +966 -0
- package/dist/docs/components/empty.md +340 -0
- package/dist/docs/components/field.md +570 -0
- package/dist/docs/components/fieldset.md +398 -0
- package/dist/docs/components/frame.md +434 -0
- package/dist/docs/components/gauge.md +299 -0
- package/dist/docs/components/get-started-visual.md +117 -0
- package/dist/docs/components/grid.md +288 -0
- package/dist/docs/components/hero-visual.md +155 -0
- package/dist/docs/components/hex.md +487 -0
- package/dist/docs/components/icon-tile.md +292 -0
- package/dist/docs/components/identicon.md +371 -0
- package/dist/docs/components/inline.md +233 -0
- package/dist/docs/components/inset.md +225 -0
- package/dist/docs/components/kbd.md +423 -0
- package/dist/docs/components/list-group.md +981 -0
- package/dist/docs/components/loading-dots.md +237 -0
- package/dist/docs/components/menu.md +934 -0
- package/dist/docs/components/native-select.md +204 -0
- package/dist/docs/components/network-logo.md +248 -0
- package/dist/docs/components/number-field.md +543 -0
- package/dist/docs/components/otp-field.md +616 -0
- package/dist/docs/components/pagination.md +516 -0
- package/dist/docs/components/popover.md +544 -0
- package/dist/docs/components/progress.md +388 -0
- package/dist/docs/components/qr.md +314 -0
- package/dist/docs/components/radio-group.md +528 -0
- package/dist/docs/components/secret-value.md +406 -0
- package/dist/docs/components/select.md +751 -0
- package/dist/docs/components/separator.md +379 -0
- package/dist/docs/components/sidebar-menu.md +922 -0
- package/dist/docs/components/skeleton.md +517 -0
- package/dist/docs/components/slider.md +539 -0
- package/dist/docs/components/snippet.md +424 -0
- package/dist/docs/components/spinner.md +216 -0
- package/dist/docs/components/split-bar.md +139 -0
- package/dist/docs/components/split-button.md +464 -0
- package/dist/docs/components/stack.md +299 -0
- package/dist/docs/components/status-chip.md +226 -0
- package/dist/docs/components/status-indicator.md +119 -0
- package/dist/docs/components/status-row.md +174 -0
- package/dist/docs/components/stepper.md +451 -0
- package/dist/docs/components/success-hero.md +157 -0
- package/dist/docs/components/surface.md +639 -0
- package/dist/docs/components/switch.md +472 -0
- package/dist/docs/components/table.md +967 -0
- package/dist/docs/components/tabs.md +627 -0
- package/dist/docs/components/tempo-logo.md +185 -0
- package/dist/docs/components/text-input.md +624 -0
- package/dist/docs/components/textarea.md +352 -0
- package/dist/docs/components/toast.md +535 -0
- package/dist/docs/components/token-logo.md +371 -0
- package/dist/docs/components/token.md +247 -0
- package/dist/docs/components/tooltip.md +490 -0
- package/dist/docs/components/verification-code.md +116 -0
- package/dist/docs/components/visual.md +249 -0
- package/dist/docs/components.md +203 -0
- package/dist/docs/foundations/accessibility.md +377 -0
- package/dist/docs/foundations/agents.md +150 -0
- package/dist/docs/foundations/color.md +522 -0
- package/dist/docs/foundations/content/tone.md +194 -0
- package/dist/docs/foundations/content/voice.md +194 -0
- package/dist/docs/foundations/content/writing-style.md +406 -0
- package/dist/docs/foundations/iconography.md +282 -0
- package/dist/docs/foundations/intent.md +360 -0
- package/dist/docs/foundations/layout.md +508 -0
- package/dist/docs/foundations/linter.md +296 -0
- package/dist/docs/foundations/motion.md +151 -0
- package/dist/docs/foundations/radius-and-padding.md +86 -0
- package/dist/docs/foundations/typography.md +266 -0
- package/dist/docs/index.md +137 -0
- package/dist/docs/introduction/faq.md +132 -0
- package/dist/docs/introduction/getting-started.md +377 -0
- package/dist/docs/patterns/blockchain-values.md +709 -0
- package/dist/docs/patterns/dashboards.md +638 -0
- package/dist/docs/patterns/destructive-actions.md +626 -0
- package/dist/docs/patterns/empty-states.md +612 -0
- package/dist/docs/patterns/errors-and-validation.md +808 -0
- package/dist/docs/patterns/feedback-and-status.md +518 -0
- package/dist/docs/patterns/forms.md +679 -0
- package/dist/docs/patterns/loading.md +630 -0
- package/dist/docs/patterns/navigation.md +397 -0
- package/dist/docs/patterns/payments.md +765 -0
- package/dist/docs/patterns/responsive-layout.md +997 -0
- package/dist/docs/patterns/tables-and-lists.md +964 -0
- package/dist/docs/products/tempo-console.md +671 -0
- package/dist/docs/products/tempo-performance.md +437 -0
- package/dist/docs/products/tempo-wallet.md +438 -0
- package/dist/web/components/OtpField.css +1 -1
- package/dist/web/components/OtpField.d.ts +1 -1
- package/dist/web/components/OtpField.d.ts.map +1 -1
- package/dist/web/components/OtpField.js +3 -4
- package/dist/web/components/OtpField.js.map +1 -1
- package/dist/web/components/OtpField.js.zyzz.json +1 -1
- package/dist/web/index.js.zyzz.json +1 -1
- package/package.json +1 -1
- package/src/web/components/OtpField.tsx +2 -24
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
# AlertDialog
|
|
2
|
+
|
|
3
|
+
Asks you to confirm a critical action before it happens.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/AlertDialog.tsx)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
A modal confirmation that blocks the page until the user decides. It never closes on an outside press. It takes the parts and the `small` size of a [Dialog](/docs/components/dialog). Reserve it for decisions that need an explicit answer.
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Basic
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { AlertDialog, Button, ButtonGroup } from '@tempoxyz/ds'
|
|
17
|
+
|
|
18
|
+
export function Demo() {
|
|
19
|
+
return (
|
|
20
|
+
<AlertDialog.Root>
|
|
21
|
+
<AlertDialog.Trigger render={<Button />}>Delete key</AlertDialog.Trigger>
|
|
22
|
+
<AlertDialog.Popup>
|
|
23
|
+
<AlertDialog.Header>
|
|
24
|
+
<AlertDialog.Title>Delete this key?</AlertDialog.Title>
|
|
25
|
+
<AlertDialog.Description>
|
|
26
|
+
Apps that use this key stop working immediately. You cannot undo this.
|
|
27
|
+
</AlertDialog.Description>
|
|
28
|
+
</AlertDialog.Header>
|
|
29
|
+
<ButtonGroup>
|
|
30
|
+
<AlertDialog.Close render={<Button size="large" variant="secondary" />}>
|
|
31
|
+
Cancel
|
|
32
|
+
</AlertDialog.Close>
|
|
33
|
+
<AlertDialog.Close render={<Button size="large" variant="danger" />}>
|
|
34
|
+
Delete key
|
|
35
|
+
</AlertDialog.Close>
|
|
36
|
+
</ButtonGroup>
|
|
37
|
+
</AlertDialog.Popup>
|
|
38
|
+
</AlertDialog.Root>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/AlertDialog/Basic.tsx)
|
|
44
|
+
|
|
45
|
+
## Anatomy
|
|
46
|
+
|
|
47
|
+
Import the component and assemble its parts.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { AlertDialog, ButtonGroup } from '@tempoxyz/ds'
|
|
51
|
+
|
|
52
|
+
<AlertDialog.Root>
|
|
53
|
+
<AlertDialog.Trigger />
|
|
54
|
+
<AlertDialog.Popup>
|
|
55
|
+
<AlertDialog.Header>
|
|
56
|
+
<AlertDialog.Title />
|
|
57
|
+
<AlertDialog.Description />
|
|
58
|
+
</AlertDialog.Header>
|
|
59
|
+
<AlertDialog.Body />
|
|
60
|
+
<ButtonGroup>
|
|
61
|
+
<AlertDialog.Close />
|
|
62
|
+
</ButtonGroup>
|
|
63
|
+
</AlertDialog.Popup>
|
|
64
|
+
</AlertDialog.Root>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Guidelines
|
|
68
|
+
|
|
69
|
+
### When to Use
|
|
70
|
+
|
|
71
|
+
* Confirm an action you can't undo, such as Revoke key, Delete webhook, or Remove passkey.
|
|
72
|
+
* Ask before discarding unsaved work, such as Discard changes? on a settings page with edits.
|
|
73
|
+
|
|
74
|
+
### When Not to Use
|
|
75
|
+
|
|
76
|
+
* Use a [Dialog](/docs/components/dialog) for a task with fields, or to review a payment before sending it.
|
|
77
|
+
* For reversible actions, such as archiving an address, act at once and offer Undo in a [Toast](/docs/components/toast). The toast dismisses itself, so keep another way to restore the item.
|
|
78
|
+
* Use an [Alert](/docs/components/alert) or [Banner](/docs/components/banner) for a warning that needs no decision.
|
|
79
|
+
* Use a [Toast](/docs/components/toast) to report that an action finished.
|
|
80
|
+
|
|
81
|
+
### Focus the Safe Action
|
|
82
|
+
|
|
83
|
+
Opening focuses the first tabbable element in the popup. Place Cancel first in the DOM, or pass its ref to `initialFocus` on `AlertDialog.Popup`, so an Enter press right after opening cancels.
|
|
84
|
+
|
|
85
|
+
**Do:** Start focus on Cancel.
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
/** Do example for "Focus the Safe Action" on the AlertDialog page: start focus on Cancel. @module */
|
|
89
|
+
import { Button, style } from '@tempoxyz/ds'
|
|
90
|
+
import { Focus } from '../../../components/mdx/Access.js'
|
|
91
|
+
|
|
92
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
93
|
+
export function Demo() {
|
|
94
|
+
return (
|
|
95
|
+
<div {...styles.popup()}>
|
|
96
|
+
<span {...styles.title()}>Delete this webhook?</span>
|
|
97
|
+
<p {...styles.description()}>
|
|
98
|
+
Payment events stop reaching api.acme.com/hooks. You can’t undo this.
|
|
99
|
+
</p>
|
|
100
|
+
<div {...styles.actions()}>
|
|
101
|
+
<Focus>
|
|
102
|
+
<Button size="small" variant="secondary">
|
|
103
|
+
Cancel
|
|
104
|
+
</Button>
|
|
105
|
+
</Focus>
|
|
106
|
+
<Button size="small">Delete webhook</Button>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
namespace styles {
|
|
113
|
+
export const actions = style({
|
|
114
|
+
alignItems: 'center',
|
|
115
|
+
columnGap: '8',
|
|
116
|
+
display: 'flex',
|
|
117
|
+
justifyContent: 'flex-end',
|
|
118
|
+
marginTop: '16',
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
export const description = style({
|
|
122
|
+
color: 'content.secondary',
|
|
123
|
+
margin: '0 !custom',
|
|
124
|
+
typography: 'body.b2',
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
export const popup = style({
|
|
128
|
+
backgroundColor: 'background.elevated',
|
|
129
|
+
borderRadius: 'sm',
|
|
130
|
+
boxShadow: 'regular',
|
|
131
|
+
boxSizing: 'border-box',
|
|
132
|
+
display: 'flex',
|
|
133
|
+
flexDirection: 'column',
|
|
134
|
+
padding: '24',
|
|
135
|
+
rowGap: '8',
|
|
136
|
+
width: '17rem !custom',
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
export const title = style({ color: 'content.primary', typography: 'heading.h3' })
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Don't:** Start focus on the destructive action, where one Enter press confirms it.
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
/**
|
|
147
|
+
* Don't example for "Focus the Safe Action" on the AlertDialog page.
|
|
148
|
+
* Don't start focus on the destructive action, where one Enter press confirms it.
|
|
149
|
+
* @module
|
|
150
|
+
*/
|
|
151
|
+
import { Button, style } from '@tempoxyz/ds'
|
|
152
|
+
import { Focus } from '../../../components/mdx/Access.js'
|
|
153
|
+
|
|
154
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
155
|
+
export function Demo() {
|
|
156
|
+
return (
|
|
157
|
+
<div {...styles.popup()}>
|
|
158
|
+
<span {...styles.title()}>Delete this webhook?</span>
|
|
159
|
+
<p {...styles.description()}>
|
|
160
|
+
Payment events stop reaching api.acme.com/hooks. You can’t undo this.
|
|
161
|
+
</p>
|
|
162
|
+
<div {...styles.actions()}>
|
|
163
|
+
<Button size="small" variant="secondary">
|
|
164
|
+
Cancel
|
|
165
|
+
</Button>
|
|
166
|
+
<Focus>
|
|
167
|
+
<Button size="small">Delete webhook</Button>
|
|
168
|
+
</Focus>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
namespace styles {
|
|
175
|
+
export const actions = style({
|
|
176
|
+
alignItems: 'center',
|
|
177
|
+
columnGap: '8',
|
|
178
|
+
display: 'flex',
|
|
179
|
+
justifyContent: 'flex-end',
|
|
180
|
+
marginTop: '16',
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
export const description = style({
|
|
184
|
+
color: 'content.secondary',
|
|
185
|
+
margin: '0 !custom',
|
|
186
|
+
typography: 'body.b2',
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
export const popup = style({
|
|
190
|
+
backgroundColor: 'background.elevated',
|
|
191
|
+
borderRadius: 'sm',
|
|
192
|
+
boxShadow: 'regular',
|
|
193
|
+
boxSizing: 'border-box',
|
|
194
|
+
display: 'flex',
|
|
195
|
+
flexDirection: 'column',
|
|
196
|
+
padding: '24',
|
|
197
|
+
rowGap: '8',
|
|
198
|
+
width: '17rem !custom',
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
export const title = style({ color: 'content.primary', typography: 'heading.h3' })
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Always Offer Cancel
|
|
206
|
+
|
|
207
|
+
Only Escape, `closeButton` and `AlertDialog.Close` close the dialog, so render a Cancel button with `AlertDialog.Close`.
|
|
208
|
+
|
|
209
|
+
**Do:** Pair the confirm button with Cancel.
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
/** Do example for "Always Offer Cancel" on the AlertDialog page: pair the confirm button with Cancel. @module */
|
|
213
|
+
import { Button, style } from '@tempoxyz/ds'
|
|
214
|
+
|
|
215
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
216
|
+
export function Demo() {
|
|
217
|
+
return (
|
|
218
|
+
<div {...styles.popup()}>
|
|
219
|
+
<span {...styles.title()}>Revoke this API key?</span>
|
|
220
|
+
<p {...styles.description()}>
|
|
221
|
+
Apps that use the Production server key stop working immediately. You can’t undo this.
|
|
222
|
+
</p>
|
|
223
|
+
<div {...styles.actions()}>
|
|
224
|
+
<Button size="small" variant="secondary">
|
|
225
|
+
Cancel
|
|
226
|
+
</Button>
|
|
227
|
+
<Button size="small">Revoke key</Button>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
namespace styles {
|
|
234
|
+
export const actions = style({
|
|
235
|
+
columnGap: '8',
|
|
236
|
+
display: 'flex',
|
|
237
|
+
justifyContent: 'flex-end',
|
|
238
|
+
marginTop: '16',
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
export const description = style({
|
|
242
|
+
color: 'content.secondary',
|
|
243
|
+
margin: '0 !custom',
|
|
244
|
+
typography: 'body.b2',
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
export const popup = style({
|
|
248
|
+
backgroundColor: 'background.elevated',
|
|
249
|
+
borderRadius: 'sm',
|
|
250
|
+
boxShadow: 'regular',
|
|
251
|
+
boxSizing: 'border-box',
|
|
252
|
+
display: 'flex',
|
|
253
|
+
flexDirection: 'column',
|
|
254
|
+
padding: '24',
|
|
255
|
+
rowGap: '8',
|
|
256
|
+
width: '17rem !custom',
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
export const title = style({ color: 'content.primary', typography: 'heading.h3' })
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**Don't:** Render the confirm button alone. An outside press doesn't close the dialog.
|
|
264
|
+
|
|
265
|
+
```tsx
|
|
266
|
+
/**
|
|
267
|
+
* Don't example for "Always Offer Cancel" on the AlertDialog page.
|
|
268
|
+
* Don't render the confirm button alone. An outside press doesn't close the dialog.
|
|
269
|
+
* @module
|
|
270
|
+
*/
|
|
271
|
+
import { Button, style } from '@tempoxyz/ds'
|
|
272
|
+
|
|
273
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
274
|
+
export function Demo() {
|
|
275
|
+
return (
|
|
276
|
+
<div {...styles.popup()}>
|
|
277
|
+
<span {...styles.title()}>Revoke this API key?</span>
|
|
278
|
+
<p {...styles.description()}>
|
|
279
|
+
Apps that use the Production server key stop working immediately. You can’t undo this.
|
|
280
|
+
</p>
|
|
281
|
+
<div {...styles.actions()}>
|
|
282
|
+
<Button size="small">Revoke key</Button>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
namespace styles {
|
|
289
|
+
export const actions = style({
|
|
290
|
+
alignItems: 'center',
|
|
291
|
+
columnGap: '8',
|
|
292
|
+
display: 'flex',
|
|
293
|
+
justifyContent: 'flex-end',
|
|
294
|
+
marginTop: '16',
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
export const description = style({
|
|
298
|
+
color: 'content.secondary',
|
|
299
|
+
margin: '0 !custom',
|
|
300
|
+
typography: 'body.b2',
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
export const popup = style({
|
|
304
|
+
backgroundColor: 'background.elevated',
|
|
305
|
+
borderRadius: 'sm',
|
|
306
|
+
boxShadow: 'regular',
|
|
307
|
+
boxSizing: 'border-box',
|
|
308
|
+
display: 'flex',
|
|
309
|
+
flexDirection: 'column',
|
|
310
|
+
padding: '24',
|
|
311
|
+
rowGap: '8',
|
|
312
|
+
width: '17rem !custom',
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
export const title = style({ color: 'content.primary', typography: 'heading.h3' })
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Show Progress on the Confirm Button
|
|
320
|
+
|
|
321
|
+
If the action waits on the network, such as revoking a key:
|
|
322
|
+
|
|
323
|
+
1. Render the confirm button without `AlertDialog.Close`, and control `open` on `AlertDialog.Root`.
|
|
324
|
+
2. Set `loading` while the request runs.
|
|
325
|
+
3. Close the dialog on success. Show any error inside the dialog.
|
|
326
|
+
|
|
327
|
+
**Do:** Set `loading` on the confirm button and keep the dialog open.
|
|
328
|
+
|
|
329
|
+
```tsx
|
|
330
|
+
/**
|
|
331
|
+
* Do example for "Show Progress on the Confirm Button" on the AlertDialog page.
|
|
332
|
+
* Set `loading` on the confirm button and keep the dialog open.
|
|
333
|
+
* @module
|
|
334
|
+
*/
|
|
335
|
+
import { Button, style } from '@tempoxyz/ds'
|
|
336
|
+
|
|
337
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
338
|
+
export function Demo() {
|
|
339
|
+
return (
|
|
340
|
+
<div {...styles.popup()}>
|
|
341
|
+
<span {...styles.title()}>Revoke this API key?</span>
|
|
342
|
+
<p {...styles.description()}>
|
|
343
|
+
Apps that use the Production server key stop working immediately. You can’t undo this.
|
|
344
|
+
</p>
|
|
345
|
+
<div {...styles.actions()}>
|
|
346
|
+
<Button size="small" variant="secondary">
|
|
347
|
+
Cancel
|
|
348
|
+
</Button>
|
|
349
|
+
<Button size="small" loading>
|
|
350
|
+
Revoke key
|
|
351
|
+
</Button>
|
|
352
|
+
</div>
|
|
353
|
+
</div>
|
|
354
|
+
)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
namespace styles {
|
|
358
|
+
export const actions = style({
|
|
359
|
+
alignItems: 'center',
|
|
360
|
+
columnGap: '8',
|
|
361
|
+
display: 'flex',
|
|
362
|
+
justifyContent: 'flex-end',
|
|
363
|
+
marginTop: '16',
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
export const description = style({
|
|
367
|
+
color: 'content.secondary',
|
|
368
|
+
margin: '0 !custom',
|
|
369
|
+
typography: 'body.b2',
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
export const popup = style({
|
|
373
|
+
backgroundColor: 'background.elevated',
|
|
374
|
+
borderRadius: 'sm',
|
|
375
|
+
boxShadow: 'regular',
|
|
376
|
+
boxSizing: 'border-box',
|
|
377
|
+
display: 'flex',
|
|
378
|
+
flexDirection: 'column',
|
|
379
|
+
padding: '24',
|
|
380
|
+
rowGap: '8',
|
|
381
|
+
width: '17rem !custom',
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
export const title = style({ color: 'content.primary', typography: 'heading.h3' })
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Don't:** Add a separate spinner and leave the buttons active.
|
|
389
|
+
|
|
390
|
+
```tsx
|
|
391
|
+
/**
|
|
392
|
+
* Don't example for "Show Progress on the Confirm Button" on the AlertDialog page.
|
|
393
|
+
* Don't add a separate spinner and leave the buttons active.
|
|
394
|
+
* @module
|
|
395
|
+
*/
|
|
396
|
+
import { Button, Spinner, style } from '@tempoxyz/ds'
|
|
397
|
+
|
|
398
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
399
|
+
export function Demo() {
|
|
400
|
+
return (
|
|
401
|
+
<div {...styles.popup()}>
|
|
402
|
+
<span {...styles.title()}>Revoke this API key?</span>
|
|
403
|
+
<p {...styles.description()}>
|
|
404
|
+
Apps that use the Production server key stop working immediately. You can’t undo this.
|
|
405
|
+
</p>
|
|
406
|
+
<div {...styles.actions()}>
|
|
407
|
+
<Spinner aria-label="Revoking key" />
|
|
408
|
+
<Button size="small" variant="secondary">
|
|
409
|
+
Cancel
|
|
410
|
+
</Button>
|
|
411
|
+
<Button size="small">Revoke key</Button>
|
|
412
|
+
</div>
|
|
413
|
+
</div>
|
|
414
|
+
)
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
namespace styles {
|
|
418
|
+
export const actions = style({
|
|
419
|
+
alignItems: 'center',
|
|
420
|
+
columnGap: '8',
|
|
421
|
+
display: 'flex',
|
|
422
|
+
justifyContent: 'flex-end',
|
|
423
|
+
marginTop: '16',
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
export const description = style({
|
|
427
|
+
color: 'content.secondary',
|
|
428
|
+
margin: '0 !custom',
|
|
429
|
+
typography: 'body.b2',
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
export const popup = style({
|
|
433
|
+
backgroundColor: 'background.elevated',
|
|
434
|
+
borderRadius: 'sm',
|
|
435
|
+
boxShadow: 'regular',
|
|
436
|
+
boxSizing: 'border-box',
|
|
437
|
+
display: 'flex',
|
|
438
|
+
flexDirection: 'column',
|
|
439
|
+
padding: '24',
|
|
440
|
+
rowGap: '8',
|
|
441
|
+
width: '17rem !custom',
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
export const title = style({ color: 'content.primary', typography: 'heading.h3' })
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
## Content
|
|
449
|
+
|
|
450
|
+
### Ask a Specific Question
|
|
451
|
+
|
|
452
|
+
Write the title as one question that names the action and its object, such as Revoke this API key?
|
|
453
|
+
|
|
454
|
+
### State the Consequence
|
|
455
|
+
|
|
456
|
+
Always include an `AlertDialog.Description`. Say what stops working, then whether it can be recovered, without repeating the title.
|
|
457
|
+
|
|
458
|
+
### Repeat the Action Verb on the Confirm Button
|
|
459
|
+
|
|
460
|
+
Label the confirm button with the verb from the trigger and title, such as Revoke key after Revoke this API key?
|
|
461
|
+
|
|
462
|
+
**Do:** Repeat the action's verb on the confirm button, such as Revoke key.
|
|
463
|
+
|
|
464
|
+
```tsx
|
|
465
|
+
/** Do example for "Always Offer Cancel" on the AlertDialog page: pair the confirm button with Cancel. @module */
|
|
466
|
+
import { Button, style } from '@tempoxyz/ds'
|
|
467
|
+
|
|
468
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
469
|
+
export function Demo() {
|
|
470
|
+
return (
|
|
471
|
+
<div {...styles.popup()}>
|
|
472
|
+
<span {...styles.title()}>Revoke this API key?</span>
|
|
473
|
+
<p {...styles.description()}>
|
|
474
|
+
Apps that use the Production server key stop working immediately. You can’t undo this.
|
|
475
|
+
</p>
|
|
476
|
+
<div {...styles.actions()}>
|
|
477
|
+
<Button size="small" variant="secondary">
|
|
478
|
+
Cancel
|
|
479
|
+
</Button>
|
|
480
|
+
<Button size="small">Revoke key</Button>
|
|
481
|
+
</div>
|
|
482
|
+
</div>
|
|
483
|
+
)
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
namespace styles {
|
|
487
|
+
export const actions = style({
|
|
488
|
+
columnGap: '8',
|
|
489
|
+
display: 'flex',
|
|
490
|
+
justifyContent: 'flex-end',
|
|
491
|
+
marginTop: '16',
|
|
492
|
+
})
|
|
493
|
+
|
|
494
|
+
export const description = style({
|
|
495
|
+
color: 'content.secondary',
|
|
496
|
+
margin: '0 !custom',
|
|
497
|
+
typography: 'body.b2',
|
|
498
|
+
})
|
|
499
|
+
|
|
500
|
+
export const popup = style({
|
|
501
|
+
backgroundColor: 'background.elevated',
|
|
502
|
+
borderRadius: 'sm',
|
|
503
|
+
boxShadow: 'regular',
|
|
504
|
+
boxSizing: 'border-box',
|
|
505
|
+
display: 'flex',
|
|
506
|
+
flexDirection: 'column',
|
|
507
|
+
padding: '24',
|
|
508
|
+
rowGap: '8',
|
|
509
|
+
width: '17rem !custom',
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
export const title = style({ color: 'content.primary', typography: 'heading.h3' })
|
|
513
|
+
}
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
**Don't:** Ask Are you sure? or label the confirm button OK.
|
|
517
|
+
|
|
518
|
+
```tsx
|
|
519
|
+
/**
|
|
520
|
+
* Don't example for "Repeat the Action Verb on the Confirm Button" on the AlertDialog page.
|
|
521
|
+
* Don't ask Are you sure? or label the confirm button OK.
|
|
522
|
+
* @module
|
|
523
|
+
*/
|
|
524
|
+
import { Button, style } from '@tempoxyz/ds'
|
|
525
|
+
|
|
526
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
527
|
+
export function Demo() {
|
|
528
|
+
return (
|
|
529
|
+
<div {...styles.popup()}>
|
|
530
|
+
<span {...styles.title()}>Are you sure?</span>
|
|
531
|
+
<p {...styles.description()}>This action cannot be undone.</p>
|
|
532
|
+
<div {...styles.actions()}>
|
|
533
|
+
<Button size="small" variant="secondary">
|
|
534
|
+
Cancel
|
|
535
|
+
</Button>
|
|
536
|
+
<Button size="small">OK</Button>
|
|
537
|
+
</div>
|
|
538
|
+
</div>
|
|
539
|
+
)
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
namespace styles {
|
|
543
|
+
export const actions = style({
|
|
544
|
+
columnGap: '8',
|
|
545
|
+
display: 'flex',
|
|
546
|
+
justifyContent: 'flex-end',
|
|
547
|
+
marginTop: '16',
|
|
548
|
+
})
|
|
549
|
+
|
|
550
|
+
export const description = style({
|
|
551
|
+
color: 'content.secondary',
|
|
552
|
+
margin: '0 !custom',
|
|
553
|
+
typography: 'body.b2',
|
|
554
|
+
})
|
|
555
|
+
|
|
556
|
+
export const popup = style({
|
|
557
|
+
backgroundColor: 'background.elevated',
|
|
558
|
+
borderRadius: 'sm',
|
|
559
|
+
boxShadow: 'regular',
|
|
560
|
+
boxSizing: 'border-box',
|
|
561
|
+
display: 'flex',
|
|
562
|
+
flexDirection: 'column',
|
|
563
|
+
padding: '24',
|
|
564
|
+
rowGap: '8',
|
|
565
|
+
width: '17rem !custom',
|
|
566
|
+
})
|
|
567
|
+
|
|
568
|
+
export const title = style({ color: 'content.primary', typography: 'heading.h3' })
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Avoid Two Cancels
|
|
573
|
+
|
|
574
|
+
If the action cancels something, such as a scheduled payment, label the pair Keep payment and Cancel payment. A plain Cancel beside Cancel payment is ambiguous.
|
|
575
|
+
|
|
576
|
+
## Accessibility
|
|
577
|
+
|
|
578
|
+
Follows the [WAI-ARIA alert dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/).
|
|
579
|
+
|
|
580
|
+
### Semantics
|
|
581
|
+
|
|
582
|
+
* **AlertDialog.Trigger (button):** Announces the dialog and whether it is open.
|
|
583
|
+
* **AlertDialog.Popup (alertdialog):** The dialog is always modal.
|
|
584
|
+
* **AlertDialog.Title (h2):** Names the popup. Include it in every alert dialog.
|
|
585
|
+
* **AlertDialog.Description (aria-describedby):** Describes the popup. Include it in every alert dialog.
|
|
586
|
+
* **Page Behind (inert):** The page behind ignores input and stops scrolling.
|
|
587
|
+
* **Reduced Motion (prefers-reduced-motion):** The dialog fades in and out without scaling or sliding.
|
|
588
|
+
|
|
589
|
+
### Keyboard
|
|
590
|
+
|
|
591
|
+
* **Open or Activate (Enter or Space):** Opens the dialog from the trigger, and activates the focused action.
|
|
592
|
+
* **Move to the Next Action (Tab):** Moves focus to the next action, wrapping from the last to the first.
|
|
593
|
+
* **Move to the Previous Action (Shift+Tab):** Moves focus to the previous action, wrapping from the first to the last.
|
|
594
|
+
* **Close the Alert Dialog (Escape):** Closes the dialog and returns focus to the trigger that opened it.
|
|
595
|
+
|
|
596
|
+
### Focus
|
|
597
|
+
|
|
598
|
+
* **Opening:** Focuses the first tabbable element, or the popup on touch. Pass `initialFocus` to start on Cancel.
|
|
599
|
+
* **Trapping:** Focus stays inside the popup while it is open, and Tab never leaves it.
|
|
600
|
+
* **Outside Press:** Does not close the popup. Only Escape, `closeButton` or `AlertDialog.Close` closes it.
|
|
601
|
+
* **Closing:** Focus returns to the trigger. Pass `finalFocus` when the trigger is gone, such as after deleting its row.
|
|
602
|
+
|
|
603
|
+
### Your Responsibilities
|
|
604
|
+
|
|
605
|
+
* **Render a Title and Description:** Always render both in `AlertDialog.Header`. Without them, the popup has no name or description.
|
|
606
|
+
|
|
607
|
+
## Related
|
|
608
|
+
|
|
609
|
+
[Dialog](/docs/components/dialog)
|
|
610
|
+
|
|
611
|
+
Use for focused tasks with fields.
|
|
612
|
+
|
|
613
|
+
[Button](/docs/components/button)
|
|
614
|
+
|
|
615
|
+
Use for each action in the footer.
|
|
616
|
+
|
|
617
|
+
[ButtonGroup](/docs/components/button-group)
|
|
618
|
+
|
|
619
|
+
Use for the Cancel and confirm actions.
|
|
620
|
+
|
|
621
|
+
[Menu](/docs/components/menu)
|
|
622
|
+
|
|
623
|
+
Use for opening a confirmation from a destructive item.
|
|
624
|
+
|
|
625
|
+
[Toast](/docs/components/toast)
|
|
626
|
+
|
|
627
|
+
Use for Undo after reversible actions.
|
|
628
|
+
|
|
629
|
+
[Destructive Actions](/docs/patterns/destructive-actions)
|
|
630
|
+
|
|
631
|
+
Covers deleting and revoking.
|