@nexub/mcp 6.4.0 → 6.6.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,47 @@
1
+ # Chart Zoom
2
+
3
+ Zoom any chart to part of its range with a two-thumb slider.
4
+
5
+ - Package: `@nexub/react` · Category: Data Display · Status: beta
6
+ - Import: `import { ChartZoom } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/chart-zoom
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `data` (required) | `T[]` | | The full data. |
14
+ | `index` (required) | `keyof T` | | The category key; its values label the range. |
15
+ | `children` (required) | `(slice: T[]) => ReactNode` | | Render the chart for the visible slice. |
16
+ | `defaultRange` | `[start, end]` | | Starting indexes; the whole range by default. |
17
+ | `minSpan` | `number` | `2` | Fewest categories shown. |
18
+
19
+ ## Example: Zoom a year of revenue
20
+
21
+ ```tsx
22
+ 'use client';
23
+
24
+ import { ChartZoom, LineChart } from '@nexub/react';
25
+
26
+ const data = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'].map((month, i) => ({
27
+ month,
28
+ revenue: 120 + i * 14 + (i % 3) * 9,
29
+ }));
30
+
31
+ export default function Example() {
32
+ return (
33
+ <ChartZoom data={data} index="month" defaultRange={[3, 8]} className="w-full">
34
+ {(slice) => (
35
+ <LineChart className="w-full" title="Revenue ($k)" data={slice} index="month" series={[{ key: 'revenue', label: 'Revenue' }]} />
36
+ )}
37
+ </ChartZoom>
38
+ );
39
+ }
40
+ ```
41
+
42
+ ## Accessibility
43
+
44
+ - `Arrow keys / Home / End`: Move the focused thumb.
45
+ - Thumbs read "Zoom start: Mar" and "Zoom end: Sep". Charts themselves stay server components; only this wrapper runs on the client.
46
+
47
+ Related: [line-chart](line-chart.md), [bar-chart](bar-chart.md), [chart-toggle](chart-toggle.md)
@@ -14,6 +14,8 @@ Feature-rich data table with sorting and row selection powered by TanStack Table
14
14
  | `data` (required) | `TData[]` | | Array of row data objects to render. |
15
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
16
  | `expanded / defaultExpanded / onExpandedChange` | `ExpandedState` | | Expanded rows by row id (see `getRowId`), or `true` for all. |
17
+ | `onRowOrderChange` | `(data: TData[]) => void` | | Adds a handle column: drag rows, or Alt+ArrowUp/Down on a handle. Hidden while a column is sorted. |
18
+ | `getRowLabel` | `(row) => string` | | Names a row in "Move ‹label›" and the move announcements. |
17
19
  | `caption` | `ReactNode` | | Names the table for assistive tech (and its scroll region). Shown below the table; add `captionHidden` to keep it screen-reader only. |
18
20
  | `enableSorting` | `boolean` | `false` | Click a header to sort; Shift+click adds more columns, numbered 1, 2… (5.3). |
19
21
  | `enableRowSelection` | `boolean` | `false` | Turns on row selection state. |
@@ -294,6 +296,53 @@ export default function Example() {
294
296
  }
295
297
  ```
296
298
 
299
+ ## Example: Export CSV
300
+
301
+ `toCSV(rows, columns)` quotes and escapes per RFC 4180 and neutralises cells that start like a spreadsheet formula. Pass what the person sees.
302
+
303
+ ```tsx
304
+ 'use client';
305
+
306
+ import { Button, DataTable, toCSV, type DataTableColumn } from '@nexub/react';
307
+
308
+ type Invoice = { id: string; customer: string; amount: number };
309
+
310
+ const data: Invoice[] = [
311
+ { id: 'INV-1042', customer: 'Acme, Inc.', amount: 1200 },
312
+ { id: 'INV-1043', customer: 'Globex', amount: 860 },
313
+ ];
314
+
315
+ const columns: DataTableColumn<Invoice>[] = [
316
+ { accessorKey: 'id', header: 'Invoice' },
317
+ { accessorKey: 'customer', header: 'Customer' },
318
+ { accessorKey: 'amount', header: 'Amount', meta: { align: 'end' } },
319
+ ];
320
+
321
+ function download() {
322
+ const csv = toCSV(data, [
323
+ { header: 'Invoice', value: 'id' },
324
+ { header: 'Customer', value: 'customer' },
325
+ { header: 'Amount', value: 'amount' },
326
+ ]);
327
+ const url = URL.createObjectURL(new Blob([csv], { type: 'text/csv;charset=utf-8' }));
328
+ const a = Object.assign(document.createElement('a'), { href: url, download: 'invoices.csv' });
329
+ a.click();
330
+ URL.revokeObjectURL(url);
331
+ }
332
+
333
+ export default function Example() {
334
+ return (
335
+ <DataTable
336
+ caption="Invoices"
337
+ captionHidden
338
+ columns={columns}
339
+ data={data}
340
+ toolbar={<Button variant="outlined" size="sm" onClick={download}>Export CSV</Button>}
341
+ />
342
+ );
343
+ }
344
+ ```
345
+
297
346
  ## Accessibility
