@maxio-com/react-ui-components 9.16.0 → 9.17.0
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/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/skills/maxio-react/SKILL.md +69 -0
- package/dist/skills/maxio-react/agents/openai.yaml +4 -0
- package/dist/skills/maxio-react/references/components-action-list.md +92 -0
- package/dist/skills/maxio-react/references/components-action-menu.md +162 -0
- package/dist/skills/maxio-react/references/components-avatar.md +66 -0
- package/dist/skills/maxio-react/references/components-breadcrumbs.md +86 -0
- package/dist/skills/maxio-react/references/components-buttons-button.md +170 -0
- package/dist/skills/maxio-react/references/components-buttons-iconbutton.md +102 -0
- package/dist/skills/maxio-react/references/components-card.md +175 -0
- package/dist/skills/maxio-react/references/components-chip.md +151 -0
- package/dist/skills/maxio-react/references/components-data-table.md +344 -0
- package/dist/skills/maxio-react/references/components-drawer.md +293 -0
- package/dist/skills/maxio-react/references/components-flex.md +185 -0
- package/dist/skills/maxio-react/references/components-forms-checkbox.md +257 -0
- package/dist/skills/maxio-react/references/components-forms-combobox.md +250 -0
- package/dist/skills/maxio-react/references/components-forms-radio-group.md +202 -0
- package/dist/skills/maxio-react/references/components-forms-select.md +295 -0
- package/dist/skills/maxio-react/references/components-forms-textarea.md +187 -0
- package/dist/skills/maxio-react/references/components-forms-textfield.md +254 -0
- package/dist/skills/maxio-react/references/components-grid.md +140 -0
- package/dist/skills/maxio-react/references/components-icon.md +169 -0
- package/dist/skills/maxio-react/references/components-link.md +180 -0
- package/dist/skills/maxio-react/references/components-listbox.md +205 -0
- package/dist/skills/maxio-react/references/components-loading-spinner.md +123 -0
- package/dist/skills/maxio-react/references/components-logo.md +91 -0
- package/dist/skills/maxio-react/references/components-notifications-alert.md +103 -0
- package/dist/skills/maxio-react/references/components-notifications-banner.md +173 -0
- package/dist/skills/maxio-react/references/components-notifications-toast.md +155 -0
- package/dist/skills/maxio-react/references/components-pagination.md +115 -0
- package/dist/skills/maxio-react/references/components-popover.md +176 -0
- package/dist/skills/maxio-react/references/components-progressbar.md +98 -0
- package/dist/skills/maxio-react/references/components-segmentedcontrol.md +292 -0
- package/dist/skills/maxio-react/references/components-tabs.md +193 -0
- package/dist/skills/maxio-react/references/components-tag.md +117 -0
- package/dist/skills/maxio-react/references/components-tile.md +114 -0
- package/dist/skills/maxio-react/references/components-toggle.md +218 -0
- package/dist/skills/maxio-react/references/components-tooltip.md +178 -0
- package/dist/skills/maxio-react/references/components-typography-body.md +101 -0
- package/dist/skills/maxio-react/references/components-typography-code.md +72 -0
- package/dist/skills/maxio-react/references/components-typography-display.md +91 -0
- package/dist/skills/maxio-react/references/components-typography-heading.md +88 -0
- package/dist/skills/maxio-react/references/components-typography-label.md +82 -0
- package/dist/skills/maxio-react/references/deprecated-textinput.md +250 -0
- package/dist/skills/maxio-react/references/foundations-dark-mode.md +85 -0
- package/dist/skills/maxio-react/references/foundations-design-tokens-about.md +108 -0
- package/dist/skills/maxio-react/references/foundations-design-tokens-colors-primitive-colors.md +33 -0
- package/dist/skills/maxio-react/references/foundations-design-tokens-colors-semantic-colors.md +11 -0
- package/dist/skills/maxio-react/references/foundations-start-here.md +128 -0
- package/dist/skills/maxio-react/references/patterns-auth-layout.md +318 -0
- package/dist/skills/maxio-react/references/patterns-side-nav.md +182 -0
- package/dist/skills/maxio-react/references/patterns-top-bar.md +214 -0
- package/package.json +2 -2
- package/typings/index.d.ts +15 -2
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Authentication Layout
|
|
2
|
+
|
|
3
|
+
Provides screen layout for user authentication flow.
|
|
4
|
+
|
|
5
|
+
```jsx
|
|
6
|
+
import { AuthLayout } from '@maxio-com/react-ui-components';
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Playground
|
|
10
|
+
|
|
11
|
+
## Alert
|
|
12
|
+
|
|
13
|
+
Use an alert to show authentication errors, status updates, or other contextual information above the main content card.
|
|
14
|
+
|
|
15
|
+
## Leading Element
|
|
16
|
+
|
|
17
|
+
Use a leading element for back actions, status icons, or other compact header affordances.
|
|
18
|
+
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { AuthLayout, Body, Button, Flex, Icon, IconButton, Link, Select, TextField } from "@maxio-com/react-ui-components";
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Prop Types
|
|
26
|
+
|
|
27
|
+
### AuthLayout
|
|
28
|
+
|
|
29
|
+
| Prop | Type | Required | Default | Description | Source |
|
|
30
|
+
| --- | --- | --- | --- | --- | --- |
|
|
31
|
+
| `alert` | `AlertProps` | no | - | - | TypeLiteral |
|
|
32
|
+
| `description` | `ReactNode` | no | - | - | TypeLiteral |
|
|
33
|
+
| `footer` | `ReactNode` | no | - | - | TypeLiteral |
|
|
34
|
+
| `heading` | `string` | yes | - | - | TypeLiteral |
|
|
35
|
+
| `leadingElement` | `ReactNode` | no | `null` | - | TypeLiteral |
|
|
36
|
+
| `sentiment` | `"danger" \| "success"` | no | `success` | - | TypeLiteral |
|
|
37
|
+
| `topAddon` | `ReactNode` | no | `null` | - | TypeLiteral |
|
|
38
|
+
|
|
39
|
+
## Stories
|
|
40
|
+
|
|
41
|
+
### With Form
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
const WithForm = () => <AuthLayout
|
|
45
|
+
heading="Log In"
|
|
46
|
+
footer={(<>
|
|
47
|
+
<Flex
|
|
48
|
+
gap={2}
|
|
49
|
+
grow
|
|
50
|
+
style={{ color: 'var(--maxio-color-text-tertiary)' }}
|
|
51
|
+
>
|
|
52
|
+
<Body size="xs">© Maxio, LLC.</Body>
|
|
53
|
+
<Link
|
|
54
|
+
href="https://www.maxio.com/privacy-policy"
|
|
55
|
+
size="xs"
|
|
56
|
+
underline
|
|
57
|
+
variant="tertiary"
|
|
58
|
+
>
|
|
59
|
+
Privacy
|
|
60
|
+
</Link>
|
|
61
|
+
</Flex>
|
|
62
|
+
<div>
|
|
63
|
+
<Select
|
|
64
|
+
label="Hosting Region"
|
|
65
|
+
options={[
|
|
66
|
+
{ label: 'US', value: 'https://example.com' },
|
|
67
|
+
{ label: 'EU', value: 'https://example.com' },
|
|
68
|
+
]}
|
|
69
|
+
inline
|
|
70
|
+
onChange={() => {}}
|
|
71
|
+
></Select>
|
|
72
|
+
</div>
|
|
73
|
+
</>)}
|
|
74
|
+
description={null}
|
|
75
|
+
children={
|
|
76
|
+
<Flex flexDirection="col" gap={4}>
|
|
77
|
+
<TextField size="lg" label="Email" onChange={() => {}} />
|
|
78
|
+
<Button
|
|
79
|
+
size="lg"
|
|
80
|
+
icon={<Icon variant="arrow-right-long" />}
|
|
81
|
+
fullWidth
|
|
82
|
+
>
|
|
83
|
+
Continue
|
|
84
|
+
</Button>
|
|
85
|
+
</Flex>
|
|
86
|
+
} />;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### With Alert
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
const WithAlert = () => <AuthLayout
|
|
93
|
+
heading="Log In"
|
|
94
|
+
description="Description goes here. It can be a short text to guide the user."
|
|
95
|
+
footer={(<>
|
|
96
|
+
<Flex
|
|
97
|
+
gap={2}
|
|
98
|
+
grow
|
|
99
|
+
style={{ color: 'var(--maxio-color-text-tertiary)' }}
|
|
100
|
+
>
|
|
101
|
+
<Body size="xs">© Maxio, LLC.</Body>
|
|
102
|
+
<Link
|
|
103
|
+
href="https://www.maxio.com/privacy-policy"
|
|
104
|
+
size="xs"
|
|
105
|
+
underline
|
|
106
|
+
variant="tertiary"
|
|
107
|
+
>
|
|
108
|
+
Privacy
|
|
109
|
+
</Link>
|
|
110
|
+
</Flex>
|
|
111
|
+
<div>
|
|
112
|
+
<Select
|
|
113
|
+
label="Hosting Region"
|
|
114
|
+
options={[
|
|
115
|
+
{ label: 'US', value: 'https://example.com' },
|
|
116
|
+
{ label: 'EU', value: 'https://example.com' },
|
|
117
|
+
]}
|
|
118
|
+
inline
|
|
119
|
+
onChange={() => {}}
|
|
120
|
+
></Select>
|
|
121
|
+
</div>
|
|
122
|
+
</>)}
|
|
123
|
+
alert={{
|
|
124
|
+
title: args.alert?.title || 'Alert Title',
|
|
125
|
+
children: args.alert?.children || 'This is an alert message.',
|
|
126
|
+
sentiment: args.alert?.sentiment || 'info',
|
|
127
|
+
}} />;
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### With Buttons
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
const WithButtons = () => <AuthLayout
|
|
134
|
+
heading="Log In"
|
|
135
|
+
description="Description goes here. It can be a short text to guide the user."
|
|
136
|
+
footer={(<>
|
|
137
|
+
<Flex
|
|
138
|
+
gap={2}
|
|
139
|
+
grow
|
|
140
|
+
style={{ color: 'var(--maxio-color-text-tertiary)' }}
|
|
141
|
+
>
|
|
142
|
+
<Body size="xs">© Maxio, LLC.</Body>
|
|
143
|
+
<Link
|
|
144
|
+
href="https://www.maxio.com/privacy-policy"
|
|
145
|
+
size="xs"
|
|
146
|
+
underline
|
|
147
|
+
variant="tertiary"
|
|
148
|
+
>
|
|
149
|
+
Privacy
|
|
150
|
+
</Link>
|
|
151
|
+
</Flex>
|
|
152
|
+
<div>
|
|
153
|
+
<Select
|
|
154
|
+
label="Hosting Region"
|
|
155
|
+
options={[
|
|
156
|
+
{ label: 'US', value: 'https://example.com' },
|
|
157
|
+
{ label: 'EU', value: 'https://example.com' },
|
|
158
|
+
]}
|
|
159
|
+
inline
|
|
160
|
+
onChange={() => {}}
|
|
161
|
+
></Select>
|
|
162
|
+
</div>
|
|
163
|
+
</>)}
|
|
164
|
+
children={
|
|
165
|
+
<Flex flexDirection="col" gap={2}>
|
|
166
|
+
<Button
|
|
167
|
+
size="lg"
|
|
168
|
+
icon={<Icon variant="arrow-right-long" />}
|
|
169
|
+
fullWidth
|
|
170
|
+
variant="tertiary"
|
|
171
|
+
>
|
|
172
|
+
Button
|
|
173
|
+
</Button>
|
|
174
|
+
<Button
|
|
175
|
+
size="lg"
|
|
176
|
+
icon={<Icon variant="arrow-right-long" />}
|
|
177
|
+
fullWidth
|
|
178
|
+
variant="tertiary"
|
|
179
|
+
>
|
|
180
|
+
Button
|
|
181
|
+
</Button>
|
|
182
|
+
<Button
|
|
183
|
+
size="lg"
|
|
184
|
+
icon={<Icon variant="arrow-right-long" />}
|
|
185
|
+
fullWidth
|
|
186
|
+
variant="tertiary"
|
|
187
|
+
>
|
|
188
|
+
Button
|
|
189
|
+
</Button>
|
|
190
|
+
</Flex>
|
|
191
|
+
} />;
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### With Clickable Leading Element
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
const WithClickableLeadingElement = () => <AuthLayout
|
|
198
|
+
heading="Log In"
|
|
199
|
+
description="Description goes here. It can be a short text to guide the user."
|
|
200
|
+
footer={(<>
|
|
201
|
+
<Flex
|
|
202
|
+
gap={2}
|
|
203
|
+
grow
|
|
204
|
+
style={{ color: 'var(--maxio-color-text-tertiary)' }}
|
|
205
|
+
>
|
|
206
|
+
<Body size="xs">© Maxio, LLC.</Body>
|
|
207
|
+
<Link
|
|
208
|
+
href="https://www.maxio.com/privacy-policy"
|
|
209
|
+
size="xs"
|
|
210
|
+
underline
|
|
211
|
+
variant="tertiary"
|
|
212
|
+
>
|
|
213
|
+
Privacy
|
|
214
|
+
</Link>
|
|
215
|
+
</Flex>
|
|
216
|
+
<div>
|
|
217
|
+
<Select
|
|
218
|
+
label="Hosting Region"
|
|
219
|
+
options={[
|
|
220
|
+
{ label: 'US', value: 'https://example.com' },
|
|
221
|
+
{ label: 'EU', value: 'https://example.com' },
|
|
222
|
+
]}
|
|
223
|
+
inline
|
|
224
|
+
onChange={() => {}}
|
|
225
|
+
></Select>
|
|
226
|
+
</div>
|
|
227
|
+
</>)}
|
|
228
|
+
leadingElement={
|
|
229
|
+
<IconButton
|
|
230
|
+
variant="tertiary"
|
|
231
|
+
size="sm"
|
|
232
|
+
aria-label="Go back"
|
|
233
|
+
icon={<Icon variant="arrow-left" />}
|
|
234
|
+
onClick={() => console.log('clicked')}
|
|
235
|
+
/>
|
|
236
|
+
} />;
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### With Leading Element
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
const WithLeadingElement = () => <AuthLayout
|
|
243
|
+
heading="Log In"
|
|
244
|
+
description="Description goes here. It can be a short text to guide the user."
|
|
245
|
+
footer={(<>
|
|
246
|
+
<Flex
|
|
247
|
+
gap={2}
|
|
248
|
+
grow
|
|
249
|
+
style={{ color: 'var(--maxio-color-text-tertiary)' }}
|
|
250
|
+
>
|
|
251
|
+
<Body size="xs">© Maxio, LLC.</Body>
|
|
252
|
+
<Link
|
|
253
|
+
href="https://www.maxio.com/privacy-policy"
|
|
254
|
+
size="xs"
|
|
255
|
+
underline
|
|
256
|
+
variant="tertiary"
|
|
257
|
+
>
|
|
258
|
+
Privacy
|
|
259
|
+
</Link>
|
|
260
|
+
</Flex>
|
|
261
|
+
<div>
|
|
262
|
+
<Select
|
|
263
|
+
label="Hosting Region"
|
|
264
|
+
options={[
|
|
265
|
+
{ label: 'US', value: 'https://example.com' },
|
|
266
|
+
{ label: 'EU', value: 'https://example.com' },
|
|
267
|
+
]}
|
|
268
|
+
inline
|
|
269
|
+
onChange={() => {}}
|
|
270
|
+
></Select>
|
|
271
|
+
</div>
|
|
272
|
+
</>)}
|
|
273
|
+
sentiment="danger"
|
|
274
|
+
leadingElement={
|
|
275
|
+
<Icon size="md" variant="check-circle maxio-icon--danger" />
|
|
276
|
+
} />;
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### With Top Addon
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
const WithTopAddon = () => <AuthLayout
|
|
283
|
+
heading="Log In"
|
|
284
|
+
description="Description goes here. It can be a short text to guide the user."
|
|
285
|
+
footer={(<>
|
|
286
|
+
<Flex
|
|
287
|
+
gap={2}
|
|
288
|
+
grow
|
|
289
|
+
style={{ color: 'var(--maxio-color-text-tertiary)' }}
|
|
290
|
+
>
|
|
291
|
+
<Body size="xs">© Maxio, LLC.</Body>
|
|
292
|
+
<Link
|
|
293
|
+
href="https://www.maxio.com/privacy-policy"
|
|
294
|
+
size="xs"
|
|
295
|
+
underline
|
|
296
|
+
variant="tertiary"
|
|
297
|
+
>
|
|
298
|
+
Privacy
|
|
299
|
+
</Link>
|
|
300
|
+
</Flex>
|
|
301
|
+
<div>
|
|
302
|
+
<Select
|
|
303
|
+
label="Hosting Region"
|
|
304
|
+
options={[
|
|
305
|
+
{ label: 'US', value: 'https://example.com' },
|
|
306
|
+
{ label: 'EU', value: 'https://example.com' },
|
|
307
|
+
]}
|
|
308
|
+
inline
|
|
309
|
+
onChange={() => {}}
|
|
310
|
+
></Select>
|
|
311
|
+
</div>
|
|
312
|
+
</>)}
|
|
313
|
+
topAddon={<Link href="#">Log Out</Link>}
|
|
314
|
+
sentiment="danger"
|
|
315
|
+
leadingElement={
|
|
316
|
+
<Icon size="md" variant="check-circle maxio-icon--danger" />
|
|
317
|
+
} />;
|
|
318
|
+
```
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# SideNav
|
|
2
|
+
|
|
3
|
+
## Usage Guidelines
|
|
4
|
+
|
|
5
|
+
### Overview
|
|
6
|
+
|
|
7
|
+
SideNav provides persistent application navigation for Maxio products.
|
|
8
|
+
|
|
9
|
+
#### When to Use
|
|
10
|
+
|
|
11
|
+
- Use SideNav for persistent product navigation that should remain available across application pages.
|
|
12
|
+
- Use SideNav when navigation needs grouped sections, expandable sub-navigation, and a current-page indicator.
|
|
13
|
+
- Use SideNav when users need to switch between sites or reach site-level actions from the same navigation region.
|
|
14
|
+
|
|
15
|
+
#### When Not to Use
|
|
16
|
+
|
|
17
|
+
- Do not use SideNav for secondary page-level actions. Use TopBar, Tabs, ActionMenu, or Button patterns depending on the task.
|
|
18
|
+
- Do not use SideNav for short in-page navigation or step-by-step flows.
|
|
19
|
+
- Do not use SideNav when the page has only one or two destinations that are better represented as links in the main content.
|
|
20
|
+
|
|
21
|
+
### Behavior
|
|
22
|
+
|
|
23
|
+
- **Mouse and touch**: links navigate immediately. Parent menu buttons expand one section at a time and open the collapsed sidebar before showing sub-items.
|
|
24
|
+
- **Keyboard**: the brand link, site switcher, toggle button, section buttons, and links are reachable through normal Tab order. Parent buttons toggle with Enter or Space.
|
|
25
|
+
- **Focus management**: keep the Maxio focus ring visible. When the sidebar is collapsed, top-level items expose hover tooltips while focus and activation remain on the link or button.
|
|
26
|
+
- **Controlled state**: pass `isOpen` and `onChange` when application layout owns the collapsed state. Omit `isOpen` for internal responsive state based on `collapseBreakpoint`.
|
|
27
|
+
- **Persistence**: keep the active section marked through `isCurrent` so visual state and `aria-current="page"` stay aligned after route changes.
|
|
28
|
+
|
|
29
|
+
### Accessibility
|
|
30
|
+
|
|
31
|
+
- Use the rendered `<nav>` landmark for the primary application navigation. Add a descriptive `aria-label` in static HTML when the page includes multiple navigation landmarks.
|
|
32
|
+
- Use real links with `href` for destinations and buttons for expandable section headers.
|
|
33
|
+
- Mark the current destination with `aria-current="page"` through the section item's `isCurrent` value.
|
|
34
|
+
- Keep `aria-expanded` synchronized on parent menu buttons that reveal nested lists.
|
|
35
|
+
- Keep site switcher actions as keyboard-accessible links with descriptive labels.
|
|
36
|
+
|
|
37
|
+
### Content
|
|
38
|
+
|
|
39
|
+
- Keep top-level section names short and stable so collapsed tooltips and expanded labels match.
|
|
40
|
+
- Group related destinations under clear headings such as "Integrations" only when the heading improves scanning.
|
|
41
|
+
- Use one active item at a time. If a child route is current, keep its parent section expanded or visually associated with the active child.
|
|
42
|
+
- Avoid using icons as the only way to identify a destination; labels should remain meaningful when icons are hidden.
|
|
43
|
+
|
|
44
|
+
### Related
|
|
45
|
+
|
|
46
|
+
- **[TopBar](patterns-top-bar.md)**: use for global utilities such as search, help, notifications, and profile actions.
|
|
47
|
+
- **[ActionMenu](components-action-menu.md)**: use for compact groups of contextual actions.
|
|
48
|
+
- **[Tabs](components-tabs.md)**: use for switching between related views inside one page or workflow.
|
|
49
|
+
|
|
50
|
+
## React
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { SideNav } from '@maxio-com/react-ui-components';
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### State Management
|
|
57
|
+
|
|
58
|
+
SideNav can manage its own collapsed state or receive it from the application shell.
|
|
59
|
+
|
|
60
|
+
#### Controlled
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
const [isOpen, setIsOpen] = React.useState(true);
|
|
64
|
+
|
|
65
|
+
<SideNav
|
|
66
|
+
topDropdownItems={topDropdownItems}
|
|
67
|
+
sections={sections}
|
|
68
|
+
isOpen={isOpen}
|
|
69
|
+
onChange={setIsOpen}
|
|
70
|
+
shouldToggleSidebar
|
|
71
|
+
/>;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Uncontrolled
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
<SideNav
|
|
78
|
+
topDropdownItems={topDropdownItems}
|
|
79
|
+
sections={sections}
|
|
80
|
+
collapseBreakpoint={800}
|
|
81
|
+
shouldToggleSidebar
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Navigation Data
|
|
86
|
+
|
|
87
|
+
Use `topDropdownItems` for the site switcher and `sections` for grouped navigation lists. Each item with `isCurrent: true` renders the active page state.
|
|
88
|
+
|
|
89
|
+
### `topDropdownItems` typings:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
topDropdownItems: {
|
|
93
|
+
mainItem: SideNavTopDropdownItem;
|
|
94
|
+
otherItems: SideNavTopDropdownItem[];
|
|
95
|
+
actions: SideNavTopDropdownItem[];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface SideNavTopDropdownItem {
|
|
99
|
+
id: string;
|
|
100
|
+
title: string;
|
|
101
|
+
icon: IconVariant;
|
|
102
|
+
url: string;
|
|
103
|
+
iconClass?: string;
|
|
104
|
+
rel?: string;
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `sections` typings:
|
|
109
|
+
|
|
110
|
+
As of `Component` property, it is used to render custom component instead of default one.
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
sections: SectionGroup[];
|
|
114
|
+
|
|
115
|
+
type SectionGroup = (Section | SectionHeading)[];
|
|
116
|
+
|
|
117
|
+
interface SectionHeading {
|
|
118
|
+
title: string;
|
|
119
|
+
type?: 'heading';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
interface Section extends SingleSectionWithItems {
|
|
123
|
+
Component?: SectionComponent;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
type SectionComponent = React.FC<{ section: SingleSectionWithItems }>;
|
|
127
|
+
|
|
128
|
+
interface SingleSectionWithItems extends SingleSection {
|
|
129
|
+
isOpen?: boolean;
|
|
130
|
+
items?: SingleSection[];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
interface SingleSection {
|
|
134
|
+
href?: string;
|
|
135
|
+
icon: IconVariant | null;
|
|
136
|
+
name: string;
|
|
137
|
+
key: string;
|
|
138
|
+
isCurrent?: boolean;
|
|
139
|
+
type?: 'regular';
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Imports
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { SideNav } from "@maxio-com/react-ui-components";
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Prop Types
|
|
150
|
+
|
|
151
|
+
### SideNav
|
|
152
|
+
|
|
153
|
+
| Prop | Type | Required | Default | Description | Source |
|
|
154
|
+
| --- | --- | --- | --- | --- | --- |
|
|
155
|
+
| `collapseBreakpoint` | `number` | no | `800` | - | SideNavProviderProps |
|
|
156
|
+
| `isOpen` | `boolean` | no | - | - | SideNavProviderProps |
|
|
157
|
+
| `onChange` | `((isOpen: boolean) => void)` | no | - | - | SideNavProviderProps |
|
|
158
|
+
| `sections` | `SectionGroup[]` | no | `[]` | - | SideNavProviderProps |
|
|
159
|
+
| `shouldToggleSidebar` | `boolean` | no | `false` | - | SideNavProviderProps |
|
|
160
|
+
| `topDropdownItems` | `SideNavTopDropdown` | yes | - | - | SideNavProviderProps |
|
|
161
|
+
| `withIcons` | `boolean` | no | `true` | - | SideNavProviderProps |
|
|
162
|
+
|
|
163
|
+
## Stories
|
|
164
|
+
|
|
165
|
+
### Default
|
|
166
|
+
|
|
167
|
+
Use SideNav for persistent application navigation with a site switcher, grouped product areas, and expandable sub-navigation. Mark the current page with `isCurrent` so the generated link receives `aria-current="page"`.
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
const Default = () => <SideNav
|
|
171
|
+
topDropdownItems={TOP_DROPDOWN_ITEMS_MOCK}
|
|
172
|
+
sections={[
|
|
173
|
+
SIDE_NAV_ITEMS_MOCK,
|
|
174
|
+
SIDE_NAV_INTEGRATION_ITEMS_MOCK,
|
|
175
|
+
SIDE_NAV_BOTTOM_ITEMS_MOCK,
|
|
176
|
+
]}
|
|
177
|
+
withIcons
|
|
178
|
+
shouldToggleSidebar
|
|
179
|
+
collapseBreakpoint={800}
|
|
180
|
+
isOpen={undefined}
|
|
181
|
+
onChange={() => {}} />;
|
|
182
|
+
```
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# TopBar
|
|
2
|
+
|
|
3
|
+
## Usage Guidelines
|
|
4
|
+
|
|
5
|
+
### Overview
|
|
6
|
+
|
|
7
|
+
TopBar provides the persistent application header area for global actions, search, account controls, and the side navigation opener in responsive layouts.
|
|
8
|
+
|
|
9
|
+
#### When to Use
|
|
10
|
+
|
|
11
|
+
- Use TopBar for persistent application-level actions such as search, help, notifications, profile access, and account context.
|
|
12
|
+
- Use TopBar with SideNav when responsive layouts need a header control to reopen collapsed navigation.
|
|
13
|
+
- Use the center area for high-value global controls that should remain available across pages, such as search or environment menus.
|
|
14
|
+
|
|
15
|
+
#### When Not to Use
|
|
16
|
+
|
|
17
|
+
- Do not use TopBar as the primary page navigation. Use SideNav or page-level navigation for destination lists.
|
|
18
|
+
- Do not place page-specific actions in TopBar when they only affect one table, card, or form section.
|
|
19
|
+
- Do not overload TopBar with every global link. Group secondary choices in ActionMenu or move them to SideNav.
|
|
20
|
+
|
|
21
|
+
### Behavior
|
|
22
|
+
|
|
23
|
+
- **Mouse and touch**: icon buttons and menus activate according to their underlying Button, IconButton, Link, or ActionMenu behavior.
|
|
24
|
+
- **Keyboard**: preserve native Tab order through the side navigation opener, center controls, and right-side actions.
|
|
25
|
+
- **Focus management**: when the side navigation opener is shown, return focus to a sensible place after the side navigation opens or closes.
|
|
26
|
+
- **Responsive state**: set `sideNavIsClosed` only when the side navigation is collapsed and the opener should be visible.
|
|
27
|
+
- **Composition**: pass persistent right-side controls through `actions` and optional center content through `children`.
|
|
28
|
+
|
|
29
|
+
### Accessibility
|
|
30
|
+
|
|
31
|
+
- TopBar renders a `nav` landmark, so use it for navigation and application actions that deserve landmark navigation.
|
|
32
|
+
- Keep every icon-only action accessible with a specific `aria-label`, such as "Open Search" or "Notifications".
|
|
33
|
+
- Use buttons for in-page actions and anchors for navigation to another route or resource.
|
|
34
|
+
- Keep search fields labelled and submit them with semantic form behavior when search can be submitted.
|
|
35
|
+
- Do not rely on icon shape alone to communicate action purpose.
|
|
36
|
+
|
|
37
|
+
### Content
|
|
38
|
+
|
|
39
|
+
- Keep action labels short and outcome-oriented, even when they are only exposed to assistive technology.
|
|
40
|
+
- Use profile avatar alt text that identifies the account or person when the image conveys identity.
|
|
41
|
+
- Prefer visible labels for center menus so administrative or environment context can be scanned quickly.
|
|
42
|
+
|
|
43
|
+
### Related
|
|
44
|
+
|
|
45
|
+
- **[SideNav](patterns-side-nav.md)**: use for primary application navigation and collapsed navigation state.
|
|
46
|
+
- **[IconButton](components-buttons-iconbutton.md)**: use for icon-only actions inside the top bar.
|
|
47
|
+
- **[ActionMenu](components-action-menu.md)**: use to group multiple related top bar actions.
|
|
48
|
+
|
|
49
|
+
## React
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { TopBar } from '@maxio-com/react-ui-components';
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Imports
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import {
|
|
59
|
+
Avatar,
|
|
60
|
+
Flex,
|
|
61
|
+
Icon,
|
|
62
|
+
IconButton,
|
|
63
|
+
Menu,
|
|
64
|
+
MenuButton,
|
|
65
|
+
MenuList,
|
|
66
|
+
Select,
|
|
67
|
+
TextField,
|
|
68
|
+
TopBar,
|
|
69
|
+
} from "@maxio-com/react-ui-components";
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Prop Types
|
|
73
|
+
|
|
74
|
+
### TopBar
|
|
75
|
+
|
|
76
|
+
| Prop | Type | Required | Default | Description | Source |
|
|
77
|
+
| --- | --- | --- | --- | --- | --- |
|
|
78
|
+
| `actions` | `ReactNode` | yes | - | Actions displayed on the right side of the top bar | TypeLiteral |
|
|
79
|
+
| `children` | `ReactNode` | no | - | Additional actions displayed in the middle of the top bar | TypeLiteral |
|
|
80
|
+
| `openSideNav` | `(() => void)` | no | - | Callback function to open the side navigation | TypeLiteral |
|
|
81
|
+
| `sideNavIsClosed` | `boolean` | no | - | Show/hide side navigation button | TypeLiteral |
|
|
82
|
+
|
|
83
|
+
## Stories
|
|
84
|
+
|
|
85
|
+
### Default
|
|
86
|
+
|
|
87
|
+
Use the default top bar for persistent global actions such as search, help, notifications, and profile access. Keep icon-only actions accessible with concise `aria-label` values.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
const Default = () => <TopBar actions={topBarActions} />;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### With Search Input
|
|
94
|
+
|
|
95
|
+
Use a search field in the top bar when search is active and benefits from filters or visible input. Include the side navigation opener when responsive layout has collapsed the side navigation.
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
const WithSearchInput = () => <TopBar
|
|
99
|
+
actions={topBarActions}
|
|
100
|
+
sideNavIsClosed
|
|
101
|
+
openSideNav={action('Open side navigation')}>(<>
|
|
102
|
+
<form>
|
|
103
|
+
<Flex gap={2}>
|
|
104
|
+
<Select
|
|
105
|
+
options={[
|
|
106
|
+
{
|
|
107
|
+
label: 'Customer Name / Number',
|
|
108
|
+
value: 'customer-name-number',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
label: 'Option 2',
|
|
112
|
+
value: 'option-2',
|
|
113
|
+
},
|
|
114
|
+
]}
|
|
115
|
+
/>
|
|
116
|
+
<TextField
|
|
117
|
+
aria-label="Search"
|
|
118
|
+
leadingElement={<Icon variant="search" />}
|
|
119
|
+
trailingElement={
|
|
120
|
+
<IconButton
|
|
121
|
+
aria-label="Clear Search"
|
|
122
|
+
variant="ghost"
|
|
123
|
+
icon={<Icon variant="cross" />}
|
|
124
|
+
onClick={action('Search button clicked')}
|
|
125
|
+
/>
|
|
126
|
+
}
|
|
127
|
+
onChange={() => {}}
|
|
128
|
+
placeholder="Search customers"
|
|
129
|
+
fullWidth
|
|
130
|
+
/>
|
|
131
|
+
</Flex>
|
|
132
|
+
</form>
|
|
133
|
+
</>)</TopBar>;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### With Action Menus
|
|
137
|
+
|
|
138
|
+
Use action menus in the center area when administrative context switching or environment controls need to remain available across pages. Keep menu labels visible so the options are scannable.
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
const WithActionMenus = () => <TopBar
|
|
142
|
+
actions={topBarActions}
|
|
143
|
+
sideNavIsClosed
|
|
144
|
+
openSideNav={action('Open side navigation')}>(<>
|
|
145
|
+
<form>
|
|
146
|
+
<Flex>
|
|
147
|
+
<Menu>
|
|
148
|
+
<MenuButton variant="ghost" aria-label="Admin">
|
|
149
|
+
Admin
|
|
150
|
+
</MenuButton>
|
|
151
|
+
<MenuList
|
|
152
|
+
items={[
|
|
153
|
+
{
|
|
154
|
+
id: 1,
|
|
155
|
+
label: 'Item 1',
|
|
156
|
+
link: {
|
|
157
|
+
href: '#',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
]}
|
|
161
|
+
/>
|
|
162
|
+
</Menu>
|
|
163
|
+
<Menu>
|
|
164
|
+
<MenuButton variant="ghost" aria-label="Admin Reports">
|
|
165
|
+
Admin Reports
|
|
166
|
+
</MenuButton>
|
|
167
|
+
<MenuList
|
|
168
|
+
items={[
|
|
169
|
+
{
|
|
170
|
+
id: 1,
|
|
171
|
+
label: 'Item 1',
|
|
172
|
+
link: {
|
|
173
|
+
href: '#',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
]}
|
|
177
|
+
/>
|
|
178
|
+
</Menu>
|
|
179
|
+
<Menu>
|
|
180
|
+
<MenuButton variant="ghost" aria-label="Staging">
|
|
181
|
+
Staging
|
|
182
|
+
</MenuButton>
|
|
183
|
+
<MenuList
|
|
184
|
+
items={[
|
|
185
|
+
{
|
|
186
|
+
id: 1,
|
|
187
|
+
label: 'Item 1',
|
|
188
|
+
link: {
|
|
189
|
+
href: '#',
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
]}
|
|
193
|
+
/>
|
|
194
|
+
</Menu>
|
|
195
|
+
<Menu>
|
|
196
|
+
<MenuButton variant="ghost" aria-label="Feature Flags">
|
|
197
|
+
Feature Flags
|
|
198
|
+
</MenuButton>
|
|
199
|
+
<MenuList
|
|
200
|
+
items={[
|
|
201
|
+
{
|
|
202
|
+
id: 1,
|
|
203
|
+
label: 'Item 1',
|
|
204
|
+
link: {
|
|
205
|
+
href: '#',
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
]}
|
|
209
|
+
/>
|
|
210
|
+
</Menu>
|
|
211
|
+
</Flex>
|
|
212
|
+
</form>
|
|
213
|
+
</>)</TopBar>;
|
|
214
|
+
```
|