@tempoxyz/ds 0.3.10 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/AGENTS.md +9 -0
- package/dist/docs/components/accordion.md +489 -0
- package/dist/docs/components/address-card.md +147 -0
- package/dist/docs/components/agent-logo.md +194 -0
- package/dist/docs/components/alert-dialog.md +631 -0
- package/dist/docs/components/alert.md +448 -0
- package/dist/docs/components/amount-input.md +305 -0
- package/dist/docs/components/amount.md +794 -0
- package/dist/docs/components/app-shell.md +559 -0
- package/dist/docs/components/asset-chip.md +294 -0
- package/dist/docs/components/autocomplete.md +619 -0
- package/dist/docs/components/avatar.md +321 -0
- package/dist/docs/components/badge.md +339 -0
- package/dist/docs/components/badged-logo.md +116 -0
- package/dist/docs/components/banner.md +379 -0
- package/dist/docs/components/bar-chart.md +208 -0
- package/dist/docs/components/breadcrumbs.md +380 -0
- package/dist/docs/components/button-group.md +286 -0
- package/dist/docs/components/button.md +650 -0
- package/dist/docs/components/calendar.md +375 -0
- package/dist/docs/components/callout.md +96 -0
- package/dist/docs/components/checkbox-group.md +521 -0
- package/dist/docs/components/checkbox.md +467 -0
- package/dist/docs/components/choice-group.md +516 -0
- package/dist/docs/components/choicebox.md +641 -0
- package/dist/docs/components/code.md +100 -0
- package/dist/docs/components/combobox.md +939 -0
- package/dist/docs/components/container.md +257 -0
- package/dist/docs/components/copy-button.md +642 -0
- package/dist/docs/components/date-picker.md +514 -0
- package/dist/docs/components/dialog.md +1332 -0
- package/dist/docs/components/drawer.md +966 -0
- package/dist/docs/components/empty.md +340 -0
- package/dist/docs/components/field.md +570 -0
- package/dist/docs/components/fieldset.md +398 -0
- package/dist/docs/components/frame.md +434 -0
- package/dist/docs/components/gauge.md +299 -0
- package/dist/docs/components/get-started-visual.md +117 -0
- package/dist/docs/components/grid.md +288 -0
- package/dist/docs/components/hero-visual.md +155 -0
- package/dist/docs/components/hex.md +487 -0
- package/dist/docs/components/icon-tile.md +292 -0
- package/dist/docs/components/identicon.md +371 -0
- package/dist/docs/components/inline.md +233 -0
- package/dist/docs/components/inset.md +225 -0
- package/dist/docs/components/kbd.md +423 -0
- package/dist/docs/components/list-group.md +981 -0
- package/dist/docs/components/loading-dots.md +237 -0
- package/dist/docs/components/menu.md +934 -0
- package/dist/docs/components/native-select.md +204 -0
- package/dist/docs/components/network-logo.md +248 -0
- package/dist/docs/components/number-field.md +543 -0
- package/dist/docs/components/otp-field.md +616 -0
- package/dist/docs/components/pagination.md +516 -0
- package/dist/docs/components/popover.md +544 -0
- package/dist/docs/components/progress.md +388 -0
- package/dist/docs/components/qr.md +314 -0
- package/dist/docs/components/radio-group.md +528 -0
- package/dist/docs/components/secret-value.md +406 -0
- package/dist/docs/components/select.md +751 -0
- package/dist/docs/components/separator.md +379 -0
- package/dist/docs/components/sidebar-menu.md +922 -0
- package/dist/docs/components/skeleton.md +517 -0
- package/dist/docs/components/slider.md +539 -0
- package/dist/docs/components/snippet.md +424 -0
- package/dist/docs/components/spinner.md +216 -0
- package/dist/docs/components/split-bar.md +139 -0
- package/dist/docs/components/split-button.md +464 -0
- package/dist/docs/components/stack.md +299 -0
- package/dist/docs/components/status-chip.md +226 -0
- package/dist/docs/components/status-indicator.md +119 -0
- package/dist/docs/components/status-row.md +174 -0
- package/dist/docs/components/stepper.md +451 -0
- package/dist/docs/components/success-hero.md +157 -0
- package/dist/docs/components/surface.md +639 -0
- package/dist/docs/components/switch.md +472 -0
- package/dist/docs/components/table.md +967 -0
- package/dist/docs/components/tabs.md +627 -0
- package/dist/docs/components/tempo-logo.md +185 -0
- package/dist/docs/components/text-input.md +624 -0
- package/dist/docs/components/textarea.md +352 -0
- package/dist/docs/components/toast.md +535 -0
- package/dist/docs/components/token-logo.md +371 -0
- package/dist/docs/components/token.md +247 -0
- package/dist/docs/components/tooltip.md +490 -0
- package/dist/docs/components/verification-code.md +116 -0
- package/dist/docs/components/visual.md +249 -0
- package/dist/docs/components.md +203 -0
- package/dist/docs/foundations/accessibility.md +377 -0
- package/dist/docs/foundations/agents.md +150 -0
- package/dist/docs/foundations/color.md +522 -0
- package/dist/docs/foundations/content/tone.md +194 -0
- package/dist/docs/foundations/content/voice.md +194 -0
- package/dist/docs/foundations/content/writing-style.md +406 -0
- package/dist/docs/foundations/iconography.md +282 -0
- package/dist/docs/foundations/intent.md +360 -0
- package/dist/docs/foundations/layout.md +508 -0
- package/dist/docs/foundations/linter.md +296 -0
- package/dist/docs/foundations/motion.md +151 -0
- package/dist/docs/foundations/radius-and-padding.md +86 -0
- package/dist/docs/foundations/typography.md +266 -0
- package/dist/docs/index.md +137 -0
- package/dist/docs/introduction/faq.md +132 -0
- package/dist/docs/introduction/getting-started.md +377 -0
- package/dist/docs/patterns/blockchain-values.md +709 -0
- package/dist/docs/patterns/dashboards.md +638 -0
- package/dist/docs/patterns/destructive-actions.md +626 -0
- package/dist/docs/patterns/empty-states.md +612 -0
- package/dist/docs/patterns/errors-and-validation.md +808 -0
- package/dist/docs/patterns/feedback-and-status.md +518 -0
- package/dist/docs/patterns/forms.md +679 -0
- package/dist/docs/patterns/loading.md +630 -0
- package/dist/docs/patterns/navigation.md +397 -0
- package/dist/docs/patterns/payments.md +765 -0
- package/dist/docs/patterns/responsive-layout.md +997 -0
- package/dist/docs/patterns/tables-and-lists.md +964 -0
- package/dist/docs/products/tempo-console.md +671 -0
- package/dist/docs/products/tempo-performance.md +437 -0
- package/dist/docs/products/tempo-wallet.md +438 -0
- package/package.json +1 -1
|
@@ -0,0 +1,981 @@
|
|
|
1
|
+
# ListGroup
|
|
2
|
+
|
|
3
|
+
Stacks rows for details, pickers, checklists, and settings.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/ListGroup.tsx)
|
|
6
|
+
|
|
7
|
+
Figma: [Content/List Group](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-1837), [Content/List Row](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-1666) (`ListGroup.Row`), [Content/Prompt Row](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-3419) (`ListGroup.Row`)
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
ListGroup lays out key-value facts, pickable items, and checklists, and groups them plain, boxed, or spaced. Plain rows line up with the content around them.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Basic
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { ListGroup, style } from '@tempoxyz/ds'
|
|
19
|
+
|
|
20
|
+
export const fill = true
|
|
21
|
+
export function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<ListGroup.Root {...styles.rows()}>
|
|
24
|
+
<ListGroup.Row>
|
|
25
|
+
<ListGroup.Label>Network</ListGroup.Label>
|
|
26
|
+
Tempo
|
|
27
|
+
</ListGroup.Row>
|
|
28
|
+
<ListGroup.Row>
|
|
29
|
+
<ListGroup.Label>Chain ID</ListGroup.Label>
|
|
30
|
+
4217
|
|
31
|
+
</ListGroup.Row>
|
|
32
|
+
<ListGroup.Row>
|
|
33
|
+
<ListGroup.Label>Network fee</ListGroup.Label>
|
|
34
|
+
$0.0001
|
|
35
|
+
</ListGroup.Row>
|
|
36
|
+
<ListGroup.Row>
|
|
37
|
+
<ListGroup.Label>Status</ListGroup.Label>
|
|
38
|
+
Confirmed
|
|
39
|
+
</ListGroup.Row>
|
|
40
|
+
</ListGroup.Root>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
namespace styles {
|
|
45
|
+
export const rows = style({ maxWidth: '24rem !custom' })
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Basic.tsx)
|
|
50
|
+
|
|
51
|
+
### Variant
|
|
52
|
+
|
|
53
|
+
Set `variant` on `ListGroup.Root` to `plain` (default), `boxed`, or `spaced`. Name the group with a `ListGroup.Heading` right before it.
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import { ListGroup, style } from '@tempoxyz/ds'
|
|
57
|
+
import { Check } from '@tempoxyz/ds/icons'
|
|
58
|
+
|
|
59
|
+
export function Demo() {
|
|
60
|
+
return (
|
|
61
|
+
<div {...styles.grid()}>
|
|
62
|
+
<div>
|
|
63
|
+
<ListGroup.Heading>Fees</ListGroup.Heading>
|
|
64
|
+
<ListGroup.Root variant="boxed">
|
|
65
|
+
<ListGroup.Row>
|
|
66
|
+
<ListGroup.Label>Network fee</ListGroup.Label>
|
|
67
|
+
0.001 USDC
|
|
68
|
+
</ListGroup.Row>
|
|
69
|
+
<ListGroup.Row>
|
|
70
|
+
<ListGroup.Label>Paid in</ListGroup.Label>
|
|
71
|
+
USDC
|
|
72
|
+
</ListGroup.Row>
|
|
73
|
+
<ListGroup.Row>
|
|
74
|
+
<ListGroup.Label>Arrives</ListGroup.Label>
|
|
75
|
+
Seconds
|
|
76
|
+
</ListGroup.Row>
|
|
77
|
+
</ListGroup.Root>
|
|
78
|
+
</div>
|
|
79
|
+
<div>
|
|
80
|
+
<ListGroup.Heading>Fees</ListGroup.Heading>
|
|
81
|
+
<ListGroup.Root variant="plain">
|
|
82
|
+
<ListGroup.Row>
|
|
83
|
+
<ListGroup.Label>Network fee</ListGroup.Label>
|
|
84
|
+
0.001 USDC
|
|
85
|
+
</ListGroup.Row>
|
|
86
|
+
<ListGroup.Row>
|
|
87
|
+
<ListGroup.Label>Paid in</ListGroup.Label>
|
|
88
|
+
USDC
|
|
89
|
+
</ListGroup.Row>
|
|
90
|
+
<ListGroup.Row>
|
|
91
|
+
<ListGroup.Label>Arrives</ListGroup.Label>
|
|
92
|
+
Seconds
|
|
93
|
+
</ListGroup.Row>
|
|
94
|
+
</ListGroup.Root>
|
|
95
|
+
</div>
|
|
96
|
+
<div>
|
|
97
|
+
<ListGroup.Heading>Benefits</ListGroup.Heading>
|
|
98
|
+
<ListGroup.Root variant="spaced">
|
|
99
|
+
<ListGroup.Row>
|
|
100
|
+
<Check {...styles.check()} />
|
|
101
|
+
Never get locked out if you lose email access
|
|
102
|
+
</ListGroup.Row>
|
|
103
|
+
<ListGroup.Row>
|
|
104
|
+
<Check {...styles.check()} />
|
|
105
|
+
Approve with your device, no codes
|
|
106
|
+
</ListGroup.Row>
|
|
107
|
+
<ListGroup.Row>
|
|
108
|
+
<Check {...styles.check()} />
|
|
109
|
+
Stays on your device. Tempo never sees it
|
|
110
|
+
</ListGroup.Row>
|
|
111
|
+
</ListGroup.Root>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
namespace styles {
|
|
118
|
+
export const check = style({ color: 'content.positive', flexShrink: '0 !custom', fontSize: '16' })
|
|
119
|
+
|
|
120
|
+
export const grid = style({
|
|
121
|
+
alignItems: 'start',
|
|
122
|
+
display: 'grid',
|
|
123
|
+
gap: '24',
|
|
124
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(20rem, 1fr)) !custom',
|
|
125
|
+
})
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Variant.tsx)
|
|
130
|
+
|
|
131
|
+
### Title and Description
|
|
132
|
+
|
|
133
|
+
Stack a `ListGroup.Title` over a `ListGroup.Description` in `ListGroup.Info`, after an [Avatar](/docs/components/avatar). The row grows to 64px.
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
import { Avatar, ListGroup, style } from '@tempoxyz/ds'
|
|
137
|
+
import { Wallet } from '@tempoxyz/ds/icons'
|
|
138
|
+
|
|
139
|
+
export function Demo() {
|
|
140
|
+
return (
|
|
141
|
+
<div {...styles.list()}>
|
|
142
|
+
<ListGroup.Heading>Recent</ListGroup.Heading>
|
|
143
|
+
<ListGroup.Root dividers={false}>
|
|
144
|
+
<ListGroup.Row action="navigation" onClick={() => {}}>
|
|
145
|
+
<Avatar size="32">
|
|
146
|
+
<Avatar.Fallback>MR</Avatar.Fallback>
|
|
147
|
+
</Avatar>
|
|
148
|
+
<ListGroup.Info>
|
|
149
|
+
<ListGroup.Title>Maya Rao</ListGroup.Title>
|
|
150
|
+
<ListGroup.Description>maya@studio.co</ListGroup.Description>
|
|
151
|
+
</ListGroup.Info>
|
|
152
|
+
</ListGroup.Row>
|
|
153
|
+
<ListGroup.Row action="navigation" onClick={() => {}}>
|
|
154
|
+
<Avatar size="32">
|
|
155
|
+
<Avatar.Fallback>AC</Avatar.Fallback>
|
|
156
|
+
</Avatar>
|
|
157
|
+
<ListGroup.Info>
|
|
158
|
+
<ListGroup.Title>Acme Co.</ListGroup.Title>
|
|
159
|
+
<ListGroup.Description>0x5d21…7e9a</ListGroup.Description>
|
|
160
|
+
</ListGroup.Info>
|
|
161
|
+
</ListGroup.Row>
|
|
162
|
+
<ListGroup.Row action="navigation" onClick={() => {}}>
|
|
163
|
+
<Avatar size="32">
|
|
164
|
+
<Avatar.Fallback>
|
|
165
|
+
<Wallet />
|
|
166
|
+
</Avatar.Fallback>
|
|
167
|
+
</Avatar>
|
|
168
|
+
<ListGroup.Info>
|
|
169
|
+
<ListGroup.Title>Savings wallet</ListGroup.Title>
|
|
170
|
+
<ListGroup.Description>0x19be…c044</ListGroup.Description>
|
|
171
|
+
</ListGroup.Info>
|
|
172
|
+
</ListGroup.Row>
|
|
173
|
+
</ListGroup.Root>
|
|
174
|
+
</div>
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
namespace styles {
|
|
179
|
+
export const list = style({ maxWidth: '25rem !custom', width: '100% !custom' })
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Items.tsx)
|
|
184
|
+
|
|
185
|
+
### Large Info
|
|
186
|
+
|
|
187
|
+
Set `size="large"` on `ListGroup.Info` for the row that introduces a boxed group. It sets a 16px title over a monospace address.
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
import { Button, formatHex, ListGroup, style } from '@tempoxyz/ds'
|
|
191
|
+
|
|
192
|
+
const address = '0x7a3f2c1e9b4d5a6f7c8e9d0a1b2c3d4e5fb8e091c2'
|
|
193
|
+
|
|
194
|
+
export function Demo() {
|
|
195
|
+
return (
|
|
196
|
+
<ListGroup.Root variant="boxed" {...styles.rows()}>
|
|
197
|
+
<ListGroup.Row>
|
|
198
|
+
<span aria-hidden="true" {...styles.art()} />
|
|
199
|
+
<ListGroup.Info size="large">
|
|
200
|
+
<ListGroup.Title>Tempo Wallet</ListGroup.Title>
|
|
201
|
+
<ListGroup.Description>{formatHex(address, { min: 6 })}</ListGroup.Description>
|
|
202
|
+
</ListGroup.Info>
|
|
203
|
+
<Button
|
|
204
|
+
aria-label="Copy wallet address"
|
|
205
|
+
onClick={() => void navigator.clipboard.writeText(address)}
|
|
206
|
+
size="xsmall"
|
|
207
|
+
variant="secondary"
|
|
208
|
+
>
|
|
209
|
+
Copy
|
|
210
|
+
</Button>
|
|
211
|
+
</ListGroup.Row>
|
|
212
|
+
<ListGroup.Row>
|
|
213
|
+
<ListGroup.Label>Network</ListGroup.Label>
|
|
214
|
+
Tempo Mainnet
|
|
215
|
+
</ListGroup.Row>
|
|
216
|
+
<ListGroup.Row>
|
|
217
|
+
<ListGroup.Label>Signed in as</ListGroup.Label>
|
|
218
|
+
piri@tempo.xyz
|
|
219
|
+
</ListGroup.Row>
|
|
220
|
+
<ListGroup.Row>
|
|
221
|
+
<ListGroup.Label>Signers</ListGroup.Label>1 · email
|
|
222
|
+
</ListGroup.Row>
|
|
223
|
+
</ListGroup.Root>
|
|
224
|
+
)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
namespace styles {
|
|
228
|
+
export const art = style({
|
|
229
|
+
backgroundImage: 'linear-gradient(#1f1a14, #eda866, #261f1a) !custom',
|
|
230
|
+
borderRadius: 'xs',
|
|
231
|
+
flexShrink: '0 !custom',
|
|
232
|
+
height: '40',
|
|
233
|
+
width: '40',
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
export const rows = style({ maxWidth: '25rem !custom', width: '100% !custom' })
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Entity.tsx)
|
|
241
|
+
|
|
242
|
+
### Networks
|
|
243
|
+
|
|
244
|
+
Lead with a [NetworkLogo](/docs/components/network-logo), and list supported assets in [AssetChip](/docs/components/asset-chip) elements inside a `ListGroup.Chips` under the title.
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
import { AssetChip, ListGroup, NetworkLogo, style } from '@tempoxyz/ds'
|
|
248
|
+
|
|
249
|
+
const networks = [
|
|
250
|
+
{ name: 'Base', network: 'base' },
|
|
251
|
+
{ name: 'Ethereum', network: 'ethereum' },
|
|
252
|
+
{ name: 'Polygon', network: 'polygon' },
|
|
253
|
+
] as const
|
|
254
|
+
|
|
255
|
+
export function Demo() {
|
|
256
|
+
return (
|
|
257
|
+
<ListGroup.Root dividers={false} {...styles.rows()}>
|
|
258
|
+
{networks.map((entry) => (
|
|
259
|
+
<ListGroup.Row action="navigation" key={entry.network} onClick={() => {}}>
|
|
260
|
+
<NetworkLogo network={entry.network} size="large" />
|
|
261
|
+
<ListGroup.Info>
|
|
262
|
+
<ListGroup.Title>{entry.name}</ListGroup.Title>
|
|
263
|
+
<ListGroup.Chips>
|
|
264
|
+
<AssetChip>USDC</AssetChip>
|
|
265
|
+
<AssetChip>USDT</AssetChip>
|
|
266
|
+
</ListGroup.Chips>
|
|
267
|
+
</ListGroup.Info>
|
|
268
|
+
</ListGroup.Row>
|
|
269
|
+
))}
|
|
270
|
+
</ListGroup.Root>
|
|
271
|
+
)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
namespace styles {
|
|
275
|
+
export const rows = style({ maxWidth: '25rem !custom', width: '100% !custom' })
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Networks.tsx)
|
|
280
|
+
|
|
281
|
+
### Meter
|
|
282
|
+
|
|
283
|
+
Lead with an [AgentLogo](/docs/components/agent-logo) and end with a `ListGroup.Meter` to show how much of a limit each agent used. The bars line up from row to row.
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
/** Demonstrates ListGroup rows that show how much of a spending limit each agent used. @module */
|
|
287
|
+
import { AgentLogo, ListGroup, style } from '@tempoxyz/ds'
|
|
288
|
+
|
|
289
|
+
const agents = [
|
|
290
|
+
{ agent: 'claude', limit: 10, name: 'Claude', spent: 6.6 },
|
|
291
|
+
{ agent: 'codex', limit: 25, name: 'Codex', spent: 4 },
|
|
292
|
+
{ agent: 'cursor', limit: 5, name: 'Cursor', spent: 4.75 },
|
|
293
|
+
] as const
|
|
294
|
+
|
|
295
|
+
export function Demo() {
|
|
296
|
+
return (
|
|
297
|
+
<div {...styles.rows()}>
|
|
298
|
+
<ListGroup.Heading>Agents</ListGroup.Heading>
|
|
299
|
+
<ListGroup.Root>
|
|
300
|
+
{agents.map((entry) => (
|
|
301
|
+
<ListGroup.Row key={entry.agent}>
|
|
302
|
+
<AgentLogo agent={entry.agent} />
|
|
303
|
+
<ListGroup.Info>
|
|
304
|
+
<ListGroup.Title>{entry.name}</ListGroup.Title>
|
|
305
|
+
</ListGroup.Info>
|
|
306
|
+
<ListGroup.Meter
|
|
307
|
+
aria-label={`${entry.name} spending limit used`}
|
|
308
|
+
getAriaValueText={() => `${entry.spent.toFixed(2)} of ${entry.limit} USDC`}
|
|
309
|
+
max={entry.limit}
|
|
310
|
+
value={entry.spent}
|
|
311
|
+
>
|
|
312
|
+
{entry.spent.toFixed(2)} USDC
|
|
313
|
+
</ListGroup.Meter>
|
|
314
|
+
</ListGroup.Row>
|
|
315
|
+
))}
|
|
316
|
+
</ListGroup.Root>
|
|
317
|
+
</div>
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
namespace styles {
|
|
322
|
+
export const rows = style({ maxWidth: '25rem !custom', width: '100% !custom' })
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Meter.tsx)
|
|
327
|
+
|
|
328
|
+
### Stacked Value
|
|
329
|
+
|
|
330
|
+
Put a `ListGroup.Description` above the value in `ListGroup.Info` for a single fact.
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
import { ListGroup, style } from '@tempoxyz/ds'
|
|
334
|
+
|
|
335
|
+
export function Demo() {
|
|
336
|
+
return (
|
|
337
|
+
<ListGroup.Root variant="spaced" {...styles.rows()}>
|
|
338
|
+
<ListGroup.Row>
|
|
339
|
+
<ListGroup.Info>
|
|
340
|
+
<ListGroup.Description>Signing with</ListGroup.Description>
|
|
341
|
+
This device
|
|
342
|
+
</ListGroup.Info>
|
|
343
|
+
</ListGroup.Row>
|
|
344
|
+
</ListGroup.Root>
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
namespace styles {
|
|
349
|
+
export const rows = style({ maxWidth: '25rem !custom', width: '100% !custom' })
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Fact.tsx)
|
|
354
|
+
|
|
355
|
+
### Action
|
|
356
|
+
|
|
357
|
+
Set `action="navigation"` on a `ListGroup.Row` that opens something, which adds a chevron. Pass `render` to make it a link, or `onClick` to make it a button.
|
|
358
|
+
|
|
359
|
+
```tsx
|
|
360
|
+
import { ListGroup, style } from '@tempoxyz/ds'
|
|
361
|
+
|
|
362
|
+
export function Demo() {
|
|
363
|
+
return (
|
|
364
|
+
<ListGroup.Root {...styles.rows()}>
|
|
365
|
+
<ListGroup.Row action="navigation" render={<a href="#action" />}>
|
|
366
|
+
Activity
|
|
367
|
+
</ListGroup.Row>
|
|
368
|
+
<ListGroup.Row action="navigation" render={<a href="#action" />}>
|
|
369
|
+
Access keys
|
|
370
|
+
</ListGroup.Row>
|
|
371
|
+
<ListGroup.Row onClick={() => {}}>Sign out</ListGroup.Row>
|
|
372
|
+
</ListGroup.Root>
|
|
373
|
+
)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
namespace styles {
|
|
377
|
+
export const rows = style({ maxWidth: '24rem !custom', width: '100% !custom' })
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Action.tsx)
|
|
382
|
+
|
|
383
|
+
### Radio
|
|
384
|
+
|
|
385
|
+
Give each row a `value` inside a `ListGroup.RadioGroup` to pick one option. Each row is a bordered radio. Set `disabled` on a row to keep it visible but unavailable.
|
|
386
|
+
|
|
387
|
+
```tsx
|
|
388
|
+
/** Demonstrates ListGroup rows that pick one account in a ListGroup.RadioGroup. @module */
|
|
389
|
+
import { Avatar, ListGroup, style } from '@tempoxyz/ds'
|
|
390
|
+
|
|
391
|
+
const accounts = [
|
|
392
|
+
{ detail: 'maya@studio.co', disabled: false, initials: 'MR', name: 'Maya Rao', value: 'maya' },
|
|
393
|
+
{ detail: 'ops@acme.co', disabled: false, initials: 'AC', name: 'Acme Co.', value: 'acme' },
|
|
394
|
+
{
|
|
395
|
+
detail: 'Signed out',
|
|
396
|
+
disabled: true,
|
|
397
|
+
initials: 'SW',
|
|
398
|
+
name: 'Savings wallet',
|
|
399
|
+
value: 'savings',
|
|
400
|
+
},
|
|
401
|
+
] as const
|
|
402
|
+
|
|
403
|
+
export function Demo() {
|
|
404
|
+
return (
|
|
405
|
+
<ListGroup.RadioGroup aria-label="Account" defaultValue="maya" {...styles.rows()}>
|
|
406
|
+
{accounts.map((entry) => (
|
|
407
|
+
<ListGroup.Row disabled={entry.disabled} key={entry.value} value={entry.value}>
|
|
408
|
+
<Avatar size="32">
|
|
409
|
+
<Avatar.Fallback>{entry.initials}</Avatar.Fallback>
|
|
410
|
+
</Avatar>
|
|
411
|
+
<ListGroup.Info>
|
|
412
|
+
<ListGroup.Title>{entry.name}</ListGroup.Title>
|
|
413
|
+
<ListGroup.Description>{entry.detail}</ListGroup.Description>
|
|
414
|
+
</ListGroup.Info>
|
|
415
|
+
</ListGroup.Row>
|
|
416
|
+
))}
|
|
417
|
+
</ListGroup.RadioGroup>
|
|
418
|
+
)
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
namespace styles {
|
|
422
|
+
export const rows = style({ maxWidth: '25rem !custom', width: '100% !custom' })
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Radio.tsx)
|
|
427
|
+
|
|
428
|
+
### Option
|
|
429
|
+
|
|
430
|
+
Set `variant="option"` on a `ListGroup.RadioGroup` for the options of a picker. The selected row fills, without a border or a ring.
|
|
431
|
+
|
|
432
|
+
```tsx
|
|
433
|
+
/** Demonstrates ListGroup option rows that pick one account in a picker. @module */
|
|
434
|
+
import { Avatar, ListGroup, style } from '@tempoxyz/ds'
|
|
435
|
+
|
|
436
|
+
const accounts = [
|
|
437
|
+
{ detail: 'maya@studio.co', initials: 'MR', name: 'Maya Rao', value: 'maya' },
|
|
438
|
+
{ detail: 'ops@acme.co', initials: 'AC', name: 'Acme Co.', value: 'acme' },
|
|
439
|
+
] as const
|
|
440
|
+
|
|
441
|
+
export function Demo() {
|
|
442
|
+
return (
|
|
443
|
+
<ListGroup.RadioGroup
|
|
444
|
+
aria-label="Account"
|
|
445
|
+
defaultValue="maya"
|
|
446
|
+
variant="option"
|
|
447
|
+
{...styles.rows()}
|
|
448
|
+
>
|
|
449
|
+
{accounts.map((entry) => (
|
|
450
|
+
<ListGroup.Row key={entry.value} value={entry.value}>
|
|
451
|
+
<Avatar size="32">
|
|
452
|
+
<Avatar.Fallback>{entry.initials}</Avatar.Fallback>
|
|
453
|
+
</Avatar>
|
|
454
|
+
<ListGroup.Info>
|
|
455
|
+
<ListGroup.Title>{entry.name}</ListGroup.Title>
|
|
456
|
+
<ListGroup.Description>{entry.detail}</ListGroup.Description>
|
|
457
|
+
</ListGroup.Info>
|
|
458
|
+
</ListGroup.Row>
|
|
459
|
+
))}
|
|
460
|
+
</ListGroup.RadioGroup>
|
|
461
|
+
)
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
namespace styles {
|
|
465
|
+
export const rows = style({ maxWidth: '25rem !custom', width: '100% !custom' })
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Option.tsx)
|
|
470
|
+
|
|
471
|
+
### Dividers
|
|
472
|
+
|
|
473
|
+
A list group draws a divider above every row after the first. Set `dividers={false}` on `ListGroup.Root` to drop them.
|
|
474
|
+
|
|
475
|
+
```tsx
|
|
476
|
+
import { ListGroup, style } from '@tempoxyz/ds'
|
|
477
|
+
|
|
478
|
+
export function Demo() {
|
|
479
|
+
return (
|
|
480
|
+
<div {...styles.grid()}>
|
|
481
|
+
<ListGroup.Root>
|
|
482
|
+
<ListGroup.Row>
|
|
483
|
+
<ListGroup.Label>Network</ListGroup.Label>
|
|
484
|
+
Tempo
|
|
485
|
+
</ListGroup.Row>
|
|
486
|
+
<ListGroup.Row>
|
|
487
|
+
<ListGroup.Label>Chain ID</ListGroup.Label>
|
|
488
|
+
4217
|
|
489
|
+
</ListGroup.Row>
|
|
490
|
+
</ListGroup.Root>
|
|
491
|
+
<ListGroup.Root dividers={false}>
|
|
492
|
+
<ListGroup.Row>
|
|
493
|
+
<ListGroup.Label>TokenLogo</ListGroup.Label>
|
|
494
|
+
USDT · TRC-20
|
|
495
|
+
</ListGroup.Row>
|
|
496
|
+
<ListGroup.Row>
|
|
497
|
+
<ListGroup.Label>Rate</ListGroup.Label>1 USDT = 1 USD
|
|
498
|
+
</ListGroup.Row>
|
|
499
|
+
</ListGroup.Root>
|
|
500
|
+
</div>
|
|
501
|
+
)
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
namespace styles {
|
|
505
|
+
export const grid = style({
|
|
506
|
+
alignItems: 'start',
|
|
507
|
+
display: 'grid',
|
|
508
|
+
gap: '24',
|
|
509
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(20rem, 1fr)) !custom',
|
|
510
|
+
})
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/ListGroup/Dividers.tsx)
|
|
515
|
+
|
|
516
|
+
## Anatomy
|
|
517
|
+
|
|
518
|
+
Import the component and assemble its parts.
|
|
519
|
+
|
|
520
|
+
```tsx
|
|
521
|
+
import { ListGroup } from '@tempoxyz/ds'
|
|
522
|
+
|
|
523
|
+
<ListGroup.Heading />
|
|
524
|
+
<ListGroup.Root>
|
|
525
|
+
<ListGroup.Row>
|
|
526
|
+
<ListGroup.Icon />
|
|
527
|
+
<ListGroup.Label />
|
|
528
|
+
</ListGroup.Row>
|
|
529
|
+
<ListGroup.Row>
|
|
530
|
+
<ListGroup.Info>
|
|
531
|
+
<ListGroup.Title />
|
|
532
|
+
<ListGroup.Description />
|
|
533
|
+
<ListGroup.Chips />
|
|
534
|
+
</ListGroup.Info>
|
|
535
|
+
<ListGroup.Meter />
|
|
536
|
+
</ListGroup.Row>
|
|
537
|
+
</ListGroup.Root>
|
|
538
|
+
<ListGroup.RadioGroup>
|
|
539
|
+
<ListGroup.Row />
|
|
540
|
+
</ListGroup.RadioGroup>
|
|
541
|
+
<ListGroup>
|
|
542
|
+
<ListGroup.Row />
|
|
543
|
+
</ListGroup>
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## Guidelines
|
|
547
|
+
|
|
548
|
+
### When to Use
|
|
549
|
+
|
|
550
|
+
* Show the facts a person checks as label and value pairs, such as the amount, fee, and recipient of a payment.
|
|
551
|
+
* Let a person pick one contact, wallet, network, or vault from a short list.
|
|
552
|
+
* Show how much of a spending limit each agent used, with `ListGroup.Meter`.
|
|
553
|
+
* List up to three benefits in an onboarding step with `variant="spaced"`.
|
|
554
|
+
* List settings or pages to open, such as Access keys and Connected apps.
|
|
555
|
+
|
|
556
|
+
### When Not to Use
|
|
557
|
+
|
|
558
|
+
* Use [Table](/docs/components/table) to compare many records across the same fields.
|
|
559
|
+
* Use [Accordion](/docs/components/accordion) to reveal details under a heading, such as a fee breakdown or help answers.
|
|
560
|
+
* Use [Menu](/docs/components/menu) for a list of actions that opens from a button.
|
|
561
|
+
* Use [SidebarMenu](/docs/components/sidebar-menu) for the main navigation of an app.
|
|
562
|
+
* Use [Field](/docs/components/field) with form controls when people edit the values.
|
|
563
|
+
* Use [RadioGroup](/docs/components/radio-group) to pick one short text option in a form, without an avatar or a description.
|
|
564
|
+
|
|
565
|
+
### Pick a Variant by What the Group Holds
|
|
566
|
+
|
|
567
|
+
* **Boxed (boxed):** For reviews and receipts: what goes out, what comes in, fees, and key changes.
|
|
568
|
+
* **Plain (plain):** For pickers and recent contacts, where a person taps a row to choose it.
|
|
569
|
+
* **Spaced (spaced):** For checklists, benefits, and short facts that need no dividers between them.
|
|
570
|
+
|
|
571
|
+
### Use One Boxed Group per Topic
|
|
572
|
+
|
|
573
|
+
Give each topic its own boxed group, and name it by what it holds, not by the screen it sits on.
|
|
574
|
+
|
|
575
|
+
**Do:** Name each group by its contents, such as Assets out and Fees.
|
|
576
|
+
|
|
577
|
+
```tsx
|
|
578
|
+
<div style={{ display: 'grid', gap: 16, width: 280 }}>
|
|
579
|
+
<div>
|
|
580
|
+
<ListGroup.Heading>Assets out</ListGroup.Heading>
|
|
581
|
+
<ListGroup.Root variant="boxed">
|
|
582
|
+
<ListGroup.Row>
|
|
583
|
+
<ListGroup.Label>Amount</ListGroup.Label>
|
|
584
|
+
120.00 USDC
|
|
585
|
+
</ListGroup.Row>
|
|
586
|
+
<ListGroup.Row>
|
|
587
|
+
<ListGroup.Label>To</ListGroup.Label>
|
|
588
|
+
Maya Rao
|
|
589
|
+
</ListGroup.Row>
|
|
590
|
+
</ListGroup.Root>
|
|
591
|
+
</div>
|
|
592
|
+
<div>
|
|
593
|
+
<ListGroup.Heading>Fees</ListGroup.Heading>
|
|
594
|
+
<ListGroup.Root variant="boxed">
|
|
595
|
+
<ListGroup.Row>
|
|
596
|
+
<ListGroup.Label>Network fee</ListGroup.Label>
|
|
597
|
+
0.001 USDC
|
|
598
|
+
</ListGroup.Row>
|
|
599
|
+
</ListGroup.Root>
|
|
600
|
+
</div>
|
|
601
|
+
</div>
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
**Don't:** Mix topics in one group named after the screen.
|
|
605
|
+
|
|
606
|
+
```tsx
|
|
607
|
+
<div style={{ width: 280 }}>
|
|
608
|
+
<ListGroup.Heading>Review send</ListGroup.Heading>
|
|
609
|
+
<ListGroup.Root variant="boxed">
|
|
610
|
+
<ListGroup.Row>
|
|
611
|
+
<ListGroup.Label>Amount</ListGroup.Label>
|
|
612
|
+
120.00 USDC
|
|
613
|
+
</ListGroup.Row>
|
|
614
|
+
<ListGroup.Row>
|
|
615
|
+
<ListGroup.Label>To</ListGroup.Label>
|
|
616
|
+
Maya Rao
|
|
617
|
+
</ListGroup.Row>
|
|
618
|
+
<ListGroup.Row>
|
|
619
|
+
<ListGroup.Label>Network fee</ListGroup.Label>
|
|
620
|
+
0.001 USDC
|
|
621
|
+
</ListGroup.Row>
|
|
622
|
+
</ListGroup.Root>
|
|
623
|
+
</div>
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Put the Label First
|
|
627
|
+
|
|
628
|
+
`ListGroup.Label` keeps its width and pushes the value to the end of the row. Format values with [Amount](/docs/components/amount), [Hex](/docs/components/hex), and [Badge](/docs/components/badge).
|
|
629
|
+
|
|
630
|
+
**Do:** Pair each `ListGroup.Label` with a formatted value, such as an `Amount` or a `Hex`.
|
|
631
|
+
|
|
632
|
+
```tsx
|
|
633
|
+
/**
|
|
634
|
+
* Do example for "Put the Label First" on the ListGroup page.
|
|
635
|
+
* Pair each `ListGroup.Label` with a formatted value, such as an `Amount` or a `Hex`.
|
|
636
|
+
* @module
|
|
637
|
+
*/
|
|
638
|
+
import { Amount, Badge, Hex, ListGroup, style } from '@tempoxyz/ds'
|
|
639
|
+
|
|
640
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
641
|
+
export function Demo() {
|
|
642
|
+
return (
|
|
643
|
+
<ListGroup {...styles.rows()}>
|
|
644
|
+
<ListGroup.Row>
|
|
645
|
+
<ListGroup.Label>Amount</ListGroup.Label>
|
|
646
|
+
<Amount symbol="USDC" value="48.50" />
|
|
647
|
+
</ListGroup.Row>
|
|
648
|
+
<ListGroup.Row>
|
|
649
|
+
<ListGroup.Label>Network fee</ListGroup.Label>
|
|
650
|
+
<Amount symbol="USDC" value="0.0004" />
|
|
651
|
+
</ListGroup.Row>
|
|
652
|
+
<ListGroup.Row>
|
|
653
|
+
<ListGroup.Label>Recipient</ListGroup.Label>
|
|
654
|
+
<span {...styles.value()}>
|
|
655
|
+
<Hex value="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" />
|
|
656
|
+
</span>
|
|
657
|
+
</ListGroup.Row>
|
|
658
|
+
<ListGroup.Row>
|
|
659
|
+
<ListGroup.Label>Status</ListGroup.Label>
|
|
660
|
+
<Badge>Confirmed</Badge>
|
|
661
|
+
</ListGroup.Row>
|
|
662
|
+
</ListGroup>
|
|
663
|
+
)
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
namespace styles {
|
|
667
|
+
export const rows = style({ width: '100% !custom' })
|
|
668
|
+
|
|
669
|
+
// Hex shrinks to its container, so the cap goes on a wrapper.
|
|
670
|
+
export const value = style({ display: 'inline-flex', maxWidth: '10rem !custom', minWidth: '0' })
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
**Don't:** Use a `Table` with Field and Value columns for one record.
|
|
675
|
+
|
|
676
|
+
```tsx
|
|
677
|
+
/**
|
|
678
|
+
* Don't example for "Put the Label First" on the ListGroup page.
|
|
679
|
+
* Don't use a `Table` with Field and Value columns for one record.
|
|
680
|
+
* @module
|
|
681
|
+
*/
|
|
682
|
+
import { Table } from '@tempoxyz/ds'
|
|
683
|
+
|
|
684
|
+
const fields = [
|
|
685
|
+
['Amount', '48.50 USDC'],
|
|
686
|
+
['Network fee', '0.0004 USDC'],
|
|
687
|
+
['Recipient', '0xd8dA…6045'],
|
|
688
|
+
['Status', 'Confirmed'],
|
|
689
|
+
] as const
|
|
690
|
+
|
|
691
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
692
|
+
export function Demo() {
|
|
693
|
+
return (
|
|
694
|
+
<Table size="small">
|
|
695
|
+
<Table.Head>
|
|
696
|
+
<Table.Row>
|
|
697
|
+
<Table.HeaderCell>Field</Table.HeaderCell>
|
|
698
|
+
<Table.HeaderCell>Value</Table.HeaderCell>
|
|
699
|
+
</Table.Row>
|
|
700
|
+
</Table.Head>
|
|
701
|
+
<Table.Body>
|
|
702
|
+
{fields.map(([field, value]) => (
|
|
703
|
+
<Table.Row key={field}>
|
|
704
|
+
<Table.Cell>{field}</Table.Cell>
|
|
705
|
+
<Table.Cell>{value}</Table.Cell>
|
|
706
|
+
</Table.Row>
|
|
707
|
+
))}
|
|
708
|
+
</Table.Body>
|
|
709
|
+
</Table>
|
|
710
|
+
)
|
|
711
|
+
}
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
### Shorten Addresses in Rows
|
|
715
|
+
|
|
716
|
+
A [Hex](/docs/components/hex) fills the space beside its label, so a long address crowds the label and ends short of the other values. Wrap it in an element capped at about `10rem`, and add `copy`. Before a payment, show the full recipient outside the rows, as the [Hex](/docs/components/hex) page shows.
|
|
717
|
+
|
|
718
|
+
**Do:** Cap the width of a `Hex` so it ends with the other values.
|
|
719
|
+
|
|
720
|
+
```tsx
|
|
721
|
+
/**
|
|
722
|
+
* Do example for "Shorten Addresses in ListGroup" on the ListGroup page.
|
|
723
|
+
* Cap the width of a `Hex` so it ends with the other values.
|
|
724
|
+
* @module
|
|
725
|
+
*/
|
|
726
|
+
import { Amount, Hex, ListGroup, style } from '@tempoxyz/ds'
|
|
727
|
+
|
|
728
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
729
|
+
export function Demo() {
|
|
730
|
+
return (
|
|
731
|
+
<ListGroup {...styles.rows()}>
|
|
732
|
+
<ListGroup.Row>
|
|
733
|
+
<ListGroup.Label>Amount</ListGroup.Label>
|
|
734
|
+
<Amount symbol="USDC" value="48.50" />
|
|
735
|
+
</ListGroup.Row>
|
|
736
|
+
<ListGroup.Row>
|
|
737
|
+
<ListGroup.Label>Recipient</ListGroup.Label>
|
|
738
|
+
<span {...styles.value()}>
|
|
739
|
+
<Hex copy value="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" />
|
|
740
|
+
</span>
|
|
741
|
+
</ListGroup.Row>
|
|
742
|
+
</ListGroup>
|
|
743
|
+
)
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
namespace styles {
|
|
747
|
+
export const rows = style({ width: '100% !custom' })
|
|
748
|
+
|
|
749
|
+
// Hex shrinks to its container, so the cap goes on a wrapper.
|
|
750
|
+
export const value = style({ display: 'inline-flex', maxWidth: '10rem !custom', minWidth: '0' })
|
|
751
|
+
}
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
**Don't:** Let a `Hex` fill the row up to its label.
|
|
755
|
+
|
|
756
|
+
```tsx
|
|
757
|
+
/**
|
|
758
|
+
* Don't example for "Shorten Addresses in ListGroup" on the ListGroup page.
|
|
759
|
+
* Don't let a `Hex` fill the row up to its label.
|
|
760
|
+
* @module
|
|
761
|
+
*/
|
|
762
|
+
import { Amount, Hex, ListGroup, style } from '@tempoxyz/ds'
|
|
763
|
+
|
|
764
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
765
|
+
export function Demo() {
|
|
766
|
+
return (
|
|
767
|
+
<ListGroup {...styles.rows()}>
|
|
768
|
+
<ListGroup.Row>
|
|
769
|
+
<ListGroup.Label>Amount</ListGroup.Label>
|
|
770
|
+
<Amount symbol="USDC" value="48.50" />
|
|
771
|
+
</ListGroup.Row>
|
|
772
|
+
<ListGroup.Row>
|
|
773
|
+
<ListGroup.Label>Recipient</ListGroup.Label>
|
|
774
|
+
<Hex copy value="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" />
|
|
775
|
+
</ListGroup.Row>
|
|
776
|
+
</ListGroup>
|
|
777
|
+
)
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
namespace styles {
|
|
781
|
+
export const rows = style({ width: '100% !custom' })
|
|
782
|
+
}
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
### Pick an Action by What the Row Does
|
|
786
|
+
|
|
787
|
+
* **None (none):** For read-only details, such as Chain ID. With `onClick`, the row becomes a button.
|
|
788
|
+
* **Navigation (navigation):** Opens another page and shows a trailing chevron. Renders a button, or a link through `render`.
|
|
789
|
+
* **Copy (Button):** Copies a value. Keep the row static, which fills on hover, and end it with an `xsmall` [Button](/docs/components/button).
|
|
790
|
+
|
|
791
|
+
### Keep Pressable Rows Free of Other Controls
|
|
792
|
+
|
|
793
|
+
A pressable row is one button or link. If a row holds its own control, such as a [Switch](/docs/components/switch), leave `action` and `onClick` off and place the control at the end. The row fills on hover, and the control stays the only target.
|
|
794
|
+
|
|
795
|
+
**Do:** Place the control at the end of a static row.
|
|
796
|
+
|
|
797
|
+
```tsx
|
|
798
|
+
/**
|
|
799
|
+
* Do example for "Keep Pressable ListGroup Free of Other Controls" on the ListGroup page.
|
|
800
|
+
* Place the control at the end of a static row.
|
|
801
|
+
* @module
|
|
802
|
+
*/
|
|
803
|
+
import { ListGroup, style, Switch } from '@tempoxyz/ds'
|
|
804
|
+
|
|
805
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
806
|
+
export function Demo() {
|
|
807
|
+
return (
|
|
808
|
+
<ListGroup {...styles.rows()}>
|
|
809
|
+
<ListGroup.Row action="navigation">Access keys</ListGroup.Row>
|
|
810
|
+
<ListGroup.Row>
|
|
811
|
+
<ListGroup.Label>Payment emails</ListGroup.Label>
|
|
812
|
+
<Switch aria-label="Payment emails" defaultChecked />
|
|
813
|
+
</ListGroup.Row>
|
|
814
|
+
</ListGroup>
|
|
815
|
+
)
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
namespace styles {
|
|
819
|
+
export const rows = style({ width: '100% !custom' })
|
|
820
|
+
}
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
**Don't:** Nest a control in a row with an `action`.
|
|
824
|
+
|
|
825
|
+
```tsx
|
|
826
|
+
/**
|
|
827
|
+
* Don't example for "Keep Pressable ListGroup Free of Other Controls" on the ListGroup page.
|
|
828
|
+
* Don't nest a control in a row with an `action`.
|
|
829
|
+
* @module
|
|
830
|
+
*/
|
|
831
|
+
import { ListGroup, style, Switch } from '@tempoxyz/ds'
|
|
832
|
+
|
|
833
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
834
|
+
export function Demo() {
|
|
835
|
+
return (
|
|
836
|
+
<ListGroup {...styles.rows()}>
|
|
837
|
+
<ListGroup.Row action="navigation">Access keys</ListGroup.Row>
|
|
838
|
+
<ListGroup.Row action="navigation">
|
|
839
|
+
<ListGroup.Label>Payment emails</ListGroup.Label>
|
|
840
|
+
<Switch aria-label="Payment emails" defaultChecked />
|
|
841
|
+
</ListGroup.Row>
|
|
842
|
+
</ListGroup>
|
|
843
|
+
)
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
namespace styles {
|
|
847
|
+
export const rows = style({ width: '100% !custom' })
|
|
848
|
+
}
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
## Content
|
|
852
|
+
|
|
853
|
+
* **Row text:** Name the destination or setting, such as Access keys, not Manage. The chevron is hidden from screen readers.
|
|
854
|
+
* **Labels:** Short nouns without colons, such as Network fee.
|
|
855
|
+
* **Descriptions:** One line of current state in `ListGroup.Description`, such as 2 active keys.
|
|
856
|
+
* **Group headings:** Name what the group holds, such as Fees, Assets out, or Contacts.
|
|
857
|
+
* **Checklists:** Three benefits at most, each a short line, such as Approve with your device, no codes.
|
|
858
|
+
* **Order:** Keep the same labels in the same order wherever a record appears, such as a review and its receipt.
|
|
859
|
+
|
|
860
|
+
**Do:** Name the page each row opens.
|
|
861
|
+
|
|
862
|
+
```tsx
|
|
863
|
+
/**
|
|
864
|
+
* Do example for the Content section on the ListGroup page.
|
|
865
|
+
* Name the page each row opens.
|
|
866
|
+
* @module
|
|
867
|
+
*/
|
|
868
|
+
import { ListGroup, style } from '@tempoxyz/ds'
|
|
869
|
+
|
|
870
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
871
|
+
export function Demo() {
|
|
872
|
+
return (
|
|
873
|
+
<ListGroup {...styles.rows()}>
|
|
874
|
+
<ListGroup.Row action="navigation">Access keys</ListGroup.Row>
|
|
875
|
+
<ListGroup.Row action="navigation">Recovery methods</ListGroup.Row>
|
|
876
|
+
<ListGroup.Row action="navigation">Connected apps</ListGroup.Row>
|
|
877
|
+
</ListGroup>
|
|
878
|
+
)
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
namespace styles {
|
|
882
|
+
export const rows = style({ width: '100% !custom' })
|
|
883
|
+
}
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
**Don't:** Use vague labels such as Manage, View more, or Other.
|
|
887
|
+
|
|
888
|
+
```tsx
|
|
889
|
+
/**
|
|
890
|
+
* Don't example for the Content section on the ListGroup page.
|
|
891
|
+
* Don't use vague labels such as Manage, View more, or Other.
|
|
892
|
+
* @module
|
|
893
|
+
*/
|
|
894
|
+
import { ListGroup, style } from '@tempoxyz/ds'
|
|
895
|
+
|
|
896
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
897
|
+
export function Demo() {
|
|
898
|
+
return (
|
|
899
|
+
<ListGroup {...styles.rows()}>
|
|
900
|
+
<ListGroup.Row action="navigation">Manage</ListGroup.Row>
|
|
901
|
+
<ListGroup.Row action="navigation">View more</ListGroup.Row>
|
|
902
|
+
<ListGroup.Row action="navigation">Other</ListGroup.Row>
|
|
903
|
+
</ListGroup>
|
|
904
|
+
)
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
namespace styles {
|
|
908
|
+
export const rows = style({ width: '100% !custom' })
|
|
909
|
+
}
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
## Accessibility
|
|
913
|
+
|
|
914
|
+
### Semantics
|
|
915
|
+
|
|
916
|
+
* **ListGroup.Root (div):** Adds no role. The rows read as plain content.
|
|
917
|
+
* **Row Elements (button):** Pressable rows render a `button`, or the `render` element.
|
|
918
|
+
* **Chevron (aria-hidden):** The navigation chevron is hidden from screen readers.
|
|
919
|
+
* **ListGroup.Label (span):** A key-value row reads as plain text, such as "Network Tempo".
|
|
920
|
+
* **Radio Rows (radio):** A row with a `value` reads as a radio, named by its text.
|
|
921
|
+
* **ListGroup.Meter (meter):** Reads its name and `aria-valuetext`, not the value shown.
|
|
922
|
+
* **Disabled Rows (disabled):** Sets `disabled` or `aria-disabled`, and dims the row.
|
|
923
|
+
|
|
924
|
+
### Keyboard
|
|
925
|
+
|
|
926
|
+
* **Move Between Rows (Tab):** Moves focus to the next button, link, or radio group.
|
|
927
|
+
* **Activate a Row (Enter):** Activates a button or link row.
|
|
928
|
+
* **Press a Button Row (Space):** Activates a button row.
|
|
929
|
+
* **Pick a Radio Row (Down Arrow):** Moves focus and selection to the next radio row.
|
|
930
|
+
|
|
931
|
+
### Your Responsibilities
|
|
932
|
+
|
|
933
|
+
* **Render Links for Navigation (render):** Use a real link through `render`, so middle-click, the context menu, and screen reader link lists work.
|
|
934
|
+
* **Head Each Group (ListGroup.Heading):** ListGroup adds no role or name. Pass a heading element to `ListGroup.Heading` through `render`.
|
|
935
|
+
* **Name Radio Groups and Meters (aria-label):** Name each `ListGroup.RadioGroup` and `ListGroup.Meter`, and pass `getAriaValueText` to a meter.
|
|
936
|
+
|
|
937
|
+
## Related
|
|
938
|
+
|
|
939
|
+
[Table](/docs/components/table)
|
|
940
|
+
|
|
941
|
+
Use for comparing many records.
|
|
942
|
+
|
|
943
|
+
[Accordion](/docs/components/accordion)
|
|
944
|
+
|
|
945
|
+
Use for collapsible sections of content.
|
|
946
|
+
|
|
947
|
+
[Surface](/docs/components/surface)
|
|
948
|
+
|
|
949
|
+
Use for grouping rows in a card.
|
|
950
|
+
|
|
951
|
+
[Amount](/docs/components/amount)
|
|
952
|
+
|
|
953
|
+
Use for values.
|
|
954
|
+
|
|
955
|
+
[Hex](/docs/components/hex)
|
|
956
|
+
|
|
957
|
+
Use for values.
|
|
958
|
+
|
|
959
|
+
[Avatar](/docs/components/avatar)
|
|
960
|
+
|
|
961
|
+
Use for the leading image of a contact row.
|
|
962
|
+
|
|
963
|
+
[NetworkLogo](/docs/components/network-logo)
|
|
964
|
+
|
|
965
|
+
Use for the leading logo of a network row.
|
|
966
|
+
|
|
967
|
+
[AssetChip](/docs/components/asset-chip)
|
|
968
|
+
|
|
969
|
+
Use for the assets a network row supports.
|
|
970
|
+
|
|
971
|
+
[AgentLogo](/docs/components/agent-logo)
|
|
972
|
+
|
|
973
|
+
Use for the leading logo of an agent row.
|
|
974
|
+
|
|
975
|
+
[RadioGroup](/docs/components/radio-group)
|
|
976
|
+
|
|
977
|
+
Use for picking one short text option in a form.
|
|
978
|
+
|
|
979
|
+
[Tables and Lists](/docs/patterns/tables-and-lists)
|
|
980
|
+
|
|
981
|
+
Covers choosing a layout.
|