@nexub/mcp 6.0.0 → 6.2.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,43 @@
1
+ # Date Time Picker
2
+
3
+ A DatePicker and a TimePicker that edit one Date, with an optional time-zone label.
4
+
5
+ - Package: `@nexub/react` · Category: Form & Input · Status: beta
6
+ - Import: `import { DateTimePicker } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/date-time-picker
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `value / onChange` | `Date \| undefined` | | Date and time in the reader’s local time. |
14
+ | `defaultTime` | `string` | `'09:00'` | Time used when the date is picked first. |
15
+ | `minuteStep` | `number` | | Passed to the TimePicker. |
16
+ | `minDate / maxDate` | `Date` | | Limits the calendar. |
17
+ | `timeZone` | `string` | | IANA zone named next to the fields, e.g. "Time zone: GMT+8 (Asia/Singapore)". Label only. |
18
+ | `aria-label` | `string` | | Names the group; the parts read "Date" and "Time". |
19
+
20
+ ## Example: Meeting start
21
+
22
+ ```tsx
23
+ 'use client';
24
+
25
+ import * as React from 'react';
26
+ import { DateTimePicker } from '@nexub/react';
27
+
28
+ export default function Example() {
29
+ const [starts, setStarts] = React.useState<Date | undefined>();
30
+ return (
31
+ <div className="flex w-full max-w-md flex-col gap-2">
32
+ <DateTimePicker aria-label="Meeting starts" value={starts} onChange={setStarts} minuteStep={15} timeZone="Asia/Singapore" />
33
+ <p className="text-body-sm text-[var(--color-on-surface-muted)]">{starts ? starts.toString() : 'Pick a date first; the time defaults to 09:00.'}</p>
34
+ </div>
35
+ );
36
+ }
37
+ ```
38
+
39
+ ## Accessibility
40
+
41
+ - A labelled group holding the DatePicker button and the native time input.
42
+
43
+ Related: [date-picker](date-picker.md), [time-picker](time-picker.md)
@@ -0,0 +1,61 @@
1
+ # Event Calendar
2
+
3
+ A month or week grid of events. Display only: your app owns the events and what a click does.
4
+
5
+ - Package: `@nexub/react` · Category: Data Display · Status: beta
6
+ - Import: `import { EventCalendar } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/event-calendar
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `events` (required) | `CalendarEvent[]` | | `{ id, title, start, end?, allDay?, tone? }`. Events spanning days show on each day; `tone` is primary, success, warning, error or info. |
14
+ | `date / defaultDate / onDateChange` | `Date` | | Any day in the shown month or week; Today and the arrows change it. |
15
+ | `view / defaultView / onViewChange` | `'month' \| 'week'` | `'month'` | Week shows every event; month shows `maxEventsPerDay` then "N more". |
16
+ | `onEventClick` | `(event) => void` | | Makes events buttons. |
17
+ | `onDayClick` | `(date) => void` | | Makes day numbers and "N more" buttons, for example to open the day. |
18
+ | `maxEventsPerDay` | `number` | `3` | Month view only. |
19
+ | `weekStartsOn` | `0–6` | | Defaults to the locale’s first day (Monday for en-GB, Sunday for en-US). |
20
+
21
+ ## Example: Team calendar
22
+
23
+ ```tsx
24
+ 'use client';
25
+
26
+ import * as React from 'react';
27
+ import { EventCalendar, type CalendarEvent } from '@nexub/react';
28
+
29
+ const today = new Date();
30
+ const on = (day: number, hour?: number) => new Date(today.getFullYear(), today.getMonth(), day, hour ?? 0);
31
+
32
+ const events: CalendarEvent[] = [
33
+ { id: '1', title: 'Design review', start: on(3, 10) },
34
+ { id: '2', title: 'Offsite', start: on(11), end: on(12), allDay: true, tone: 'success' },
35
+ { id: '3', title: 'Standup', start: on(16, 9) },
36
+ { id: '4', title: 'Launch', start: on(16, 14), tone: 'warning' },
37
+ { id: '5', title: 'Retro', start: on(16, 16) },
38
+ { id: '6', title: 'Incident review', start: on(16, 17), tone: 'error' },
39
+ ];
40
+
41
+ export default function Example() {
42
+ const [picked, setPicked] = React.useState('');
43
+ return (
44
+ <div className="flex w-full flex-col gap-2">
45
+ <EventCalendar
46
+ events={events}
47
+ onEventClick={(e) => setPicked(e.title)}
48
+ onDayClick={(d) => setPicked(d.toDateString())}
49
+ />
50
+ <p aria-live="polite" className="text-body-sm text-[var(--color-on-surface-muted)]">{picked && `Opened: ${picked}`}</p>
51
+ </div>
52
+ );
53
+ }
54
+ ```
55
+
56
+ ## Accessibility
57
+
58
+ - A table with weekday column headers; today has `aria-current="date"` and each day reads its full date.
59
+ - The title is a polite live region, so Today and the arrows announce the new month or week.
60
+
61
+ Related: [date-picker](date-picker.md), [date-time-picker](date-time-picker.md)
@@ -0,0 +1,46 @@
1
+ # Fieldset
2
+
3
+ Groups related fields under a legend; disabling it disables everything inside.
4
+
5
+ - Package: `@nexub/react` · Category: Form & Input · Status: beta
6
+ - Import: `import { Fieldset } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/fieldset
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `legend` (required) | `ReactNode` | | The group’s name, read before each field inside it. |
14
+ | `description` | `ReactNode` | | Hint under the legend, linked with `aria-describedby`. |
15
+ | `disabled` | `boolean` | | Disables every control inside, natively. |
16
+
17
+ ## Example: Grouped fields
18
+
19
+ ```tsx
20
+ import { Fieldset, FormField, Input } from '@nexub/react';
21
+
22
+ export default function Example() {
23
+ return (
24
+ <Fieldset legend="Billing address" description="Printed on every invoice." className="w-full max-w-sm">
25
+ <FormField.Root name="street">
26
+ <FormField.Label>Street</FormField.Label>
27
+ <FormField.Control>
28
+ <Input autoComplete="street-address" />
29
+ </FormField.Control>
30
+ </FormField.Root>
31
+ <FormField.Root name="city">
32
+ <FormField.Label>City</FormField.Label>
33
+ <FormField.Control>
34
+ <Input autoComplete="address-level2" />
35
+ </FormField.Control>
36
+ </FormField.Root>
37
+ </Fieldset>
38
+ );
39
+ }
40
+ ```
41
+
42
+ ## Accessibility
43
+
44
+ - Renders a native `<fieldset>` and `<legend>`; screen readers announce the legend on entering the group.
45
+
46
+ Related: [form](form.md), [form-field](form-field.md)
@@ -0,0 +1,70 @@
1
+ # Form
2
+
3
+ Validates on submit with the browser’s own checks plus yours, shows each message on its FormField and focuses the first invalid field.
4
+
5
+ - Package: `@nexub/react` · Category: Form & Input · Status: beta
6
+ - Import: `import { Form } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/form
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `onSubmit` | `(data: FormData, event) => void \| Promise` | | Runs only when every field is valid. Return a promise to mark the form busy (`aria-busy`, `useForm().submitting`) until it settles. |
14
+ | `validate` | `(data: FormData) => Record<string, string \| false \| null \| undefined>` | | Checks the browser can’t do (cross-field rules, a zod schema, a server answer). Keys are field names; empty values mean valid. |
15
+ | `onInvalidSubmit` | `(errors: FormErrorItem[]) => void` | | Errors in field order after a failed submit, ready for ErrorSummary. |
16
+ | `useForm()` | `{ errors, submitting } \| null` | | Reads the closest Form’s state, for a submit button or a custom field. |
17
+
18
+ ## Example: Native validation plus a custom rule
19
+
20
+ ```tsx
21
+ 'use client';
22
+
23
+ import * as React from 'react';
24
+ import { Button, Form, FormField, Input, useForm } from '@nexub/react';
25
+
26
+ function Submit() {
27
+ const submitting = useForm()?.submitting;
28
+ return (
29
+ <Button type="submit" className="self-start" disabled={submitting}>
30
+ {submitting ? 'Inviting…' : 'Send invite'}
31
+ </Button>
32
+ );
33
+ }
34
+
35
+ export default function Example() {
36
+ const [sent, setSent] = React.useState('');
37
+ return (
38
+ <Form
39
+ className="w-full max-w-sm"
40
+ validate={(data) => ({
41
+ email: String(data.get('email')).endsWith('@example.com') && 'Use a work address, not example.com',
42
+ })}
43
+ onSubmit={async (data) => {
44
+ await new Promise((r) => setTimeout(r, 600));
45
+ setSent(`Invite sent to ${data.get('email')}`);
46
+ }}
47
+ >
48
+ <FormField.Root name="email" required>
49
+ <FormField.Label>Email</FormField.Label>
50
+ <FormField.Control>
51
+ <Input type="email" autoComplete="email" />
52
+ </FormField.Control>
53
+ <FormField.Error />
54
+ </FormField.Root>
55
+ <Submit />
56
+ <p aria-live="polite" className="text-body-sm text-[var(--color-on-surface-muted)]">{sent}</p>
57
+ </Form>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ## Accessibility
63
+
64
+ - `Enter`: Submits from any text field; the first invalid field takes focus.
65
+ - Messages come from the browser’s constraint validation (`required`, `type="email"`, `pattern`, `min`…), so they are already in the reader’s language.
66
+ - FormField.Root with the same `name` picks the message up: the control gets `aria-invalid` and `aria-describedby`, and FormField.Error shows the text.
67
+ - A field’s error clears as soon as it is edited; the rest stay until the next submit.
68
+ - For long forms, render ErrorSummary (@nexub/patterns) from `onInvalidSubmit`.
69
+
70
+ Related: [form-field](form-field.md), [fieldset](fieldset.md)
@@ -0,0 +1,50 @@
1
+ # Inline Edit
2
+
3
+ Text that becomes an input on click, for renaming things in place.
4
+
5
+ - Package: `@nexub/react` · Category: Form & Input · Status: beta
6
+ - Import: `import { InlineEdit } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/inline-edit
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `value` (required) | `string` | | The saved text. |
14
+ | `onSave` (required) | `(value: string) => void \| Promise` | | Called on Enter or blur when the text changed. A promise keeps the field open and busy; a rejection keeps it open and invalid. |
15
+ | `label` (required) | `string` | | Names the input, and the button reads "Edit ‹label›, ‹value›". |
16
+ | `placeholder` | `string` | | Shown when the value is empty. |
17
+ | `disabled` | `boolean` | | Shows the text without editing. |
18
+
19
+ ## Example: Rename
20
+
21
+ ```tsx
22
+ 'use client';
23
+
24
+ import * as React from 'react';
25
+ import { InlineEdit } from '@nexub/react';
26
+
27
+ export default function Example() {
28
+ const [name, setName] = React.useState('Q4 launch plan');
29
+ return (
30
+ <InlineEdit
31
+ label="Project name"
32
+ placeholder="Add a name"
33
+ value={name}
34
+ onSave={(next) => {
35
+ if (!next.trim()) return Promise.reject(new Error('Name is required'));
36
+ setName(next.trim());
37
+ }}
38
+ />
39
+ );
40
+ }
41
+ ```
42
+
43
+ ## Accessibility
44
+
45
+ - `Enter / Space`: On the text: starts editing.
46
+ - `Enter`: In the input: saves.
47
+ - `Escape`: Reverts and returns focus to the text.
48
+ - Moving focus away saves too. Validate in `onSave` and reject to keep the field open.
49
+
50
+ Related: [input](input.md), [form](form.md)
@@ -0,0 +1,40 @@
1
+ # Time Picker
2
+
3
+ A time field on the native time input: 12 or 24 hours from the reader’s locale, and the platform picker on phones.
4
+
5
+ - Package: `@nexub/react` · Category: Form & Input · Status: beta
6
+ - Import: `import { TimePicker } from '@nexub/react';`
7
+ - Docs: https://nexub-ds-docs.pages.dev/components/time-picker
8
+
9
+ ## Props
10
+
11
+ | Prop | Type | Default | Description |
12
+ | --- | --- | --- | --- |
13
+ | `value / defaultValue / onValueChange` | `string` | | 24-hour `"HH:mm"`, whatever the display format. |
14
+ | `minuteStep` | `number` | `1` | Minutes per step for the arrow keys and the picker. |
15
+ | `min / max / required / name` | `string \| boolean` | | Native attributes; Form validates them. |
16
+
17
+ ## Example: Reminder time
18
+
19
+ ```tsx
20
+ import { FormField, TimePicker } from '@nexub/react';
21
+
22
+ export default function Example() {
23
+ return (
24
+ <FormField.Root name="reminder" className="w-40">
25
+ <FormField.Label>Remind me at</FormField.Label>
26
+ <FormField.Control>
27
+ <TimePicker defaultValue="09:00" minuteStep={15} />
28
+ </FormField.Control>
29
+ </FormField.Root>
30
+ );
31
+ }
32
+ ```
33
+
34
+ ## Accessibility
35
+
36
+ - `ArrowUp / ArrowDown`: Changes the focused segment (hour, minute, AM/PM).
37
+ - `ArrowLeft / ArrowRight`: Moves between segments.
38
+ - Native `<input type="time">`: screen readers announce each segment, and phones open their own time picker.
39
+
40
+ Related: [date-time-picker](date-time-picker.md), [date-picker](date-picker.md)
@@ -1,6 +1,6 @@
1
1
  # Component index
