@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.
Files changed (120) hide show
  1. package/dist/docs/AGENTS.md +9 -0
  2. package/dist/docs/components/accordion.md +489 -0
  3. package/dist/docs/components/address-card.md +147 -0
  4. package/dist/docs/components/agent-logo.md +194 -0
  5. package/dist/docs/components/alert-dialog.md +631 -0
  6. package/dist/docs/components/alert.md +448 -0
  7. package/dist/docs/components/amount-input.md +305 -0
  8. package/dist/docs/components/amount.md +794 -0
  9. package/dist/docs/components/app-shell.md +559 -0
  10. package/dist/docs/components/asset-chip.md +294 -0
  11. package/dist/docs/components/autocomplete.md +619 -0
  12. package/dist/docs/components/avatar.md +321 -0
  13. package/dist/docs/components/badge.md +339 -0
  14. package/dist/docs/components/badged-logo.md +116 -0
  15. package/dist/docs/components/banner.md +379 -0
  16. package/dist/docs/components/bar-chart.md +208 -0
  17. package/dist/docs/components/breadcrumbs.md +380 -0
  18. package/dist/docs/components/button-group.md +286 -0
  19. package/dist/docs/components/button.md +650 -0
  20. package/dist/docs/components/calendar.md +375 -0
  21. package/dist/docs/components/callout.md +96 -0
  22. package/dist/docs/components/checkbox-group.md +521 -0
  23. package/dist/docs/components/checkbox.md +467 -0
  24. package/dist/docs/components/choice-group.md +516 -0
  25. package/dist/docs/components/choicebox.md +641 -0
  26. package/dist/docs/components/code.md +100 -0
  27. package/dist/docs/components/combobox.md +939 -0
  28. package/dist/docs/components/container.md +257 -0
  29. package/dist/docs/components/copy-button.md +642 -0
  30. package/dist/docs/components/date-picker.md +514 -0
  31. package/dist/docs/components/dialog.md +1332 -0
  32. package/dist/docs/components/drawer.md +966 -0
  33. package/dist/docs/components/empty.md +340 -0
  34. package/dist/docs/components/field.md +570 -0
  35. package/dist/docs/components/fieldset.md +398 -0
  36. package/dist/docs/components/frame.md +434 -0
  37. package/dist/docs/components/gauge.md +299 -0
  38. package/dist/docs/components/get-started-visual.md +117 -0
  39. package/dist/docs/components/grid.md +288 -0
  40. package/dist/docs/components/hero-visual.md +155 -0
  41. package/dist/docs/components/hex.md +487 -0
  42. package/dist/docs/components/icon-tile.md +292 -0
  43. package/dist/docs/components/identicon.md +371 -0
  44. package/dist/docs/components/inline.md +233 -0
  45. package/dist/docs/components/inset.md +225 -0
  46. package/dist/docs/components/kbd.md +423 -0
  47. package/dist/docs/components/list-group.md +981 -0
  48. package/dist/docs/components/loading-dots.md +237 -0
  49. package/dist/docs/components/menu.md +934 -0
  50. package/dist/docs/components/native-select.md +204 -0
  51. package/dist/docs/components/network-logo.md +248 -0
  52. package/dist/docs/components/number-field.md +543 -0
  53. package/dist/docs/components/otp-field.md +616 -0
  54. package/dist/docs/components/pagination.md +516 -0
  55. package/dist/docs/components/popover.md +544 -0
  56. package/dist/docs/components/progress.md +388 -0
  57. package/dist/docs/components/qr.md +314 -0
  58. package/dist/docs/components/radio-group.md +528 -0
  59. package/dist/docs/components/secret-value.md +406 -0
  60. package/dist/docs/components/select.md +751 -0
  61. package/dist/docs/components/separator.md +379 -0
  62. package/dist/docs/components/sidebar-menu.md +922 -0
  63. package/dist/docs/components/skeleton.md +517 -0
  64. package/dist/docs/components/slider.md +539 -0
  65. package/dist/docs/components/snippet.md +424 -0
  66. package/dist/docs/components/spinner.md +216 -0
  67. package/dist/docs/components/split-bar.md +139 -0
  68. package/dist/docs/components/split-button.md +464 -0
  69. package/dist/docs/components/stack.md +299 -0
  70. package/dist/docs/components/status-chip.md +226 -0
  71. package/dist/docs/components/status-indicator.md +119 -0
  72. package/dist/docs/components/status-row.md +174 -0
  73. package/dist/docs/components/stepper.md +451 -0
  74. package/dist/docs/components/success-hero.md +157 -0
  75. package/dist/docs/components/surface.md +639 -0
  76. package/dist/docs/components/switch.md +472 -0
  77. package/dist/docs/components/table.md +967 -0
  78. package/dist/docs/components/tabs.md +627 -0
  79. package/dist/docs/components/tempo-logo.md +185 -0
  80. package/dist/docs/components/text-input.md +624 -0
  81. package/dist/docs/components/textarea.md +352 -0
  82. package/dist/docs/components/toast.md +535 -0
  83. package/dist/docs/components/token-logo.md +371 -0
  84. package/dist/docs/components/token.md +247 -0
  85. package/dist/docs/components/tooltip.md +490 -0
  86. package/dist/docs/components/verification-code.md +116 -0
  87. package/dist/docs/components/visual.md +249 -0
  88. package/dist/docs/components.md +203 -0
  89. package/dist/docs/foundations/accessibility.md +377 -0
  90. package/dist/docs/foundations/agents.md +150 -0
  91. package/dist/docs/foundations/color.md +522 -0
  92. package/dist/docs/foundations/content/tone.md +194 -0
  93. package/dist/docs/foundations/content/voice.md +194 -0
  94. package/dist/docs/foundations/content/writing-style.md +406 -0
  95. package/dist/docs/foundations/iconography.md +282 -0
  96. package/dist/docs/foundations/intent.md +360 -0
  97. package/dist/docs/foundations/layout.md +508 -0
  98. package/dist/docs/foundations/linter.md +296 -0
  99. package/dist/docs/foundations/motion.md +151 -0
  100. package/dist/docs/foundations/radius-and-padding.md +86 -0
  101. package/dist/docs/foundations/typography.md +266 -0
  102. package/dist/docs/index.md +137 -0
  103. package/dist/docs/introduction/faq.md +132 -0
  104. package/dist/docs/introduction/getting-started.md +377 -0
  105. package/dist/docs/patterns/blockchain-values.md +709 -0
  106. package/dist/docs/patterns/dashboards.md +638 -0
  107. package/dist/docs/patterns/destructive-actions.md +626 -0
  108. package/dist/docs/patterns/empty-states.md +612 -0
  109. package/dist/docs/patterns/errors-and-validation.md +808 -0
  110. package/dist/docs/patterns/feedback-and-status.md +518 -0
  111. package/dist/docs/patterns/forms.md +679 -0
  112. package/dist/docs/patterns/loading.md +630 -0
  113. package/dist/docs/patterns/navigation.md +397 -0
  114. package/dist/docs/patterns/payments.md +765 -0
  115. package/dist/docs/patterns/responsive-layout.md +997 -0
  116. package/dist/docs/patterns/tables-and-lists.md +964 -0
  117. package/dist/docs/products/tempo-console.md +671 -0
  118. package/dist/docs/products/tempo-performance.md +437 -0
  119. package/dist/docs/products/tempo-wallet.md +438 -0
  120. package/package.json +1 -1
