@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.
- package/README.md +7 -6
- package/dist/docs/AGENTS.md +12 -0
- package/dist/docs/index.md +145 -0
- package/dist/docs/marketing/introduction/getting-started.md +241 -0
- package/dist/docs/product/components/accordion.md +489 -0
- package/dist/docs/product/components/address-card.md +147 -0
- package/dist/docs/product/components/agent-logo.md +194 -0
- package/dist/docs/product/components/alert-dialog.md +631 -0
- package/dist/docs/product/components/alert.md +448 -0
- package/dist/docs/product/components/amount-input.md +305 -0
- package/dist/docs/product/components/amount.md +794 -0
- package/dist/docs/product/components/app-shell.md +559 -0
- package/dist/docs/product/components/asset-chip.md +294 -0
- package/dist/docs/product/components/autocomplete.md +620 -0
- package/dist/docs/product/components/avatar.md +321 -0
- package/dist/docs/product/components/badge.md +339 -0
- package/dist/docs/product/components/badged-logo.md +116 -0
- package/dist/docs/product/components/banner.md +379 -0
- package/dist/docs/product/components/bar-chart.md +208 -0
- package/dist/docs/product/components/breadcrumbs.md +380 -0
- package/dist/docs/product/components/button-group.md +286 -0
- package/dist/docs/product/components/button.md +650 -0
- package/dist/docs/product/components/calendar.md +375 -0
- package/dist/docs/product/components/callout.md +96 -0
- package/dist/docs/product/components/checkbox-group.md +521 -0
- package/dist/docs/product/components/checkbox.md +467 -0
- package/dist/docs/product/components/choice-group.md +516 -0
- package/dist/docs/product/components/choicebox.md +641 -0
- package/dist/docs/product/components/code.md +100 -0
- package/dist/docs/product/components/combobox.md +939 -0
- package/dist/docs/product/components/container.md +257 -0
- package/dist/docs/product/components/copy-button.md +642 -0
- package/dist/docs/product/components/date-picker.md +514 -0
- package/dist/docs/product/components/dialog.md +1332 -0
- package/dist/docs/product/components/drawer.md +966 -0
- package/dist/docs/product/components/empty.md +340 -0
- package/dist/docs/product/components/field.md +570 -0
- package/dist/docs/product/components/fieldset.md +398 -0
- package/dist/docs/product/components/frame.md +434 -0
- package/dist/docs/product/components/gauge.md +299 -0
- package/dist/docs/product/components/get-started-visual.md +117 -0
- package/dist/docs/product/components/grid.md +288 -0
- package/dist/docs/product/components/hero-visual.md +155 -0
- package/dist/docs/product/components/hex.md +487 -0
- package/dist/docs/product/components/icon-tile.md +292 -0
- package/dist/docs/product/components/identicon.md +371 -0
- package/dist/docs/product/components/inline.md +233 -0
- package/dist/docs/product/components/inset.md +225 -0
- package/dist/docs/product/components/kbd.md +423 -0
- package/dist/docs/product/components/list-group.md +981 -0
- package/dist/docs/product/components/loading-dots.md +237 -0
- package/dist/docs/product/components/menu.md +934 -0
- package/dist/docs/product/components/native-select.md +204 -0
- package/dist/docs/product/components/network-logo.md +248 -0
- package/dist/docs/product/components/number-field.md +543 -0
- package/dist/docs/product/components/otp-field.md +616 -0
- package/dist/docs/product/components/pagination.md +516 -0
- package/dist/docs/product/components/popover.md +544 -0
- package/dist/docs/product/components/progress.md +388 -0
- package/dist/docs/product/components/qr.md +314 -0
- package/dist/docs/product/components/radio-group.md +528 -0
- package/dist/docs/product/components/secret-value.md +406 -0
- package/dist/docs/product/components/select.md +751 -0
- package/dist/docs/product/components/separator.md +379 -0
- package/dist/docs/product/components/sidebar-menu.md +922 -0
- package/dist/docs/product/components/skeleton.md +517 -0
- package/dist/docs/product/components/slider.md +539 -0
- package/dist/docs/product/components/snippet.md +424 -0
- package/dist/docs/product/components/spinner.md +216 -0
- package/dist/docs/product/components/split-bar.md +139 -0
- package/dist/docs/product/components/split-button.md +464 -0
- package/dist/docs/product/components/stack.md +299 -0
- package/dist/docs/product/components/status-chip.md +226 -0
- package/dist/docs/product/components/status-indicator.md +119 -0
- package/dist/docs/product/components/status-row.md +174 -0
- package/dist/docs/product/components/stepper.md +451 -0
- package/dist/docs/product/components/success-hero.md +157 -0
- package/dist/docs/product/components/surface.md +639 -0
- package/dist/docs/product/components/switch.md +472 -0
- package/dist/docs/product/components/table.md +967 -0
- package/dist/docs/product/components/tabs.md +627 -0
- package/dist/docs/product/components/tempo-logo.md +185 -0
- package/dist/docs/product/components/text-input.md +624 -0
- package/dist/docs/product/components/textarea.md +352 -0
- package/dist/docs/product/components/toast.md +535 -0
- package/dist/docs/product/components/token-logo.md +371 -0
- package/dist/docs/product/components/token.md +247 -0
- package/dist/docs/product/components/tooltip.md +490 -0
- package/dist/docs/product/components/verification-code.md +116 -0
- package/dist/docs/product/components/visual.md +249 -0
- package/dist/docs/product/components.md +203 -0
- package/dist/docs/product/foundations/accessibility.md +377 -0
- package/dist/docs/product/foundations/agents.md +150 -0
- package/dist/docs/product/foundations/color.md +522 -0
- package/dist/docs/product/foundations/content/tone.md +194 -0
- package/dist/docs/product/foundations/content/voice.md +194 -0
- package/dist/docs/product/foundations/content/writing-style.md +406 -0
- package/dist/docs/product/foundations/iconography.md +282 -0
- package/dist/docs/product/foundations/intent.md +360 -0
- package/dist/docs/product/foundations/layout.md +508 -0
- package/dist/docs/product/foundations/linter.md +496 -0
- package/dist/docs/product/foundations/motion.md +151 -0
- package/dist/docs/product/foundations/radius-and-padding.md +86 -0
- package/dist/docs/product/foundations/typography.md +266 -0
- package/dist/docs/product/introduction/faq.md +133 -0
- package/dist/docs/product/introduction/getting-started.md +377 -0
- package/dist/docs/product/patterns/blockchain-values.md +709 -0
- package/dist/docs/product/patterns/dashboards.md +638 -0
- package/dist/docs/product/patterns/destructive-actions.md +626 -0
- package/dist/docs/product/patterns/empty-states.md +612 -0
- package/dist/docs/product/patterns/errors-and-validation.md +808 -0
- package/dist/docs/product/patterns/feedback-and-status.md +518 -0
- package/dist/docs/product/patterns/forms.md +679 -0
- package/dist/docs/product/patterns/loading.md +630 -0
- package/dist/docs/product/patterns/navigation.md +397 -0
- package/dist/docs/product/patterns/payments.md +765 -0
- package/dist/docs/product/patterns/responsive-layout.md +997 -0
- package/dist/docs/product/patterns/tables-and-lists.md +964 -0
- package/dist/docs/product/products/tempo-console.md +671 -0
- package/dist/docs/product/products/tempo-performance.md +437 -0
- package/dist/docs/product/products/tempo-wallet.md +438 -0
- package/dist/marketing/index.d.ts +4 -0
- package/dist/marketing/index.d.ts.map +1 -0
- package/dist/marketing/index.js +4 -0
- package/dist/marketing/index.js.map +1 -0
- package/dist/marketing/index.js.zyzz.json +1 -0
- package/dist/marketing/vars.d.ts +907 -0
- package/dist/marketing/vars.d.ts.map +1 -0
- package/dist/marketing/vars.js +15 -0
- package/dist/marketing/vars.js.map +1 -0
- package/dist/marketing/vars.js.zyzz.json +1 -0
- package/dist/marketing/zyzz.config.d.ts +4512 -0
- package/dist/marketing/zyzz.config.d.ts.map +1 -0
- package/dist/marketing/zyzz.config.js +63 -0
- package/dist/marketing/zyzz.config.js.map +1 -0
- package/dist/marketing/zyzz.config.js.zyzz.json +1 -0
- package/dist/oxlint/index.d.ts +12 -1
- package/dist/oxlint/index.d.ts.map +1 -1
- package/dist/oxlint/index.js +39 -1
- package/dist/oxlint/index.js.map +1 -1
- package/dist/oxlint/internal/Docs.d.ts +9 -0
- package/dist/oxlint/internal/Docs.d.ts.map +1 -0
- package/dist/oxlint/internal/Docs.js +15 -0
- package/dist/oxlint/internal/Docs.js.map +1 -0
- package/dist/oxlint/internal/Imports.d.ts +1 -1
- package/dist/oxlint/internal/Imports.d.ts.map +1 -1
- package/dist/oxlint/internal/Imports.js +2 -0
- package/dist/oxlint/internal/Imports.js.map +1 -1
- package/dist/oxlint/internal/Styles.d.ts +40 -0
- package/dist/oxlint/internal/Styles.d.ts.map +1 -0
- package/dist/oxlint/internal/Styles.js +194 -0
- package/dist/oxlint/internal/Styles.js.map +1 -0
- package/dist/oxlint/internal/Tokens.d.ts +16 -0
- package/dist/oxlint/internal/Tokens.d.ts.map +1 -0
- package/dist/oxlint/internal/Tokens.js +39 -0
- package/dist/oxlint/internal/Tokens.js.map +1 -0
- package/dist/oxlint/rules/NoCrossSurface.d.ts +2 -2
- package/dist/oxlint/rules/NoCrossSurface.js +3 -3
- package/dist/oxlint/rules/NoCrossSurface.js.map +1 -1
- package/dist/oxlint/rules/NoCustomValues.d.ts +11 -0
- package/dist/oxlint/rules/NoCustomValues.d.ts.map +1 -0
- package/dist/oxlint/rules/NoCustomValues.js +150 -0
- package/dist/oxlint/rules/NoCustomValues.js.map +1 -0
- package/dist/oxlint/rules/NoSingleKeyShortcuts.d.ts +11 -0
- package/dist/oxlint/rules/NoSingleKeyShortcuts.d.ts.map +1 -0
- package/dist/oxlint/rules/NoSingleKeyShortcuts.js +158 -0
- package/dist/oxlint/rules/NoSingleKeyShortcuts.js.map +1 -0
- package/dist/oxlint/rules/PreferComponent.d.ts +3 -2
- package/dist/oxlint/rules/PreferComponent.d.ts.map +1 -1
- package/dist/oxlint/rules/PreferComponent.js +11 -4
- package/dist/oxlint/rules/PreferComponent.js.map +1 -1
- package/dist/oxlint/rules/PreferLayout.d.ts +9 -0
- package/dist/oxlint/rules/PreferLayout.d.ts.map +1 -0
- package/dist/oxlint/rules/PreferLayout.js +90 -0
- package/dist/oxlint/rules/PreferLayout.js.map +1 -0
- package/dist/oxlint/rules/PreferProgress.d.ts +9 -0
- package/dist/oxlint/rules/PreferProgress.d.ts.map +1 -0
- package/dist/oxlint/rules/PreferProgress.js +43 -0
- package/dist/oxlint/rules/PreferProgress.js.map +1 -0
- package/dist/oxlint/rules/PreferSurface.d.ts +9 -0
- package/dist/oxlint/rules/PreferSurface.d.ts.map +1 -0
- package/dist/oxlint/rules/PreferSurface.js +55 -0
- package/dist/oxlint/rules/PreferSurface.js.map +1 -0
- package/dist/oxlint/rules/RequireAccessibleName.d.ts.map +1 -1
- package/dist/oxlint/rules/RequireAccessibleName.js +3 -1
- package/dist/oxlint/rules/RequireAccessibleName.js.map +1 -1
- package/dist/oxlint/rules/RequireScrollRegion.d.ts +11 -0
- package/dist/oxlint/rules/RequireScrollRegion.d.ts.map +1 -0
- package/dist/oxlint/rules/RequireScrollRegion.js +71 -0
- package/dist/oxlint/rules/RequireScrollRegion.js.map +1 -0
- package/dist/web/icons/index.js.zyzz.json +1 -0
- package/package.json +6 -1
- package/src/marketing/README.md +21 -0
- package/src/marketing/index.ts +3 -0
- package/src/marketing/vars.ts +751 -0
- package/src/marketing/zyzz.config.ts +376 -0
- package/src/oxlint/index.ts +40 -1
- package/src/oxlint/internal/Docs.ts +18 -0
- package/src/oxlint/internal/Imports.ts +2 -1
- package/src/oxlint/internal/Styles.ts +240 -0
- package/src/oxlint/internal/Tokens.ts +43 -0
- package/src/oxlint/rules/NoCrossSurface.ts +3 -3
- package/src/oxlint/rules/NoCustomValues.ts +170 -0
- package/src/oxlint/rules/NoSingleKeyShortcuts.ts +190 -0
- package/src/oxlint/rules/PreferComponent.ts +11 -4
- package/src/oxlint/rules/PreferLayout.ts +96 -0
- package/src/oxlint/rules/PreferProgress.ts +49 -0
- package/src/oxlint/rules/PreferSurface.ts +70 -0
- package/src/oxlint/rules/RequireAccessibleName.ts +3 -1
- package/src/oxlint/rules/RequireScrollRegion.ts +92 -0
|
@@ -0,0 +1,642 @@
|
|
|
1
|
+
# CopyButton
|
|
2
|
+
|
|
3
|
+
Copies a value to the clipboard and confirms the copy.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/CopyButton.tsx)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
A copy button is an icon-only button that writes a value to the clipboard and confirms the copy for two seconds.
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Basic
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { CopyButton } from '@tempoxyz/ds'
|
|
17
|
+
|
|
18
|
+
export function Demo() {
|
|
19
|
+
return <CopyButton value="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" />
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/CopyButton/Basic.tsx)
|
|
24
|
+
|
|
25
|
+
### Size
|
|
26
|
+
|
|
27
|
+
Set `size` to `small` (default), `medium`, or `large`.
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
31
|
+
|
|
32
|
+
const address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
|
|
33
|
+
|
|
34
|
+
export function Demo() {
|
|
35
|
+
return (
|
|
36
|
+
<div {...styles.row()}>
|
|
37
|
+
{(['small', 'medium', 'large'] as const).map((size) => (
|
|
38
|
+
<CopyButton key={size} size={size} value={address} />
|
|
39
|
+
))}
|
|
40
|
+
</div>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
namespace styles {
|
|
45
|
+
export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '12' })
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/CopyButton/Size.tsx)
|
|
50
|
+
|
|
51
|
+
### Variant
|
|
52
|
+
|
|
53
|
+
Set `variant` to any [Button](button.md) variant, such as `tertiary` (default) or `secondary`.
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
57
|
+
|
|
58
|
+
const address = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
|
|
59
|
+
|
|
60
|
+
export function Demo() {
|
|
61
|
+
return (
|
|
62
|
+
<div {...styles.row()}>
|
|
63
|
+
<CopyButton value={address} />
|
|
64
|
+
<CopyButton value={address} variant="secondary" />
|
|
65
|
+
<CopyButton size="medium" value={address} variant="secondary" />
|
|
66
|
+
</div>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
namespace styles {
|
|
71
|
+
export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '12' })
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/CopyButton/Variant.tsx)
|
|
76
|
+
|
|
77
|
+
### Disabled
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
import { CopyButton } from '@tempoxyz/ds'
|
|
81
|
+
|
|
82
|
+
export function Demo() {
|
|
83
|
+
return <CopyButton disabled value="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" />
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/CopyButton/Disabled.tsx)
|
|
88
|
+
|
|
89
|
+
## Anatomy
|
|
90
|
+
|
|
91
|
+
Import the component and assemble its parts.
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import { CopyButton } from '@tempoxyz/ds'
|
|
95
|
+
|
|
96
|
+
<CopyButton />
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Guidelines
|
|
100
|
+
|
|
101
|
+
### When to Use
|
|
102
|
+
|
|
103
|
+
* Copy a value you'd otherwise select by hand, such as a webhook ID or an invite link.
|
|
104
|
+
* Add copying beside a value in your own layout, such as a table cell.
|
|
105
|
+
|
|
106
|
+
### When Not to Use
|
|
107
|
+
|
|
108
|
+
* Use [Hex](hex.md) with `copy` for addresses and transaction hashes. It truncates the middle and adds this button.
|
|
109
|
+
* Use [Snippet](snippet.md) for a command or code value.
|
|
110
|
+
* Use [SecretValue](secret-value.md) for API keys and other secrets that stay hidden until revealed.
|
|
111
|
+
* Use a [Button](button.md) for other actions, such as Share or Download.
|
|
112
|
+
|
|
113
|
+
### Place It Right After the Value
|
|
114
|
+
|
|
115
|
+
Put the button on the same line, immediately after the value. Give each value its own button.
|
|
116
|
+
|
|
117
|
+
**Do:** Place a copy button directly after each value.
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
/**
|
|
121
|
+
* Do example for "Place It Right After the Value" on the CopyButton page.
|
|
122
|
+
* Place a copy button directly after each value.
|
|
123
|
+
* @module
|
|
124
|
+
*/
|
|
125
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
126
|
+
|
|
127
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
128
|
+
export function Demo() {
|
|
129
|
+
return (
|
|
130
|
+
<div {...styles.rows()}>
|
|
131
|
+
<div {...styles.row()}>
|
|
132
|
+
<span {...styles.label()}>Webhook ID</span>
|
|
133
|
+
<span {...styles.value()}>
|
|
134
|
+
wh_51c8e20d
|
|
135
|
+
<CopyButton aria-label="Copy webhook ID" value="wh_51c8e20d" />
|
|
136
|
+
</span>
|
|
137
|
+
</div>
|
|
138
|
+
<div {...styles.row()}>
|
|
139
|
+
<span {...styles.label()}>Key ID</span>
|
|
140
|
+
<span {...styles.value()}>
|
|
141
|
+
key_9f2c41a7
|
|
142
|
+
<CopyButton aria-label="Copy key ID" value="key_9f2c41a7" />
|
|
143
|
+
</span>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
namespace styles {
|
|
150
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
151
|
+
|
|
152
|
+
export const row = style({
|
|
153
|
+
alignItems: 'center',
|
|
154
|
+
display: 'flex',
|
|
155
|
+
justifyContent: 'space-between',
|
|
156
|
+
minHeight: '32',
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
export const rows = style({
|
|
160
|
+
display: 'flex',
|
|
161
|
+
flexDirection: 'column',
|
|
162
|
+
rowGap: '8',
|
|
163
|
+
width: '16rem !custom',
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
export const value = style({
|
|
167
|
+
alignItems: 'center',
|
|
168
|
+
color: 'content.primary',
|
|
169
|
+
columnGap: '4',
|
|
170
|
+
display: 'flex',
|
|
171
|
+
typography: 'mono.m1',
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Don't:** Place one copy button away from the values, where its target is unclear.
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
/**
|
|
180
|
+
* Don't example for "Place It Right After the Value" on the CopyButton page.
|
|
181
|
+
* Don't place one copy button away from the values, where its target is unclear.
|
|
182
|
+
* @module
|
|
183
|
+
*/
|
|
184
|
+
import { CopyButton, 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.rows()}>
|
|
190
|
+
<div {...styles.header()}>
|
|
191
|
+
<span {...styles.title()}>Webhook</span>
|
|
192
|
+
<CopyButton aria-label="Copy" value="wh_51c8e20d" />
|
|
193
|
+
</div>
|
|
194
|
+
<div {...styles.row()}>
|
|
195
|
+
<span {...styles.label()}>Webhook ID</span>
|
|
196
|
+
<span {...styles.value()}>wh_51c8e20d</span>
|
|
197
|
+
</div>
|
|
198
|
+
<div {...styles.row()}>
|
|
199
|
+
<span {...styles.label()}>Key ID</span>
|
|
200
|
+
<span {...styles.value()}>key_9f2c41a7</span>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
namespace styles {
|
|
207
|
+
export const header = style({
|
|
208
|
+
alignItems: 'center',
|
|
209
|
+
display: 'flex',
|
|
210
|
+
justifyContent: 'space-between',
|
|
211
|
+
marginBottom: '4',
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
215
|
+
|
|
216
|
+
export const row = style({
|
|
217
|
+
alignItems: 'center',
|
|
218
|
+
display: 'flex',
|
|
219
|
+
justifyContent: 'space-between',
|
|
220
|
+
minHeight: '32',
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
export const rows = style({
|
|
224
|
+
display: 'flex',
|
|
225
|
+
flexDirection: 'column',
|
|
226
|
+
rowGap: '8',
|
|
227
|
+
width: '16rem !custom',
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
export const title = style({ color: 'content.primary', typography: 'body.b1Strong' })
|
|
231
|
+
|
|
232
|
+
export const value = style({ color: 'content.primary', typography: 'mono.m1' })
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Copy the Full Value
|
|
237
|
+
|
|
238
|
+
Pass the complete value to `value`, even when the screen shows a shortened form.
|
|
239
|
+
|
|
240
|
+
**Do:** Copy the complete value behind a shortened display.
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
/**
|
|
244
|
+
* Do example for "Copy the Full Value" on the CopyButton page.
|
|
245
|
+
* Copy the complete value behind a shortened display.
|
|
246
|
+
* @module
|
|
247
|
+
*/
|
|
248
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
249
|
+
|
|
250
|
+
const url = 'https://hooks.tempo.xyz/v1/payments/wh_51c8e20d'
|
|
251
|
+
|
|
252
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
253
|
+
export function Demo() {
|
|
254
|
+
return (
|
|
255
|
+
<div {...styles.stack()}>
|
|
256
|
+
<span {...styles.value()}>
|
|
257
|
+
hooks.tempo.xyz/…/wh_51c8e20d
|
|
258
|
+
<CopyButton aria-label="Copy webhook URL" copied value={url} />
|
|
259
|
+
</span>
|
|
260
|
+
<div {...styles.clipboard()}>
|
|
261
|
+
<span {...styles.label()}>Clipboard</span>
|
|
262
|
+
<span {...styles.copied()}>{url}</span>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
namespace styles {
|
|
269
|
+
export const clipboard = style({
|
|
270
|
+
backgroundColor: 'container.regular',
|
|
271
|
+
borderRadius: '2xs',
|
|
272
|
+
display: 'flex',
|
|
273
|
+
flexDirection: 'column',
|
|
274
|
+
paddingBlock: '8',
|
|
275
|
+
paddingInline: '12',
|
|
276
|
+
rowGap: '2px !custom',
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
export const copied = style({ color: 'content.primary', typography: 'mono.m1' })
|
|
280
|
+
|
|
281
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
282
|
+
|
|
283
|
+
export const stack = style({
|
|
284
|
+
display: 'flex',
|
|
285
|
+
flexDirection: 'column',
|
|
286
|
+
rowGap: '8',
|
|
287
|
+
width: '17rem !custom',
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
export const value = style({
|
|
291
|
+
alignItems: 'center',
|
|
292
|
+
color: 'content.primary',
|
|
293
|
+
columnGap: '4',
|
|
294
|
+
display: 'flex',
|
|
295
|
+
typography: 'mono.m1',
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Don't:** Copy the shortened text that the screen shows.
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
/**
|
|
304
|
+
* Don't example for "Copy the Full Value" on the CopyButton page.
|
|
305
|
+
* Don't copy the shortened text that the screen shows.
|
|
306
|
+
* @module
|
|
307
|
+
*/
|
|
308
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
309
|
+
|
|
310
|
+
const display = 'hooks.tempo.xyz/…/wh_51c8e20d'
|
|
311
|
+
|
|
312
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
313
|
+
export function Demo() {
|
|
314
|
+
return (
|
|
315
|
+
<div {...styles.stack()}>
|
|
316
|
+
<span {...styles.value()}>
|
|
317
|
+
{display}
|
|
318
|
+
<CopyButton aria-label="Copy webhook URL" copied value={display} />
|
|
319
|
+
</span>
|
|
320
|
+
<div {...styles.clipboard()}>
|
|
321
|
+
<span {...styles.label()}>Clipboard</span>
|
|
322
|
+
<span {...styles.copied()}>{display}</span>
|
|
323
|
+
</div>
|
|
324
|
+
</div>
|
|
325
|
+
)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
namespace styles {
|
|
329
|
+
export const clipboard = style({
|
|
330
|
+
backgroundColor: 'container.regular',
|
|
331
|
+
borderRadius: '2xs',
|
|
332
|
+
display: 'flex',
|
|
333
|
+
flexDirection: 'column',
|
|
334
|
+
paddingBlock: '8',
|
|
335
|
+
paddingInline: '12',
|
|
336
|
+
rowGap: '2px !custom',
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
export const copied = style({ color: 'content.primary', typography: 'mono.m1' })
|
|
340
|
+
|
|
341
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
342
|
+
|
|
343
|
+
export const stack = style({
|
|
344
|
+
display: 'flex',
|
|
345
|
+
flexDirection: 'column',
|
|
346
|
+
rowGap: '8',
|
|
347
|
+
width: '17rem !custom',
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
export const value = style({
|
|
351
|
+
alignItems: 'center',
|
|
352
|
+
color: 'content.primary',
|
|
353
|
+
columnGap: '4',
|
|
354
|
+
display: 'flex',
|
|
355
|
+
typography: 'mono.m1',
|
|
356
|
+
})
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Keep the Built-In Confirmation
|
|
361
|
+
|
|
362
|
+
After a copy, the icon turns into a check for two seconds and screen readers announce Copied. If the clipboard refuses the write, the button shows no confirmation and doesn't call `onCopy`, so keep the value selectable as text.
|
|
363
|
+
|
|
364
|
+
**Do:** Let the check icon confirm the copy.
|
|
365
|
+
|
|
366
|
+
```tsx
|
|
367
|
+
/**
|
|
368
|
+
* Do example for "Keep the Built-In Confirmation" on the CopyButton page.
|
|
369
|
+
* Let the check icon confirm the copy.
|
|
370
|
+
* @module
|
|
371
|
+
*/
|
|
372
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
373
|
+
|
|
374
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
375
|
+
export function Demo() {
|
|
376
|
+
return (
|
|
377
|
+
<div {...styles.stack()}>
|
|
378
|
+
<div {...styles.row()}>
|
|
379
|
+
<span {...styles.label()}>Webhook ID</span>
|
|
380
|
+
<span {...styles.value()}>
|
|
381
|
+
wh_51c8e20d
|
|
382
|
+
<CopyButton aria-label="Copy webhook ID" copied value="wh_51c8e20d" />
|
|
383
|
+
</span>
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
namespace styles {
|
|
390
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
391
|
+
|
|
392
|
+
export const row = style({
|
|
393
|
+
alignItems: 'center',
|
|
394
|
+
display: 'flex',
|
|
395
|
+
justifyContent: 'space-between',
|
|
396
|
+
minHeight: '32',
|
|
397
|
+
})
|
|
398
|
+
|
|
399
|
+
export const stack = style({
|
|
400
|
+
display: 'flex',
|
|
401
|
+
flexDirection: 'column',
|
|
402
|
+
rowGap: '16',
|
|
403
|
+
width: '16rem !custom',
|
|
404
|
+
})
|
|
405
|
+
|
|
406
|
+
export const value = style({
|
|
407
|
+
alignItems: 'center',
|
|
408
|
+
color: 'content.primary',
|
|
409
|
+
columnGap: '4',
|
|
410
|
+
display: 'flex',
|
|
411
|
+
typography: 'mono.m1',
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Don't:** Add a [Toast](toast.md) or text such as Copied to clipboard.
|
|
417
|
+
|
|
418
|
+
```tsx
|
|
419
|
+
/**
|
|
420
|
+
* Don't example for "Keep the Built-In Confirmation" on the CopyButton page.
|
|
421
|
+
* Don't add a Toast or text such as Copied to clipboard.
|
|
422
|
+
* @module
|
|
423
|
+
*/
|
|
424
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
425
|
+
import { CheckCircle } from '@tempoxyz/ds/icons'
|
|
426
|
+
|
|
427
|
+
// Toasts render in a portal, so this preview draws one in place with the toast's styles.
|
|
428
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
429
|
+
export function Demo() {
|
|
430
|
+
return (
|
|
431
|
+
<div {...styles.stack()}>
|
|
432
|
+
<div {...styles.row()}>
|
|
433
|
+
<span {...styles.label()}>Webhook ID</span>
|
|
434
|
+
<span {...styles.value()}>
|
|
435
|
+
wh_51c8e20d
|
|
436
|
+
<CopyButton aria-label="Copy webhook ID" copied value="wh_51c8e20d" />
|
|
437
|
+
</span>
|
|
438
|
+
</div>
|
|
439
|
+
<div {...styles.toast()}>
|
|
440
|
+
<CheckCircle {...styles.icon()} />
|
|
441
|
+
<span {...styles.title()}>Copied to clipboard</span>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
namespace styles {
|
|
448
|
+
export const icon = style({ color: 'content.positive', flexShrink: '0 !custom', fontSize: '20' })
|
|
449
|
+
|
|
450
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
451
|
+
|
|
452
|
+
export const row = style({
|
|
453
|
+
alignItems: 'center',
|
|
454
|
+
display: 'flex',
|
|
455
|
+
justifyContent: 'space-between',
|
|
456
|
+
minHeight: '32',
|
|
457
|
+
})
|
|
458
|
+
|
|
459
|
+
export const stack = style({
|
|
460
|
+
display: 'flex',
|
|
461
|
+
flexDirection: 'column',
|
|
462
|
+
rowGap: '16',
|
|
463
|
+
width: '16rem !custom',
|
|
464
|
+
})
|
|
465
|
+
|
|
466
|
+
export const title = style({ color: 'content.primary', typography: 'body.b2Strong' })
|
|
467
|
+
|
|
468
|
+
export const toast = style({
|
|
469
|
+
alignItems: 'center',
|
|
470
|
+
backgroundColor: 'background.elevated',
|
|
471
|
+
borderRadius: 'sm',
|
|
472
|
+
boxShadow: 'regular',
|
|
473
|
+
boxSizing: 'border-box',
|
|
474
|
+
columnGap: '12',
|
|
475
|
+
display: 'flex',
|
|
476
|
+
paddingBlock: '16',
|
|
477
|
+
paddingInline: '20',
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
export const value = style({
|
|
481
|
+
alignItems: 'center',
|
|
482
|
+
color: 'content.primary',
|
|
483
|
+
columnGap: '4',
|
|
484
|
+
display: 'flex',
|
|
485
|
+
typography: 'mono.m1',
|
|
486
|
+
})
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
### Choose a Variant by Context
|
|
491
|
+
|
|
492
|
+
* **Text (default):** Inline values in rows, tables, and cards.
|
|
493
|
+
* **Secondary (secondary):** A standalone value you mainly copy, such as an invite link.
|
|
494
|
+
|
|
495
|
+
Keep `small` beside body text. Use `medium` or `large` in touch layouts, or beside a large value or a control of that size.
|
|
496
|
+
|
|
497
|
+
### Let a Clickable Row Copy
|
|
498
|
+
|
|
499
|
+
If a whole row copies on press, handle the copy in the row and pass `copied` to the button. The button shows the confirmation without a second copy. [Snippet](snippet.md) and [SecretValue](secret-value.md) work this way.
|
|
500
|
+
|
|
501
|
+
**Do:** Pass `copied` so the button confirms the row's copy.
|
|
502
|
+
|
|
503
|
+
```tsx
|
|
504
|
+
/**
|
|
505
|
+
* Do example for "Let a Clickable Row Copy" on the CopyButton page.
|
|
506
|
+
* Pass `copied` so the button confirms the row's copy.
|
|
507
|
+
* @module
|
|
508
|
+
*/
|
|
509
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
510
|
+
|
|
511
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
512
|
+
export function Demo() {
|
|
513
|
+
return (
|
|
514
|
+
<div {...styles.row()}>
|
|
515
|
+
<span {...styles.label()}>Invite link</span>
|
|
516
|
+
<span {...styles.value()}>
|
|
517
|
+
tempo.xyz/invite/7kq2
|
|
518
|
+
<CopyButton aria-label="Copy invite link" copied value="https://tempo.xyz/invite/7kq2" />
|
|
519
|
+
</span>
|
|
520
|
+
</div>
|
|
521
|
+
)
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
namespace styles {
|
|
525
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
526
|
+
|
|
527
|
+
// The pressed row draws its hover background, since the preview is inert.
|
|
528
|
+
export const row = style({
|
|
529
|
+
alignItems: 'center',
|
|
530
|
+
backgroundColor: 'container.regular',
|
|
531
|
+
borderRadius: 'xs',
|
|
532
|
+
boxSizing: 'border-box',
|
|
533
|
+
display: 'flex',
|
|
534
|
+
justifyContent: 'space-between',
|
|
535
|
+
minHeight: '40',
|
|
536
|
+
paddingInline: '12',
|
|
537
|
+
width: '17rem !custom',
|
|
538
|
+
})
|
|
539
|
+
|
|
540
|
+
export const value = style({
|
|
541
|
+
alignItems: 'center',
|
|
542
|
+
color: 'content.primary',
|
|
543
|
+
columnGap: '4',
|
|
544
|
+
display: 'flex',
|
|
545
|
+
typography: 'mono.m1',
|
|
546
|
+
})
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Don't:** Leave the button unconfirmed after the row copies.
|
|
551
|
+
|
|
552
|
+
```tsx
|
|
553
|
+
/**
|
|
554
|
+
* Don't example for "Let a Clickable Row Copy" on the CopyButton page.
|
|
555
|
+
* Don't leave the button unconfirmed after the row copies.
|
|
556
|
+
* @module
|
|
557
|
+
*/
|
|
558
|
+
import { CopyButton, style } from '@tempoxyz/ds'
|
|
559
|
+
|
|
560
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
561
|
+
export function Demo() {
|
|
562
|
+
return (
|
|
563
|
+
<div {...styles.row()}>
|
|
564
|
+
<span {...styles.label()}>Invite link</span>
|
|
565
|
+
<span {...styles.value()}>
|
|
566
|
+
tempo.xyz/invite/7kq2
|
|
567
|
+
<CopyButton aria-label="Copy invite link" value="https://tempo.xyz/invite/7kq2" />
|
|
568
|
+
</span>
|
|
569
|
+
</div>
|
|
570
|
+
)
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
namespace styles {
|
|
574
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
575
|
+
|
|
576
|
+
// The pressed row draws its hover background, since the preview is inert.
|
|
577
|
+
export const row = style({
|
|
578
|
+
alignItems: 'center',
|
|
579
|
+
backgroundColor: 'container.regular',
|
|
580
|
+
borderRadius: 'xs',
|
|
581
|
+
boxSizing: 'border-box',
|
|
582
|
+
display: 'flex',
|
|
583
|
+
justifyContent: 'space-between',
|
|
584
|
+
minHeight: '40',
|
|
585
|
+
paddingInline: '12',
|
|
586
|
+
width: '17rem !custom',
|
|
587
|
+
})
|
|
588
|
+
|
|
589
|
+
export const value = style({
|
|
590
|
+
alignItems: 'center',
|
|
591
|
+
color: 'content.primary',
|
|
592
|
+
columnGap: '4',
|
|
593
|
+
display: 'flex',
|
|
594
|
+
typography: 'mono.m1',
|
|
595
|
+
})
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
## Accessibility
|
|
600
|
+
|
|
601
|
+
A copy button renders an icon-only [Button](button.md) with a visually hidden status message. It follows the [WAI-ARIA Authoring Practices button pattern](https://www.w3.org/WAI/ARIA/apg/patterns/button/).
|
|
602
|
+
|
|
603
|
+
### Semantics
|
|
604
|
+
|
|
605
|
+
* **Button (button):** A native button. Enter and Space copy, and it joins the tab order.
|
|
606
|
+
* **Name (aria-label):** Defaults to "Copy" and the value. Shows on hover, not on focus or touch.
|
|
607
|
+
* **Copied State (2s):** After a copy, the name changes to "Copied", then returns.
|
|
608
|
+
* **Status Region (status):** A polite live region holds the confirmation text.
|
|
609
|
+
* **Disabled (disabled):** Removes the button from the tab order unless you set `focusableWhenDisabled`.
|
|
610
|
+
* **Clipboard Fallback (execCommand):** Copies where the Clipboard API is unavailable, such as insecure contexts and some iframes.
|
|
611
|
+
|
|
612
|
+
### Keyboard
|
|
613
|
+
|
|
614
|
+
* **Move Focus to the Button (Tab):** Moves focus to the button.
|
|
615
|
+
* **Copy the Value (Enter or Space):** Copies the value.
|
|
616
|
+
|
|
617
|
+
### Your Responsibilities
|
|
618
|
+
|
|
619
|
+
* **Name What It Copies (aria-label):** Name the value, such as "Copy address". A raw address reads poorly.
|
|
620
|
+
* **Announce Parent Failures (copied):** If a parent copies on its own click, announce failures from that parent.
|
|
621
|
+
|
|
622
|
+
## Related
|
|
623
|
+
|
|
624
|
+
[Hex](hex.md)
|
|
625
|
+
|
|
626
|
+
Use for addresses and hashes with copying built in.
|
|
627
|
+
|
|
628
|
+
[Snippet](snippet.md)
|
|
629
|
+
|
|
630
|
+
Use for commands and code.
|
|
631
|
+
|
|
632
|
+
[SecretValue](secret-value.md)
|
|
633
|
+
|
|
634
|
+
Use for API keys and secrets.
|
|
635
|
+
|
|
636
|
+
[Button](button.md)
|
|
637
|
+
|
|
638
|
+
Use for other icon-only actions.
|
|
639
|
+
|
|
640
|
+
[Blockchain Values](../patterns/blockchain-values.md)
|
|
641
|
+
|
|
642
|
+
Covers showing addresses, hashes, and amounts.
|