@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,922 @@
|
|
|
1
|
+
# SidebarMenu
|
|
2
|
+
|
|
3
|
+
Vertical navigation for sidebars and drawers.
|
|
4
|
+
|
|
5
|
+
[View source and API](https://github.com/tempoxyz/ds/blob/main/src/web/components/SidebarMenu.tsx)
|
|
6
|
+
|
|
7
|
+
Figma: [Buttons/Floating Action Button](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5265-2305) (`SidebarMenu.Item`), [Navigation/Account Row](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-3036) (`SidebarMenu.AccountRow`), [Navigation/Nav Item](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-2694) (`SidebarMenu.Item`), [Navigation/Sidebar Promo](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5629-2524) (`SidebarMenu.Promo`), [Navigation/Tab Bar Item](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5265-2279) (`SidebarMenu.Item`), [Navigation/Wallet Sidebar](https://www.figma.com/design/yE96kcymnNR88PJp6G1sPs?node-id=5227-2727) (`SidebarMenu.Root`)
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
SidebarMenu renders vertical navigation of icon and label rows, for sidebars and drawers. Items are links, not menu items.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### Basic
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
19
|
+
import { Key, Settings, Users } from '@tempoxyz/ds/icons'
|
|
20
|
+
|
|
21
|
+
export function Demo() {
|
|
22
|
+
return (
|
|
23
|
+
<SidebarMenu.Root aria-label="Console" {...styles.column()}>
|
|
24
|
+
<SidebarMenu.Group>
|
|
25
|
+
<SidebarMenu.GroupLabel>Project</SidebarMenu.GroupLabel>
|
|
26
|
+
<SidebarMenu.Item href="#">
|
|
27
|
+
<Key />
|
|
28
|
+
API Keys
|
|
29
|
+
</SidebarMenu.Item>
|
|
30
|
+
</SidebarMenu.Group>
|
|
31
|
+
<SidebarMenu.Group>
|
|
32
|
+
<SidebarMenu.GroupLabel>Organization</SidebarMenu.GroupLabel>
|
|
33
|
+
<SidebarMenu.Item active href="#">
|
|
34
|
+
<Users />
|
|
35
|
+
Team
|
|
36
|
+
</SidebarMenu.Item>
|
|
37
|
+
<SidebarMenu.Item render={<button type="button" />}>
|
|
38
|
+
<Settings />
|
|
39
|
+
Settings
|
|
40
|
+
</SidebarMenu.Item>
|
|
41
|
+
</SidebarMenu.Group>
|
|
42
|
+
</SidebarMenu.Root>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
namespace styles {
|
|
47
|
+
export const column = style({ width: '15rem !custom' })
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/SidebarMenu/Basic.tsx)
|
|
52
|
+
|
|
53
|
+
### Size
|
|
54
|
+
|
|
55
|
+
Set `size` on `SidebarMenu.Root` to `small`, `medium` (default), or `large`.
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
59
|
+
import { Coins, CreditCard, Home, ShieldCheck, Trend } from '@tempoxyz/ds/icons'
|
|
60
|
+
|
|
61
|
+
export function Demo() {
|
|
62
|
+
return (
|
|
63
|
+
<div {...styles.row()}>
|
|
64
|
+
{(['small', 'medium', 'large'] as const).map((size) => (
|
|
65
|
+
<SidebarMenu.Root aria-label={`Wallet ${size}`} key={size} size={size} {...styles.column()}>
|
|
66
|
+
<SidebarMenu.Item active href="#">
|
|
67
|
+
<Home />
|
|
68
|
+
Home
|
|
69
|
+
</SidebarMenu.Item>
|
|
70
|
+
<SidebarMenu.Item href="#">
|
|
71
|
+
<Coins />
|
|
72
|
+
Balances
|
|
73
|
+
</SidebarMenu.Item>
|
|
74
|
+
<SidebarMenu.Item href="#">
|
|
75
|
+
<Trend />
|
|
76
|
+
Activity
|
|
77
|
+
</SidebarMenu.Item>
|
|
78
|
+
<SidebarMenu.Item href="#">
|
|
79
|
+
<CreditCard />
|
|
80
|
+
Credits
|
|
81
|
+
</SidebarMenu.Item>
|
|
82
|
+
<SidebarMenu.Item href="#">
|
|
83
|
+
<ShieldCheck />
|
|
84
|
+
Authorized Apps
|
|
85
|
+
</SidebarMenu.Item>
|
|
86
|
+
</SidebarMenu.Root>
|
|
87
|
+
))}
|
|
88
|
+
</div>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
namespace styles {
|
|
93
|
+
export const column = style({ width: '15rem !custom' })
|
|
94
|
+
|
|
95
|
+
export const row = style({ display: 'flex', flexWrap: 'wrap', gap: '32' })
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/SidebarMenu/Size.tsx)
|
|
100
|
+
|
|
101
|
+
### Submenu
|
|
102
|
+
|
|
103
|
+
Nest items in a `SidebarMenu.Submenu`. Set `defaultOpen` to expand it on first render.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
107
|
+
import {
|
|
108
|
+
Bank,
|
|
109
|
+
Bell,
|
|
110
|
+
ChartBar,
|
|
111
|
+
Document,
|
|
112
|
+
GasFee,
|
|
113
|
+
Globe,
|
|
114
|
+
Grid,
|
|
115
|
+
Key,
|
|
116
|
+
Link,
|
|
117
|
+
Lock,
|
|
118
|
+
Mail,
|
|
119
|
+
Receipt,
|
|
120
|
+
Users,
|
|
121
|
+
Wallet,
|
|
122
|
+
} from '@tempoxyz/ds/icons'
|
|
123
|
+
|
|
124
|
+
export function Demo() {
|
|
125
|
+
return (
|
|
126
|
+
<SidebarMenu.Root aria-label="Dashboard" size="small" {...styles.column()}>
|
|
127
|
+
<SidebarMenu.Item active href="#">
|
|
128
|
+
<Grid />
|
|
129
|
+
Overview
|
|
130
|
+
</SidebarMenu.Item>
|
|
131
|
+
<SidebarMenu.Item href="#">
|
|
132
|
+
<ChartBar />
|
|
133
|
+
Analytics
|
|
134
|
+
</SidebarMenu.Item>
|
|
135
|
+
<SidebarMenu.Submenu defaultOpen>
|
|
136
|
+
<SidebarMenu.SubmenuTrigger>
|
|
137
|
+
<Receipt />
|
|
138
|
+
Transactions
|
|
139
|
+
</SidebarMenu.SubmenuTrigger>
|
|
140
|
+
<SidebarMenu.SubmenuPanel>
|
|
141
|
+
<SidebarMenu.Item href="#">Incoming</SidebarMenu.Item>
|
|
142
|
+
<SidebarMenu.Item href="#">Outgoing</SidebarMenu.Item>
|
|
143
|
+
<SidebarMenu.Item href="#">Refunds</SidebarMenu.Item>
|
|
144
|
+
</SidebarMenu.SubmenuPanel>
|
|
145
|
+
</SidebarMenu.Submenu>
|
|
146
|
+
<SidebarMenu.Group>
|
|
147
|
+
<SidebarMenu.GroupLabel>Payments</SidebarMenu.GroupLabel>
|
|
148
|
+
<SidebarMenu.Item href="#">
|
|
149
|
+
<Wallet />
|
|
150
|
+
Wallets
|
|
151
|
+
</SidebarMenu.Item>
|
|
152
|
+
<SidebarMenu.Item href="#">
|
|
153
|
+
<Bank />
|
|
154
|
+
Payouts
|
|
155
|
+
</SidebarMenu.Item>
|
|
156
|
+
<SidebarMenu.Item href="#">
|
|
157
|
+
<GasFee />
|
|
158
|
+
Fee payer
|
|
159
|
+
</SidebarMenu.Item>
|
|
160
|
+
<SidebarMenu.Item href="#">
|
|
161
|
+
<Link />
|
|
162
|
+
Payment links
|
|
163
|
+
</SidebarMenu.Item>
|
|
164
|
+
</SidebarMenu.Group>
|
|
165
|
+
<SidebarMenu.Group>
|
|
166
|
+
<SidebarMenu.GroupLabel>Developers</SidebarMenu.GroupLabel>
|
|
167
|
+
<SidebarMenu.Item href="#">
|
|
168
|
+
<Key />
|
|
169
|
+
API keys
|
|
170
|
+
</SidebarMenu.Item>
|
|
171
|
+
<SidebarMenu.Item href="#">
|
|
172
|
+
<Globe />
|
|
173
|
+
Webhooks
|
|
174
|
+
</SidebarMenu.Item>
|
|
175
|
+
<SidebarMenu.Item href="#">
|
|
176
|
+
<Document />
|
|
177
|
+
Docs
|
|
178
|
+
</SidebarMenu.Item>
|
|
179
|
+
</SidebarMenu.Group>
|
|
180
|
+
<SidebarMenu.Group>
|
|
181
|
+
<SidebarMenu.GroupLabel>Settings</SidebarMenu.GroupLabel>
|
|
182
|
+
<SidebarMenu.Item href="#">
|
|
183
|
+
<Users />
|
|
184
|
+
Team
|
|
185
|
+
</SidebarMenu.Item>
|
|
186
|
+
<SidebarMenu.Item href="#">
|
|
187
|
+
<Lock />
|
|
188
|
+
Security
|
|
189
|
+
</SidebarMenu.Item>
|
|
190
|
+
<SidebarMenu.Item href="#">
|
|
191
|
+
<Bell />
|
|
192
|
+
Notifications
|
|
193
|
+
</SidebarMenu.Item>
|
|
194
|
+
<SidebarMenu.Item href="#">
|
|
195
|
+
<Mail />
|
|
196
|
+
Emails
|
|
197
|
+
</SidebarMenu.Item>
|
|
198
|
+
</SidebarMenu.Group>
|
|
199
|
+
</SidebarMenu.Root>
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
namespace styles {
|
|
204
|
+
export const column = style({ width: '15rem !custom' })
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/SidebarMenu/Submenu.tsx)
|
|
209
|
+
|
|
210
|
+
### Account Row
|
|
211
|
+
|
|
212
|
+
Render a `SidebarMenu.AccountRow` in a `SidebarMenu.Account`, which draws the divider above it at the bottom of the sidebar. Pass the row to `Menu.Trigger` through `render` to open the account menu. The row ends in a chevron only while it opens a menu.
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
/** Shows the account row at the bottom of a sidebar, under its divider, opening the account menu. @module */
|
|
216
|
+
import { Avatar, Menu, SidebarMenu, style } from '@tempoxyz/ds'
|
|
217
|
+
import { Copy, Help, LogOut, User } from '@tempoxyz/ds/icons'
|
|
218
|
+
|
|
219
|
+
/** Renders the help link, then the account row as the trigger of the account menu. */
|
|
220
|
+
export function Demo() {
|
|
221
|
+
return (
|
|
222
|
+
<div {...styles.column()}>
|
|
223
|
+
<SidebarMenu.Root aria-label="Support">
|
|
224
|
+
<SidebarMenu.Item href="#">
|
|
225
|
+
<Help />
|
|
226
|
+
Help
|
|
227
|
+
</SidebarMenu.Item>
|
|
228
|
+
</SidebarMenu.Root>
|
|
229
|
+
<SidebarMenu.Account>
|
|
230
|
+
<Menu.Root>
|
|
231
|
+
<Menu.Trigger
|
|
232
|
+
render={<SidebarMenu.AccountRow description="piril@tempo.xyz" label="Piril Akay" />}
|
|
233
|
+
>
|
|
234
|
+
<Avatar size="32">
|
|
235
|
+
<Avatar.Fallback>PA</Avatar.Fallback>
|
|
236
|
+
</Avatar>
|
|
237
|
+
</Menu.Trigger>
|
|
238
|
+
<Menu.Popup side="top">
|
|
239
|
+
<Menu.Item>
|
|
240
|
+
<User />
|
|
241
|
+
Account details
|
|
242
|
+
</Menu.Item>
|
|
243
|
+
<Menu.Item>
|
|
244
|
+
<Copy />
|
|
245
|
+
Copy address
|
|
246
|
+
</Menu.Item>
|
|
247
|
+
<Menu.Separator />
|
|
248
|
+
<Menu.Item intent="negative">
|
|
249
|
+
<LogOut />
|
|
250
|
+
Sign out
|
|
251
|
+
</Menu.Item>
|
|
252
|
+
</Menu.Popup>
|
|
253
|
+
</Menu.Root>
|
|
254
|
+
</SidebarMenu.Account>
|
|
255
|
+
</div>
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
namespace styles {
|
|
260
|
+
export const column = style({
|
|
261
|
+
display: 'flex',
|
|
262
|
+
flexDirection: 'column',
|
|
263
|
+
rowGap: '8',
|
|
264
|
+
width: '15rem !custom',
|
|
265
|
+
})
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/SidebarMenu/AccountRow.tsx)
|
|
270
|
+
|
|
271
|
+
### Logo
|
|
272
|
+
|
|
273
|
+
Pass a `SidebarMenu.Logo` to an account row that names a product or wallet, such as the wallet switcher at the top of the sidebar.
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
/** Shows the wallet switcher at the top of a sidebar, with the Tempo mark in a logo tile. @module */
|
|
277
|
+
import { Menu, SidebarMenu, style, TempoLogo } from '@tempoxyz/ds'
|
|
278
|
+
import { Plus, Wallet } from '@tempoxyz/ds/icons'
|
|
279
|
+
|
|
280
|
+
/** Renders the wallet row, with the logo tile as its media, as the trigger of the wallet menu. */
|
|
281
|
+
export function Demo() {
|
|
282
|
+
return (
|
|
283
|
+
<div {...styles.column()}>
|
|
284
|
+
<Menu.Root>
|
|
285
|
+
<Menu.Trigger
|
|
286
|
+
render={<SidebarMenu.AccountRow description="0xc721…s9dk" label="Tempo Wallet" />}
|
|
287
|
+
>
|
|
288
|
+
<SidebarMenu.Logo>
|
|
289
|
+
<TempoLogo type="mark" />
|
|
290
|
+
</SidebarMenu.Logo>
|
|
291
|
+
</Menu.Trigger>
|
|
292
|
+
<Menu.Popup>
|
|
293
|
+
<Menu.Item>
|
|
294
|
+
<Wallet />
|
|
295
|
+
Savings
|
|
296
|
+
</Menu.Item>
|
|
297
|
+
<Menu.Separator />
|
|
298
|
+
<Menu.Item>
|
|
299
|
+
<Plus />
|
|
300
|
+
New wallet
|
|
301
|
+
</Menu.Item>
|
|
302
|
+
</Menu.Popup>
|
|
303
|
+
</Menu.Root>
|
|
304
|
+
</div>
|
|
305
|
+
)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
namespace styles {
|
|
309
|
+
export const column = style({ width: '15rem !custom' })
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
[View example source](https://github.com/tempoxyz/ds/blob/main/docs/src/examples/demos/SidebarMenu/Logo.tsx)
|
|
314
|
+
|
|
315
|
+
## Anatomy
|
|
316
|
+
|
|
317
|
+
Import the component and assemble its parts.
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
import { SidebarMenu } from '@tempoxyz/ds'
|
|
321
|
+
|
|
322
|
+
<SidebarMenu.Root>
|
|
323
|
+
<SidebarMenu.Group>
|
|
324
|
+
<SidebarMenu.GroupLabel />
|
|
325
|
+
<SidebarMenu.Item />
|
|
326
|
+
<SidebarMenu.Submenu>
|
|
327
|
+
<SidebarMenu.SubmenuTrigger />
|
|
328
|
+
<SidebarMenu.SubmenuPanel>
|
|
329
|
+
<SidebarMenu.Item />
|
|
330
|
+
</SidebarMenu.SubmenuPanel>
|
|
331
|
+
</SidebarMenu.Submenu>
|
|
332
|
+
</SidebarMenu.Group>
|
|
333
|
+
</SidebarMenu.Root>
|
|
334
|
+
<SidebarMenu.AccountRow>
|
|
335
|
+
<SidebarMenu.Logo />
|
|
336
|
+
</SidebarMenu.AccountRow>
|
|
337
|
+
<SidebarMenu.Account>
|
|
338
|
+
<SidebarMenu.AccountRow />
|
|
339
|
+
</SidebarMenu.Account>
|
|
340
|
+
<SidebarMenu.Mark />
|
|
341
|
+
<SidebarMenu.Promo />
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
## Guidelines
|
|
345
|
+
|
|
346
|
+
### When to Use
|
|
347
|
+
|
|
348
|
+
* Navigate a product with five or more destinations, such as Home, API keys, Webhooks, Team, and Settings.
|
|
349
|
+
* Navigate inside `AppShell.Sidebar` ([AppShell](app-shell.md)), which moves the menu into a drawer below 1024px.
|
|
350
|
+
|
|
351
|
+
### When Not to Use
|
|
352
|
+
|
|
353
|
+
* Use [Menu](menu.md) for a list of actions, such as Rename key or Revoke key.
|
|
354
|
+
* Use [Tabs](tabs.md) to switch views inside one page.
|
|
355
|
+
* Use [Breadcrumbs](breadcrumbs.md) to show where a deeply nested page sits.
|
|
356
|
+
* Use [ListGroup](list-group.md) for a settings page that lists its subpages in the content.
|
|
357
|
+
|
|
358
|
+
### Group Related Destinations
|
|
359
|
+
|
|
360
|
+
Wrap related items in a `SidebarMenu.Group` with a `SidebarMenu.GroupLabel`, such as Payments or Developers. Adjacent groups render with space between them.
|
|
361
|
+
|
|
362
|
+
If the first group holds the main pages, such as Home, it can skip its label. Give it an `aria-label` instead.
|
|
363
|
+
|
|
364
|
+
**Do:** Group items under short labels.
|
|
365
|
+
|
|
366
|
+
```tsx
|
|
367
|
+
/** Do example for "Group Related Destinations" on the SidebarMenu page: group items under short labels. @module */
|
|
368
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
369
|
+
import { Bank, Globe, Grid, Key, Wallet } from '@tempoxyz/ds/icons'
|
|
370
|
+
|
|
371
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
372
|
+
export function Demo() {
|
|
373
|
+
return (
|
|
374
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.column()}>
|
|
375
|
+
<SidebarMenu.Group aria-label="Project">
|
|
376
|
+
<SidebarMenu.Item active href="#">
|
|
377
|
+
<Grid />
|
|
378
|
+
Home
|
|
379
|
+
</SidebarMenu.Item>
|
|
380
|
+
</SidebarMenu.Group>
|
|
381
|
+
<SidebarMenu.Group>
|
|
382
|
+
<SidebarMenu.GroupLabel>Payments</SidebarMenu.GroupLabel>
|
|
383
|
+
<SidebarMenu.Item href="#">
|
|
384
|
+
<Wallet />
|
|
385
|
+
Wallets
|
|
386
|
+
</SidebarMenu.Item>
|
|
387
|
+
<SidebarMenu.Item href="#">
|
|
388
|
+
<Bank />
|
|
389
|
+
Payouts
|
|
390
|
+
</SidebarMenu.Item>
|
|
391
|
+
</SidebarMenu.Group>
|
|
392
|
+
<SidebarMenu.Group>
|
|
393
|
+
<SidebarMenu.GroupLabel>Developers</SidebarMenu.GroupLabel>
|
|
394
|
+
<SidebarMenu.Item href="#">
|
|
395
|
+
<Key />
|
|
396
|
+
API keys
|
|
397
|
+
</SidebarMenu.Item>
|
|
398
|
+
<SidebarMenu.Item href="#">
|
|
399
|
+
<Globe />
|
|
400
|
+
Webhooks
|
|
401
|
+
</SidebarMenu.Item>
|
|
402
|
+
</SidebarMenu.Group>
|
|
403
|
+
</SidebarMenu.Root>
|
|
404
|
+
)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
namespace styles {
|
|
408
|
+
export const column = style({ width: '15rem !custom' })
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
**Don't:** List unrelated destinations in one flat column.
|
|
413
|
+
|
|
414
|
+
```tsx
|
|
415
|
+
/**
|
|
416
|
+
* Don't example for "Group Related Destinations" on the SidebarMenu page.
|
|
417
|
+
* Don't list unrelated destinations in one flat column.
|
|
418
|
+
* @module
|
|
419
|
+
*/
|
|
420
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
421
|
+
import { Bank, Bell, Globe, Grid, Key, Lock, Users, Wallet } from '@tempoxyz/ds/icons'
|
|
422
|
+
|
|
423
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
424
|
+
export function Demo() {
|
|
425
|
+
return (
|
|
426
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.column()}>
|
|
427
|
+
<SidebarMenu.Item active href="#">
|
|
428
|
+
<Grid />
|
|
429
|
+
Home
|
|
430
|
+
</SidebarMenu.Item>
|
|
431
|
+
<SidebarMenu.Item href="#">
|
|
432
|
+
<Wallet />
|
|
433
|
+
Wallets
|
|
434
|
+
</SidebarMenu.Item>
|
|
435
|
+
<SidebarMenu.Item href="#">
|
|
436
|
+
<Key />
|
|
437
|
+
API keys
|
|
438
|
+
</SidebarMenu.Item>
|
|
439
|
+
<SidebarMenu.Item href="#">
|
|
440
|
+
<Users />
|
|
441
|
+
Team
|
|
442
|
+
</SidebarMenu.Item>
|
|
443
|
+
<SidebarMenu.Item href="#">
|
|
444
|
+
<Bank />
|
|
445
|
+
Payouts
|
|
446
|
+
</SidebarMenu.Item>
|
|
447
|
+
<SidebarMenu.Item href="#">
|
|
448
|
+
<Bell />
|
|
449
|
+
Notifications
|
|
450
|
+
</SidebarMenu.Item>
|
|
451
|
+
<SidebarMenu.Item href="#">
|
|
452
|
+
<Globe />
|
|
453
|
+
Webhooks
|
|
454
|
+
</SidebarMenu.Item>
|
|
455
|
+
<SidebarMenu.Item href="#">
|
|
456
|
+
<Lock />
|
|
457
|
+
Security
|
|
458
|
+
</SidebarMenu.Item>
|
|
459
|
+
</SidebarMenu.Root>
|
|
460
|
+
)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
namespace styles {
|
|
464
|
+
export const column = style({ width: '15rem !custom' })
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### Keep Item Counts Low
|
|
469
|
+
|
|
470
|
+
* **Per group:** Three to seven items, in at most four or five groups.
|
|
471
|
+
* **Single items:** Avoid groups of one, except an unlabelled first group.
|
|
472
|
+
* **Long menus:** If a menu has 15 or more items, set `size="small"` for 32px rows and 16px icons.
|
|
473
|
+
* **Overflow:** Move rare pages onto a hub page built from [ListGroup](list-group.md), such as Settings.
|
|
474
|
+
|
|
475
|
+
**Do:** Put several related items in each group.
|
|
476
|
+
|
|
477
|
+
```tsx
|
|
478
|
+
/**
|
|
479
|
+
* Do example for "Keep Item Counts Low" on the SidebarMenu page.
|
|
480
|
+
* Put several related items in each group.
|
|
481
|
+
* @module
|
|
482
|
+
*/
|
|
483
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
484
|
+
import { Bank, Globe, Key, Wallet } from '@tempoxyz/ds/icons'
|
|
485
|
+
|
|
486
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
487
|
+
export function Demo() {
|
|
488
|
+
return (
|
|
489
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.column()}>
|
|
490
|
+
<SidebarMenu.Group>
|
|
491
|
+
<SidebarMenu.GroupLabel>Payments</SidebarMenu.GroupLabel>
|
|
492
|
+
<SidebarMenu.Item href="#">
|
|
493
|
+
<Wallet />
|
|
494
|
+
Wallets
|
|
495
|
+
</SidebarMenu.Item>
|
|
496
|
+
<SidebarMenu.Item href="#">
|
|
497
|
+
<Bank />
|
|
498
|
+
Payouts
|
|
499
|
+
</SidebarMenu.Item>
|
|
500
|
+
</SidebarMenu.Group>
|
|
501
|
+
<SidebarMenu.Group>
|
|
502
|
+
<SidebarMenu.GroupLabel>Developers</SidebarMenu.GroupLabel>
|
|
503
|
+
<SidebarMenu.Item href="#">
|
|
504
|
+
<Key />
|
|
505
|
+
API keys
|
|
506
|
+
</SidebarMenu.Item>
|
|
507
|
+
<SidebarMenu.Item href="#">
|
|
508
|
+
<Globe />
|
|
509
|
+
Webhooks
|
|
510
|
+
</SidebarMenu.Item>
|
|
511
|
+
</SidebarMenu.Group>
|
|
512
|
+
</SidebarMenu.Root>
|
|
513
|
+
)
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
namespace styles {
|
|
517
|
+
export const column = style({ width: '15rem !custom' })
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
**Don't:** Give each item a group of its own.
|
|
522
|
+
|
|
523
|
+
```tsx
|
|
524
|
+
/**
|
|
525
|
+
* Don't example for "Keep Item Counts Low" on the SidebarMenu page.
|
|
526
|
+
* Don't give each item a group of its own.
|
|
527
|
+
* @module
|
|
528
|
+
*/
|
|
529
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
530
|
+
import { Bank, Globe, Key, Wallet } from '@tempoxyz/ds/icons'
|
|
531
|
+
|
|
532
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
533
|
+
export function Demo() {
|
|
534
|
+
return (
|
|
535
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.column()}>
|
|
536
|
+
<SidebarMenu.Group>
|
|
537
|
+
<SidebarMenu.GroupLabel>Treasury</SidebarMenu.GroupLabel>
|
|
538
|
+
<SidebarMenu.Item href="#">
|
|
539
|
+
<Wallet />
|
|
540
|
+
Wallets
|
|
541
|
+
</SidebarMenu.Item>
|
|
542
|
+
</SidebarMenu.Group>
|
|
543
|
+
<SidebarMenu.Group>
|
|
544
|
+
<SidebarMenu.GroupLabel>Payments</SidebarMenu.GroupLabel>
|
|
545
|
+
<SidebarMenu.Item href="#">
|
|
546
|
+
<Bank />
|
|
547
|
+
Payouts
|
|
548
|
+
</SidebarMenu.Item>
|
|
549
|
+
</SidebarMenu.Group>
|
|
550
|
+
<SidebarMenu.Group>
|
|
551
|
+
<SidebarMenu.GroupLabel>Access</SidebarMenu.GroupLabel>
|
|
552
|
+
<SidebarMenu.Item href="#">
|
|
553
|
+
<Key />
|
|
554
|
+
API keys
|
|
555
|
+
</SidebarMenu.Item>
|
|
556
|
+
</SidebarMenu.Group>
|
|
557
|
+
<SidebarMenu.Group>
|
|
558
|
+
<SidebarMenu.GroupLabel>Integrations</SidebarMenu.GroupLabel>
|
|
559
|
+
<SidebarMenu.Item href="#">
|
|
560
|
+
<Globe />
|
|
561
|
+
Webhooks
|
|
562
|
+
</SidebarMenu.Item>
|
|
563
|
+
</SidebarMenu.Group>
|
|
564
|
+
</SidebarMenu.Root>
|
|
565
|
+
)
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
namespace styles {
|
|
569
|
+
export const column = style({ width: '15rem !custom' })
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
### Nest One Level at Most
|
|
574
|
+
|
|
575
|
+
A `SidebarMenu.Submenu` collapses related pages under a trigger. Open the submenu that holds the current page with `defaultOpen` or a controlled `open`. The trigger only expands and collapses, so give its pages their own items.
|
|
576
|
+
|
|
577
|
+
**Do:** Nest one level, such as Incoming and Outgoing under Transactions, without icons.
|
|
578
|
+
|
|
579
|
+
```tsx
|
|
580
|
+
/**
|
|
581
|
+
* Do example for "Nest One Level at Most" on the SidebarMenu page.
|
|
582
|
+
* Nest one level, such as Incoming and Outgoing under Transactions, without icons.
|
|
583
|
+
* @module
|
|
584
|
+
*/
|
|
585
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
586
|
+
import { Grid, Receipt } from '@tempoxyz/ds/icons'
|
|
587
|
+
|
|
588
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
589
|
+
export function Demo() {
|
|
590
|
+
return (
|
|
591
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.column()}>
|
|
592
|
+
<SidebarMenu.Item href="#">
|
|
593
|
+
<Grid />
|
|
594
|
+
Home
|
|
595
|
+
</SidebarMenu.Item>
|
|
596
|
+
<SidebarMenu.Submenu defaultOpen>
|
|
597
|
+
<SidebarMenu.SubmenuTrigger>
|
|
598
|
+
<Receipt />
|
|
599
|
+
Transactions
|
|
600
|
+
</SidebarMenu.SubmenuTrigger>
|
|
601
|
+
<SidebarMenu.SubmenuPanel>
|
|
602
|
+
<SidebarMenu.Item active href="#">
|
|
603
|
+
Incoming
|
|
604
|
+
</SidebarMenu.Item>
|
|
605
|
+
<SidebarMenu.Item href="#">Outgoing</SidebarMenu.Item>
|
|
606
|
+
</SidebarMenu.SubmenuPanel>
|
|
607
|
+
</SidebarMenu.Submenu>
|
|
608
|
+
</SidebarMenu.Root>
|
|
609
|
+
)
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
namespace styles {
|
|
613
|
+
export const column = style({ width: '15rem !custom' })
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
**Don't:** Nest a submenu inside another submenu.
|
|
618
|
+
|
|
619
|
+
```tsx
|
|
620
|
+
/**
|
|
621
|
+
* Don't example for "Nest One Level at Most" on the SidebarMenu page.
|
|
622
|
+
* Don't nest a submenu inside another submenu.
|
|
623
|
+
* @module
|
|
624
|
+
*/
|
|
625
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
626
|
+
import { Grid, Receipt } from '@tempoxyz/ds/icons'
|
|
627
|
+
|
|
628
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
629
|
+
export function Demo() {
|
|
630
|
+
return (
|
|
631
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.column()}>
|
|
632
|
+
<SidebarMenu.Item href="#">
|
|
633
|
+
<Grid />
|
|
634
|
+
Home
|
|
635
|
+
</SidebarMenu.Item>
|
|
636
|
+
<SidebarMenu.Submenu defaultOpen>
|
|
637
|
+
<SidebarMenu.SubmenuTrigger>
|
|
638
|
+
<Receipt />
|
|
639
|
+
Transactions
|
|
640
|
+
</SidebarMenu.SubmenuTrigger>
|
|
641
|
+
<SidebarMenu.SubmenuPanel>
|
|
642
|
+
<SidebarMenu.Submenu defaultOpen>
|
|
643
|
+
<SidebarMenu.SubmenuTrigger>Incoming</SidebarMenu.SubmenuTrigger>
|
|
644
|
+
<SidebarMenu.SubmenuPanel>
|
|
645
|
+
<SidebarMenu.Item active href="#">
|
|
646
|
+
Pending
|
|
647
|
+
</SidebarMenu.Item>
|
|
648
|
+
<SidebarMenu.Item href="#">Settled</SidebarMenu.Item>
|
|
649
|
+
</SidebarMenu.SubmenuPanel>
|
|
650
|
+
</SidebarMenu.Submenu>
|
|
651
|
+
<SidebarMenu.Item href="#">Outgoing</SidebarMenu.Item>
|
|
652
|
+
</SidebarMenu.SubmenuPanel>
|
|
653
|
+
</SidebarMenu.Submenu>
|
|
654
|
+
</SidebarMenu.Root>
|
|
655
|
+
)
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
namespace styles {
|
|
659
|
+
export const column = style({ width: '15rem !custom' })
|
|
660
|
+
}
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
### Keep Labels on One Line
|
|
664
|
+
|
|
665
|
+
Items do not wrap. Give every top-level item an icon, or none of them. Mark a link that leaves the product, such as API docs, with a trailing `ExternalLink` icon.
|
|
666
|
+
|
|
667
|
+
**Do:** Shorten each label to the page's name.
|
|
668
|
+
|
|
669
|
+
```tsx
|
|
670
|
+
/**
|
|
671
|
+
* Do example for "Keep Labels on One Line" on the SidebarMenu page.
|
|
672
|
+
* Shorten each label to the page's name.
|
|
673
|
+
* @module
|
|
674
|
+
*/
|
|
675
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
676
|
+
import { Globe, Grid, Key } from '@tempoxyz/ds/icons'
|
|
677
|
+
|
|
678
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
679
|
+
export function Demo() {
|
|
680
|
+
return (
|
|
681
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.column()}>
|
|
682
|
+
<SidebarMenu.Item href="#">
|
|
683
|
+
<Grid />
|
|
684
|
+
Home
|
|
685
|
+
</SidebarMenu.Item>
|
|
686
|
+
<SidebarMenu.Item active href="#">
|
|
687
|
+
<Key />
|
|
688
|
+
API keys
|
|
689
|
+
</SidebarMenu.Item>
|
|
690
|
+
<SidebarMenu.Item href="#">
|
|
691
|
+
<Globe />
|
|
692
|
+
Webhooks
|
|
693
|
+
</SidebarMenu.Item>
|
|
694
|
+
</SidebarMenu.Root>
|
|
695
|
+
)
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
namespace styles {
|
|
699
|
+
export const column = style({ width: '15rem !custom' })
|
|
700
|
+
}
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
**Don't:** Write labels longer than the sidebar is wide.
|
|
704
|
+
|
|
705
|
+
```tsx
|
|
706
|
+
/**
|
|
707
|
+
* Don't example for "Keep Labels on One Line" on the SidebarMenu page.
|
|
708
|
+
* Don't write labels longer than the sidebar is wide.
|
|
709
|
+
* @module
|
|
710
|
+
*/
|
|
711
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
712
|
+
import { Globe, Grid, Key } from '@tempoxyz/ds/icons'
|
|
713
|
+
|
|
714
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
715
|
+
export function Demo() {
|
|
716
|
+
return (
|
|
717
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.column()}>
|
|
718
|
+
<SidebarMenu.Item href="#">
|
|
719
|
+
<Grid />
|
|
720
|
+
Home
|
|
721
|
+
</SidebarMenu.Item>
|
|
722
|
+
<SidebarMenu.Item active href="#">
|
|
723
|
+
<Key />
|
|
724
|
+
Manage your API keys and secrets
|
|
725
|
+
</SidebarMenu.Item>
|
|
726
|
+
<SidebarMenu.Item href="#">
|
|
727
|
+
<Globe />
|
|
728
|
+
Webhooks
|
|
729
|
+
</SidebarMenu.Item>
|
|
730
|
+
</SidebarMenu.Root>
|
|
731
|
+
)
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
namespace styles {
|
|
735
|
+
export const column = style({ width: '15rem !custom' })
|
|
736
|
+
}
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
### Put Workspace and Account Controls at the Edges
|
|
740
|
+
|
|
741
|
+
In an [AppShell](app-shell.md), put the project switcher in `AppShell.SidebarHeader` and the account menu in a `SidebarMenu.Account` at the end of `AppShell.SidebarFooter`. Both open a [Menu](menu.md): trigger the account menu with a `SidebarMenu.AccountRow`, and render the switcher with `render={<button type="button" />}`.
|
|
742
|
+
|
|
743
|
+
**Do:** Pin the project switcher to the top and the account to the bottom.
|
|
744
|
+
|
|
745
|
+
```tsx
|
|
746
|
+
/**
|
|
747
|
+
* Do example for "Put Workspace and Account Controls at the Edges" on the SidebarMenu page.
|
|
748
|
+
* Pin the project switcher to the top and the account to the bottom.
|
|
749
|
+
* @module
|
|
750
|
+
*/
|
|
751
|
+
import { Avatar, SidebarMenu, style } from '@tempoxyz/ds'
|
|
752
|
+
import { ChevronDown, Globe, Grid, Key, Store } from '@tempoxyz/ds/icons'
|
|
753
|
+
|
|
754
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
755
|
+
export function Demo() {
|
|
756
|
+
return (
|
|
757
|
+
<div {...styles.sidebar()}>
|
|
758
|
+
<SidebarMenu.Root aria-label="Project" size="small">
|
|
759
|
+
<SidebarMenu.Item render={<button type="button" />}>
|
|
760
|
+
<Store />
|
|
761
|
+
Checkout
|
|
762
|
+
<ChevronDown {...styles.chevron()} />
|
|
763
|
+
</SidebarMenu.Item>
|
|
764
|
+
</SidebarMenu.Root>
|
|
765
|
+
<SidebarMenu.Root aria-label="Console" size="small" {...styles.body()}>
|
|
766
|
+
<SidebarMenu.Item active href="#">
|
|
767
|
+
<Grid />
|
|
768
|
+
Home
|
|
769
|
+
</SidebarMenu.Item>
|
|
770
|
+
<SidebarMenu.Item href="#">
|
|
771
|
+
<Key />
|
|
772
|
+
API keys
|
|
773
|
+
</SidebarMenu.Item>
|
|
774
|
+
<SidebarMenu.Item href="#">
|
|
775
|
+
<Globe />
|
|
776
|
+
Webhooks
|
|
777
|
+
</SidebarMenu.Item>
|
|
778
|
+
</SidebarMenu.Root>
|
|
779
|
+
<SidebarMenu.Account>
|
|
780
|
+
<SidebarMenu.AccountRow description="alice@tempo.xyz" label="Alice Chen">
|
|
781
|
+
<Avatar size="32">
|
|
782
|
+
<Avatar.Fallback>AC</Avatar.Fallback>
|
|
783
|
+
</Avatar>
|
|
784
|
+
</SidebarMenu.AccountRow>
|
|
785
|
+
</SidebarMenu.Account>
|
|
786
|
+
</div>
|
|
787
|
+
)
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
namespace styles {
|
|
791
|
+
export const body = style({ flex: '1 !custom' })
|
|
792
|
+
|
|
793
|
+
export const chevron = style({ marginInlineStart: 'auto !custom' })
|
|
794
|
+
|
|
795
|
+
export const sidebar = style({
|
|
796
|
+
display: 'flex',
|
|
797
|
+
flexDirection: 'column',
|
|
798
|
+
height: '20rem !custom',
|
|
799
|
+
rowGap: '12',
|
|
800
|
+
width: '15rem !custom',
|
|
801
|
+
})
|
|
802
|
+
}
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
**Don't:** List the switcher and the account among the pages.
|
|
806
|
+
|
|
807
|
+
```tsx
|
|
808
|
+
/**
|
|
809
|
+
* Don't example for "Put Workspace and Account Controls at the Edges" on the SidebarMenu page.
|
|
810
|
+
* Don't list the switcher and the account among the pages.
|
|
811
|
+
* @module
|
|
812
|
+
*/
|
|
813
|
+
import { SidebarMenu, style } from '@tempoxyz/ds'
|
|
814
|
+
import { ChevronDown, Globe, Grid, Key, Store, UserCircle } from '@tempoxyz/ds/icons'
|
|
815
|
+
|
|
816
|
+
/** Renders the static preview, which the guideline card shows inert. */
|
|
817
|
+
export function Demo() {
|
|
818
|
+
return (
|
|
819
|
+
<div {...styles.sidebar()}>
|
|
820
|
+
<SidebarMenu.Root aria-label="Console" size="small">
|
|
821
|
+
<SidebarMenu.Item active href="#">
|
|
822
|
+
<Grid />
|
|
823
|
+
Home
|
|
824
|
+
</SidebarMenu.Item>
|
|
825
|
+
<SidebarMenu.Item href="#">
|
|
826
|
+
<Key />
|
|
827
|
+
API keys
|
|
828
|
+
</SidebarMenu.Item>
|
|
829
|
+
<SidebarMenu.Item href="#">
|
|
830
|
+
<Globe />
|
|
831
|
+
Webhooks
|
|
832
|
+
</SidebarMenu.Item>
|
|
833
|
+
</SidebarMenu.Root>
|
|
834
|
+
<SidebarMenu.Root aria-label="Project" size="small">
|
|
835
|
+
<SidebarMenu.Item render={<button type="button" />}>
|
|
836
|
+
<Store />
|
|
837
|
+
Checkout
|
|
838
|
+
<ChevronDown {...styles.chevron()} />
|
|
839
|
+
</SidebarMenu.Item>
|
|
840
|
+
</SidebarMenu.Root>
|
|
841
|
+
<SidebarMenu.Root aria-label="Account" size="small">
|
|
842
|
+
<SidebarMenu.Item render={<button type="button" />}>
|
|
843
|
+
<UserCircle />
|
|
844
|
+
Alice Chen
|
|
845
|
+
</SidebarMenu.Item>
|
|
846
|
+
</SidebarMenu.Root>
|
|
847
|
+
</div>
|
|
848
|
+
)
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
namespace styles {
|
|
852
|
+
export const chevron = style({ marginInlineStart: 'auto !custom' })
|
|
853
|
+
|
|
854
|
+
export const sidebar = style({
|
|
855
|
+
display: 'flex',
|
|
856
|
+
flexDirection: 'column',
|
|
857
|
+
height: '20rem !custom',
|
|
858
|
+
rowGap: '12',
|
|
859
|
+
width: '15rem !custom',
|
|
860
|
+
})
|
|
861
|
+
}
|
|
862
|
+
```
|
|
863
|
+
|
|
864
|
+
## Content
|
|
865
|
+
|
|
866
|
+
* **Items:** Match the page's `AppShell.Title`, such as API keys. Use one or two nouns, without verbs such as Manage.
|
|
867
|
+
* **Group labels:** Short nouns, such as Payments, not repeated in the items below.
|
|
868
|
+
* **Account row:** The person's name over their email or wallet address, such as Piril Akay over <piril@tempo.xyz>.
|
|
869
|
+
* **Logo row:** The product or wallet name over its address, such as Tempo Wallet over 0xc721…s9dk.
|
|
870
|
+
|
|
871
|
+
## Accessibility
|
|
872
|
+
|
|
873
|
+
SidebarMenu renders a navigation landmark of links, with disclosure submenus and no menu roles. It follows the [WAI-ARIA Authoring Practices disclosure navigation example](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/).
|
|
874
|
+
|
|
875
|
+
### Semantics
|
|
876
|
+
|
|
877
|
+
* **SidebarMenu.Root (nav):** A landmark named "Main" unless you pass `aria-label`.
|
|
878
|
+
* **SidebarMenu.Item (aria-current):** Each item is a link. The active item is marked as the current page.
|
|
879
|
+
* **SidebarMenu.Group (group):** Named by its group label.
|
|
880
|
+
* **SidebarMenu.SubmenuTrigger (aria-expanded):** A button that reports whether its submenu is open. Enter and Space toggle it.
|
|
881
|
+
* **SidebarMenu.SubmenuPanel:** Collapsed links leave the tab order. Under reduced motion, it fades instead of growing.
|
|
882
|
+
* **SidebarMenu.AccountRow (button):** A button named by its two lines. As a menu trigger, it reports whether the menu is open.
|
|
883
|
+
* **SidebarMenu.Account (div):** A plain frame. Its divider is decorative, so it announces no separator before the row.
|
|
884
|
+
* **SidebarMenu.Logo (aria-hidden):** Hidden with the rest of the row's media. The row's label names the product or wallet.
|
|
885
|
+
|
|
886
|
+
### Keyboard
|
|
887
|
+
|
|
888
|
+
* **Move Through Items (Tab):** Moves focus through items and submenu triggers.
|
|
889
|
+
* **Follow or Toggle (Enter):** Follows a focused link or toggles a submenu.
|
|
890
|
+
* **Toggle a Submenu (Space):** Toggles the focused submenu.
|
|
891
|
+
|
|
892
|
+
Arrow keys do not move focus. Links in a landmark use the Tab order.
|
|
893
|
+
|
|
894
|
+
### Focus
|
|
895
|
+
|
|
896
|
+
Focus stays on a submenu trigger when it toggles. After it opens, the next Tab moves to its first link.
|
|
897
|
+
|
|
898
|
+
### Your Responsibilities
|
|
899
|
+
|
|
900
|
+
* **Name Each Landmark (SC 2.4.1):** If a page has several navigation landmarks, give each a distinct `aria-label`.
|
|
901
|
+
* **Mark One Active Item (active):** Mark only the current page. When it is nested, keep its submenu open.
|
|
902
|
+
* **Name Unlabelled Groups (aria-label):** Name a group that has no visible label.
|
|
903
|
+
* **Keep a Consistent Order (SC 3.2.3):** Keep the item order the same on every page.
|
|
904
|
+
* **Name Pages in Text (aria-hidden):** Icons are hidden from assistive technology. The text label must name the page.
|
|
905
|
+
|
|
906
|
+
## Related
|
|
907
|
+
|
|
908
|
+
[AppShell](app-shell.md)
|
|
909
|
+
|
|
910
|
+
Use for the frame that holds the sidebar.
|
|
911
|
+
|
|
912
|
+
[Menu](menu.md)
|
|
913
|
+
|
|
914
|
+
Use for lists of actions.
|
|
915
|
+
|
|
916
|
+
[Tabs](tabs.md)
|
|
917
|
+
|
|
918
|
+
Use for views within one page.
|
|
919
|
+
|
|
920
|
+
[Navigation](../patterns/navigation.md)
|
|
921
|
+
|
|
922
|
+
Covers choosing between navigation components.
|