@nexub/mcp 8.7.0 → 8.8.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/skill/references/components/app-shell.md +62 -0
- package/dist/skill/references/components/aspect-ratio.md +60 -0
- package/dist/skill/references/components/check-list.md +53 -0
- package/dist/skill/references/components/command-palette.md +108 -0
- package/dist/skill/references/components/container.md +50 -0
- package/dist/skill/references/components/context-menu.md +62 -0
- package/dist/skill/references/components/country-badge.md +49 -0
- package/dist/skill/references/components/dropdown-menu.md +99 -0
- package/dist/skill/references/components/file-upload.md +73 -0
- package/dist/skill/references/components/flag.md +38 -0
- package/dist/skill/references/components/form-error.md +46 -0
- package/dist/skill/references/components/keyboard-shortcut.md +55 -0
- package/dist/skill/references/components/logo.md +59 -0
- package/dist/skill/references/components/menubar.md +83 -0
- package/dist/skill/references/components/navigation-menu.md +78 -0
- package/dist/skill/references/components/page-header.md +64 -0
- package/dist/skill/references/components/section.md +43 -0
- package/dist/skill/references/components/sidebar.md +78 -0
- package/dist/skill/references/components/toolbar.md +72 -0
- package/dist/skill/references/components/top-nav.md +48 -0
- package/dist/skill/references/components/visually-hidden.md +40 -0
- package/dist/skill/references/components.md +23 -2
- package/dist/skill/references/tokens.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Form Error
|
|
2
|
+
|
|
3
|
+
An error message with an alert icon, announced when it appears.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Form & Input · Status: stable
|
|
6
|
+
- Import: `import { FormError } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/form-error
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
- A validation message under a field you lay out yourself
|
|
12
|
+
|
|
13
|
+
## When not to use
|
|
14
|
+
|
|
15
|
+
- Inside `FormField.Root`: use `FormField.Error`, which wires the ids for you
|
|
16
|
+
- Errors for a whole form: use the Error Summary pattern
|
|
17
|
+
|
|
18
|
+
## Props
|
|
19
|
+
|
|
20
|
+
| Prop | Type | Default | Description |
|
|
21
|
+
| --- | --- | --- | --- |
|
|
22
|
+
| `children` | `ReactNode` | | The message: say what went wrong and how to fix it. |
|
|
23
|
+
| `id` | `string` | | Point the control at it with `aria-describedby` so the message is read with the field. |
|
|
24
|
+
|
|
25
|
+
## Example: Under a field
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { FormError, Input, Label } from '@nexub/react';
|
|
29
|
+
|
|
30
|
+
export default function Example() {
|
|
31
|
+
return (
|
|
32
|
+
<div className="flex w-[280px] flex-col gap-1">
|
|
33
|
+
<Label htmlFor="fe-email">Email</Label>
|
|
34
|
+
<Input id="fe-email" type="email" defaultValue="jane@" aria-invalid aria-describedby="fe-email-error" />
|
|
35
|
+
<FormError id="fe-email-error">Enter an email address like name@example.com.</FormError>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Accessibility
|
|
42
|
+
|
|
43
|
+
- Roles: alert
|
|
44
|
+
- Has `role="alert"`, so it is announced when rendered. Render it only when there is an error.
|
|
45
|
+
|
|
46
|
+
Related: [form-field](form-field.md), [helper-text](helper-text.md)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Keyboard Shortcut
|
|
2
|
+
|
|
3
|
+
A key combination as `Kbd` keys joined by plus signs, read as one label.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Inline Primitives · Status: stable
|
|
6
|
+
- Import: `import { KeyboardShortcut } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/keyboard-shortcut
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `keys` | `string[]` | | The keys in order, e.g. `['⌘', 'K']`. Read as "⌘+K" (`aria-label`); pass your own `aria-label` for a spoken form like "Command K". |
|
|
14
|
+
|
|
15
|
+
## Example: Default
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { KeyboardShortcut } from '@nexub/react';
|
|
19
|
+
|
|
20
|
+
export default function Example() {
|
|
21
|
+
return (
|
|
22
|
+
<div className="flex flex-wrap items-center gap-4">
|
|
23
|
+
<KeyboardShortcut keys={['⌘', 'K']} aria-label="Command K" />
|
|
24
|
+
<KeyboardShortcut keys={['Ctrl', 'Shift', 'P']} />
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Example: In a menu
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { KeyboardShortcut, Text } from '@nexub/react';
|
|
34
|
+
|
|
35
|
+
const rows = [
|
|
36
|
+
{ label: 'Search', keys: ['⌘', 'K'], spoken: 'Command K' },
|
|
37
|
+
{ label: 'New project', keys: ['⌘', 'N'], spoken: 'Command N' },
|
|
38
|
+
{ label: 'Save', keys: ['⌘', 'S'], spoken: 'Command S' },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
export default function Example() {
|
|
42
|
+
return (
|
|
43
|
+
<ul className="flex w-[260px] flex-col gap-2">
|
|
44
|
+
{rows.map((r) => (
|
|
45
|
+
<li key={r.label} className="flex items-center justify-between">
|
|
46
|
+
<Text size="body-sm">{r.label}</Text>
|
|
47
|
+
<KeyboardShortcut keys={r.keys} aria-label={r.spoken} />
|
|
48
|
+
</li>
|
|
49
|
+
))}
|
|
50
|
+
</ul>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Related: [kbd](kbd.md), [command-palette](command-palette.md)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Logo
|
|
2
|
+
|
|
3
|
+
The Nexub mark and wordmark, with an optional product name.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Inline Primitives · Status: stable
|
|
6
|
+
- Import: `import { Logo } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/logo
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `variant` | `'full' \| 'icon' \| 'mark'` | | `full` = mark and wordmark; `icon` = the mark only. `mark` is the old name for `icon`. |
|
|
14
|
+
| `product` | `string` | | Product name after the wordmark, e.g. "Command Hub". Truncates in a narrow container. Ignored for `icon`. |
|
|
15
|
+
| `size` | `'sm' \| 'md' \| 'lg'` | | Height: 24, 32 or 40 px. |
|
|
16
|
+
| `tone` | `'default' \| 'inverse'` | | `inverse` is always white, for dark backgrounds or imagery in either theme. |
|
|
17
|
+
| `mark` | `'color' \| 'mono'` | | `color` = the official mark in brand colours; `mono` = `currentColor`. |
|
|
18
|
+
|
|
19
|
+
## Example: Variants
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { Logo } from '@nexub/react';
|
|
23
|
+
|
|
24
|
+
export default function Example() {
|
|
25
|
+
return (
|
|
26
|
+
<div className="flex flex-wrap items-center gap-6">
|
|
27
|
+
<Logo />
|
|
28
|
+
<Logo variant="icon" />
|
|
29
|
+
<Logo mark="mono" />
|
|
30
|
+
<span className="rounded-shape-container bg-[var(--color-inverse-surface)] p-3">
|
|
31
|
+
<Logo tone="inverse" />
|
|
32
|
+
</span>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Example: With a product name
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import { Logo } from '@nexub/react';
|
|
42
|
+
|
|
43
|
+
export default function Example() {
|
|
44
|
+
return (
|
|
45
|
+
<div className="flex flex-col items-start gap-4">
|
|
46
|
+
<Logo product="Command Hub" size="sm" />
|
|
47
|
+
<Logo product="Command Hub" />
|
|
48
|
+
<Logo product="Command Hub" size="lg" />
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Accessibility
|
|
55
|
+
|
|
56
|
+
- Roles: img
|
|
57
|
+
- Read as "Nexub", or "Nexub Command Hub" with `product`.
|
|
58
|
+
|
|
59
|
+
Related: [top-nav](top-nav.md), [sidebar](sidebar.md)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Menubar
|
|
2
|
+
|
|
3
|
+
A horizontal bar of menus, like a desktop app’s File / Edit / View, built on Radix.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Navigation · Status: stable
|
|
6
|
+
- Import: `import { Menubar } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/menubar
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
- Editors and tools with many commands grouped like a desktop app
|
|
12
|
+
|
|
13
|
+
## When not to use
|
|
14
|
+
|
|
15
|
+
- Site navigation: use `NavigationMenu` or `TopNav`
|
|
16
|
+
- A few icon actions: use `Toolbar`
|
|
17
|
+
|
|
18
|
+
## Props
|
|
19
|
+
|
|
20
|
+
| Prop | Type | Default | Description |
|
|
21
|
+
| --- | --- | --- | --- |
|
|
22
|
+
| `Menubar.Root` | `compound` | | The bar (`value`, `onValueChange`, `loop`). |
|
|
23
|
+
| `Menubar.Menu` | `compound` | | One menu: a trigger and its content. |
|
|
24
|
+
| `Menubar.Trigger` | `compound` | | The menu’s button in the bar. |
|
|
25
|
+
| `Menubar.Portal / Content` | `compound` | | Renders the floating menu in a portal (`sideOffset` default 8). |
|
|
26
|
+
| `Menubar.Item` | `compound` | | An action (`onSelect`, `disabled`). |
|
|
27
|
+
| `Menubar.CheckboxItem / RadioGroup / RadioItem` | `compound` | | Toggle and single-choice items. |
|
|
28
|
+
| `Menubar.Label / Group / Separator / Arrow` | `compound` | | Section heading, grouping, divider and an optional arrow. |
|
|
29
|
+
| `Menubar.Sub / SubTrigger / SubContent` | `compound` | | A nested submenu. |
|
|
30
|
+
|
|
31
|
+
## Example: Default
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { Menubar } from '@nexub/react';
|
|
35
|
+
|
|
36
|
+
export default function Example() {
|
|
37
|
+
return (
|
|
38
|
+
<Menubar.Root>
|
|
39
|
+
<Menubar.Menu>
|
|
40
|
+
<Menubar.Trigger>File</Menubar.Trigger>
|
|
41
|
+
<Menubar.Portal>
|
|
42
|
+
<Menubar.Content>
|
|
43
|
+
<Menubar.Item>New file</Menubar.Item>
|
|
44
|
+
<Menubar.Item>Open…</Menubar.Item>
|
|
45
|
+
<Menubar.Separator />
|
|
46
|
+
<Menubar.Item>Save</Menubar.Item>
|
|
47
|
+
</Menubar.Content>
|
|
48
|
+
</Menubar.Portal>
|
|
49
|
+
</Menubar.Menu>
|
|
50
|
+
<Menubar.Menu>
|
|
51
|
+
<Menubar.Trigger>Edit</Menubar.Trigger>
|
|
52
|
+
<Menubar.Portal>
|
|
53
|
+
<Menubar.Content>
|
|
54
|
+
<Menubar.Item>Undo</Menubar.Item>
|
|
55
|
+
<Menubar.Item>Redo</Menubar.Item>
|
|
56
|
+
<Menubar.Separator />
|
|
57
|
+
<Menubar.Item>Copy</Menubar.Item>
|
|
58
|
+
<Menubar.Item>Paste</Menubar.Item>
|
|
59
|
+
</Menubar.Content>
|
|
60
|
+
</Menubar.Portal>
|
|
61
|
+
</Menubar.Menu>
|
|
62
|
+
<Menubar.Menu>
|
|
63
|
+
<Menubar.Trigger>View</Menubar.Trigger>
|
|
64
|
+
<Menubar.Portal>
|
|
65
|
+
<Menubar.Content>
|
|
66
|
+
<Menubar.Item>Zoom in</Menubar.Item>
|
|
67
|
+
<Menubar.Item>Zoom out</Menubar.Item>
|
|
68
|
+
</Menubar.Content>
|
|
69
|
+
</Menubar.Portal>
|
|
70
|
+
</Menubar.Menu>
|
|
71
|
+
</Menubar.Root>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Accessibility
|
|
77
|
+
|
|
78
|
+
- Roles: menubar, menu, menuitem
|
|
79
|
+
- `Arrow Left / Right`: Moves between menus in the bar, and between open menus.
|
|
80
|
+
- `Enter / Space / Arrow Down`: Opens the focused menu.
|
|
81
|
+
- `Escape`: Closes the menu.
|
|
82
|
+
|
|
83
|
+
Related: [dropdown-menu](dropdown-menu.md), [toolbar](toolbar.md), [context-menu](context-menu.md)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Navigation Menu
|
|
2
|
+
|
|
3
|
+
Site navigation links with flyout panels, built on Radix.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Navigation · Status: stable
|
|
6
|
+
- Import: `import { NavigationMenu } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/navigation-menu
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
- Marketing or docs sites whose sections need a flyout of links
|
|
12
|
+
|
|
13
|
+
## When not to use
|
|
14
|
+
|
|
15
|
+
- Actions: use `DropdownMenu` or `Menubar`
|
|
16
|
+
- App navigation without flyouts: use `TopNav` or `Sidebar`
|
|
17
|
+
|
|
18
|
+
## Props
|
|
19
|
+
|
|
20
|
+
| Prop | Type | Default | Description |
|
|
21
|
+
| --- | --- | --- | --- |
|
|
22
|
+
| `NavigationMenu.Root` | `compound` | | The `<nav>` (`value`, `onValueChange`, `delayDuration`). Renders the panel viewport for you. |
|
|
23
|
+
| `NavigationMenu.List / Item` | `compound` | | The list of top-level entries. |
|
|
24
|
+
| `NavigationMenu.Trigger` | `compound` | | Opens the item’s panel on hover or click. |
|
|
25
|
+
| `NavigationMenu.Content` | `compound` | | The flyout panel for an item. |
|
|
26
|
+
| `NavigationMenu.Link` | `compound` | | A link, top-level or inside a panel (`href`, `active`, `asChild` for router links). |
|
|
27
|
+
| `NavigationMenu.Indicator` | `compound` | | Optional arrow under the open trigger. |
|
|
28
|
+
|
|
29
|
+
## Example: Default
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { NavigationMenu } from '@nexub/react';
|
|
33
|
+
|
|
34
|
+
const products = [
|
|
35
|
+
{ title: 'Analytics', body: 'Track key metrics in real time.' },
|
|
36
|
+
{ title: 'Dashboards', body: 'Build and share custom views.' },
|
|
37
|
+
{ title: 'Reports', body: 'Export and schedule reports.' },
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export default function Example() {
|
|
41
|
+
return (
|
|
42
|
+
<NavigationMenu.Root aria-label="Site">
|
|
43
|
+
<NavigationMenu.List>
|
|
44
|
+
<NavigationMenu.Item>
|
|
45
|
+
<NavigationMenu.Trigger>Products</NavigationMenu.Trigger>
|
|
46
|
+
<NavigationMenu.Content>
|
|
47
|
+
<ul className="grid w-[280px] gap-1 p-2">
|
|
48
|
+
{products.map((p) => (
|
|
49
|
+
<li key={p.title}>
|
|
50
|
+
<NavigationMenu.Link href="#">
|
|
51
|
+
<span className="block text-label-lg">{p.title}</span>
|
|
52
|
+
<span className="mt-1 block text-body-sm text-[var(--color-on-surface-muted)]">{p.body}</span>
|
|
53
|
+
</NavigationMenu.Link>
|
|
54
|
+
</li>
|
|
55
|
+
))}
|
|
56
|
+
</ul>
|
|
57
|
+
</NavigationMenu.Content>
|
|
58
|
+
</NavigationMenu.Item>
|
|
59
|
+
<NavigationMenu.Item>
|
|
60
|
+
<NavigationMenu.Link href="#">Pricing</NavigationMenu.Link>
|
|
61
|
+
</NavigationMenu.Item>
|
|
62
|
+
<NavigationMenu.Item>
|
|
63
|
+
<NavigationMenu.Link href="#">Docs</NavigationMenu.Link>
|
|
64
|
+
</NavigationMenu.Item>
|
|
65
|
+
</NavigationMenu.List>
|
|
66
|
+
</NavigationMenu.Root>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Accessibility
|
|
72
|
+
|
|
73
|
+
- `Tab`: Moves between top-level entries.
|
|
74
|
+
- `Enter / Space`: Opens or closes a panel.
|
|
75
|
+
- `Escape`: Closes the panel and returns focus to its trigger.
|
|
76
|
+
- Give `NavigationMenu.Root` an `aria-label` when the page has more than one navigation landmark.
|
|
77
|
+
|
|
78
|
+
Related: [top-nav](top-nav.md), [menubar](menubar.md)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Page Header
|
|
2
|
+
|
|
3
|
+
The top of a page: title, description, breadcrumb and actions.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Layout · Status: stable
|
|
6
|
+
- Import: `import { PageHeader } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/page-header
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `title` | `ReactNode` | | The page title. Truncates on one line. |
|
|
14
|
+
| `description` | `ReactNode` | | A line under the title. |
|
|
15
|
+
| `actions` | `ReactNode` | | Buttons on the end side; they wrap under the title on narrow screens. |
|
|
16
|
+
| `breadcrumb` | `ReactNode` | | A `Breadcrumb` above the title. |
|
|
17
|
+
| `level` | `1 \| 2 \| 3` | | Heading level of the title. Use 2 or 3 when the page already has an h1. |
|
|
18
|
+
|
|
19
|
+
## Example: Default
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { Button, PageHeader } from '@nexub/react';
|
|
23
|
+
|
|
24
|
+
export default function Example() {
|
|
25
|
+
return (
|
|
26
|
+
<PageHeader
|
|
27
|
+
className="w-full"
|
|
28
|
+
level={2}
|
|
29
|
+
title="Projects"
|
|
30
|
+
description="Everything your team is working on."
|
|
31
|
+
actions={<><Button variant="outlined">Import</Button><Button>New project</Button></>}
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Example: With breadcrumb
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { Breadcrumb, Button, PageHeader } from '@nexub/react';
|
|
41
|
+
|
|
42
|
+
export default function Example() {
|
|
43
|
+
return (
|
|
44
|
+
<PageHeader
|
|
45
|
+
className="w-full"
|
|
46
|
+
level={2}
|
|
47
|
+
breadcrumb={
|
|
48
|
+
<Breadcrumb.Root>
|
|
49
|
+
<Breadcrumb.List>
|
|
50
|
+
<Breadcrumb.Item><Breadcrumb.Link href="#">Projects</Breadcrumb.Link></Breadcrumb.Item>
|
|
51
|
+
<Breadcrumb.Separator />
|
|
52
|
+
<Breadcrumb.Item><Breadcrumb.Page>Billing service</Breadcrumb.Page></Breadcrumb.Item>
|
|
53
|
+
</Breadcrumb.List>
|
|
54
|
+
</Breadcrumb.Root>
|
|
55
|
+
}
|
|
56
|
+
title="Billing service"
|
|
57
|
+
description="Updated 2 hours ago"
|
|
58
|
+
actions={<Button variant="outlined">Settings</Button>}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Related: [breadcrumb](breadcrumb.md), [app-shell](app-shell.md), [heading](heading.md)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Section
|
|
2
|
+
|
|
3
|
+
A full-width page band with vertical padding and a background tone; put a `Container` inside.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Layout · Status: stable
|
|
6
|
+
- Import: `import { Section } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/section
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `paddingY` | `'sm' \| 'md' \| 'lg'` | | Vertical padding: 48, 80 or 128 px. |
|
|
14
|
+
| `tone` | `'default' \| 'subtle' \| 'muted' \| 'inverse'` | | Background: the surface, two container tints, or the inverse surface. |
|
|
15
|
+
| `asChild` | `boolean` | | Apply the classes to the child element instead of a `<section>`. |
|
|
16
|
+
|
|
17
|
+
## Example: Tones
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { Container, Section, Text } from '@nexub/react';
|
|
21
|
+
|
|
22
|
+
const tones = ['default', 'subtle', 'muted', 'inverse'] as const;
|
|
23
|
+
|
|
24
|
+
export default function Example() {
|
|
25
|
+
return (
|
|
26
|
+
<div className="w-full overflow-hidden rounded-shape-container border border-[var(--color-outline-variant)]">
|
|
27
|
+
{tones.map((tone) => (
|
|
28
|
+
<Section key={tone} tone={tone} paddingY="sm" aria-label={`${tone} tone`}>
|
|
29
|
+
<Container size="sm">
|
|
30
|
+
<Text size="body-sm" className="text-inherit">tone="{tone}"</Text>
|
|
31
|
+
</Container>
|
|
32
|
+
</Section>
|
|
33
|
+
))}
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Accessibility
|
|
40
|
+
|
|
41
|
+
- A `<section>` is a region landmark only when it has an accessible name: give it `aria-labelledby` pointing at its heading.
|
|
42
|
+
|
|
43
|
+
Related: [container](container.md), [box](box.md)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Sidebar
|
|
2
|
+
|
|
3
|
+
Vertical app navigation: a header, grouped items with icons, and a pinned footer. Collapses to icons.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Navigation · Status: stable
|
|
6
|
+
- Import: `import { Sidebar } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/sidebar
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `collapsed` | `boolean` | | Icon-only width. Labels stay for screen readers and show as a native tooltip. |
|
|
14
|
+
| `aria-label` | `string` | | Name of the nav landmark. Defaults to the localised "Sidebar". |
|
|
15
|
+
| `SidebarHeader status` | `ReactNode` | | Trailing element next to the logo (`Sidebar.Header` children), e.g. a `Badge`. Moves under the logo when they don’t fit. |
|
|
16
|
+
| `SidebarGroup label` | `string` | | Heading above a group of items. |
|
|
17
|
+
| `SidebarItem icon` | `ReactNode` | | Leading icon; the only thing shown when collapsed. |
|
|
18
|
+
| `SidebarItem active` | `boolean` | | Marks the current page (`aria-current="page"`). |
|
|
19
|
+
| `SidebarItem asChild` | `boolean` | | Use your router `<Link>` as the item; pass it as the only child. |
|
|
20
|
+
| `Sidebar.Separator / Footer` | `compound` | | A divider, and a footer that stays pinned while the items scroll. |
|
|
21
|
+
|
|
22
|
+
## Example: Default
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { Badge, Logo, Sidebar } from '@nexub/react';
|
|
26
|
+
import { BarChart3, Folder, Home, Settings, Users } from '@nexub/icons';
|
|
27
|
+
|
|
28
|
+
export default function Example() {
|
|
29
|
+
return (
|
|
30
|
+
<div className="h-[380px]">
|
|
31
|
+
<Sidebar.Root aria-label="Workspace" className="rounded-shape-container">
|
|
32
|
+
<Sidebar.Header status={<Badge variant="soft" size="sm">Beta</Badge>}>
|
|
33
|
+
<Logo size="sm" />
|
|
34
|
+
</Sidebar.Header>
|
|
35
|
+
<Sidebar.Group>
|
|
36
|
+
<Sidebar.Item href="#" icon={<Home size="sm" />} active>Overview</Sidebar.Item>
|
|
37
|
+
<Sidebar.Item href="#" icon={<Folder size="sm" />}>Projects</Sidebar.Item>
|
|
38
|
+
<Sidebar.Item href="#" icon={<BarChart3 size="sm" />}>Reports</Sidebar.Item>
|
|
39
|
+
</Sidebar.Group>
|
|
40
|
+
<Sidebar.Group label="Admin">
|
|
41
|
+
<Sidebar.Item href="#" icon={<Users size="sm" />}>Members</Sidebar.Item>
|
|
42
|
+
<Sidebar.Item href="#" icon={<Settings size="sm" />}>Settings</Sidebar.Item>
|
|
43
|
+
</Sidebar.Group>
|
|
44
|
+
<Sidebar.Footer className="text-body-sm text-[var(--color-on-surface-muted)]">v2.4.0</Sidebar.Footer>
|
|
45
|
+
</Sidebar.Root>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Example: Collapsed
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import * as React from 'react';
|
|
55
|
+
import { Button, Sidebar } from '@nexub/react';
|
|
56
|
+
import { BarChart3, Folder, Home, Settings } from '@nexub/icons';
|
|
57
|
+
|
|
58
|
+
export default function Example() {
|
|
59
|
+
const [collapsed, setCollapsed] = React.useState(true);
|
|
60
|
+
return (
|
|
61
|
+
<div className="flex h-[280px] items-start gap-4">
|
|
62
|
+
<Sidebar.Root aria-label="Workspace" collapsed={collapsed} className="rounded-shape-container">
|
|
63
|
+
<Sidebar.Group>
|
|
64
|
+
<Sidebar.Item href="#" icon={<Home size="sm" />} active>Overview</Sidebar.Item>
|
|
65
|
+
<Sidebar.Item href="#" icon={<Folder size="sm" />}>Projects</Sidebar.Item>
|
|
66
|
+
<Sidebar.Item href="#" icon={<BarChart3 size="sm" />}>Reports</Sidebar.Item>
|
|
67
|
+
<Sidebar.Item href="#" icon={<Settings size="sm" />}>Settings</Sidebar.Item>
|
|
68
|
+
</Sidebar.Group>
|
|
69
|
+
</Sidebar.Root>
|
|
70
|
+
<Button variant="outlined" onClick={() => setCollapsed((c) => !c)} aria-pressed={!collapsed}>
|
|
71
|
+
{collapsed ? 'Expand' : 'Collapse'}
|
|
72
|
+
</Button>
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Related: [app-shell](app-shell.md), [navigation-rail](navigation-rail.md), [top-nav](top-nav.md)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Toolbar
|
|
2
|
+
|
|
3
|
+
A row of buttons and toggles with one tab stop and arrow-key movement, built on Radix.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Actions · Status: stable
|
|
6
|
+
- Import: `import { Toolbar } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/toolbar
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `floating` | `boolean` | | A glass capsule for the control layer above content, e.g. editor or selection actions. |
|
|
14
|
+
| `placement` | `'bottom'` | | With `floating`: pin it to the bottom centre of the viewport. |
|
|
15
|
+
| `orientation / loop / dir` | `Radix Toolbar props` | | Arrow-key direction and wrapping. |
|
|
16
|
+
| `aria-label` | `string` | | Name the toolbar, e.g. "Text formatting". |
|
|
17
|
+
| `Toolbar.Button` | `compound` | | An action button. |
|
|
18
|
+
| `Toolbar.ToggleGroup / ToggleItem` | `compound` | | A set of toggles (`type="single" \| "multiple"`, `value`). Icon-only items need `aria-label`. |
|
|
19
|
+
| `Toolbar.Separator` | `compound` | | A divider between groups. |
|
|
20
|
+
|
|
21
|
+
## Example: Default
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { Toolbar } from '@nexub/react';
|
|
25
|
+
|
|
26
|
+
export default function Example() {
|
|
27
|
+
return (
|
|
28
|
+
<Toolbar.Root aria-label="Text formatting">
|
|
29
|
+
<Toolbar.ToggleGroup type="multiple" aria-label="Text style">
|
|
30
|
+
<Toolbar.ToggleItem value="bold" aria-label="Bold"><strong>B</strong></Toolbar.ToggleItem>
|
|
31
|
+
<Toolbar.ToggleItem value="italic" aria-label="Italic"><em>I</em></Toolbar.ToggleItem>
|
|
32
|
+
<Toolbar.ToggleItem value="underline" aria-label="Underline"><span className="underline">U</span></Toolbar.ToggleItem>
|
|
33
|
+
</Toolbar.ToggleGroup>
|
|
34
|
+
<Toolbar.Separator />
|
|
35
|
+
<Toolbar.ToggleGroup type="single" defaultValue="left" aria-label="Alignment">
|
|
36
|
+
<Toolbar.ToggleItem value="left" aria-label="Align left">L</Toolbar.ToggleItem>
|
|
37
|
+
<Toolbar.ToggleItem value="center" aria-label="Align centre">C</Toolbar.ToggleItem>
|
|
38
|
+
<Toolbar.ToggleItem value="right" aria-label="Align right">R</Toolbar.ToggleItem>
|
|
39
|
+
</Toolbar.ToggleGroup>
|
|
40
|
+
<Toolbar.Separator />
|
|
41
|
+
<Toolbar.Button>Clear formatting</Toolbar.Button>
|
|
42
|
+
</Toolbar.Root>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Example: Floating
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { Toolbar } from '@nexub/react';
|
|
51
|
+
import { Copy, Pencil, Trash2 } from '@nexub/icons';
|
|
52
|
+
|
|
53
|
+
export default function Example() {
|
|
54
|
+
return (
|
|
55
|
+
<Toolbar.Root floating aria-label="Selection">
|
|
56
|
+
<Toolbar.Button><Pencil size="sm" aria-hidden="true" />Edit</Toolbar.Button>
|
|
57
|
+
<Toolbar.Button><Copy size="sm" aria-hidden="true" />Duplicate</Toolbar.Button>
|
|
58
|
+
<Toolbar.Separator />
|
|
59
|
+
<Toolbar.Button><Trash2 size="sm" aria-hidden="true" />Delete</Toolbar.Button>
|
|
60
|
+
</Toolbar.Root>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Accessibility
|
|
66
|
+
|
|
67
|
+
- Roles: toolbar
|
|
68
|
+
- `Tab`: Moves into and out of the toolbar (one tab stop).
|
|
69
|
+
- `Arrow Left / Right`: Moves between controls.
|
|
70
|
+
- `Enter / Space`: Activates a button or toggles an item.
|
|
71
|
+
|
|
72
|
+
Related: [toggle-group](toggle-group.md), [button-group](button-group.md), [action-bar](action-bar.md)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Top Nav
|
|
2
|
+
|
|
3
|
+
A sticky app header: logo, main navigation links and trailing actions.
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Navigation · Status: stable
|
|
6
|
+
- Import: `import { TopNav } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/top-nav
|
|
8
|
+
|
|
9
|
+
## Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `surface` | `'solid' \| 'glass'` | | Glass material on the bar — see Foundations → Materials. |
|
|
14
|
+
| `scrollEdge` | `'soft' \| 'hard'` | | `soft` dissolves scrolling content under the bar (no divider); `hard` is an opaque band. Default: a divider. |
|
|
15
|
+
| `TopNav.Logo / Menu / Actions` | `compound` | | The logo slot, the `<nav>` of links (scrolls sideways on narrow screens) and the end-aligned actions. |
|
|
16
|
+
| `TopNavItem active` | `boolean` | | Marks the current page (`aria-current="page"`). |
|
|
17
|
+
| `TopNavItem asChild` | `boolean` | | Use your router `<Link>` instead of an `<a>`. |
|
|
18
|
+
|
|
19
|
+
## Example: Default
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { Avatar, IconButton, Logo, TopNav } from '@nexub/react';
|
|
23
|
+
import { Bell } from '@nexub/icons';
|
|
24
|
+
|
|
25
|
+
export default function Example() {
|
|
26
|
+
return (
|
|
27
|
+
<TopNav.Root className="static w-full">
|
|
28
|
+
<TopNav.Logo><Logo size="sm" /></TopNav.Logo>
|
|
29
|
+
<TopNav.Menu>
|
|
30
|
+
<TopNav.Item href="#" active>Overview</TopNav.Item>
|
|
31
|
+
<TopNav.Item href="#">Projects</TopNav.Item>
|
|
32
|
+
<TopNav.Item href="#">Reports</TopNav.Item>
|
|
33
|
+
</TopNav.Menu>
|
|
34
|
+
<TopNav.Actions>
|
|
35
|
+
<IconButton variant="ghost" label="Notifications"><Bell size="sm" /></IconButton>
|
|
36
|
+
<Avatar size="sm" name="Jane Smith" />
|
|
37
|
+
</TopNav.Actions>
|
|
38
|
+
</TopNav.Root>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Accessibility
|
|
44
|
+
|
|
45
|
+
- Roles: banner, navigation
|
|
46
|
+
- `TopNav.Root` is a `<header>`; `TopNav.Menu` is a `<nav>` named with the localised "Main navigation".
|
|
47
|
+
|
|
48
|
+
Related: [app-shell](app-shell.md), [sidebar](sidebar.md), [navigation-menu](navigation-menu.md), [logo](logo.md)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Visually Hidden
|
|
2
|
+
|
|
3
|
+
Content for screen readers only: hidden on screen but still read out (Radix).
|
|
4
|
+
|
|
5
|
+
- Package: `@nexub/react` · Category: Inline Primitives · Status: stable
|
|
6
|
+
- Import: `import { VisuallyHidden } from '@nexub/react';`
|
|
7
|
+
- Docs: https://nexub-ds-docs.pages.dev/components/visually-hidden
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
- Extra context a sighted user gets from layout, e.g. "(opens in a new tab)"
|
|
12
|
+
|
|
13
|
+
## When not to use
|
|
14
|
+
|
|
15
|
+
- Naming an icon button: `IconButton` takes a `label`
|
|
16
|
+
- Hiding content from everyone: use `hidden`
|
|
17
|
+
|
|
18
|
+
## Props
|
|
19
|
+
|
|
20
|
+
| Prop | Type | Default | Description |
|
|
21
|
+
| --- | --- | --- | --- |
|
|
22
|
+
| `children` | `ReactNode` | | The text to read out. |
|
|
23
|
+
| `asChild` | `boolean` | | Hide your own element instead of a `<span>`. |
|
|
24
|
+
|
|
25
|
+
## Example: Label an icon
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { Link, VisuallyHidden } from '@nexub/react';
|
|
29
|
+
|
|
30
|
+
export default function Example() {
|
|
31
|
+
return (
|
|
32
|
+
<Link href="https://example.com" target="_blank" rel="noreferrer">
|
|
33
|
+
Status page
|
|
34
|
+
<VisuallyHidden> (opens in a new tab)</VisuallyHidden>
|
|
35
|
+
</Link>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Related: [icon-button](icon-button.md)
|