@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
package/src/panels/canvas-dnd.ts
CHANGED
|
@@ -10,17 +10,18 @@ import {
|
|
|
10
10
|
monitorForElements,
|
|
11
11
|
} from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { VOID_ELEMENTS, canvasPanels, elToPath, getNodeAtPath, isAncestor } from "../store";
|
|
14
14
|
import { activeTab } from "../workspace/workspace";
|
|
15
15
|
import { view } from "../view";
|
|
16
16
|
import { applyDropInstruction } from "../panels/dnd";
|
|
17
17
|
import { effectiveZoom } from "../canvas/canvas-helpers";
|
|
18
18
|
|
|
19
19
|
import type { CanvasPanel } from "../types";
|
|
20
|
-
export type { CanvasPanel };
|
|
21
20
|
|
|
22
21
|
import type { JxPath } from "../state";
|
|
23
22
|
|
|
23
|
+
export type { CanvasPanel };
|
|
24
|
+
|
|
24
25
|
interface DropInstruction {
|
|
25
26
|
type: "reorder-above" | "reorder-below" | "make-child";
|
|
26
27
|
}
|
|
@@ -43,8 +44,8 @@ export function registerPanelDnD(panel: CanvasPanel) {
|
|
|
43
44
|
const allEls = canvas.querySelectorAll("*");
|
|
44
45
|
|
|
45
46
|
// Drop-target callbacks fire on EVERY target in the stack (innermost → outermost),
|
|
46
|
-
//
|
|
47
|
-
//
|
|
47
|
+
// And every canvas element is a drop target — so the indicator and the drop are
|
|
48
|
+
// Driven from the monitor using only the innermost target.
|
|
48
49
|
/** Innermost drop target if it belongs to this panel's canvas, else null */
|
|
49
50
|
const innermostCanvasTarget = (location: {
|
|
50
51
|
current: {
|
|
@@ -54,22 +55,19 @@ export function registerPanelDnD(panel: CanvasPanel) {
|
|
|
54
55
|
}[];
|
|
55
56
|
};
|
|
56
57
|
}) => {
|
|
57
|
-
const target = location.current.dropTargets
|
|
58
|
-
if (!target)
|
|
58
|
+
const [target] = location.current.dropTargets;
|
|
59
|
+
if (!target) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
59
62
|
const tEl = target.element as HTMLElement;
|
|
60
63
|
const tPath = target.data.path;
|
|
61
|
-
if (!canvas.contains(tEl) || !Array.isArray(tPath))
|
|
62
|
-
|
|
64
|
+
if (!canvas.contains(tEl) || !Array.isArray(tPath)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
return { el: tEl, isLeaf: Boolean(target.data._isVoid), path: tPath as JxPath };
|
|
63
68
|
};
|
|
64
69
|
|
|
65
70
|
const monitorCleanup = monitorForElements({
|
|
66
|
-
onDragStart({ location }) {
|
|
67
|
-
view.lastDragInput = location.current.input;
|
|
68
|
-
for (const el of canvas.querySelectorAll("*")) {
|
|
69
|
-
(el as HTMLElement).style.pointerEvents = "auto";
|
|
70
|
-
}
|
|
71
|
-
for (const p of canvasPanels) p.overlayClk.style.pointerEvents = "none";
|
|
72
|
-
},
|
|
73
71
|
onDrag({ location }) {
|
|
74
72
|
view.lastDragInput = location.current.input;
|
|
75
73
|
const target = innermostCanvasTarget(location);
|
|
@@ -81,8 +79,8 @@ export function registerPanelDnD(panel: CanvasPanel) {
|
|
|
81
79
|
showCanvasDropIndicator(target.el, target.path, target.isLeaf, panel);
|
|
82
80
|
} else if (location.current.dropTargets.length > 0) {
|
|
83
81
|
// Pointer is over a non-canvas target (e.g. a layer row) — hide this panel's
|
|
84
|
-
//
|
|
85
|
-
//
|
|
82
|
+
// Indicator. When over dead space (no targets at all) keep the last indicator
|
|
83
|
+
// Visible so it persists for the whole drag.
|
|
86
84
|
if (_activeDropEl && canvas.contains(_activeDropEl)) {
|
|
87
85
|
_activeDropEl.classList.remove("canvas-drop-target");
|
|
88
86
|
_activeDropEl = null;
|
|
@@ -90,6 +88,15 @@ export function registerPanelDnD(panel: CanvasPanel) {
|
|
|
90
88
|
dropLine.style.display = "none";
|
|
91
89
|
}
|
|
92
90
|
},
|
|
91
|
+
onDragStart({ location }) {
|
|
92
|
+
view.lastDragInput = location.current.input;
|
|
93
|
+
for (const el of canvas.querySelectorAll("*")) {
|
|
94
|
+
(el as HTMLElement).style.pointerEvents = "auto";
|
|
95
|
+
}
|
|
96
|
+
for (const p of canvasPanels) {
|
|
97
|
+
p.overlayClk.style.pointerEvents = "none";
|
|
98
|
+
}
|
|
99
|
+
},
|
|
93
100
|
onDrop({ source, location }) {
|
|
94
101
|
const target = innermostCanvasTarget(location);
|
|
95
102
|
if (target) {
|
|
@@ -103,13 +110,17 @@ export function registerPanelDnD(panel: CanvasPanel) {
|
|
|
103
110
|
_activeDropEl?.classList.remove("canvas-drop-target");
|
|
104
111
|
_activeDropEl = null;
|
|
105
112
|
for (const p of canvasPanels) {
|
|
106
|
-
if (p.dropLine)
|
|
113
|
+
if (p.dropLine) {
|
|
114
|
+
p.dropLine.style.display = "none";
|
|
115
|
+
}
|
|
107
116
|
}
|
|
108
117
|
view.lastDragInput = null;
|
|
109
118
|
for (const el of canvas.querySelectorAll("*")) {
|
|
110
119
|
(el as HTMLElement).style.pointerEvents = "none";
|
|
111
120
|
}
|
|
112
|
-
for (const p of canvasPanels)
|
|
121
|
+
for (const p of canvasPanels) {
|
|
122
|
+
p.overlayClk.style.pointerEvents = "";
|
|
123
|
+
}
|
|
113
124
|
},
|
|
114
125
|
});
|
|
115
126
|
view.canvasDndCleanups.push(monitorCleanup);
|
|
@@ -117,7 +128,9 @@ export function registerPanelDnD(panel: CanvasPanel) {
|
|
|
117
128
|
const document = activeTab.value?.doc.document;
|
|
118
129
|
for (const el of allEls) {
|
|
119
130
|
const elPath = elToPath.get(el);
|
|
120
|
-
if (!elPath)
|
|
131
|
+
if (!elPath) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
121
134
|
|
|
122
135
|
const node = getNodeAtPath(document!, elPath);
|
|
123
136
|
const tag = (node?.tagName || "div").toLowerCase();
|
|
@@ -127,14 +140,16 @@ export function registerPanelDnD(panel: CanvasPanel) {
|
|
|
127
140
|
const isLeaf = VOID_ELEMENTS.has(tag) || !hasElementChildren;
|
|
128
141
|
|
|
129
142
|
const cleanup = dropTargetForElements({
|
|
130
|
-
element: /** @type {HTMLElement} */ el,
|
|
131
143
|
canDrop({ source }) {
|
|
132
144
|
const srcPath = source.data.path as JxPath | undefined;
|
|
133
|
-
if (srcPath && isAncestor(srcPath, elPath))
|
|
145
|
+
if (srcPath && isAncestor(srcPath, elPath)) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
134
148
|
return true;
|
|
135
149
|
},
|
|
150
|
+
element: /** @type {HTMLElement} */ el,
|
|
136
151
|
getData() {
|
|
137
|
-
return {
|
|
152
|
+
return { _isVoid: isLeaf, path: elPath };
|
|
138
153
|
},
|
|
139
154
|
});
|
|
140
155
|
view.canvasDndCleanups.push(cleanup);
|
|
@@ -148,22 +163,24 @@ export function registerPanelDnD(panel: CanvasPanel) {
|
|
|
148
163
|
* @returns {DropResult}
|
|
149
164
|
*/
|
|
150
165
|
function getCanvasDropResult(el: HTMLElement, elPath: JxPath, isLeaf: boolean): DropResult {
|
|
151
|
-
if (!view.lastDragInput)
|
|
166
|
+
if (!view.lastDragInput) {
|
|
152
167
|
return {
|
|
153
168
|
instruction: { type: "make-child" },
|
|
154
169
|
referenceEl: el,
|
|
155
170
|
targetPath: elPath,
|
|
156
171
|
};
|
|
172
|
+
}
|
|
157
173
|
const y = view.lastDragInput.clientY;
|
|
158
174
|
|
|
159
175
|
if (elPath.length === 0) {
|
|
160
|
-
const children =
|
|
161
|
-
if (children.length === 0)
|
|
176
|
+
const children = [...el.children] as HTMLElement[];
|
|
177
|
+
if (children.length === 0) {
|
|
162
178
|
return {
|
|
163
179
|
instruction: { type: "make-child" },
|
|
164
180
|
referenceEl: el,
|
|
165
181
|
targetPath: elPath,
|
|
166
182
|
};
|
|
183
|
+
}
|
|
167
184
|
return nearestChildEdge(children, y, elPath);
|
|
168
185
|
}
|
|
169
186
|
|
|
@@ -176,18 +193,20 @@ function getCanvasDropResult(el: HTMLElement, elPath: JxPath, isLeaf: boolean):
|
|
|
176
193
|
return { instruction, referenceEl: el, targetPath: elPath };
|
|
177
194
|
}
|
|
178
195
|
|
|
179
|
-
if (relY < 0.25)
|
|
196
|
+
if (relY < 0.25) {
|
|
180
197
|
return {
|
|
181
198
|
instruction: { type: "reorder-above" },
|
|
182
199
|
referenceEl: el,
|
|
183
200
|
targetPath: elPath,
|
|
184
201
|
};
|
|
185
|
-
|
|
202
|
+
}
|
|
203
|
+
if (relY > 0.75) {
|
|
186
204
|
return {
|
|
187
205
|
instruction: { type: "reorder-below" },
|
|
188
206
|
referenceEl: el,
|
|
189
207
|
targetPath: elPath,
|
|
190
208
|
};
|
|
209
|
+
}
|
|
191
210
|
return {
|
|
192
211
|
instruction: { type: "make-child" },
|
|
193
212
|
referenceEl: el,
|
|
@@ -3,24 +3,34 @@
|
|
|
3
3
|
|
|
4
4
|
import { html, nothing } from "lit-html";
|
|
5
5
|
import { classMap } from "lit-html/directives/class-map.js";
|
|
6
|
+
import type { TemplateResult } from "lit-html";
|
|
6
7
|
|
|
7
8
|
/** Expanded data entries set — persists across renders. */
|
|
8
9
|
const expandedDataKeys = new Set();
|
|
9
10
|
|
|
10
11
|
/** Unwrap a Vue ref (has .value and .__v_isRef) to get the underlying value. */
|
|
11
12
|
function unwrapSignal(value: unknown) {
|
|
12
|
-
if (value && typeof value === "object" && (value as Record<string, unknown>).__v_isRef)
|
|
13
|
+
if (value && typeof value === "object" && (value as Record<string, unknown>).__v_isRef) {
|
|
13
14
|
return (value as Record<string, unknown>).value;
|
|
15
|
+
}
|
|
14
16
|
return value;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
/** Type label for a signal value in the data explorer. */
|
|
18
20
|
function dataTypeLabel(value: unknown) {
|
|
19
21
|
const v = unwrapSignal(value);
|
|
20
|
-
if (v === null)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (
|
|
22
|
+
if (v === null) {
|
|
23
|
+
return "null";
|
|
24
|
+
}
|
|
25
|
+
if (v === undefined) {
|
|
26
|
+
return "pending";
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(v)) {
|
|
29
|
+
return `Array(${v.length})`;
|
|
30
|
+
}
|
|
31
|
+
if (typeof v === "object") {
|
|
32
|
+
return `{${Object.keys(v).length}}`;
|
|
33
|
+
}
|
|
24
34
|
return typeof v;
|
|
25
35
|
}
|
|
26
36
|
|
|
@@ -82,8 +92,11 @@ export function renderDataExplorerTemplate(
|
|
|
82
92
|
expanded: isExpanded,
|
|
83
93
|
})}
|
|
84
94
|
@click=${() => {
|
|
85
|
-
if (expandedDataKeys.has(name))
|
|
86
|
-
|
|
95
|
+
if (expandedDataKeys.has(name)) {
|
|
96
|
+
expandedDataKeys.delete(name);
|
|
97
|
+
} else {
|
|
98
|
+
expandedDataKeys.add(name);
|
|
99
|
+
}
|
|
87
100
|
renderLeftPanel();
|
|
88
101
|
}}
|
|
89
102
|
>
|
|
@@ -91,8 +104,8 @@ export function renderDataExplorerTemplate(
|
|
|
91
104
|
<span class="data-name">${name}</span>
|
|
92
105
|
<span
|
|
93
106
|
class=${classMap({
|
|
94
|
-
"data-type": true,
|
|
95
107
|
"data-pending": unwrapped === null,
|
|
108
|
+
"data-type": true,
|
|
96
109
|
})}
|
|
97
110
|
>${dataTypeLabel(value)}</span
|
|
98
111
|
>
|
|
@@ -115,7 +128,7 @@ export function renderDataTreeTemplate(
|
|
|
115
128
|
value: unknown,
|
|
116
129
|
depth: number,
|
|
117
130
|
maxDepth = 5,
|
|
118
|
-
):
|
|
131
|
+
): TemplateResult {
|
|
119
132
|
const indent = `${(depth + 1) * 12}px`;
|
|
120
133
|
|
|
121
134
|
if (depth > maxDepth) {
|
|
@@ -140,7 +153,7 @@ export function renderDataTreeTemplate(
|
|
|
140
153
|
|
|
141
154
|
if (Array.isArray(value)) {
|
|
142
155
|
const cap = 20;
|
|
143
|
-
const items:
|
|
156
|
+
const items: TemplateResult[] = value.slice(0, cap).map((item, i) => {
|
|
144
157
|
if (item === null || item === undefined || typeof item !== "object") {
|
|
145
158
|
const valText =
|
|
146
159
|
typeof item === "string" && item.length > 80
|
|
@@ -171,7 +184,7 @@ export function renderDataTreeTemplate(
|
|
|
171
184
|
const obj = value as Record<string, unknown>;
|
|
172
185
|
const keys = Object.keys(obj);
|
|
173
186
|
const cap = 30;
|
|
174
|
-
const items:
|
|
187
|
+
const items: TemplateResult[] = keys.slice(0, cap).map((key) => {
|
|
175
188
|
const v = obj[key];
|
|
176
189
|
if (v === null || v === undefined || typeof v !== "object") {
|
|
177
190
|
const valText =
|