@nexub/mcp 6.2.0 → 6.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.
@@ -12,6 +12,8 @@ Feature-rich data table with sorting and row selection powered by TanStack Table
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
14
  | `data` (required) | `TData[]` | | Array of row data objects to render. |
15
+ | `getSubRows` | `(row, index) => TData[] \| undefined` | | Nested rows (a tree table). The first column gets an expand toggle (`aria-expanded`) and indents each level; sorting sorts within each level. |
16
+ | `expanded / defaultExpanded / onExpandedChange` | `ExpandedState` | | Expanded rows by row id (see `getRowId`), or `true` for all. |
15
17
  | `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
18
  | `enableSorting` | `boolean` | `false` | Click a header to sort; Shift+click adds more columns, numbered 1, 2… (5.3). |
17
19
  | `enableRowSelection` | `boolean` | `false` | Turns on row selection state. |
@@ -242,6 +244,56 @@ export default function Example() {
242
244
  }
243
245
  ```
244
246
 
247
+ ## Example: Tree rows
248
+
249
+ `getSubRows` nests rows: the first column gets an expand toggle and indents each level. With pages, a parent and its children stay on one page.
250
+
251
+ ```tsx
252
+ 'use client';
253
+
254
+ import { DataTable, type DataTableColumn } from '@nexub/react';
255
+
256
+ type Account = { name: string; owner: string; arr: number; children?: Account[] };
257
+
258
+ const data: Account[] = [
259
+ {
260
+ name: 'Acme Group',
261
+ owner: 'Ada',
262
+ arr: 420000,
263
+ children: [
264
+ { name: 'Acme EU', owner: 'Grace', arr: 180000, children: [{ name: 'Acme Berlin', owner: 'Grace', arr: 60000 }] },
265
+ { name: 'Acme US', owner: 'Alan', arr: 240000 },
266
+ ],
267
+ },
268
+ { name: 'Globex', owner: 'Linus', arr: 95000 },
269
+ ];
270
+
271
+ const columns: DataTableColumn<Account>[] = [
272
+ { accessorKey: 'name', header: 'Account' },
273
+ { accessorKey: 'owner', header: 'Owner' },
274
+ {
275
+ accessorKey: 'arr',
276
+ header: 'ARR',
277
+ meta: { align: 'end' },
278
+ cell: ({ getValue }) => new Intl.NumberFormat('en', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }).format(getValue<number>()),
279
+ },
280
+ ];
281
+
282
+ export default function Example() {
283
+ return (
284
+ <DataTable
285
+ caption="Accounts by region"
286
+ captionHidden
287
+ columns={columns}
288
+ data={data}
289
+ getSubRows={(row) => row.children}
290
+ getRowId={(row) => row.name}
291
+ defaultExpanded={{ 'Acme Group': true }}
292
+ />
293
+ );
294
+ }
295
+ ```
296
+
245
297
  ## Accessibility
246
298
 
247
299
  - Roles: table (default), grid (with `grid`), columnheader with aria-sort when sortable