@@ -0,0 +1,406 @@
1
+ # Writing Style
2
+
3
+ How Tempo writes interface text: sentence case, a verb first, and plain words.
4
+
5
+ ## Overview
6
+
7
+ Tempo's interface text is short, specific, and plain. It names the thing and the action in words that a reader new to crypto knows.
8
+
9
+ The rules follow [tempo.xyz](https://tempo.xyz) and the [developer docs](https://tempo.xyz/developers). [Where the Sources Differ](#where-the-sources-differ) records the choice for product screens.
10
+
11
+ ## Principles
12
+
13
+ * **Clear Before Clever:** State what happens, in familiar words.
14
+ * **Short:** Cut each word that doesn't change the meaning.
15
+ * **Specific:** Name the action and its object, not Continue.
16
+ * **Consistent:** Call one thing by one name everywhere.
17
+
18
+ ## Capitalization
19
+
20
+ Use sentence case everywhere, capitalizing only the first word and proper nouns.
21
+
22
+ **Do:** Capitalize the first word of each heading, sentence, and label.
23
+
24
+ ```tsx
25
+ /**
26
+ * Do example for "Writing Style" on the Writing Style page.
27
+ * Capitalize the first word of each heading, sentence, and label.
28
+ * @module
29
+ */
30
+ import { Button, style } from '@tempoxyz/ds'
31
+
32
+ /** Renders the static preview, which the guideline card shows inert. */
33
+ export function Demo() {
34
+ return (
35
+ <div {...styles.card()}>
36
+ <p {...styles.title()}>Add funds</p>
37
+ <p {...styles.text()}>Deposit USDC from another wallet or an exchange.</p>
38
+ <Button size="small">Copy deposit address</Button>
39
+ </div>
40
+ )
41
+ }
42
+
43
+ namespace styles {
44
+ export const card = style({
45
+ alignItems: 'flex-start',
46
+ display: 'flex',
47
+ flexDirection: 'column',
48
+ gap: '8',
49
+ maxWidth: '18rem !custom',
50
+ })
51
+
52
+ export const text = style({
53
+ color: 'content.secondary',
54
+ margin: '0 !custom',
55
+ typography: 'body.b2',
56
+ })
57
+
58
+ export const title = style({
59
+ color: 'content.primary',
60
+ margin: '0 !custom',
61
+ typography: 'body.b1Strong',
62
+ })
63
+ }
64
+ ```
65
+
66
+ **Don't:** Capitalize every word, in headings or anywhere else in the interface.
67
+
68
+ ```tsx
69
+ /**
70
+ * Don't example for "Writing Style" on the Writing Style page.
71
+ * Don't capitalize every word, in headings or anywhere else in the interface.
72
+ * @module
73
+ */
74
+ import { Button, style } from '@tempoxyz/ds'
75
+
76
+ /** Renders the static preview, which the guideline card shows inert. */
77
+ export function Demo() {
78
+ return (
79
+ <div {...styles.card()}>
80
+ <p {...styles.title()}>Add Funds</p>
81
+ <p {...styles.text()}>Deposit USDC From Another Wallet or an Exchange.</p>
82
+ <Button size="small">Copy Deposit Address</Button>
83
+ </div>
84
+ )
85
+ }
86
+
87
+ namespace styles {
88
+ export const card = style({
89
+ alignItems: 'flex-start',
90
+ display: 'flex',
91
+ flexDirection: 'column',
92
+ gap: '8',
93
+ maxWidth: '18rem !custom',
94
+ })
95
+
96
+ export const text = style({
97
+ color: 'content.secondary',
98
+ margin: '0 !custom',
99
+ typography: 'body.b2',
100
+ })
101
+
102
+ export const title = style({
103
+ color: 'content.primary',
104
+ margin: '0 !custom',
105
+ typography: 'body.b1Strong',
106
+ })
107
+ }
108
+ ```
109
+
110
+ ### Proper Nouns
111
+
112
+ * **Tempo Products and Standards:** Tempo Wallet, Tempo Explorer, and TIP-20.
113
+ * **Companies and Networks:** Other companies, products, and networks.
114
+ * **People, Places, and Languages:** Including currencies named after a place.
115
+ * **Symbols and Values:** Keep USDC, iOS, and 0x1a2b… exactly as written.
116
+ * **Lowercase Symbols:** Rewrite a sentence that starts with pathUSD.
117
+ * **Features and Concepts:** Keep access key and passkey lowercase in titles.
118
+
119
+ **Do:** Capitalize the product name and nothing else.
120
+
121
+ ```tsx
122
+ <Field.Root>
123
+ <Field.Label>Recipient address</Field.Label>
124
+ <TextInput.Group>
125
+ <TextInput.Control placeholder="0x…" />
126
+ </TextInput.Group>
127
+ <Field.Description>Paste a Tempo address or choose a saved contact.</Field.Description>
128
+ </Field.Root>
129
+ ```
130
+
131
+ **Don't:** Capitalize common words or lowercase a product name.
132
+
133
+ ```tsx
134
+ <Field.Root>
135
+ <Field.Label>Recipient Address</Field.Label>
136
+ <TextInput.Group>
137
+ <TextInput.Control placeholder="0x…" />
138
+ </TextInput.Group>
139
+ <Field.Description>Paste a tempo address or choose a saved Contact.</Field.Description>
140
+ </Field.Root>
141
+ ```
142
+
143
+ ### Never All Caps
144
+
145
+ **Do:** Choose clearer words, or use size and weight sparingly.
146
+
147
+ ```tsx
148
+ <Alert intent="warning">
149
+ <Alert.Icon />
150
+ <Alert.Content>This quote expires in 10 minutes.</Alert.Content>
151
+ </Alert>
152
+ ```
153
+
154
+ **Don't:** Set text in all caps or use capitals for emphasis.
155
+
156
+ ```tsx
157
+ <Alert intent="warning">
158
+ <Alert.Icon />
159
+ <Alert.Content>THIS QUOTE EXPIRES IN 10 MINUTES.</Alert.Content>
160
+ </Alert>
161
+ ```
162
+
163
+ ## Write Labels
164
+
165
+ ### Buttons
166
+
167
+ * **Verb First:** Start each button and menu item with a verb.
168
+ * **Short Labels:** Use one to three words, such as Add funds.
169
+ * **One Label per Action:** Use the same label for an action everywhere.
170
+
171
+ **Do:** Name the action and the object it affects.
172
+
173
+ ```tsx
174
+ <Button>Delete access key</Button>
175
+ ```
176
+
177
+ **Don't:** Use generic labels such as "OK", "Yes", or "Submit".
178
+
179
+ ```tsx
180
+ <Button>OK</Button>
181
+ ```
182
+
183
+ ### Form Labels
184
+
185
+ * **Name the Value:** Use a noun phrase, with no colon or Enter your.
186
+ * **Hints in the Description:** Put format hints in the field's description.
187
+ * **Example Placeholders:** Use a placeholder only for an example value.
188
+ * **Mark the Minority:** Mark optional fields when most are required.
189
+
190
+ ### Headings and Titles
191
+
192
+ * **Name the Page:** Name the page or task, such as API keys.
193
+ * **Verb for a Task:** Start a task title with its verb.
194
+ * **Question to Confirm:** Write a confirmation title as a question.
195
+ * **One Phrase:** Use one phrase, with no end punctuation.
196
+
197
+ ### Links
198
+
199
+ * **Name the Destination:** Name where the link goes.
200
+ * **No Typed Arrows:** Leave out →, and let [ListGroup](/docs/components/list-group) draw a chevron.
201
+
202
+ ### Tooltips
203
+
204
+ * **A Few Words:** Name or clarify the trigger of a [Tooltip](/docs/components/tooltip).
205
+ * **Definitions:** A definition can be one full sentence.
206
+ * **Nothing Essential:** Keep actions and essential details on the page.
207
+
208
+ ### Status Labels
209
+
210
+ * **Short Status:** Use one or two words in a [Badge](/docs/components/badge) or status column.
211
+ * **One Name per Status:** Keep one name for each status on every screen.
212
+
213
+ ## Write Messages
214
+
215
+ ### Structure Error Messages
216
+
217
+ Most errors state three things, in this order.
218
+
219
+ * **What Happened:** State the outcome first, in plain words.
220
+ * **Why:** State the cause if it helps the reader act.
221
+ * **What to Do:** End with the action that resolves it.
222
+ * **Beside a Field:** Lead with the fix when context shows the issue.
223
+ * **Unknown Cause:** Say what to try, not only Something went wrong.
224
+ * **Support Reference:** Add a support reference as secondary text.
225
+
226
+ **Do:** State how to fix the value, with the limit that applies.
227
+
228
+ ```tsx
229
+ /**
230
+ * Do example for "Structure Error Messages" on the Writing Style page.
231
+ * State how to fix the value, with the limit that applies.
232
+ * @module
233
+ */
234
+ import { AmountInput, Field, style, Token } from '@tempoxyz/ds'
235
+
236
+ /** Renders the static preview, which the guideline card shows inert. */
237
+ export function Demo() {
238
+ return (
239
+ <Field.Root invalid {...styles.field()}>
240
+ <AmountInput.Root defaultValue="1500">
241
+ <Field.Label>Amount</Field.Label>
242
+ <AmountInput.Control />
243
+ <Token readOnly symbol="USDC" />
244
+ <Field.Error match>Enter an amount up to your balance of 1,250.00 USDC.</Field.Error>
245
+ </AmountInput.Root>
246
+ </Field.Root>
247
+ )
248
+ }
249
+
250
+ namespace styles {
251
+ export const field = style({ maxWidth: '18rem !custom', width: '100% !custom' })
252
+ }
253
+ ```
254
+
255
+ **Don't:** Show raw error names, codes, or RPC messages as the message.
256
+
257
+ ```tsx
258
+ /**
259
+ * Don't example for "Structure Error Messages" on the Writing Style page.
260
+ * Don't show raw error names, codes, or RPC messages as the message.
261
+ * @module
262
+ */
263
+ import { AmountInput, Field, style, Token } from '@tempoxyz/ds'
264
+
265
+ /** Renders the static preview, which the guideline card shows inert. */
266
+ export function Demo() {
267
+ return (
268
+ <Field.Root invalid {...styles.field()}>
269
+ <AmountInput.Root defaultValue="1500">
270
+ <Field.Label>Amount</Field.Label>
271
+ <AmountInput.Control />
272
+ <Token readOnly symbol="USDC" />
273
+ <Field.Error match>Error: InsufficientBalance</Field.Error>
274
+ </AmountInput.Root>
275
+ </Field.Root>
276
+ )
277
+ }
278
+
279
+ namespace styles {
280
+ export const field = style({ maxWidth: '18rem !custom', width: '100% !custom' })
281
+ }
282
+ ```
283
+
284
+ ### Empty States
285
+
286
+ * **Why It's Empty:** Say why the area has nothing to show.
287
+ * **What to Do Next:** Offer the next step, as [Empty States](/docs/patterns/empty-states) shows.
288
+
289
+ ### Confirmations
290
+
291
+ * **Two to Four Words:** Title a [Toast](/docs/components/toast) with the outcome.
292
+ * **Needed Detail Only:** Describe only needed detail, such as the amount.
293
+ * **Shortcut Actions:** Make each toast action reachable elsewhere too.
294
+
295
+ ## Put the Important Words First
296
+
297
+ Readers scan the first few words of a line.
298
+
299
+ **Do:** Start with the subject, and put conditions after it.
300
+
301
+ ```tsx
302
+ <Alert intent="warning">
303
+ <Alert.Icon />
304
+ <Alert.Content>Transfers over $10,000 need a second approval.</Alert.Content>
305
+ </Alert>
306
+ ```
307
+
308
+ **Don't:** Open with filler or bury the rule at the end.
309
+
310
+ ```tsx
311
+ <Alert intent="warning">
312
+ <Alert.Icon />
313
+ <Alert.Content>Please note that, depending on the amount, a second approval may be needed.</Alert.Content>
314
+ </Alert>
315
+ ```
316
+
317
+ ## Use Plain Words
318
+
319
+ Write for a reader new to crypto.
320
+
321
+ * **Everyday Words:** Say network fee, not gas.
322
+ * **Define at First Use:** Explain a technical term at its first use.
323
+
324
+ ## Address the Reader as You
325
+
326
+ * **Your, Not My:** Use your for what belongs to the reader, not my.
327
+ * **We for Tempo:** Use we only for Tempo as a company, and rarely.
328
+
329
+ **Do:** Address the reader and state what happens next.
330
+
331
+ ```tsx
332
+ <Empty.Root>
333
+ <Empty.Icon>
334
+ <Wallet />
335
+ </Empty.Icon>
336
+ <Empty.Title>No payments yet</Empty.Title>
337
+ <Empty.Description>Payments you send or receive appear here.</Empty.Description>
338
+ </Empty.Root>
339
+ ```
340
+
341
+ **Don't:** Describe the reader in the third person.
342
+
343
+ ```tsx
344
+ <Empty.Root>
345
+ <Empty.Icon>
346
+ <Wallet />
347
+ </Empty.Icon>
348
+ <Empty.Title>No payments yet</Empty.Title>
349
+ <Empty.Description>The user has not made any payments.</Empty.Description>
350
+ </Empty.Root>
351
+ ```
352
+
353
+ ## Keep It Short
354
+
355
+ * **Buttons (1 to 3 words):** A verb and its object.
356
+ * **Headings (under 6 words):** The page or the task.
357
+ * **Descriptions (1 sentence):** The detail that the title leaves out.
358
+ * **Error Messages (1 or 2 sentences):** The outcome, then the fix.
359
+ * **Sentences (under 20 words):** Split a longer sentence in two.
360
+
361
+ **Do:** Cut filler such as please, simply, just, and successfully.
362
+
363
+ ```tsx
364
+ <Alert intent="positive">
365
+ <Alert.Icon />
366
+ <Alert.Content>Payment sent</Alert.Content>
367
+ </Alert>
368
+ ```
369
+
370
+ **Don't:** Pad a message with words that add nothing.
371
+
372
+ ```tsx
373
+ <Alert intent="positive">
374
+ <Alert.Icon />
375
+ <Alert.Content>Your payment was sent successfully</Alert.Content>
376
+ </Alert>
377
+ ```
378
+
379
+ ## Write for Everyone
380
+
381
+ * **Name the Control:** Name the control, not below, above, or click.
382
+ * **Prefer Common Words:** Skip idioms, which translate poorly.
383
+
384
+ ## Where the Sources Differ
385
+
386
+ | Topic | What the sources do | Product screens |
387
+ | --------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------- |
388
+ | Heading case | Site and docs headings use sentence case. The docs home and one docs heading use Title Case. Tempo Performance mixes both. | Sentence case. |
389
+ | Contractions | The docs mix can't with cannot, and doesn't with does not. Tempo Wallet errors use Cannot. | Contractions. |
390
+ | Repeated labels | The marketing site words one contact button two ways. | One label per action. |
391
+ | Link arrows | Some docs links end with →. | No typed arrows. |
392
+ | Colon titles | Some docs and site titles join two phrases with a colon. | One phrase per title. |
393
+
394
+ ## Related
395
+
396
+ [Button](/docs/components/button)
397
+
398
+ Use for button labels.
399
+
400
+ [Field](/docs/components/field)
401
+
402
+ Use for labels, descriptions, and errors.
403
+
404
+ [Errors and Validation](/docs/patterns/errors-and-validation)
405
+
406
+ Covers when and where to show errors.
@@ -0,0 +1,282 @@
1
+ # Iconography
2
+
3
+ Icons from the Tempo catalog, and how to size, color, and label them.
4
+
5
+ ## Overview
6
+
7
+ Icons support a label rather than replace it. Every icon in the catalog shares one grid and stroke weight, so any group of icons reads as one family.
8
+
9
+
10
+
11
+ * **Grid (16 by 16):** Every icon draws on the same square grid.
12
+ * **Size (1em):** An icon matches the font size of its text.
13
+ * **Color (currentColor):** An icon fills with the color of its text.
14
+ * **Imports (one module each):** A build carries only the icons it imports.
15
+
16
+ ```tsx
17
+ import { Send } from '@tempoxyz/ds/icons'
18
+
19
+ export function SendButton() {
20
+ return (
21
+ <Button>
22
+ <Send />
23
+ Send payment
24
+ </Button>
25
+ )
26
+ }
27
+ ```
28
+
29
+ ## Size and Color
30
+
31
+ Components size and color their own icons, so inside a [Button](/docs/components/button) you add only the icon as a child.
32
+
33
+ ### Size
34
+
35
+ * **Beside Text (1em):** The default in buttons, links, and running text.
36
+ * **Beside Titles (20px):** A larger icon beside a section or card title.
37
+ * **Status Icons (20px):** A status icon beside a message, as in a [Toast](/docs/components/toast).
38
+ * **Alert Indicator (16px):** An [Alert](/docs/components/alert) marks its tone with a square in a 16px box.
39
+ * **Modal Icons (24px):** An [IconTile](/docs/components/icon-tile) frames the icon above a modal title.
40
+ * **Standalone Icons (fontSize):** Set its font size, not its width and height.
41
+
42
+ ### Color
43
+
44
+ Set the color on the icon or its parent, with the same roles as text.
45
+
46
+ * **Primary (content.primary):** The default, beside primary labels and text.
47
+ * **Secondary (content.secondary):** Beside metadata, such as an update time.
48
+ * **Status (content.warning):** Only for an icon that reports a status.
49
+
50
+ ## Guidelines
51
+
52
+ ### Pair Icons With Text
53
+
54
+ Drop the label only for actions that are familiar without words, such as Close, Copy, and More. Don't give an icon to only one of several buttons, since it draws attention to that action.
55
+
56
+ **Do:** Use icon-only buttons for actions with a universal icon.
57
+
58
+ ```tsx
59
+ <Button aria-label="Copy address" shape="icon" variant="secondary">
60
+ <Copy />
61
+ </Button>
62
+ <Button aria-label="Delete contact" shape="icon" variant="secondary">
63
+ <Delete />
64
+ </Button>
65
+ ```
66
+
67
+ **Don't:** Drop the label from actions that have no universal icon.
68
+
69
+ ```tsx
70
+ <Button aria-label="Wallets" shape="icon" variant="secondary">
71
+ <Wallet />
72
+ </Button>
73
+ <Button aria-label="Access keys" shape="icon" variant="secondary">
74
+ <Key />
75
+ </Button>
76
+ ```
77
+
78
+ ### Match Icons to Their Text
79
+
80
+ An icon that inherits from its label scales with the type and stays aligned. Any other color reads as a status.
81
+
82
+ **Do:** Let an inline icon inherit the size and color of its label.
83
+
84
+ ```tsx
85
+ /**
86
+ * Do example for "Match Icons to Their Text" on the Iconography page.
87
+ * Let an inline icon inherit the size and color of its label.
88
+ * @module
89
+ */
90
+ import { Copy } from '@tempoxyz/ds/icons'
91
+ import { style } from '@tempoxyz/ds'
92
+
93
+ /** Renders the static preview, which the guideline card shows inert. */
94
+ export function Demo() {
95
+ return (
96
+ <span {...styles.label()}>
97
+ <Copy />
98
+ Copy address
99
+ </span>
100
+ )
101
+ }
102
+
103
+ namespace styles {
104
+ export const label = style({
105
+ alignItems: 'center',
106
+ color: 'content.primary',
107
+ display: 'inline-flex',
108
+ gap: '4',
109
+ typography: 'body.b2Strong',
110
+ })
111
+ }
112
+ ```
113
+
114
+ **Don't:** Enlarge or recolor an inline icon apart from its text.
115
+
116
+ ```tsx
117
+ /**
118
+ * Don't example for "Match Icons to Their Text" on the Iconography page.
119
+ * Don't enlarge or recolor an inline icon apart from its text.
120
+ * @module
121
+ */
122
+ import { Copy } from '@tempoxyz/ds/icons'
123
+ import { style } from '@tempoxyz/ds'
124
+
125
+ /** Renders the static preview, which the guideline card shows inert. */
126
+ export function Demo() {
127
+ return (
128
+ <span {...styles.label()}>
129
+ <Copy {...styles.icon()} />
130
+ Copy address
131
+ </span>
132
+ )
133
+ }
134
+
135
+ namespace styles {
136
+ export const icon = style({ color: 'accent.blue.background', fontSize: '30' })
137
+
138
+ export const label = style({
139
+ alignItems: 'center',
140
+ color: 'content.primary',
141
+ display: 'inline-flex',
142
+ gap: '4',
143
+ typography: 'body.b2Strong',
144
+ })
145
+ }
146
+ ```
147
+
148
+ ### Use Catalog Icons Only
149
+
150
+ Icons from another set break the shared grid and stroke weight. If the catalog lacks an icon, propose one with its use case in the Design System project.
151
+
152
+ **Do:** Draw every icon in a group from the catalog.
153
+
154
+ ```tsx
155
+ /**
156
+ * Do example for "Use Catalog Icons Only" on the Iconography page.
157
+ * Draw every icon in a group from the catalog.
158
+ * @module
159
+ */
160
+ import { Button, style } from '@tempoxyz/ds'
161
+ import { ArrowDownLeft, Send, SwapHorizontal } from '@tempoxyz/ds/icons'
162
+
163
+ /** Renders the static preview, which the guideline card shows inert. */
164
+ export function Demo() {
165
+ return (
166
+ <div {...styles.row()}>
167
+ <Button size="small" variant="secondary">
168
+ <Send />
169
+ Send
170
+ </Button>
171
+ <Button size="small" variant="secondary">
172
+ <ArrowDownLeft />
173
+ Receive
174
+ </Button>
175
+ <Button size="small" variant="secondary">
176
+ <SwapHorizontal />
177
+ Swap
178
+ </Button>
179
+ </div>
180
+ )
181
+ }
182
+
183
+ namespace styles {
184
+ export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '8' })
185
+ }
186
+ ```
187
+
188
+ **Don't:** Mix in an icon from another set.
189
+
190
+ ```tsx
191
+ /**
192
+ * Don't example for "Use Catalog Icons Only" on the Iconography page.
193
+ * Don't mix in an icon from another set.
194
+ * @module
195
+ */
196
+ import { Button, style } from '@tempoxyz/ds'
197
+ import { ArrowDownLeft, Send } from '@tempoxyz/ds/icons'
198
+
199
+ /** Renders the static preview, which the guideline card shows inert. */
200
+ export function Demo() {
201
+ return (
202
+ <div {...styles.row()}>
203
+ <Button size="small" variant="secondary">
204
+ <Send />
205
+ Send
206
+ </Button>
207
+ <Button size="small" variant="secondary">
208
+ <ArrowDownLeft />
209
+ Receive
210
+ </Button>
211
+ <Button size="small" variant="secondary">
212
+ {/* A heavier, rounded stroke on a 24 by 24 grid, as another icon set draws it. */}
213
+ <svg
214
+ aria-hidden="true"
215
+ fill="none"
216
+ stroke="currentColor"
217
+ strokeLinecap="round"
218
+ strokeLinejoin="round"
219
+ strokeWidth="3"
220
+ viewBox="0 0 24 24"
221
+ {...styles.icon()}
222
+ >
223
+ <path d="M4 8h14l-4-4M20 16H6l4 4" />
224
+ </svg>
225
+ Swap
226
+ </Button>
227
+ </div>
228
+ )
229
+ }
230
+
231
+ namespace styles {
232
+ export const icon = style({ height: '1.25em !custom', width: '1.25em !custom' })
233
+
234
+ export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '8' })
235
+ }
236
+ ```
237
+
238
+ * **Token Logos (TokenLogo):** Render token and network logos with [TokenLogo](/docs/components/token-logo).
239
+ * **Account Images (Identicon):** Render accounts with [Avatar](/docs/components/avatar) or [Identicon](/docs/components/identicon).
240
+
241
+ ## Accessibility
242
+
243
+ * **Decorative by Default (aria-hidden):** An icon without `aria-label` or `aria-labelledby` is hidden, so screen readers skip it.
244
+ * **Meaningful Icons (role=img):** Add `aria-label` only if no nearby text states its meaning, such as a lone status icon.
245
+ * **Icon-Only Buttons (aria-label):** Label the button, not the icon. Name the action, such as Close dialog rather than X.
246
+ * **Tooltips (Tooltip):** Pair an icon-only button with a [Tooltip](/docs/components/tooltip) that repeats its label for sighted mouse users.
247
+ * **Contrast (3:1):** Applies to meaningful icons. Both `content.primary` and `content.secondary` pass.
248
+ * **Forced Colors (currentColor):** Icons follow the system text color in forced colors mode, with no extra styles.
249
+
250
+ ## Catalog
251
+
252
+ * **Names (PascalCase):** Names match the design, such as `QRCode`.
253
+ * **Reserved Names (InfinityIcon):** Avoids the JavaScript global `Infinity`.
254
+ * **Shared Names (2):** A second icon with a taken name ends in `2`.
255
+ * **Component Names (as):** Rename on import, such as `TableIcon`.
256
+ * **Raw SVGs (.svg):** The original exports, for use outside React.
257
+
258
+ ```tsx
259
+ import { Table } from '@tempoxyz/ds'
260
+ import { Table as TableIcon } from '@tempoxyz/ds/icons'
261
+ import copyUrl from '@tempoxyz/ds/icons/Copy.svg'
262
+ ```
263
+
264
+
265
+
266
+ ## Related
267
+
268
+ [Button](/docs/components/button)
269
+
270
+ Use for icon buttons and icons beside labels.
271
+
272
+ [IconTile](/docs/components/icon-tile)
273
+
274
+ Use for framed icons in headers and lists.
275
+
276
+ [Tooltip](/docs/components/tooltip)
277
+
278
+ Use for labelling icon buttons.
279
+
280
+ [Color](/docs/foundations/color)
281
+
282
+ Covers icon colors.