@nexub/mcp 5.1.0 → 5.3.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.
@@ -15,9 +15,12 @@ Type-to-search input with matching options dropdown.
15
15
  | `onValueChange` | `(value: string) => void` | | Callback fired when the selected value changes. |
16
16
  | `placeholder` | `string` | | Placeholder text shown in the input when empty. |
17
17
  | `emptyText` | `string` | | Text shown when no options match the current search query. |
18
- | `loading` | `boolean` | | Shows a loading indicator while options are being fetched. |
18
+ | `loading` | `boolean` | | Skeleton rows while options are being fetched (5.2); "Loading" is announced. |
19
19
  | `inputValue` | `string` | | Controlled input text (5.1). |
20
20
  | `onInputChange` | `(text: string) => void` | | Called as the user types, so you can fetch options (5.1). When set, options are shown as given, without built-in filtering. |
21
+ | `mode` | `'inline' \| 'popover'` | `'inline'` | Popover (5.2): a field whose list opens below it while typing. Inline keeps the list always visible; it stays the default until 6.0. |
22
+ | `onCreate` | `(text: string) => void` | | Adds a "Create “text”" option when the text matches no option (5.2). |
23
+ | `aria-label` | `string` | | Accessible name of the field when it has no visible label. |
21
24
 
22
25
  ## Example: Default
23
26
 
@@ -75,3 +78,44 @@ export default function Example() {
75
78
  );
76
79
  }
77
80
  ```
81
+
82
+ ## Example: Popover, fetch as you type
83
+
84
+ `mode="popover"` with `onInputChange`: the app filters, the list shows skeleton rows while loading.
85
+
86
+ ```tsx
87
+ 'use client';
88
+
89
+ import * as React from 'react';
90
+ import { Autocomplete } from '@nexub/react';
91
+
92
+ const all = ['Amsterdam', 'Berlin', 'Lisbon', 'London', 'Madrid', 'Paris', 'Singapore', 'Tokyo'];
93
+
94
+ // Fetch-as-you-type: onInputChange turns built-in filtering off.
95
+ export default function Example() {
96
+ const [query, setQuery] = React.useState('');
97
+ const [loading, setLoading] = React.useState(false);
98
+ const [options, setOptions] = React.useState(all.map((c) => ({ value: c, label: c })));
99
+ React.useEffect(() => {
100
+ setLoading(true);
101
+ const t = setTimeout(() => {
102
+ const q = query.toLowerCase();
103
+ setOptions(all.filter((c) => c.toLowerCase().includes(q)).map((c) => ({ value: c, label: c })));
104
+ setLoading(false);
105
+ }, 300);
106
+ return () => clearTimeout(t);
107
+ }, [query]);
108
+ return (
109
+ <div className="w-[280px]">
110
+ <Autocomplete
111
+ mode="popover"
112
+ aria-label="City"
113
+ placeholder="Search cities…"
114
+ options={options}
115
+ loading={loading}
116
+ onInputChange={setQuery}
117
+ />
118
+ </div>
119
+ );
120
+ }
121
+ ```
@@ -12,6 +12,7 @@ Compact label chip, optionally dismissible.
12
12
  | --- | --- | --- | --- |
13
13
  | `variant` | `'filled' \| 'outline'` | `'filled'` | Visual style of the chip. |
14
14
  | `onRemove` | `() => void` | | When provided, renders a dismiss button that calls this handler. |
15
+ | `removeLabel` | `string` | `'Remove'` | Accessible name of the dismiss button (5.2), e.g. "Remove Bug". Use it when several chips sit together. |
15
16
  | `size` | `'sm' \| 'md'` | | Controls chip size. |
16
17
 
17
18
  ## Example: Default
@@ -11,15 +11,19 @@ Feature-rich data table with sorting and row selection powered by TanStack Table
11
11
  | Prop | Type | Default | Description |
12
12
  | --- | --- | --- | --- |
13
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
14
  | `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. |