@@ -0,0 +1,106 @@
1
+ # Tree View
2
+
3
+ A keyboard-friendly hierarchy (ARIA tree) with lazy children and tri-state checkboxes.
4
+
5
+ - Package: `@nexub/react` · Category: Navigation · Status: beta
6
+ - Import: `import { TreeView } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/tree-view
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `nodes` (required) | `TreeNode[]` | | `{ id, label, textValue?, icon?, children?, hasChildren?, disabled? }`. |
14
+ | `aria-label / aria-labelledby` (required) | `string` | | Names the tree. |
15
+ | `expanded / defaultExpanded / onExpandedChange` | `string[]` | | Open node ids. |
16
+ | `selected / defaultSelected / onSelectedChange` | `string \| null` | | Single selection, set by click, Enter or Space. |
17
+ | `checkable` | `boolean` | | Checkboxes instead of selection. A parent is checked when all its children are and mixed when some are. |
18
+ | `checked / defaultChecked / onCheckedChange` | `string[]` | | Every checked id, parents included. |
19
+ | `onLoadChildren` | `(node) => Promise` | | Called when a `hasChildren` node without `children` opens. Load them and pass the new `nodes`; the item is `aria-busy` meanwhile. |
20
+
21
+ ## Example: Lazy loading and selection
22
+
23
+ ```tsx
24
+ 'use client';
25
+
26
+ import * as React from 'react';
27
+ import { TreeView, type TreeNode } from '@nexub/react';
28
+
29
+ export default function Example() {
30
+ const [nodes, setNodes] = React.useState<TreeNode[]>([
31
+ {
32
+ id: 'eng',
33
+ label: 'Engineering',
34
+ children: [
35
+ { id: 'web', label: 'Web', children: [{ id: 'ada', label: 'Ada Lovelace' }, { id: 'alan', label: 'Alan Turing' }] },
36
+ { id: 'mobile', label: 'Mobile', hasChildren: true },
37
+ ],
38
+ },
39
+ { id: 'design', label: 'Design', children: [{ id: 'grace', label: 'Grace Hopper' }] },
40
+ ]);
41
+ const [selected, setSelected] = React.useState<string | null>('ada');
42
+
43
+ // Pretend server call: fills Mobile's children the first time it opens.
44
+ const load = async (node: TreeNode) => {
45
+ await new Promise((r) => setTimeout(r, 700));
46
+ const fill = (list: TreeNode[]): TreeNode[] =>
47
+ list.map((n) =>
48
+ n.id === node.id
49
+ ? { ...n, children: [{ id: 'linus', label: 'Linus Torvalds' }, { id: 'margaret', label: 'Margaret Hamilton' }] }
50
+ : { ...n, children: n.children && fill(n.children) },
51
+ );
52
+ setNodes(fill);
53
+ };
54
+
55
+ return (
56
+ <div className="flex w-full max-w-xs flex-col gap-2">
57
+ <TreeView aria-label="Teams" nodes={nodes} defaultExpanded={['eng', 'web']} selected={selected} onSelectedChange={setSelected} onLoadChildren={load} />
58
+ <p className="text-body-sm text-[var(--color-on-surface-muted)]">Selected: {selected ?? 'none'}</p>
59
+ </div>
60
+ );
61
+ }
62
+ ```
63
+
64
+ ## Example: Checkboxes
65
+
66
+ ```tsx
67
+ 'use client';
68
+
69
+ import * as React from 'react';
70
+ import { TreeView, type TreeNode } from '@nexub/react';
71
+
72
+ const nodes: TreeNode[] = [
73
+ {
74
+ id: 'reports',
75
+ label: 'Reports',
76
+ children: [
77
+ { id: 'revenue', label: 'Revenue' },
78
+ { id: 'churn', label: 'Churn' },
79
+ ],
80
+ },
81
+ { id: 'settings', label: 'Settings', children: [{ id: 'billing', label: 'Billing' }, { id: 'members', label: 'Members' }] },
82
+ ];
83
+
84
+ export default function Example() {
85
+ const [checked, setChecked] = React.useState<string[]>(['revenue']);
86
+ return (
87
+ <div className="flex w-full max-w-xs flex-col gap-2">
88
+ <TreeView aria-label="Permissions" nodes={nodes} checkable defaultExpanded={['reports', 'settings']} checked={checked} onCheckedChange={setChecked} />
89
+ <p className="text-body-sm text-[var(--color-on-surface-muted)]">Granted: {checked.join(', ') || 'nothing'}</p>
90
+ </div>
91
+ );
92
+ }
93
+ ```
94
+
95
+ ## Accessibility
96
+
97
+ - Roles: tree, treeitem with aria-level, aria-setsize, aria-posinset, aria-expanded, group
98
+ - `ArrowDown / ArrowUp`: Next or previous visible item.
99
+ - `ArrowRight`: Opens a closed item, or moves to its first child. Mirrored in RTL.
100
+ - `ArrowLeft`: Closes an open item, or moves to its parent. Mirrored in RTL.
101
+ - `Home / End`: First or last visible item.
102
+ - `Enter / Space`: Selects the item, or toggles its checkbox.
103
+ - `Type a letter`: Moves to the next item starting with the typed text.
104
+ - The tree is one tab stop (roving tabindex); it returns to the last focused or the selected item.
105
+
106
+ Related: [data-table](data-table.md), [sidebar](sidebar.md)
@@ -1,6 +1,6 @@
1
1
  # Component index
2
2
 
3
- Nexub DS v6.2.0. Open `components/<slug>.md` for props, examples and accessibility notes.
3
+ Nexub DS v6.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
@@ -157,6 +157,7 @@ Never use a component marked deprecated.
157
157
  - [Pagination](components/pagination.md) `@nexub/react`: Page navigation control with prev/next and page number buttons.
158
158
  - [Saved Views](components/saved-views.md) `@nexub/react`: A menu to switch, save, update and delete saved filter views. Your app stores them.
159
159
  - [Tabs](components/tabs.md) `@nexub/react`: Layered content panels switched by tab triggers. Built on Radix UI Tabs.
160
+ - [Tree View](components/tree-view.md) `@nexub/react`: A keyboard-friendly hierarchy (ARIA tree) with lazy children and tri-state checkboxes.
160
161
 
161
162
  ## Components — Overlays
162
163
 
@@ -1,6 +1,6 @@
1
1
  # Tokens
2
2
 
3
- Nexub DS v6.2.0. Every token is a CSS custom property from `@nexub/tokens/css` (loaded by `@nexub/themes/base`).
3
+ Nexub DS v6.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": "6.2.0",
3
+ "version": "6.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",