@nexub/mcp 0.0.0-stage → 1.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.
Files changed (107) hide show
  1. package/README.md +40 -2
  2. package/dist/skill/SKILL.md +97 -0
  3. package/dist/skill/references/components/accordion.md +77 -0
  4. package/dist/skill/references/components/activity-feed.md +33 -0
  5. package/dist/skill/references/components/alert-dialog.md +48 -0
  6. package/dist/skill/references/components/alert.md +54 -0
  7. package/dist/skill/references/components/amount.md +34 -0
  8. package/dist/skill/references/components/auth-card.md +33 -0
  9. package/dist/skill/references/components/autocomplete.md +54 -0
  10. package/dist/skill/references/components/avatar-group.md +26 -0
  11. package/dist/skill/references/components/avatar.md +48 -0
  12. package/dist/skill/references/components/badge.md +71 -0
  13. package/dist/skill/references/components/banner.md +32 -0
  14. package/dist/skill/references/components/bento-grid.md +42 -0
  15. package/dist/skill/references/components/box.md +35 -0
  16. package/dist/skill/references/components/breadcrumb.md +61 -0
  17. package/dist/skill/references/components/button-group.md +43 -0
  18. package/dist/skill/references/components/button.md +118 -0
  19. package/dist/skill/references/components/callout.md +27 -0
  20. package/dist/skill/references/components/card.md +74 -0
  21. package/dist/skill/references/components/checkbox-card.md +49 -0
  22. package/dist/skill/references/components/checkbox.md +51 -0
  23. package/dist/skill/references/components/chip.md +35 -0
  24. package/dist/skill/references/components/citation.md +61 -0
  25. package/dist/skill/references/components/code-inline.md +25 -0
  26. package/dist/skill/references/components/collapsible.md +71 -0
  27. package/dist/skill/references/components/combobox.md +40 -0
  28. package/dist/skill/references/components/conversation.md +100 -0
  29. package/dist/skill/references/components/data-table.md +70 -0
  30. package/dist/skill/references/components/date-picker.md +56 -0
  31. package/dist/skill/references/components/date-range-picker.md +48 -0
  32. package/dist/skill/references/components/dialog.md +57 -0
  33. package/dist/skill/references/components/drawer.md +79 -0
  34. package/dist/skill/references/components/empty-state.md +77 -0
  35. package/dist/skill/references/components/error-state.md +37 -0
  36. package/dist/skill/references/components/error-summary.md +71 -0
  37. package/dist/skill/references/components/eyebrow-chip.md +28 -0
  38. package/dist/skill/references/components/filter-bar.md +36 -0
  39. package/dist/skill/references/components/filter-chip.md +26 -0
  40. package/dist/skill/references/components/flex.md +47 -0
  41. package/dist/skill/references/components/form-field.md +26 -0
  42. package/dist/skill/references/components/gradient-divider.md +13 -0
  43. package/dist/skill/references/components/grid.md +39 -0
  44. package/dist/skill/references/components/heading.md +46 -0
  45. package/dist/skill/references/components/helper-text.md +31 -0
  46. package/dist/skill/references/components/hover-card.md +34 -0
  47. package/dist/skill/references/components/icon-button.md +44 -0
  48. package/dist/skill/references/components/info-list.md +25 -0
  49. package/dist/skill/references/components/input.md +78 -0
  50. package/dist/skill/references/components/kbd.md +42 -0
  51. package/dist/skill/references/components/label.md +37 -0
  52. package/dist/skill/references/components/link.md +38 -0
  53. package/dist/skill/references/components/list-detail.md +27 -0
  54. package/dist/skill/references/components/media-card.md +61 -0
  55. package/dist/skill/references/components/message-bubble.md +68 -0
  56. package/dist/skill/references/components/money-input.md +30 -0
  57. package/dist/skill/references/components/motion-collapse.md +57 -0
  58. package/dist/skill/references/components/motion-fade.md +64 -0
  59. package/dist/skill/references/components/motion-scale.md +54 -0
  60. package/dist/skill/references/components/motion-slide.md +60 -0
  61. package/dist/skill/references/components/navigation-rail.md +29 -0
  62. package/dist/skill/references/components/notification-item.md +29 -0
  63. package/dist/skill/references/components/number-input.md +30 -0
  64. package/dist/skill/references/components/number-ticker.md +44 -0
  65. package/dist/skill/references/components/pagination.md +52 -0
  66. package/dist/skill/references/components/password-input.md +28 -0
  67. package/dist/skill/references/components/plan-card.md +34 -0
  68. package/dist/skill/references/components/popover.md +53 -0
  69. package/dist/skill/references/components/progress.md +39 -0
  70. package/dist/skill/references/components/prompt-input.md +95 -0
  71. package/dist/skill/references/components/radio-card.md +83 -0
  72. package/dist/skill/references/components/radio-group.md +57 -0
  73. package/dist/skill/references/components/rating.md +39 -0
  74. package/dist/skill/references/components/scroll-area.md +57 -0
  75. package/dist/skill/references/components/search-input.md +22 -0
  76. package/dist/skill/references/components/segmented-control.md +44 -0
  77. package/dist/skill/references/components/select.md +43 -0
  78. package/dist/skill/references/components/separator.md +30 -0
  79. package/dist/skill/references/components/settings-section.md +31 -0
  80. package/dist/skill/references/components/sheet.md +51 -0
  81. package/dist/skill/references/components/skeleton.md +38 -0
  82. package/dist/skill/references/components/slider.md +31 -0
  83. package/dist/skill/references/components/spinner.md +32 -0
  84. package/dist/skill/references/components/split-button.md +43 -0
  85. package/dist/skill/references/components/stack.md +35 -0
  86. package/dist/skill/references/components/stat-card.md +50 -0
  87. package/dist/skill/references/components/status-pill.md +37 -0
  88. package/dist/skill/references/components/step-indicator.md +29 -0
  89. package/dist/skill/references/components/streaming-text.md +53 -0
  90. package/dist/skill/references/components/switch.md +36 -0
  91. package/dist/skill/references/components/table.md +89 -0
  92. package/dist/skill/references/components/tabs.md +51 -0
  93. package/dist/skill/references/components/tag.md +25 -0
  94. package/dist/skill/references/components/text-gradient.md +30 -0
  95. package/dist/skill/references/components/text.md +45 -0
  96. package/dist/skill/references/components/textarea.md +40 -0
  97. package/dist/skill/references/components/thinking-indicator.md +50 -0
  98. package/dist/skill/references/components/toast.md +141 -0
  99. package/dist/skill/references/components/toggle-group.md +35 -0
  100. package/dist/skill/references/components/toggle.md +32 -0
  101. package/dist/skill/references/components/tooltip.md +34 -0
  102. package/dist/skill/references/components/user-card.md +27 -0
  103. package/dist/skill/references/components.md +192 -0
  104. package/dist/skill/references/tokens.md +234 -0
  105. package/package.json +41 -3
  106. package/src/cli.js +9 -0
  107. package/src/server.js +98 -0
