@tempoxyz/ds 0.3.10 → 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/README.md +7 -6
  2. package/dist/docs/AGENTS.md +12 -0
  3. package/dist/docs/index.md +145 -0
  4. package/dist/docs/marketing/introduction/getting-started.md +241 -0
  5. package/dist/docs/product/components/accordion.md +489 -0
  6. package/dist/docs/product/components/address-card.md +147 -0
  7. package/dist/docs/product/components/agent-logo.md +194 -0
  8. package/dist/docs/product/components/alert-dialog.md +631 -0
  9. package/dist/docs/product/components/alert.md +448 -0
  10. package/dist/docs/product/components/amount-input.md +305 -0
  11. package/dist/docs/product/components/amount.md +794 -0
  12. package/dist/docs/product/components/app-shell.md +559 -0
  13. package/dist/docs/product/components/asset-chip.md +294 -0
  14. package/dist/docs/product/components/autocomplete.md +620 -0
  15. package/dist/docs/product/components/avatar.md +321 -0
  16. package/dist/docs/product/components/badge.md +339 -0
  17. package/dist/docs/product/components/badged-logo.md +116 -0
  18. package/dist/docs/product/components/banner.md +379 -0
  19. package/dist/docs/product/components/bar-chart.md +208 -0
  20. package/dist/docs/product/components/breadcrumbs.md +380 -0
  21. package/dist/docs/product/components/button-group.md +286 -0
  22. package/dist/docs/product/components/button.md +650 -0
  23. package/dist/docs/product/components/calendar.md +375 -0
  24. package/dist/docs/product/components/callout.md +96 -0
  25. package/dist/docs/product/components/checkbox-group.md +521 -0
  26. package/dist/docs/product/components/checkbox.md +467 -0
  27. package/dist/docs/product/components/choice-group.md +516 -0
  28. package/dist/docs/product/components/choicebox.md +641 -0
  29. package/dist/docs/product/components/code.md +100 -0
  30. package/dist/docs/product/components/combobox.md +939 -0
  31. package/dist/docs/product/components/container.md +257 -0
  32. package/dist/docs/product/components/copy-button.md +642 -0
  33. package/dist/docs/product/components/date-picker.md +514 -0
  34. package/dist/docs/product/components/dialog.md +1332 -0
  35. package/dist/docs/product/components/drawer.md +966 -0
  36. package/dist/docs/product/components/empty.md +340 -0
  37. package/dist/docs/product/components/field.md +570 -0
  38. package/dist/docs/product/components/fieldset.md +398 -0
  39. package/dist/docs/product/components/frame.md +434 -0
  40. package/dist/docs/product/components/gauge.md +299 -0
  41. package/dist/docs/product/components/get-started-visual.md +117 -0
  42. package/dist/docs/product/components/grid.md +288 -0
  43. package/dist/docs/product/components/hero-visual.md +155 -0
  44. package/dist/docs/product/components/hex.md +487 -0
  45. package/dist/docs/product/components/icon-tile.md +292 -0
  46. package/dist/docs/product/components/identicon.md +371 -0
  47. package/dist/docs/product/components/inline.md +233 -0
  48. package/dist/docs/product/components/inset.md +225 -0
  49. package/dist/docs/product/components/kbd.md +423 -0
  50. package/dist/docs/product/components/list-group.md +981 -0
  51. package/dist/docs/product/components/loading-dots.md +237 -0
  52. package/dist/docs/product/components/menu.md +934 -0
  53. package/dist/docs/product/components/native-select.md +204 -0
  54. package/dist/docs/product/components/network-logo.md +248 -0
  55. package/dist/docs/product/components/number-field.md +543 -0
  56. package/dist/docs/product/components/otp-field.md +616 -0
  57. package/dist/docs/product/components/pagination.md +516 -0
  58. package/dist/docs/product/components/popover.md +544 -0
  59. package/dist/docs/product/components/progress.md +388 -0
  60. package/dist/docs/product/components/qr.md +314 -0
  61. package/dist/docs/product/components/radio-group.md +528 -0
  62. package/dist/docs/product/components/secret-value.md +406 -0
  63. package/dist/docs/product/components/select.md +751 -0
  64. package/dist/docs/product/components/separator.md +379 -0
  65. package/dist/docs/product/components/sidebar-menu.md +922 -0
  66. package/dist/docs/product/components/skeleton.md +517 -0
  67. package/dist/docs/product/components/slider.md +539 -0
  68. package/dist/docs/product/components/snippet.md +424 -0
  69. package/dist/docs/product/components/spinner.md +216 -0
  70. package/dist/docs/product/components/split-bar.md +139 -0
  71. package/dist/docs/product/components/split-button.md +464 -0
  72. package/dist/docs/product/components/stack.md +299 -0
  73. package/dist/docs/product/components/status-chip.md +226 -0
  74. package/dist/docs/product/components/status-indicator.md +119 -0
  75. package/dist/docs/product/components/status-row.md +174 -0
  76. package/dist/docs/product/components/stepper.md +451 -0
  77. package/dist/docs/product/components/success-hero.md +157 -0
  78. package/dist/docs/product/components/surface.md +639 -0
  79. package/dist/docs/product/components/switch.md +472 -0
  80. package/dist/docs/product/components/table.md +967 -0
  81. package/dist/docs/product/components/tabs.md +627 -0
  82. package/dist/docs/product/components/tempo-logo.md +185 -0
  83. package/dist/docs/product/components/text-input.md +624 -0
  84. package/dist/docs/product/components/textarea.md +352 -0
  85. package/dist/docs/product/components/toast.md +535 -0
  86. package/dist/docs/product/components/token-logo.md +371 -0
  87. package/dist/docs/product/components/token.md +247 -0
  88. package/dist/docs/product/components/tooltip.md +490 -0
  89. package/dist/docs/product/components/verification-code.md +116 -0
  90. package/dist/docs/product/components/visual.md +249 -0
  91. package/dist/docs/product/components.md +203 -0
  92. package/dist/docs/product/foundations/accessibility.md +377 -0
  93. package/dist/docs/product/foundations/agents.md +150 -0
  94. package/dist/docs/product/foundations/color.md +522 -0
  95. package/dist/docs/product/foundations/content/tone.md +194 -0
  96. package/dist/docs/product/foundations/content/voice.md +194 -0
  97. package/dist/docs/product/foundations/content/writing-style.md +406 -0
  98. package/dist/docs/product/foundations/iconography.md +282 -0
  99. package/dist/docs/product/foundations/intent.md +360 -0
  100. package/dist/docs/product/foundations/layout.md +508 -0
  101. package/dist/docs/product/foundations/linter.md +496 -0
  102. package/dist/docs/product/foundations/motion.md +151 -0
  103. package/dist/docs/product/foundations/radius-and-padding.md +86 -0
  104. package/dist/docs/product/foundations/typography.md +266 -0
  105. package/dist/docs/product/introduction/faq.md +133 -0
  106. package/dist/docs/product/introduction/getting-started.md +377 -0
  107. package/dist/docs/product/patterns/blockchain-values.md +709 -0
  108. package/dist/docs/product/patterns/dashboards.md +638 -0
  109. package/dist/docs/product/patterns/destructive-actions.md +626 -0
  110. package/dist/docs/product/patterns/empty-states.md +612 -0
  111. package/dist/docs/product/patterns/errors-and-validation.md +808 -0
  112. package/dist/docs/product/patterns/feedback-and-status.md +518 -0
  113. package/dist/docs/product/patterns/forms.md +679 -0
  114. package/dist/docs/product/patterns/loading.md +630 -0
  115. package/dist/docs/product/patterns/navigation.md +397 -0
  116. package/dist/docs/product/patterns/payments.md +765 -0
  117. package/dist/docs/product/patterns/responsive-layout.md +997 -0
  118. package/dist/docs/product/patterns/tables-and-lists.md +964 -0
  119. package/dist/docs/product/products/tempo-console.md +671 -0
  120. package/dist/docs/product/products/tempo-performance.md +437 -0
  121. package/dist/docs/product/products/tempo-wallet.md +438 -0
  122. package/dist/marketing/index.d.ts +4 -0
  123. package/dist/marketing/index.d.ts.map +1 -0
  124. package/dist/marketing/index.js +4 -0
  125. package/dist/marketing/index.js.map +1 -0
  126. package/dist/marketing/index.js.zyzz.json +1 -0
  127. package/dist/marketing/vars.d.ts +907 -0
  128. package/dist/marketing/vars.d.ts.map +1 -0
  129. package/dist/marketing/vars.js +15 -0
  130. package/dist/marketing/vars.js.map +1 -0
  131. package/dist/marketing/vars.js.zyzz.json +1 -0
  132. package/dist/marketing/zyzz.config.d.ts +4512 -0
  133. package/dist/marketing/zyzz.config.d.ts.map +1 -0
  134. package/dist/marketing/zyzz.config.js +63 -0
  135. package/dist/marketing/zyzz.config.js.map +1 -0
  136. package/dist/marketing/zyzz.config.js.zyzz.json +1 -0
  137. package/dist/oxlint/index.d.ts +12 -1
  138. package/dist/oxlint/index.d.ts.map +1 -1
  139. package/dist/oxlint/index.js +39 -1
  140. package/dist/oxlint/index.js.map +1 -1
  141. package/dist/oxlint/internal/Docs.d.ts +9 -0
  142. package/dist/oxlint/internal/Docs.d.ts.map +1 -0
  143. package/dist/oxlint/internal/Docs.js +15 -0
  144. package/dist/oxlint/internal/Docs.js.map +1 -0
  145. package/dist/oxlint/internal/Imports.d.ts +1 -1
  146. package/dist/oxlint/internal/Imports.d.ts.map +1 -1
  147. package/dist/oxlint/internal/Imports.js +2 -0
  148. package/dist/oxlint/internal/Imports.js.map +1 -1
  149. package/dist/oxlint/internal/Styles.d.ts +40 -0
  150. package/dist/oxlint/internal/Styles.d.ts.map +1 -0
  151. package/dist/oxlint/internal/Styles.js +194 -0
  152. package/dist/oxlint/internal/Styles.js.map +1 -0
  153. package/dist/oxlint/internal/Tokens.d.ts +16 -0
  154. package/dist/oxlint/internal/Tokens.d.ts.map +1 -0
  155. package/dist/oxlint/internal/Tokens.js +39 -0
  156. package/dist/oxlint/internal/Tokens.js.map +1 -0
  157. package/dist/oxlint/rules/NoCrossSurface.d.ts +2 -2
  158. package/dist/oxlint/rules/NoCrossSurface.js +3 -3
  159. package/dist/oxlint/rules/NoCrossSurface.js.map +1 -1
  160. package/dist/oxlint/rules/NoCustomValues.d.ts +11 -0
  161. package/dist/oxlint/rules/NoCustomValues.d.ts.map +1 -0
  162. package/dist/oxlint/rules/NoCustomValues.js +150 -0
  163. package/dist/oxlint/rules/NoCustomValues.js.map +1 -0
  164. package/dist/oxlint/rules/NoSingleKeyShortcuts.d.ts +11 -0
  165. package/dist/oxlint/rules/NoSingleKeyShortcuts.d.ts.map +1 -0
  166. package/dist/oxlint/rules/NoSingleKeyShortcuts.js +158 -0
  167. package/dist/oxlint/rules/NoSingleKeyShortcuts.js.map +1 -0
  168. package/dist/oxlint/rules/PreferComponent.d.ts +3 -2
  169. package/dist/oxlint/rules/PreferComponent.d.ts.map +1 -1
  170. package/dist/oxlint/rules/PreferComponent.js +11 -4
  171. package/dist/oxlint/rules/PreferComponent.js.map +1 -1
  172. package/dist/oxlint/rules/PreferLayout.d.ts +9 -0
  173. package/dist/oxlint/rules/PreferLayout.d.ts.map +1 -0
  174. package/dist/oxlint/rules/PreferLayout.js +90 -0
  175. package/dist/oxlint/rules/PreferLayout.js.map +1 -0
  176. package/dist/oxlint/rules/PreferProgress.d.ts +9 -0
  177. package/dist/oxlint/rules/PreferProgress.d.ts.map +1 -0
  178. package/dist/oxlint/rules/PreferProgress.js +43 -0
  179. package/dist/oxlint/rules/PreferProgress.js.map +1 -0
  180. package/dist/oxlint/rules/PreferSurface.d.ts +9 -0
  181. package/dist/oxlint/rules/PreferSurface.d.ts.map +1 -0
  182. package/dist/oxlint/rules/PreferSurface.js +55 -0
  183. package/dist/oxlint/rules/PreferSurface.js.map +1 -0
  184. package/dist/oxlint/rules/RequireAccessibleName.d.ts.map +1 -1
  185. package/dist/oxlint/rules/RequireAccessibleName.js +3 -1
  186. package/dist/oxlint/rules/RequireAccessibleName.js.map +1 -1
  187. package/dist/oxlint/rules/RequireScrollRegion.d.ts +11 -0
  188. package/dist/oxlint/rules/RequireScrollRegion.d.ts.map +1 -0
  189. package/dist/oxlint/rules/RequireScrollRegion.js +71 -0
  190. package/dist/oxlint/rules/RequireScrollRegion.js.map +1 -0
  191. package/dist/web/icons/index.js.zyzz.json +1 -0
  192. package/package.json +6 -1
  193. package/src/marketing/README.md +21 -0
  194. package/src/marketing/index.ts +3 -0
  195. package/src/marketing/vars.ts +751 -0
  196. package/src/marketing/zyzz.config.ts +376 -0
  197. package/src/oxlint/index.ts +40 -1
  198. package/src/oxlint/internal/Docs.ts +18 -0
  199. package/src/oxlint/internal/Imports.ts +2 -1
  200. package/src/oxlint/internal/Styles.ts +240 -0
  201. package/src/oxlint/internal/Tokens.ts +43 -0
  202. package/src/oxlint/rules/NoCrossSurface.ts +3 -3
  203. package/src/oxlint/rules/NoCustomValues.ts +170 -0
  204. package/src/oxlint/rules/NoSingleKeyShortcuts.ts +190 -0
  205. package/src/oxlint/rules/PreferComponent.ts +11 -4
  206. package/src/oxlint/rules/PreferLayout.ts +96 -0
  207. package/src/oxlint/rules/PreferProgress.ts +49 -0
  208. package/src/oxlint/rules/PreferSurface.ts +70 -0
  209. package/src/oxlint/rules/RequireAccessibleName.ts +3 -1
  210. package/src/oxlint/rules/RequireScrollRegion.ts +92 -0
