@tempoxyz/ds 0.3.10 → 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/dist/docs/AGENTS.md +12 -0
- package/dist/docs/index.md +145 -0
- package/dist/docs/marketing/introduction/getting-started.md +241 -0
- package/dist/docs/product/components/accordion.md +489 -0
- package/dist/docs/product/components/address-card.md +147 -0
- package/dist/docs/product/components/agent-logo.md +194 -0
- package/dist/docs/product/components/alert-dialog.md +631 -0
- package/dist/docs/product/components/alert.md +448 -0
- package/dist/docs/product/components/amount-input.md +305 -0
- package/dist/docs/product/components/amount.md +794 -0
- package/dist/docs/product/components/app-shell.md +559 -0
- package/dist/docs/product/components/asset-chip.md +294 -0
- package/dist/docs/product/components/autocomplete.md +620 -0
- package/dist/docs/product/components/avatar.md +321 -0
- package/dist/docs/product/components/badge.md +339 -0
- package/dist/docs/product/components/badged-logo.md +116 -0
- package/dist/docs/product/components/banner.md +379 -0
- package/dist/docs/product/components/bar-chart.md +208 -0
- package/dist/docs/product/components/breadcrumbs.md +380 -0
- package/dist/docs/product/components/button-group.md +286 -0
- package/dist/docs/product/components/button.md +650 -0
- package/dist/docs/product/components/calendar.md +375 -0
- package/dist/docs/product/components/callout.md +96 -0
- package/dist/docs/product/components/checkbox-group.md +521 -0
- package/dist/docs/product/components/checkbox.md +467 -0
- package/dist/docs/product/components/choice-group.md +516 -0
- package/dist/docs/product/components/choicebox.md +641 -0
- package/dist/docs/product/components/code.md +100 -0
- package/dist/docs/product/components/combobox.md +939 -0
- package/dist/docs/product/components/container.md +257 -0
- package/dist/docs/product/components/copy-button.md +642 -0
- package/dist/docs/product/components/date-picker.md +514 -0
- package/dist/docs/product/components/dialog.md +1332 -0
- package/dist/docs/product/components/drawer.md +966 -0
- package/dist/docs/product/components/empty.md +340 -0
- package/dist/docs/product/components/field.md +570 -0
- package/dist/docs/product/components/fieldset.md +398 -0
- package/dist/docs/product/components/frame.md +434 -0
- package/dist/docs/product/components/gauge.md +299 -0
- package/dist/docs/product/components/get-started-visual.md +117 -0
- package/dist/docs/product/components/grid.md +288 -0
- package/dist/docs/product/components/hero-visual.md +155 -0
- package/dist/docs/product/components/hex.md +487 -0
- package/dist/docs/product/components/icon-tile.md +292 -0
- package/dist/docs/product/components/identicon.md +371 -0
- package/dist/docs/product/components/inline.md +233 -0
- package/dist/docs/product/components/inset.md +225 -0
- package/dist/docs/product/components/kbd.md +423 -0
- package/dist/docs/product/components/list-group.md +981 -0
- package/dist/docs/product/components/loading-dots.md +237 -0
- package/dist/docs/product/components/menu.md +934 -0
- package/dist/docs/product/components/native-select.md +204 -0
- package/dist/docs/product/components/network-logo.md +248 -0
- package/dist/docs/product/components/number-field.md +543 -0
- package/dist/docs/product/components/otp-field.md +616 -0
- package/dist/docs/product/components/pagination.md +516 -0
- package/dist/docs/product/components/popover.md +544 -0
- package/dist/docs/product/components/progress.md +388 -0
- package/dist/docs/product/components/qr.md +314 -0
- package/dist/docs/product/components/radio-group.md +528 -0
- package/dist/docs/product/components/secret-value.md +406 -0
- package/dist/docs/product/components/select.md +751 -0
- package/dist/docs/product/components/separator.md +379 -0
- package/dist/docs/product/components/sidebar-menu.md +922 -0
- package/dist/docs/product/components/skeleton.md +517 -0
- package/dist/docs/product/components/slider.md +539 -0
- package/dist/docs/product/components/snippet.md +424 -0
- package/dist/docs/product/components/spinner.md +216 -0
- package/dist/docs/product/components/split-bar.md +139 -0
- package/dist/docs/product/components/split-button.md +464 -0
- package/dist/docs/product/components/stack.md +299 -0
- package/dist/docs/product/components/status-chip.md +226 -0
- package/dist/docs/product/components/status-indicator.md +119 -0
- package/dist/docs/product/components/status-row.md +174 -0
- package/dist/docs/product/components/stepper.md +451 -0
- package/dist/docs/product/components/success-hero.md +157 -0
- package/dist/docs/product/components/surface.md +639 -0
- package/dist/docs/product/components/switch.md +472 -0
- package/dist/docs/product/components/table.md +967 -0
- package/dist/docs/product/components/tabs.md +627 -0
- package/dist/docs/product/components/tempo-logo.md +185 -0
- package/dist/docs/product/components/text-input.md +624 -0
- package/dist/docs/product/components/textarea.md +352 -0
- package/dist/docs/product/components/toast.md +535 -0
- package/dist/docs/product/components/token-logo.md +371 -0
- package/dist/docs/product/components/token.md +247 -0
- package/dist/docs/product/components/tooltip.md +490 -0
- package/dist/docs/product/components/verification-code.md +116 -0
- package/dist/docs/product/components/visual.md +249 -0
- package/dist/docs/product/components.md +203 -0
- package/dist/docs/product/foundations/accessibility.md +377 -0
- package/dist/docs/product/foundations/agents.md +150 -0
- package/dist/docs/product/foundations/color.md +522 -0
- package/dist/docs/product/foundations/content/tone.md +194 -0
- package/dist/docs/product/foundations/content/voice.md +194 -0
- package/dist/docs/product/foundations/content/writing-style.md +406 -0
- package/dist/docs/product/foundations/iconography.md +282 -0
- package/dist/docs/product/foundations/intent.md +360 -0
- package/dist/docs/product/foundations/layout.md +508 -0
- package/dist/docs/product/foundations/linter.md +496 -0
- package/dist/docs/product/foundations/motion.md +151 -0
- package/dist/docs/product/foundations/radius-and-padding.md +86 -0
- package/dist/docs/product/foundations/typography.md +266 -0
- package/dist/docs/product/introduction/faq.md +133 -0
- package/dist/docs/product/introduction/getting-started.md +377 -0
- package/dist/docs/product/patterns/blockchain-values.md +709 -0
- package/dist/docs/product/patterns/dashboards.md +638 -0
- package/dist/docs/product/patterns/destructive-actions.md +626 -0
- package/dist/docs/product/patterns/empty-states.md +612 -0
- package/dist/docs/product/patterns/errors-and-validation.md +808 -0
- package/dist/docs/product/patterns/feedback-and-status.md +518 -0
- package/dist/docs/product/patterns/forms.md +679 -0
- package/dist/docs/product/patterns/loading.md +630 -0
- package/dist/docs/product/patterns/navigation.md +397 -0
- package/dist/docs/product/patterns/payments.md +765 -0
- package/dist/docs/product/patterns/responsive-layout.md +997 -0
- package/dist/docs/product/patterns/tables-and-lists.md +964 -0
- package/dist/docs/product/products/tempo-console.md +671 -0
- package/dist/docs/product/products/tempo-performance.md +437 -0
- package/dist/docs/product/products/tempo-wallet.md +438 -0
- package/dist/marketing/index.d.ts +4 -0
- package/dist/marketing/index.d.ts.map +1 -0
- package/dist/marketing/index.js +4 -0
- package/dist/marketing/index.js.map +1 -0
- package/dist/marketing/index.js.zyzz.json +1 -0
- package/dist/marketing/vars.d.ts +907 -0
- package/dist/marketing/vars.d.ts.map +1 -0
- package/dist/marketing/vars.js +15 -0
- package/dist/marketing/vars.js.map +1 -0
- package/dist/marketing/vars.js.zyzz.json +1 -0
- package/dist/marketing/zyzz.config.d.ts +4512 -0
- package/dist/marketing/zyzz.config.d.ts.map +1 -0
- package/dist/marketing/zyzz.config.js +63 -0
- package/dist/marketing/zyzz.config.js.map +1 -0
- package/dist/marketing/zyzz.config.js.zyzz.json +1 -0
- package/dist/oxlint/index.d.ts +12 -1
- package/dist/oxlint/index.d.ts.map +1 -1
- package/dist/oxlint/index.js +39 -1
- package/dist/oxlint/index.js.map +1 -1
- package/dist/oxlint/internal/Docs.d.ts +9 -0
- package/dist/oxlint/internal/Docs.d.ts.map +1 -0
- package/dist/oxlint/internal/Docs.js +15 -0
- package/dist/oxlint/internal/Docs.js.map +1 -0
- package/dist/oxlint/internal/Imports.d.ts +1 -1
- package/dist/oxlint/internal/Imports.d.ts.map +1 -1
- package/dist/oxlint/internal/Imports.js +2 -0
- package/dist/oxlint/internal/Imports.js.map +1 -1
- package/dist/oxlint/internal/Styles.d.ts +40 -0
- package/dist/oxlint/internal/Styles.d.ts.map +1 -0
- package/dist/oxlint/internal/Styles.js +194 -0
- package/dist/oxlint/internal/Styles.js.map +1 -0
- package/dist/oxlint/internal/Tokens.d.ts +16 -0
- package/dist/oxlint/internal/Tokens.d.ts.map +1 -0
- package/dist/oxlint/internal/Tokens.js +39 -0
- package/dist/oxlint/internal/Tokens.js.map +1 -0
- package/dist/oxlint/rules/NoCrossSurface.d.ts +2 -2
- package/dist/oxlint/rules/NoCrossSurface.js +3 -3
- package/dist/oxlint/rules/NoCrossSurface.js.map +1 -1
- package/dist/oxlint/rules/NoCustomValues.d.ts +11 -0
- package/dist/oxlint/rules/NoCustomValues.d.ts.map +1 -0
- package/dist/oxlint/rules/NoCustomValues.js +150 -0
- package/dist/oxlint/rules/NoCustomValues.js.map +1 -0
- package/dist/oxlint/rules/NoSingleKeyShortcuts.d.ts +11 -0
- package/dist/oxlint/rules/NoSingleKeyShortcuts.d.ts.map +1 -0
- package/dist/oxlint/rules/NoSingleKeyShortcuts.js +158 -0
- package/dist/oxlint/rules/NoSingleKeyShortcuts.js.map +1 -0
- package/dist/oxlint/rules/PreferComponent.d.ts +3 -2
- package/dist/oxlint/rules/PreferComponent.d.ts.map +1 -1
- package/dist/oxlint/rules/PreferComponent.js +11 -4
- package/dist/oxlint/rules/PreferComponent.js.map +1 -1
- package/dist/oxlint/rules/PreferLayout.d.ts +9 -0
- package/dist/oxlint/rules/PreferLayout.d.ts.map +1 -0
- package/dist/oxlint/rules/PreferLayout.js +90 -0
- package/dist/oxlint/rules/PreferLayout.js.map +1 -0
- package/dist/oxlint/rules/PreferProgress.d.ts +9 -0
- package/dist/oxlint/rules/PreferProgress.d.ts.map +1 -0
- package/dist/oxlint/rules/PreferProgress.js +43 -0
- package/dist/oxlint/rules/PreferProgress.js.map +1 -0
- package/dist/oxlint/rules/PreferSurface.d.ts +9 -0
- package/dist/oxlint/rules/PreferSurface.d.ts.map +1 -0
- package/dist/oxlint/rules/PreferSurface.js +55 -0
- package/dist/oxlint/rules/PreferSurface.js.map +1 -0
- package/dist/oxlint/rules/RequireAccessibleName.d.ts.map +1 -1
- package/dist/oxlint/rules/RequireAccessibleName.js +3 -1
- package/dist/oxlint/rules/RequireAccessibleName.js.map +1 -1
- package/dist/oxlint/rules/RequireScrollRegion.d.ts +11 -0
- package/dist/oxlint/rules/RequireScrollRegion.d.ts.map +1 -0
- package/dist/oxlint/rules/RequireScrollRegion.js +71 -0
- package/dist/oxlint/rules/RequireScrollRegion.js.map +1 -0
- package/dist/web/icons/index.js.zyzz.json +1 -0
- package/package.json +6 -1
- package/src/marketing/README.md +21 -0
- package/src/marketing/index.ts +3 -0
- package/src/marketing/vars.ts +751 -0
- package/src/marketing/zyzz.config.ts +376 -0
- package/src/oxlint/index.ts +40 -1
- package/src/oxlint/internal/Docs.ts +18 -0
- package/src/oxlint/internal/Imports.ts +2 -1
- package/src/oxlint/internal/Styles.ts +240 -0
- package/src/oxlint/internal/Tokens.ts +43 -0
- package/src/oxlint/rules/NoCrossSurface.ts +3 -3
- package/src/oxlint/rules/NoCustomValues.ts +170 -0
- package/src/oxlint/rules/NoSingleKeyShortcuts.ts +190 -0
- package/src/oxlint/rules/PreferComponent.ts +11 -4
- package/src/oxlint/rules/PreferLayout.ts +96 -0
- package/src/oxlint/rules/PreferProgress.ts +49 -0
- package/src/oxlint/rules/PreferSurface.ts +70 -0
- package/src/oxlint/rules/RequireAccessibleName.ts +3 -1
- package/src/oxlint/rules/RequireScrollRegion.ts +92 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
# Surface
|
|
2
|
+
|
|
3
|
+
A card container for grouping related content.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Surface.tsx)
|
|
6
|
+
|
|
7
|
+
Figma: [Content/Card](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-5510)
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
A surface renders a `div` with a thin border by default. Its `size` sets the corner radius and the padding to the same value.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Basic
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { style, Surface } from '@tempoxyz/ds'
|
|
19
|
+
import { SwapHorizontal } from '@tempoxyz/ds/icons'
|
|
20
|
+
|
|
21
|
+
export function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<div {...styles.grid()}>
|
|
24
|
+
<Surface>
|
|
25
|
+
<Surface.Header>
|
|
26
|
+
<Surface.Title>
|
|
27
|
+
<SwapHorizontal />
|
|
28
|
+
Routes
|
|
29
|
+
</Surface.Title>
|
|
30
|
+
</Surface.Header>
|
|
31
|
+
<Surface.Description>
|
|
32
|
+
Move stablecoins between Tempo and other networks.
|
|
33
|
+
</Surface.Description>
|
|
34
|
+
<Surface.Links>
|
|
35
|
+
<a href="#basic">Make a transfer</a>
|
|
36
|
+
<a href="#basic">Accept deposits</a>
|
|
37
|
+
<a href="#basic">Supported routes</a>
|
|
38
|
+
</Surface.Links>
|
|
39
|
+
</Surface>
|
|
40
|
+
</div>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
namespace styles {
|
|
45
|
+
export const grid = style({
|
|
46
|
+
alignItems: 'start',
|
|
47
|
+
backgroundColor: 'background.primary',
|
|
48
|
+
display: 'grid',
|
|
49
|
+
gap: '12',
|
|
50
|
+
padding: '16',
|
|
51
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(14rem, 1fr)) !custom',
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Surface/Basic.tsx)
|
|
57
|
+
|
|
58
|
+
### Header
|
|
59
|
+
|
|
60
|
+
Place a `Surface.Title` and an optional action inside `Surface.Header`.
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { Button, style, Surface, TokenLogo } from '@tempoxyz/ds'
|
|
64
|
+
|
|
65
|
+
const balances = [
|
|
66
|
+
['Bridged USDC (Stargate)', '0x20c000000000000000000000b9537d11c60e8b50', '$2.02'],
|
|
67
|
+
['pathUSD', '0x20c0000000000000000000000000000000000000', '$0.12'],
|
|
68
|
+
['USDT0', '0x20c00000000000000000000014f22ca97301eb73', '$0.10'],
|
|
69
|
+
] as const
|
|
70
|
+
|
|
71
|
+
export function Demo() {
|
|
72
|
+
return (
|
|
73
|
+
<div {...styles.grid()}>
|
|
74
|
+
<Surface>
|
|
75
|
+
<Surface.Header>
|
|
76
|
+
<Surface.Title>Balances</Surface.Title>
|
|
77
|
+
<Button size="small" variant="tertiary">
|
|
78
|
+
View all
|
|
79
|
+
</Button>
|
|
80
|
+
</Surface.Header>
|
|
81
|
+
{balances.map(([name, address, amount]) => (
|
|
82
|
+
<div key={address} {...styles.balance()}>
|
|
83
|
+
<TokenLogo address={address} />
|
|
84
|
+
<span {...styles.name()}>{name}</span>
|
|
85
|
+
{amount}
|
|
86
|
+
</div>
|
|
87
|
+
))}
|
|
88
|
+
</Surface>
|
|
89
|
+
</div>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
namespace styles {
|
|
94
|
+
export const balance = style({
|
|
95
|
+
alignItems: 'center',
|
|
96
|
+
columnGap: '12',
|
|
97
|
+
display: 'flex',
|
|
98
|
+
paddingBlock: '8',
|
|
99
|
+
typography: 'body.b1Strong',
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
export const grid = style({
|
|
103
|
+
backgroundColor: 'background.primary',
|
|
104
|
+
display: 'grid',
|
|
105
|
+
padding: '16',
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
export const name = style({ flex: '1 !custom' })
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Surface/Header.tsx)
|
|
113
|
+
|
|
114
|
+
### List
|
|
115
|
+
|
|
116
|
+
A [ListGroup](list-group.md) inside a surface bleeds into its padding, so a row's hover fill reaches the edges of the surface. Each row is 44px, and a [Select](select.md) in a row hugs its value at the end of the row.
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
/** Renders a small surface whose list holds a network picker and a row of token logos, for the Surface docs. @module */
|
|
120
|
+
import { ListGroup, NetworkLogo, Select, style, Surface, TokenLogo } from '@tempoxyz/ds'
|
|
121
|
+
|
|
122
|
+
const networks = [
|
|
123
|
+
{ available: true, id: 'tempo', name: 'Tempo' },
|
|
124
|
+
{ available: false, id: 'ethereum', name: 'Ethereum' },
|
|
125
|
+
{ available: false, id: 'base', name: 'Base' },
|
|
126
|
+
] as const
|
|
127
|
+
|
|
128
|
+
const stablecoins = [
|
|
129
|
+
['pathUSD', '0x20c0000000000000000000000000000000000000'],
|
|
130
|
+
['Bridged USDC (Stargate)', '0x20c000000000000000000000b9537d11c60e8b50'],
|
|
131
|
+
['USDT0', '0x20c00000000000000000000014f22ca97301eb73'],
|
|
132
|
+
] as const
|
|
133
|
+
|
|
134
|
+
export function Demo() {
|
|
135
|
+
return (
|
|
136
|
+
<div {...styles.grid()}>
|
|
137
|
+
<Surface size="small">
|
|
138
|
+
<ListGroup>
|
|
139
|
+
<ListGroup.Row>
|
|
140
|
+
<ListGroup.Label id="surface-list-network">Network</ListGroup.Label>
|
|
141
|
+
<Select.Root value="tempo">
|
|
142
|
+
<Select.Trigger aria-labelledby="surface-list-network">
|
|
143
|
+
<Select.Value>
|
|
144
|
+
{() => (
|
|
145
|
+
<span {...styles.value()}>
|
|
146
|
+
<NetworkLogo network="tempo" size="medium" />
|
|
147
|
+
Tempo
|
|
148
|
+
</span>
|
|
149
|
+
)}
|
|
150
|
+
</Select.Value>
|
|
151
|
+
<Select.Icon />
|
|
152
|
+
</Select.Trigger>
|
|
153
|
+
<Select.Popup align="end">
|
|
154
|
+
{networks.map((network) => (
|
|
155
|
+
<Select.Item disabled={!network.available} key={network.id} value={network.id}>
|
|
156
|
+
<Select.ItemPrefix>
|
|
157
|
+
<NetworkLogo network={network.id} size="medium" />
|
|
158
|
+
</Select.ItemPrefix>
|
|
159
|
+
<Select.ItemText>{network.name}</Select.ItemText>
|
|
160
|
+
{network.available ? null : <Select.ItemSuffix>Coming soon</Select.ItemSuffix>}
|
|
161
|
+
</Select.Item>
|
|
162
|
+
))}
|
|
163
|
+
</Select.Popup>
|
|
164
|
+
</Select.Root>
|
|
165
|
+
</ListGroup.Row>
|
|
166
|
+
<ListGroup.Row>
|
|
167
|
+
<ListGroup.Label>Supported stablecoins</ListGroup.Label>
|
|
168
|
+
<span {...styles.coins()}>
|
|
169
|
+
{stablecoins.map(([symbol, address]) => (
|
|
170
|
+
<TokenLogo address={address} alt={symbol} key={address} />
|
|
171
|
+
))}
|
|
172
|
+
</span>
|
|
173
|
+
</ListGroup.Row>
|
|
174
|
+
</ListGroup>
|
|
175
|
+
</Surface>
|
|
176
|
+
</div>
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
namespace styles {
|
|
181
|
+
export const coins = style({ display: 'flex', gap: '4', marginInlineStart: 'auto !custom' })
|
|
182
|
+
|
|
183
|
+
export const grid = style({ display: 'grid', maxWidth: '25rem !custom', width: '100% !custom' })
|
|
184
|
+
|
|
185
|
+
export const value = style({ alignItems: 'center', display: 'flex', gap: '8' })
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Surface/List.tsx)
|
|
190
|
+
|
|
191
|
+
### Size
|
|
192
|
+
|
|
193
|
+
Set `size` to `small`, `medium`, or `large` (default).
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
import { style, Surface } from '@tempoxyz/ds'
|
|
197
|
+
|
|
198
|
+
export function Demo() {
|
|
199
|
+
return (
|
|
200
|
+
<div {...styles.grid()}>
|
|
201
|
+
{(['large', 'medium', 'small'] as const).map((size) => (
|
|
202
|
+
<Surface key={size} size={size}>
|
|
203
|
+
Size {size}
|
|
204
|
+
</Surface>
|
|
205
|
+
))}
|
|
206
|
+
</div>
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
namespace styles {
|
|
211
|
+
// Surfaces keep their content height instead of stretching to the tallest one in a row.
|
|
212
|
+
export const grid = style({
|
|
213
|
+
alignItems: 'start',
|
|
214
|
+
backgroundColor: 'background.primary',
|
|
215
|
+
display: 'grid',
|
|
216
|
+
gap: '12',
|
|
217
|
+
padding: '16',
|
|
218
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(14rem, 1fr)) !custom',
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Surface/Size.tsx)
|
|
224
|
+
|
|
225
|
+
### Render
|
|
226
|
+
|
|
227
|
+
Pass a `button` or link to `render` for a pressable surface with hover, press, and focus styles.
|
|
228
|
+
|
|
229
|
+
```tsx
|
|
230
|
+
import { style, Surface } from '@tempoxyz/ds'
|
|
231
|
+
import { SwapHorizontal } from '@tempoxyz/ds/icons'
|
|
232
|
+
|
|
233
|
+
export function Demo() {
|
|
234
|
+
return (
|
|
235
|
+
<div {...styles.grid()}>
|
|
236
|
+
<Surface render={<a href="#render" />}>
|
|
237
|
+
<Surface.Header>
|
|
238
|
+
<Surface.Title>
|
|
239
|
+
<SwapHorizontal />
|
|
240
|
+
Routes
|
|
241
|
+
</Surface.Title>
|
|
242
|
+
</Surface.Header>
|
|
243
|
+
<Surface.Description>
|
|
244
|
+
Move stablecoins between Tempo and other networks.
|
|
245
|
+
</Surface.Description>
|
|
246
|
+
</Surface>
|
|
247
|
+
<Surface render={<button type="button" />}>Interactive button</Surface>
|
|
248
|
+
<Surface render={<a href="#render" />}>Interactive link</Surface>
|
|
249
|
+
</div>
|
|
250
|
+
)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
namespace styles {
|
|
254
|
+
// Surfaces keep their content height instead of stretching to the tallest one in a row.
|
|
255
|
+
export const grid = style({
|
|
256
|
+
alignItems: 'start',
|
|
257
|
+
backgroundColor: 'background.primary',
|
|
258
|
+
display: 'grid',
|
|
259
|
+
gap: '12',
|
|
260
|
+
padding: '16',
|
|
261
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(14rem, 1fr)) !custom',
|
|
262
|
+
})
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Surface/Render.tsx)
|
|
267
|
+
|
|
268
|
+
### Disabled
|
|
269
|
+
|
|
270
|
+
Set `disabled` on a pressable surface to block interaction.
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
import { style, Surface } from '@tempoxyz/ds'
|
|
274
|
+
|
|
275
|
+
export function Demo() {
|
|
276
|
+
return (
|
|
277
|
+
<div {...styles.grid()}>
|
|
278
|
+
<Surface disabled render={<button type="button" />}>
|
|
279
|
+
Disabled button
|
|
280
|
+
</Surface>
|
|
281
|
+
</div>
|
|
282
|
+
)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
namespace styles {
|
|
286
|
+
export const grid = style({
|
|
287
|
+
alignItems: 'start',
|
|
288
|
+
backgroundColor: 'background.primary',
|
|
289
|
+
display: 'grid',
|
|
290
|
+
padding: '16',
|
|
291
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(14rem, 1fr)) !custom',
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Surface/Disabled.tsx)
|
|
297
|
+
|
|
298
|
+
## Anatomy
|
|
299
|
+
|
|
300
|
+
Import the component and assemble its parts.
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
import { Surface } from '@tempoxyz/ds'
|
|
304
|
+
|
|
305
|
+
<Surface>
|
|
306
|
+
<Surface.Header>
|
|
307
|
+
<Surface.Title />
|
|
308
|
+
</Surface.Header>
|
|
309
|
+
<Surface.Description />
|
|
310
|
+
<Surface.Links />
|
|
311
|
+
</Surface>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Guidelines
|
|
315
|
+
|
|
316
|
+
### When to Use
|
|
317
|
+
|
|
318
|
+
* Group related content into a card, such as a wallet's Balance, an Activity list, or an API key's details.
|
|
319
|
+
* Make a whole card pressable when it leads to one place, such as a project card that opens its dashboard.
|
|
320
|
+
|
|
321
|
+
### When Not to Use
|
|
322
|
+
|
|
323
|
+
* Use [Alert](alert.md) for a message about a section, and [Banner](banner.md) for one about the page.
|
|
324
|
+
* Use [Dialog](dialog.md) or [Popover](popover.md) for content that opens over the page.
|
|
325
|
+
* Use [Stack](stack.md) or [Inset](inset.md) to space content without a visible container.
|
|
326
|
+
* Use [Frame](frame.md) inside a surface for a card with a footer of actions.
|
|
327
|
+
|
|
328
|
+
### Name Each Card
|
|
329
|
+
|
|
330
|
+
Start a card with a `Surface.Header` that holds a `Surface.Title`. Put a card-level action at the end of the header, such as a `small` `tertiary` [Button](button.md).
|
|
331
|
+
|
|
332
|
+
**Do:** Name the card with a `Surface.Title`, and put its action at the end of the header.
|
|
333
|
+
|
|
334
|
+
```tsx
|
|
335
|
+
/**
|
|
336
|
+
* Do example for "Name Each Card" on the Surface page.
|
|
337
|
+
* Name the card with a `Surface.Title`, and put its action at the end of the header.
|
|
338
|
+
* @module
|
|
339
|
+
*/
|
|
340
|
+
import { Amount, Button, ListGroup, style, Surface } from '@tempoxyz/ds'
|
|
341
|
+
|
|
342
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
343
|
+
export function Demo() {
|
|
344
|
+
return (
|
|
345
|
+
<div {...styles.canvas()}>
|
|
346
|
+
<Surface size="medium">
|
|
347
|
+
<Surface.Header>
|
|
348
|
+
<Surface.Title>Balances</Surface.Title>
|
|
349
|
+
<Button size="small" variant="tertiary">
|
|
350
|
+
View all
|
|
351
|
+
</Button>
|
|
352
|
+
</Surface.Header>
|
|
353
|
+
<ListGroup dividers={false}>
|
|
354
|
+
<ListGroup.Row>
|
|
355
|
+
<ListGroup.Label>USDC</ListGroup.Label>
|
|
356
|
+
<Amount value="1250.00" />
|
|
357
|
+
</ListGroup.Row>
|
|
358
|
+
<ListGroup.Row>
|
|
359
|
+
<ListGroup.Label>pathUSD</ListGroup.Label>
|
|
360
|
+
<Amount value="80.25" />
|
|
361
|
+
</ListGroup.Row>
|
|
362
|
+
</ListGroup>
|
|
363
|
+
</Surface>
|
|
364
|
+
</div>
|
|
365
|
+
)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
namespace styles {
|
|
369
|
+
export const canvas = style({
|
|
370
|
+
backgroundColor: 'background.primary',
|
|
371
|
+
borderRadius: 'sm',
|
|
372
|
+
boxSizing: 'border-box',
|
|
373
|
+
padding: '12',
|
|
374
|
+
width: '100% !custom',
|
|
375
|
+
})
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Don't:** Start a card with its content.
|
|
380
|
+
|
|
381
|
+
```tsx
|
|
382
|
+
/** Don't example for "Name Each Card" on the Surface page. Don't start a card with its content. @module */
|
|
383
|
+
import { Amount, ListGroup, style, Surface } from '@tempoxyz/ds'
|
|
384
|
+
|
|
385
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
386
|
+
export function Demo() {
|
|
387
|
+
return (
|
|
388
|
+
<div {...styles.canvas()}>
|
|
389
|
+
<Surface size="medium">
|
|
390
|
+
<ListGroup dividers={false}>
|
|
391
|
+
<ListGroup.Row>
|
|
392
|
+
<ListGroup.Label>USDC</ListGroup.Label>
|
|
393
|
+
<Amount value="1250.00" />
|
|
394
|
+
</ListGroup.Row>
|
|
395
|
+
<ListGroup.Row>
|
|
396
|
+
<ListGroup.Label>pathUSD</ListGroup.Label>
|
|
397
|
+
<Amount value="80.25" />
|
|
398
|
+
</ListGroup.Row>
|
|
399
|
+
</ListGroup>
|
|
400
|
+
</Surface>
|
|
401
|
+
</div>
|
|
402
|
+
)
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
namespace styles {
|
|
406
|
+
export const canvas = style({
|
|
407
|
+
backgroundColor: 'background.primary',
|
|
408
|
+
borderRadius: 'sm',
|
|
409
|
+
boxSizing: 'border-box',
|
|
410
|
+
padding: '12',
|
|
411
|
+
width: '100% !custom',
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Match Size to Density
|
|
417
|
+
|
|
418
|
+
* **Large (24px):** The default, for page cards such as Balances.
|
|
419
|
+
* **Medium (16px):** For dashboard tiles, such as TPS.
|
|
420
|
+
* **Small (12px):** For compact tiles, such as Block time.
|
|
421
|
+
|
|
422
|
+
Keep one size across cards that sit side by side.
|
|
423
|
+
|
|
424
|
+
### Keep Pressable Cards Free of Other Controls
|
|
425
|
+
|
|
426
|
+
A surface rendered as a link or button is one target, and screen readers announce the whole card as one control.
|
|
427
|
+
|
|
428
|
+
**Do:** Make the whole card one link with a short title.
|
|
429
|
+
|
|
430
|
+
```tsx
|
|
431
|
+
/**
|
|
432
|
+
* Do example for "Keep Pressable Cards Free of Other Controls" on the Surface page.
|
|
433
|
+
* Make the whole card one link with a short title.
|
|
434
|
+
* @module
|
|
435
|
+
*/
|
|
436
|
+
import { style, Surface } from '@tempoxyz/ds'
|
|
437
|
+
|
|
438
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
439
|
+
export function Demo() {
|
|
440
|
+
return (
|
|
441
|
+
<div {...styles.canvas()}>
|
|
442
|
+
<Surface render={<a href="#" />} size="medium">
|
|
443
|
+
<span {...styles.title()}>Production key</span>
|
|
444
|
+
<span {...styles.meta()}>Created 3 days ago</span>
|
|
445
|
+
</Surface>
|
|
446
|
+
</div>
|
|
447
|
+
)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
namespace styles {
|
|
451
|
+
export const canvas = style({
|
|
452
|
+
backgroundColor: 'background.primary',
|
|
453
|
+
borderRadius: 'sm',
|
|
454
|
+
padding: '16',
|
|
455
|
+
width: '16rem !custom',
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
export const meta = style({ color: 'content.secondary', display: 'block', typography: 'body.b3' })
|
|
459
|
+
|
|
460
|
+
export const title = style({ display: 'block', typography: 'body.b1Strong' })
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**Don't:** Place a button inside a pressable card.
|
|
465
|
+
|
|
466
|
+
```tsx
|
|
467
|
+
/**
|
|
468
|
+
* Don't example for "Keep Pressable Cards Free of Other Controls" on the Surface page.
|
|
469
|
+
* Don't place a button inside a pressable card.
|
|
470
|
+
* @module
|
|
471
|
+
*/
|
|
472
|
+
import { Button, style, Surface } from '@tempoxyz/ds'
|
|
473
|
+
|
|
474
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
475
|
+
export function Demo() {
|
|
476
|
+
return (
|
|
477
|
+
<div {...styles.canvas()}>
|
|
478
|
+
<Surface render={<a href="#" />} size="medium">
|
|
479
|
+
<span {...styles.title()}>Production key</span>
|
|
480
|
+
<span {...styles.meta()}>Created 3 days ago</span>
|
|
481
|
+
<Button size="small" {...styles.action()}>
|
|
482
|
+
Revoke key
|
|
483
|
+
</Button>
|
|
484
|
+
</Surface>
|
|
485
|
+
</div>
|
|
486
|
+
)
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
namespace styles {
|
|
490
|
+
export const action = style({ marginBlockStart: '12' })
|
|
491
|
+
|
|
492
|
+
export const canvas = style({
|
|
493
|
+
backgroundColor: 'background.primary',
|
|
494
|
+
borderRadius: 'sm',
|
|
495
|
+
padding: '16',
|
|
496
|
+
width: '16rem !custom',
|
|
497
|
+
})
|
|
498
|
+
|
|
499
|
+
export const meta = style({ color: 'content.secondary', display: 'block', typography: 'body.b3' })
|
|
500
|
+
|
|
501
|
+
export const title = style({ display: 'block', typography: 'body.b1Strong' })
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### Don't Nest Surfaces
|
|
506
|
+
|
|
507
|
+
Divide the content of one surface with [ListGroup](list-group.md), a [Table](table.md), or a [Separator](separator.md). A table placed directly inside a surface bleeds 12px into its padding, so its rows end 12px inside the edges of a large surface and its text stays on the content edge. The surface draws no border around it.
|
|
508
|
+
|
|
509
|
+
**Do:** Divide one surface with ListGroup.
|
|
510
|
+
|
|
511
|
+
```tsx
|
|
512
|
+
/** Do example for "Don't Nest Surfaces" on the Surface page: divide one surface with ListGroup. @module */
|
|
513
|
+
import { Amount, Hex, ListGroup, style, Surface } from '@tempoxyz/ds'
|
|
514
|
+
|
|
515
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
516
|
+
export function Demo() {
|
|
517
|
+
return (
|
|
518
|
+
<div {...styles.canvas()}>
|
|
519
|
+
<Surface size="medium">
|
|
520
|
+
<ListGroup>
|
|
521
|
+
<ListGroup.Row>
|
|
522
|
+
<ListGroup.Label>Amount</ListGroup.Label>
|
|
523
|
+
<Amount symbol="USDC" value="48.50" />
|
|
524
|
+
</ListGroup.Row>
|
|
525
|
+
<ListGroup.Row>
|
|
526
|
+
<ListGroup.Label>Recipient</ListGroup.Label>
|
|
527
|
+
<Hex value="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" />
|
|
528
|
+
</ListGroup.Row>
|
|
529
|
+
</ListGroup>
|
|
530
|
+
</Surface>
|
|
531
|
+
</div>
|
|
532
|
+
)
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
namespace styles {
|
|
536
|
+
export const canvas = style({
|
|
537
|
+
backgroundColor: 'background.primary',
|
|
538
|
+
borderRadius: 'sm',
|
|
539
|
+
boxSizing: 'border-box',
|
|
540
|
+
padding: '12',
|
|
541
|
+
width: '100% !custom',
|
|
542
|
+
})
|
|
543
|
+
}
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**Don't:** Place surfaces inside a surface.
|
|
547
|
+
|
|
548
|
+
```tsx
|
|
549
|
+
/** Don't example for "Don't Nest Surfaces" on the Surface page. Don't place surfaces inside a surface. @module */
|
|
550
|
+
import { Amount, Hex, style, Surface } from '@tempoxyz/ds'
|
|
551
|
+
|
|
552
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
553
|
+
export function Demo() {
|
|
554
|
+
return (
|
|
555
|
+
<div {...styles.canvas()}>
|
|
556
|
+
<Surface size="medium" {...styles.outer()}>
|
|
557
|
+
<Surface size="small" {...styles.row()}>
|
|
558
|
+
<span>Amount</span>
|
|
559
|
+
<Amount symbol="USDC" value="48.50" />
|
|
560
|
+
</Surface>
|
|
561
|
+
<Surface size="small" {...styles.row()}>
|
|
562
|
+
<span>Recipient</span>
|
|
563
|
+
<Hex value="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" />
|
|
564
|
+
</Surface>
|
|
565
|
+
</Surface>
|
|
566
|
+
</div>
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
namespace styles {
|
|
571
|
+
export const canvas = style({
|
|
572
|
+
backgroundColor: 'background.primary',
|
|
573
|
+
borderRadius: 'sm',
|
|
574
|
+
boxSizing: 'border-box',
|
|
575
|
+
padding: '12',
|
|
576
|
+
width: '100% !custom',
|
|
577
|
+
})
|
|
578
|
+
|
|
579
|
+
export const outer = style({ display: 'flex', flexDirection: 'column', gap: '8' })
|
|
580
|
+
|
|
581
|
+
export const row = style({
|
|
582
|
+
alignItems: 'center',
|
|
583
|
+
backgroundColor: 'container.regular',
|
|
584
|
+
display: 'flex',
|
|
585
|
+
justifyContent: 'space-between',
|
|
586
|
+
})
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
## Content
|
|
591
|
+
|
|
592
|
+
* Write titles as short nouns, such as Balances, Activity, or Routes.
|
|
593
|
+
* Keep `Surface.Description` to one or two sentences.
|
|
594
|
+
* Use `Surface.Links` for two or three follow-up tasks, written as verbs, such as Make a transfer.
|
|
595
|
+
|
|
596
|
+
## Accessibility
|
|
597
|
+
|
|
598
|
+
A surface takes its semantics from the element you render, such as a `section`, a `button`, or a link.
|
|
599
|
+
|
|
600
|
+
### Semantics
|
|
601
|
+
|
|
602
|
+
* **Default Element (div):** Carries no role.
|
|
603
|
+
* **Surface.Title (h2):** Lets screen reader users find the card by heading.
|
|
604
|
+
* **Surface.Description (p):** A plain paragraph under the title.
|
|
605
|
+
* **Pressable Cards (button or link):** The whole card becomes one control, named by its text.
|
|
606
|
+
* **Disabled (aria-disabled):** Dims the card and drops pointer events. Only a button also stops keyboard activation.
|
|
607
|
+
|
|
608
|
+
### Keyboard
|
|
609
|
+
|
|
610
|
+
For a pressable surface rendered as a button or link:
|
|
611
|
+
|
|
612
|
+
* **Move Focus to the Card (Tab):** Moves focus to the card.
|
|
613
|
+
* **Activate a Link or Button (Enter):** Activates a link or button card.
|
|
614
|
+
* **Activate a Button (Space):** Activates a button card.
|
|
615
|
+
|
|
616
|
+
### Your Responsibilities
|
|
617
|
+
|
|
618
|
+
* **Name Regions (aria-labelledby):** If the card is a distinct region, render a section labelled by its title.
|
|
619
|
+
* **Fit the Outline (h2):** Place cards where their title's heading level fits the page outline.
|
|
620
|
+
* **Keep Pressable Text Short:** The card's full content becomes its accessible name, so keep its text short.
|
|
621
|
+
* **Disabling Link Cards (href):** A link can't be disabled. Remove its `href` when it must not work.
|
|
622
|
+
|
|
623
|
+
## Related
|
|
624
|
+
|
|
625
|
+
[Frame](frame.md)
|
|
626
|
+
|
|
627
|
+
Use for a header, body, and footer inside a card.
|
|
628
|
+
|
|
629
|
+
[ListGroup](list-group.md)
|
|
630
|
+
|
|
631
|
+
Use for divided content in a card.
|
|
632
|
+
|
|
633
|
+
[Grid](grid.md)
|
|
634
|
+
|
|
635
|
+
Use for laying out several cards.
|
|
636
|
+
|
|
637
|
+
[Dashboards](../patterns/dashboards.md)
|
|
638
|
+
|
|
639
|
+
Covers metric tiles.
|