@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,627 @@
|
|
|
1
|
+
# Tabs
|
|
2
|
+
|
|
3
|
+
Switches between related views.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/Tabs.tsx)
|
|
6
|
+
|
|
7
|
+
Figma: [Controls/Tab](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-3285) (`Tabs.Tab`), [Tab](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=1186-3208) (`Tabs.Tab`)
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Tabs render an underlined or pill tab list over a set of panels. Use them for related content, and use links for page navigation.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Basic
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { Tabs } from '@tempoxyz/ds'
|
|
19
|
+
|
|
20
|
+
export function Demo() {
|
|
21
|
+
return (
|
|
22
|
+
<Tabs.Root defaultValue="overview">
|
|
23
|
+
<Tabs.List aria-label="Sections">
|
|
24
|
+
<Tabs.Tab value="overview">Overview</Tabs.Tab>
|
|
25
|
+
<Tabs.Tab value="activity">Activity</Tabs.Tab>
|
|
26
|
+
<Tabs.Tab value="settings">Settings</Tabs.Tab>
|
|
27
|
+
<Tabs.Indicator />
|
|
28
|
+
</Tabs.List>
|
|
29
|
+
<Tabs.Panel value="overview">Overview content</Tabs.Panel>
|
|
30
|
+
<Tabs.Panel value="activity">Activity content</Tabs.Panel>
|
|
31
|
+
<Tabs.Panel value="settings">Settings content</Tabs.Panel>
|
|
32
|
+
</Tabs.Root>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Tabs/Basic.tsx)
|
|
38
|
+
|
|
39
|
+
### Size
|
|
40
|
+
|
|
41
|
+
Set `size` on `Tabs.List` to `small`, `medium` (default), or `large`, for 32px, 40px, or 56px tabs.
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
import { Stack, Tabs } from '@tempoxyz/ds'
|
|
45
|
+
import { Plus } from '@tempoxyz/ds/icons'
|
|
46
|
+
|
|
47
|
+
export function Demo() {
|
|
48
|
+
return (
|
|
49
|
+
<Stack align="start" gap="24">
|
|
50
|
+
{(['small', 'medium', 'large'] as const).map((size) => (
|
|
51
|
+
<Tabs.Root defaultValue="overview" key={size}>
|
|
52
|
+
<Tabs.List aria-label={`Sections ${size}`} size={size}>
|
|
53
|
+
<Tabs.Tab value="overview">Overview</Tabs.Tab>
|
|
54
|
+
<Tabs.Tab value="activity">
|
|
55
|
+
<Plus />
|
|
56
|
+
Activity
|
|
57
|
+
</Tabs.Tab>
|
|
58
|
+
<Tabs.Tab disabled value="settings">
|
|
59
|
+
Settings
|
|
60
|
+
</Tabs.Tab>
|
|
61
|
+
<Tabs.Indicator />
|
|
62
|
+
</Tabs.List>
|
|
63
|
+
<Tabs.Panel value="overview">Overview content</Tabs.Panel>
|
|
64
|
+
<Tabs.Panel value="activity">Activity content</Tabs.Panel>
|
|
65
|
+
</Tabs.Root>
|
|
66
|
+
))}
|
|
67
|
+
</Stack>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Tabs/Size.tsx)
|
|
73
|
+
|
|
74
|
+
### Disabled
|
|
75
|
+
|
|
76
|
+
Set `disabled` on a `Tabs.Tab` to skip it during selection.
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { Tabs } from '@tempoxyz/ds'
|
|
80
|
+
|
|
81
|
+
export function Demo() {
|
|
82
|
+
return (
|
|
83
|
+
<Tabs.Root defaultValue="overview">
|
|
84
|
+
<Tabs.List aria-label="Sections">
|
|
85
|
+
<Tabs.Tab value="overview">Overview</Tabs.Tab>
|
|
86
|
+
<Tabs.Tab value="activity">Activity</Tabs.Tab>
|
|
87
|
+
<Tabs.Tab disabled value="settings">
|
|
88
|
+
Settings
|
|
89
|
+
</Tabs.Tab>
|
|
90
|
+
<Tabs.Indicator />
|
|
91
|
+
</Tabs.List>
|
|
92
|
+
<Tabs.Panel value="overview">Overview content</Tabs.Panel>
|
|
93
|
+
<Tabs.Panel value="activity">Activity content</Tabs.Panel>
|
|
94
|
+
</Tabs.Root>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Tabs/Disabled.tsx)
|
|
100
|
+
|
|
101
|
+
### Expand
|
|
102
|
+
|
|
103
|
+
Set `expand` on `Tabs.List` to stretch the tabs across the available width.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import { Tabs } from '@tempoxyz/ds'
|
|
107
|
+
|
|
108
|
+
export function Demo() {
|
|
109
|
+
return (
|
|
110
|
+
<Tabs.Root defaultValue="activity" style={{ width: '20rem' }}>
|
|
111
|
+
<Tabs.List aria-label="Account" expand>
|
|
112
|
+
<Tabs.Tab value="activity">Activity</Tabs.Tab>
|
|
113
|
+
<Tabs.Tab value="assets">Assets</Tabs.Tab>
|
|
114
|
+
<Tabs.Tab value="keys">Keys</Tabs.Tab>
|
|
115
|
+
<Tabs.Indicator />
|
|
116
|
+
</Tabs.List>
|
|
117
|
+
</Tabs.Root>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Tabs/Expand.tsx)
|
|
123
|
+
|
|
124
|
+
### Pill
|
|
125
|
+
|
|
126
|
+
Set `variant="pill"` on `Tabs.List` for filled tabs. The fill marks the active tab, so a pill list takes no `Tabs.Indicator`. Pill tabs are 32px, 40px, or 48px tall.
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import { Stack, Tabs } from '@tempoxyz/ds'
|
|
130
|
+
|
|
131
|
+
export function Demo() {
|
|
132
|
+
return (
|
|
133
|
+
<Stack align="start" gap="24">
|
|
134
|
+
{(['small', 'medium', 'large'] as const).map((size) => (
|
|
135
|
+
<Tabs.Root defaultValue="all" key={size}>
|
|
136
|
+
<Tabs.List aria-label={`Transfers ${size}`} size={size} variant="pill">
|
|
137
|
+
<Tabs.Tab value="all">All</Tabs.Tab>
|
|
138
|
+
<Tabs.Tab value="payments">Payments</Tabs.Tab>
|
|
139
|
+
<Tabs.Tab value="payouts">Payouts</Tabs.Tab>
|
|
140
|
+
</Tabs.List>
|
|
141
|
+
</Tabs.Root>
|
|
142
|
+
))}
|
|
143
|
+
</Stack>
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Tabs/Pill.tsx)
|
|
149
|
+
|
|
150
|
+
### Appearance
|
|
151
|
+
|
|
152
|
+
Set `appearance` on a pill `Tabs.List` to `base` (default) on the page, `inverse` on an inverse surface, or `overlay` over an image or video.
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
import { Stack, Tabs, variants } from '@tempoxyz/ds'
|
|
156
|
+
|
|
157
|
+
export function Demo() {
|
|
158
|
+
return (
|
|
159
|
+
<Stack gap="16">
|
|
160
|
+
{(['base', 'inverse', 'overlay'] as const).map((appearance) => (
|
|
161
|
+
<div key={appearance} {...styles.surface({ appearance })}>
|
|
162
|
+
<Tabs.Root defaultValue="all">
|
|
163
|
+
<Tabs.List
|
|
164
|
+
appearance={appearance}
|
|
165
|
+
aria-label={`Transfers ${appearance}`}
|
|
166
|
+
variant="pill"
|
|
167
|
+
>
|
|
168
|
+
<Tabs.Tab value="all">All</Tabs.Tab>
|
|
169
|
+
<Tabs.Tab value="payments">Payments</Tabs.Tab>
|
|
170
|
+
<Tabs.Tab value="payouts">Payouts</Tabs.Tab>
|
|
171
|
+
</Tabs.List>
|
|
172
|
+
</Tabs.Root>
|
|
173
|
+
</div>
|
|
174
|
+
))}
|
|
175
|
+
</Stack>
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
namespace styles {
|
|
180
|
+
export const surface = variants({
|
|
181
|
+
base: { borderRadius: 'sm', padding: '16' },
|
|
182
|
+
variants: {
|
|
183
|
+
appearance: {
|
|
184
|
+
base: { backgroundColor: 'background.primary' },
|
|
185
|
+
inverse: { backgroundColor: 'inverse.background.primary' },
|
|
186
|
+
overlay: {
|
|
187
|
+
backgroundImage: 'linear-gradient(135deg, #4471ed, #7e59e4) !custom',
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/Tabs/Appearance.tsx)
|
|
196
|
+
|
|
197
|
+
## Anatomy
|
|
198
|
+
|
|
199
|
+
Import the component and assemble its parts.
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
import { Tabs } from '@tempoxyz/ds'
|
|
203
|
+
|
|
204
|
+
<Tabs.Root>
|
|
205
|
+
<Tabs.List>
|
|
206
|
+
<Tabs.Tab />
|
|
207
|
+
<Tabs.Indicator />
|
|
208
|
+
</Tabs.List>
|
|
209
|
+
<Tabs.Panel />
|
|
210
|
+
</Tabs.Root>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Guidelines
|
|
214
|
+
|
|
215
|
+
### When to Use
|
|
216
|
+
|
|
217
|
+
* Switch between views of one subject at the same level, such as a webhook's Overview, Deliveries, and Settings.
|
|
218
|
+
* Split a dense page into parts used one at a time, such as Balances and Activity on a wallet's home screen.
|
|
219
|
+
|
|
220
|
+
### When Not to Use
|
|
221
|
+
|
|
222
|
+
* Use [ChoiceGroup](choice-group.md) to pick a value that changes the current view, such as a chart's 1D, 1W, or 1M range.
|
|
223
|
+
* Use [SidebarMenu](sidebar-menu.md) or links to move between pages with their own URLs.
|
|
224
|
+
* Use [Stepper](stepper.md) for steps completed in order.
|
|
225
|
+
* Use [Accordion](accordion.md) to open several sections at once, or to compare them.
|
|
226
|
+
|
|
227
|
+
### Keep Tabs Few and Short
|
|
228
|
+
|
|
229
|
+
Use two to five tabs with one-word or two-word labels. Overflowing tabs scroll sideways, and tabs past the edge are easy to miss.
|
|
230
|
+
|
|
231
|
+
* **Never applies:** Hide the tab.
|
|
232
|
+
* **Temporarily unavailable:** Disable the tab, such as Deliveries before a webhook's first event, and state why in the open panel.
|
|
233
|
+
|
|
234
|
+
**Do:** Use a few short, parallel labels.
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
/** Do example for "Keep Tabs Few and Short" on the Tabs page: use a few short, parallel labels. @module */
|
|
238
|
+
import { Tabs } from '@tempoxyz/ds'
|
|
239
|
+
|
|
240
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
241
|
+
export function Demo() {
|
|
242
|
+
return (
|
|
243
|
+
<Tabs.Root defaultValue="overview">
|
|
244
|
+
<Tabs.List aria-label="Webhook">
|
|
245
|
+
<Tabs.Tab value="overview">Overview</Tabs.Tab>
|
|
246
|
+
<Tabs.Tab value="deliveries">Deliveries</Tabs.Tab>
|
|
247
|
+
<Tabs.Tab value="settings">Settings</Tabs.Tab>
|
|
248
|
+
<Tabs.Indicator />
|
|
249
|
+
</Tabs.List>
|
|
250
|
+
</Tabs.Root>
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Don't:** Add so many tabs that the row scrolls.
|
|
256
|
+
|
|
257
|
+
```tsx
|
|
258
|
+
/**
|
|
259
|
+
* Don't example for "Keep Tabs Few and Short" on the Tabs page.
|
|
260
|
+
* Don't add so many tabs that the row scrolls.
|
|
261
|
+
* @module
|
|
262
|
+
*/
|
|
263
|
+
import { style, Tabs } from '@tempoxyz/ds'
|
|
264
|
+
|
|
265
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
266
|
+
export function Demo() {
|
|
267
|
+
return (
|
|
268
|
+
<Tabs.Root defaultValue="overview" {...styles.root()}>
|
|
269
|
+
<Tabs.List aria-label="Webhook">
|
|
270
|
+
<Tabs.Tab value="overview">Endpoint overview</Tabs.Tab>
|
|
271
|
+
<Tabs.Tab value="deliveries">Recent deliveries</Tabs.Tab>
|
|
272
|
+
<Tabs.Tab value="failed">Failed attempts</Tabs.Tab>
|
|
273
|
+
<Tabs.Tab value="secrets">Signing secrets</Tabs.Tab>
|
|
274
|
+
<Tabs.Tab value="settings">Settings</Tabs.Tab>
|
|
275
|
+
<Tabs.Indicator />
|
|
276
|
+
</Tabs.List>
|
|
277
|
+
</Tabs.Root>
|
|
278
|
+
)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
namespace styles {
|
|
282
|
+
export const root = style({ maxWidth: '100% !custom' })
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Place One Indicator in Every Underline List
|
|
287
|
+
|
|
288
|
+
Put a `Tabs.Indicator` after the tabs in each underline `Tabs.List`. It slides a bar under the active tab.
|
|
289
|
+
|
|
290
|
+
**Do:** End every list with a `Tabs.Indicator`.
|
|
291
|
+
|
|
292
|
+
```tsx
|
|
293
|
+
/** Do example for "Keep Tabs Few and Short" on the Tabs page: use a few short, parallel labels. @module */
|
|
294
|
+
import { Tabs } from '@tempoxyz/ds'
|
|
295
|
+
|
|
296
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
297
|
+
export function Demo() {
|
|
298
|
+
return (
|
|
299
|
+
<Tabs.Root defaultValue="overview">
|
|
300
|
+
<Tabs.List aria-label="Webhook">
|
|
301
|
+
<Tabs.Tab value="overview">Overview</Tabs.Tab>
|
|
302
|
+
<Tabs.Tab value="deliveries">Deliveries</Tabs.Tab>
|
|
303
|
+
<Tabs.Tab value="settings">Settings</Tabs.Tab>
|
|
304
|
+
<Tabs.Indicator />
|
|
305
|
+
</Tabs.List>
|
|
306
|
+
</Tabs.Root>
|
|
307
|
+
)
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
**Don't:** Leave out the indicator, so only the label marks the active tab.
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
/**
|
|
315
|
+
* Don't example for "Place One Indicator in Every List" on the Tabs page.
|
|
316
|
+
* Don't leave out the indicator, so only the label marks the active tab.
|
|
317
|
+
* @module
|
|
318
|
+
*/
|
|
319
|
+
import { Tabs } from '@tempoxyz/ds'
|
|
320
|
+
|
|
321
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
322
|
+
export function Demo() {
|
|
323
|
+
return (
|
|
324
|
+
<Tabs.Root defaultValue="overview">
|
|
325
|
+
<Tabs.List aria-label="Webhook">
|
|
326
|
+
<Tabs.Tab value="overview">Overview</Tabs.Tab>
|
|
327
|
+
<Tabs.Tab value="deliveries">Deliveries</Tabs.Tab>
|
|
328
|
+
<Tabs.Tab value="settings">Settings</Tabs.Tab>
|
|
329
|
+
</Tabs.List>
|
|
330
|
+
</Tabs.Root>
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Keep Panels Independent
|
|
336
|
+
|
|
337
|
+
Make each panel complete on its own. A Save button in one panel can't show errors in another, so use a [Stepper](stepper.md) flow or one longer form.
|
|
338
|
+
|
|
339
|
+
**Do:** Keep the fields of one form together.
|
|
340
|
+
|
|
341
|
+
```tsx
|
|
342
|
+
/** Do example for "Keep Panels Independent" on the Tabs page: keep the fields of one form together. @module */
|
|
343
|
+
import { Button, Field, Stack, style, TextInput } from '@tempoxyz/ds'
|
|
344
|
+
|
|
345
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
346
|
+
export function Demo() {
|
|
347
|
+
return (
|
|
348
|
+
<Stack gap="16" {...styles.fill()}>
|
|
349
|
+
<Field.Root>
|
|
350
|
+
<Field.Label>Key name</Field.Label>
|
|
351
|
+
<TextInput.Group>
|
|
352
|
+
<TextInput.Control defaultValue="Checkout server" />
|
|
353
|
+
</TextInput.Group>
|
|
354
|
+
</Field.Root>
|
|
355
|
+
<Field.Root>
|
|
356
|
+
<Field.Label>Daily limit</Field.Label>
|
|
357
|
+
<TextInput.Group>
|
|
358
|
+
<TextInput.Control defaultValue="5,000.00 USDC" />
|
|
359
|
+
</TextInput.Group>
|
|
360
|
+
</Field.Root>
|
|
361
|
+
<div {...styles.actions()}>
|
|
362
|
+
<Button size="small">Save key</Button>
|
|
363
|
+
</div>
|
|
364
|
+
</Stack>
|
|
365
|
+
)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
namespace styles {
|
|
369
|
+
export const actions = style({ columnGap: '8', display: 'flex', justifyContent: 'flex-end' })
|
|
370
|
+
|
|
371
|
+
export const fill = style({ width: '100% !custom' })
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
**Don't:** Split a form across tabs.
|
|
376
|
+
|
|
377
|
+
```tsx
|
|
378
|
+
/** Don't example for "Keep Panels Independent" on the Tabs page. Don't split a form across tabs. @module */
|
|
379
|
+
import { Button, Field, Stack, style, Tabs, TextInput } from '@tempoxyz/ds'
|
|
380
|
+
|
|
381
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
382
|
+
export function Demo() {
|
|
383
|
+
return (
|
|
384
|
+
<Tabs.Root defaultValue="details" {...styles.fill()}>
|
|
385
|
+
<Tabs.List aria-label="Key" size="small">
|
|
386
|
+
<Tabs.Tab value="details">Details</Tabs.Tab>
|
|
387
|
+
<Tabs.Tab value="limits">Limits</Tabs.Tab>
|
|
388
|
+
<Tabs.Indicator />
|
|
389
|
+
</Tabs.List>
|
|
390
|
+
<Tabs.Panel value="details">
|
|
391
|
+
<Stack gap="16" {...styles.panel()}>
|
|
392
|
+
<Field.Root>
|
|
393
|
+
<Field.Label>Key name</Field.Label>
|
|
394
|
+
<TextInput.Group>
|
|
395
|
+
<TextInput.Control defaultValue="Checkout server" />
|
|
396
|
+
</TextInput.Group>
|
|
397
|
+
</Field.Root>
|
|
398
|
+
<div {...styles.actions()}>
|
|
399
|
+
<Button size="small">Save key</Button>
|
|
400
|
+
</div>
|
|
401
|
+
</Stack>
|
|
402
|
+
</Tabs.Panel>
|
|
403
|
+
</Tabs.Root>
|
|
404
|
+
)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
namespace styles {
|
|
408
|
+
export const actions = style({ columnGap: '8', display: 'flex', justifyContent: 'flex-end' })
|
|
409
|
+
|
|
410
|
+
export const fill = style({ width: '100% !custom' })
|
|
411
|
+
|
|
412
|
+
export const panel = style({ marginBlockStart: '16' })
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Keep the Selected Tab on Reload
|
|
417
|
+
|
|
418
|
+
If a tab marks a significant view, store it in the URL. Control `Tabs.Root` with `value` and `onValueChange`.
|
|
419
|
+
|
|
420
|
+
**Do:** Store the tab in the URL, such as `?tab=deliveries`, so a reload or a shared link opens it.
|
|
421
|
+
|
|
422
|
+
```tsx
|
|
423
|
+
/**
|
|
424
|
+
* Do example for "Keep the Selected Tab on Reload" on the Tabs page.
|
|
425
|
+
* Store the tab in the URL, such as `?tab=deliveries`, so a reload or a shared link opens it.
|
|
426
|
+
* @module
|
|
427
|
+
*/
|
|
428
|
+
import { style, Tabs } from '@tempoxyz/ds'
|
|
429
|
+
|
|
430
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
431
|
+
export function Demo() {
|
|
432
|
+
return (
|
|
433
|
+
<div {...styles.page()}>
|
|
434
|
+
<span {...styles.address()}>console.tempo.xyz/webhooks/wh_8f3a?tab=deliveries</span>
|
|
435
|
+
<Tabs.Root defaultValue="deliveries">
|
|
436
|
+
<Tabs.List aria-label="Webhook" size="small">
|
|
437
|
+
<Tabs.Tab value="overview">Overview</Tabs.Tab>
|
|
438
|
+
<Tabs.Tab value="deliveries">Deliveries</Tabs.Tab>
|
|
439
|
+
<Tabs.Tab value="settings">Settings</Tabs.Tab>
|
|
440
|
+
<Tabs.Indicator />
|
|
441
|
+
</Tabs.List>
|
|
442
|
+
</Tabs.Root>
|
|
443
|
+
</div>
|
|
444
|
+
)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
namespace styles {
|
|
448
|
+
export const address = style({
|
|
449
|
+
backgroundColor: 'container.regular',
|
|
450
|
+
borderRadius: 'full',
|
|
451
|
+
color: 'content.secondary',
|
|
452
|
+
cornerShape: 'round',
|
|
453
|
+
paddingBlock: '4',
|
|
454
|
+
paddingInline: '12',
|
|
455
|
+
typography: 'body.b3',
|
|
456
|
+
})
|
|
457
|
+
|
|
458
|
+
export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '16' })
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**Don't:** Reset a reloaded or shared page to the first tab.
|
|
463
|
+
|
|
464
|
+
```tsx
|
|
465
|
+
/**
|
|
466
|
+
* Don't example for "Keep the Selected Tab on Reload" on the Tabs page.
|
|
467
|
+
* Don't reset a reloaded or shared page to the first tab.
|
|
468
|
+
* @module
|
|
469
|
+
*/
|
|
470
|
+
import { style, Tabs } from '@tempoxyz/ds'
|
|
471
|
+
|
|
472
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
473
|
+
export function Demo() {
|
|
474
|
+
return (
|
|
475
|
+
<div {...styles.page()}>
|
|
476
|
+
<span {...styles.address()}>console.tempo.xyz/webhooks/wh_8f3a</span>
|
|
477
|
+
<Tabs.Root defaultValue="overview">
|
|
478
|
+
<Tabs.List aria-label="Webhook" size="small">
|
|
479
|
+
<Tabs.Tab value="overview">Overview</Tabs.Tab>
|
|
480
|
+
<Tabs.Tab value="deliveries">Deliveries</Tabs.Tab>
|
|
481
|
+
<Tabs.Tab value="settings">Settings</Tabs.Tab>
|
|
482
|
+
<Tabs.Indicator />
|
|
483
|
+
</Tabs.List>
|
|
484
|
+
</Tabs.Root>
|
|
485
|
+
</div>
|
|
486
|
+
)
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
namespace styles {
|
|
490
|
+
export const address = style({
|
|
491
|
+
backgroundColor: 'container.regular',
|
|
492
|
+
borderRadius: 'full',
|
|
493
|
+
color: 'content.secondary',
|
|
494
|
+
cornerShape: 'round',
|
|
495
|
+
paddingBlock: '4',
|
|
496
|
+
paddingInline: '12',
|
|
497
|
+
typography: 'body.b3',
|
|
498
|
+
})
|
|
499
|
+
|
|
500
|
+
export const page = style({ display: 'flex', flexDirection: 'column', rowGap: '16' })
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Expand Tabs in Narrow Containers
|
|
505
|
+
|
|
506
|
+
Set `expand` in a narrow container, such as a [Surface](surface.md) or a phone-width column. Leave it off across a wide page, where stretched tabs drift apart.
|
|
507
|
+
|
|
508
|
+
**Do:** Stretch the tabs across a narrow card with `expand`.
|
|
509
|
+
|
|
510
|
+
```tsx
|
|
511
|
+
/**
|
|
512
|
+
* Do example for "Expand Tabs in Narrow Containers" on the Tabs page.
|
|
513
|
+
* Stretch the tabs across a narrow card with `expand`.
|
|
514
|
+
* @module
|
|
515
|
+
*/
|
|
516
|
+
import { style, Surface, Tabs } from '@tempoxyz/ds'
|
|
517
|
+
|
|
518
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
519
|
+
export function Demo() {
|
|
520
|
+
return (
|
|
521
|
+
<Surface size="small" {...styles.card()}>
|
|
522
|
+
<Tabs.Root defaultValue="balances">
|
|
523
|
+
<Tabs.List aria-label="Wallet" expand size="small">
|
|
524
|
+
<Tabs.Tab value="balances">Balances</Tabs.Tab>
|
|
525
|
+
<Tabs.Tab value="activity">Activity</Tabs.Tab>
|
|
526
|
+
<Tabs.Indicator />
|
|
527
|
+
</Tabs.List>
|
|
528
|
+
</Tabs.Root>
|
|
529
|
+
</Surface>
|
|
530
|
+
)
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
namespace styles {
|
|
534
|
+
export const card = style({ width: '16rem !custom' })
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
**Don't:** Leave a gap at the end of the row in a narrow card.
|
|
539
|
+
|
|
540
|
+
```tsx
|
|
541
|
+
/**
|
|
542
|
+
* Don't example for "Expand Tabs in Narrow Containers" on the Tabs page.
|
|
543
|
+
* Don't leave a gap at the end of the row in a narrow card.
|
|
544
|
+
* @module
|
|
545
|
+
*/
|
|
546
|
+
import { style, Surface, Tabs } from '@tempoxyz/ds'
|
|
547
|
+
|
|
548
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
549
|
+
export function Demo() {
|
|
550
|
+
return (
|
|
551
|
+
<Surface size="small" {...styles.card()}>
|
|
552
|
+
<Tabs.Root defaultValue="balances">
|
|
553
|
+
<Tabs.List aria-label="Wallet" size="small">
|
|
554
|
+
<Tabs.Tab value="balances">Balances</Tabs.Tab>
|
|
555
|
+
<Tabs.Tab value="activity">Activity</Tabs.Tab>
|
|
556
|
+
<Tabs.Indicator />
|
|
557
|
+
</Tabs.List>
|
|
558
|
+
</Tabs.Root>
|
|
559
|
+
</Surface>
|
|
560
|
+
)
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
namespace styles {
|
|
564
|
+
export const card = style({ width: '16rem !custom' })
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
## Content
|
|
569
|
+
|
|
570
|
+
* Use nouns that name the panel's content, such as Overview, Activity, or Settings.
|
|
571
|
+
* Keep labels parallel in form and length, such as Send, Receive, and Swap.
|
|
572
|
+
* Add an icon only if every tab in the list has one.
|
|
573
|
+
* Don't repeat the page title in each label, such as Webhook overview and Webhook settings.
|
|
574
|
+
|
|
575
|
+
## Accessibility
|
|
576
|
+
|
|
577
|
+
Tabs follow the [WAI-ARIA tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/), with manual activation by default.
|
|
578
|
+
|
|
579
|
+
### Semantics
|
|
580
|
+
|
|
581
|
+
* **Tabs.List (tablist):** Holds the tabs, and needs its own name.
|
|
582
|
+
* **Tabs.Tab (tab):** A button. The active tab is selected and points at its panel.
|
|
583
|
+
* **Tabs.Panel (tabpanel):** Named by its tab. Hidden panels unmount unless you set `keepMounted`, which find in page requires.
|
|
584
|
+
* **Disabled Tabs (aria-disabled):** Reachable with the arrow keys, but can't be activated or shown first.
|
|
585
|
+
* **Tabs.Indicator:** Decorative, and ignores pointer events. Under reduced motion, it moves without sliding.
|
|
586
|
+
|
|
587
|
+
### Keyboard
|
|
588
|
+
|
|
589
|
+
* **Move into the List (Tab):** Moves focus to the active tab, then to the open panel.
|
|
590
|
+
* **Move to the Next Tab (Right Arrow):** Moves focus to the next tab, and wraps at the end.
|
|
591
|
+
* **Move to the Previous Tab (Left Arrow):** Moves focus to the previous tab, and wraps at the start.
|
|
592
|
+
* **Move to the First Tab (Home):** Moves focus to the first tab.
|
|
593
|
+
* **Move to the Last Tab (End):** Moves focus to the last tab.
|
|
594
|
+
* **Activate the Tab (Enter or Space):** Activates the focused tab and shows its panel.
|
|
595
|
+
|
|
596
|
+
Set `activateOnFocus` on `Tabs.List` to activate a tab on focus. Use it only if panels render without delay.
|
|
597
|
+
|
|
598
|
+
### Focus
|
|
599
|
+
|
|
600
|
+
* **One Tab Stop:** Only the active tab is in the Tab order. Arrow keys move between tabs.
|
|
601
|
+
* **Focusable Panel:** The open panel is focusable, so Tab moves into it even if it holds no controls.
|
|
602
|
+
|
|
603
|
+
### Your Responsibilities
|
|
604
|
+
|
|
605
|
+
* **Name the List (SC 4.1.2):** Name the tab list, such as "Sections".
|
|
606
|
+
|
|
607
|
+
## Related
|
|
608
|
+
|
|
609
|
+
[ChoiceGroup](choice-group.md)
|
|
610
|
+
|
|
611
|
+
Use for one value that changes a view.
|
|
612
|
+
|
|
613
|
+
[SidebarMenu](sidebar-menu.md)
|
|
614
|
+
|
|
615
|
+
Use for navigating between pages.
|
|
616
|
+
|
|
617
|
+
[Accordion](accordion.md)
|
|
618
|
+
|
|
619
|
+
Use for sections you open together.
|
|
620
|
+
|
|
621
|
+
[Snippet](snippet.md)
|
|
622
|
+
|
|
623
|
+
Use for a command with a tab per tool.
|
|
624
|
+
|
|
625
|
+
[Navigation](../patterns/navigation.md)
|
|
626
|
+
|
|
627
|
+
Covers choosing between navigation components.
|