@actuate-media/cms-admin 0.11.0 → 0.12.1
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/LICENSE +21 -21
- package/dist/__tests__/components/comment-mark.test.d.ts +2 -0
- package/dist/__tests__/components/comment-mark.test.d.ts.map +1 -0
- package/dist/__tests__/components/comment-mark.test.js +89 -0
- package/dist/__tests__/components/comment-mark.test.js.map +1 -0
- package/dist/__tests__/components/comment-side-panel.test.d.ts +2 -0
- package/dist/__tests__/components/comment-side-panel.test.d.ts.map +1 -0
- package/dist/__tests__/components/comment-side-panel.test.js +291 -0
- package/dist/__tests__/components/comment-side-panel.test.js.map +1 -0
- package/dist/__tests__/components/notification-bell.test.d.ts +2 -0
- package/dist/__tests__/components/notification-bell.test.d.ts.map +1 -0
- package/dist/__tests__/components/notification-bell.test.js +200 -0
- package/dist/__tests__/components/notification-bell.test.js.map +1 -0
- package/dist/__tests__/components/offline-status.test.d.ts +2 -0
- package/dist/__tests__/components/offline-status.test.d.ts.map +1 -0
- package/dist/__tests__/components/offline-status.test.js +56 -0
- package/dist/__tests__/components/offline-status.test.js.map +1 -0
- package/dist/__tests__/components/presence-chips-helpers.test.d.ts +2 -0
- package/dist/__tests__/components/presence-chips-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/components/presence-chips-helpers.test.js +35 -0
- package/dist/__tests__/components/presence-chips-helpers.test.js.map +1 -0
- package/dist/__tests__/fields/component-block-helpers.test.d.ts +7 -0
- package/dist/__tests__/fields/component-block-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/fields/component-block-helpers.test.js +592 -0
- package/dist/__tests__/fields/component-block-helpers.test.js.map +1 -0
- package/dist/__tests__/lib/active-editor.test.d.ts +2 -0
- package/dist/__tests__/lib/active-editor.test.d.ts.map +1 -0
- package/dist/__tests__/lib/active-editor.test.js +57 -0
- package/dist/__tests__/lib/active-editor.test.js.map +1 -0
- package/dist/__tests__/lib/coauthor-client.test.d.ts +2 -0
- package/dist/__tests__/lib/coauthor-client.test.d.ts.map +1 -0
- package/dist/__tests__/lib/coauthor-client.test.js +173 -0
- package/dist/__tests__/lib/coauthor-client.test.js.map +1 -0
- package/dist/__tests__/lib/collaboration-provider.test.d.ts +2 -0
- package/dist/__tests__/lib/collaboration-provider.test.d.ts.map +1 -0
- package/dist/__tests__/lib/collaboration-provider.test.js +335 -0
- package/dist/__tests__/lib/collaboration-provider.test.js.map +1 -0
- package/dist/__tests__/lib/comment-anchor.test.d.ts +2 -0
- package/dist/__tests__/lib/comment-anchor.test.d.ts.map +1 -0
- package/dist/__tests__/lib/comment-anchor.test.js +173 -0
- package/dist/__tests__/lib/comment-anchor.test.js.map +1 -0
- package/dist/__tests__/lib/comments-client.test.d.ts +2 -0
- package/dist/__tests__/lib/comments-client.test.d.ts.map +1 -0
- package/dist/__tests__/lib/comments-client.test.js +202 -0
- package/dist/__tests__/lib/comments-client.test.js.map +1 -0
- package/dist/__tests__/lib/notifications-client.test.d.ts +2 -0
- package/dist/__tests__/lib/notifications-client.test.d.ts.map +1 -0
- package/dist/__tests__/lib/notifications-client.test.js +155 -0
- package/dist/__tests__/lib/notifications-client.test.js.map +1 -0
- package/dist/__tests__/lib/slash-command.test.d.ts +2 -0
- package/dist/__tests__/lib/slash-command.test.d.ts.map +1 -0
- package/dist/__tests__/lib/slash-command.test.js +123 -0
- package/dist/__tests__/lib/slash-command.test.js.map +1 -0
- package/dist/actuate-admin.css +1 -1
- package/dist/components/AICoauthorBubbleMenu.d.ts +18 -0
- package/dist/components/AICoauthorBubbleMenu.d.ts.map +1 -0
- package/dist/components/AICoauthorBubbleMenu.js +113 -0
- package/dist/components/AICoauthorBubbleMenu.js.map +1 -0
- package/dist/components/CoauthorResultPopover.d.ts +28 -0
- package/dist/components/CoauthorResultPopover.d.ts.map +1 -0
- package/dist/components/CoauthorResultPopover.js +42 -0
- package/dist/components/CoauthorResultPopover.js.map +1 -0
- package/dist/components/CommandPalette.d.ts +1 -1
- package/dist/components/CommandPalette.d.ts.map +1 -1
- package/dist/components/CommandPalette.js +138 -40
- package/dist/components/CommandPalette.js.map +1 -1
- package/dist/components/CommentMark.d.ts +54 -0
- package/dist/components/CommentMark.d.ts.map +1 -0
- package/dist/components/CommentMark.js +104 -0
- package/dist/components/CommentMark.js.map +1 -0
- package/dist/components/CommentSidePanel.d.ts +86 -0
- package/dist/components/CommentSidePanel.d.ts.map +1 -0
- package/dist/components/CommentSidePanel.js +165 -0
- package/dist/components/CommentSidePanel.js.map +1 -0
- package/dist/components/LivePreview.d.ts.map +1 -1
- package/dist/components/LivePreview.js +80 -16
- package/dist/components/LivePreview.js.map +1 -1
- package/dist/components/NotificationBell.d.ts +45 -0
- package/dist/components/NotificationBell.d.ts.map +1 -0
- package/dist/components/NotificationBell.js +90 -0
- package/dist/components/NotificationBell.js.map +1 -0
- package/dist/components/OfflineStatus.d.ts +39 -0
- package/dist/components/OfflineStatus.d.ts.map +1 -0
- package/dist/components/OfflineStatus.js +47 -0
- package/dist/components/OfflineStatus.js.map +1 -0
- package/dist/components/PresenceChips.d.ts +31 -0
- package/dist/components/PresenceChips.d.ts.map +1 -0
- package/dist/components/PresenceChips.js +58 -0
- package/dist/components/PresenceChips.js.map +1 -0
- package/dist/components/TipTapEditor.d.ts +61 -1
- package/dist/components/TipTapEditor.d.ts.map +1 -1
- package/dist/components/TipTapEditor.js +211 -8
- package/dist/components/TipTapEditor.js.map +1 -1
- package/dist/components/ui/Badge.d.ts +1 -1
- package/dist/fields/ComponentBlockField.d.ts +25 -0
- package/dist/fields/ComponentBlockField.d.ts.map +1 -0
- package/dist/fields/ComponentBlockField.js +74 -0
- package/dist/fields/ComponentBlockField.js.map +1 -0
- package/dist/fields/FieldRenderer.d.ts +3 -0
- package/dist/fields/FieldRenderer.d.ts.map +1 -1
- package/dist/fields/FieldRenderer.js +3 -1
- package/dist/fields/FieldRenderer.js.map +1 -1
- package/dist/fields/PropInput.d.ts +14 -0
- package/dist/fields/PropInput.d.ts.map +1 -0
- package/dist/fields/PropInput.js +163 -0
- package/dist/fields/PropInput.js.map +1 -0
- package/dist/fields/component-block-helpers.d.ts +96 -0
- package/dist/fields/component-block-helpers.d.ts.map +1 -0
- package/dist/fields/component-block-helpers.js +323 -0
- package/dist/fields/component-block-helpers.js.map +1 -0
- package/dist/fields/index.d.ts +4 -0
- package/dist/fields/index.d.ts.map +1 -1
- package/dist/fields/index.js +2 -0
- package/dist/fields/index.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/active-editor.d.ts +6 -0
- package/dist/lib/active-editor.d.ts.map +1 -0
- package/dist/lib/active-editor.js +35 -0
- package/dist/lib/active-editor.js.map +1 -0
- package/dist/lib/coauthor-client.d.ts +72 -0
- package/dist/lib/coauthor-client.d.ts.map +1 -0
- package/dist/lib/coauthor-client.js +98 -0
- package/dist/lib/coauthor-client.js.map +1 -0
- package/dist/lib/collaboration-provider.d.ts +142 -0
- package/dist/lib/collaboration-provider.d.ts.map +1 -0
- package/dist/lib/collaboration-provider.js +168 -0
- package/dist/lib/collaboration-provider.js.map +1 -0
- package/dist/lib/comment-anchor.d.ts +86 -0
- package/dist/lib/comment-anchor.d.ts.map +1 -0
- package/dist/lib/comment-anchor.js +139 -0
- package/dist/lib/comment-anchor.js.map +1 -0
- package/dist/lib/comments-client.d.ts +106 -0
- package/dist/lib/comments-client.d.ts.map +1 -0
- package/dist/lib/comments-client.js +138 -0
- package/dist/lib/comments-client.js.map +1 -0
- package/dist/lib/notifications-client.d.ts +68 -0
- package/dist/lib/notifications-client.d.ts.map +1 -0
- package/dist/lib/notifications-client.js +85 -0
- package/dist/lib/notifications-client.js.map +1 -0
- package/dist/lib/slash-command.d.ts +39 -0
- package/dist/lib/slash-command.d.ts.map +1 -0
- package/dist/lib/slash-command.js +50 -0
- package/dist/lib/slash-command.js.map +1 -0
- package/package.json +20 -4
- package/src/__tests__/components/comment-mark.test.ts +99 -0
- package/src/__tests__/components/comment-side-panel.test.tsx +343 -0
- package/src/__tests__/components/notification-bell.test.tsx +213 -0
- package/src/__tests__/components/offline-status.test.tsx +66 -0
- package/src/__tests__/components/presence-chips-helpers.test.ts +44 -0
- package/src/__tests__/fields/component-block-helpers.test.ts +674 -0
- package/src/__tests__/lib/active-editor.test.ts +70 -0
- package/src/__tests__/lib/coauthor-client.test.ts +213 -0
- package/src/__tests__/lib/collaboration-provider.test.ts +425 -0
- package/src/__tests__/lib/comment-anchor.test.ts +188 -0
- package/src/__tests__/lib/comments-client.test.ts +239 -0
- package/src/__tests__/lib/notifications-client.test.ts +195 -0
- package/src/__tests__/lib/slash-command.test.ts +146 -0
- package/src/components/AICoauthorBubbleMenu.tsx +187 -0
- package/src/components/CoauthorResultPopover.tsx +193 -0
- package/src/components/CommandPalette.tsx +397 -209
- package/src/components/CommentMark.ts +138 -0
- package/src/components/CommentSidePanel.tsx +521 -0
- package/src/components/LivePreview.tsx +117 -11
- package/src/components/NotificationBell.tsx +242 -0
- package/src/components/OfflineStatus.tsx +90 -0
- package/src/components/PresenceChips.tsx +150 -0
- package/src/components/TipTapEditor.tsx +310 -12
- package/src/fields/ComponentBlockField.tsx +179 -0
- package/src/fields/FieldRenderer.tsx +8 -0
- package/src/fields/PropInput.tsx +552 -0
- package/src/fields/component-block-helpers.ts +341 -0
- package/src/fields/index.ts +4 -0
- package/src/index.ts +27 -0
- package/src/lib/active-editor.ts +39 -0
- package/src/lib/coauthor-client.ts +160 -0
- package/src/lib/collaboration-provider.ts +306 -0
- package/src/lib/comment-anchor.ts +179 -0
- package/src/lib/comments-client.ts +208 -0
- package/src/lib/notifications-client.ts +146 -0
- package/src/lib/slash-command.ts +67 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Recursive input dispatcher for component-block props. Given a
|
|
5
|
+
* {@link PropSpec} and the currently stored value, renders the correct
|
|
6
|
+
* editor:
|
|
7
|
+
*
|
|
8
|
+
* | PropType.kind | Editor |
|
|
9
|
+
* | --------------------- | ---------------------------------------------- |
|
|
10
|
+
* | `string` | single-line text input |
|
|
11
|
+
* | `number` | native number input |
|
|
12
|
+
* | `boolean` | switch (ToggleField look) |
|
|
13
|
+
* | `enum` | select with the literal values |
|
|
14
|
+
* | `literal` | readonly display (it's the only allowed value) |
|
|
15
|
+
* | `array` | add/remove list of recursive PropInputs |
|
|
16
|
+
* | `object` | bordered group of recursive PropInputs |
|
|
17
|
+
* | `union` (discriminated) | variant picker + recursive object form |
|
|
18
|
+
* | `union` (other) | JSON textarea + hint |
|
|
19
|
+
* | `reference` | JSON textarea + "unresolved" hint |
|
|
20
|
+
* | `unknown` | JSON textarea + warning |
|
|
21
|
+
*
|
|
22
|
+
* The component is intentionally small and self-contained — no calls
|
|
23
|
+
* into cms-core; the parent {@link ComponentBlockField} runs validation
|
|
24
|
+
* via `validateComponentBlockValue` and pipes per-prop errors back in
|
|
25
|
+
* via the `errors` prop.
|
|
26
|
+
*/
|
|
27
|
+
import { detectDiscriminator, findVariant, } from '@actuate-media/component-blocks/discriminated-union';
|
|
28
|
+
import { defaultForType, parseEnumSelection, safeJsonStringify, switchUnionVariant, } from './component-block-helpers.js';
|
|
29
|
+
export { defaultForType };
|
|
30
|
+
export function PropInput({ prop, value, onChange, errors, path }) {
|
|
31
|
+
const fullPath = path ?? prop.name;
|
|
32
|
+
const safeErrors = errors ?? EMPTY_ERRORS;
|
|
33
|
+
const error = safeErrors[fullPath];
|
|
34
|
+
return (_jsxs("div", { className: "space-y-1", children: [_jsx(PropInputBody, { prop: prop, value: value, onChange: onChange, errors: safeErrors, path: fullPath }), prop.description && !error ? (_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: prop.description })) : null, error ? _jsx("p", { className: "text-xs text-[var(--destructive)]", children: error }) : null] }));
|
|
35
|
+
}
|
|
36
|
+
const EMPTY_ERRORS = Object.freeze({});
|
|
37
|
+
function PropInputBody({ prop, value, onChange, errors, path }) {
|
|
38
|
+
const type = prop.type;
|
|
39
|
+
switch (type.kind) {
|
|
40
|
+
case 'string':
|
|
41
|
+
return _jsx(StringInput, { label: fieldLabel(prop), value: value, onChange: onChange });
|
|
42
|
+
case 'number':
|
|
43
|
+
return _jsx(NumberInputControl, { label: fieldLabel(prop), value: value, onChange: onChange });
|
|
44
|
+
case 'boolean':
|
|
45
|
+
return _jsx(BooleanInput, { label: fieldLabel(prop), value: value, onChange: onChange });
|
|
46
|
+
case 'enum':
|
|
47
|
+
return (_jsx(EnumInput, { label: fieldLabel(prop), options: type.values, value: value, onChange: onChange }));
|
|
48
|
+
case 'literal':
|
|
49
|
+
return _jsx(LiteralDisplay, { label: fieldLabel(prop), literal: type.value });
|
|
50
|
+
case 'array':
|
|
51
|
+
return (_jsx(ArrayInput, { label: fieldLabel(prop), itemType: type.itemType, itemPath: path, value: value, onChange: onChange, errors: errors }));
|
|
52
|
+
case 'object':
|
|
53
|
+
return (_jsx(ObjectInput, { label: fieldLabel(prop), fields: type.fields, value: value, onChange: onChange, errors: errors, path: path }));
|
|
54
|
+
case 'union': {
|
|
55
|
+
const detected = detectDiscriminator(type);
|
|
56
|
+
if (detected) {
|
|
57
|
+
return (_jsx(DiscriminatedUnionInput, { label: fieldLabel(prop), union: detected, value: value, onChange: onChange, errors: errors, path: path }));
|
|
58
|
+
}
|
|
59
|
+
return (_jsx(JsonFallback, { label: fieldLabel(prop), value: value, onChange: onChange, hint: fallbackHint(type) }));
|
|
60
|
+
}
|
|
61
|
+
case 'reference':
|
|
62
|
+
case 'unknown':
|
|
63
|
+
default:
|
|
64
|
+
return (_jsx(JsonFallback, { label: fieldLabel(prop), value: value, onChange: onChange, hint: fallbackHint(type) }));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function fieldLabel(prop) {
|
|
68
|
+
return (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-medium", children: prop.name }), prop.required ? _jsx("span", { className: "ml-0.5 text-[var(--destructive)]", children: "*" }) : null] }));
|
|
69
|
+
}
|
|
70
|
+
function fallbackHint(type) {
|
|
71
|
+
if (type.kind === 'reference') {
|
|
72
|
+
return `Type '${type.targetType}' could not be resolved — paste a raw JSON value for now.`;
|
|
73
|
+
}
|
|
74
|
+
if (type.kind === 'union') {
|
|
75
|
+
return 'Non-discriminated union — paste a raw JSON value (the form renders a picker for unions with a shared literal tag field like `kind`).';
|
|
76
|
+
}
|
|
77
|
+
return 'Unknown type — paste a raw JSON value.';
|
|
78
|
+
}
|
|
79
|
+
// ─── Primitive editors ───────────────────────────────────────────────
|
|
80
|
+
function StringInput({ label, value, onChange, }) {
|
|
81
|
+
const stringVal = typeof value === 'string' ? value : '';
|
|
82
|
+
return (_jsxs("label", { className: "block text-sm", children: [_jsx("div", { className: "mb-1", children: label }), _jsx("input", { type: "text", value: stringVal, onChange: (e) => onChange(e.target.value), className: "w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-[var(--ring)]" })] }));
|
|
83
|
+
}
|
|
84
|
+
function NumberInputControl({ label, value, onChange, }) {
|
|
85
|
+
const numericVal = typeof value === 'number' ? value : '';
|
|
86
|
+
return (_jsxs("label", { className: "block text-sm", children: [_jsx("div", { className: "mb-1", children: label }), _jsx("input", { type: "number", value: numericVal === '' ? '' : numericVal, onChange: (e) => {
|
|
87
|
+
const raw = e.target.value;
|
|
88
|
+
if (raw === '') {
|
|
89
|
+
onChange(undefined);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const parsed = Number(raw);
|
|
93
|
+
onChange(Number.isNaN(parsed) ? raw : parsed);
|
|
94
|
+
}, className: "w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-[var(--ring)]" })] }));
|
|
95
|
+
}
|
|
96
|
+
function BooleanInput({ label, value, onChange, }) {
|
|
97
|
+
const boolVal = value === true;
|
|
98
|
+
return (_jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("span", { children: label }), _jsx("button", { type: "button", role: "switch", "aria-checked": boolVal, onClick: () => onChange(!boolVal), className: `relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors ${boolVal ? 'bg-[var(--primary)]' : 'bg-[var(--muted)]'}`, children: _jsx("span", { className: `pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow-sm ring-0 transition-transform ${boolVal ? 'translate-x-5' : 'translate-x-0'}` }) })] }));
|
|
99
|
+
}
|
|
100
|
+
function EnumInput({ label, options, value, onChange, }) {
|
|
101
|
+
const currentIdx = options.findIndex((o) => o === value);
|
|
102
|
+
return (_jsxs("label", { className: "block text-sm", children: [_jsx("div", { className: "mb-1", children: label }), _jsxs("select", { value: currentIdx === -1 ? '' : String(currentIdx), onChange: (e) => {
|
|
103
|
+
onChange(parseEnumSelection(e.target.value, options));
|
|
104
|
+
}, className: "w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-[var(--ring)]", children: [_jsx("option", { value: "", children: "Select\u2026" }), options.map((opt, idx) => (_jsx("option", { value: idx, children: String(opt) }, String(opt))))] })] }));
|
|
105
|
+
}
|
|
106
|
+
function LiteralDisplay({ label, literal, }) {
|
|
107
|
+
return (_jsxs("div", { className: "text-sm", children: [_jsx("div", { className: "mb-1", children: label }), _jsxs("div", { className: "rounded-md border border-dashed border-[var(--border)] bg-[var(--muted)] px-3 py-2 text-xs text-[var(--muted-foreground)]", children: ["Fixed: ", _jsx("code", { children: String(literal) })] })] }));
|
|
108
|
+
}
|
|
109
|
+
// ─── Composite editors ───────────────────────────────────────────────
|
|
110
|
+
function ObjectInput({ label, fields, value, onChange, errors, path, }) {
|
|
111
|
+
const obj = isPlainObject(value) ? value : {};
|
|
112
|
+
return (_jsxs("fieldset", { className: "rounded-md border border-[var(--border)] bg-[var(--card)] p-3 text-sm", children: [_jsx("legend", { className: "px-1 text-xs tracking-wide text-[var(--muted-foreground)] uppercase", children: label }), _jsx("div", { className: "space-y-3", children: fields.map((field) => (_jsx(PropInput, { prop: field, value: obj[field.name], onChange: (next) => onChange({ ...obj, [field.name]: next }), errors: errors, path: `${path}.${field.name}` }, field.name))) })] }));
|
|
113
|
+
}
|
|
114
|
+
function ArrayInput({ label, itemType, itemPath, value, onChange, errors, }) {
|
|
115
|
+
const arr = Array.isArray(value) ? value : [];
|
|
116
|
+
return (_jsxs("div", { className: "text-sm", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsx("span", { children: label }), _jsx("button", { type: "button", onClick: () => onChange([...arr, defaultForType(itemType)]), className: "rounded-md border border-[var(--border)] bg-[var(--input-background)] px-2 py-1 text-xs text-[var(--foreground)] hover:bg-[var(--accent)]", children: "+ Add" })] }), arr.length === 0 ? (_jsx("div", { className: "rounded-md border border-dashed border-[var(--border)] px-3 py-4 text-center text-xs text-[var(--muted-foreground)]", children: "No items yet" })) : (_jsx("ol", { className: "space-y-2", children: arr.map((item, idx) => (_jsxs("li", { className: "rounded-md border border-[var(--border)] bg-[var(--card)] p-3", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between text-xs text-[var(--muted-foreground)]", children: [_jsxs("span", { children: ["Item ", idx + 1] }), _jsx("button", { type: "button", onClick: () => onChange(arr.filter((_, i) => i !== idx)), className: "text-[var(--destructive)] hover:underline", children: "Remove" })] }), _jsx(PropInput, { prop: { name: `[${idx}]`, type: itemType, required: true }, value: item, onChange: (next) => onChange(arr.map((v, i) => (i === idx ? next : v))), errors: errors, path: `${itemPath}[${idx}]` })] }, idx))) }))] }));
|
|
117
|
+
}
|
|
118
|
+
function DiscriminatedUnionInput({ label, union, value, onChange, errors, path, }) {
|
|
119
|
+
const currentVariant = findVariant(value, union);
|
|
120
|
+
const obj = isPlainObject(value) ? value : {};
|
|
121
|
+
function switchTo(variantIdx) {
|
|
122
|
+
const variant = union.variants[variantIdx];
|
|
123
|
+
if (!variant)
|
|
124
|
+
return;
|
|
125
|
+
onChange(switchUnionVariant(value, union, variant));
|
|
126
|
+
}
|
|
127
|
+
const currentIdx = currentVariant
|
|
128
|
+
? union.variants.findIndex((v) => v.value === currentVariant.value)
|
|
129
|
+
: -1;
|
|
130
|
+
return (_jsxs("fieldset", { className: "rounded-md border border-[var(--border)] bg-[var(--card)] p-3 text-sm", children: [_jsx("legend", { className: "px-1 text-xs tracking-wide text-[var(--muted-foreground)] uppercase", children: label }), _jsxs("div", { className: "space-y-3", children: [_jsxs("label", { className: "block text-sm", children: [_jsxs("div", { className: "mb-1", children: [_jsx("span", { className: "font-medium", children: union.field }), _jsx("span", { className: "ml-0.5 text-[var(--destructive)]", children: "*" }), _jsx("span", { className: "ml-2 text-xs text-[var(--muted-foreground)]", children: "(variant)" })] }), _jsxs("select", { value: currentIdx === -1 ? '' : String(currentIdx), onChange: (e) => {
|
|
131
|
+
const idx = Number(e.target.value);
|
|
132
|
+
if (Number.isInteger(idx) && idx >= 0 && idx < union.variants.length) {
|
|
133
|
+
switchTo(idx);
|
|
134
|
+
}
|
|
135
|
+
}, className: "w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-[var(--ring)]", children: [_jsx("option", { value: "", disabled: true, children: "Select a variant\u2026" }), union.variants.map((variant, idx) => (_jsx("option", { value: idx, children: String(variant.value) }, String(variant.value))))] })] }), currentVariant && currentVariant.remainingFields.length > 0 ? (_jsx("div", { className: "space-y-3", children: currentVariant.remainingFields.map((field) => (_jsx(PropInput, { prop: field, value: obj[field.name], onChange: (next) => onChange({ ...obj, [field.name]: next }), errors: errors, path: `${path}.${field.name}` }, field.name))) })) : null, !currentVariant ? (_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Pick a variant to configure its fields." })) : null] })] }));
|
|
136
|
+
}
|
|
137
|
+
function JsonFallback({ label, value, onChange, hint, }) {
|
|
138
|
+
// Treat both `undefined` and `null` as "empty" — `null` arrives as
|
|
139
|
+
// the structural default for kinds we can't seed (union / reference /
|
|
140
|
+
// unknown) and also from a JSON round-trip on `undefined`. Rendering
|
|
141
|
+
// the literal string "null" would surface as broken UX.
|
|
142
|
+
const text = value === undefined || value === null ? '' : safeJsonStringify(value);
|
|
143
|
+
return (_jsxs("label", { className: "block text-sm", children: [_jsx("div", { className: "mb-1", children: label }), _jsx("textarea", { value: text, onChange: (e) => {
|
|
144
|
+
const raw = e.target.value;
|
|
145
|
+
if (raw.trim() === '') {
|
|
146
|
+
onChange(undefined);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
onChange(JSON.parse(raw));
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Keep the raw string so the user can finish editing without
|
|
154
|
+
// losing focus; the validator will catch it on save.
|
|
155
|
+
onChange(raw);
|
|
156
|
+
}
|
|
157
|
+
}, rows: 3, className: "w-full rounded-md border border-[var(--border)] bg-[var(--input-background)] px-3 py-2 font-mono text-xs outline-none focus:ring-2 focus:ring-[var(--ring)]" }), _jsx("p", { className: "mt-1 text-xs text-[var(--muted-foreground)]", children: hint })] }));
|
|
158
|
+
}
|
|
159
|
+
// ─── Helpers ─────────────────────────────────────────────────────────
|
|
160
|
+
function isPlainObject(v) {
|
|
161
|
+
return v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=PropInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropInput.js","sourceRoot":"","sources":["../../src/fields/PropInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers behind `<ComponentBlockField>`. Extracted so vitest can
|
|
3
|
+
* exercise them in node without spinning up jsdom — the React component
|
|
4
|
+
* just composes these into UI.
|
|
5
|
+
*
|
|
6
|
+
* Kept structurally typed (no peer-dep import of types here would be
|
|
7
|
+
* cleaner, but the `PropType` discriminated union is the contract we
|
|
8
|
+
* promise consumers, so we lean on the package's types).
|
|
9
|
+
*/
|
|
10
|
+
import type { DiscriminatedUnion, DiscriminatedVariant } from '@actuate-media/component-blocks/discriminated-union';
|
|
11
|
+
import type { ComponentSpec, Manifest, PropType } from '@actuate-media/component-blocks';
|
|
12
|
+
import type { ComponentBlockValue } from './ComponentBlockField.js';
|
|
13
|
+
/**
|
|
14
|
+
* Compute the list of components an editor can pick from given the
|
|
15
|
+
* manifest + the optional allow-list. Returns the full list when no
|
|
16
|
+
* filter is provided; returns `[]` when every entry is filtered out
|
|
17
|
+
* (the caller renders an error in that case).
|
|
18
|
+
*/
|
|
19
|
+
export declare function getAllowedComponents(manifest: Manifest, allow: string[] | undefined): ComponentSpec[];
|
|
20
|
+
/**
|
|
21
|
+
* JSON-encode any value so it round-trips cleanly through the
|
|
22
|
+
* JsonFallback textarea. Previously the helper short-circuited for
|
|
23
|
+
* strings (returning the raw string), which made the textarea
|
|
24
|
+
* stateful: typing `"hello"` parsed to the JS string `hello`,
|
|
25
|
+
* re-rendered as bare `hello`, then `JSON.parse('hello')` threw on
|
|
26
|
+
* the next edit and the field "locked" as a raw string. Always
|
|
27
|
+
* stringifying keeps the textarea visually consistent with the
|
|
28
|
+
* underlying JSON value.
|
|
29
|
+
*
|
|
30
|
+
* Falls back to `String(v)` for values that can't be JSON-encoded
|
|
31
|
+
* (e.g. circular refs) so the field remains editable.
|
|
32
|
+
*/
|
|
33
|
+
export declare function safeJsonStringify(v: unknown): string;
|
|
34
|
+
/**
|
|
35
|
+
* Map an `<select>` change-event value to an enum-prop value.
|
|
36
|
+
*
|
|
37
|
+
* The placeholder `<option value="">Select…</option>` clears the field
|
|
38
|
+
* to `undefined`; any other value is the stringified array index into
|
|
39
|
+
* `options`. Extracted so we can test the clear semantics without
|
|
40
|
+
* spinning up jsdom: previously the inline handler used `Number("")`,
|
|
41
|
+
* which evaluates to `0` and silently picked the first option instead
|
|
42
|
+
* of clearing.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseEnumSelection<T>(raw: string, options: readonly T[]): T | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Produce a sensible empty value for a freshly-created array item or
|
|
47
|
+
* required prop. The admin form generator never wants `undefined` in
|
|
48
|
+
* an array; that breaks downstream PropInput defaults and confuses
|
|
49
|
+
* validators.
|
|
50
|
+
*/
|
|
51
|
+
export declare function defaultForType(type: PropType): unknown;
|
|
52
|
+
/**
|
|
53
|
+
* Seed an empty props object for a freshly-picked component using each
|
|
54
|
+
* prop's explicit `defaultValue` when set, else the structural default
|
|
55
|
+
* from {@link defaultForType} (only for required props — optional
|
|
56
|
+
* unset props stay absent so they render as empty inputs).
|
|
57
|
+
*/
|
|
58
|
+
export declare function seedPropsForComponent(spec: ComponentSpec): Record<string, unknown>;
|
|
59
|
+
/**
|
|
60
|
+
* Compute the next value for a discriminated-union field when the
|
|
61
|
+
* editor switches variants. Pure helper so the React component stays
|
|
62
|
+
* thin and the seeding rules can be unit-tested without rendering.
|
|
63
|
+
*
|
|
64
|
+
* Seeding rules:
|
|
65
|
+
* 1. The discriminator field is always written to the variant's
|
|
66
|
+
* tag value.
|
|
67
|
+
* 2. Optional fields shared by both variants survive the switch
|
|
68
|
+
* (preserves "edited the same label" intent across, e.g.,
|
|
69
|
+
* Link → Modal where both carry `label`).
|
|
70
|
+
* 3. Required fields exclusive to the new variant are seeded by
|
|
71
|
+
* priority: explicit `field.defaultValue` first (matches
|
|
72
|
+
* `seedPropsForComponent`), else the structural default from
|
|
73
|
+
* `defaultForType` — but only when that default is non-null.
|
|
74
|
+
* A `null` from `defaultForType` (reference / unknown / non-
|
|
75
|
+
* discriminated union types) is treated as "no sensible default"
|
|
76
|
+
* and the field is left absent so the validator's
|
|
77
|
+
* "missing required prop" message and the data agree.
|
|
78
|
+
* 4. Fields exclusive to the previous variant are dropped so the
|
|
79
|
+
* value stays structurally valid against the chosen variant.
|
|
80
|
+
*/
|
|
81
|
+
export declare function switchUnionVariant(current: unknown, union: DiscriminatedUnion, variant: DiscriminatedVariant): Record<string, unknown>;
|
|
82
|
+
/**
|
|
83
|
+
* Build a minimal structural validator that mirrors the rules the
|
|
84
|
+
* cms-core `validateComponentBlockValue` runs server-side, so the form
|
|
85
|
+
* can show feedback without a round-trip. Kept in sync with cms-core
|
|
86
|
+
* by inspection; the canonical implementation lives there.
|
|
87
|
+
*/
|
|
88
|
+
export declare function buildClientValidator(manifest: Manifest, allow: string[] | undefined): (value: ComponentBlockValue) => string | true;
|
|
89
|
+
/**
|
|
90
|
+
* The validator returns a single error string. The form wants to show
|
|
91
|
+
* the message under the specific input that triggered it — so we parse
|
|
92
|
+
* the message back into a sparse `{ propPath → message }` map. Pure
|
|
93
|
+
* function so it's trivial to unit-test.
|
|
94
|
+
*/
|
|
95
|
+
export declare function parsePerPropErrors(message: string | null): Record<string, string>;
|
|
96
|
+
//# sourceMappingURL=component-block-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-block-helpers.d.ts","sourceRoot":"","sources":["../../src/fields/component-block-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,qDAAqD,CAAA;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAY,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAElG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAEnE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,GAC1B,aAAa,EAAE,CAGjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAMpD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,SAAS,CAKvF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CA6CtD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyBlF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,oBAAoB,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoBzB;AAMD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,GAC1B,CAAC,KAAK,EAAE,mBAAmB,KAAK,MAAM,GAAG,IAAI,CA4B/C;AA8ED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOjF"}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers behind `<ComponentBlockField>`. Extracted so vitest can
|
|
3
|
+
* exercise them in node without spinning up jsdom — the React component
|
|
4
|
+
* just composes these into UI.
|
|
5
|
+
*
|
|
6
|
+
* Kept structurally typed (no peer-dep import of types here would be
|
|
7
|
+
* cleaner, but the `PropType` discriminated union is the contract we
|
|
8
|
+
* promise consumers, so we lean on the package's types).
|
|
9
|
+
*/
|
|
10
|
+
import { detectDiscriminator, findVariant, } from '@actuate-media/component-blocks/discriminated-union';
|
|
11
|
+
/**
|
|
12
|
+
* Compute the list of components an editor can pick from given the
|
|
13
|
+
* manifest + the optional allow-list. Returns the full list when no
|
|
14
|
+
* filter is provided; returns `[]` when every entry is filtered out
|
|
15
|
+
* (the caller renders an error in that case).
|
|
16
|
+
*/
|
|
17
|
+
export function getAllowedComponents(manifest, allow) {
|
|
18
|
+
if (!allow || allow.length === 0)
|
|
19
|
+
return manifest.components;
|
|
20
|
+
return manifest.components.filter((c) => allow.includes(c.name));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* JSON-encode any value so it round-trips cleanly through the
|
|
24
|
+
* JsonFallback textarea. Previously the helper short-circuited for
|
|
25
|
+
* strings (returning the raw string), which made the textarea
|
|
26
|
+
* stateful: typing `"hello"` parsed to the JS string `hello`,
|
|
27
|
+
* re-rendered as bare `hello`, then `JSON.parse('hello')` threw on
|
|
28
|
+
* the next edit and the field "locked" as a raw string. Always
|
|
29
|
+
* stringifying keeps the textarea visually consistent with the
|
|
30
|
+
* underlying JSON value.
|
|
31
|
+
*
|
|
32
|
+
* Falls back to `String(v)` for values that can't be JSON-encoded
|
|
33
|
+
* (e.g. circular refs) so the field remains editable.
|
|
34
|
+
*/
|
|
35
|
+
export function safeJsonStringify(v) {
|
|
36
|
+
try {
|
|
37
|
+
return JSON.stringify(v, null, 2);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return String(v);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Map an `<select>` change-event value to an enum-prop value.
|
|
45
|
+
*
|
|
46
|
+
* The placeholder `<option value="">Select…</option>` clears the field
|
|
47
|
+
* to `undefined`; any other value is the stringified array index into
|
|
48
|
+
* `options`. Extracted so we can test the clear semantics without
|
|
49
|
+
* spinning up jsdom: previously the inline handler used `Number("")`,
|
|
50
|
+
* which evaluates to `0` and silently picked the first option instead
|
|
51
|
+
* of clearing.
|
|
52
|
+
*/
|
|
53
|
+
export function parseEnumSelection(raw, options) {
|
|
54
|
+
if (raw === '')
|
|
55
|
+
return undefined;
|
|
56
|
+
const idx = Number(raw);
|
|
57
|
+
if (!Number.isInteger(idx) || idx < 0 || idx >= options.length)
|
|
58
|
+
return undefined;
|
|
59
|
+
return options[idx];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Produce a sensible empty value for a freshly-created array item or
|
|
63
|
+
* required prop. The admin form generator never wants `undefined` in
|
|
64
|
+
* an array; that breaks downstream PropInput defaults and confuses
|
|
65
|
+
* validators.
|
|
66
|
+
*/
|
|
67
|
+
export function defaultForType(type) {
|
|
68
|
+
switch (type.kind) {
|
|
69
|
+
case 'string':
|
|
70
|
+
return '';
|
|
71
|
+
case 'number':
|
|
72
|
+
return 0;
|
|
73
|
+
case 'boolean':
|
|
74
|
+
return false;
|
|
75
|
+
case 'enum':
|
|
76
|
+
return type.values[0] ?? '';
|
|
77
|
+
case 'literal':
|
|
78
|
+
return type.value;
|
|
79
|
+
case 'array':
|
|
80
|
+
return [];
|
|
81
|
+
case 'object':
|
|
82
|
+
return Object.fromEntries(type.fields.filter((f) => f.required).map((f) => [f.name, defaultForType(f.type)]));
|
|
83
|
+
case 'union': {
|
|
84
|
+
// Discriminated unions DO have a sensible structural default:
|
|
85
|
+
// pick the first variant and seed its required fields (plus the
|
|
86
|
+
// discriminator). This makes a Hero with a `cta: Link | Modal`
|
|
87
|
+
// prop render an editable form on first paint instead of forcing
|
|
88
|
+
// the editor through the JSON textarea fallback.
|
|
89
|
+
const detected = detectDiscriminator(type);
|
|
90
|
+
if (detected) {
|
|
91
|
+
const variant = detected.variants[0];
|
|
92
|
+
const out = { [detected.field]: variant.value };
|
|
93
|
+
for (const field of variant.remainingFields) {
|
|
94
|
+
if (field.required)
|
|
95
|
+
out[field.name] = defaultForType(field.type);
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
default:
|
|
102
|
+
// `reference`, `unknown`: there's no single sensible structural
|
|
103
|
+
// default. We return `null` instead of `undefined` so the value
|
|
104
|
+
// survives a JSON round-trip — `JSON.stringify` turns
|
|
105
|
+
// `undefined` array items into `null` anyway, which would
|
|
106
|
+
// contradict the documented "never undefined in an array"
|
|
107
|
+
// invariant and surface as the literal string `null` in the
|
|
108
|
+
// JsonFallback textarea.
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Seed an empty props object for a freshly-picked component using each
|
|
114
|
+
* prop's explicit `defaultValue` when set, else the structural default
|
|
115
|
+
* from {@link defaultForType} (only for required props — optional
|
|
116
|
+
* unset props stay absent so they render as empty inputs).
|
|
117
|
+
*/
|
|
118
|
+
export function seedPropsForComponent(spec) {
|
|
119
|
+
const out = {};
|
|
120
|
+
for (const prop of spec.props) {
|
|
121
|
+
if (prop.defaultValue !== undefined && prop.defaultValue !== null) {
|
|
122
|
+
out[prop.name] = prop.defaultValue;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (prop.required) {
|
|
126
|
+
const seed = defaultForType(prop.type);
|
|
127
|
+
// For non-discriminated `union` / `reference` / `unknown` kinds
|
|
128
|
+
// defaultForType returns `null` (so arrays survive a JSON
|
|
129
|
+
// round-trip), but seeding a top-level required prop with
|
|
130
|
+
// `null` would immediately trip the validator's "Missing
|
|
131
|
+
// required prop" branch on first render — the user would see
|
|
132
|
+
// a red error before they touched anything. Leave those
|
|
133
|
+
// required props absent so the absence and the validation
|
|
134
|
+
// message describe the same state honestly; the user provides
|
|
135
|
+
// a value via the JsonFallback. Discriminated unions return
|
|
136
|
+
// a structural default and seed cleanly.
|
|
137
|
+
if (seed !== null) {
|
|
138
|
+
out[prop.name] = seed;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Compute the next value for a discriminated-union field when the
|
|
146
|
+
* editor switches variants. Pure helper so the React component stays
|
|
147
|
+
* thin and the seeding rules can be unit-tested without rendering.
|
|
148
|
+
*
|
|
149
|
+
* Seeding rules:
|
|
150
|
+
* 1. The discriminator field is always written to the variant's
|
|
151
|
+
* tag value.
|
|
152
|
+
* 2. Optional fields shared by both variants survive the switch
|
|
153
|
+
* (preserves "edited the same label" intent across, e.g.,
|
|
154
|
+
* Link → Modal where both carry `label`).
|
|
155
|
+
* 3. Required fields exclusive to the new variant are seeded by
|
|
156
|
+
* priority: explicit `field.defaultValue` first (matches
|
|
157
|
+
* `seedPropsForComponent`), else the structural default from
|
|
158
|
+
* `defaultForType` — but only when that default is non-null.
|
|
159
|
+
* A `null` from `defaultForType` (reference / unknown / non-
|
|
160
|
+
* discriminated union types) is treated as "no sensible default"
|
|
161
|
+
* and the field is left absent so the validator's
|
|
162
|
+
* "missing required prop" message and the data agree.
|
|
163
|
+
* 4. Fields exclusive to the previous variant are dropped so the
|
|
164
|
+
* value stays structurally valid against the chosen variant.
|
|
165
|
+
*/
|
|
166
|
+
export function switchUnionVariant(current, union, variant) {
|
|
167
|
+
const obj = isPlainObject(current) ? current : {};
|
|
168
|
+
const next = { [union.field]: variant.value };
|
|
169
|
+
const carryable = new Set(variant.remainingFields.map((f) => f.name));
|
|
170
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
171
|
+
if (k === union.field)
|
|
172
|
+
continue;
|
|
173
|
+
if (carryable.has(k))
|
|
174
|
+
next[k] = v;
|
|
175
|
+
}
|
|
176
|
+
for (const field of variant.remainingFields) {
|
|
177
|
+
if (!field.required || next[field.name] !== undefined)
|
|
178
|
+
continue;
|
|
179
|
+
if (field.defaultValue !== undefined && field.defaultValue !== null) {
|
|
180
|
+
next[field.name] = field.defaultValue;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const seed = defaultForType(field.type);
|
|
184
|
+
if (seed !== null) {
|
|
185
|
+
next[field.name] = seed;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return next;
|
|
189
|
+
}
|
|
190
|
+
function isPlainObject(value) {
|
|
191
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Build a minimal structural validator that mirrors the rules the
|
|
195
|
+
* cms-core `validateComponentBlockValue` runs server-side, so the form
|
|
196
|
+
* can show feedback without a round-trip. Kept in sync with cms-core
|
|
197
|
+
* by inspection; the canonical implementation lives there.
|
|
198
|
+
*/
|
|
199
|
+
export function buildClientValidator(manifest, allow) {
|
|
200
|
+
// An empty `allow` array is treated the same way `getAllowedComponents`
|
|
201
|
+
// treats it: as "no filter". Without this, the picker shows every
|
|
202
|
+
// component while the validator rejects every selection, leading to
|
|
203
|
+
// a UI/validator deadlock.
|
|
204
|
+
const allowed = allow && allow.length > 0 ? new Set(allow) : null;
|
|
205
|
+
return (value) => {
|
|
206
|
+
const spec = manifest.components.find((c) => c.name === value.component);
|
|
207
|
+
if (!spec) {
|
|
208
|
+
const known = manifest.components.map((c) => c.name).join(', ') || '<none>';
|
|
209
|
+
return `Unknown component '${value.component}'. Manifest knows: ${known}.`;
|
|
210
|
+
}
|
|
211
|
+
if (allowed && !allowed.has(value.component)) {
|
|
212
|
+
return `Component '${value.component}' is not in the allow-list for this field.`;
|
|
213
|
+
}
|
|
214
|
+
for (const propSpec of spec.props) {
|
|
215
|
+
const v = value.props[propSpec.name];
|
|
216
|
+
if (v === undefined || v === null) {
|
|
217
|
+
if (propSpec.required) {
|
|
218
|
+
return `Missing required prop '${propSpec.name}' for component '${value.component}'.`;
|
|
219
|
+
}
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
const err = clientShapeError(v, propSpec);
|
|
223
|
+
if (err)
|
|
224
|
+
return err;
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function clientShapeError(value, prop) {
|
|
230
|
+
const t = prop.type;
|
|
231
|
+
switch (t.kind) {
|
|
232
|
+
case 'string':
|
|
233
|
+
return typeof value === 'string' ? null : `Prop '${prop.name}' must be a string.`;
|
|
234
|
+
case 'number':
|
|
235
|
+
return typeof value === 'number' && !Number.isNaN(value)
|
|
236
|
+
? null
|
|
237
|
+
: `Prop '${prop.name}' must be a number.`;
|
|
238
|
+
case 'boolean':
|
|
239
|
+
return typeof value === 'boolean' ? null : `Prop '${prop.name}' must be a boolean.`;
|
|
240
|
+
case 'enum':
|
|
241
|
+
return t.values.includes(value)
|
|
242
|
+
? null
|
|
243
|
+
: `Prop '${prop.name}' must be one of: ${t.values.join(', ')}.`;
|
|
244
|
+
case 'array':
|
|
245
|
+
return Array.isArray(value) ? null : `Prop '${prop.name}' must be an array.`;
|
|
246
|
+
case 'object': {
|
|
247
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
248
|
+
return `Prop '${prop.name}' must be an object.`;
|
|
249
|
+
}
|
|
250
|
+
// Recurse: check that each required nested field is present and
|
|
251
|
+
// structurally compatible. Without this, passing `{}` for an
|
|
252
|
+
// object prop with required `label` and `href` children sailed
|
|
253
|
+
// through the client validator while the server-side
|
|
254
|
+
// validateComponentBlockValue would reject it on save — a
|
|
255
|
+
// silent gap in the "live structural validation" promise.
|
|
256
|
+
const obj = value;
|
|
257
|
+
for (const field of t.fields) {
|
|
258
|
+
const child = obj[field.name];
|
|
259
|
+
if (child === undefined || child === null) {
|
|
260
|
+
if (field.required) {
|
|
261
|
+
return `Prop '${prop.name}.${field.name}' is required but missing.`;
|
|
262
|
+
}
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
const childError = clientShapeError(child, {
|
|
266
|
+
...field,
|
|
267
|
+
// Build a dotted path so parsePerPropErrors can attribute
|
|
268
|
+
// the error to the nested input, not just the outer prop.
|
|
269
|
+
name: `${prop.name}.${field.name}`,
|
|
270
|
+
});
|
|
271
|
+
if (childError)
|
|
272
|
+
return childError;
|
|
273
|
+
}
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
case 'union': {
|
|
277
|
+
// Discriminated unions get the same recursive treatment as plain
|
|
278
|
+
// objects: route the value into the matching variant's schema
|
|
279
|
+
// and validate against that. Non-discriminated unions remain
|
|
280
|
+
// unvalidated on the client (server still catches them) — the
|
|
281
|
+
// shape is too open to assert structurally.
|
|
282
|
+
const detected = detectDiscriminator(t);
|
|
283
|
+
if (!detected)
|
|
284
|
+
return null;
|
|
285
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
286
|
+
return `Prop '${prop.name}' must be an object with a '${detected.field}' discriminator.`;
|
|
287
|
+
}
|
|
288
|
+
const variant = findVariant(value, detected);
|
|
289
|
+
if (!variant) {
|
|
290
|
+
const allowed = detected.variants.map((v) => JSON.stringify(v.value)).join(', ');
|
|
291
|
+
return `Prop '${prop.name}.${detected.field}' must be one of: ${allowed}.`;
|
|
292
|
+
}
|
|
293
|
+
// Recurse into the variant's fields, scoped to the prop path.
|
|
294
|
+
// We treat the variant as an inline object so the existing
|
|
295
|
+
// object-branch logic applies verbatim.
|
|
296
|
+
return clientShapeError(value, {
|
|
297
|
+
name: prop.name,
|
|
298
|
+
required: prop.required,
|
|
299
|
+
type: variant.type,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
default:
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* The validator returns a single error string. The form wants to show
|
|
308
|
+
* the message under the specific input that triggered it — so we parse
|
|
309
|
+
* the message back into a sparse `{ propPath → message }` map. Pure
|
|
310
|
+
* function so it's trivial to unit-test.
|
|
311
|
+
*/
|
|
312
|
+
export function parsePerPropErrors(message) {
|
|
313
|
+
if (!message)
|
|
314
|
+
return {};
|
|
315
|
+
const propMatch = /Prop '([^']+)'/.exec(message);
|
|
316
|
+
if (propMatch)
|
|
317
|
+
return { [propMatch[1]]: message };
|
|
318
|
+
const missing = /Missing required prop '([^']+)'/.exec(message);
|
|
319
|
+
if (missing)
|
|
320
|
+
return { [missing[1]]: message };
|
|
321
|
+
return {};
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=component-block-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-block-helpers.js","sourceRoot":"","sources":["../../src/fields/component-block-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/fields/index.d.ts
CHANGED
|
@@ -15,4 +15,8 @@ export type { BlockTypeDefinition } from './block-types.js';
|
|
|
15
15
|
export { GroupField } from './GroupField.js';
|
|
16
16
|
export { NavBuilderField } from './NavBuilderField.js';
|
|
17
17
|
export { NumberField } from './NumberField.js';
|
|
18
|
+
export { ComponentBlockField } from './ComponentBlockField.js';
|
|
19
|
+
export type { ComponentBlockFieldProps, ComponentBlockValue } from './ComponentBlockField.js';
|
|
20
|
+
export { PropInput, defaultForType } from './PropInput.js';
|
|
21
|
+
export type { PropInputProps } from './PropInput.js';
|
|
18
22
|
//# sourceMappingURL=index.d.ts.map
|