@@ -0,0 +1,71 @@
1
+ # Collapsible
2
+
3
+ Toggle visibility of content with smooth animation.
4
+
5
+ - Package: `@nexub/react` · Category: Disclosure · Status: stable
6
+ - Import: `import { Collapsible } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/collapsible
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `Collapsible.Root open` | `boolean` | | Controlled open state. |
14
+ | `Collapsible.Root defaultOpen` | `boolean` | `false` | Whether the collapsible is open by default (uncontrolled). |
15
+ | `Collapsible.Root onOpenChange` | `(open: boolean) => void` | | Callback fired when the open state changes. |
16
+ | `Collapsible.Root disabled` | `boolean` | `false` | Prevents the user from toggling the collapsible. |
17
+ | `Collapsible.Trigger asChild` | `boolean` | `false` | Merges props onto the immediate child element (Radix Slot). |
18
+ | `Collapsible.Content forceMount` | `boolean` | `false` | Keeps the content mounted in the DOM even when closed. |
19
+
20
+ ## Example: Default
21
+
22
+ ```tsx
23
+ <Collapsible.Root>
24
+ <Collapsible.Trigger asChild>
25
+ <Button variant="outline">Toggle details</Button>
26
+ </Collapsible.Trigger>
27
+ <Collapsible.Content>
28
+ <div style={{ paddingTop: '12px', color: 'var(--color-text-secondary)' }}>
29
+ Hidden content revealed on toggle.
30
+ </div>
31
+ </Collapsible.Content>
32
+ </Collapsible.Root>
33
+ ```
34
+
35
+ ## Example: Controlled
36
+
37
+ ```tsx
38
+ function ControlledExample() {
39
+ const [open, setOpen] = React.useState(false);
40
+ return (
41
+ <Collapsible.Root open={open} onOpenChange={setOpen}>
42
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
43
+ <span style={{ fontWeight: 500 }}>Advanced settings</span>
44
+ <Collapsible.Trigger asChild>
45
+ <IconButton
46
+ aria-label={open ? 'Collapse' : 'Expand'}
47
+ variant="ghost"
48
+ size="sm"
49
+ />
50
+ </Collapsible.Trigger>
51
+ </div>
52
+ <Collapsible.Content>
53
+ <div style={{ paddingTop: '12px', display: 'flex', flexDirection: 'column', gap: '12px' }}>
54
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
55
+ <Switch id="notif" />
56
+ <Label htmlFor="notif">Enable notifications</Label>
57
+ </div>
58
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
59
+ <Switch id="autosave" />
60
+ <Label htmlFor="autosave">Auto-save drafts</Label>
61
+ </div>
62
+ <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
63
+ <Switch id="tooltips" />
64
+ <Label htmlFor="tooltips">Show tooltips</Label>
65
+ </div>
66
+ </div>
67
+ </Collapsible.Content>
68
+ </Collapsible.Root>
69
+ );
70
+ }
71
+ ```
@@ -0,0 +1,40 @@
1
+ # Combobox
2
+
3
+ Command-palette style searchable dropdown built on cmdk.
4
+
5
+ - Package: `@nexub/react` · Category: Form Controls · Status: stable
6
+ - Import: `import { Combobox } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/combobox
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `Combobox.Root` | `compound` | | Root cmdk command container. |
14
+ | `Combobox.Input` | `compound` | | Search input that filters the list. |
15
+ | `Combobox.List` | `compound` | | Scrollable list container for groups and items. |
16
+ | `Combobox.Group` | `compound` | | Labeled group of items within the list. |
17
+ | `Combobox.Item` | `compound` | | Individual selectable option. |
18
+ | `Combobox.Empty` | `compound` | | Content shown when no items match the search query. |
19
+ | `Combobox.Separator` | `compound` | | Visual separator between groups or items. |
20
+
21
+ ## Example: Default
22
+
23
+ ```tsx
24
+ <Combobox.Root>
25
+ <Combobox.Input placeholder="Search..." />
26
+ <Combobox.List>
27
+ <Combobox.Empty>No results found.</Combobox.Empty>
28
+ <Combobox.Group heading="Frameworks">
29
+ <Combobox.Item value="react">React</Combobox.Item>
30
+ <Combobox.Item value="vue">Vue</Combobox.Item>
31
+ <Combobox.Item value="svelte">Svelte</Combobox.Item>
32
+ </Combobox.Group>
33
+ <Combobox.Separator />
34
+ <Combobox.Group heading="Languages">
35
+ <Combobox.Item value="typescript">TypeScript</Combobox.Item>
36
+ <Combobox.Item value="rust">Rust</Combobox.Item>
37
+ </Combobox.Group>
38
+ </Combobox.List>
39
+ </Combobox.Root>
40
+ ```
@@ -0,0 +1,100 @@
1
+ # Conversation
2
+
3
+ Chat layout: a scrolling message list that follows new content, with a sticky composer underneath.
4
+
5
+ - Package: `@nexub/patterns` · Category: AI · Status: beta
6
+ - Import: `import { Conversation } from '@nexub/patterns';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/patterns/conversation
8
+
9
+ ## When to use
10
+
11
+ - A full chat or assistant view: messages above, composer below.
12
+
13
+ ## When not to use
14
+
15
+ - A single question and answer: a PromptInput and a MessageBubble in normal flow are enough.
16
+ - Comment threads that don’t follow new content: use ActivityFeed.
17
+
18
+ ## Props
19
+
20
+ | Prop | Type | Default | Description |
21
+ | --- | --- | --- | --- |
22
+ | `children` | `ReactNode` | | The messages, usually MessageBubbles. |
23
+ | `composer` | `ReactNode` | | Sticky slot under the list, usually a PromptInput. |
24
+ | `autoScroll` | `boolean` | `true` | Follow new content while the reader is at the bottom. Scrolling up stops following and shows "Jump to latest". |
25
+ | `announce` | `boolean` | `false` | Make the list a polite `role="log"`. Only for whole-message updates: with token streaming it announces every chunk. |
26
+ | `messages` | `Partial<ConversationMessages>` | | Overrides for `jumpToLatest` and `conversation`. |
27
+
28
+ ## Example: Mini chat
29
+
30
+ Send a message: it shows Thinking, then streams a cited reply. Stop or Escape ends the reply early.
31
+
32
+ ```tsx
33
+ type Message = { id: number; from: 'user' | 'assistant'; text: string };
34
+
35
+ const REPLY = 'Air-source heat pumps work in most homes and run at roughly the cost of gas.';
36
+ const SOURCE = { title: 'Choosing a heat pump', url: 'https://example.com/guides/heat-pumps' };
37
+
38
+ function Chat() {
39
+ const [messages, setMessages] = React.useState<Message[]>([]);
40
+ const [status, setStatus] = React.useState<'idle' | 'submitting' | 'streaming'>('idle');
41
+ const timer = React.useRef<ReturnType<typeof setTimeout>>();
42
+
43
+ function send(text: string) {
44
+ const id = Date.now();
45
+ setMessages((m) => [...m, { id, from: 'user', text }, { id: id + 1, from: 'assistant', text: '' }]);
46
+ setStatus('submitting');
47
+ timer.current = setTimeout(() => {
48
+ setStatus('streaming');
49
+ stream(id + 1, 0);
50
+ }, 800);
51
+ }
52
+
53
+ function stream(id: number, length: number) {
54
+ setMessages((m) => m.map((msg) => (msg.id === id ? { ...msg, text: REPLY.slice(0, length) } : msg)));
55
+ if (length >= REPLY.length) return setStatus('idle');
56
+ timer.current = setTimeout(() => stream(id, length + 4), 50);
57
+ }
58
+
59
+ function stop() {
60
+ clearTimeout(timer.current);
61
+ setStatus('idle');
62
+ }
63
+
64
+ const last = messages[messages.length - 1];
65
+
66
+ return (
67
+ <Conversation
68
+ style={{ height: 420 }}
69
+ composer={<PromptInput placeholder="Ask about heat pumps" status={status} onSubmit={send} onStop={stop} />}
70
+ >
71
+ {messages.map((msg) =>
72
+ msg.from === 'user' ? (
73
+ <MessageBubble key={msg.id} from="user">{msg.text}</MessageBubble>
74
+ ) : (
75
+ <MessageBubble key={msg.id} from="assistant">
76
+ {status === 'submitting' && msg === last ? (
77
+ <ThinkingIndicator />
78
+ ) : (
79
+ <>
80
+ <StreamingText as="span" text={msg.text} streaming={status === 'streaming' && msg === last} />
81
+ {msg.text === REPLY && <Citation index={1} source={SOURCE} />}
82
+ </>
83
+ )}
84
+ </MessageBubble>
85
+ ),
86
+ )}
87
+ </Conversation>
88
+ );
89
+ }
90
+ ```
91
+
92
+ ## Accessibility
93
+
94
+ - Roles: region (default) or log (with `announce`)
95
+ - `Tab`: The message list is focusable so keyboard users can scroll it.
96
+ - Keep focus in the composer while a reply streams; don’t move it to the new message.
97
+ - The list is named "Conversation". Leave `announce` off while streaming tokens and announce the finished reply once instead.
98
+ - With reduced motion, "Jump to latest" scrolls instantly.
99
+
100
+ Related: [message-bubble](message-bubble.md), [prompt-input](prompt-input.md), [streaming-text](streaming-text.md)
@@ -0,0 +1,70 @@
1
+ # Data Table
2
+
3
+ Feature-rich data table with sorting and row selection powered by TanStack Table.
4
+
5
+ - Package: `@nexub/react` · Category: Data Display · Status: stable
6
+ - Import: `import { DataTable } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/data-table
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `columns` (required) | `DataTableColumn<TData>[]` | | TanStack Table column definitions (`DataTableColumn` is exported from @nexub/react). Set `meta: { align: 'end' }` for numeric columns; headers, sort buttons and cells follow it. |
14
+ | `caption` | `ReactNode` | | Names the table for assistive tech (and its scroll region). Shown below the table; add `captionHidden` to keep it screen-reader only. |
15
+ | `data` (required) | `TData[]` | | Array of row data objects to render. |
16
+ | `enableSorting` | `boolean` | `false` | Enables click-to-sort on column headers. |
17
+ | `enableRowSelection` | `boolean` | `false` | Adds a checkbox column for row selection. |
18
+ | `pagination.pageSize` | `number` | `10` | Number of rows per page when pagination is active. |
19
+ | `pagination.pageIndex` | `number` | `0` | Zero-based index of the currently visible page. |
20
+ | `onRowSelectionChange` | `(selectedRows: TData[]) => void` | | Callback invoked when the row selection state changes. |
21
+ | `loading` | `boolean` | `false` | Shows a skeleton loading state over the table body. |
22
+ | `emptyState` | `React.ReactNode` | | Custom content rendered when the data array is empty. |
23
+
24
+ ## Example: Default
25
+
26
+ ```tsx
27
+ const columns = [
28
+ { accessorKey: 'name', header: 'Name' },
29
+ { accessorKey: 'role', header: 'Role' },
30
+ { accessorKey: 'status', header: 'Status' },
31
+ { accessorKey: 'joined', header: 'Joined' },
32
+ ];
33
+
34
+ const data = [
35
+ { name: 'Alice Johnson', role: 'Admin', status: 'Active', joined: '2024-01-10' },
36
+ { name: 'Bob Martinez', role: 'Editor', status: 'Pending', joined: '2024-03-22' },
37
+ { name: 'Carol Smith', role: 'Viewer', status: 'Inactive', joined: '2024-06-05' },
38
+ { name: 'David Lee', role: 'Editor', status: 'Active', joined: '2024-09-17' },
39
+ { name: 'Eva Chen', role: 'Admin', status: 'Active', joined: '2025-01-03' },
40
+ ];
41
+
42
+ <DataTable columns={columns} data={data} />
43
+ ```
44
+
45
+ ## Example: With sorting
46
+
47
+ ```tsx
48
+ const columns = [
49
+ { accessorKey: 'name', header: 'Name', enableSorting: true },
50
+ { accessorKey: 'role', header: 'Role', enableSorting: true },
51
+ { accessorKey: 'status', header: 'Status', enableSorting: true },
52
+ { accessorKey: 'joined', header: 'Joined', enableSorting: true },
53
+ ];
54
+
55
+ const data = [
56
+ { name: 'Alice Johnson', role: 'Admin', status: 'Active', joined: '2024-01-10' },
57
+ { name: 'Bob Martinez', role: 'Editor', status: 'Pending', joined: '2024-03-22' },
58
+ { name: 'Carol Smith', role: 'Viewer', status: 'Inactive', joined: '2024-06-05' },
59
+ { name: 'David Lee', role: 'Editor', status: 'Active', joined: '2024-09-17' },
60
+ { name: 'Eva Chen', role: 'Admin', status: 'Active', joined: '2025-01-03' },
61
+ ];
62
+
63
+ <DataTable
64
+ columns={columns}
65
+ data={data}
66
+ enableSorting
67
+ enableRowSelection
68
+ pagination={{ pageSize: 5, pageIndex: 0 }}
69
+ />
70
+ ```
@@ -0,0 +1,56 @@
1
+ # Date Picker
2
+
3
+ Calendar date picker with text input.
4
+
5
+ - Package: `@nexub/react` · Category: Form & Input · Status: stable
6
+ - Import: `import { DatePicker } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/date-picker
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `value` | `Date \| undefined` | | Controlled selected date value. |
14
+ | `onChange` | `(date: Date \| undefined) => void` | | Callback invoked when the selected date changes. |
15
+ | `locale` | `Locale (date-fns)` | | Month and weekday names, week start and the trigger format. Defaults to the NexubProvider `dateLocale`; the calendar also follows the provider `dir`, so arrows flip in RTL. |
16
+ | `placeholder` | `string` | `'Pick a date'` | Placeholder text displayed in the input when no date is selected. |
17
+ | `disabled` | `boolean` | `false` | Disables the date picker input and calendar. |
18
+ | `minDate` | `Date` | | Earliest selectable date. Dates before this are greyed out. |
19
+ | `maxDate` | `Date` | | Latest selectable date. Dates after this are greyed out. |
20
+ | `format` | `string` | `'dd/MM/yyyy'` | Date format string for the text input display. |
21
+ | `aria-label` | `string` | | Field name for screen readers; the selected value is appended. |
22
+ | `id` | `string` | | Id for the trigger button, e.g. to pair with a <label htmlFor>. |
23
+ | `error` | `string` | | Error message displayed below the input. |
24
+
25
+ ## Example: Default
26
+
27
+ ```tsx
28
+ <DatePicker placeholder="Select a date…" />
29
+ ```
30
+
31
+ ## Example: With value
32
+
33
+ ```tsx
34
+ function ControlledDatePicker() {
35
+ const [date, setDate] = React.useState(new Date('2026-01-15'));
36
+ return (
37
+ <DatePicker
38
+ aria-label="Appointment date"
39
+ value={date}
40
+ onChange={setDate}
41
+ placeholder="Select a date…"
42
+ />
43
+ );
44
+ }
45
+ ```
46
+
47
+ ## Example: With constraints
48
+
49
+ ```tsx
50
+ <DatePicker
51
+ aria-label="Schedule for"
52
+ placeholder="Select a future date…"
53
+ minDate={new Date()}
54
+ maxDate={new Date(Date.now() + 90 * 24 * 60 * 60 * 1000)}
55
+ />
56
+ ```
@@ -0,0 +1,48 @@
1
+ # Date Range Picker
2
+
3
+ Dual-calendar date range selector.
4
+
5
+ - Package: `@nexub/react` · Category: Form & Input · Status: stable
6
+ - Import: `import { DateRangePicker } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/date-range-picker
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `value` | `{ from: Date \| undefined; to: Date \| undefined }` | | Controlled date range value. |
14
+ | `onChange` | `(range: { from: Date \| undefined; to: Date \| undefined }) => void` | | Callback invoked when the selected range changes. |
15
+ | `locale` | `Locale (date-fns)` | | Month and weekday names, week start and the trigger format. Defaults to the NexubProvider `dateLocale`; the calendar also follows the provider `dir`, so arrows flip in RTL. |
16
+ | `placeholder` | `string` | `'Select date range'` | Placeholder text shown in the trigger input when no range is selected. |
17
+ | `disabled` | `boolean` | `false` | Disables the trigger input and calendar popover. |
18
+ | `minDate` | `Date` | | Earliest selectable date. Dates before this are greyed out. |
19
+ | `maxDate` | `Date` | | Latest selectable date. Dates after this are greyed out. |
20
+ | `numberOfMonths` | `number` | `2` | Number of months to display in the calendar popover. |
21
+ | `aria-label` | `string` | | Field name for screen readers; the selected value is appended. |
22
+ | `id` | `string` | | Id for the trigger button, e.g. to pair with a <label htmlFor>. |
23
+ | `error` | `string` | | Error message displayed below the input. |
24
+
25
+ ## Example: Default
26
+
27
+ ```tsx
28
+ <DateRangePicker placeholder="Select date range…" />
29
+ ```
30
+
31
+ ## Example: Controlled
32
+
33
+ ```tsx
34
+ function ControlledDateRangePicker() {
35
+ const [range, setRange] = React.useState({
36
+ from: new Date('2026-04-01'),
37
+ to: new Date('2026-04-14'),
38
+ });
39
+ return (
40
+ <DateRangePicker
41
+ aria-label="Booking period"
42
+ value={range}
43
+ onChange={setRange}
44
+ placeholder="Select date range…"
45
+ />
46
+ );
47
+ }
48
+ ```
@@ -0,0 +1,57 @@
1
+ # Dialog
2
+
3
+ Modal dialog built on Radix UI. Fully accessible with focus trapping and ARIA roles.
4
+
5
+ - Package: `@nexub/react` · Category: Overlays · Status: stable
6
+ - Import: `import { Dialog } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/dialog
8
+
9
+ ## When to use
10
+
11
+ - Confirming a destructive or irreversible action
12
+ - Collecting a small form without leaving the current page
13
+ - Displaying critical information that requires acknowledgement
14
+ - Previewing content before taking an action
15
+
16
+ ## When not to use
17
+
18
+ - Long multi-step flows — use a Drawer or a dedicated page instead
19
+ - Quick contextual info — use a Tooltip or Popover
20
+ - Non-blocking side panels — use Sheet or Drawer
21
+ - Stacking multiple dialogs — always limit to one at a time
22
+
23
+ ## Props
24
+
25
+ | Prop | Type | Default | Description |
26
+ | --- | --- | --- | --- |
27
+ | `open` | `boolean` | | Controlled open state. |
28
+ | `onOpenChange` | `(open: boolean) => void` | | Callback when open state changes. |
29
+ | `defaultOpen` | `boolean` | `false` | Uncontrolled initial open state. |
30
+ | `surface` | `'solid' \| 'glass'` | `'solid'` | Glass material on Dialog.Content — see Foundations → Materials. |
31
+
32
+ ## Example: Default
33
+
34
+ ```tsx
35
+ <Dialog.Root>
36
+ <Dialog.Trigger asChild>
37
+ <Button>Open Dialog</Button>
38
+ </Dialog.Trigger>
39
+ <Dialog.Portal>
40
+ <Dialog.Overlay />
41
+ <Dialog.Content>
42
+ <Dialog.Header>
43
+ <Dialog.Title>Edit profile</Dialog.Title>
44
+ <Dialog.Description>
45
+ Make changes to your profile here.
46
+ </Dialog.Description>
47
+ </Dialog.Header>
48
+ <Dialog.Footer>
49
+ <Dialog.Close asChild>
50
+ <Button variant="outline">Cancel</Button>
51
+ </Dialog.Close>
52
+ <Button>Save changes</Button>
53
+ </Dialog.Footer>
54
+ </Dialog.Content>
55
+ </Dialog.Portal>
56
+ </Dialog.Root>
57
+ ```
@@ -0,0 +1,79 @@
1
+ # Drawer
2
+
3
+ Slide-in panel from any edge of the screen.
4
+
5
+ - Package: `@nexub/react` · Category: Overlays · Status: stable
6
+ - Import: `import { Drawer } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/drawer
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `Drawer.Root` | `compound` | | Root provider that manages open/close state. |
14
+ | `Drawer.Trigger` | `compound` | | Element that opens the drawer. |
15
+ | `Drawer.Portal` | `compound` | | Portals the overlay and content into the document body. |
16
+ | `Drawer.Overlay` | `compound` | | Dimmed backdrop rendered behind the drawer. |
17
+ | `Drawer.Content` | `compound` | | The drawer panel. Accepts a side prop. |
18
+ | `scrollLock` | `'style' \| 'class'` | | On Drawer.Root. How page scroll is locked while open. `class` adds a class from @nexub/themes/base instead of injecting a <style> tag, so it works under a strict CSP (style-src 'self'). Default `style`. |
19
+ | `side` | `'left' \| 'right' \| 'top' \| 'bottom'` | | Edge of the screen from which the drawer slides in. |
20
+ | `Drawer.Header` | `compound` | | Header section of the drawer panel. |
21
+ | `Drawer.Footer` | `compound` | | Footer section of the drawer panel. |
22
+ | `Drawer.Title` | `compound` | | Accessible title for the drawer. |
23
+ | `Drawer.Description` | `compound` | | Supporting description text for the drawer. |
24
+ | `Drawer.Close` | `compound` | | Element that closes the drawer. |
25
+ | `surface` | `'solid' \| 'glass'` | `'solid'` | Glass material on Drawer.Content — see Foundations → Materials. |
26
+
27
+ ## Example: Default
28
+
29
+ ```tsx
30
+ <Drawer.Root>
31
+ <Drawer.Trigger asChild>
32
+ <Button variant="outline">Open drawer</Button>
33
+ </Drawer.Trigger>
34
+ <Drawer.Portal>
35
+ <Drawer.Overlay />
36
+ <Drawer.Content side="right">
37
+ <Drawer.Header>
38
+ <Drawer.Title>Edit profile</Drawer.Title>
39
+ <Drawer.Description>Make changes to your profile settings.</Drawer.Description>
40
+ </Drawer.Header>
41
+ <div style={{ padding: '16px', flex: 1 }}>
42
+ <Text size="body-sm" tone="secondary">Drawer body content goes here.</Text>
43
+ </div>
44
+ <Drawer.Footer>
45
+ <Drawer.Close asChild>
46
+ <Button variant="outline">Cancel</Button>
47
+ </Drawer.Close>
48
+ <Button variant="primary">Save changes</Button>
49
+ </Drawer.Footer>
50
+ </Drawer.Content>
51
+ </Drawer.Portal>
52
+ </Drawer.Root>
53
+ ```
54
+
55
+ ## Example: Bottom sheet
56
+
57
+ ```tsx
58
+ <Drawer.Root>
59
+ <Drawer.Trigger asChild>
60
+ <Button variant="outline">Open bottom sheet</Button>
61
+ </Drawer.Trigger>
62
+ <Drawer.Portal>
63
+ <Drawer.Overlay />
64
+ <Drawer.Content side="bottom">
65
+ <Drawer.Header>
66
+ <Drawer.Title>Share</Drawer.Title>
67
+ </Drawer.Header>
68
+ <div style={{ padding: '16px' }}>
69
+ <Text size="body-sm">Choose how you would like to share this item.</Text>
70
+ </div>
71
+ <Drawer.Footer>
72
+ <Drawer.Close asChild>
73
+ <Button variant="outline" fullWidth>Cancel</Button>
74
+ </Drawer.Close>
75
+ </Drawer.Footer>
76
+ </Drawer.Content>
77
+ </Drawer.Portal>
78
+ </Drawer.Root>
79
+ ```
@@ -0,0 +1,77 @@
1
+ # Empty State
2
+
3
+ Placeholder UI shown when a list or page has no content.
4
+
5
+ - Package: `@nexub/react` · Category: Data Display · Status: stable
6
+ - Import: `import { EmptyState } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/empty-state
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `EmptyState.Root layout` | `'centered' \| 'inline'` | `'centered'` | "centered" stacks content vertically in the middle of its container; "inline" aligns content to the start. |
14
+ | `EmptyState.Illustration children` | `React.ReactNode` | | Icon or SVG illustration to render above the title. |
15
+ | `EmptyState.Title children` (required) | `React.ReactNode` | | Primary heading text for the empty state. |
16
+ | `EmptyState.Description children` | `React.ReactNode` | | Supporting text providing more context or guidance. |
17
+ | `EmptyState.Actions children` | `React.ReactNode` | | One or more action buttons rendered below the description. |
18
+
19
+ ## Example: Default
20
+
21
+ ```tsx
22
+ <EmptyState.Root>
23
+ <EmptyState.Illustration>
24
+ <svg
25
+ width="48"
26
+ height="48"
27
+ viewBox="0 0 24 24"
28
+ fill="none"
29
+ stroke="var(--color-text-disabled)"
30
+ strokeWidth="1.5"
31
+ strokeLinecap="round"
32
+ strokeLinejoin="round"
33
+ aria-hidden="true"
34
+ >
35
+ <circle cx="11" cy="11" r="8" />
36
+ <path d="m21 21-4.35-4.35" />
37
+ </svg>
38
+ </EmptyState.Illustration>
39
+ <EmptyState.Title>No results found</EmptyState.Title>
40
+ <EmptyState.Description>
41
+ Try adjusting your search or filters to find what you're looking for.
42
+ </EmptyState.Description>
43
+ <EmptyState.Actions>
44
+ <Button variant="primary">Clear filters</Button>
45
+ <Button variant="outline">Browse all</Button>
46
+ </EmptyState.Actions>
47
+ </EmptyState.Root>
48
+ ```
49
+
50
+ ## Example: Custom illustration
51
+
52
+ ```tsx
53
+ <EmptyState.Root>
54
+ <EmptyState.Illustration>
55
+ <svg
56
+ width="80"
57
+ height="80"
58
+ viewBox="0 0 80 80"
59
+ fill="none"
60
+ xmlns="http://www.w3.org/2000/svg"
61
+ aria-hidden="true"
62
+ >
63
+ <rect width="80" height="80" rx="40" fill="var(--color-bg-subtle)" />
64
+ <rect x="24" y="28" width="32" height="24" rx="4" stroke="var(--color-border-strong)" strokeWidth="2" />
65
+ <path d="M24 36h32" stroke="var(--color-border-strong)" strokeWidth="2" />
66
+ <circle cx="40" cy="48" r="4" fill="var(--color-text-disabled)" />
67
+ </svg>
68
+ </EmptyState.Illustration>
69
+ <EmptyState.Title>No documents yet</EmptyState.Title>
70
+ <EmptyState.Description>
71
+ Upload your first document to get started.
72
+ </EmptyState.Description>
73
+ <EmptyState.Actions>
74
+ <Button variant="primary">Upload document</Button>
75
+ </EmptyState.Actions>
76
+ </EmptyState.Root>
77
+ ```
@@ -0,0 +1,37 @@
1
+ # Error State
2
+
3
+ Full-page or section error view with retry action.
4
+
5
+ - Package: `@nexub/react` · Category: Data Display · Status: stable
6
+ - Import: `import { ErrorState } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/error-state
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `title` (required) | `string` | | Primary error heading shown to the user. |
14
+ | `description` | `string` | | Supporting text with more detail about the error or recovery steps. |
15
+ | `tone` | `'error' \| 'warning' \| 'info'` | `'error'` | Controls the icon and colour scheme of the error state. |
16
+ | `onRetry` | `() => void` | | When provided, renders a "Try again" button that calls this function on click. |
17
+ | `actions` | `React.ReactNode` | | Custom action elements rendered below the description. Takes priority over the default retry button. |
18
+
19
+ ## Example: Default
20
+
21
+ ```tsx
22
+ <ErrorState
23
+ title="Something went wrong"
24
+ description="We could not load the data. Please try again."
25
+ onRetry={() => {}}
26
+ />
27
+ ```
28
+
29
+ ## Example: Warning
30
+
31
+ ```tsx
32
+ <ErrorState
33
+ tone="warning"
34
+ title="Connection issue"
35
+ description="Check your network and try again."
36
+ />
37
+ ```