@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,517 @@
|
|
|
1
|
+
# Skeleton
|
|
2
|
+
|
|
3
|
+
Holds the place of content while it loads.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Skeleton.tsx)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Skeleton renders a loading placeholder at the size of the content it wraps.
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Basic
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { Skeleton, style } from '@tempoxyz/ds'
|
|
17
|
+
|
|
18
|
+
export function Demo() {
|
|
19
|
+
return (
|
|
20
|
+
<div {...styles.row()}>
|
|
21
|
+
<div {...styles.column()}>
|
|
22
|
+
<Skeleton style={{ height: 14, width: 160 }} />
|
|
23
|
+
<Skeleton style={{ height: 14, width: 96 }} />
|
|
24
|
+
</div>
|
|
25
|
+
<Skeleton>
|
|
26
|
+
<p {...styles.text()}>Keeps the size of its content</p>
|
|
27
|
+
</Skeleton>
|
|
28
|
+
</div>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
namespace styles {
|
|
33
|
+
export const column = style({ display: 'flex', flexDirection: 'column', gap: '8' })
|
|
34
|
+
|
|
35
|
+
export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '16' })
|
|
36
|
+
|
|
37
|
+
export const text = style({ margin: '0', typography: 'body.b2' })
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Skeleton/Basic.tsx)
|
|
42
|
+
|
|
43
|
+
### Shape
|
|
44
|
+
|
|
45
|
+
Set `shape` to `default` (default), `pill`, or `circle`.
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { Skeleton, style } from '@tempoxyz/ds'
|
|
49
|
+
|
|
50
|
+
export function Demo() {
|
|
51
|
+
return (
|
|
52
|
+
<div {...styles.row()}>
|
|
53
|
+
<Skeleton shape="circle" style={{ height: 40, width: 40 }} />
|
|
54
|
+
<Skeleton shape="default" style={{ height: 14, width: 160 }} />
|
|
55
|
+
<Skeleton shape="pill" style={{ height: 32, width: 96 }} />
|
|
56
|
+
</div>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
namespace styles {
|
|
61
|
+
export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '16' })
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Skeleton/Shape.tsx)
|
|
66
|
+
|
|
67
|
+
### Show
|
|
68
|
+
|
|
69
|
+
Set `show={false}` when data arrives to reveal the content. `show` defaults to `true`.
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
import { Skeleton, style } from '@tempoxyz/ds'
|
|
73
|
+
|
|
74
|
+
export function Demo() {
|
|
75
|
+
return (
|
|
76
|
+
<div {...styles.row()}>
|
|
77
|
+
<Skeleton>
|
|
78
|
+
<p {...styles.text()}>Loading content</p>
|
|
79
|
+
</Skeleton>
|
|
80
|
+
<Skeleton show={false}>
|
|
81
|
+
<p {...styles.text()}>Loaded content</p>
|
|
82
|
+
</Skeleton>
|
|
83
|
+
</div>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
namespace styles {
|
|
88
|
+
export const row = style({ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '16' })
|
|
89
|
+
|
|
90
|
+
export const text = style({ margin: '0', typography: 'body.b2' })
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Skeleton/Show.tsx)
|
|
95
|
+
|
|
96
|
+
## Anatomy
|
|
97
|
+
|
|
98
|
+
Import the component and assemble its parts.
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { Skeleton } from '@tempoxyz/ds'
|
|
102
|
+
|
|
103
|
+
<Skeleton />
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Guidelines
|
|
107
|
+
|
|
108
|
+
### When to Use
|
|
109
|
+
|
|
110
|
+
* Hold the place of content with a known layout, such as balances, activity rows, or metric tiles.
|
|
111
|
+
* Fill table rows, cards, and lists on first load, with the expected or a typical item count.
|
|
112
|
+
|
|
113
|
+
### When Not to Use
|
|
114
|
+
|
|
115
|
+
* Use [Spinner](/docs/components/spinner) when the shape of the result is unknown, or for a busy control.
|
|
116
|
+
* Use [Progress](/docs/components/progress) for a long task with measurable work.
|
|
117
|
+
* Use `loading` on a [Button](/docs/components/button) while its action runs.
|
|
118
|
+
* Use [Empty](/docs/components/empty) when the request returns no records.
|
|
119
|
+
|
|
120
|
+
### Match the Final Content's Shape
|
|
121
|
+
|
|
122
|
+
* **`circle`:** Avatars, identicons, and token icons.
|
|
123
|
+
* **`pill`:** Pill-shaped controls, such as an extra-small button.
|
|
124
|
+
* **`default`:** Text, blocks, badges, and buttons.
|
|
125
|
+
|
|
126
|
+
For a list, repeat each row's structure instead of one block.
|
|
127
|
+
|
|
128
|
+
**Do:** Mirror each row's icon, text lines, and amount.
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
/**
|
|
132
|
+
* Do example for "Match the Final Content's Shape" on the Skeleton page.
|
|
133
|
+
* Mirror each row's icon, text lines, and amount.
|
|
134
|
+
* @module
|
|
135
|
+
*/
|
|
136
|
+
import { Skeleton, style } from '@tempoxyz/ds'
|
|
137
|
+
|
|
138
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
139
|
+
export function Demo() {
|
|
140
|
+
return (
|
|
141
|
+
<div {...styles.list()}>
|
|
142
|
+
{['0x8f3c…a21b', '0x41d2…9c07', '0xb7e0…3f5a'].map((address) => (
|
|
143
|
+
<div {...styles.row()} key={address}>
|
|
144
|
+
<Skeleton shape="circle" style={{ height: 32, width: 32 }} />
|
|
145
|
+
<div {...styles.text()}>
|
|
146
|
+
<Skeleton>
|
|
147
|
+
<div {...styles.title()}>{address}</div>
|
|
148
|
+
</Skeleton>
|
|
149
|
+
<Skeleton>
|
|
150
|
+
<div {...styles.meta()}>Oct 18, 14:02</div>
|
|
151
|
+
</Skeleton>
|
|
152
|
+
</div>
|
|
153
|
+
<Skeleton>
|
|
154
|
+
<div {...styles.title()}>+50.00 USDC</div>
|
|
155
|
+
</Skeleton>
|
|
156
|
+
</div>
|
|
157
|
+
))}
|
|
158
|
+
</div>
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
namespace styles {
|
|
163
|
+
export const list = style({ display: 'flex', flexDirection: 'column', gap: '16' })
|
|
164
|
+
|
|
165
|
+
export const meta = style({ typography: 'body.b3' })
|
|
166
|
+
|
|
167
|
+
export const row = style({ alignItems: 'center', display: 'flex', gap: '12' })
|
|
168
|
+
|
|
169
|
+
export const text = style({
|
|
170
|
+
alignItems: 'flex-start',
|
|
171
|
+
display: 'flex',
|
|
172
|
+
flex: '1 !custom',
|
|
173
|
+
flexDirection: 'column',
|
|
174
|
+
gap: '4',
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
export const title = style({ typography: 'body.b2' })
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Don't:** Cover a list with one block that hides its structure.
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
/**
|
|
185
|
+
* Don't example for "Match the Final Content's Shape" on the Skeleton page.
|
|
186
|
+
* Don't cover a list with one block that hides its structure.
|
|
187
|
+
* @module
|
|
188
|
+
*/
|
|
189
|
+
import { Skeleton } from '@tempoxyz/ds'
|
|
190
|
+
|
|
191
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
192
|
+
export function Demo() {
|
|
193
|
+
return <Skeleton style={{ height: 144, width: 256 }} />
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Wrap the Real Content
|
|
198
|
+
|
|
199
|
+
Skeleton takes the size of its children and hides them with `visibility: hidden`. Set `show={false}` when the data arrives, so the content keeps its place in reading order.
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
<Skeleton show={loading}>
|
|
203
|
+
<Amount currency="USD" value={balance} />
|
|
204
|
+
</Skeleton>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Size an empty skeleton with `style` only when there is nothing to wrap.
|
|
208
|
+
|
|
209
|
+
**Do:** Wrap the element that holds the data, with a placeholder of typical length.
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
/**
|
|
213
|
+
* Do example for "Wrap the Real Content" on the Skeleton page.
|
|
214
|
+
* Wrap the element that holds the data, with a placeholder of typical length.
|
|
215
|
+
* @module
|
|
216
|
+
*/
|
|
217
|
+
import { Skeleton, style } from '@tempoxyz/ds'
|
|
218
|
+
|
|
219
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
220
|
+
export function Demo() {
|
|
221
|
+
return (
|
|
222
|
+
<div {...styles.card()}>
|
|
223
|
+
<div {...styles.label()}>Balance</div>
|
|
224
|
+
<Skeleton>
|
|
225
|
+
<div {...styles.value()}>1,250.00 USDC</div>
|
|
226
|
+
</Skeleton>
|
|
227
|
+
</div>
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
namespace styles {
|
|
232
|
+
export const card = style({
|
|
233
|
+
alignItems: 'flex-start',
|
|
234
|
+
display: 'flex',
|
|
235
|
+
flexDirection: 'column',
|
|
236
|
+
gap: '4',
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
240
|
+
|
|
241
|
+
export const value = style({ color: 'content.primary', typography: 'heading.h1' })
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Don't:** Swap in a separately sized block that doesn't match the content.
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
/**
|
|
249
|
+
* Don't example for "Wrap the Real Content" on the Skeleton page.
|
|
250
|
+
* Don't swap in a separately sized block that doesn't match the content.
|
|
251
|
+
* @module
|
|
252
|
+
*/
|
|
253
|
+
import { Skeleton, style } from '@tempoxyz/ds'
|
|
254
|
+
|
|
255
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
256
|
+
export function Demo() {
|
|
257
|
+
return (
|
|
258
|
+
<div {...styles.card()}>
|
|
259
|
+
<div {...styles.label()}>Balance</div>
|
|
260
|
+
<Skeleton style={{ height: 12, width: 80 }} />
|
|
261
|
+
</div>
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
namespace styles {
|
|
266
|
+
export const card = style({
|
|
267
|
+
alignItems: 'flex-start',
|
|
268
|
+
display: 'flex',
|
|
269
|
+
flexDirection: 'column',
|
|
270
|
+
gap: '4',
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Keep Labels and Controls Visible
|
|
278
|
+
|
|
279
|
+
Keep headings, labels, tabs, filters, and buttons that do not depend on the data on screen.
|
|
280
|
+
|
|
281
|
+
**Do:** Keep the label and actions, and hold the place of the amount.
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
/**
|
|
285
|
+
* Do example for "Keep Labels and Controls Visible" on the Skeleton page.
|
|
286
|
+
* Keep the label and actions, and hold the place of the amount.
|
|
287
|
+
* @module
|
|
288
|
+
*/
|
|
289
|
+
import { Button, Skeleton, style } from '@tempoxyz/ds'
|
|
290
|
+
|
|
291
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
292
|
+
export function Demo() {
|
|
293
|
+
return (
|
|
294
|
+
<div {...styles.card()}>
|
|
295
|
+
<div {...styles.label()}>Balance</div>
|
|
296
|
+
<Skeleton>
|
|
297
|
+
<div {...styles.value()}>$1,250.00</div>
|
|
298
|
+
</Skeleton>
|
|
299
|
+
<div {...styles.actions()}>
|
|
300
|
+
<Button size="small">Send</Button>
|
|
301
|
+
<Button size="small" variant="secondary">
|
|
302
|
+
Receive
|
|
303
|
+
</Button>
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
namespace styles {
|
|
310
|
+
export const actions = style({ display: 'flex', gap: '8', marginBlockStart: '12' })
|
|
311
|
+
|
|
312
|
+
export const card = style({
|
|
313
|
+
alignItems: 'flex-start',
|
|
314
|
+
display: 'flex',
|
|
315
|
+
flexDirection: 'column',
|
|
316
|
+
gap: '4',
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
320
|
+
|
|
321
|
+
export const value = style({ color: 'content.primary', typography: 'heading.h1' })
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Don't:** Turn static labels and buttons into skeletons.
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
/**
|
|
329
|
+
* Don't example for "Keep Labels and Controls Visible" on the Skeleton page.
|
|
330
|
+
* Don't turn static labels and buttons into skeletons.
|
|
331
|
+
* @module
|
|
332
|
+
*/
|
|
333
|
+
import { Button, Skeleton, style } from '@tempoxyz/ds'
|
|
334
|
+
|
|
335
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
336
|
+
export function Demo() {
|
|
337
|
+
return (
|
|
338
|
+
<div {...styles.card()}>
|
|
339
|
+
<Skeleton>
|
|
340
|
+
<div {...styles.label()}>Balance</div>
|
|
341
|
+
</Skeleton>
|
|
342
|
+
<Skeleton>
|
|
343
|
+
<div {...styles.value()}>$1,250.00</div>
|
|
344
|
+
</Skeleton>
|
|
345
|
+
<div {...styles.actions()}>
|
|
346
|
+
<Skeleton shape="pill">
|
|
347
|
+
<Button size="small">Send</Button>
|
|
348
|
+
</Skeleton>
|
|
349
|
+
<Skeleton shape="pill">
|
|
350
|
+
<Button size="small" variant="secondary">
|
|
351
|
+
Receive
|
|
352
|
+
</Button>
|
|
353
|
+
</Skeleton>
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
namespace styles {
|
|
360
|
+
export const actions = style({ display: 'flex', gap: '8', marginBlockStart: '12' })
|
|
361
|
+
|
|
362
|
+
export const card = style({
|
|
363
|
+
alignItems: 'flex-start',
|
|
364
|
+
display: 'flex',
|
|
365
|
+
flexDirection: 'column',
|
|
366
|
+
gap: '4',
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
export const label = style({ color: 'content.secondary', typography: 'body.b3' })
|
|
370
|
+
|
|
371
|
+
export const value = style({ color: 'content.primary', typography: 'heading.h1' })
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Keep Current Data During a Refresh
|
|
376
|
+
|
|
377
|
+
**Do:** Keep values on screen, such as a polled balance, until the new ones arrive.
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
/**
|
|
381
|
+
* Do example for "Keep Current Data During a Refresh" on the Skeleton page.
|
|
382
|
+
* Keep values on screen, such as a polled balance, until the new ones arrive.
|
|
383
|
+
* @module
|
|
384
|
+
*/
|
|
385
|
+
import { style } from '@tempoxyz/ds'
|
|
386
|
+
|
|
387
|
+
const payments = [
|
|
388
|
+
{ address: '0x8f3c…a21b', amount: '+50.00 USDC' },
|
|
389
|
+
{ address: '0x41d2…9c07', amount: '-25.00 USDC' },
|
|
390
|
+
]
|
|
391
|
+
|
|
392
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
393
|
+
export function Demo() {
|
|
394
|
+
return (
|
|
395
|
+
<div {...styles.list()}>
|
|
396
|
+
<div {...styles.heading()}>Activity</div>
|
|
397
|
+
{payments.map((payment) => (
|
|
398
|
+
<div {...styles.row()} key={payment.address}>
|
|
399
|
+
<div>{payment.address}</div>
|
|
400
|
+
<div>{payment.amount}</div>
|
|
401
|
+
</div>
|
|
402
|
+
))}
|
|
403
|
+
</div>
|
|
404
|
+
)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
namespace styles {
|
|
408
|
+
export const heading = style({ color: 'content.primary', typography: 'body.b2Strong' })
|
|
409
|
+
|
|
410
|
+
export const list = style({
|
|
411
|
+
display: 'flex',
|
|
412
|
+
flexDirection: 'column',
|
|
413
|
+
gap: '12',
|
|
414
|
+
width: '100% !custom',
|
|
415
|
+
})
|
|
416
|
+
|
|
417
|
+
export const row = style({
|
|
418
|
+
alignItems: 'center',
|
|
419
|
+
display: 'flex',
|
|
420
|
+
justifyContent: 'space-between',
|
|
421
|
+
typography: 'body.b2',
|
|
422
|
+
})
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**Don't:** Return to skeletons on every refresh.
|
|
427
|
+
|
|
428
|
+
```tsx
|
|
429
|
+
/**
|
|
430
|
+
* Don't example for "Keep Current Data During a Refresh" on the Skeleton page.
|
|
431
|
+
* Don't return to skeletons on every refresh.
|
|
432
|
+
* @module
|
|
433
|
+
*/
|
|
434
|
+
import { Skeleton, style } from '@tempoxyz/ds'
|
|
435
|
+
|
|
436
|
+
const payments = [
|
|
437
|
+
{ address: '0x8f3c…a21b', amount: '+50.00 USDC' },
|
|
438
|
+
{ address: '0x41d2…9c07', amount: '-25.00 USDC' },
|
|
439
|
+
]
|
|
440
|
+
|
|
441
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
442
|
+
export function Demo() {
|
|
443
|
+
return (
|
|
444
|
+
<div {...styles.list()}>
|
|
445
|
+
<div {...styles.heading()}>Activity</div>
|
|
446
|
+
{payments.map((payment) => (
|
|
447
|
+
<div {...styles.row()} key={payment.address}>
|
|
448
|
+
<Skeleton>
|
|
449
|
+
<div>{payment.address}</div>
|
|
450
|
+
</Skeleton>
|
|
451
|
+
<Skeleton>
|
|
452
|
+
<div>{payment.amount}</div>
|
|
453
|
+
</Skeleton>
|
|
454
|
+
</div>
|
|
455
|
+
))}
|
|
456
|
+
</div>
|
|
457
|
+
)
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
namespace styles {
|
|
461
|
+
export const heading = style({ color: 'content.primary', typography: 'body.b2Strong' })
|
|
462
|
+
|
|
463
|
+
export const list = style({
|
|
464
|
+
display: 'flex',
|
|
465
|
+
flexDirection: 'column',
|
|
466
|
+
gap: '12',
|
|
467
|
+
width: '100% !custom',
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
export const row = style({
|
|
471
|
+
alignItems: 'center',
|
|
472
|
+
display: 'flex',
|
|
473
|
+
justifyContent: 'space-between',
|
|
474
|
+
typography: 'body.b2',
|
|
475
|
+
})
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Skip It for Fast Responses
|
|
480
|
+
|
|
481
|
+
* **Fast Responses (Under 300 ms):** Delay the skeleton, so the content renders without a flash.
|
|
482
|
+
* **Typical Waits (300 ms to 10 s):** Show the skeleton.
|
|
483
|
+
* **Long Waits (Over 10 s):** Show [Progress](/docs/components/progress). See [Loading](/docs/patterns/loading).
|
|
484
|
+
|
|
485
|
+
## Accessibility
|
|
486
|
+
|
|
487
|
+
Skeleton renders a `div` that marks its content busy and hides it until `show={false}`. It has no live region, and most screen readers ignore `aria-busy` on a plain `div`.
|
|
488
|
+
|
|
489
|
+
### Semantics
|
|
490
|
+
|
|
491
|
+
* **Busy State (aria-busy):** Marks the region busy while `show` is true.
|
|
492
|
+
* **Hidden Content (visibility: hidden):** Screen readers skip the placeholder text, and focus cannot reach hidden controls.
|
|
493
|
+
* **Pointer Events:** The root blocks pointer events while it shows, so placeholder buttons are inert.
|
|
494
|
+
* **Reduced Motion (prefers-reduced-motion):** The sweep stops, and the placeholder stays a static tint.
|
|
495
|
+
|
|
496
|
+
### Your Responsibilities
|
|
497
|
+
|
|
498
|
+
* **Announce Long Loads (status):** For main content, state what loads in a status message, such as "Loading activity".
|
|
499
|
+
* **Handle Failures:** If loading fails, show an error message. Never leave a skeleton that does not resolve.
|
|
500
|
+
|
|
501
|
+
## Related
|
|
502
|
+
|
|
503
|
+
[Spinner](/docs/components/spinner)
|
|
504
|
+
|
|
505
|
+
Use for loading with an unknown shape.
|
|
506
|
+
|
|
507
|
+
[Progress](/docs/components/progress)
|
|
508
|
+
|
|
509
|
+
Use for measurable work.
|
|
510
|
+
|
|
511
|
+
[Empty](/docs/components/empty)
|
|
512
|
+
|
|
513
|
+
Use for a region with nothing to show.
|
|
514
|
+
|
|
515
|
+
[Loading](/docs/patterns/loading)
|
|
516
|
+
|
|
517
|
+
Covers choosing a loading indicator.
|