2
2
 
3
- Nexub DS v6.0.0. Open `components/<slug>.md` for props, examples and accessibility notes.
3
+ Nexub DS v6.2.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
@@ -36,6 +36,7 @@ Never use a component marked deprecated.
36
36
  - [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
37
  - [Empty State](components/empty-state.md) `@nexub/react`: Placeholder UI shown when a list or page has no content.
38
38
  - [Error State](components/error-state.md) `@nexub/react`: Full-page or section error view with retry action.
39
+ - [Event Calendar](components/event-calendar.md) `@nexub/react`: A month or week grid of events. Display only: your app owns the events and what a click does.
39
40
  - [Funnel](components/funnel.md) `@nexub/react`: Drop-off through ordered steps, with conversion from the first step.
40
41
  - [Gauge](components/gauge.md) `@nexub/react`: Progress toward a target on a 270° arc.
41
42
  - [Heatmap](components/heatmap.md) `@nexub/react`: Intensity over a grid, such as activity by weekday and week, in seven sequential steps.
@@ -67,8 +68,12 @@ Never use a component marked deprecated.
67
68
 
68
69
  - [Date Picker](components/date-picker.md) `@nexub/react`: Calendar date picker with text input.
69
70
  - [Date Range Picker](components/date-range-picker.md) `@nexub/react`: Dual-calendar date range selector.
71
+ - [Date Time Picker](components/date-time-picker.md) `@nexub/react`: A DatePicker and a TimePicker that edit one Date, with an optional time-zone label.
72
+ - [Fieldset](components/fieldset.md) `@nexub/react`: Groups related fields under a legend; disabling it disables everything inside.
73
+ - [Form](components/form.md) `@nexub/react`: Validates on submit with the browser’s own checks plus yours, shows each message on its FormField and focuses the first invalid field.
70
74
  - [Form Field](components/form-field.md) `@nexub/react`: Wraps Label, Input, HelperText and FormError into a single accessible group.
71
75
  - [Helper Text](components/helper-text.md) `@nexub/react`: Small supporting text placed beneath a form field to provide hints or validation feedback.
76
+ - [Inline Edit](components/inline-edit.md) `@nexub/react`: Text that becomes an input on click, for renaming things in place.
72
77
  - [Input](components/input.md) `@nexub/react`: Text input field for forms. Supports size variants, icons, addons, and validation states.
73
78
  - [Label](components/label.md) `@nexub/react`: An accessible form label that optionally shows a required asterisk and links to an input via htmlFor.
74
79
  - [Money Input](components/money-input.md) `@nexub/react`: An amount field: locale-aware parsing as you type, grouped on blur, the currency symbol leading.
@@ -76,6 +81,7 @@ Never use a component marked deprecated.
76
81
  - [Password Input](components/password-input.md) `@nexub/react`: A password field with a built-in toggle to reveal or hide the entered value.
77
82
  - [Search Input](components/search-input.md) `@nexub/react`: A text input pre-wired with a search icon and a clear button for filtering content.
78
83
  - [Textarea](components/textarea.md) `@nexub/react`: A multi-line text input with configurable resize behaviour, size, and validation states.
84
+ - [Time Picker](components/time-picker.md) `@nexub/react`: A time field on the native time input: 12 or 24 hours from the reader’s locale, and the platform picker on phones.
79
85
 
80
86
  ## Components — Form Controls
81
87
 
@@ -1,6 +1,6 @@
1
1
  # Tokens
2
2
 
3
- Nexub DS v6.0.0. Every token is a CSS custom property from `@nexub/tokens/css` (loaded by `@nexub/themes/base`).
3
+ Nexub DS v6.2.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.0.0",
3
+ "version": "6.2.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",