@jxsuite/studio 0.28.2 → 0.28.4
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.js +86144 -83971
- package/dist/studio.js.map +229 -219
- package/package.json +5 -5
- package/src/browse/browse-modal.ts +9 -3
- package/src/browse/browse.ts +139 -82
- package/src/canvas/canvas-diff.ts +35 -18
- package/src/canvas/canvas-helpers.ts +55 -21
- package/src/canvas/canvas-live-render.ts +140 -89
- package/src/canvas/canvas-render.ts +127 -82
- package/src/canvas/canvas-utils.ts +68 -42
- package/src/canvas/nested-site-style.ts +15 -7
- package/src/editor/component-inline-edit.ts +90 -51
- package/src/editor/content-inline-edit.ts +75 -72
- package/src/editor/context-menu.ts +125 -71
- package/src/editor/convert-targets.ts +17 -13
- package/src/editor/convert-to-component.ts +51 -28
- package/src/editor/convert-to-repeater.ts +44 -19
- package/src/editor/inline-edit.ts +107 -52
- package/src/editor/inline-format.ts +128 -60
- package/src/editor/insertion-helper.ts +26 -14
- package/src/editor/shortcuts.ts +89 -43
- package/src/editor/slash-menu.ts +41 -26
- package/src/files/components.ts +9 -7
- package/src/files/file-ops.ts +53 -33
- package/src/files/files.ts +246 -143
- package/src/format/constraints.ts +25 -15
- package/src/format/format-host.ts +33 -10
- package/src/github/github-auth.ts +24 -14
- package/src/github/github-publish.ts +20 -14
- package/src/new-project/new-project-modal.ts +27 -18
- package/src/panels/activity-bar.ts +27 -26
- package/src/panels/ai-panel.ts +100 -44
- package/src/panels/block-action-bar.ts +84 -52
- package/src/panels/canvas-dnd.ts +47 -28
- package/src/panels/data-explorer.ts +24 -11
- package/src/panels/dnd.ts +148 -100
- package/src/panels/editors.ts +54 -37
- package/src/panels/elements-panel.ts +23 -13
- package/src/panels/events-panel.ts +48 -38
- package/src/panels/git-panel.ts +95 -60
- package/src/panels/head-panel.ts +138 -84
- package/src/panels/imports-panel.ts +66 -29
- package/src/panels/layers-panel.ts +80 -36
- package/src/panels/left-panel.ts +86 -53
- package/src/panels/overlays.ts +36 -19
- package/src/panels/panel-events.ts +48 -27
- package/src/panels/panel-scheduler.ts +41 -23
- package/src/panels/preview-render.ts +26 -26
- package/src/panels/properties-panel.ts +155 -118
- package/src/panels/pseudo-preview.ts +31 -15
- package/src/panels/quick-search.ts +28 -13
- package/src/panels/right-panel.ts +35 -24
- package/src/panels/shared.ts +46 -29
- package/src/panels/signals-panel.ts +303 -186
- package/src/panels/statusbar.ts +27 -12
- package/src/panels/style-inputs.ts +30 -24
- package/src/panels/style-panel.ts +130 -90
- package/src/panels/style-utils.ts +63 -23
- package/src/panels/stylebook-layers-panel.ts +27 -30
- package/src/panels/stylebook-panel.ts +140 -72
- package/src/panels/tab-strip.ts +21 -10
- package/src/panels/toolbar.ts +52 -40
- package/src/panels/welcome-screen.ts +1 -1
- package/src/platform.ts +2 -1
- package/src/platforms/devserver.ts +221 -105
- package/src/recent-projects.ts +15 -7
- package/src/resize-edges.ts +7 -5
- package/src/services/cem-export.ts +73 -57
- package/src/services/code-services.ts +52 -25
- package/src/services/monaco-setup.ts +5 -5
- package/src/settings/content-types-editor.ts +133 -62
- package/src/settings/css-vars-editor.ts +31 -14
- package/src/settings/defs-editor.ts +125 -63
- package/src/settings/general-settings.ts +11 -6
- package/src/settings/head-editor.ts +30 -15
- package/src/settings/schema-field-ui.ts +75 -35
- package/src/settings/settings-modal.ts +35 -17
- package/src/site-context.ts +80 -47
- package/src/state.ts +98 -65
- package/src/store.ts +42 -23
- package/src/studio.ts +165 -144
- package/src/tabs/tab.ts +51 -45
- package/src/tabs/transact.ts +230 -109
- package/src/types.ts +60 -51
- package/src/ui/button-group.ts +3 -2
- package/src/ui/color-selector.ts +33 -15
- package/src/ui/expression-editor.ts +139 -86
- package/src/ui/field-input.ts +35 -18
- package/src/ui/field-row.ts +1 -1
- package/src/ui/icons.ts +5 -6
- package/src/ui/layers.ts +33 -26
- package/src/ui/media-picker.ts +13 -7
- package/src/ui/panel-resize.ts +39 -20
- package/src/ui/spectrum.ts +4 -2
- package/src/ui/unit-selector.ts +20 -11
- package/src/ui/value-selector.ts +13 -7
- package/src/ui/widgets.ts +34 -18
- package/src/utils/canvas-media.ts +66 -33
- package/src/utils/edit-display.ts +43 -44
- package/src/utils/google-fonts.ts +10 -6
- package/src/utils/inherited-style.ts +22 -8
- package/src/utils/studio-utils.ts +88 -45
- package/src/view.ts +9 -5
- package/src/workspace/workspace.ts +49 -29
|
@@ -10,16 +10,21 @@ import { html, render as litRender } from "lit-html";
|
|
|
10
10
|
import { repeat } from "lit-html/directives/repeat.js";
|
|
11
11
|
import { getPlatform } from "../platform";
|
|
12
12
|
import { projectState } from "../store";
|
|
13
|
-
import {
|
|
13
|
+
import { addFieldFormTpl, detectFieldFormat, fieldCardTpl, schemaForType } from "./schema-field-ui";
|
|
14
14
|
import { toCamelCase } from "../utils/studio-utils";
|
|
15
15
|
|
|
16
|
-
import type {
|
|
16
|
+
import type { FieldHandlers } from "./schema-field-ui.js";
|
|
17
|
+
import type {
|
|
18
|
+
ContentTypeSchema,
|
|
19
|
+
ContentTypeSchemaField,
|
|
20
|
+
ProjectConfig,
|
|
21
|
+
} from "@jxsuite/schema/types";
|
|
17
22
|
|
|
18
23
|
// ─── Module state ─────────────────────────────────────────────────────────────
|
|
19
24
|
|
|
20
25
|
let selectedContentType: string | null = null;
|
|
21
26
|
let showAddField = false;
|
|
22
|
-
let newFieldState = {
|
|
27
|
+
let newFieldState = { format: "", name: "", required: false, type: "string" };
|
|
23
28
|
let showNewContentType = false;
|
|
24
29
|
let newContentTypeName = "";
|
|
25
30
|
|
|
@@ -47,18 +52,26 @@ function getSelectedSchema(): ContentTypeSchema | undefined {
|
|
|
47
52
|
function handleNewContentType(rerender: () => void) {
|
|
48
53
|
const slug = newContentTypeName
|
|
49
54
|
.toLowerCase()
|
|
50
|
-
.
|
|
51
|
-
.
|
|
52
|
-
if (!slug)
|
|
55
|
+
.replaceAll(/\s+/g, "-")
|
|
56
|
+
.replaceAll(/[^a-z0-9-]/g, "");
|
|
57
|
+
if (!slug) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
53
60
|
|
|
54
61
|
const config = projectState?.projectConfig;
|
|
55
|
-
if (!config)
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
if (!config) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!config.contentTypes) {
|
|
66
|
+
config.contentTypes = {};
|
|
67
|
+
}
|
|
68
|
+
if (config.contentTypes[slug]) {
|
|
69
|
+
return;
|
|
70
|
+
} // Already exists
|
|
58
71
|
|
|
59
72
|
config.contentTypes[slug] = {
|
|
73
|
+
schema: { properties: {}, required: [], type: "object" },
|
|
60
74
|
source: `./content/${slug}/`,
|
|
61
|
-
schema: { type: "object", properties: {}, required: [] },
|
|
62
75
|
};
|
|
63
76
|
|
|
64
77
|
selectedContentType = slug;
|
|
@@ -76,22 +89,32 @@ function handleNewContentType(rerender: () => void) {
|
|
|
76
89
|
/** @param {() => void} rerender */
|
|
77
90
|
function handleAddField(rerender: () => void) {
|
|
78
91
|
const raw = newFieldState.name.trim();
|
|
79
|
-
if (!raw || !selectedContentType)
|
|
92
|
+
if (!raw || !selectedContentType) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
80
95
|
const name = toCamelCase(raw);
|
|
81
96
|
|
|
82
97
|
const schema = getSelectedSchema();
|
|
83
|
-
if (!schema)
|
|
98
|
+
if (!schema) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
84
101
|
|
|
85
|
-
if (!schema.properties)
|
|
102
|
+
if (!schema.properties) {
|
|
103
|
+
schema.properties = {};
|
|
104
|
+
}
|
|
86
105
|
schema.properties[name] = schemaForType(newFieldState.type, newFieldState.format || undefined);
|
|
87
106
|
|
|
88
107
|
if (newFieldState.required) {
|
|
89
|
-
if (!schema.required)
|
|
90
|
-
|
|
108
|
+
if (!schema.required) {
|
|
109
|
+
schema.required = [];
|
|
110
|
+
}
|
|
111
|
+
if (!schema.required.includes(name)) {
|
|
112
|
+
schema.required.push(name);
|
|
113
|
+
}
|
|
91
114
|
}
|
|
92
115
|
|
|
93
116
|
showAddField = false;
|
|
94
|
-
newFieldState = {
|
|
117
|
+
newFieldState = { format: "", name: "", required: false, type: "string" };
|
|
95
118
|
rerender();
|
|
96
119
|
saveProjectConfig();
|
|
97
120
|
}
|
|
@@ -102,7 +125,9 @@ function handleAddField(rerender: () => void) {
|
|
|
102
125
|
*/
|
|
103
126
|
function handleDeleteField(fieldName: string, rerender: () => void) {
|
|
104
127
|
const schema = getSelectedSchema();
|
|
105
|
-
if (!schema?.properties)
|
|
128
|
+
if (!schema?.properties) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
106
131
|
|
|
107
132
|
delete schema.properties[fieldName];
|
|
108
133
|
if (schema.required) {
|
|
@@ -119,12 +144,19 @@ function handleDeleteField(fieldName: string, rerender: () => void) {
|
|
|
119
144
|
*/
|
|
120
145
|
function handleToggleRequired(fieldName: string, rerender: () => void) {
|
|
121
146
|
const schema = getSelectedSchema();
|
|
122
|
-
if (!schema)
|
|
123
|
-
|
|
147
|
+
if (!schema) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (!schema.required) {
|
|
151
|
+
schema.required = [];
|
|
152
|
+
}
|
|
124
153
|
|
|
125
154
|
const idx = schema.required.indexOf(fieldName);
|
|
126
|
-
if (idx
|
|
127
|
-
|
|
155
|
+
if (idx !== -1) {
|
|
156
|
+
schema.required.splice(idx, 1);
|
|
157
|
+
} else {
|
|
158
|
+
schema.required.push(fieldName);
|
|
159
|
+
}
|
|
128
160
|
|
|
129
161
|
rerender();
|
|
130
162
|
saveProjectConfig();
|
|
@@ -138,9 +170,11 @@ function handleToggleRequired(fieldName: string, rerender: () => void) {
|
|
|
138
170
|
function handleRenameField(oldName: string, newName: string, rerender: () => void) {
|
|
139
171
|
const schema = getSelectedSchema();
|
|
140
172
|
const normalized = toCamelCase(newName);
|
|
141
|
-
if (!schema?.properties || !normalized || schema.properties[normalized])
|
|
173
|
+
if (!schema?.properties || !normalized || schema.properties[normalized]) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
142
176
|
|
|
143
|
-
const newProps: Record<string,
|
|
177
|
+
const newProps: Record<string, ContentTypeSchemaField> = {};
|
|
144
178
|
for (const [key, val] of Object.entries(schema.properties)) {
|
|
145
179
|
newProps[key === oldName ? normalized : key] = val;
|
|
146
180
|
}
|
|
@@ -161,7 +195,9 @@ function handleRenameField(oldName: string, newName: string, rerender: () => voi
|
|
|
161
195
|
*/
|
|
162
196
|
function handleChangeType(fieldName: string, newType: string, rerender: () => void) {
|
|
163
197
|
const schema = getSelectedSchema();
|
|
164
|
-
if (!schema?.properties?.[fieldName])
|
|
198
|
+
if (!schema?.properties?.[fieldName]) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
165
201
|
|
|
166
202
|
const oldFormat =
|
|
167
203
|
newType === "string" || newType === "array"
|
|
@@ -179,7 +215,9 @@ function handleChangeType(fieldName: string, newType: string, rerender: () => vo
|
|
|
179
215
|
*/
|
|
180
216
|
function handleChangeFormat(fieldName: string, format: string, rerender: () => void) {
|
|
181
217
|
const schema = getSelectedSchema();
|
|
182
|
-
if (!schema?.properties?.[fieldName])
|
|
218
|
+
if (!schema?.properties?.[fieldName]) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
183
221
|
|
|
184
222
|
const prop = schema.properties[fieldName];
|
|
185
223
|
const type = prop.type || "string";
|
|
@@ -195,7 +233,9 @@ function handleChangeFormat(fieldName: string, format: string, rerender: () => v
|
|
|
195
233
|
*/
|
|
196
234
|
function handleChangeRefTarget(fieldName: string, target: string, rerender: () => void) {
|
|
197
235
|
const schema = getSelectedSchema();
|
|
198
|
-
if (!schema?.properties)
|
|
236
|
+
if (!schema?.properties) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
199
239
|
|
|
200
240
|
schema.properties[fieldName] = { $ref: `#/contentTypes/${target}` };
|
|
201
241
|
rerender();
|
|
@@ -216,17 +256,27 @@ function handleAddNestedField(
|
|
|
216
256
|
) {
|
|
217
257
|
const schema = getSelectedSchema();
|
|
218
258
|
const parent = schema?.properties?.[parentName];
|
|
219
|
-
if (!parent)
|
|
259
|
+
if (!parent) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
220
262
|
|
|
221
263
|
const name = toCamelCase(fieldState.name);
|
|
222
|
-
if (!name)
|
|
264
|
+
if (!name) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
223
267
|
|
|
224
|
-
if (!parent.properties)
|
|
268
|
+
if (!parent.properties) {
|
|
269
|
+
parent.properties = {};
|
|
270
|
+
}
|
|
225
271
|
parent.properties[name] = schemaForType(fieldState.type);
|
|
226
272
|
|
|
227
273
|
if (fieldState.required) {
|
|
228
|
-
if (!parent.required)
|
|
229
|
-
|
|
274
|
+
if (!parent.required) {
|
|
275
|
+
parent.required = [];
|
|
276
|
+
}
|
|
277
|
+
if (!parent.required.includes(name)) {
|
|
278
|
+
parent.required.push(name);
|
|
279
|
+
}
|
|
230
280
|
}
|
|
231
281
|
|
|
232
282
|
rerender();
|
|
@@ -241,7 +291,9 @@ function handleAddNestedField(
|
|
|
241
291
|
function handleDeleteNested(parentName: string, childName: string, rerender: () => void) {
|
|
242
292
|
const schema = getSelectedSchema();
|
|
243
293
|
const parent = schema?.properties?.[parentName];
|
|
244
|
-
if (!parent?.properties)
|
|
294
|
+
if (!parent?.properties) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
245
297
|
|
|
246
298
|
delete parent.properties[childName];
|
|
247
299
|
if (parent.required) {
|
|
@@ -260,12 +312,19 @@ function handleDeleteNested(parentName: string, childName: string, rerender: ()
|
|
|
260
312
|
function handleToggleNestedRequired(parentName: string, childName: string, rerender: () => void) {
|
|
261
313
|
const schema = getSelectedSchema();
|
|
262
314
|
const parent = schema?.properties?.[parentName];
|
|
263
|
-
if (!parent)
|
|
264
|
-
|
|
315
|
+
if (!parent) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
if (!parent.required) {
|
|
319
|
+
parent.required = [];
|
|
320
|
+
}
|
|
265
321
|
|
|
266
322
|
const idx = parent.required.indexOf(childName);
|
|
267
|
-
if (idx
|
|
268
|
-
|
|
323
|
+
if (idx !== -1) {
|
|
324
|
+
parent.required.splice(idx, 1);
|
|
325
|
+
} else {
|
|
326
|
+
parent.required.push(childName);
|
|
327
|
+
}
|
|
269
328
|
|
|
270
329
|
rerender();
|
|
271
330
|
saveProjectConfig();
|
|
@@ -286,9 +345,11 @@ function handleRenameNested(
|
|
|
286
345
|
const schema = getSelectedSchema();
|
|
287
346
|
const parent = schema?.properties?.[parentName];
|
|
288
347
|
const normalized = toCamelCase(newChild);
|
|
289
|
-
if (!parent?.properties || !normalized || parent.properties[normalized])
|
|
348
|
+
if (!parent?.properties || !normalized || parent.properties[normalized]) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
290
351
|
|
|
291
|
-
const newProps: Record<string,
|
|
352
|
+
const newProps: Record<string, ContentTypeSchemaField> = {};
|
|
292
353
|
for (const [key, val] of Object.entries(parent.properties)) {
|
|
293
354
|
newProps[key === oldChild ? normalized : key] = val;
|
|
294
355
|
}
|
|
@@ -316,7 +377,9 @@ function handleChangeNestedType(
|
|
|
316
377
|
) {
|
|
317
378
|
const schema = getSelectedSchema();
|
|
318
379
|
const parent = schema?.properties?.[parentName];
|
|
319
|
-
if (!parent?.properties?.[childName])
|
|
380
|
+
if (!parent?.properties?.[childName]) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
320
383
|
|
|
321
384
|
const oldFormat =
|
|
322
385
|
newType === "string" || newType === "array"
|
|
@@ -341,7 +404,9 @@ function handleChangeNestedFormat(
|
|
|
341
404
|
) {
|
|
342
405
|
const schema = getSelectedSchema();
|
|
343
406
|
const parent = schema?.properties?.[parentName];
|
|
344
|
-
if (!parent?.properties?.[childName])
|
|
407
|
+
if (!parent?.properties?.[childName]) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
345
410
|
|
|
346
411
|
const prop = parent.properties[childName];
|
|
347
412
|
const type = prop.type || "string";
|
|
@@ -352,9 +417,13 @@ function handleChangeNestedFormat(
|
|
|
352
417
|
|
|
353
418
|
/** @param {() => void} rerender */
|
|
354
419
|
function handleDeleteContentType(rerender: () => void) {
|
|
355
|
-
if (!selectedContentType)
|
|
420
|
+
if (!selectedContentType) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
356
423
|
const config = projectState?.projectConfig;
|
|
357
|
-
if (!config?.contentTypes?.[selectedContentType])
|
|
424
|
+
if (!config?.contentTypes?.[selectedContentType]) {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
358
427
|
|
|
359
428
|
delete config.contentTypes[selectedContentType];
|
|
360
429
|
selectedContentType = null;
|
|
@@ -405,7 +474,9 @@ export function renderContentTypesEditor(container: HTMLElement) {
|
|
|
405
474
|
newContentTypeName = (e.target as HTMLInputElement).value;
|
|
406
475
|
}}
|
|
407
476
|
@keydown=${(e: KeyboardEvent) => {
|
|
408
|
-
if (e.key === "Enter")
|
|
477
|
+
if (e.key === "Enter") {
|
|
478
|
+
handleNewContentType(rerender);
|
|
479
|
+
}
|
|
409
480
|
if (e.key === "Escape") {
|
|
410
481
|
showNewContentType = false;
|
|
411
482
|
rerender();
|
|
@@ -442,22 +513,22 @@ export function renderContentTypesEditor(container: HTMLElement) {
|
|
|
442
513
|
const properties = schema.properties || {};
|
|
443
514
|
const required = schema.required || [];
|
|
444
515
|
|
|
445
|
-
const handlers:
|
|
446
|
-
onDelete: (n: string) => handleDeleteField(n, rerender),
|
|
447
|
-
onToggleRequired: (n: string) => handleToggleRequired(n, rerender),
|
|
448
|
-
onRename: (oldN: string, newN: string) => handleRenameField(oldN, newN, rerender),
|
|
449
|
-
onChangeType: (n: string, t: string) => handleChangeType(n, t, rerender),
|
|
450
|
-
onChangeFormat: (n: string, f: string) => handleChangeFormat(n, f, rerender),
|
|
451
|
-
onChangeRefTarget: (n: string, target: string) => handleChangeRefTarget(n, target, rerender),
|
|
516
|
+
const handlers: FieldHandlers = {
|
|
452
517
|
onAddNestedField: (p: string, s: { name: string; type: string; required: boolean }) =>
|
|
453
518
|
handleAddNestedField(p, s, rerender),
|
|
454
|
-
|
|
455
|
-
onToggleNestedRequired: (p: string, c: string) => handleToggleNestedRequired(p, c, rerender),
|
|
456
|
-
onRenameNested: (p: string, o: string, n: string) => handleRenameNested(p, o, n, rerender),
|
|
457
|
-
onChangeNestedType: (p: string, c: string, t: string) =>
|
|
458
|
-
handleChangeNestedType(p, c, t, rerender),
|
|
519
|
+
onChangeFormat: (n: string, f: string) => handleChangeFormat(n, f, rerender),
|
|
459
520
|
onChangeNestedFormat: (p: string, c: string, f: string) =>
|
|
460
521
|
handleChangeNestedFormat(p, c, f, rerender),
|
|
522
|
+
onChangeNestedType: (p: string, c: string, t: string) =>
|
|
523
|
+
handleChangeNestedType(p, c, t, rerender),
|
|
524
|
+
onChangeRefTarget: (n: string, target: string) => handleChangeRefTarget(n, target, rerender),
|
|
525
|
+
onChangeType: (n: string, t: string) => handleChangeType(n, t, rerender),
|
|
526
|
+
onDelete: (n: string) => handleDeleteField(n, rerender),
|
|
527
|
+
onDeleteNested: (p: string, c: string) => handleDeleteNested(p, c, rerender),
|
|
528
|
+
onRename: (oldN: string, newN: string) => handleRenameField(oldN, newN, rerender),
|
|
529
|
+
onRenameNested: (p: string, o: string, n: string) => handleRenameNested(p, o, n, rerender),
|
|
530
|
+
onToggleNestedRequired: (p: string, c: string) => handleToggleNestedRequired(p, c, rerender),
|
|
531
|
+
onToggleRequired: (n: string) => handleToggleRequired(n, rerender),
|
|
461
532
|
};
|
|
462
533
|
|
|
463
534
|
const fieldCards = repeat(
|
|
@@ -490,21 +561,21 @@ export function renderContentTypesEditor(container: HTMLElement) {
|
|
|
490
561
|
<div class="schema-field-list">${fieldCards}</div>
|
|
491
562
|
${showAddField
|
|
492
563
|
? addFieldFormTpl(newFieldState, {
|
|
493
|
-
onInput: (field, value) => {
|
|
494
|
-
newFieldState = { ...newFieldState, [field]: value };
|
|
495
|
-
rerender();
|
|
496
|
-
},
|
|
497
|
-
onConfirm: () => handleAddField(rerender),
|
|
498
564
|
onCancel: () => {
|
|
499
565
|
showAddField = false;
|
|
500
566
|
newFieldState = {
|
|
501
|
-
name: "",
|
|
502
|
-
type: "string",
|
|
503
567
|
format: "",
|
|
568
|
+
name: "",
|
|
504
569
|
required: false,
|
|
570
|
+
type: "string",
|
|
505
571
|
};
|
|
506
572
|
rerender();
|
|
507
573
|
},
|
|
574
|
+
onConfirm: () => handleAddField(rerender),
|
|
575
|
+
onInput: (field, value) => {
|
|
576
|
+
newFieldState = { ...newFieldState, [field]: value };
|
|
577
|
+
rerender();
|
|
578
|
+
},
|
|
508
579
|
})
|
|
509
580
|
: html`
|
|
510
581
|
<sp-action-button
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
import { html, render as litRender, nothing } from "lit-html";
|
|
8
8
|
import { ref } from "lit-html/directives/ref.js";
|
|
9
9
|
import { projectState } from "../store";
|
|
10
|
-
import { updateSiteConfig } from "../site-context";
|
|
11
|
-
import { getEffectiveMedia } from "../site-context";
|
|
10
|
+
import { getEffectiveMedia, updateSiteConfig } from "../site-context";
|
|
12
11
|
import { friendlyNameToVar, varDisplayName } from "../utils/studio-utils";
|
|
13
12
|
|
|
14
13
|
import type { JxStyle } from "@jxsuite/schema/types";
|
|
@@ -32,15 +31,23 @@ export function renderCssVarsEditor(container: HTMLElement) {
|
|
|
32
31
|
font: [string, string | number][];
|
|
33
32
|
size: [string, string | number][];
|
|
34
33
|
other: [string, string | number][];
|
|
35
|
-
} = { color: [], font: [],
|
|
34
|
+
} = { color: [], font: [], other: [], size: [] };
|
|
36
35
|
for (const [k, v] of Object.entries(rootStyle)) {
|
|
37
|
-
if (!k.startsWith("--"))
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
if (!k.startsWith("--")) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (typeof v !== "string" && typeof v !== "number") {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (k.startsWith("--color")) {
|
|
43
|
+
groups.color.push([k, v]);
|
|
44
|
+
} else if (k.startsWith("--font")) {
|
|
45
|
+
groups.font.push([k, v]);
|
|
46
|
+
} else if (k.startsWith("--size") || k.startsWith("--spacing") || k.startsWith("--radius")) {
|
|
42
47
|
groups.size.push([k, v]);
|
|
43
|
-
else
|
|
48
|
+
} else {
|
|
49
|
+
groups.other.push([k, v]);
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
const mediaNames = media ? Object.keys(media).filter((m) => m !== "--") : [];
|
|
@@ -62,7 +69,9 @@ export function renderCssVarsEditor(container: HTMLElement) {
|
|
|
62
69
|
|
|
63
70
|
const addVar = (prefix: string, friendlyName: string, val: string) => {
|
|
64
71
|
const varName = friendlyNameToVar(friendlyName, prefix);
|
|
65
|
-
if (!varName || !val)
|
|
72
|
+
if (!varName || !val) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
66
75
|
rootStyle[varName] = val;
|
|
67
76
|
save();
|
|
68
77
|
renderCssVarsEditor(container);
|
|
@@ -268,7 +277,9 @@ function renderMediaOverrides(varName: string, rootStyle: JxStyle, mediaNames: s
|
|
|
268
277
|
}
|
|
269
278
|
}
|
|
270
279
|
|
|
271
|
-
if (overrides.length === 0)
|
|
280
|
+
if (overrides.length === 0) {
|
|
281
|
+
return nothing;
|
|
282
|
+
}
|
|
272
283
|
|
|
273
284
|
return html`
|
|
274
285
|
<div class="css-var-media-overrides">
|
|
@@ -280,7 +291,9 @@ function renderMediaOverrides(varName: string, rootStyle: JxStyle, mediaNames: s
|
|
|
280
291
|
size="s"
|
|
281
292
|
.value=${String(o.value)}
|
|
282
293
|
@change=${(e: Event) => {
|
|
283
|
-
if (!rootStyle[`@${o.mediaName}`])
|
|
294
|
+
if (!rootStyle[`@${o.mediaName}`]) {
|
|
295
|
+
rootStyle[`@${o.mediaName}`] = {};
|
|
296
|
+
}
|
|
284
297
|
(rootStyle[`@${o.mediaName}`] as Record<string, unknown>)[varName] = (
|
|
285
298
|
e.target as HTMLInputElement
|
|
286
299
|
).value;
|
|
@@ -316,14 +329,18 @@ function renderAddRow(
|
|
|
316
329
|
size="s"
|
|
317
330
|
placeholder=${placeholder}
|
|
318
331
|
${ref((el) => {
|
|
319
|
-
if (el)
|
|
332
|
+
if (el) {
|
|
333
|
+
nameEl = el as HTMLInputElement;
|
|
334
|
+
}
|
|
320
335
|
})}
|
|
321
336
|
></sp-textfield>
|
|
322
337
|
<sp-textfield
|
|
323
338
|
size="s"
|
|
324
339
|
placeholder=${valuePlaceholder}
|
|
325
340
|
${ref((el) => {
|
|
326
|
-
if (el)
|
|
341
|
+
if (el) {
|
|
342
|
+
valEl = el as HTMLInputElement;
|
|
343
|
+
}
|
|
327
344
|
})}
|
|
328
345
|
></sp-textfield>
|
|
329
346
|
<sp-action-button
|