@jxsuite/studio 0.19.0 → 0.21.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.
- package/dist/studio.css +98 -98
- package/dist/studio.js +13476 -12330
- package/dist/studio.js.map +152 -148
- package/dist/workers/editor.worker.js +79 -79
- package/dist/workers/json.worker.js +109 -109
- package/dist/workers/ts.worker.js +82 -82
- package/package.json +19 -7
- package/src/browse/browse-modal.js +16 -13
- package/src/browse/browse.js +44 -35
- package/src/canvas/canvas-diff.js +24 -16
- package/src/canvas/canvas-helpers.js +24 -19
- package/src/canvas/canvas-live-render.js +113 -39
- package/src/canvas/canvas-render.js +119 -73
- package/src/canvas/canvas-utils.js +51 -21
- package/src/canvas/nested-site-style.js +50 -0
- package/src/editor/component-inline-edit.js +14 -13
- package/src/editor/content-inline-edit.js +22 -10
- package/src/editor/context-menu.js +28 -14
- package/src/editor/convert-targets.js +60 -0
- package/src/editor/convert-to-component.js +20 -19
- package/src/editor/convert-to-repeater.js +226 -0
- package/src/editor/inline-edit.js +69 -28
- package/src/editor/insertion-helper.js +16 -12
- package/src/editor/shortcuts.js +14 -4
- package/src/editor/slash-menu.js +40 -19
- package/src/files/components.js +1 -1
- package/src/files/file-ops.js +37 -16
- package/src/files/files.js +322 -68
- package/src/github/github-auth.js +122 -0
- package/src/github/github-publish.js +126 -0
- package/src/markdown/md-convert.js +172 -107
- package/src/new-project/new-project-modal.js +204 -0
- package/src/panels/activity-bar.js +27 -25
- package/src/panels/ai-panel.js +406 -0
- package/src/panels/block-action-bar.js +77 -28
- package/src/panels/canvas-dnd.js +8 -2
- package/src/panels/data-explorer.js +19 -13
- package/src/panels/dnd.js +144 -92
- package/src/panels/editors.js +55 -35
- package/src/panels/elements-panel.js +33 -19
- package/src/panels/events-panel.js +15 -10
- package/src/panels/git-panel.js +475 -99
- package/src/panels/head-panel.js +121 -81
- package/src/panels/imports-panel.js +94 -65
- package/src/panels/layers-panel.js +64 -43
- package/src/panels/left-panel.js +105 -48
- package/src/panels/overlays.js +1 -0
- package/src/panels/panel-events.js +45 -30
- package/src/panels/preview-render.js +23 -18
- package/src/panels/properties-panel.js +378 -257
- package/src/panels/pseudo-preview.js +2 -2
- package/src/panels/quick-search.js +11 -9
- package/src/panels/right-panel.js +42 -16
- package/src/panels/shared.js +4 -4
- package/src/panels/signals-panel.js +415 -166
- package/src/panels/statusbar.js +10 -6
- package/src/panels/style-inputs.js +67 -35
- package/src/panels/style-panel.js +239 -134
- package/src/panels/style-utils.js +34 -16
- package/src/panels/stylebook-layers-panel.js +12 -10
- package/src/panels/stylebook-panel.js +134 -66
- package/src/panels/tab-strip.js +5 -2
- package/src/panels/toolbar.js +333 -109
- package/src/panels/welcome-screen.js +121 -0
- package/src/platform.js +2 -4
- package/src/platforms/devserver.js +113 -7
- package/src/resize-edges.js +98 -0
- package/src/services/cem-export.js +12 -7
- package/src/services/code-services.js +30 -12
- package/src/settings/content-types-editor.js +8 -8
- package/src/settings/css-vars-editor.js +30 -24
- package/src/settings/defs-editor.js +12 -7
- package/src/settings/general-settings.js +85 -3
- package/src/settings/head-editor.js +30 -24
- package/src/settings/schema-field-ui.js +58 -39
- package/src/settings/settings-modal.js +12 -9
- package/src/site-context.js +41 -31
- package/src/state.js +70 -29
- package/src/store.js +36 -35
- package/src/studio.js +120 -90
- package/src/tabs/tab.js +67 -43
- package/src/tabs/transact.js +23 -13
- package/src/ui/button-group.js +24 -24
- package/src/ui/color-selector.js +28 -23
- package/src/ui/field-row.js +3 -3
- package/src/ui/icons.js +2 -2
- package/src/ui/layers.js +31 -1
- package/src/ui/media-picker.js +7 -7
- package/src/ui/spectrum.js +5 -1
- package/src/ui/unit-selector.js +18 -16
- package/src/ui/value-selector.js +21 -15
- package/src/ui/widgets.js +22 -19
- package/src/utils/canvas-media.js +5 -4
- package/src/utils/edit-display.js +32 -26
- package/src/utils/google-fonts.js +11 -11
- package/src/utils/inherited-style.js +9 -8
- package/src/utils/studio-utils.js +18 -18
- package/src/view.js +58 -1
- package/src/workspace/workspace.js +29 -7
|
@@ -8,6 +8,7 @@ import { html, nothing } from "lit-html";
|
|
|
8
8
|
import { classMap } from "lit-html/directives/class-map.js";
|
|
9
9
|
import { ifDefined } from "lit-html/directives/if-defined.js";
|
|
10
10
|
import { styleMap } from "lit-html/directives/style-map.js";
|
|
11
|
+
import { projectState } from "../state.js";
|
|
11
12
|
import { activeTab } from "../workspace/workspace.js";
|
|
12
13
|
import {
|
|
13
14
|
transactDoc,
|
|
@@ -20,17 +21,87 @@ import { renderFieldRow } from "../ui/field-row.js";
|
|
|
20
21
|
import { renderMediaPicker } from "../ui/media-picker.js";
|
|
21
22
|
import { fetchPluginSchema, pluginSchemaCache } from "../services/code-services.js";
|
|
22
23
|
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {{
|
|
26
|
+
* document: JxMutableNode;
|
|
27
|
+
* ui?: Record<string, unknown>;
|
|
28
|
+
* mode?: string;
|
|
29
|
+
* selection?: (string | number)[] | null;
|
|
30
|
+
* canvas?: Record<string, unknown>;
|
|
31
|
+
* _collapsedSignalCats?: Set<string>;
|
|
32
|
+
* documentPath?: string | null;
|
|
33
|
+
* }} SignalsPanelState
|
|
34
|
+
*
|
|
35
|
+
* @typedef {{ renderLeftPanel(): void; renderCanvas(): void; updateSession(patch: object): void }} SignalsPanelCtx
|
|
36
|
+
*
|
|
37
|
+
* @typedef {Record<string, unknown> & {
|
|
38
|
+
* $prototype?: string;
|
|
39
|
+
* $compute?: string;
|
|
40
|
+
* $deps?: string[];
|
|
41
|
+
* $handler?: unknown;
|
|
42
|
+
* $src?: string;
|
|
43
|
+
* $export?: string;
|
|
44
|
+
* type?: string;
|
|
45
|
+
* default?: unknown;
|
|
46
|
+
* description?: string;
|
|
47
|
+
* attribute?: string;
|
|
48
|
+
* reflects?: boolean;
|
|
49
|
+
* deprecated?: string | boolean;
|
|
50
|
+
* format?: string;
|
|
51
|
+
* url?: string;
|
|
52
|
+
* method?: string;
|
|
53
|
+
* timing?: string;
|
|
54
|
+
* key?: string;
|
|
55
|
+
* database?: string;
|
|
56
|
+
* store?: string;
|
|
57
|
+
* version?: number;
|
|
58
|
+
* name?: string;
|
|
59
|
+
* body?: string;
|
|
60
|
+
* parameters?: Record<string, unknown>[];
|
|
61
|
+
* emits?: Record<string, unknown>[];
|
|
62
|
+
* fields?: unknown;
|
|
63
|
+
* contentType?: string;
|
|
64
|
+
* id?: unknown;
|
|
65
|
+
* filter?: Record<string, unknown>;
|
|
66
|
+
* sort?: { field?: string; order?: string };
|
|
67
|
+
* limit?: number;
|
|
68
|
+
* }} SignalDef
|
|
69
|
+
*
|
|
70
|
+
* @typedef {{ name: string; type?: { text?: string }; description?: string; optional?: boolean }} CemParameter
|
|
71
|
+
*
|
|
72
|
+
* @typedef {{ name: string; type?: { text?: string }; description?: string }} CemEvent
|
|
73
|
+
*
|
|
74
|
+
* @typedef {{
|
|
75
|
+
* type?: string;
|
|
76
|
+
* properties?: Record<string, SchemaProperty>;
|
|
77
|
+
* required?: string[];
|
|
78
|
+
* description?: string;
|
|
79
|
+
* }} JsonSchema
|
|
80
|
+
*
|
|
81
|
+
* @typedef {{
|
|
82
|
+
* type?: string;
|
|
83
|
+
* enum?: string[];
|
|
84
|
+
* default?: unknown;
|
|
85
|
+
* format?: string;
|
|
86
|
+
* minimum?: number;
|
|
87
|
+
* maximum?: number;
|
|
88
|
+
* description?: string;
|
|
89
|
+
* examples?: string[];
|
|
90
|
+
* name?: string;
|
|
91
|
+
* }} SchemaProperty
|
|
92
|
+
*/
|
|
93
|
+
|
|
23
94
|
// ─── Module-local state ─────────────────────────────────────────────────────
|
|
24
95
|
|
|
25
96
|
/** Expanded signal editor state (persists across renders). */
|
|
26
|
-
/** @type {
|
|
97
|
+
/** @type {string | null} */
|
|
27
98
|
let expandedSignal = null;
|
|
28
99
|
|
|
29
100
|
/** Track which functions have the advanced param editor open. */
|
|
30
101
|
const advancedParamOpen = new Set();
|
|
31
102
|
|
|
32
103
|
/** Default templates for creating new signal definitions. */
|
|
33
|
-
const DEF_TEMPLATES = /** @type {Record<string,
|
|
104
|
+
const DEF_TEMPLATES = /** @type {Record<string, SignalDef>} */ ({
|
|
34
105
|
state: { type: "string", default: "" },
|
|
35
106
|
computed: { $compute: "", $deps: [] },
|
|
36
107
|
request: { $prototype: "Request", url: "", method: "GET", timing: "client" },
|
|
@@ -67,34 +138,36 @@ const STUDIO_RESERVED_KEYS = new Set([
|
|
|
67
138
|
/**
|
|
68
139
|
* Classify a state entry into a category string.
|
|
69
140
|
*
|
|
70
|
-
* @param {
|
|
141
|
+
* @param {SignalDef | unknown} def
|
|
71
142
|
*/
|
|
72
143
|
export function defCategory(def) {
|
|
73
144
|
if (!def) return "state";
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
if (
|
|
145
|
+
const d = /** @type {SignalDef} */ (def);
|
|
146
|
+
if (d.$handler || d.$prototype === "Function") return "function";
|
|
147
|
+
if (d.$compute) return "computed";
|
|
148
|
+
if (d.$prototype) return "data";
|
|
77
149
|
return "state";
|
|
78
150
|
}
|
|
79
151
|
|
|
80
152
|
/**
|
|
81
153
|
* Badge label for a def category.
|
|
82
154
|
*
|
|
83
|
-
* @param {
|
|
155
|
+
* @param {SignalDef | unknown} def
|
|
84
156
|
*/
|
|
85
157
|
export function defBadgeLabel(def) {
|
|
86
158
|
if (!def) return "S";
|
|
87
|
-
|
|
88
|
-
if (
|
|
89
|
-
if (
|
|
159
|
+
const d = /** @type {SignalDef} */ (def);
|
|
160
|
+
if (d.$handler || d.$prototype === "Function") return "F";
|
|
161
|
+
if (d.$compute) return "C";
|
|
162
|
+
if (d.$prototype) return d.$prototype.charAt(0);
|
|
90
163
|
return "S";
|
|
91
164
|
}
|
|
92
165
|
|
|
93
166
|
/**
|
|
94
167
|
* Hint text for a signal row.
|
|
95
168
|
*
|
|
96
|
-
* @param {
|
|
97
|
-
* @param {
|
|
169
|
+
* @param {string} name
|
|
170
|
+
* @param {SignalDef | null | undefined} def
|
|
98
171
|
*/
|
|
99
172
|
export function defHint(name, def) {
|
|
100
173
|
if (!def) return "";
|
|
@@ -120,7 +193,7 @@ export function defHint(name, def) {
|
|
|
120
193
|
/**
|
|
121
194
|
* Whether the current document defines a custom element (hyphenated tagName).
|
|
122
195
|
*
|
|
123
|
-
* @param {
|
|
196
|
+
* @param {SignalsPanelState} S
|
|
124
197
|
*/
|
|
125
198
|
export function isCustomElementDoc(S) {
|
|
126
199
|
return (S.document.tagName || "").includes("-");
|
|
@@ -129,14 +202,16 @@ export function isCustomElementDoc(S) {
|
|
|
129
202
|
/**
|
|
130
203
|
* Recursively collect CSS `part` attributes from the document tree.
|
|
131
204
|
*
|
|
132
|
-
* @param {
|
|
133
|
-
* @param {
|
|
205
|
+
* @param {JxMutableNode | null | undefined} node
|
|
206
|
+
* @param {{ name: string; tag: string }[]} [parts]
|
|
134
207
|
*/
|
|
135
208
|
export function collectCssParts(node, parts = []) {
|
|
136
209
|
if (node?.attributes?.part)
|
|
137
210
|
parts.push({ name: node.attributes.part, tag: node.tagName || "div" });
|
|
138
211
|
if (Array.isArray(node?.children))
|
|
139
|
-
node.children.forEach((
|
|
212
|
+
node.children.forEach((c) => {
|
|
213
|
+
if (typeof c !== "string") collectCssParts(c, parts);
|
|
214
|
+
});
|
|
140
215
|
return parts;
|
|
141
216
|
}
|
|
142
217
|
|
|
@@ -144,13 +219,14 @@ export function collectCssParts(node, parts = []) {
|
|
|
144
219
|
* Resolve a $ref value to a display string using signal defaults. Used by the canvas to show real
|
|
145
220
|
* values instead of raw refs.
|
|
146
221
|
*
|
|
147
|
-
* @param {
|
|
148
|
-
* @param {
|
|
222
|
+
* @param {unknown} value
|
|
223
|
+
* @param {Record<string, SignalDef> | null | undefined} defs
|
|
149
224
|
*/
|
|
150
225
|
export function resolveDefaultForCanvas(value, defs) {
|
|
151
|
-
if (!value || typeof value !== "object" || !value.$ref)
|
|
152
|
-
|
|
153
|
-
/** @type {
|
|
226
|
+
if (!value || typeof value !== "object" || !(/** @type {Record<string, unknown>} */ (value).$ref))
|
|
227
|
+
return value;
|
|
228
|
+
const ref = /** @type {string} */ (/** @type {Record<string, unknown>} */ (value).$ref);
|
|
229
|
+
/** @type {string | undefined} */
|
|
154
230
|
let defName;
|
|
155
231
|
if (ref.startsWith("#/state/")) defName = ref.slice(8);
|
|
156
232
|
else if (ref.startsWith("$")) defName = ref;
|
|
@@ -187,11 +263,11 @@ export function resolveDefaultForCanvas(value, defs) {
|
|
|
187
263
|
|
|
188
264
|
/** Simple field row for signal editors — vertical stacked layout. */
|
|
189
265
|
export function signalFieldRow(
|
|
190
|
-
/** @type {
|
|
191
|
-
/** @type {
|
|
192
|
-
/** @type {
|
|
266
|
+
/** @type {string} */ label,
|
|
267
|
+
/** @type {string} */ value,
|
|
268
|
+
/** @type {(value: string) => void} */ onChange,
|
|
193
269
|
) {
|
|
194
|
-
/** @type {
|
|
270
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
195
271
|
let debounce;
|
|
196
272
|
return renderFieldRow({
|
|
197
273
|
prop: label,
|
|
@@ -201,9 +277,12 @@ export function signalFieldRow(
|
|
|
201
277
|
<sp-textfield
|
|
202
278
|
size="s"
|
|
203
279
|
value=${value}
|
|
204
|
-
@input=${(/** @type {
|
|
280
|
+
@input=${(/** @type {Event} */ e) => {
|
|
205
281
|
clearTimeout(debounce);
|
|
206
|
-
debounce = setTimeout(
|
|
282
|
+
debounce = setTimeout(
|
|
283
|
+
() => onChange(/** @type {HTMLInputElement} */ (e.target).value),
|
|
284
|
+
400,
|
|
285
|
+
);
|
|
207
286
|
}}
|
|
208
287
|
></sp-textfield>
|
|
209
288
|
`,
|
|
@@ -211,22 +290,22 @@ export function signalFieldRow(
|
|
|
211
290
|
}
|
|
212
291
|
|
|
213
292
|
/** Normalize a parameter entry to a CEM object. */
|
|
214
|
-
export function normParam(/** @type {
|
|
215
|
-
return typeof p === "string" ? { name: p } : p;
|
|
293
|
+
export function normParam(/** @type {string | Record<string, unknown>} */ p) {
|
|
294
|
+
return typeof p === "string" ? { name: p } : /** @type {CemParameter} */ (p);
|
|
216
295
|
}
|
|
217
296
|
|
|
218
297
|
// ─── Left panel: Signals ─────────────────────────────────────────────────────
|
|
219
298
|
|
|
220
299
|
/**
|
|
221
|
-
* @param {
|
|
222
|
-
* @param {
|
|
300
|
+
* @param {SignalsPanelState} S
|
|
301
|
+
* @param {SignalsPanelCtx} ctx
|
|
223
302
|
*/
|
|
224
303
|
export function renderSignalsTemplate(S, ctx) {
|
|
225
304
|
const defs = S.document.state || {};
|
|
226
305
|
const entries = Object.entries(defs);
|
|
227
306
|
|
|
228
307
|
// Group by category
|
|
229
|
-
const groups = /** @type {Record<string,
|
|
308
|
+
const groups = /** @type {Record<string, [string, SignalDef][]>} */ ({
|
|
230
309
|
state: [],
|
|
231
310
|
computed: [],
|
|
232
311
|
data: [],
|
|
@@ -259,7 +338,7 @@ export function renderSignalsTemplate(S, ctx) {
|
|
|
259
338
|
}}
|
|
260
339
|
>
|
|
261
340
|
${items.map(([name, def]) => {
|
|
262
|
-
/** @type {
|
|
341
|
+
/** @type {boolean} */
|
|
263
342
|
const isExpanded = expandedSignal === name;
|
|
264
343
|
return html`
|
|
265
344
|
<div
|
|
@@ -276,7 +355,7 @@ export function renderSignalsTemplate(S, ctx) {
|
|
|
276
355
|
quiet
|
|
277
356
|
size="xs"
|
|
278
357
|
class="signal-del"
|
|
279
|
-
@click=${(/** @type {
|
|
358
|
+
@click=${(/** @type {Event} */ e) => {
|
|
280
359
|
e.stopPropagation();
|
|
281
360
|
transactDoc(activeTab.value, (t) => mutateRemoveDef(t, name));
|
|
282
361
|
}}
|
|
@@ -304,8 +383,8 @@ export function renderSignalsTemplate(S, ctx) {
|
|
|
304
383
|
size="s"
|
|
305
384
|
label="+ Add…"
|
|
306
385
|
placeholder="+ Add…"
|
|
307
|
-
@change=${(/** @type {
|
|
308
|
-
const type = e.target.value;
|
|
386
|
+
@change=${(/** @type {Event} */ e) => {
|
|
387
|
+
const type = /** @type {HTMLInputElement} */ (e.target).value;
|
|
309
388
|
if (!type) return;
|
|
310
389
|
const template = DEF_TEMPLATES[type];
|
|
311
390
|
if (!template) return;
|
|
@@ -316,7 +395,13 @@ export function renderSignalsTemplate(S, ctx) {
|
|
|
316
395
|
while (S.document.state && S.document.state[n]) {
|
|
317
396
|
n = nameBase + i++;
|
|
318
397
|
}
|
|
319
|
-
transactDoc(activeTab.value, (t) =>
|
|
398
|
+
transactDoc(activeTab.value, (t) =>
|
|
399
|
+
mutateAddDef(
|
|
400
|
+
t,
|
|
401
|
+
n,
|
|
402
|
+
/** @type {Record<string, JsonValue>} */ (structuredClone(template)),
|
|
403
|
+
),
|
|
404
|
+
);
|
|
320
405
|
expandedSignal = n;
|
|
321
406
|
ctx.renderLeftPanel();
|
|
322
407
|
}}
|
|
@@ -343,10 +428,10 @@ export function renderSignalsTemplate(S, ctx) {
|
|
|
343
428
|
|
|
344
429
|
/** Render inline editor fields for a specific signal/def type. */
|
|
345
430
|
function renderSignalEditorTemplate(
|
|
346
|
-
/** @type {
|
|
347
|
-
/** @type {
|
|
348
|
-
/** @type {
|
|
349
|
-
/** @type {
|
|
431
|
+
/** @type {SignalsPanelState} */ S,
|
|
432
|
+
/** @type {string} */ name,
|
|
433
|
+
/** @type {SignalDef} */ def,
|
|
434
|
+
/** @type {SignalsPanelCtx} */ ctx,
|
|
350
435
|
) {
|
|
351
436
|
if (typeof def !== "object" || def === null) {
|
|
352
437
|
def = { default: def };
|
|
@@ -355,10 +440,10 @@ function renderSignalEditorTemplate(
|
|
|
355
440
|
|
|
356
441
|
// Helper for picker rows
|
|
357
442
|
const pickerRow = (
|
|
358
|
-
/** @type {
|
|
359
|
-
/** @type {
|
|
360
|
-
/** @type {
|
|
361
|
-
/** @type {
|
|
443
|
+
/** @type {string} */ label,
|
|
444
|
+
/** @type {string[]} */ options,
|
|
445
|
+
/** @type {string} */ currentVal,
|
|
446
|
+
/** @type {(value: string) => void} */ onChange,
|
|
362
447
|
) => {
|
|
363
448
|
return renderFieldRow({
|
|
364
449
|
prop: label,
|
|
@@ -368,10 +453,11 @@ function renderSignalEditorTemplate(
|
|
|
368
453
|
<sp-picker
|
|
369
454
|
size="s"
|
|
370
455
|
value=${currentVal}
|
|
371
|
-
@change=${(/** @type {
|
|
456
|
+
@change=${(/** @type {Event} */ e) =>
|
|
457
|
+
onChange(/** @type {HTMLInputElement} */ (e.target).value)}
|
|
372
458
|
>
|
|
373
459
|
${options.map(
|
|
374
|
-
(/** @type {
|
|
460
|
+
(/** @type {string} */ opt) => html`<sp-menu-item value=${opt}>${opt}</sp-menu-item>`,
|
|
375
461
|
)}
|
|
376
462
|
</sp-picker>
|
|
377
463
|
`,
|
|
@@ -380,12 +466,12 @@ function renderSignalEditorTemplate(
|
|
|
380
466
|
|
|
381
467
|
// Helper for textarea rows
|
|
382
468
|
const textareaRow = (
|
|
383
|
-
/** @type {
|
|
384
|
-
/** @type {
|
|
385
|
-
/** @type {
|
|
386
|
-
/** @type {
|
|
469
|
+
/** @type {string} */ label,
|
|
470
|
+
/** @type {string} */ value,
|
|
471
|
+
/** @type {(value: string) => void} */ onChange,
|
|
472
|
+
/** @type {{ minHeight?: string; mono?: boolean }} */ opts = {},
|
|
387
473
|
) => {
|
|
388
|
-
/** @type {
|
|
474
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
389
475
|
let debounce;
|
|
390
476
|
return renderFieldRow({
|
|
391
477
|
prop: label,
|
|
@@ -402,9 +488,12 @@ function renderSignalEditorTemplate(
|
|
|
402
488
|
}),
|
|
403
489
|
})}
|
|
404
490
|
.value=${value}
|
|
405
|
-
@input=${(/** @type {
|
|
491
|
+
@input=${(/** @type {Event} */ e) => {
|
|
406
492
|
clearTimeout(debounce);
|
|
407
|
-
debounce = setTimeout(
|
|
493
|
+
debounce = setTimeout(
|
|
494
|
+
() => onChange(/** @type {HTMLInputElement} */ (e.target).value),
|
|
495
|
+
500,
|
|
496
|
+
);
|
|
408
497
|
}}
|
|
409
498
|
></textarea>
|
|
410
499
|
`,
|
|
@@ -412,14 +501,14 @@ function renderSignalEditorTemplate(
|
|
|
412
501
|
};
|
|
413
502
|
|
|
414
503
|
// Name field (common to all)
|
|
415
|
-
const nameField = signalFieldRow("Name", name, (/** @type {
|
|
504
|
+
const nameField = signalFieldRow("Name", name, (/** @type {string} */ v) => {
|
|
416
505
|
if (v && v !== name && !(S.document.state && S.document.state[v])) {
|
|
417
506
|
expandedSignal = v;
|
|
418
507
|
transactDoc(activeTab.value, (t) => mutateRenameDef(t, name, v));
|
|
419
508
|
}
|
|
420
509
|
});
|
|
421
510
|
|
|
422
|
-
/** @type {
|
|
511
|
+
/** @type {import("lit-html").TemplateResult | typeof nothing} */
|
|
423
512
|
let fields = nothing;
|
|
424
513
|
|
|
425
514
|
if (cat === "state") {
|
|
@@ -432,7 +521,7 @@ function renderSignalEditorTemplate(
|
|
|
432
521
|
|
|
433
522
|
const cemFields = isCustomElementDoc(S)
|
|
434
523
|
? html`
|
|
435
|
-
${signalFieldRow("Attribute", def.attribute || "", (/** @type {
|
|
524
|
+
${signalFieldRow("Attribute", def.attribute || "", (/** @type {string} */ v) =>
|
|
436
525
|
transactDoc(activeTab.value, (t) =>
|
|
437
526
|
mutateUpdateDef(t, name, { attribute: v || undefined }),
|
|
438
527
|
),
|
|
@@ -445,9 +534,11 @@ function renderSignalEditorTemplate(
|
|
|
445
534
|
<sp-checkbox
|
|
446
535
|
class="field-check"
|
|
447
536
|
?checked=${!!def.reflects}
|
|
448
|
-
@change=${(/** @type {
|
|
537
|
+
@change=${(/** @type {Event} */ e) =>
|
|
449
538
|
transactDoc(activeTab.value, (t) =>
|
|
450
|
-
mutateUpdateDef(t, name, {
|
|
539
|
+
mutateUpdateDef(t, name, {
|
|
540
|
+
reflects: /** @type {HTMLInputElement} */ (e.target).checked || undefined,
|
|
541
|
+
}),
|
|
451
542
|
)}
|
|
452
543
|
></sp-checkbox>
|
|
453
544
|
`,
|
|
@@ -455,7 +546,7 @@ function renderSignalEditorTemplate(
|
|
|
455
546
|
${signalFieldRow(
|
|
456
547
|
"Deprecated",
|
|
457
548
|
typeof def.deprecated === "string" ? def.deprecated : "",
|
|
458
|
-
(/** @type {
|
|
549
|
+
(/** @type {string} */ v) =>
|
|
459
550
|
transactDoc(activeTab.value, (t) =>
|
|
460
551
|
mutateUpdateDef(t, name, { deprecated: v || undefined }),
|
|
461
552
|
),
|
|
@@ -468,7 +559,7 @@ function renderSignalEditorTemplate(
|
|
|
468
559
|
"Type",
|
|
469
560
|
["string", "integer", "number", "boolean", "array", "object"],
|
|
470
561
|
def.type || "string",
|
|
471
|
-
(/** @type {
|
|
562
|
+
(/** @type {string} */ v) =>
|
|
472
563
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { type: v })),
|
|
473
564
|
)}
|
|
474
565
|
${def.type === "string" || !def.type
|
|
@@ -476,7 +567,7 @@ function renderSignalEditorTemplate(
|
|
|
476
567
|
"Format",
|
|
477
568
|
["", "image", "date", "color"],
|
|
478
569
|
def.format || "",
|
|
479
|
-
(/** @type {
|
|
570
|
+
(/** @type {string} */ v) =>
|
|
480
571
|
transactDoc(activeTab.value, (t) =>
|
|
481
572
|
mutateUpdateDef(t, name, { format: v || undefined }),
|
|
482
573
|
),
|
|
@@ -487,13 +578,14 @@ function renderSignalEditorTemplate(
|
|
|
487
578
|
prop: "Default",
|
|
488
579
|
label: "Default",
|
|
489
580
|
hasValue: false,
|
|
490
|
-
widget: renderMediaPicker("default", defaultVal, (/** @type {
|
|
581
|
+
widget: renderMediaPicker("default", defaultVal, (/** @type {string} */ v) => {
|
|
491
582
|
transactDoc(activeTab.value, (t) =>
|
|
492
583
|
mutateUpdateDef(t, name, { default: v || undefined }),
|
|
493
584
|
);
|
|
494
585
|
}),
|
|
495
586
|
})
|
|
496
|
-
: signalFieldRow("Default", defaultVal, (/** @type {
|
|
587
|
+
: signalFieldRow("Default", defaultVal, (/** @type {string} */ v) => {
|
|
588
|
+
/** @type {unknown} */
|
|
497
589
|
let parsed = v;
|
|
498
590
|
if (def.type === "integer") parsed = parseInt(v, 10) || 0;
|
|
499
591
|
else if (def.type === "number") parsed = parseFloat(v) || 0;
|
|
@@ -505,9 +597,11 @@ function renderSignalEditorTemplate(
|
|
|
505
597
|
parsed = v;
|
|
506
598
|
}
|
|
507
599
|
}
|
|
508
|
-
transactDoc(activeTab.value, (t) =>
|
|
600
|
+
transactDoc(activeTab.value, (t) =>
|
|
601
|
+
mutateUpdateDef(t, name, { default: /** @type {JsonValue} */ (parsed) }),
|
|
602
|
+
);
|
|
509
603
|
})}
|
|
510
|
-
${signalFieldRow("Description", def.description || "", (/** @type {
|
|
604
|
+
${signalFieldRow("Description", def.description || "", (/** @type {string} */ v) =>
|
|
511
605
|
transactDoc(activeTab.value, (t) =>
|
|
512
606
|
mutateUpdateDef(t, name, { description: v || undefined }),
|
|
513
607
|
),
|
|
@@ -515,7 +609,7 @@ function renderSignalEditorTemplate(
|
|
|
515
609
|
${cemFields}
|
|
516
610
|
`;
|
|
517
611
|
} else if (cat === "computed") {
|
|
518
|
-
/** @type {
|
|
612
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
519
613
|
let debounce;
|
|
520
614
|
fields = html`
|
|
521
615
|
${renderFieldRow({
|
|
@@ -527,10 +621,10 @@ function renderSignalEditorTemplate(
|
|
|
527
621
|
class="field-input"
|
|
528
622
|
style="min-height:40px"
|
|
529
623
|
.value=${def.$compute || ""}
|
|
530
|
-
@input=${(/** @type {
|
|
624
|
+
@input=${(/** @type {Event} */ e) => {
|
|
531
625
|
clearTimeout(debounce);
|
|
532
626
|
debounce = setTimeout(() => {
|
|
533
|
-
const expr = e.target.value;
|
|
627
|
+
const expr = /** @type {HTMLInputElement} */ (e.target).value;
|
|
534
628
|
const depMatches = expr.match(/\$[a-zA-Z_]\w*/g) || [];
|
|
535
629
|
const deps = [...new Set(depMatches)].map((d) => `#/state/${d}`);
|
|
536
630
|
transactDoc(activeTab.value, (t) =>
|
|
@@ -549,7 +643,7 @@ function renderSignalEditorTemplate(
|
|
|
549
643
|
widget: html`
|
|
550
644
|
<span class="signal-hint" style="flex:1;max-width:none"
|
|
551
645
|
>${def.$deps
|
|
552
|
-
.map((/** @type {
|
|
646
|
+
.map((/** @type {string} */ d) => d.replace("#/state/", ""))
|
|
553
647
|
.join(", ")}</span
|
|
554
648
|
>
|
|
555
649
|
`,
|
|
@@ -567,29 +661,33 @@ function renderSignalEditorTemplate(
|
|
|
567
661
|
|
|
568
662
|
/** Data source fields for signal editor */
|
|
569
663
|
function renderDataSourceFields(
|
|
570
|
-
/** @type {
|
|
571
|
-
/** @type {
|
|
572
|
-
/** @type {
|
|
573
|
-
/** @type {
|
|
574
|
-
/** @type {
|
|
575
|
-
/** @type {
|
|
664
|
+
/** @type {SignalsPanelState} */ S,
|
|
665
|
+
/** @type {string} */ name,
|
|
666
|
+
/** @type {SignalDef} */ def,
|
|
667
|
+
/** @type {Function} */ textareaRow,
|
|
668
|
+
/** @type {Function} */ pickerRow,
|
|
669
|
+
/** @type {SignalsPanelCtx} */ ctx,
|
|
576
670
|
) {
|
|
577
671
|
const proto = def.$prototype;
|
|
578
672
|
|
|
579
673
|
if (proto === "Request") {
|
|
580
674
|
return html`
|
|
581
|
-
${signalFieldRow("URL", def.url || "", (/** @type {
|
|
675
|
+
${signalFieldRow("URL", def.url || "", (/** @type {string} */ v) =>
|
|
582
676
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { url: v })),
|
|
583
677
|
)}
|
|
584
678
|
${pickerRow(
|
|
585
679
|
"Method",
|
|
586
680
|
["GET", "POST", "PUT", "DELETE", "PATCH"],
|
|
587
681
|
def.method || "GET",
|
|
588
|
-
(/** @type {
|
|
682
|
+
(/** @type {string} */ v) =>
|
|
589
683
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { method: v })),
|
|
590
684
|
)}
|
|
591
|
-
${pickerRow(
|
|
592
|
-
|
|
685
|
+
${pickerRow(
|
|
686
|
+
"Timing",
|
|
687
|
+
["client", "server"],
|
|
688
|
+
def.timing || "client",
|
|
689
|
+
(/** @type {string} */ v) =>
|
|
690
|
+
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { timing: v })),
|
|
593
691
|
)}
|
|
594
692
|
`;
|
|
595
693
|
}
|
|
@@ -601,10 +699,10 @@ function renderDataSourceFields(
|
|
|
601
699
|
: String(def.default)
|
|
602
700
|
: "";
|
|
603
701
|
return html`
|
|
604
|
-
${signalFieldRow("Key", def.key || "", (/** @type {
|
|
702
|
+
${signalFieldRow("Key", def.key || "", (/** @type {string} */ v) =>
|
|
605
703
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { key: v })),
|
|
606
704
|
)}
|
|
607
|
-
${textareaRow("Default", defaultStr, (/** @type {
|
|
705
|
+
${textareaRow("Default", defaultStr, (/** @type {string} */ v) => {
|
|
608
706
|
try {
|
|
609
707
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { default: JSON.parse(v) }));
|
|
610
708
|
} catch {
|
|
@@ -615,13 +713,13 @@ function renderDataSourceFields(
|
|
|
615
713
|
}
|
|
616
714
|
if (proto === "IndexedDB") {
|
|
617
715
|
return html`
|
|
618
|
-
${signalFieldRow("Database", def.database || "", (/** @type {
|
|
716
|
+
${signalFieldRow("Database", def.database || "", (/** @type {string} */ v) =>
|
|
619
717
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { database: v })),
|
|
620
718
|
)}
|
|
621
|
-
${signalFieldRow("Store", def.store || "", (/** @type {
|
|
719
|
+
${signalFieldRow("Store", def.store || "", (/** @type {string} */ v) =>
|
|
622
720
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { store: v })),
|
|
623
721
|
)}
|
|
624
|
-
${signalFieldRow("Version", String(def.version || 1), (/** @type {
|
|
722
|
+
${signalFieldRow("Version", String(def.version || 1), (/** @type {string} */ v) =>
|
|
625
723
|
transactDoc(activeTab.value, (t) =>
|
|
626
724
|
mutateUpdateDef(t, name, { version: parseInt(v, 10) || 1 }),
|
|
627
725
|
),
|
|
@@ -630,14 +728,17 @@ function renderDataSourceFields(
|
|
|
630
728
|
}
|
|
631
729
|
if (proto === "Cookie") {
|
|
632
730
|
return html`
|
|
633
|
-
${signalFieldRow("Cookie", def.name || "", (/** @type {
|
|
731
|
+
${signalFieldRow("Cookie", def.name || "", (/** @type {string} */ v) =>
|
|
634
732
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { name: v })),
|
|
635
733
|
)}
|
|
636
|
-
${signalFieldRow("Default", def.default || "", (/** @type {
|
|
734
|
+
${signalFieldRow("Default", String(def.default || ""), (/** @type {string} */ v) =>
|
|
637
735
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { default: v })),
|
|
638
736
|
)}
|
|
639
737
|
`;
|
|
640
738
|
}
|
|
739
|
+
if (proto === "ContentEntry" || proto === "ContentCollection") {
|
|
740
|
+
return renderContentPrototypeFields(name, def, proto);
|
|
741
|
+
}
|
|
641
742
|
if (proto === "Set" || proto === "Map" || proto === "FormData") {
|
|
642
743
|
const fieldName = proto === "FormData" ? "fields" : "default";
|
|
643
744
|
const fieldLabel = proto === "FormData" ? "Fields" : "Default";
|
|
@@ -647,7 +748,7 @@ function renderDataSourceFields(
|
|
|
647
748
|
: proto === "FormData"
|
|
648
749
|
? JSON.stringify(def.fields || {}, null, 2)
|
|
649
750
|
: "";
|
|
650
|
-
return textareaRow(fieldLabel, defaultStr, (/** @type {
|
|
751
|
+
return textareaRow(fieldLabel, defaultStr, (/** @type {string} */ v) => {
|
|
651
752
|
try {
|
|
652
753
|
transactDoc(activeTab.value, (t) =>
|
|
653
754
|
mutateUpdateDef(t, name, { [fieldName]: JSON.parse(v) }),
|
|
@@ -659,18 +760,129 @@ function renderDataSourceFields(
|
|
|
659
760
|
return renderExternalPrototypeEditorTemplate(S, name, def, ctx);
|
|
660
761
|
}
|
|
661
762
|
|
|
763
|
+
/** ContentEntry/ContentCollection fields for signal editor */
|
|
764
|
+
function renderContentPrototypeFields(
|
|
765
|
+
/** @type {string} */ name,
|
|
766
|
+
/** @type {SignalDef} */ def,
|
|
767
|
+
/** @type {string} */ proto,
|
|
768
|
+
) {
|
|
769
|
+
const contentTypes = projectState?.projectConfig?.contentTypes;
|
|
770
|
+
const typeNames = contentTypes ? Object.keys(contentTypes) : [];
|
|
771
|
+
const currentType = def.contentType || "";
|
|
772
|
+
const schema = /** @type {ContentTypeSchema | undefined} */ (
|
|
773
|
+
currentType && contentTypes?.[currentType]?.schema
|
|
774
|
+
) ||
|
|
775
|
+
undefined;
|
|
776
|
+
|
|
777
|
+
const contentTypeField = typeNames.length
|
|
778
|
+
? html`
|
|
779
|
+
<div class="signal-field-row">
|
|
780
|
+
<label class="signal-field-label">Content Type</label>
|
|
781
|
+
<sp-picker
|
|
782
|
+
size="s"
|
|
783
|
+
value=${currentType}
|
|
784
|
+
style="width:100%"
|
|
785
|
+
@change=${(/** @type {Event} */ e) => {
|
|
786
|
+
const v = /** @type {HTMLSelectElement} */ (e.target).value;
|
|
787
|
+
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { contentType: v }));
|
|
788
|
+
}}
|
|
789
|
+
>
|
|
790
|
+
${typeNames.map((t) => html`<sp-menu-item value=${t}>${t}</sp-menu-item>`)}
|
|
791
|
+
</sp-picker>
|
|
792
|
+
</div>
|
|
793
|
+
`
|
|
794
|
+
: signalFieldRow("Content Type", currentType, (/** @type {string} */ v) =>
|
|
795
|
+
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { contentType: v })),
|
|
796
|
+
);
|
|
797
|
+
|
|
798
|
+
/** @type {import("lit-html").TemplateResult | symbol} */
|
|
799
|
+
let entryFields = nothing;
|
|
800
|
+
if (proto === "ContentEntry") {
|
|
801
|
+
const idVal = def.id;
|
|
802
|
+
const idStr =
|
|
803
|
+
idVal && typeof idVal === "object" && /** @type {Record<string, unknown>} */ (idVal).$ref
|
|
804
|
+
? /** @type {string} */ (/** @type {Record<string, unknown>} */ (idVal).$ref)
|
|
805
|
+
: typeof idVal === "string"
|
|
806
|
+
? idVal
|
|
807
|
+
: "";
|
|
808
|
+
entryFields = signalFieldRow("ID", idStr, (/** @type {string} */ v) => {
|
|
809
|
+
const val = v.startsWith("#/") ? { $ref: v } : v;
|
|
810
|
+
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { id: val }));
|
|
811
|
+
});
|
|
812
|
+
} else {
|
|
813
|
+
const filterStr = def.filter ? JSON.stringify(def.filter) : "";
|
|
814
|
+
const sortStr = def.sort ? `${def.sort.field || ""} ${def.sort.order || ""}`.trim() : "";
|
|
815
|
+
const limitStr = def.limit != null ? String(def.limit) : "";
|
|
816
|
+
entryFields = html`
|
|
817
|
+
${signalFieldRow("Filter", filterStr, (/** @type {string} */ v) => {
|
|
818
|
+
try {
|
|
819
|
+
const parsed = v ? JSON.parse(v) : undefined;
|
|
820
|
+
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { filter: parsed }));
|
|
821
|
+
} catch {}
|
|
822
|
+
})}
|
|
823
|
+
${signalFieldRow("Sort", sortStr, (/** @type {string} */ v) => {
|
|
824
|
+
if (!v) {
|
|
825
|
+
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { sort: undefined }));
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
const [field, order] = v.split(" ");
|
|
829
|
+
transactDoc(activeTab.value, (t) =>
|
|
830
|
+
mutateUpdateDef(t, name, { sort: { field, order: order || "asc" } }),
|
|
831
|
+
);
|
|
832
|
+
})}
|
|
833
|
+
${signalFieldRow("Limit", limitStr, (/** @type {string} */ v) => {
|
|
834
|
+
const num = v ? parseInt(v, 10) : undefined;
|
|
835
|
+
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { limit: num }));
|
|
836
|
+
})}
|
|
837
|
+
`;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/** @type {import("lit-html").TemplateResult | symbol} */
|
|
841
|
+
let schemaFields = nothing;
|
|
842
|
+
if (schema?.properties) {
|
|
843
|
+
const fields = Object.entries(schema.properties);
|
|
844
|
+
const required = new Set(schema.required || []);
|
|
845
|
+
schemaFields = html`
|
|
846
|
+
<div style="margin-top:8px;padding:6px 0;border-top:1px solid var(--border-dim)">
|
|
847
|
+
<div style="font-size:11px;color:var(--fg-dim);margin-bottom:4px;font-weight:500">
|
|
848
|
+
Fields (${currentType})
|
|
849
|
+
</div>
|
|
850
|
+
${fields.map(
|
|
851
|
+
([field, fieldDef]) => html`
|
|
852
|
+
<div style="font-size:11px;padding:2px 0;display:flex;gap:4px;align-items:center">
|
|
853
|
+
<code style="color:var(--fg-default)">${field}</code>
|
|
854
|
+
<span style="color:var(--fg-dim)">${/** @type {any} */ (fieldDef).type || ""}</span>
|
|
855
|
+
${required.has(field)
|
|
856
|
+
? html`<span style="color:var(--color-accent,#f36f32);font-size:9px">req</span>`
|
|
857
|
+
: nothing}
|
|
858
|
+
</div>
|
|
859
|
+
`,
|
|
860
|
+
)}
|
|
861
|
+
</div>
|
|
862
|
+
`;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
return html`
|
|
866
|
+
${contentTypeField}
|
|
867
|
+
${signalFieldRow("Prototype", proto, (/** @type {string} */ v) =>
|
|
868
|
+
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { $prototype: v })),
|
|
869
|
+
)}
|
|
870
|
+
${entryFields} ${schemaFields}
|
|
871
|
+
`;
|
|
872
|
+
}
|
|
873
|
+
|
|
662
874
|
/** Function fields for signal editor */
|
|
663
875
|
function renderFunctionFields(
|
|
664
|
-
/** @type {
|
|
665
|
-
/** @type {
|
|
666
|
-
/** @type {
|
|
667
|
-
/** @type {
|
|
668
|
-
/** @type {
|
|
876
|
+
/** @type {SignalsPanelState} */ S,
|
|
877
|
+
/** @type {string} */ name,
|
|
878
|
+
/** @type {SignalDef} */ def,
|
|
879
|
+
/** @type {Function} */ textareaRow,
|
|
880
|
+
/** @type {SignalsPanelCtx} */ ctx,
|
|
669
881
|
) {
|
|
670
882
|
const descriptionField = signalFieldRow(
|
|
671
883
|
"Description",
|
|
672
884
|
def.description || "",
|
|
673
|
-
(/** @type {
|
|
885
|
+
(/** @type {string} */ v) =>
|
|
674
886
|
transactDoc(activeTab.value, (t) =>
|
|
675
887
|
mutateUpdateDef(t, name, { description: v || undefined }),
|
|
676
888
|
),
|
|
@@ -678,10 +890,10 @@ function renderFunctionFields(
|
|
|
678
890
|
|
|
679
891
|
const bodyField = def.$src
|
|
680
892
|
? html`
|
|
681
|
-
${signalFieldRow("Source", def.$src || "", (/** @type {
|
|
893
|
+
${signalFieldRow("Source", def.$src || "", (/** @type {string} */ v) =>
|
|
682
894
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { $src: v || undefined })),
|
|
683
895
|
)}
|
|
684
|
-
${signalFieldRow("Export", def.$export || "", (/** @type {
|
|
896
|
+
${signalFieldRow("Export", def.$export || "", (/** @type {string} */ v) =>
|
|
685
897
|
transactDoc(activeTab.value, (t) =>
|
|
686
898
|
mutateUpdateDef(t, name, { $export: v || undefined }),
|
|
687
899
|
),
|
|
@@ -706,8 +918,8 @@ function renderFunctionFields(
|
|
|
706
918
|
class="field-input"
|
|
707
919
|
style="min-height:60px;font-family:monospace;font-size:11px"
|
|
708
920
|
.value=${def.body || ""}
|
|
709
|
-
@input=${(/** @type {
|
|
710
|
-
const v = e.target.value;
|
|
921
|
+
@input=${(/** @type {Event} */ e) => {
|
|
922
|
+
const v = /** @type {HTMLInputElement} */ (e.target).value;
|
|
711
923
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { body: v }));
|
|
712
924
|
}}
|
|
713
925
|
></textarea>
|
|
@@ -723,10 +935,10 @@ function renderFunctionFields(
|
|
|
723
935
|
|
|
724
936
|
/** Render CEM parameter editor with basic/advanced toggle. */
|
|
725
937
|
function renderParameterEditorTemplate(
|
|
726
|
-
/** @type {
|
|
727
|
-
/** @type {
|
|
728
|
-
/** @type {
|
|
729
|
-
/** @type {
|
|
938
|
+
/** @type {SignalsPanelState} */ S,
|
|
939
|
+
/** @type {string} */ name,
|
|
940
|
+
/** @type {SignalDef} */ def,
|
|
941
|
+
/** @type {SignalsPanelCtx} */ ctx,
|
|
730
942
|
) {
|
|
731
943
|
const params = (def.parameters || []).map(normParam);
|
|
732
944
|
const isAdvanced = advancedParamOpen.has(name);
|
|
@@ -740,7 +952,7 @@ function renderParameterEditorTemplate(
|
|
|
740
952
|
widget: html`
|
|
741
953
|
<div style="display:flex;flex-wrap:wrap;gap:4px;align-items:center">
|
|
742
954
|
${params.map(
|
|
743
|
-
(/** @type {
|
|
955
|
+
(/** @type {CemParameter} */ p, /** @type {number} */ i) => html`
|
|
744
956
|
<span
|
|
745
957
|
style="display:inline-flex;align-items:center;gap:2px;padding:1px 6px;border-radius:3px;background:var(--bg-hover);font-size:11px;font-family:monospace"
|
|
746
958
|
>
|
|
@@ -751,9 +963,11 @@ function renderParameterEditorTemplate(
|
|
|
751
963
|
transactDoc(activeTab.value, (t) =>
|
|
752
964
|
mutateUpdateDef(t, name, {
|
|
753
965
|
parameters: params.filter(
|
|
754
|
-
(/** @type {
|
|
966
|
+
(/** @type {unknown} */ _, /** @type {number} */ j) => j !== i,
|
|
755
967
|
).length
|
|
756
|
-
? params.filter(
|
|
968
|
+
? params.filter(
|
|
969
|
+
(/** @type {unknown} */ _, /** @type {number} */ j) => j !== i,
|
|
970
|
+
)
|
|
757
971
|
: undefined,
|
|
758
972
|
}),
|
|
759
973
|
);
|
|
@@ -767,11 +981,14 @@ function renderParameterEditorTemplate(
|
|
|
767
981
|
class="field-input"
|
|
768
982
|
style="width:60px;flex:0 0 auto;font-size:11px"
|
|
769
983
|
placeholder="+"
|
|
770
|
-
@keydown=${(/** @type {
|
|
771
|
-
if (e.key === "Enter" && e.target.value.trim()) {
|
|
984
|
+
@keydown=${(/** @type {KeyboardEvent} */ e) => {
|
|
985
|
+
if (e.key === "Enter" && /** @type {HTMLInputElement} */ (e.target).value.trim()) {
|
|
772
986
|
transactDoc(activeTab.value, (t) =>
|
|
773
987
|
mutateUpdateDef(t, name, {
|
|
774
|
-
parameters: [
|
|
988
|
+
parameters: [
|
|
989
|
+
...params,
|
|
990
|
+
{ name: /** @type {HTMLInputElement} */ (e.target).value.trim() },
|
|
991
|
+
],
|
|
775
992
|
}),
|
|
776
993
|
);
|
|
777
994
|
}
|
|
@@ -798,16 +1015,16 @@ function renderParameterEditorTemplate(
|
|
|
798
1015
|
widget: html`
|
|
799
1016
|
<div style="display:flex;flex-direction:column;gap:4px">
|
|
800
1017
|
${params.map(
|
|
801
|
-
(/** @type {
|
|
1018
|
+
(/** @type {CemParameter} */ p, /** @type {number} */ i) => html`
|
|
802
1019
|
<div style="display:flex;gap:4px;align-items:center">
|
|
803
1020
|
<input
|
|
804
1021
|
class="field-input"
|
|
805
1022
|
.value=${p.name || ""}
|
|
806
1023
|
placeholder="name"
|
|
807
1024
|
style="flex:1"
|
|
808
|
-
@change=${(/** @type {
|
|
1025
|
+
@change=${(/** @type {Event} */ e) => {
|
|
809
1026
|
const next = [...params];
|
|
810
|
-
next[i] = { ...next[i], name: e.target.value };
|
|
1027
|
+
next[i] = { ...next[i], name: /** @type {HTMLInputElement} */ (e.target).value };
|
|
811
1028
|
transactDoc(activeTab.value, (t) =>
|
|
812
1029
|
mutateUpdateDef(t, name, { parameters: next }),
|
|
813
1030
|
);
|
|
@@ -818,11 +1035,13 @@ function renderParameterEditorTemplate(
|
|
|
818
1035
|
.value=${p.type?.text || ""}
|
|
819
1036
|
placeholder="type"
|
|
820
1037
|
style="flex:1"
|
|
821
|
-
@change=${(/** @type {
|
|
1038
|
+
@change=${(/** @type {Event} */ e) => {
|
|
822
1039
|
const next = [...params];
|
|
823
1040
|
next[i] = {
|
|
824
1041
|
...next[i],
|
|
825
|
-
type:
|
|
1042
|
+
type: /** @type {HTMLInputElement} */ (e.target).value
|
|
1043
|
+
? { text: /** @type {HTMLInputElement} */ (e.target).value }
|
|
1044
|
+
: undefined,
|
|
826
1045
|
};
|
|
827
1046
|
transactDoc(activeTab.value, (t) =>
|
|
828
1047
|
mutateUpdateDef(t, name, { parameters: next }),
|
|
@@ -834,9 +1053,12 @@ function renderParameterEditorTemplate(
|
|
|
834
1053
|
.value=${p.description || ""}
|
|
835
1054
|
placeholder="desc"
|
|
836
1055
|
style="flex:2"
|
|
837
|
-
@change=${(/** @type {
|
|
1056
|
+
@change=${(/** @type {Event} */ e) => {
|
|
838
1057
|
const next = [...params];
|
|
839
|
-
next[i] = {
|
|
1058
|
+
next[i] = {
|
|
1059
|
+
...next[i],
|
|
1060
|
+
description: /** @type {HTMLInputElement} */ (e.target).value || undefined,
|
|
1061
|
+
};
|
|
840
1062
|
transactDoc(activeTab.value, (t) =>
|
|
841
1063
|
mutateUpdateDef(t, name, { parameters: next }),
|
|
842
1064
|
);
|
|
@@ -846,9 +1068,12 @@ function renderParameterEditorTemplate(
|
|
|
846
1068
|
type="checkbox"
|
|
847
1069
|
title="optional"
|
|
848
1070
|
.checked=${!!p.optional}
|
|
849
|
-
@change=${(/** @type {
|
|
1071
|
+
@change=${(/** @type {Event} */ e) => {
|
|
850
1072
|
const next = [...params];
|
|
851
|
-
next[i] = {
|
|
1073
|
+
next[i] = {
|
|
1074
|
+
...next[i],
|
|
1075
|
+
optional: /** @type {HTMLInputElement} */ (e.target).checked || undefined,
|
|
1076
|
+
};
|
|
852
1077
|
transactDoc(activeTab.value, (t) =>
|
|
853
1078
|
mutateUpdateDef(t, name, { parameters: next }),
|
|
854
1079
|
);
|
|
@@ -858,7 +1083,7 @@ function renderParameterEditorTemplate(
|
|
|
858
1083
|
style="cursor:pointer;opacity:0.5"
|
|
859
1084
|
@click=${() => {
|
|
860
1085
|
const next = params.filter(
|
|
861
|
-
(/** @type {
|
|
1086
|
+
(/** @type {unknown} */ _, /** @type {number} */ j) => j !== i,
|
|
862
1087
|
);
|
|
863
1088
|
transactDoc(activeTab.value, (t) =>
|
|
864
1089
|
mutateUpdateDef(t, name, { parameters: next.length ? next : undefined }),
|
|
@@ -893,11 +1118,11 @@ function renderParameterEditorTemplate(
|
|
|
893
1118
|
|
|
894
1119
|
/** Render CEM emits editor for function state entries. */
|
|
895
1120
|
function renderEmitsEditorTemplate(
|
|
896
|
-
/** @type {
|
|
897
|
-
/** @type {
|
|
898
|
-
/** @type {
|
|
1121
|
+
/** @type {SignalsPanelState} */ S,
|
|
1122
|
+
/** @type {string} */ name,
|
|
1123
|
+
/** @type {SignalDef} */ def,
|
|
899
1124
|
) {
|
|
900
|
-
const emits = def.emits || [];
|
|
1125
|
+
const emits = /** @type {CemEvent[]} */ (def.emits || []);
|
|
901
1126
|
if (emits.length === 0 && !isCustomElementDoc(S)) return nothing;
|
|
902
1127
|
|
|
903
1128
|
return html`
|
|
@@ -907,16 +1132,16 @@ function renderEmitsEditorTemplate(
|
|
|
907
1132
|
Emits
|
|
908
1133
|
</div>
|
|
909
1134
|
${emits.map(
|
|
910
|
-
(/** @type {
|
|
1135
|
+
(/** @type {CemEvent} */ ev, /** @type {number} */ i) => html`
|
|
911
1136
|
<div style="display:flex;gap:4px;align-items:center;margin-bottom:4px">
|
|
912
1137
|
<input
|
|
913
1138
|
class="field-input"
|
|
914
1139
|
.value=${ev.name || ""}
|
|
915
1140
|
placeholder="event name"
|
|
916
1141
|
style="flex:1"
|
|
917
|
-
@change=${(/** @type {
|
|
1142
|
+
@change=${(/** @type {Event} */ e) => {
|
|
918
1143
|
const next = [...emits];
|
|
919
|
-
next[i] = { ...next[i], name: e.target.value };
|
|
1144
|
+
next[i] = { ...next[i], name: /** @type {HTMLInputElement} */ (e.target).value };
|
|
920
1145
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { emits: next }));
|
|
921
1146
|
}}
|
|
922
1147
|
/>
|
|
@@ -925,9 +1150,14 @@ function renderEmitsEditorTemplate(
|
|
|
925
1150
|
.value=${ev.type?.text || ""}
|
|
926
1151
|
placeholder="type"
|
|
927
1152
|
style="flex:1"
|
|
928
|
-
@change=${(/** @type {
|
|
1153
|
+
@change=${(/** @type {Event} */ e) => {
|
|
929
1154
|
const next = [...emits];
|
|
930
|
-
next[i] = {
|
|
1155
|
+
next[i] = {
|
|
1156
|
+
...next[i],
|
|
1157
|
+
type: /** @type {HTMLInputElement} */ (e.target).value
|
|
1158
|
+
? { text: /** @type {HTMLInputElement} */ (e.target).value }
|
|
1159
|
+
: undefined,
|
|
1160
|
+
};
|
|
931
1161
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { emits: next }));
|
|
932
1162
|
}}
|
|
933
1163
|
/>
|
|
@@ -936,9 +1166,12 @@ function renderEmitsEditorTemplate(
|
|
|
936
1166
|
.value=${ev.description || ""}
|
|
937
1167
|
placeholder="description"
|
|
938
1168
|
style="flex:2"
|
|
939
|
-
@change=${(/** @type {
|
|
1169
|
+
@change=${(/** @type {Event} */ e) => {
|
|
940
1170
|
const next = [...emits];
|
|
941
|
-
next[i] = {
|
|
1171
|
+
next[i] = {
|
|
1172
|
+
...next[i],
|
|
1173
|
+
description: /** @type {HTMLInputElement} */ (e.target).value || undefined,
|
|
1174
|
+
};
|
|
942
1175
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { emits: next }));
|
|
943
1176
|
}}
|
|
944
1177
|
/>
|
|
@@ -947,9 +1180,10 @@ function renderEmitsEditorTemplate(
|
|
|
947
1180
|
@click=${() => {
|
|
948
1181
|
transactDoc(activeTab.value, (t) =>
|
|
949
1182
|
mutateUpdateDef(t, name, {
|
|
950
|
-
emits: emits.filter(
|
|
951
|
-
|
|
952
|
-
|
|
1183
|
+
emits: emits.filter(
|
|
1184
|
+
(/** @type {unknown} */ _, /** @type {number} */ j) => j !== i,
|
|
1185
|
+
).length
|
|
1186
|
+
? emits.filter((/** @type {unknown} */ _, /** @type {number} */ j) => j !== i)
|
|
953
1187
|
: undefined,
|
|
954
1188
|
}),
|
|
955
1189
|
);
|
|
@@ -978,10 +1212,10 @@ function renderEmitsEditorTemplate(
|
|
|
978
1212
|
* appropriate form controls.
|
|
979
1213
|
*/
|
|
980
1214
|
export function renderSchemaFieldsTemplate(
|
|
981
|
-
/** @type {
|
|
982
|
-
/** @type {
|
|
983
|
-
/** @type {
|
|
984
|
-
/** @type {
|
|
1215
|
+
/** @type {JsonSchema | null | undefined} */ schema,
|
|
1216
|
+
/** @type {SignalDef} */ def,
|
|
1217
|
+
/** @type {string} */ name,
|
|
1218
|
+
/** @type {SignalsPanelState} */ _S,
|
|
985
1219
|
) {
|
|
986
1220
|
if (!schema?.properties) return nothing;
|
|
987
1221
|
|
|
@@ -1003,29 +1237,33 @@ export function renderSchemaFieldsTemplate(
|
|
|
1003
1237
|
: ps.default !== undefined
|
|
1004
1238
|
? String(ps.default)
|
|
1005
1239
|
: "__none__"}
|
|
1006
|
-
@change=${(/** @type {
|
|
1240
|
+
@change=${(/** @type {Event} */ e) =>
|
|
1007
1241
|
transactDoc(activeTab.value, (t) =>
|
|
1008
1242
|
mutateUpdateDef(t, name, {
|
|
1009
|
-
[prop]: e.target.value === "__none__"
|
|
1243
|
+
[prop]: /** @type {HTMLInputElement} */ (e.target).value === "__none__"
|
|
1244
|
+
? undefined
|
|
1245
|
+
: /** @type {HTMLInputElement} */ (e.target).value,
|
|
1010
1246
|
}),
|
|
1011
1247
|
)}
|
|
1012
1248
|
>
|
|
1013
1249
|
${!required.has(prop) ? html`<sp-menu-item value="__none__">—</sp-menu-item>` : nothing}
|
|
1014
1250
|
${ps.enum.map(
|
|
1015
|
-
(/** @type {
|
|
1251
|
+
(/** @type {string} */ val) => html`<sp-menu-item value=${val}>${val}</sp-menu-item>`,
|
|
1016
1252
|
)}
|
|
1017
1253
|
</sp-picker>
|
|
1018
1254
|
`;
|
|
1019
1255
|
} else if (ps.type === "boolean") {
|
|
1020
1256
|
control = html`<sp-checkbox
|
|
1021
1257
|
?checked=${currentValue ?? ps.default ?? false}
|
|
1022
|
-
@change=${(/** @type {
|
|
1258
|
+
@change=${(/** @type {Event} */ e) =>
|
|
1023
1259
|
transactDoc(activeTab.value, (t) =>
|
|
1024
|
-
mutateUpdateDef(t, name, {
|
|
1260
|
+
mutateUpdateDef(t, name, {
|
|
1261
|
+
[prop]: /** @type {HTMLInputElement} */ (e.target).checked,
|
|
1262
|
+
}),
|
|
1025
1263
|
)}
|
|
1026
1264
|
></sp-checkbox>`;
|
|
1027
1265
|
} else if (ps.type === "integer" || ps.type === "number") {
|
|
1028
|
-
/** @type {
|
|
1266
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
1029
1267
|
let debounce;
|
|
1030
1268
|
control = html`<sp-number-field
|
|
1031
1269
|
size="s"
|
|
@@ -1034,11 +1272,13 @@ export function renderSchemaFieldsTemplate(
|
|
|
1034
1272
|
step=${ps.type === "integer" ? "1" : nothing}
|
|
1035
1273
|
.value=${currentValue !== undefined ? currentValue : nothing}
|
|
1036
1274
|
placeholder=${ps.default !== undefined ? String(ps.default) : nothing}
|
|
1037
|
-
@change=${(/** @type {
|
|
1275
|
+
@change=${(/** @type {Event} */ e) => {
|
|
1038
1276
|
clearTimeout(debounce);
|
|
1039
1277
|
debounce = setTimeout(() => {
|
|
1040
1278
|
const parsed =
|
|
1041
|
-
ps.type === "integer"
|
|
1279
|
+
ps.type === "integer"
|
|
1280
|
+
? parseInt(/** @type {HTMLInputElement} */ (e.target).value, 10)
|
|
1281
|
+
: parseFloat(/** @type {HTMLInputElement} */ (e.target).value);
|
|
1042
1282
|
transactDoc(activeTab.value, (t) =>
|
|
1043
1283
|
mutateUpdateDef(t, name, { [prop]: isNaN(parsed) ? undefined : parsed }),
|
|
1044
1284
|
);
|
|
@@ -1048,15 +1288,18 @@ export function renderSchemaFieldsTemplate(
|
|
|
1048
1288
|
} else if (ps.format === "json-schema") {
|
|
1049
1289
|
const hasValue =
|
|
1050
1290
|
currentValue && typeof currentValue === "object" && Object.keys(currentValue).length > 0;
|
|
1051
|
-
const
|
|
1052
|
-
|
|
1291
|
+
const cv = /** @type {Record<string, unknown>} */ (currentValue);
|
|
1292
|
+
const isRef = hasValue && cv.$ref;
|
|
1293
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
1053
1294
|
let debounce;
|
|
1054
1295
|
control = html`
|
|
1055
1296
|
<div class="schema-param-editor">
|
|
1056
|
-
${hasValue && !isRef &&
|
|
1297
|
+
${hasValue && !isRef && cv.properties
|
|
1057
1298
|
? html`
|
|
1058
1299
|
<div style="display:flex;flex-wrap:wrap;gap:3px;margin-bottom:4px">
|
|
1059
|
-
${Object.entries(
|
|
1300
|
+
${Object.entries(
|
|
1301
|
+
/** @type {Record<string, Record<string, unknown>>} */ (cv.properties),
|
|
1302
|
+
).map(
|
|
1060
1303
|
([k, v]) => html`
|
|
1061
1304
|
<span
|
|
1062
1305
|
style="background:var(--bg-alt);padding:1px 6px;border-radius:3px;font-size:10px;color:var(--fg-dim)"
|
|
@@ -1077,12 +1320,14 @@ export function renderSchemaFieldsTemplate(
|
|
|
1077
1320
|
})}
|
|
1078
1321
|
.value=${currentValue !== undefined ? JSON.stringify(currentValue, null, 2) : ""}
|
|
1079
1322
|
placeholder=${ps.description ?? "JSON Schema defining the data shape\u2026"}
|
|
1080
|
-
@input=${(/** @type {
|
|
1323
|
+
@input=${(/** @type {Event} */ e) => {
|
|
1081
1324
|
clearTimeout(debounce);
|
|
1082
1325
|
debounce = setTimeout(() => {
|
|
1083
1326
|
try {
|
|
1084
1327
|
transactDoc(activeTab.value, (t) =>
|
|
1085
|
-
mutateUpdateDef(t, name, {
|
|
1328
|
+
mutateUpdateDef(t, name, {
|
|
1329
|
+
[prop]: JSON.parse(/** @type {HTMLInputElement} */ (e.target).value),
|
|
1330
|
+
}),
|
|
1086
1331
|
);
|
|
1087
1332
|
} catch {}
|
|
1088
1333
|
}, 500);
|
|
@@ -1091,7 +1336,7 @@ export function renderSchemaFieldsTemplate(
|
|
|
1091
1336
|
</div>
|
|
1092
1337
|
`;
|
|
1093
1338
|
} else if (ps.type === "array" || ps.type === "object") {
|
|
1094
|
-
/** @type {
|
|
1339
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
1095
1340
|
let debounce;
|
|
1096
1341
|
control = html`<sp-textfield
|
|
1097
1342
|
multiline
|
|
@@ -1099,19 +1344,21 @@ export function renderSchemaFieldsTemplate(
|
|
|
1099
1344
|
style="min-height:40px"
|
|
1100
1345
|
.value=${currentValue !== undefined ? JSON.stringify(currentValue, null, 2) : ""}
|
|
1101
1346
|
placeholder=${ps.default !== undefined ? JSON.stringify(ps.default) : nothing}
|
|
1102
|
-
@input=${(/** @type {
|
|
1347
|
+
@input=${(/** @type {Event} */ e) => {
|
|
1103
1348
|
clearTimeout(debounce);
|
|
1104
1349
|
debounce = setTimeout(() => {
|
|
1105
1350
|
try {
|
|
1106
1351
|
transactDoc(activeTab.value, (t) =>
|
|
1107
|
-
mutateUpdateDef(t, name, {
|
|
1352
|
+
mutateUpdateDef(t, name, {
|
|
1353
|
+
[prop]: JSON.parse(/** @type {HTMLInputElement} */ (e.target).value),
|
|
1354
|
+
}),
|
|
1108
1355
|
);
|
|
1109
1356
|
} catch {}
|
|
1110
1357
|
}, 500);
|
|
1111
1358
|
}}
|
|
1112
1359
|
></sp-textfield>`;
|
|
1113
1360
|
} else {
|
|
1114
|
-
/** @type {
|
|
1361
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
1115
1362
|
let debounce;
|
|
1116
1363
|
const ph = ps.default !== undefined ? String(ps.default) : (ps.examples?.[0] ?? "");
|
|
1117
1364
|
control = html`<sp-textfield
|
|
@@ -1119,12 +1366,14 @@ export function renderSchemaFieldsTemplate(
|
|
|
1119
1366
|
.value=${currentValue ?? ""}
|
|
1120
1367
|
placeholder=${ph || nothing}
|
|
1121
1368
|
title=${ps.description || nothing}
|
|
1122
|
-
@input=${(/** @type {
|
|
1369
|
+
@input=${(/** @type {Event} */ e) => {
|
|
1123
1370
|
clearTimeout(debounce);
|
|
1124
1371
|
debounce = setTimeout(
|
|
1125
1372
|
() =>
|
|
1126
1373
|
transactDoc(activeTab.value, (t) =>
|
|
1127
|
-
mutateUpdateDef(t, name, {
|
|
1374
|
+
mutateUpdateDef(t, name, {
|
|
1375
|
+
[prop]: /** @type {HTMLInputElement} */ (e.target).value || undefined,
|
|
1376
|
+
}),
|
|
1128
1377
|
),
|
|
1129
1378
|
400,
|
|
1130
1379
|
);
|
|
@@ -1133,7 +1382,7 @@ export function renderSchemaFieldsTemplate(
|
|
|
1133
1382
|
}
|
|
1134
1383
|
|
|
1135
1384
|
return renderFieldRow({
|
|
1136
|
-
prop: ps.name,
|
|
1385
|
+
prop: ps.name || prop,
|
|
1137
1386
|
label: labelText,
|
|
1138
1387
|
hasValue: false,
|
|
1139
1388
|
widget: control,
|
|
@@ -1146,13 +1395,13 @@ export function renderSchemaFieldsTemplate(
|
|
|
1146
1395
|
* schema-driven config fields.
|
|
1147
1396
|
*/
|
|
1148
1397
|
export function renderExternalPrototypeEditorTemplate(
|
|
1149
|
-
/** @type {
|
|
1150
|
-
/** @type {
|
|
1151
|
-
/** @type {
|
|
1152
|
-
/** @type {
|
|
1398
|
+
/** @type {SignalsPanelState} */ S,
|
|
1399
|
+
/** @type {string} */ name,
|
|
1400
|
+
/** @type {SignalDef} */ def,
|
|
1401
|
+
/** @type {SignalsPanelCtx} */ ctx,
|
|
1153
1402
|
) {
|
|
1154
1403
|
// Schema-driven config fields (async with cache)
|
|
1155
|
-
/** @type {
|
|
1404
|
+
/** @type {import("lit-html").TemplateResult | typeof nothing} */
|
|
1156
1405
|
let schemaContent = nothing;
|
|
1157
1406
|
if (def.$src && def.$prototype) {
|
|
1158
1407
|
const cacheKey = `${def.$src}::${def.$prototype}`;
|
|
@@ -1173,23 +1422,23 @@ export function renderExternalPrototypeEditorTemplate(
|
|
|
1173
1422
|
>
|
|
1174
1423
|
Loading schema…
|
|
1175
1424
|
</div>`;
|
|
1176
|
-
fetchPluginSchema(def, S).then((schema) => {
|
|
1425
|
+
fetchPluginSchema(def, /** @type {{ documentPath?: string }} */ (S)).then((schema) => {
|
|
1177
1426
|
if (schema) ctx.renderLeftPanel();
|
|
1178
1427
|
});
|
|
1179
1428
|
}
|
|
1180
1429
|
}
|
|
1181
1430
|
|
|
1182
1431
|
return html`
|
|
1183
|
-
${signalFieldRow("Source", def.$src || "", (/** @type {
|
|
1432
|
+
${signalFieldRow("Source", def.$src || "", (/** @type {string} */ v) => {
|
|
1184
1433
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { $src: v || undefined }));
|
|
1185
1434
|
pluginSchemaCache.delete(`${v}::${def.$prototype}`);
|
|
1186
1435
|
})}
|
|
1187
|
-
${signalFieldRow("Prototype", def.$prototype || "", (/** @type {
|
|
1436
|
+
${signalFieldRow("Prototype", def.$prototype || "", (/** @type {string} */ v) => {
|
|
1188
1437
|
transactDoc(activeTab.value, (t) => mutateUpdateDef(t, name, { $prototype: v || undefined }));
|
|
1189
1438
|
pluginSchemaCache.delete(`${def.$src}::${v}`);
|
|
1190
1439
|
})}
|
|
1191
1440
|
${def.$export
|
|
1192
|
-
? signalFieldRow("Export", def.$export || "", (/** @type {
|
|
1441
|
+
? signalFieldRow("Export", def.$export || "", (/** @type {string} */ v) =>
|
|
1193
1442
|
transactDoc(activeTab.value, (t) =>
|
|
1194
1443
|
mutateUpdateDef(t, name, { $export: v || undefined }),
|
|
1195
1444
|
),
|