298
347
 
299
348
  - Roles: table (default), grid (with `grid`), columnheader with aria-sort when sortable
@@ -0,0 +1,57 @@
1
+ # Kanban
2
+
3
+ Columns of cards people move by dragging or with Alt+Arrow keys.
4
+
5
+ - Package: `@nexub/react` · Category: Data Display · Status: beta
6
+ - Import: `import { Kanban } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/kanban
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `columns` (required) | `{ id, title, items: T[] }[]` | | The board. |
14
+ | `getId / getLabel` (required) | `(item) => string` | | Stable key and the name read when it moves. |
15
+ | `onChange` (required) | `(columns) => void` | | Called with the columns after a move; store them (and save to your server). |
16
+ | `renderCard` (required) | `(item) => ReactNode` | | The card’s content. |
17
+
18
+ ## Example: Task board
19
+
20
+ ```tsx
21
+ 'use client';
22
+
23
+ import * as React from 'react';
24
+ import { Badge, Kanban, type KanbanColumn } from '@nexub/react';
25
+
26
+ type Task = { id: string; title: string; tag?: string };
27
+
28
+ export default function Example() {
29
+ const [columns, setColumns] = React.useState<KanbanColumn<Task>[]>([
30
+ { id: 'todo', title: 'To do', items: [{ id: '1', title: 'Write release notes', tag: 'Docs' }, { id: '2', title: 'Update pricing page' }] },
31
+ { id: 'doing', title: 'In progress', items: [{ id: '3', title: 'Billing migration', tag: 'Backend' }] },
32
+ { id: 'done', title: 'Done', items: [{ id: '4', title: 'Hire designer' }] },
33
+ ]);
34
+ return (
35
+ <Kanban
36
+ columns={columns}
37
+ getId={(t) => t.id}
38
+ getLabel={(t) => t.title}
39
+ onChange={setColumns}
40
+ renderCard={(t) => (
41
+ <div className="flex flex-col items-start gap-1">
42
+ {t.title}
43
+ {t.tag && <Badge>{t.tag}</Badge>}
44
+ </div>
45
+ )}
46
+ />
47
+ );
48
+ }
49
+ ```
50
+
51
+ ## Accessibility
52
+
53
+ - `Alt+ArrowUp / Alt+ArrowDown`: On a handle: moves the card within its column.
54
+ - `Alt+ArrowLeft / Alt+ArrowRight`: Moves the card to the previous or next column. Mirrored in RTL.
55
+ - Each column is a region named by its heading. Moves are announced: "Bravo moved to Done, position 2 of 2".
56
+
57
+ Related: [sortable](sortable.md)
@@ -0,0 +1,51 @@
1
+ # NotificationCenter
2
+
3
+ A bell with an unread count that opens the notification list.
4
+
5
+ - Package: `@nexub/patterns` · Category: Feedback · Status: beta
6
+ - Import: `import { NotificationCenter } from '@nexub/patterns';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/patterns/notification-center
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `notifications` (required) | `{ id, title, description?, timestamp?, read?, icon?, href? }[]` | | Newest first. Your app owns them and their read state. |
14
+ | `onOpen` | `(id) => void` | | A notification was opened; mark it read here. |
15
+ | `onDismiss` | `(id) => void` | | Shows a dismiss button per item. |
16
+ | `onMarkAllRead` | `() => void` | | Shows "Mark all as read" while some are unread. |
17
+ | `emptyText` | `ReactNode` | `"You’re all caught up"` | Shown with no notifications. |
18
+
19
+ ## Example: Inbox
20
+
21
+ ```tsx
22
+ 'use client';
23
+
24
+ import * as React from 'react';
25
+ import { NotificationCenter, type NotificationCenterItem } from '@nexub/patterns';
26
+
27
+ export default function Example() {
28
+ const [items, setItems] = React.useState<NotificationCenterItem[]>([
29
+ { id: '1', title: 'Deploy failed on main', description: 'Build step "test" exited with 1.', timestamp: '2 min ago' },
30
+ { id: '2', title: 'Invoice #1042 paid', timestamp: '1 h ago' },
31
+ { id: '3', title: 'Ada commented on Q4 plan', timestamp: 'Yesterday', read: true },
32
+ ]);
33
+ const markRead = (id?: string) => setItems((list) => list.map((n) => (!id || n.id === id ? { ...n, read: true } : n)));
34
+ return (
35
+ <NotificationCenter
36
+ notifications={items}
37
+ onOpen={(id) => markRead(id)}
38
+ onDismiss={(id) => setItems((list) => list.filter((n) => n.id !== id))}
39
+ onMarkAllRead={() => markRead()}
40
+ />
41
+ );
42
+ }
43
+ ```
44
+
45
+ ## Accessibility
46
+
47
+ - The bell reads "Notifications, 3 unread"; the count badge is decorative.
48
+ - The list opens in a popover labelled by its heading; Escape closes it and focus returns to the bell.
49
+ - Each item’s title is its link or button, stretched over the whole item.
50
+
51
+ Related: [notification-item](notification-item.md)
@@ -13,9 +13,10 @@ Single notification row for notification panels or dropdowns.
13
13
  | `title` (required) | `string` | | Notification title. |
