@nexub/mcp 8.6.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.
@@ -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=&quot;{tone}&quot;</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)