@tempoxyz/ds 0.3.10 → 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/package.json +1 -1
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# IconTile
|
|
2
|
+
|
|
3
|
+
Anchors a centered modal with one icon in a rounded square.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/IconTile.tsx)
|
|
6
|
+
|
|
7
|
+
Figma: [Elements/Icon Tile](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-1245)
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
An icon tile is a 56px rounded square with a 24px icon. It sits above the centered title of a modal, and `intent` tints it for the modal's outcome.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Basic
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { IconTile } from '@tempoxyz/ds'
|
|
19
|
+
import { Settings } from '@tempoxyz/ds/icons'
|
|
20
|
+
|
|
21
|
+
export function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<IconTile>
|
|
24
|
+
<Settings />
|
|
25
|
+
</IconTile>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/IconTile/Basic.tsx)
|
|
31
|
+
|
|
32
|
+
### Intent
|
|
33
|
+
|
|
34
|
+
Set `intent` to `neutral` (default), `positive`, `warning`, or `negative`. Each tints the fill and the icon.
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { IconTile, style } from '@tempoxyz/ds'
|
|
38
|
+
import { AlertTriangle, Check, Delete, Passkey } from '@tempoxyz/ds/icons'
|
|
39
|
+
|
|
40
|
+
export function Demo() {
|
|
41
|
+
return (
|
|
42
|
+
<div {...styles.row()}>
|
|
43
|
+
<IconTile intent="neutral">
|
|
44
|
+
<Passkey />
|
|
45
|
+
</IconTile>
|
|
46
|
+
<IconTile intent="positive">
|
|
47
|
+
<Check />
|
|
48
|
+
</IconTile>
|
|
49
|
+
<IconTile intent="warning">
|
|
50
|
+
<AlertTriangle />
|
|
51
|
+
</IconTile>
|
|
52
|
+
<IconTile intent="negative">
|
|
53
|
+
<Delete />
|
|
54
|
+
</IconTile>
|
|
55
|
+
</div>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
namespace styles {
|
|
60
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/IconTile/Intent.tsx)
|
|
65
|
+
|
|
66
|
+
## Anatomy
|
|
67
|
+
|
|
68
|
+
Import the component and assemble its parts.
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { IconTile } from '@tempoxyz/ds'
|
|
72
|
+
|
|
73
|
+
<IconTile />
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Guidelines
|
|
77
|
+
|
|
78
|
+
### When to Use
|
|
79
|
+
|
|
80
|
+
* Top a centered acknowledgment, onboarding, success, or destructive confirmation modal with one chip above the title.
|
|
81
|
+
|
|
82
|
+
### When Not to Use
|
|
83
|
+
|
|
84
|
+
* Use [Avatar](/docs/components/avatar) with an icon to lead a list row, such as a wallet or app.
|
|
85
|
+
* Use [Button](/docs/components/button) with `shape="icon"` for an icon that does something. The chip isn't interactive.
|
|
86
|
+
* Use [Badge](/docs/components/badge) to show a status.
|
|
87
|
+
* Use [Visual](/docs/components/visual) for an illustrated onboarding or feature modal. Never pair the two.
|
|
88
|
+
|
|
89
|
+
### Pair the Chip With a Title
|
|
90
|
+
|
|
91
|
+
**Do:** Place the chip above a centered title that states the outcome.
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
/**
|
|
95
|
+
* Do example for "Pair the Chip With a Title" on the IconTile page.
|
|
96
|
+
* Place the chip above a centered title that states the outcome.
|
|
97
|
+
* @module
|
|
98
|
+
*/
|
|
99
|
+
import { IconTile, style } from '@tempoxyz/ds'
|
|
100
|
+
import { Check } from '@tempoxyz/ds/icons'
|
|
101
|
+
|
|
102
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
103
|
+
export function Demo() {
|
|
104
|
+
return (
|
|
105
|
+
<div {...styles.stack()}>
|
|
106
|
+
<IconTile intent="positive">
|
|
107
|
+
<Check />
|
|
108
|
+
</IconTile>
|
|
109
|
+
<span {...styles.title()}>Payment sent</span>
|
|
110
|
+
<span {...styles.detail()}>Jane Cooper received 25.00 USDC.</span>
|
|
111
|
+
</div>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
namespace styles {
|
|
116
|
+
export const detail = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
117
|
+
|
|
118
|
+
export const stack = style({
|
|
119
|
+
alignItems: 'center',
|
|
120
|
+
display: 'flex',
|
|
121
|
+
flexDirection: 'column',
|
|
122
|
+
gap: '4',
|
|
123
|
+
textAlign: 'center',
|
|
124
|
+
width: '100% !custom',
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
export const title = style({
|
|
128
|
+
color: 'content.primary',
|
|
129
|
+
marginBlockStart: '20',
|
|
130
|
+
typography: 'body.b1Strong',
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Don't:** Rely on the chip alone to state the outcome.
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
/**
|
|
139
|
+
* Don't example for "Pair the Chip With a Title" on the IconTile page.
|
|
140
|
+
* Don't rely on the chip alone to state the outcome.
|
|
141
|
+
* @module
|
|
142
|
+
*/
|
|
143
|
+
import { IconTile, style } from '@tempoxyz/ds'
|
|
144
|
+
import { Check } from '@tempoxyz/ds/icons'
|
|
145
|
+
|
|
146
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
147
|
+
export function Demo() {
|
|
148
|
+
return (
|
|
149
|
+
<div {...styles.stack()}>
|
|
150
|
+
<IconTile intent="positive">
|
|
151
|
+
<Check />
|
|
152
|
+
</IconTile>
|
|
153
|
+
</div>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
namespace styles {
|
|
158
|
+
export const stack = style({ display: 'flex', justifyContent: 'center', width: '100% !custom' })
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Use One Icon From the Library
|
|
163
|
+
|
|
164
|
+
The icon inherits the intent's color and the chip's 24px font size, so leave its size and color unset.
|
|
165
|
+
|
|
166
|
+
**Do:** Pass one icon from `@tempoxyz/ds/icons`.
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
/**
|
|
170
|
+
* Do example for "Pair the Chip With a Title" on the IconTile page.
|
|
171
|
+
* Place the chip above a centered title that states the outcome.
|
|
172
|
+
* @module
|
|
173
|
+
*/
|
|
174
|
+
import { IconTile, style } from '@tempoxyz/ds'
|
|
175
|
+
import { Check } from '@tempoxyz/ds/icons'
|
|
176
|
+
|
|
177
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
178
|
+
export function Demo() {
|
|
179
|
+
return (
|
|
180
|
+
<div {...styles.stack()}>
|
|
181
|
+
<IconTile intent="positive">
|
|
182
|
+
<Check />
|
|
183
|
+
</IconTile>
|
|
184
|
+
<span {...styles.title()}>Payment sent</span>
|
|
185
|
+
<span {...styles.detail()}>Jane Cooper received 25.00 USDC.</span>
|
|
186
|
+
</div>
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
namespace styles {
|
|
191
|
+
export const detail = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
192
|
+
|
|
193
|
+
export const stack = style({
|
|
194
|
+
alignItems: 'center',
|
|
195
|
+
display: 'flex',
|
|
196
|
+
flexDirection: 'column',
|
|
197
|
+
gap: '4',
|
|
198
|
+
textAlign: 'center',
|
|
199
|
+
width: '100% !custom',
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
export const title = style({
|
|
203
|
+
color: 'content.primary',
|
|
204
|
+
marginBlockStart: '20',
|
|
205
|
+
typography: 'body.b1Strong',
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Don't:** Put text, numbers, or images in the chip.
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
/**
|
|
214
|
+
* Don't example for "Use One Icon From the Library" on the IconTile page.
|
|
215
|
+
* Don't put text, numbers, or images in the chip.
|
|
216
|
+
* @module
|
|
217
|
+
*/
|
|
218
|
+
import { IconTile, style } from '@tempoxyz/ds'
|
|
219
|
+
|
|
220
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
221
|
+
export function Demo() {
|
|
222
|
+
return (
|
|
223
|
+
<div {...styles.stack()}>
|
|
224
|
+
<IconTile intent="positive">OK</IconTile>
|
|
225
|
+
<span {...styles.title()}>Payment sent</span>
|
|
226
|
+
<span {...styles.detail()}>Jane Cooper received 25.00 USDC.</span>
|
|
227
|
+
</div>
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
namespace styles {
|
|
232
|
+
export const detail = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
233
|
+
|
|
234
|
+
export const stack = style({
|
|
235
|
+
alignItems: 'center',
|
|
236
|
+
display: 'flex',
|
|
237
|
+
flexDirection: 'column',
|
|
238
|
+
gap: '4',
|
|
239
|
+
textAlign: 'center',
|
|
240
|
+
width: '100% !custom',
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
export const title = style({
|
|
244
|
+
color: 'content.primary',
|
|
245
|
+
marginBlockStart: '20',
|
|
246
|
+
typography: 'body.b1Strong',
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Match the Intent to the Outcome
|
|
252
|
+
|
|
253
|
+
Use one chip per modal, and leave it out of form and review modals.
|
|
254
|
+
|
|
255
|
+
* **Feature (neutral):** Introduces a feature, such as passkeys.
|
|
256
|
+
* **Done (positive):** Confirms a finished task, such as a payment.
|
|
257
|
+
* **Risk (warning):** Flags a risk to read before you continue.
|
|
258
|
+
* **Irreversible (negative):** Marks an action that can't be undone.
|
|
259
|
+
|
|
260
|
+
## Accessibility
|
|
261
|
+
|
|
262
|
+
An icon tile renders a `<span>` with no role and takes no focus. The icon inside sets what assistive technology perceives.
|
|
263
|
+
|
|
264
|
+
### Semantics
|
|
265
|
+
|
|
266
|
+
* **Chip (span):** Has no role of its own.
|
|
267
|
+
* **Unnamed Icons (aria-hidden):** Icons without an `aria-label` are hidden, so the chip is silent.
|
|
268
|
+
* **Named Icons (img):** An icon with an `aria-label` is announced as an image.
|
|
269
|
+
|
|
270
|
+
### Your Responsibilities
|
|
271
|
+
|
|
272
|
+
* **Leave Decorative Icons Unnamed:** If the title below the chip names the outcome, leave the icon unnamed.
|
|
273
|
+
* **Name Icons That Stand Alone (aria-label):** If the icon carries meaning alone, label it, such as "Wallet connected".
|
|
274
|
+
* **State the Outcome in Text (intent):** The tint has no text alternative, so the modal title states the outcome.
|
|
275
|
+
|
|
276
|
+
## Related
|
|
277
|
+
|
|
278
|
+
[Avatar](/docs/components/avatar)
|
|
279
|
+
|
|
280
|
+
Use for people, contacts, and wallets in list rows.
|
|
281
|
+
|
|
282
|
+
[Button](/docs/components/button)
|
|
283
|
+
|
|
284
|
+
Use for icon actions.
|
|
285
|
+
|
|
286
|
+
[Visual](/docs/components/visual)
|
|
287
|
+
|
|
288
|
+
Use for illustrated onboarding and feature modals.
|
|
289
|
+
|
|
290
|
+
[Iconography](/docs/foundations/iconography)
|
|
291
|
+
|
|
292
|
+
Covers choosing icons.
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# Identicon
|
|
2
|
+
|
|
3
|
+
Shows a unique gradient avatar derived from an address.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Identicon.tsx)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
An identicon is a round gradient avatar derived from an address. The same address always renders the same colors.
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Basic
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Identicon } from '@tempoxyz/ds'
|
|
17
|
+
|
|
18
|
+
export function Demo() {
|
|
19
|
+
return <Identicon address="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" />
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Identicon/Basic.tsx)
|
|
24
|
+
|
|
25
|
+
### Size
|
|
26
|
+
|
|
27
|
+
Set `size` to `16`, `24`, `32`, `40` (default), `48`, or `64` pixels.
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { Identicon, style } from '@tempoxyz/ds'
|
|
31
|
+
|
|
32
|
+
export function Demo() {
|
|
33
|
+
return (
|
|
34
|
+
<div {...styles.row()}>
|
|
35
|
+
{(['16', '24', '32', '40', '48', '64'] as const).map((size) => (
|
|
36
|
+
<Identicon address="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" key={size} size={size} />
|
|
37
|
+
))}
|
|
38
|
+
</div>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
namespace styles {
|
|
43
|
+
export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '12' })
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Identicon/Size.tsx)
|
|
48
|
+
|
|
49
|
+
### Address
|
|
50
|
+
|
|
51
|
+
Each `address` derives its own colors.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { Identicon, style } from '@tempoxyz/ds'
|
|
55
|
+
|
|
56
|
+
const addresses = [
|
|
57
|
+
'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
|
|
58
|
+
'0x71C7656EC7ab88b098defB751B7401B5f6d8976F',
|
|
59
|
+
'0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
|
|
60
|
+
'0x0000000000000000000000000000000000000000',
|
|
61
|
+
'0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
|
|
62
|
+
'0x6B175474E89094C44Da98b954EedeAC495271d0F',
|
|
63
|
+
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
64
|
+
'0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
export function Demo() {
|
|
68
|
+
return (
|
|
69
|
+
<div {...styles.row()}>
|
|
70
|
+
{addresses.map((address) => (
|
|
71
|
+
<Identicon address={address} key={address} size="64" />
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
namespace styles {
|
|
78
|
+
export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '12' })
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Identicon/Address.tsx)
|
|
83
|
+
|
|
84
|
+
## Anatomy
|
|
85
|
+
|
|
86
|
+
Import the component and assemble its parts.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { Identicon } from '@tempoxyz/ds'
|
|
90
|
+
|
|
91
|
+
<Identicon />
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Guidelines
|
|
95
|
+
|
|
96
|
+
### When to Use
|
|
97
|
+
|
|
98
|
+
* Give an address an image beside its text, in recipient lists, activity rows, and account switchers.
|
|
99
|
+
* Fill an `Avatar.Fallback` for an account known only by its address.
|
|
100
|
+
|
|
101
|
+
### When Not to Use
|
|
102
|
+
|
|
103
|
+
* Use [Avatar](/docs/components/avatar) for people and organizations with a name.
|
|
104
|
+
* Use [TokenLogo](/docs/components/token-logo) for a token contract, which has its own icon.
|
|
105
|
+
* Use [Hex](/docs/components/hex) to read, compare, or copy the address.
|
|
106
|
+
|
|
107
|
+
### Always Show the Address Beside It
|
|
108
|
+
|
|
109
|
+
Colors come from seven hue palettes, so addresses often look alike. Color alone doesn't identify an account ([SC 1.4.1](https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html)).
|
|
110
|
+
|
|
111
|
+
**Do:** Place the address, with `copy`, or the account name beside each identicon.
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
/**
|
|
115
|
+
* Do example for "Always Show the Address Beside It" on the Identicon page.
|
|
116
|
+
* Place the address, with `copy`, or the account name beside each identicon.
|
|
117
|
+
* @module
|
|
118
|
+
*/
|
|
119
|
+
import { Hex, Identicon, style } from '@tempoxyz/ds'
|
|
120
|
+
|
|
121
|
+
const addresses = [
|
|
122
|
+
'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
|
|
123
|
+
'0x71C7656EC7ab88b098defB751B7401B5f6d8976F',
|
|
124
|
+
] as const
|
|
125
|
+
|
|
126
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
127
|
+
export function Demo() {
|
|
128
|
+
return (
|
|
129
|
+
<div {...styles.list()}>
|
|
130
|
+
{addresses.map((address) => (
|
|
131
|
+
<div key={address} {...styles.row()}>
|
|
132
|
+
<Identicon address={address} aria-hidden size="32" />
|
|
133
|
+
<Hex copy value={address} />
|
|
134
|
+
</div>
|
|
135
|
+
))}
|
|
136
|
+
</div>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
namespace styles {
|
|
141
|
+
export const list = style({ display: 'grid', gap: '12', minWidth: '0' })
|
|
142
|
+
|
|
143
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '12', minWidth: '0' })
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Don't:** Show identicons without the address or name they stand for.
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
/**
|
|
151
|
+
* Don't example for "Always Show the Address Beside It" on the Identicon page.
|
|
152
|
+
* Don't show identicons without the address or name they stand for.
|
|
153
|
+
* @module
|
|
154
|
+
*/
|
|
155
|
+
import { Identicon, style } from '@tempoxyz/ds'
|
|
156
|
+
|
|
157
|
+
const addresses = [
|
|
158
|
+
'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
|
|
159
|
+
'0x71C7656EC7ab88b098defB751B7401B5f6d8976F',
|
|
160
|
+
'0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe',
|
|
161
|
+
] as const
|
|
162
|
+
|
|
163
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
164
|
+
export function Demo() {
|
|
165
|
+
return (
|
|
166
|
+
<div {...styles.row()}>
|
|
167
|
+
{addresses.map((address) => (
|
|
168
|
+
<Identicon address={address} key={address} size="32" />
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
namespace styles {
|
|
175
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Don't Treat It as Verification
|
|
180
|
+
|
|
181
|
+
An identicon doesn't prove an address is correct. Before a send, show the full address on the review step.
|
|
182
|
+
|
|
183
|
+
**Do:** Ask people to compare characters.
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
/**
|
|
187
|
+
* Do example for "Don't Treat It as Verification" on the Identicon page.
|
|
188
|
+
* Ask people to compare characters.
|
|
189
|
+
* @module
|
|
190
|
+
*/
|
|
191
|
+
import { Hex, Identicon, style } from '@tempoxyz/ds'
|
|
192
|
+
|
|
193
|
+
const address = '0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc'
|
|
194
|
+
|
|
195
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
196
|
+
export function Demo() {
|
|
197
|
+
return (
|
|
198
|
+
<div {...styles.field()}>
|
|
199
|
+
<span {...styles.label()}>Recipient</span>
|
|
200
|
+
<div {...styles.row()}>
|
|
201
|
+
<Identicon address={address} aria-hidden size="24" />
|
|
202
|
+
<Hex size="small" value={address} />
|
|
203
|
+
</div>
|
|
204
|
+
<span {...styles.hint()}>Compare every character with the address you copied.</span>
|
|
205
|
+
</div>
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
namespace styles {
|
|
210
|
+
export const field = style({ display: 'grid', gap: '8', width: '100% !custom' })
|
|
211
|
+
|
|
212
|
+
export const hint = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
213
|
+
|
|
214
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
215
|
+
|
|
216
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '8', minWidth: '0' })
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Don't:** Ask people to compare colors.
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
/**
|
|
224
|
+
* Don't example for "Don't Treat It as Verification" on the Identicon page.
|
|
225
|
+
* Don't ask people to compare colors.
|
|
226
|
+
* @module
|
|
227
|
+
*/
|
|
228
|
+
import { Hex, Identicon, style } from '@tempoxyz/ds'
|
|
229
|
+
|
|
230
|
+
const address = '0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc'
|
|
231
|
+
|
|
232
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
233
|
+
export function Demo() {
|
|
234
|
+
return (
|
|
235
|
+
<div {...styles.field()}>
|
|
236
|
+
<span {...styles.label()}>Recipient</span>
|
|
237
|
+
<div {...styles.row()}>
|
|
238
|
+
<Identicon address={address} aria-hidden size="24" />
|
|
239
|
+
<Hex size="small" value={address} />
|
|
240
|
+
</div>
|
|
241
|
+
<span {...styles.hint()}>Make sure the colors match your contact.</span>
|
|
242
|
+
</div>
|
|
243
|
+
)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
namespace styles {
|
|
247
|
+
export const field = style({ display: 'grid', gap: '8', width: '100% !custom' })
|
|
248
|
+
|
|
249
|
+
export const hint = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
250
|
+
|
|
251
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b2' })
|
|
252
|
+
|
|
253
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '8', minWidth: '0' })
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Derive It From the Address
|
|
258
|
+
|
|
259
|
+
Letter case doesn't change the colors, so checksummed and lowercase forms match.
|
|
260
|
+
|
|
261
|
+
**Do:** Pass the address, so a rename keeps the same image.
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
/**
|
|
265
|
+
* Do example for "Derive It From the Address" on the Identicon page.
|
|
266
|
+
* Pass the address, so a rename keeps the same image.
|
|
267
|
+
* @module
|
|
268
|
+
*/
|
|
269
|
+
import { Identicon, style } from '@tempoxyz/ds'
|
|
270
|
+
|
|
271
|
+
const address = '0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc'
|
|
272
|
+
|
|
273
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
274
|
+
export function Demo() {
|
|
275
|
+
return (
|
|
276
|
+
<div {...styles.list()}>
|
|
277
|
+
<div {...styles.row()}>
|
|
278
|
+
<Identicon address={address} aria-hidden size="32" />
|
|
279
|
+
<span {...styles.name()}>Alice</span>
|
|
280
|
+
</div>
|
|
281
|
+
<div {...styles.row()}>
|
|
282
|
+
<Identicon address={address} aria-hidden size="32" />
|
|
283
|
+
<span {...styles.name()}>Alice Chen</span>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
namespace styles {
|
|
290
|
+
export const list = style({ display: 'grid', gap: '12' })
|
|
291
|
+
|
|
292
|
+
export const name = style({ color: 'content.primary', typography: 'body.b2' })
|
|
293
|
+
|
|
294
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Don't:** Pass a display name. The image changes when the name does.
|
|
299
|
+
|
|
300
|
+
```tsx
|
|
301
|
+
/**
|
|
302
|
+
* Don't example for "Derive It From the Address" on the Identicon page.
|
|
303
|
+
* Don't pass a display name. The image changes when the name does.
|
|
304
|
+
* @module
|
|
305
|
+
*/
|
|
306
|
+
import { Identicon, style } from '@tempoxyz/ds'
|
|
307
|
+
|
|
308
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
309
|
+
export function Demo() {
|
|
310
|
+
return (
|
|
311
|
+
<div {...styles.list()}>
|
|
312
|
+
<div {...styles.row()}>
|
|
313
|
+
<Identicon address="Alice" aria-hidden size="32" />
|
|
314
|
+
<span {...styles.name()}>Alice</span>
|
|
315
|
+
</div>
|
|
316
|
+
<div {...styles.row()}>
|
|
317
|
+
<Identicon address="Alice Chen" aria-hidden size="32" />
|
|
318
|
+
<span {...styles.name()}>Alice Chen</span>
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
namespace styles {
|
|
325
|
+
export const list = style({ display: 'grid', gap: '12' })
|
|
326
|
+
|
|
327
|
+
export const name = style({ color: 'content.primary', typography: 'body.b2' })
|
|
328
|
+
|
|
329
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Size It With the Text Beside It
|
|
334
|
+
|
|
335
|
+
* **Inline (16):** Inline with body text.
|
|
336
|
+
* **Dense Rows (24 or 32):** In dense rows and tables.
|
|
337
|
+
* **List Rows (40):** The default, in list rows.
|
|
338
|
+
* **Account Headers (48 or 64):** In account headers.
|
|
339
|
+
* **Fill a Frame (fill):** Inside an avatar fallback or other sized frame.
|
|
340
|
+
|
|
341
|
+
## Accessibility
|
|
342
|
+
|
|
343
|
+
An identicon renders an `<svg>` with the `img` role. It takes no focus.
|
|
344
|
+
|
|
345
|
+
### Semantics
|
|
346
|
+
|
|
347
|
+
* **Root (img):** Announced as an image by name.
|
|
348
|
+
* **Name (aria-label):** Defaults to the full address, all 42 characters.
|
|
349
|
+
|
|
350
|
+
### Your Responsibilities
|
|
351
|
+
|
|
352
|
+
* **Hide a Duplicate (aria-hidden):** If the address is in nearby text, hide the identicon so it isn't announced twice.
|
|
353
|
+
* **Name a Standalone Identicon (aria-label):** If it stands alone, name the account, such as "Savings account".
|
|
354
|
+
|
|
355
|
+
## Related
|
|
356
|
+
|
|
357
|
+
[Avatar](/docs/components/avatar)
|
|
358
|
+
|
|
359
|
+
Use for people and organizations.
|
|
360
|
+
|
|
361
|
+
[Hex](/docs/components/hex)
|
|
362
|
+
|
|
363
|
+
Use for showing and copying addresses.
|
|
364
|
+
|
|
365
|
+
[TokenLogo](/docs/components/token-logo)
|
|
366
|
+
|
|
367
|
+
Use for token icons.
|
|
368
|
+
|
|
369
|
+
[Blockchain Values](/docs/patterns/blockchain-values)
|
|
370
|
+
|
|
371
|
+
Covers displaying addresses.
|