15
+ | `caption` | `ReactNode` | | Names the table for assistive tech (and its scroll region). Shown below the table; add `captionHidden` to keep it screen-reader only. |
16
+ | `enableSorting` | `boolean` | `false` | Click a header to sort; Shift+click adds more columns, numbered 1, 2… (5.3). |
17
+ | `enableRowSelection` | `boolean` | `false` | Turns on row selection state. |
18
+ | `selectionColumn` | `boolean` | `false` | With `enableRowSelection` (5.3): a checkbox column, select-page in its header, and "Select all N" across pages. On by default from 6.0. |
19
+ | `rowSelection / onRowSelectionChange` | `Record<string, boolean>` | | Controlled selection keyed by row id (5.3). |
20
+ | `getRowId` | `(row: TData, index: number) => string` | | Stable row ids for selection; defaults to the row index (5.3). |
21
+ | `bulkActions` | `(rows: TData[], clear: () => void) => ReactNode` | | A floating bar while rows are selected, with the count, your actions and a clear button (5.3). |
22
+ | `density / defaultDensity / onDensityChange` | `'comfortable' \| 'compact'` | `'comfortable'` | Row height (5.3). |
23
+ | `columnVisibility / onColumnVisibilityChange` | `Record<string, boolean>` | | Which columns show, keyed by column id (5.3). |
24
+ | `viewOptions` | `boolean` | `false` | A "View" menu above the table for density and column visibility (5.3). |
25
+ | `toolbar` | `ReactNode` | | Content at the start of the row above the table, e.g. filters (5.3). |
26
+ | `pagination.pageSize` | `number` | `20` | Rows per page; pagination is on when `pagination` is set. |
23
27
 
24
28
  ## Example: Default
25
29
 
@@ -72,3 +76,67 @@ export default function Example() {
72
76
  );
73
77
  }
74
78
  ```
79
+
80
+ ## Example: Selection, bulk actions and view menu
81
+
82
+ Select rows with the checkbox column; the bar at the bottom acts on them. The View menu switches density and hides columns.
83
+
84
+ ```tsx
85
+ 'use client';
86
+
87
+ import * as React from 'react';
88
+ import { Button, DataTable, type DataTableColumn } from '@nexub/react';
89
+
90
+ interface Invoice {
91
+ id: string;
92
+ customer: string;
93
+ status: string;
94
+ amount: number;
95
+ }
96
+
97
+ const invoices: Invoice[] = [
98
+ { id: 'INV-2041', customer: 'Acme', status: 'Overdue', amount: 1200 },
99
+ { id: 'INV-2042', customer: 'Globex', status: 'Paid', amount: 860 },
100
+ { id: 'INV-2043', customer: 'Initech', status: 'Draft', amount: 430 },
101
+ { id: 'INV-2044', customer: 'Umbrella', status: 'Overdue', amount: 2150 },
102
+ { id: 'INV-2045', customer: 'Hooli', status: 'Paid', amount: 990 },
103
+ ];
104
+
105
+ const columns: DataTableColumn<Invoice>[] = [
106
+ { accessorKey: 'id', header: 'Invoice' },
107
+ { accessorKey: 'customer', header: 'Customer' },
108
+ { accessorKey: 'status', header: 'Status' },
109
+ { accessorKey: 'amount', header: 'Amount', meta: { align: 'end' } },
110
+ ];
111
+
112
+ export default function Example() {
113
+ const [selection, setSelection] = React.useState<Record<string, boolean>>({ 'INV-2041': true, 'INV-2044': true });
114
+ return (
115
+ <div className="w-full max-w-[640px]">
116
+ <DataTable
117
+ caption="Invoices"
118
+ captionHidden
119
+ columns={columns}
120
+ data={invoices}
121
+ getRowId={(r) => r.id}
122
+ enableSorting
123
+ enableRowSelection
124
+ selectionColumn
125
+ rowSelection={selection}
126
+ onRowSelectionChange={setSelection}
127
+ viewOptions
128
+ bulkActions={(rows, clear) => (
129
+ <>
130
+ <Button size="sm" variant="outline" onClick={clear}>
131
+ Send reminders ({rows.length})
132
+ </Button>
133
+ <Button size="sm" variant="destructive" onClick={clear}>
134
+ Void
135
+ </Button>
136
+ </>
137
+ )}
138
+ />
139
+ </div>
140
+ );
141
+ }
142
+ ```
@@ -0,0 +1,70 @@
1
+ # Multi Select
2
+
3
+ Pick several options as chips, with search, "+N more" and an optional create option.
4
+
5
+ - Package: `@nexub/react` · Category: Form Controls · Status: beta
6
+ - Import: `import { MultiSelect } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/multi-select
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `options` (required) | `{ value: string; label: string }[]` | | The options to pick from. |
14
+ | `value / defaultValue` | `string[]` | | Selected values, controlled or not. |
15
+ | `onValueChange` | `(value: string[]) => void` | | Called with the new selection. |
16
+ | `maxVisibleChips` | `number` | `3` | Chips shown before the rest collapse into "+N more". |
17
+ | `onInputChange` | `(text: string) => void` | | Called as the user types. When set, options are shown as given, so you can fetch them. |
18
+ | `onCreate` | `(text: string) => void` | | Adds a "Create “text”" option when the text matches no option. |
19
+ | `loading` | `boolean` | | Skeleton rows instead of options; "Loading" is announced. |
20
+ | `aria-label / aria-labelledby` | `string` | | Name the field: there is no visible label inside it. |
21
+
22
+ ## Example: Labels with create
23
+
24
+ ```tsx
25
+ 'use client';
26
+
27
+ import * as React from 'react';
28
+ import { MultiSelect } from '@nexub/react';
29
+
30
+ const labels = [
31
+ { value: 'bug', label: 'Bug' },
32
+ { value: 'design', label: 'Design' },
33
+ { value: 'docs', label: 'Docs' },
34
+ { value: 'perf', label: 'Performance' },
35
+ { value: 'a11y', label: 'Accessibility' },
36
+ { value: 'security', label: 'Security' },
37
+ ];
38
+
39
+ export default function Example() {
40
+ const [options, setOptions] = React.useState(labels);
41
+ const [value, setValue] = React.useState(['bug', 'a11y']);
42
+ return (
43
+ <div className="w-[320px]">
44
+ <MultiSelect
45
+ aria-label="Labels"
46
+ placeholder="Add labels…"
47
+ options={options}
48
+ value={value}
49
+ onValueChange={setValue}
50
+ onCreate={(text) => {
51
+ const v = text.toLowerCase();
52
+ setOptions((o) => [...o, { value: v, label: text }]);
53
+ setValue((s) => [...s, v]);
54
+ }}
55
+ />
56
+ </div>
57
+ );
58
+ }
59
+ ```
60
+
61
+ ## Accessibility
62
+
63
+ - `Type`: Filters the options and opens the list.
64
+ - `ArrowDown / ArrowUp`: Moves through the options.
65
+ - `Enter`: Toggles the highlighted option.
66
+ - `Backspace`: In an empty field, removes the last chip.
67
+ - `Escape`: Closes the list.
68
+ - Options carry `aria-checked`; each chip has a "Remove <label>" button.
69
+
70
+ Related: [autocomplete](autocomplete.md), [chip](chip.md), [select](select.md)
@@ -1,6 +1,6 @@
1
1
  # Component index
