@grampro/kit 2.7.1 → 2.7.3
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.
- package/.gbs/skills/gbs-components/SKILL.md +233 -207
- package/.gbs/skills/gbs-components/references/data-grid.md +9 -0
- package/.gbs/skills/gbs-components/references/forms.md +12 -0
- package/.gbs/skills/gbs-components/references/install.md +42 -5
- package/CHANGELOG.md +963 -798
- package/README.md +13 -4
- package/index.cjs +250 -138
- package/package.json +1 -1
- package/source/components/accordion/passport.json +1 -1
- package/source/components/alert/passport.json +1 -1
- package/source/components/avatar/passport.json +1 -1
- package/source/components/badge/passport.json +1 -1
- package/source/components/breadcrumb/passport.json +1 -1
- package/source/components/button/passport.json +1 -1
- package/source/components/card/passport.json +1 -1
- package/source/components/checkbox/passport.json +2 -2
- package/source/components/checkbox/passport.manual.json +1 -1
- package/source/components/checkbox/react/Checkbox.tsx +14 -0
- package/source/components/combobox/passport.json +3 -2
- package/source/components/combobox/passport.manual.json +1 -1
- package/source/components/combobox/react/MultiSelect.tsx +13 -0
- package/source/components/combobox/react/Select.tsx +13 -0
- package/source/components/combobox/react/surface.ts +70 -0
- package/source/components/data-grid/passport.json +6 -6
- package/source/components/data-grid/react/DataGrid.tsx +353 -351
- package/source/components/date-picker/passport.json +3 -2
- package/source/components/date-picker/passport.manual.json +1 -1
- package/source/components/date-picker/react/DatePicker.tsx +16 -2
- package/source/components/date-picker/react/DateRangePicker.tsx +16 -2
- package/source/components/date-picker/react/surface.ts +68 -0
- package/source/components/dialog/passport.json +1 -1
- package/source/components/file-uploader/passport.json +1 -1
- package/source/components/input/passport.json +2 -2
- package/source/components/input/passport.manual.json +1 -1
- package/source/components/input/react/Input.tsx +21 -0
- package/source/components/menu/passport.json +1 -1
- package/source/components/modal/passport.json +1 -1
- package/source/components/number-input/passport.json +2 -2
- package/source/components/number-input/passport.manual.json +1 -1
- package/source/components/number-input/react/NumberInput.tsx +30 -0
- package/source/components/popover/passport.json +1 -1
- package/source/components/progress/passport.json +1 -1
- package/source/components/radio-group/passport.json +2 -2
- package/source/components/radio-group/passport.manual.json +1 -1
- package/source/components/radio-group/react/RadioGroup.tsx +33 -0
- package/source/components/shared/core/agent/field-executors.ts +173 -137
- package/source/components/shared/core/agent/index.ts +21 -0
- package/source/components/shared/core/agent/surface.ts +437 -0
- package/source/components/shared/core/agent/webmcp.ts +332 -328
- package/source/components/shared/core/agent/write.ts +62 -58
- package/source/components/shared/index.ts +7 -0
- package/source/components/shared/react/AgentSurface.tsx +145 -0
- package/source/components/shared/react/agentSurfaceContext.ts +92 -0
- package/source/components/shared/react/useFieldAgent.ts +62 -88
- package/source/components/shared/version.json +4 -4
- package/source/components/shared/version.ts +6 -6
- package/source/components/skeleton/passport.json +1 -1
- package/source/components/spinner/passport.json +1 -1
- package/source/components/switch/passport.json +2 -2
- package/source/components/switch/passport.manual.json +1 -1
- package/source/components/switch/react/Switch.tsx +16 -0
- package/source/components/tabs/passport.json +1 -1
- package/source/components/textarea/passport.json +2 -2
- package/source/components/textarea/passport.manual.json +1 -1
- package/source/components/textarea/react/Textarea.tsx +16 -0
- package/source/components/toaster/passport.json +1 -1
- package/source/components/tooltip/passport.json +1 -1
- package/tools/doctor/baseline.cjs +228 -0
- package/tools/doctor/contract.cjs +252 -0
- package/tools/doctor/format.cjs +160 -0
- package/tools/doctor/index.cjs +246 -0
- package/tools/doctor/usage.cjs +95 -0
- package/tools/jsx-tags.cjs +120 -0
- package/tools/mcp/server.cjs +60 -41
- package/tools/passport/extract.cjs +22 -40
- package/tools/passport/hash.cjs +56 -0
- package/tools/passport/index.cjs +4 -2
- package/tools/passport/typescript.cjs +220 -0
- package/tools/prompt.cjs +205 -0
- package/tools/ui.cjs +67 -0
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
]
|
|
11
11
|
},
|
|
12
12
|
"source": {
|
|
13
|
-
"libraryVersion": "2.7.
|
|
13
|
+
"libraryVersion": "2.7.3",
|
|
14
14
|
"files": [
|
|
15
15
|
"core/agent.ts",
|
|
16
16
|
"core/group.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"react/locale.ts",
|
|
24
24
|
"react/props.ts"
|
|
25
25
|
],
|
|
26
|
-
"sourceHash": "sha256:
|
|
26
|
+
"sourceHash": "sha256:3bb3c0d76ef4b8d42f6b3bc0a3cdd203a90a1662175ec62ae40eba49ce7ad423"
|
|
27
27
|
},
|
|
28
28
|
"purpose": "A single native checkbox, and CheckboxGroup for several that share a name, with mixed state, a select-all and group-level validation.",
|
|
29
29
|
"props": [
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"intentDomains": [
|
|
6
6
|
"ActionIntent"
|
|
7
7
|
],
|
|
8
|
-
"$operationsNote": "Mirrors shared/core/agent/field.ts, which is what the runtime dispatches on. source/components/shared/core/agent/__tests__/field-passport.test.ts fails if the two drift. No `apiMethod`: a field is written through its ref — the element for most of these, a handle for Combobox and DatePicker — and that is a normal case, not a gap.",
|
|
8
|
+
"$operationsNote": "Mirrors shared/core/agent/field.ts, which is what the runtime dispatches on. source/components/shared/core/agent/__tests__/field-passport.test.ts fails if the two drift. No `apiMethod`: a field is written through its ref — the element for most of these, a handle for Combobox and DatePicker — and that is a normal case, not a gap. Inside an <AgentSurface> the component registers itself with these operations; NumberInput and RadioGroup are then written through their own commit path rather than the element.",
|
|
9
9
|
"operations": {
|
|
10
10
|
"setValue": {
|
|
11
11
|
"summary": "Write a value into the field, as though a person had entered it.",
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from "react";
|
|
15
15
|
import { useControllableState } from "../../shared/react/useControllableState";
|
|
16
16
|
import { describeField } from "../../shared/core/field";
|
|
17
|
+
import { labelText, useAgentSurfaceField } from "../../shared/react/agentSurfaceContext";
|
|
17
18
|
import type { CheckboxSize, CheckedState } from "../core/types";
|
|
18
19
|
import { CheckboxGroupContext } from "./context";
|
|
19
20
|
import { cx, type CheckboxSlot } from "./props";
|
|
@@ -107,6 +108,19 @@ export function Checkbox(props: CheckboxProps) {
|
|
|
107
108
|
onCheckedChange?.(next);
|
|
108
109
|
};
|
|
109
110
|
|
|
111
|
+
// Inside an <AgentSurface>, offered to an agent as a yes/no it can set.
|
|
112
|
+
useAgentSurfaceField(() => ({
|
|
113
|
+
contract: {
|
|
114
|
+
component: "Checkbox",
|
|
115
|
+
kind: "boolean",
|
|
116
|
+
label: labelText(label, inputProps["aria-label"], name, value),
|
|
117
|
+
disabled: disabled || group?.disabled,
|
|
118
|
+
required,
|
|
119
|
+
operations: ["setValue", "clear", "focus"],
|
|
120
|
+
},
|
|
121
|
+
target: () => inputRef.current,
|
|
122
|
+
}));
|
|
123
|
+
|
|
110
124
|
const invalid = Boolean(error) || (group?.invalid ?? false);
|
|
111
125
|
const describedBy = describeField(id, { extra: describedByProp, description, error });
|
|
112
126
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
]
|
|
10
10
|
},
|
|
11
11
|
"source": {
|
|
12
|
-
"libraryVersion": "2.7.
|
|
12
|
+
"libraryVersion": "2.7.3",
|
|
13
13
|
"files": [
|
|
14
14
|
"core/agent.ts",
|
|
15
15
|
"core/filter.ts",
|
|
@@ -24,9 +24,10 @@
|
|
|
24
24
|
"react/icons.tsx",
|
|
25
25
|
"react/locale.ts",
|
|
26
26
|
"react/props.ts",
|
|
27
|
+
"react/surface.ts",
|
|
27
28
|
"react/useCombobox.ts"
|
|
28
29
|
],
|
|
29
|
-
"sourceHash": "sha256:
|
|
30
|
+
"sourceHash": "sha256:c8001ea7c65beeed1b50d9f35cb0fcc447d01cea88128dda3d8b3584bd542496"
|
|
30
31
|
},
|
|
31
32
|
"purpose": "Select and MultiSelect: a searchable combobox for one or many values, with options in the browser's top layer, optional virtualisation and create-on-type.",
|
|
32
33
|
"props": [
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"Recommendation",
|
|
8
8
|
"Classification"
|
|
9
9
|
],
|
|
10
|
-
"$operationsNote": "Mirrors shared/core/agent/field.ts, which is what the runtime dispatches on. source/components/shared/core/agent/__tests__/field-passport.test.ts fails if the two drift. No `apiMethod`: a field is written through its ref — the element for most of these, a handle for Combobox and DatePicker — and that is a normal case, not a gap.",
|
|
10
|
+
"$operationsNote": "Mirrors shared/core/agent/field.ts, which is what the runtime dispatches on. source/components/shared/core/agent/__tests__/field-passport.test.ts fails if the two drift. No `apiMethod`: a field is written through its ref — the element for most of these, a handle for Combobox and DatePicker — and that is a normal case, not a gap. Inside an <AgentSurface> the component registers itself with these operations; NumberInput and RadioGroup are then written through their own commit path rather than the element.",
|
|
11
11
|
"operations": {
|
|
12
12
|
"setValue": {
|
|
13
13
|
"summary": "Write a value into the field, as though a person had entered it.",
|
|
@@ -8,6 +8,7 @@ import { Listbox } from "./Listbox";
|
|
|
8
8
|
import { defaultComboboxText } from "./locale";
|
|
9
9
|
import { ComboboxPopover } from "./Popover";
|
|
10
10
|
import { cx, type ComboboxHandle, type ComboboxSharedProps } from "./props";
|
|
11
|
+
import { useComboboxSurface } from "./surface";
|
|
11
12
|
import { useCombobox } from "./useCombobox";
|
|
12
13
|
|
|
13
14
|
export interface MultiSelectProps<V extends OptionValue = string> extends ComboboxSharedProps<V> {
|
|
@@ -89,6 +90,18 @@ export function MultiSelect<V extends OptionValue = string>(props: MultiSelectPr
|
|
|
89
90
|
const visibleTags = hidden > 0 ? selectedOptions.slice(0, maxVisibleTags) : selectedOptions;
|
|
90
91
|
|
|
91
92
|
useImperativeHandle(ref, () => combobox.handle, [combobox.handle]);
|
|
93
|
+
useComboboxSurface({
|
|
94
|
+
component: "MultiSelect",
|
|
95
|
+
label,
|
|
96
|
+
ariaLabel: props["aria-label"],
|
|
97
|
+
name,
|
|
98
|
+
required,
|
|
99
|
+
disabled,
|
|
100
|
+
options,
|
|
101
|
+
mode: props.mode,
|
|
102
|
+
max: max,
|
|
103
|
+
handle: combobox.handle,
|
|
104
|
+
});
|
|
92
105
|
|
|
93
106
|
const selectableVisible = combobox.entries.filter(
|
|
94
107
|
(entry) => !entry.option.disabled && !combobox.isSelected(entry.option.value),
|
|
@@ -8,6 +8,7 @@ import { ChevronIcon, XIcon } from "./icons";
|
|
|
8
8
|
import { Listbox } from "./Listbox";
|
|
9
9
|
import { ComboboxPopover } from "./Popover";
|
|
10
10
|
import { cx, type ComboboxHandle, type ComboboxSharedProps } from "./props";
|
|
11
|
+
import { useComboboxSurface } from "./surface";
|
|
11
12
|
import { useCombobox } from "./useCombobox";
|
|
12
13
|
|
|
13
14
|
export interface SelectProps<V extends OptionValue = string> extends ComboboxSharedProps<V> {
|
|
@@ -83,6 +84,18 @@ export function Select<V extends OptionValue = string>(props: SelectProps<V>) {
|
|
|
83
84
|
const selected = combobox.selectedOptions[0];
|
|
84
85
|
|
|
85
86
|
useImperativeHandle(ref, () => combobox.handle, [combobox.handle]);
|
|
87
|
+
useComboboxSurface({
|
|
88
|
+
component: "Select",
|
|
89
|
+
label,
|
|
90
|
+
ariaLabel: props["aria-label"],
|
|
91
|
+
name,
|
|
92
|
+
required,
|
|
93
|
+
disabled,
|
|
94
|
+
options,
|
|
95
|
+
mode: props.mode,
|
|
96
|
+
max: undefined,
|
|
97
|
+
handle: combobox.handle,
|
|
98
|
+
});
|
|
86
99
|
|
|
87
100
|
return (
|
|
88
101
|
<div
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { labelText, useAgentSurfaceField } from "../../shared/react/agentSurfaceContext";
|
|
4
|
+
import type { ComboboxOption, OptionValue } from "../core/types";
|
|
5
|
+
import type { ComboboxHandle } from "./props";
|
|
6
|
+
|
|
7
|
+
interface ComboboxSurfaceParams<V extends OptionValue> {
|
|
8
|
+
component: "Select" | "MultiSelect";
|
|
9
|
+
label: unknown;
|
|
10
|
+
ariaLabel: unknown;
|
|
11
|
+
name?: string;
|
|
12
|
+
required: boolean;
|
|
13
|
+
disabled: boolean;
|
|
14
|
+
options: readonly ComboboxOption<V>[];
|
|
15
|
+
mode?: "client" | "server";
|
|
16
|
+
max?: number;
|
|
17
|
+
handle: ComboboxHandle<V>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Inside an <AgentSurface>, offer a Select or MultiSelect with its options.
|
|
22
|
+
*
|
|
23
|
+
* An agent speaks in strings and an option's value may be a number, so values
|
|
24
|
+
* are offered as text and mapped back to the option they came from before the
|
|
25
|
+
* write. In server mode the options are only the current results, so none are
|
|
26
|
+
* enumerated: the set is the server's, not the component's.
|
|
27
|
+
*/
|
|
28
|
+
export function useComboboxSurface<V extends OptionValue>(params: ComboboxSurfaceParams<V>): void {
|
|
29
|
+
useAgentSurfaceField(() => {
|
|
30
|
+
const { component, options, handle } = params;
|
|
31
|
+
const multiple = component === "MultiSelect";
|
|
32
|
+
const enumerate = params.mode !== "server";
|
|
33
|
+
const back = (value: unknown): V => {
|
|
34
|
+
const text = String(value);
|
|
35
|
+
return (options.find((option) => String(option.value) === text)?.value ?? text) as V;
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
contract: {
|
|
39
|
+
component,
|
|
40
|
+
kind: multiple ? "multiChoice" : "choice",
|
|
41
|
+
label: labelText(params.label, params.ariaLabel, params.name),
|
|
42
|
+
disabled: params.disabled,
|
|
43
|
+
required: params.required,
|
|
44
|
+
...(enumerate
|
|
45
|
+
? {
|
|
46
|
+
options: options.map((option) => ({
|
|
47
|
+
value: String(option.value),
|
|
48
|
+
label: option.label,
|
|
49
|
+
...(option.disabled ? { disabled: true } : {}),
|
|
50
|
+
})),
|
|
51
|
+
}
|
|
52
|
+
: {}),
|
|
53
|
+
...(multiple && params.max !== undefined ? { maxSelected: params.max } : {}),
|
|
54
|
+
operations: ["setValue", "clear", "focus", "open", "close"],
|
|
55
|
+
},
|
|
56
|
+
target: () => ({
|
|
57
|
+
setValue: (next) =>
|
|
58
|
+
handle.setValue(
|
|
59
|
+
(next == null ? null : Array.isArray(next) ? next.map(back) : back(next)) as Parameters<
|
|
60
|
+
ComboboxHandle<V>["setValue"]
|
|
61
|
+
>[0],
|
|
62
|
+
),
|
|
63
|
+
clear: handle.clear,
|
|
64
|
+
focus: handle.focus,
|
|
65
|
+
open: handle.open,
|
|
66
|
+
close: handle.close,
|
|
67
|
+
}),
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
]
|
|
15
15
|
},
|
|
16
16
|
"source": {
|
|
17
|
-
"libraryVersion": "2.7.
|
|
17
|
+
"libraryVersion": "2.7.3",
|
|
18
18
|
"files": [
|
|
19
19
|
"agent/coerce.ts",
|
|
20
20
|
"agent/contract.ts",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"react/keyboard.ts",
|
|
65
65
|
"react/locale.ts"
|
|
66
66
|
],
|
|
67
|
-
"sourceHash": "sha256:
|
|
67
|
+
"sourceHash": "sha256:1047a3723ee462533fa5b82741d89309723cecedc71ea4b1339176a50ced0545"
|
|
68
68
|
},
|
|
69
69
|
"purpose": "Display and operate on tabular data. Virtualized; holds its own sort, filter, search, selection, column and pagination state in an external store exposed through GridApi.",
|
|
70
70
|
"props": [
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"required": false,
|
|
94
94
|
"default": false,
|
|
95
95
|
"origin": "derived",
|
|
96
|
-
"description": "Render a natural-language box above the grid.\
|
|
96
|
+
"description": "Render a natural-language box above the grid.\n\nNeeds a `<GramproAIProvider>` above it supplying an adapter; without one\nthis renders nothing and the grid is unchanged. No model is bundled or\ndownloaded — the application brings its own.",
|
|
97
97
|
"descriptionOrigin": "jsdoc"
|
|
98
98
|
},
|
|
99
99
|
{
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
"typeText": "ReactNode",
|
|
153
153
|
"required": false,
|
|
154
154
|
"origin": "derived",
|
|
155
|
-
"description": "Shown in place of rows when there are none. Worth distinguishing \"nothing\
|
|
155
|
+
"description": "Shown in place of rows when there are none. Worth distinguishing \"nothing\nhere yet\" from \"nothing matched your filters\", which the default does not.",
|
|
156
156
|
"descriptionOrigin": "jsdoc"
|
|
157
157
|
},
|
|
158
158
|
{
|
|
@@ -306,7 +306,7 @@
|
|
|
306
306
|
"required": false,
|
|
307
307
|
"default": false,
|
|
308
308
|
"origin": "derived",
|
|
309
|
-
"description": "Show the loading treatment over the grid. The existing rows stay in place\
|
|
309
|
+
"description": "Show the loading treatment over the grid. The existing rows stay in place\nunderneath, so a refresh does not empty the screen.",
|
|
310
310
|
"descriptionOrigin": "jsdoc"
|
|
311
311
|
},
|
|
312
312
|
{
|
|
@@ -483,7 +483,7 @@
|
|
|
483
483
|
"required": false,
|
|
484
484
|
"default": true,
|
|
485
485
|
"origin": "derived",
|
|
486
|
-
"description": "The toolbar above the grid. `true` for all of it, `false` for none, or an\
|
|
486
|
+
"description": "The toolbar above the grid. `true` for all of it, `false` for none, or an\nobject to choose parts — `{ search: true, export: false }` — and to put\nyour own controls at its `start` or `end`.",
|
|
487
487
|
"descriptionOrigin": "jsdoc"
|
|
488
488
|
}
|
|
489
489
|
],
|