@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,116 @@
1
+ # BadgedLogo
2
+
3
+ Marks a token or an app with a small badge on the corner of its logo.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/BadgedLogo.tsx)
6
+
7
+ Figma: [Elements/Badged Logo](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5606-2531) (`BadgedLogo.Root`)
8
+
9
+ ## Overview
10
+
11
+ A badged logo insets a 44px logo in a 56px box and overlaps its lower trailing corner with a 20px badge. The badge holds one icon, such as an arrow that marks the destination of a transfer.
12
+
13
+ ## Examples
14
+
15
+ ### Token
16
+
17
+ ```tsx
18
+ /** Renders a token logo with an arrow badge on the BadgedLogo page. @module */
19
+ import { BadgedLogo, TokenLogo } from '@tempoxyz/ds'
20
+ import { ArrowRight } from '@tempoxyz/ds/icons'
21
+
22
+ export function Demo() {
23
+ return (
24
+ <BadgedLogo.Root>
25
+ <TokenLogo symbol="USDC" />
26
+ <BadgedLogo.Badge>
27
+ <ArrowRight />
28
+ </BadgedLogo.Badge>
29
+ </BadgedLogo.Root>
30
+ )
31
+ }
32
+ ```
33
+
34
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/BadgedLogo/Basic.tsx)
35
+
36
+ ### App
37
+
38
+ An app without artwork takes a tile with the first letter of its name.
39
+
40
+ ```tsx
41
+ /** Renders an app tile with an arrow badge on the BadgedLogo page. @module */
42
+ import { BadgedLogo } from '@tempoxyz/ds'
43
+ import { ArrowRight } from '@tempoxyz/ds/icons'
44
+
45
+ export function Demo() {
46
+ return (
47
+ <BadgedLogo.Root>
48
+ <BadgedLogo.Tile>A</BadgedLogo.Tile>
49
+ <BadgedLogo.Badge>
50
+ <ArrowRight />
51
+ </BadgedLogo.Badge>
52
+ </BadgedLogo.Root>
53
+ )
54
+ }
55
+ ```
56
+
57
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/BadgedLogo/App.tsx)
58
+
59
+ ## Anatomy
60
+
61
+ Import the component and assemble its parts.
62
+
63
+ ```tsx
64
+ import { BadgedLogo } from '@tempoxyz/ds'
65
+
66
+ <BadgedLogo.Root>
67
+ <BadgedLogo.Tile />
68
+ <BadgedLogo.Badge />
69
+ </BadgedLogo.Root>
70
+ ```
71
+
72
+ ## Guidelines
73
+
74
+ ### When to Use
75
+
76
+ * Mark the token or the app at one end of a transfer, such as the destination of a send.
77
+
78
+ ### When Not to Use
79
+
80
+ * Use [TokenLogo](token-logo.md) for a token without a badge.
81
+ * Use [Avatar](avatar.md) for a person, a contact, or a wallet.
82
+ * Use [IconTile](icon-tile.md) for one icon above the title of a modal.
83
+
84
+ ### Put the Logo First and the Badge Last
85
+
86
+ Pass one logo, then one `BadgedLogo.Badge`. The root sizes the logo to 44px, so leave its size unset.
87
+
88
+ ### Use One Small Icon in the Badge
89
+
90
+ The badge centers one 12px icon in the primary color. Do not put text or a second icon in it.
91
+
92
+ ## Content
93
+
94
+ Fill a `BadgedLogo.Tile` with the first letter of the app's name, in uppercase.
95
+
96
+ ## Accessibility
97
+
98
+ A badged logo renders `<span>` elements with no role and takes no focus.
99
+
100
+ * **Logo (img):** A token logo with `alt` announces its name.
101
+ * **Badge (aria-hidden):** An icon without `aria-label` stays hidden.
102
+ * **Meaning in Text:** Name what the badge means in text beside it.
103
+
104
+ ## Related
105
+
106
+ [TokenLogo](token-logo.md)
107
+
108
+ Use for a token logo without a badge.
109
+
110
+ [Avatar](avatar.md)
111
+
112
+ Use for people, contacts, and wallets.
113
+
114
+ [IconTile](icon-tile.md)
115
+
116
+ Use for one icon above the title of a modal.
@@ -0,0 +1,379 @@
1
+ # Banner
2
+
3
+ Shows a full-width message about the system or page.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Banner.tsx)
6
+
7
+ ## Overview
8
+
9
+ A full-width strip for a message about the whole product or page.
10
+
11
+ ## Examples
12
+
13
+ ### Basic
14
+
15
+ ```tsx
16
+ import { Banner } from '@tempoxyz/ds'
17
+
18
+ export const fill = true
19
+ export function Demo() {
20
+ return (
21
+ <Banner>
22
+ <Banner.Content>Tempo mainnet is live.</Banner.Content>
23
+ <Banner.Action>Read more</Banner.Action>
24
+ <Banner.Dismiss />
25
+ </Banner>
26
+ )
27
+ }
28
+ ```
29
+
30
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Banner/Basic.tsx)
31
+
32
+ ### Intent
33
+
34
+ Set `intent` to `neutral` (default), `info`, `positive`, `warning`, or `negative`.
35
+
36
+ ```tsx
37
+ import { Banner, style } from '@tempoxyz/ds'
38
+
39
+ export const fill = true
40
+ export function Demo() {
41
+ return (
42
+ <div {...styles.stack()}>
43
+ {(['neutral', 'info', 'positive', 'warning', 'negative'] as const).map((intent) => (
44
+ <Banner intent={intent} key={intent}>
45
+ <Banner.Content>Tempo mainnet is live.</Banner.Content>
46
+ <Banner.Action>Read more</Banner.Action>
47
+ <Banner.Dismiss />
48
+ </Banner>
49
+ ))}
50
+ </div>
51
+ )
52
+ }
53
+
54
+ namespace styles {
55
+ export const stack = style({ display: 'flex', flexDirection: 'column', gap: '8' })
56
+ }
57
+ ```
58
+
59
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Banner/Intent.tsx)
60
+
61
+ ## Anatomy
62
+
63
+ Import the component and assemble its parts.
64
+
65
+ ```tsx
66
+ import { Banner } from '@tempoxyz/ds'
67
+
68
+ <Banner>
69
+ <Banner.Content />
70
+ <Banner.Action />
71
+ <Banner.Dismiss />
72
+ </Banner>
73
+ ```
74
+
75
+ ## Guidelines
76
+
77
+ ### When to Use
78
+
79
+ * Report a condition that affects the whole product or page, such as degraded RPC service or paused deposits.
80
+ * Announce maintenance or a change for every account, such as a new webhook retry policy.
81
+ * Mark the environment, such as a testnet build of Tempo Wallet.
82
+
83
+ ### When Not to Use
84
+
85
+ * Use [Alert](alert.md) for a message about one section, form, or field.
86
+ * Use [Toast](toast.md) to confirm that an action finished, such as Payment sent.
87
+ * If an action needs a decision before it continues, use [AlertDialog](alert-dialog.md).
88
+ * Use `Field.Error` from [Field](field.md) for a validation message on one input.
89
+
90
+ ### Choose an Intent by Severity
91
+
92
+ * **Neutral (neutral):** The default. Announcements with no severity, such as a testnet notice.
93
+ * **Info (info):** Context that needs no action now, such as upcoming maintenance.
94
+ * **Positive (positive):** A resolved condition, such as resumed deposits.
95
+ * **Warning (warning):** Degraded service or a step to take soon, such as delayed deposits.
96
+ * **Negative (negative):** An outage or failure that blocks work, such as paused payments.
97
+
98
+ ### State Severity in the Text
99
+
100
+ Banner has no icon part, so the text carries the severity. The `intent` tint doesn't reach screen reader users or forced-colors modes.
101
+
102
+ **Do:** Name the affected feature and the impact, such as delayed deposits.
103
+
104
+ ```tsx
105
+ /**
106
+ * Do example for "State Severity in the Text" on the Banner page.
107
+ * Name the affected feature and the impact, such as delayed deposits.
108
+ * @module
109
+ */
110
+ import { Banner } from '@tempoxyz/ds'
111
+
112
+ /** Renders the static preview, which the guideline card shows inert. */
113
+ export function Demo() {
114
+ return (
115
+ <Banner intent="warning">
116
+ <Banner.Content>Deposits from Ethereum are delayed by about 20 minutes.</Banner.Content>
117
+ <Banner.Action>View status</Banner.Action>
118
+ </Banner>
119
+ )
120
+ }
121
+ ```
122
+
123
+ **Don't:** Rely on the `negative` tint to say that something is broken.
124
+
125
+ ```tsx
126
+ /**
127
+ * Don't example for "State Severity in the Text" on the Banner page.
128
+ * Don't rely on the `negative` tint to say that something is broken.
129
+ * @module
130
+ */
131
+ import { Banner } from '@tempoxyz/ds'
132
+
133
+ /** Renders the static preview, which the guideline card shows inert. */
134
+ export function Demo() {
135
+ return (
136
+ <Banner intent="negative">
137
+ <Banner.Content>Heads up</Banner.Content>
138
+ <Banner.Action>Learn more</Banner.Action>
139
+ </Banner>
140
+ )
141
+ }
142
+ ```
143
+
144
+ ### Show One Banner at a Time
145
+
146
+ Hold the less severe messages until the current one clears. Place the banner above the page header.
147
+
148
+ **Do:** Show the single most urgent banner above the page content.
149
+
150
+ ```tsx
151
+ /**
152
+ * Do example for "Show One Banner at a Time" on the Banner page.
153
+ * Show the single most urgent banner above the page content.
154
+ * @module
155
+ */
156
+ import { Banner, style } from '@tempoxyz/ds'
157
+
158
+ /** Renders the static preview, which the guideline card shows inert. */
159
+ export function Demo() {
160
+ return (
161
+ <div {...styles.page()}>
162
+ <Banner intent="negative">
163
+ <Banner.Content>Payments are paused while we fix an RPC outage.</Banner.Content>
164
+ </Banner>
165
+ <div {...styles.content()}>
166
+ <div {...styles.label()}>Balance</div>
167
+ <div {...styles.value()}>$1,250.00</div>
168
+ </div>
169
+ </div>
170
+ )
171
+ }
172
+
173
+ namespace styles {
174
+ export const content = style({
175
+ display: 'flex',
176
+ flexDirection: 'column',
177
+ gap: '4',
178
+ padding: '16',
179
+ })
180
+
181
+ export const label = style({ color: 'content.secondary', typography: 'body.b3' })
182
+
183
+ export const page = style({ display: 'flex', flexDirection: 'column', width: '100% !custom' })
184
+
185
+ export const value = style({ color: 'content.primary', typography: 'heading.h2' })
186
+ }
187
+ ```
188
+
189
+ **Don't:** Stack several banners of different intents.
190
+
191
+ ```tsx
192
+ /**
193
+ * Don't example for "Show One Banner at a Time" on the Banner page.
194
+ * Don't stack several banners of different intents.
195
+ * @module
196
+ */
197
+ import { Banner, style } from '@tempoxyz/ds'
198
+
199
+ /** Renders the static preview, which the guideline card shows inert. */
200
+ export function Demo() {
201
+ return (
202
+ <div {...styles.page()}>
203
+ <Banner intent="negative">
204
+ <Banner.Content>Payments are paused.</Banner.Content>
205
+ </Banner>
206
+ <Banner intent="info">
207
+ <Banner.Content>Maintenance on Oct 22 at 14:00 UTC.</Banner.Content>
208
+ </Banner>
209
+ <Banner>
210
+ <Banner.Content>Webhooks now retry for 24 hours.</Banner.Content>
211
+ <Banner.Dismiss />
212
+ </Banner>
213
+ </div>
214
+ )
215
+ }
216
+
217
+ namespace styles {
218
+ export const page = style({ display: 'flex', flexDirection: 'column', width: '100% !custom' })
219
+ }
220
+ ```
221
+
222
+ ### Limit Dismissal to Announcements
223
+
224
+ `Banner.Dismiss` only renders the button. Remove the banner in its `onClick`, and store the dismissal so the banner doesn't return on the next page.
225
+
226
+ **Do:** Add `Banner.Dismiss` to announcements and `info` messages.
227
+
228
+ ```tsx
229
+ /**
230
+ * Do example for "Limit Dismissal to Announcements" on the Banner page.
231
+ * Add `Banner.Dismiss` to announcements and `info` messages.
232
+ * @module
233
+ */
234
+ import { Banner, style } from '@tempoxyz/ds'
235
+
236
+ /** Renders the static preview, which the guideline card shows inert. */
237
+ export function Demo() {
238
+ return (
239
+ <div {...styles.page()}>
240
+ <Banner intent="info">
241
+ <Banner.Content>Maintenance starts Oct 22 at 14:00 UTC.</Banner.Content>
242
+ <Banner.Dismiss />
243
+ </Banner>
244
+ </div>
245
+ )
246
+ }
247
+
248
+ namespace styles {
249
+ export const page = style({ display: 'flex', flexDirection: 'column', width: '100% !custom' })
250
+ }
251
+ ```
252
+
253
+ **Don't:** Let people dismiss an active outage. Remove the banner when the condition ends.
254
+
255
+ ```tsx
256
+ /**
257
+ * Don't example for "Limit Dismissal to Announcements" on the Banner page.
258
+ * Don't let people dismiss an active outage. Remove the banner when the condition ends.
259
+ * @module
260
+ */
261
+ import { Banner, style } from '@tempoxyz/ds'
262
+
263
+ /** Renders the static preview, which the guideline card shows inert. */
264
+ export function Demo() {
265
+ return (
266
+ <div {...styles.page()}>
267
+ <Banner intent="negative">
268
+ <Banner.Content>Payments are paused during an RPC outage.</Banner.Content>
269
+ <Banner.Dismiss />
270
+ </Banner>
271
+ </div>
272
+ )
273
+ }
274
+
275
+ namespace styles {
276
+ export const page = style({ display: 'flex', flexDirection: 'column', width: '100% !custom' })
277
+ }
278
+ ```
279
+
280
+ ### Offer One Action
281
+
282
+ **Do:** Add at most one `Banner.Action`, such as View status.
283
+
284
+ ```tsx
285
+ /**
286
+ * Do example for "Offer One Action" on the Banner page.
287
+ * Add at most one `Banner.Action`, such as View status.
288
+ * @module
289
+ */
290
+ import { Banner, style } from '@tempoxyz/ds'
291
+
292
+ /** Renders the static preview, which the guideline card shows inert. */
293
+ export function Demo() {
294
+ return (
295
+ <div {...styles.page()}>
296
+ <Banner intent="warning">
297
+ <Banner.Content>Deposits from Ethereum are delayed by about 20 minutes.</Banner.Content>
298
+ <Banner.Action>View status</Banner.Action>
299
+ </Banner>
300
+ </div>
301
+ )
302
+ }
303
+
304
+ namespace styles {
305
+ export const page = style({ display: 'flex', flexDirection: 'column', width: '100% !custom' })
306
+ }
307
+ ```
308
+
309
+ **Don't:** Add several actions to one banner.
310
+
311
+ ```tsx
312
+ /** Don't example for "Offer One Action" on the Banner page. Don't add several actions to one banner. @module */
313
+ import { Banner, style } from '@tempoxyz/ds'
314
+
315
+ /** Renders the static preview, which the guideline card shows inert. */
316
+ export function Demo() {
317
+ return (
318
+ <div {...styles.page()}>
319
+ <Banner intent="warning">
320
+ <Banner.Content>Deposits are delayed.</Banner.Content>
321
+ <Banner.Action>Status</Banner.Action>
322
+ <Banner.Action>Support</Banner.Action>
323
+ <Banner.Action>Retry</Banner.Action>
324
+ </Banner>
325
+ </div>
326
+ )
327
+ }
328
+
329
+ namespace styles {
330
+ export const page = style({ display: 'flex', flexDirection: 'column', width: '100% !custom' })
331
+ }
332
+ ```
333
+
334
+ ## Content
335
+
336
+ * Lead with what changed and who it affects, then what to do: Deposits from Ethereum are delayed by about 20 minutes.
337
+ * Keep it to one or two short sentences.
338
+ * Give times with a time zone, such as Maintenance starts Oct 22 at 14:00 UTC.
339
+ * Describe the condition, not the intent. Write Payments are paused, not Error or Warning.
340
+ * Name the destination in the action label, such as View status. Avoid Click here and Learn more.
341
+
342
+ ## Accessibility
343
+
344
+ Renders a plain `div` with no role and no live region. The action and dismiss controls are native buttons, and the banner never takes focus.
345
+
346
+ ### Semantics
347
+
348
+ * **Banner (div):** Not a landmark or live region. Screen readers read it in order, so place it before the main content.
349
+ * **Banner.Action (button):** To make it a link, pass `render` with a link and `nativeButton={false}`.
350
+ * **Banner.Dismiss (button):** Named "Dismiss" by default. Its close icon is decorative.
351
+
352
+ ### Keyboard
353
+
354
+ * **Move to the Next Control (Tab):** Focuses the action, then the dismiss button.
355
+ * **Activate the Button (Enter or Space):** Activates the action or the dismiss button.
356
+
357
+ ### Your Responsibilities
358
+
359
+ * **Announce Late Banners (role):** If a banner appears after page load, add `role="status"`, or `role="alert"` for an outage.
360
+ * **Move Focus on Dismiss:** After a dismissal, move focus to the start of the main content.
361
+ * **Name Each Dismiss (aria-label):** If a page has several, name each one, such as "Dismiss maintenance notice".
362
+
363
+ ## Related
364
+
365
+ [Alert](alert.md)
366
+
367
+ Use for a message about one section.
368
+
369
+ [Toast](toast.md)
370
+
371
+ Use for confirming a finished action.
372
+
373
+ [AlertDialog](alert-dialog.md)
374
+
375
+ Use for a decision before an action continues.
376
+
377
+ [Feedback and Status](../patterns/feedback-and-status.md)
378
+
379
+ Covers choosing a message component.
@@ -0,0 +1,208 @@
1
+ # BarChart
2
+
3
+ Shows values over time as stacked bars, such as the daily spend of each agent.
4
+
5
+ [View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/BarChart.tsx)
6
+
7
+ Figma: [Data/Chart Tooltip](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-5422) (`BarChart.Tooltip`), [Data/Stacked Bar Chart](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-4523)
8
+
9
+ ## Overview
10
+
11
+ A bar chart renders one bar per entry of its data, with a segment for each series stacked from the baseline. A value axis with three even ticks leads the plot, labels name the bars under it, and a legend names each series. Hovering a bar, or moving to it with the arrow keys, shows the value of each series. Values are zero or more, such as spend or counts. Chart a signed change, such as a refund, another way.
12
+
13
+ ## Examples
14
+
15
+ ### Basic
16
+
17
+ ```tsx
18
+ import { BarChart } from '@tempoxyz/ds'
19
+
20
+ const days = ['Oct 1', 'Oct 2', 'Oct 3', 'Oct 4', 'Oct 5', 'Oct 6', 'Today']
21
+
22
+ export function Demo() {
23
+ return (
24
+ <BarChart
25
+ aria-label="Spend by agent"
26
+ data={days.map((day, index) => ({
27
+ claude: [1.2, 0.8, 2.1, 0, 1.6, 2.4, 1.1][index]!,
28
+ codex: [0.4, 0.9, 0.3, 0, 1.2, 0.6, 0.8][index]!,
29
+ day,
30
+ }))}
31
+ format={(value) => `$${value}`}
32
+ index="day"
33
+ series={[
34
+ { color: '#d97757', key: 'claude', label: 'Claude' },
35
+ { color: '#10a37f', key: 'codex', label: 'Codex' },
36
+ ]}
37
+ />
38
+ )
39
+ }
40
+ ```
41
+
42
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/BarChart/Basic.tsx)
43
+
44
+ ### Ticks
45
+
46
+ Pass `ticks` to label only some bars, such as every seventh day.
47
+
48
+ ```tsx
49
+ import { BarChart } from '@tempoxyz/ds'
50
+
51
+ const days = Array.from({ length: 30 }, (_, index) => (index === 29 ? 'Today' : `Oct ${index + 1}`))
52
+
53
+ export function Demo() {
54
+ return (
55
+ <BarChart
56
+ aria-label="Spend over 30 days"
57
+ data={days.map((day, index) => ({ claude: ((index * 7) % 11) / 4, day }))}
58
+ format={(value) => `$${value}`}
59
+ index="day"
60
+ series={[{ color: '#d97757', key: 'claude', label: 'Claude' }]}
61
+ ticks={['Oct 1', 'Oct 8', 'Oct 15', 'Oct 22', 'Today']}
62
+ />
63
+ )
64
+ }
65
+ ```
66
+
67
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/BarChart/Ticks.tsx)
68
+
69
+ ### Tooltip
70
+
71
+ `BarChart.Tooltip` renders the card that a hovered bar shows, which also renders alone.
72
+
73
+ ```tsx
74
+ import { BarChart } from '@tempoxyz/ds'
75
+
76
+ export function Demo() {
77
+ return (
78
+ <BarChart.Tooltip
79
+ items={[
80
+ { color: '#0a0a0a', label: 'CLI', value: '$3.27' },
81
+ { color: '#10a37f', label: 'Codex', value: '$0.90' },
82
+ { color: '#1f1f1f', label: 'Cursor', value: '$0.10' },
83
+ ]}
84
+ label="Oct 12"
85
+ total="$4.32"
86
+ />
87
+ )
88
+ }
89
+ ```
90
+
91
+ [View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/BarChart/Tooltip.tsx)
92
+
93
+ ## Anatomy
94
+
95
+ Import the component and assemble its parts.
96
+
97
+ ```tsx
98
+ import { BarChart } from '@tempoxyz/ds'
99
+
100
+ <BarChart />
101
+ <BarChart.Tooltip />
102
+ ```
103
+
104
+ ## Guidelines
105
+
106
+ ### When to Use
107
+
108
+ * Show how a value changes over days or weeks, and which series make it up.
109
+
110
+ ### When Not to Use
111
+
112
+ * Use [SplitBar](split-bar.md) to split one total between two parts.
113
+ * Use [Table](table.md) when people need to read or compare exact values.
114
+ * Use [Gauge](gauge.md) for one value against a limit.
115
+
116
+ ### Keep Each Series in One Color
117
+
118
+ **Do:** Give each series a color that stays the same wherever it appears, such as the agent's own color.
119
+
120
+ ```tsx
121
+ import { BarChart } from '@tempoxyz/ds'
122
+
123
+ const days = ['Oct 1', 'Oct 2', 'Oct 3', 'Today']
124
+
125
+ export function Demo() {
126
+ return (
127
+ <BarChart
128
+ aria-label="Spend by agent"
129
+ data={days.map((day, index) => ({ claude: index + 1, codex: 1, day }))}
130
+ format={(value) => `$${value}`}
131
+ height={140}
132
+ index="day"
133
+ series={[
134
+ { color: '#d97757', key: 'claude', label: 'Claude' },
135
+ { color: '#10a37f', key: 'codex', label: 'Codex' },
136
+ ]}
137
+ />
138
+ )
139
+ }
140
+ ```
141
+
142
+ **Don't:** Use the positive and negative colors for series. They mean a status.
143
+
144
+ ```tsx
145
+ import { BarChart } from '@tempoxyz/ds'
146
+
147
+ const days = ['Oct 1', 'Oct 2', 'Oct 3', 'Today']
148
+
149
+ export function Demo() {
150
+ return (
151
+ <BarChart
152
+ aria-label="Spend by agent"
153
+ data={days.map((day, index) => ({ claude: index + 1, codex: 1, day }))}
154
+ format={(value) => `$${value}`}
155
+ height={140}
156
+ index="day"
157
+ series={[
158
+ { color: '#13a963', key: 'claude', label: 'Claude' },
159
+ { color: '#eb3417', key: 'codex', label: 'Codex' },
160
+ ]}
161
+ />
162
+ )
163
+ }
164
+ ```
165
+
166
+ ### Label a Few Bars
167
+
168
+ * **Every Bar (up to 7):** Label every bar of a week.
169
+ * **Every Seventh Bar (ticks):** Label every seventh bar of a month.
170
+
171
+ ## Content
172
+
173
+ ### Format Values the Same Way
174
+
175
+ Pass one `format` for the axis, the tooltip, and the total, such as whole dollars. Name each series with the name people know it by, such as Claude.
176
+
177
+ ## Accessibility
178
+
179
+ A bar chart renders a `<div>` with the `figure` role. Its plot takes focus, and the arrow keys move between bars and show their tooltip.
180
+
181
+ ### Semantics
182
+
183
+ * **Root (figure):** Screen readers announce the chart by its `aria-label`.
184
+ * **Legend (text):** The legend names each series in text, so color is never the only cue.
185
+
186
+ ### Keyboard
187
+
188
+ * **Move Focus to the Plot (Tab):** Moves focus to the plot, which shows the first bar's tooltip.
189
+ * **Move Between Bars (Left or Right Arrow):** Moves to the previous or next bar and shows its tooltip.
190
+
191
+ ### Your Responsibilities
192
+
193
+ * **Name the Chart (aria-label):** Pass `aria-label`, or `aria-labelledby` pointing at the chart's heading.
194
+ * **Offer the Values (Table):** Offer the same values in a [Table](table.md) when people need exact values.
195
+
196
+ ## Related
197
+
198
+ [SplitBar](split-bar.md)
199
+
200
+ Use for one total split between two parts.
201
+
202
+ [AgentLogo](agent-logo.md)
203
+
204
+ Use for the agent of each series.
205
+
206
+ [Table](table.md)
207
+
208
+ Use for exact values.