@@ -0,0 +1,371 @@
1
+ # TokenLogo
2
+
3
+ Shows a token logo by contract address or symbol.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/TokenLogo.tsx)
6
+
7
+ Figma: [Elements/Logo](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-2546)
8
+
9
+ ## Overview
10
+
11
+ A token logo renders a stablecoin's artwork, found by contract address or symbol, with its brand colors. Its `alt` is empty unless set, which suits a logo beside the token name.
12
+
13
+ ## Examples
14
+
15
+ ### Basic
16
+
17
+ ```tsx
18
+ import { style, TokenLogo } from '@tempoxyz/ds'
19
+
20
+ export function Demo() {
21
+ return (
22
+ <TokenLogo.Provider>
23
+ <div {...styles.row()}>
24
+ <TokenLogo address="0x20c0000000000000000000000000000000000000" />
25
+ pathUSD
26
+ </div>
27
+ </TokenLogo.Provider>
28
+ )
29
+ }
30
+
31
+ namespace styles {
32
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
33
+ }
34
+ ```
35
+
36
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/TokenLogo/Basic.tsx)
37
+
38
+ ### Size
39
+
40
+ Set `size` to `small` (16px), `medium` (20px, default), or `large` (32px).
41
+
42
+ ```tsx
43
+ import { style, TokenLogo } from '@tempoxyz/ds'
44
+
45
+ const tokens = [
46
+ ['pathUSD', '0x20c0000000000000000000000000000000000000'],
47
+ ['USDC.e', '0x20c000000000000000000000b9537d11c60e8b50'],
48
+ ['EURC.e', '0x20c0000000000000000000001621e21f71cf12fb'],
49
+ ['USDT0', '0x20c00000000000000000000014f22ca97301eb73'],
50
+ ['frxUSD', '0x20c0000000000000000000003554d28269e0f3c2'],
51
+ ] as const
52
+
53
+ export function Demo() {
54
+ return (
55
+ <TokenLogo.Provider>
56
+ <div {...styles.grid()}>
57
+ {tokens.map(([label, address]) => (
58
+ <div key={address} {...styles.row()}>
59
+ {(['small', 'medium', 'large'] as const).map((size) => (
60
+ <TokenLogo address={address} key={size} size={size} />
61
+ ))}
62
+ {label}
63
+ </div>
64
+ ))}
65
+ </div>
66
+ </TokenLogo.Provider>
67
+ )
68
+ }
69
+
70
+ namespace styles {
71
+ export const grid = style({ display: 'grid', gap: '12' })
72
+
73
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
74
+ }
75
+ ```
76
+
77
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/TokenLogo/Size.tsx)
78
+
79
+ ### Symbol
80
+
81
+ Pass `symbol` instead of `address` to resolve the token through the token list.
82
+
83
+ ```tsx
84
+ import { style, TokenLogo } from '@tempoxyz/ds'
85
+
86
+ export function Demo() {
87
+ return (
88
+ <TokenLogo.Provider>
89
+ <div {...styles.row()}>
90
+ <TokenLogo size="large" symbol="pathUSD" />
91
+ By symbol: pathUSD
92
+ </div>
93
+ </TokenLogo.Provider>
94
+ )
95
+ }
96
+
97
+ namespace styles {
98
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
99
+ }
100
+ ```
101
+
102
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/TokenLogo/Symbol.tsx)
103
+
104
+ ### Fallback
105
+
106
+ An unknown address or symbol renders a placeholder.
107
+
108
+ ```tsx
109
+ import { style, TokenLogo } from '@tempoxyz/ds'
110
+
111
+ export function Demo() {
112
+ return (
113
+ <TokenLogo.Provider>
114
+ <div {...styles.grid()}>
115
+ <div {...styles.row()}>
116
+ <TokenLogo address="0x0000000000000000000000000000000000000001" size="large" />
117
+ Unknown address (service placeholder)
118
+ </div>
119
+ <div {...styles.row()}>
120
+ <TokenLogo size="large" symbol="UNKNOWN" />
121
+ Unknown symbol (fallback)
122
+ </div>
123
+ </div>
124
+ </TokenLogo.Provider>
125
+ )
126
+ }
127
+
128
+ namespace styles {
129
+ export const grid = style({ display: 'grid', gap: '12' })
130
+
131
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
132
+ }
133
+ ```
134
+
135
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/TokenLogo/Fallback.tsx)
136
+
137
+ ## Anatomy
138
+
139
+ Import the component and assemble its parts.
140
+
141
+ ```tsx
142
+ import { TokenLogo } from '@tempoxyz/ds'
143
+
144
+ <TokenLogo.Provider>
145
+ <TokenLogo />
146
+ </TokenLogo.Provider>
147
+ ```
148
+
149
+ ## Guidelines
150
+
151
+ ### When to Use
152
+
153
+ * Show a token's logo beside its symbol in balance lists, token selectors, payment reviews, and activity rows.
154
+
155
+ ### When Not to Use
156
+
157
+ * Use [Token](token.md) to show which token an amount is in, and to let a person change it.
158
+ * Use [Identicon](identicon.md) for an account address.
159
+ * Use [Avatar](avatar.md) for people and organizations.
160
+ * Use [IconTile](icon-tile.md) for a feature or category icon.
161
+ * Use [NetworkLogo](network-logo.md) for the chain a token lives on.
162
+ * Use [AssetChip](asset-chip.md) to list the assets a row supports.
163
+
164
+ ### Pair the Icon With the Symbol
165
+
166
+ Many token icons look alike, and an unknown token can copy a well-known icon.
167
+
168
+ **Do:** Show the symbol beside each token icon.
169
+
170
+ ```tsx
171
+ /**
172
+ * Do example for "Pair the Icon With the Symbol" on the TokenLogo page.
173
+ * Show the symbol beside each token icon.
174
+ * @module
175
+ */
176
+ import { style, TokenLogo } from '@tempoxyz/ds'
177
+
178
+ const tokens = [
179
+ ['pathUSD', '0x20c0000000000000000000000000000000000000'],
180
+ ['USDC.e', '0x20c000000000000000000000b9537d11c60e8b50'],
181
+ ['EURC.e', '0x20c0000000000000000000001621e21f71cf12fb'],
182
+ ] as const
183
+
184
+ /** Renders the static preview, which the guideline card shows inert. */
185
+ export function Demo() {
186
+ return (
187
+ <TokenLogo.Provider>
188
+ <div {...styles.list()}>
189
+ {tokens.map(([symbol, address]) => (
190
+ <div key={address} {...styles.row()}>
191
+ <TokenLogo address={address} />
192
+ <span {...styles.symbol()}>{symbol}</span>
193
+ </div>
194
+ ))}
195
+ </div>
196
+ </TokenLogo.Provider>
197
+ )
198
+ }
199
+
200
+ namespace styles {
201
+ export const list = style({ display: 'grid', gap: '12' })
202
+
203
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
204
+
205
+ export const symbol = style({ color: 'content.primary', typography: 'body.b2Strong' })
206
+ }
207
+ ```
208
+
209
+ **Don't:** Ask people to tell tokens apart by icon alone.
210
+
211
+ ```tsx
212
+ /**
213
+ * Don't example for "Pair the Icon With the Symbol" on the TokenLogo page.
214
+ * Don't ask people to tell tokens apart by icon alone.
215
+ * @module
216
+ */
217
+ import { style, TokenLogo } from '@tempoxyz/ds'
218
+
219
+ const addresses = [
220
+ '0x20c0000000000000000000000000000000000000',
221
+ '0x20c000000000000000000000b9537d11c60e8b50',
222
+ '0x20c0000000000000000000001621e21f71cf12fb',
223
+ ] as const
224
+
225
+ /** Renders the static preview, which the guideline card shows inert. */
226
+ export function Demo() {
227
+ return (
228
+ <TokenLogo.Provider>
229
+ <div {...styles.row()}>
230
+ {addresses.map((address) => (
231
+ <TokenLogo address={address} key={address} />
232
+ ))}
233
+ </div>
234
+ </TokenLogo.Provider>
235
+ )
236
+ }
237
+
238
+ namespace styles {
239
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
240
+ }
241
+ ```
242
+
243
+ ### Prefer the Address
244
+
245
+ * **Address (address):** Use it when you have it. It loads the image directly and names one contract.
246
+ * **Symbol (symbol):** Resolves through the token list first, which adds a request. Different tokens can share a symbol.
247
+ * **Lists (TokenLogo.Provider):** Wrap lists so tokens share one lookup per symbol and a default `chainId`.
248
+
249
+ Pass `resolveSrc` or `resolveAddress` to `TokenLogo.Provider` to load icons or addresses from your own source.
250
+
251
+ ### Show Unknown Tokens as Unknown
252
+
253
+ A gray circle renders while an icon loads or after it fails.
254
+
255
+ **Do:** Show the address in a [Hex](hex.md) beside the symbol of a token that isn't on the
256
+ list.
257
+
258
+ ```tsx
259
+ /**
260
+ * Do example for "Show Unknown Tokens as Unknown" on the TokenLogo page.
261
+ * Show the address in a Hex beside the symbol of a token that isn't on the list.
262
+ * @module
263
+ */
264
+ import { Hex, style, TokenLogo } from '@tempoxyz/ds'
265
+
266
+ const address = '0x20c00000000000000000000098a3f2c1e5d70b44'
267
+
268
+ /** Renders the static preview, which the guideline card shows inert. */
269
+ export function Demo() {
270
+ return (
271
+ <div {...styles.row()}>
272
+ <TokenLogo address={address} />
273
+ <div {...styles.text()}>
274
+ <span {...styles.symbol()}>USDC</span>
275
+ <Hex size="small" value={address} />
276
+ </div>
277
+ </div>
278
+ )
279
+ }
280
+
281
+ namespace styles {
282
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12', minWidth: '0' })
283
+
284
+ export const symbol = style({ color: 'content.primary', typography: 'body.b2Strong' })
285
+
286
+ export const text = style({ display: 'grid', gap: '4', minWidth: '0' })
287
+ }
288
+ ```
289
+
290
+ **Don't:** Show only the symbol. Any token can claim it.
291
+
292
+ ```tsx
293
+ /**
294
+ * Don't example for "Show Unknown Tokens as Unknown" on the TokenLogo page.
295
+ * Don't show only the symbol. Any token can claim it.
296
+ * @module
297
+ */
298
+ import { style, TokenLogo } from '@tempoxyz/ds'
299
+
300
+ const address = '0x20c00000000000000000000098a3f2c1e5d70b44'
301
+
302
+ /** Renders the static preview, which the guideline card shows inert. */
303
+ export function Demo() {
304
+ return (
305
+ <div {...styles.row()}>
306
+ <TokenLogo address={address} />
307
+ <span {...styles.symbol()}>USDC</span>
308
+ </div>
309
+ )
310
+ }
311
+
312
+ namespace styles {
313
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
314
+
315
+ export const symbol = style({ color: 'content.primary', typography: 'body.b2Strong' })
316
+ }
317
+ ```
318
+
319
+ ### Match Size to the Context
320
+
321
+ * **Small (16px):** Inline beside an amount.
322
+ * **Medium (20px):** The default, and the logo in a [Token](token.md).
323
+ * **Large (32px):** In asset rows and token pickers.
324
+
325
+ ## Accessibility
326
+
327
+ A token logo renders a native `<img>`, decorative by default. It is not interactive and takes no focus.
328
+
329
+ ### Semantics
330
+
331
+ * **Root (img):** Has empty alt text by default, so screen readers skip it beside a visible name.
332
+ * **Loading and Errors:** Renders a gray circle while loading or after an error. Text must identify the token.
333
+ * **Data Status (data-status):** Reports `loading`, `loaded`, or `error` for styling. Screen readers don't announce it.
334
+
335
+ ### Your Responsibilities
336
+
337
+ * **Name a Standalone Icon (alt):** If the icon stands alone, such as in an icon-only selector, pass the token name.
338
+
339
+ ## Related
340
+
341
+ [Amount](amount.md)
342
+
343
+ Use for token amounts.
344
+
345
+ [Token](token.md)
346
+
347
+ Use for a token pill that labels or picks a token.
348
+
349
+ [AssetChip](asset-chip.md)
350
+
351
+ Use for listing the assets a row supports.
352
+
353
+ [NetworkLogo](network-logo.md)
354
+
355
+ Use for the chain a token lives on.
356
+
357
+ [Identicon](identicon.md)
358
+
359
+ Use for account addresses.
360
+
361
+ [Avatar](avatar.md)
362
+
363
+ Use for people and organizations.
364
+
365
+ [Select](select.md)
366
+
367
+ Use for token selectors.
368
+
369
+ [Blockchain Values](../patterns/blockchain-values.md)
370
+
371
+ Covers tokens and addresses.
@@ -0,0 +1,247 @@
1
+ # Token
2
+
3
+ Shows which token an amount is in, and opens a picker to change it.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Token.tsx)
6
+
7
+ Figma: [Elements/Token](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-1266)
8
+
9
+ ## Overview
10
+
11
+ A token renders a pill with a [TokenLogo](token-logo.md) and the token's symbol. By default it is a button with a chevron that opens a token picker. Set `readOnly` for a static pill.
12
+
13
+ ## Examples
14
+
15
+ ### Basic
16
+
17
+ ```tsx
18
+ import { Token, TokenLogo } from '@tempoxyz/ds'
19
+
20
+ export function Demo() {
21
+ return (
22
+ <TokenLogo.Provider>
23
+ <Token address="0x20c0000000000000000000000000000000000000" symbol="pathUSD" />
24
+ </TokenLogo.Provider>
25
+ )
26
+ }
27
+ ```
28
+
29
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Token/Basic.tsx)
30
+
31
+ ### Read-Only
32
+
33
+ Set `readOnly` to render a span without the chevron, for reviews and receipts.
34
+
35
+ ```tsx
36
+ import { Token, TokenLogo } from '@tempoxyz/ds'
37
+
38
+ export function Demo() {
39
+ return (
40
+ <TokenLogo.Provider>
41
+ <Token address="0x20c0000000000000000000000000000000000000" readOnly symbol="pathUSD" />
42
+ </TokenLogo.Provider>
43
+ )
44
+ }
45
+ ```
46
+
47
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Token/ReadOnly.tsx)
48
+
49
+ ### Picker
50
+
51
+ Pass the token to a trigger's `render`, such as a [Dialog](dialog.md) trigger, to open a token picker.
52
+
53
+ ```tsx
54
+ import { Dialog, style, Token, TokenLogo } from '@tempoxyz/ds'
55
+ import { useState } from 'react'
56
+
57
+ const tokens = [
58
+ ['pathUSD', '0x20c0000000000000000000000000000000000000'],
59
+ ['USDC.e', '0x20c000000000000000000000b9537d11c60e8b50'],
60
+ ['USDT0', '0x20c00000000000000000000014f22ca97301eb73'],
61
+ ] as const
62
+
63
+ export function Demo() {
64
+ const [selected, setSelected] = useState<(typeof tokens)[number]>(tokens[0])
65
+
66
+ return (
67
+ <TokenLogo.Provider>
68
+ <Dialog.Root>
69
+ <Dialog.Trigger render={<Token address={selected[1]} symbol={selected[0]} />} />
70
+ <Dialog.Popup closeButton>
71
+ <Dialog.Header>
72
+ <Dialog.Title>Select token</Dialog.Title>
73
+ </Dialog.Header>
74
+ <Dialog.Body>
75
+ <div {...styles.list()}>
76
+ {tokens.map((token) => (
77
+ <Dialog.Close
78
+ key={token[1]}
79
+ onClick={() => setSelected(token)}
80
+ render={<button type="button" {...styles.option()} />}
81
+ >
82
+ <TokenLogo address={token[1]} size="large" />
83
+ {token[0]}
84
+ </Dialog.Close>
85
+ ))}
86
+ </div>
87
+ </Dialog.Body>
88
+ </Dialog.Popup>
89
+ </Dialog.Root>
90
+ </TokenLogo.Provider>
91
+ )
92
+ }
93
+
94
+ namespace styles {
95
+ export const list = style({ display: 'grid', gap: '4' })
96
+
97
+ export const option = style({
98
+ alignItems: 'center',
99
+ backgroundColor: 'transparent !custom',
100
+ border: 'none !custom',
101
+ borderRadius: 'xs',
102
+ color: 'content.primary',
103
+ cursor: 'pointer',
104
+ display: 'flex',
105
+ gap: '12',
106
+ padding: '12',
107
+ textAlign: 'start',
108
+ typography: 'body.b2Strong',
109
+ selectors: { '&:hover': { backgroundColor: 'container.regular' } },
110
+ })
111
+ }
112
+ ```
113
+
114
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Token/Picker.tsx)
115
+
116
+ ## Anatomy
117
+
118
+ Import the component and assemble its parts.
119
+
120
+ ```tsx
121
+ import { Token } from '@tempoxyz/ds'
122
+
123
+ <Token />
124
+ ```
125
+
126
+ ## Guidelines
127
+
128
+ ### When to Use
129
+
130
+ * Name the token after the digits in an [AmountInput](amount-input.md), and let a person change it.
131
+ * Name a fixed token in a review or a receipt with `readOnly`.
132
+
133
+ ### When Not to Use
134
+
135
+ * Use [TokenLogo](token-logo.md) for a logo beside a symbol in a list row.
136
+ * Use [AssetChip](asset-chip.md) to list the assets a row supports.
137
+ * Use [Select](select.md) to choose a token in a form field with a label.
138
+
139
+ ### Show the Chevron Only on a Picker
140
+
141
+ The chevron tells people that the token opens a picker.
142
+
143
+ **Do:** Set `readOnly` in reviews and receipts, where the token can't change.
144
+
145
+ ```tsx
146
+ /**
147
+ * Do example for "Show the Chevron Only on a Picker" on the Token page.
148
+ * Render a read-only pill where the token can't change.
149
+ * @module
150
+ */
151
+ import { style, Token, TokenLogo } from '@tempoxyz/ds'
152
+
153
+ /** Renders the static preview, which the guideline card shows inert. */
154
+ export function Demo() {
155
+ return (
156
+ <TokenLogo.Provider>
157
+ <div {...styles.row()}>
158
+ <span {...styles.amount()}>25.00</span>
159
+ <Token address="0x20c0000000000000000000000000000000000000" readOnly symbol="pathUSD" />
160
+ </div>
161
+ </TokenLogo.Provider>
162
+ )
163
+ }
164
+
165
+ namespace styles {
166
+ export const amount = style({ color: 'content.primary', typography: 'heading.h2' })
167
+
168
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
169
+ }
170
+ ```
171
+
172
+ **Don't:** Show the chevron on a token that opens nothing.
173
+
174
+ ```tsx
175
+ /**
176
+ * Don't example for "Show the Chevron Only on a Picker" on the Token page.
177
+ * A chevron on a token that can't change promises a picker that never opens.
178
+ * @module
179
+ */
180
+ import { style, Token, TokenLogo } from '@tempoxyz/ds'
181
+
182
+ /** Renders the static preview, which the guideline card shows inert. */
183
+ export function Demo() {
184
+ return (
185
+ <TokenLogo.Provider>
186
+ <div {...styles.row()}>
187
+ <span {...styles.amount()}>25.00</span>
188
+ <Token address="0x20c0000000000000000000000000000000000000" symbol="pathUSD" />
189
+ </div>
190
+ </TokenLogo.Provider>
191
+ )
192
+ }
193
+
194
+ namespace styles {
195
+ export const amount = style({ color: 'content.primary', typography: 'heading.h2' })
196
+
197
+ export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
198
+ }
199
+ ```
200
+
201
+ ### Prefer the Address
202
+
203
+ * **Address (address):** Loads the logo directly. `symbol` still labels the pill.
204
+ * **Symbol (symbol):** Resolves the logo through the token list first.
205
+
206
+ ## Content
207
+
208
+ ### Use the Token's Symbol
209
+
210
+ Write the symbol as the token defines it, such as pathUSD or USDC.e. Keep amounts, network names, and verbs outside the pill.
211
+
212
+ ## Accessibility
213
+
214
+ A token renders a native `<button>` built on Base UI Button, or a `<span>` when `readOnly`. The logo and the chevron are hidden from screen readers.
215
+
216
+ ### Semantics
217
+
218
+ * **Root (button):** The symbol names the button. A picker trigger adds popup state.
219
+ * **Read-Only (readOnly):** Renders a span, so screen readers read the symbol as text.
220
+
221
+ ### Keyboard
222
+
223
+ * **Move Focus to the Token (Tab):** Moves focus to the token.
224
+ * **Open the Picker (Enter or Space):** Opens the picker that the token triggers.
225
+
226
+ ### Your Responsibilities
227
+
228
+ * **Open a Picker (render):** Pass the token to a picker trigger's `render`. If nothing opens, set `readOnly`.
229
+ * **Describe the Action (aria-label):** If the symbol alone doesn't say what the token does, add a label that keeps the symbol.
230
+
231
+ ## Related
232
+
233
+ [TokenLogo](token-logo.md)
234
+
235
+ Use for token logos.
236
+
237
+ [AmountInput](amount-input.md)
238
+
239
+ Use for entering an amount beside a token.
240
+
241
+ [AssetChip](asset-chip.md)
242
+
243
+ Use for listing the assets a row supports.
244
+
245
+ [Dialog](dialog.md)
246
+
247
+ Use for a token picker.