2
2
 
3
- Nexub DS v5.1.0. Open `components/<slug>.md` for props, examples and accessibility notes.
3
+ Nexub DS v5.3.0. Open `components/<slug>.md` for props, examples and accessibility notes.
4
4
  Never use a component marked deprecated.
5
5
 
6
6
  ## Components — Actions
@@ -83,6 +83,7 @@ Never use a component marked deprecated.
83
83
  - [Checkbox](components/checkbox.md) `@nexub/react`: Binary checkbox input built on Radix UI.
84
84
  - [Checkbox Card](components/checkbox-card.md) `@nexub/react`: A checkbox drawn as a whole card: title, description and optional icon. Pick any number.
85
85
  - [Combobox](components/combobox.md) `@nexub/react`: Command-palette style searchable dropdown built on cmdk.
86
+ - [Multi Select](components/multi-select.md) `@nexub/react`: Pick several options as chips, with search, "+N more" and an optional create option.
86
87
  - [Radio Card](components/radio-card.md) `@nexub/react`: A radio group where each option is a whole card: title, description and optional icon, one choice.
87
88
  - [Radio Group](components/radio-group.md) `@nexub/react`: Group of mutually exclusive radio inputs.
88
89
  - [Select](components/select.md) `@nexub/react`: Accessible dropdown select built on Radix UI. Supports groups and search.
@@ -1,6 +1,6 @@
1
1
  # Tokens
2
2
 
3
- Nexub DS v5.1.0. Every token is a CSS custom property from `@nexub/tokens/css` (loaded by `@nexub/themes/base`).
3
+ Nexub DS v5.3.0. Every token is a CSS custom property from `@nexub/tokens/css` (loaded by `@nexub/themes/base`).
4
4
  The Tailwind preset (`@nexub/tokens/tailwind`) maps them to utilities. Never hardcode a hex, px spacing or shadow that a token covers.
5
5
 
6
6
  ## Color roles
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexub/mcp",
3
- "version": "5.1.0",
3
+ "version": "5.3.0",
4
4
  "description": "MCP server for Nexub Design System: gives Claude, Cursor and any MCP client the components, patterns, tokens and design rules of the installed release.",
5
5
  "type": "module",
6
6
  "license": "MIT",