14
14
  | `description` | `string` | | Supporting text. |
15
15
  | `timestamp` | `string` | | Relative time string. |
16
- | `unread` | `boolean` | `false` | Applies unread indicator styling. |
17
- | `avatar` | `React.ReactNode` | | Avatar for the notification actor. |
18
- | `onClick` | `() => void` | | Click handler for the item. |
16
+ | `read` | `boolean` | `false` | Unread items get a tinted background and an "Unread" dot. |
17
+ | `icon` | `ReactNode` | | Icon or avatar before the text. |
18
+ | `href / onSelect` | `string / () => void` | | Makes the whole item a link or a button (6.6). |
19
+ | `onDismiss` | `() => void` | | Shows a dismiss button. |
19
20
 
20
21
  ## Example: Default
21
22
 
@@ -0,0 +1,44 @@
1
+ # Sortable
2
+
3
+ A list people reorder by dragging or with Alt+Arrow keys on a handle.
4
+
5
+ - Package: `@nexub/react` · Category: Data Display · Status: beta
6
+ - Import: `import { Sortable } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/sortable
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `items` (required) | `T[]` | | The list, in order. |
14
+ | `getId / getLabel` (required) | `(item) => string` | | Stable key, and the name read in "Move ‹label›" and the move announcements. |
15
+ | `onReorder` (required) | `(items: T[]) => void` | | Called with the new order; store it. |
16
+ | `children` (required) | `(item) => ReactNode` | | The item’s content; the handle sits before it. |
17
+ | `aria-label` | `string` | | Names the list. |
18
+
19
+ ## Example: Widget order
20
+
21
+ ```tsx
22
+ 'use client';
23
+
24
+ import * as React from 'react';
25
+ import { Sortable } from '@nexub/react';
26
+
27
+ export default function Example() {
28
+ const [widgets, setWidgets] = React.useState(['Revenue', 'Active users', 'Churn', 'Support tickets']);
29
+ return (
30
+ <Sortable aria-label="Dashboard widgets" items={widgets} getId={(w) => w} getLabel={(w) => w} onReorder={setWidgets} className="w-full max-w-sm">
31
+ {(w) => w}
32
+ </Sortable>
33
+ );
34
+ }
35
+ ```
36
+
37
+ ## Accessibility
38
+
39
+ - `Alt+ArrowUp / Alt+ArrowDown`: On a handle: moves the item; focus stays on its handle.
40
+ - Every handle is a button named "Move ‹label›", described by the key hint.
41
+ - Moves are announced: "Alpha moved to position 3 of 5".
42
+ - Mouse drag uses the native drag-and-drop API, so there is no extra dependency.
43
+
44
+ Related: [kanban](kanban.md), [data-table](data-table.md)
@@ -1,6 +1,6 @@
1
1
  # Component index
2
2
 
3
- Nexub DS v6.4.0. Open `components/<slug>.md` for props, examples and accessibility notes.
3
+ Nexub DS v6.6.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
@@ -32,6 +32,7 @@ Never use a component marked deprecated.
32
32
  - [Amount](components/amount.md) `@nexub/react`: Honest money: Intl formatting, tabular numerals, the currency’s minor unit and a true minus sign.
33
33
  - [Bar Chart](components/bar-chart.md) `@nexub/react`: Compare values across categories, grouped or stacked. Server-rendered SVG on the chart palette.
34
34
  - [Chart Toggle](components/chart-toggle.md) `@nexub/react`: A legend whose entries switch series on and off, wrapped around any chart.
35
+ - [Chart Zoom](components/chart-zoom.md) `@nexub/react`: Zoom any chart to part of its range with a two-thumb slider.
35
36
  - [Data Table](components/data-table.md) `@nexub/react`: Feature-rich data table with sorting and row selection powered by TanStack Table.
36
37
  - [Donut Chart](components/donut-chart.md) `@nexub/react`: Parts of a whole, with an optional total in the hole. Keep it to six slices or fewer.
37
38
  - [Empty State](components/empty-state.md) `@nexub/react`: Placeholder UI shown when a list or page has no content.
@@ -40,9 +41,11 @@ Never use a component marked deprecated.
40
41
  - [Funnel](components/funnel.md) `@nexub/react`: Drop-off through ordered steps, with conversion from the first step.
41
42
  - [Gauge](components/gauge.md) `@nexub/react`: Progress toward a target on a 270° arc.
42
43
  - [Heatmap](components/heatmap.md) `@nexub/react`: Intensity over a grid, such as activity by weekday and week, in seven sequential steps.
44
+ - [Kanban](components/kanban.md) `@nexub/react`: Columns of cards people move by dragging or with Alt+Arrow keys.
43
45
  - [KPI Tile](components/kpi-tile.md) `@nexub/react`: A headline number with its change versus last period and a trend line.
44
46
  - [Line Chart](components/line-chart.md) `@nexub/react`: Show a trend over ordered categories such as time. Server-rendered SVG on the chart palette.
45
47
  - [Number Ticker](components/number-ticker.md) `@nexub/react`: A number whose digits roll to new values on the spatial spring. The first render never animates.
48
+ - [Sortable](components/sortable.md) `@nexub/react`: A list people reorder by dragging or with Alt+Arrow keys on a handle.
46
49
  - [Sparkline](components/sparkline.md) `@nexub/react`: A tiny trend line with no axes, for stat cards and table cells.
47
50
  - [Table](components/table.md) `@nexub/react`: Semantic HTML table with styled variants.
48
51
 
@@ -210,6 +213,7 @@ Never use a component marked deprecated.
210
213
 
211
214
  ## Patterns — Feedback
212
215
 
216
+ - [NotificationCenter](components/notification-center.md) `@nexub/patterns`: A bell with an unread count that opens the notification list.
213
217
  - [NotificationItem](components/notification-item.md) `@nexub/patterns`: Single notification row for notification panels or dropdowns.
214
218
 
215
219
  ## Patterns — Forms
@@ -1,6 +1,6 @@
1
1
  # Tokens
2
2
 
3
- Nexub DS v6.4.0. Every token is a CSS custom property from `@nexub/tokens/css` (loaded by `@nexub/themes/base`).
3
+ Nexub DS v6.6.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.4.0",
3
+ "version": "6.6.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",