@jxsuite/studio 0.10.2 → 0.13.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/README.md +82 -0
- package/dist/studio.js +5114 -3424
- package/dist/studio.js.map +65 -49
- package/package.json +6 -3
- package/src/browse/browse.js +27 -3
- package/src/canvas/canvas-diff.js +184 -0
- package/src/canvas/canvas-helpers.js +10 -14
- package/src/canvas/canvas-live-render.js +136 -17
- package/src/canvas/canvas-render.js +154 -21
- package/src/canvas/canvas-utils.js +21 -23
- package/src/editor/component-inline-edit.js +54 -41
- package/src/editor/content-inline-edit.js +46 -47
- package/src/editor/context-menu.js +63 -39
- package/src/editor/convert-to-component.js +11 -14
- package/src/editor/insertion-helper.js +8 -10
- package/src/editor/shortcuts.js +69 -39
- package/src/files/components.js +15 -4
- package/src/files/files.js +72 -24
- package/src/panels/activity-bar.js +29 -7
- package/src/panels/block-action-bar.js +104 -80
- package/src/panels/canvas-dnd.js +132 -50
- package/src/panels/dnd.js +32 -28
- package/src/panels/editors.js +7 -14
- package/src/panels/elements-panel.js +9 -3
- package/src/panels/events-panel.js +44 -39
- package/src/panels/git-panel.js +45 -3
- package/src/panels/layers-panel.js +16 -11
- package/src/panels/left-panel.js +108 -43
- package/src/panels/overlays.js +97 -35
- package/src/panels/panel-events.js +18 -11
- package/src/panels/properties-panel.js +467 -98
- package/src/panels/right-panel.js +85 -37
- package/src/panels/shared.js +0 -22
- package/src/panels/signals-panel.js +125 -54
- package/src/panels/statusbar.js +23 -8
- package/src/panels/style-inputs.js +4 -2
- package/src/panels/style-panel.js +128 -105
- package/src/panels/stylebook-panel.js +42 -17
- package/src/panels/tab-strip.js +124 -0
- package/src/panels/toolbar.js +39 -9
- package/src/reactivity.js +28 -0
- package/src/settings/content-types-editor.js +78 -8
- package/src/settings/defs-editor.js +56 -7
- package/src/settings/schema-field-ui.js +99 -11
- package/src/site-context.js +105 -0
- package/src/state.js +0 -456
- package/src/store.js +105 -124
- package/src/studio.js +112 -121
- package/src/tabs/tab.js +153 -0
- package/src/tabs/transact.js +406 -0
- package/src/ui/spectrum.js +2 -0
- package/src/view.js +3 -0
- package/src/workspace/workspace.js +89 -0
|
@@ -5,61 +5,100 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { html, render as litRender, nothing } from "lit-html";
|
|
8
|
-
import {
|
|
8
|
+
import { updateUi, rightPanel } from "../store.js";
|
|
9
|
+
import { effect, effectScope } from "../reactivity.js";
|
|
10
|
+
import { activeTab } from "../workspace/workspace.js";
|
|
9
11
|
import { tabIcon } from "./activity-bar.js";
|
|
10
12
|
import { eventsSidebarTemplate } from "./events-panel.js";
|
|
11
13
|
import { isCustomElementDoc } from "./signals-panel.js";
|
|
12
|
-
|
|
14
|
+
|
|
13
15
|
import { isColorPopoverOpen } from "../ui/color-selector.js";
|
|
14
16
|
import { renderStylePanelTemplate } from "./style-panel.js";
|
|
15
17
|
import { renderPropertiesPanelTemplate } from "./properties-panel.js";
|
|
16
18
|
|
|
17
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {{
|
|
21
|
+
* navigateToComponent: (path: string) => void;
|
|
22
|
+
* getCanvasMode: () => string;
|
|
23
|
+
* renderCanvas: () => void;
|
|
24
|
+
* updateForcedPseudoPreview: () => void;
|
|
25
|
+
* }} RightPanelCtx
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/** @type {RightPanelCtx | null} */
|
|
18
29
|
let _ctx = null;
|
|
19
30
|
|
|
20
|
-
/** @type {(
|
|
21
|
-
let
|
|
31
|
+
/** @type {import("@vue/reactivity").EffectScope | null} */
|
|
32
|
+
let _scope = null;
|
|
33
|
+
|
|
34
|
+
let _rendering = false;
|
|
35
|
+
let _scheduled = false;
|
|
22
36
|
|
|
23
37
|
/**
|
|
24
38
|
* Mount the right panel.
|
|
25
39
|
*
|
|
26
|
-
* @param {
|
|
27
|
-
* updateForcedPseudoPreview }
|
|
40
|
+
* @param {RightPanelCtx} ctx
|
|
28
41
|
*/
|
|
29
42
|
export function mount(ctx) {
|
|
30
43
|
_ctx = ctx;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
_scope = effectScope();
|
|
45
|
+
_scope.run(() => {
|
|
46
|
+
effect(() => {
|
|
47
|
+
const tab = activeTab.value;
|
|
48
|
+
if (!tab) return;
|
|
49
|
+
// Track properties the right panel reads
|
|
50
|
+
void tab.doc.document;
|
|
51
|
+
void tab.session.selection;
|
|
52
|
+
void tab.session.ui.rightTab;
|
|
53
|
+
void tab.session.ui.activeMedia;
|
|
54
|
+
void tab.session.ui.activeSelector;
|
|
55
|
+
void tab.session.ui.styleSections;
|
|
56
|
+
void tab.session.ui.styleShorthands;
|
|
57
|
+
void tab.session.ui.styleFilter;
|
|
58
|
+
void tab.session.ui.styleFilterActive;
|
|
59
|
+
void tab.session.ui.inspectorSections;
|
|
60
|
+
|
|
61
|
+
const colorPopoverOpen = isColorPopoverOpen();
|
|
62
|
+
const activeTag = document.activeElement?.tagName;
|
|
63
|
+
const rightHasFocus =
|
|
64
|
+
!colorPopoverOpen &&
|
|
65
|
+
rightPanel.contains(document.activeElement) &&
|
|
66
|
+
(activeTag === "INPUT" ||
|
|
67
|
+
activeTag === "TEXTAREA" ||
|
|
68
|
+
activeTag === "SP-TEXTFIELD" ||
|
|
69
|
+
activeTag === "SP-NUMBER-FIELD" ||
|
|
70
|
+
activeTag === "SP-PICKER" ||
|
|
71
|
+
activeTag === "SP-COMBOBOX" ||
|
|
72
|
+
activeTag === "SP-SEARCH");
|
|
73
|
+
|
|
74
|
+
if (!rightHasFocus) {
|
|
75
|
+
render();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
50
78
|
});
|
|
51
79
|
}
|
|
52
80
|
|
|
53
81
|
export function unmount() {
|
|
54
|
-
|
|
55
|
-
|
|
82
|
+
_scope?.stop();
|
|
83
|
+
_scope = null;
|
|
56
84
|
_ctx = null;
|
|
57
85
|
}
|
|
58
86
|
|
|
59
87
|
export function render() {
|
|
60
88
|
if (!_ctx) return;
|
|
89
|
+
if (_rendering) return;
|
|
90
|
+
if (!_scheduled) {
|
|
91
|
+
_scheduled = true;
|
|
92
|
+
queueMicrotask(_flush);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function _flush() {
|
|
97
|
+
_scheduled = false;
|
|
98
|
+
if (!_ctx) return;
|
|
99
|
+
if (_rendering) return;
|
|
100
|
+
_rendering = true;
|
|
61
101
|
try {
|
|
62
|
-
ensureLitState(rightPanel);
|
|
63
102
|
litRender(rightPanelTemplate(), rightPanel);
|
|
64
103
|
} catch (e) {
|
|
65
104
|
console.error("right-panel render error:", e);
|
|
@@ -71,12 +110,22 @@ export function render() {
|
|
|
71
110
|
} catch (e2) {
|
|
72
111
|
console.error("right-panel retry failed:", e2);
|
|
73
112
|
}
|
|
113
|
+
} finally {
|
|
114
|
+
_rendering = false;
|
|
74
115
|
}
|
|
75
116
|
_ctx.updateForcedPseudoPreview();
|
|
76
117
|
}
|
|
77
118
|
|
|
78
119
|
function rightPanelTemplate() {
|
|
79
|
-
const
|
|
120
|
+
const ctx = /** @type {RightPanelCtx} */ (_ctx);
|
|
121
|
+
const aTab = activeTab.value;
|
|
122
|
+
if (!aTab) return nothing;
|
|
123
|
+
const S = /** @type {any} */ ({
|
|
124
|
+
ui: aTab.session.ui,
|
|
125
|
+
document: aTab.doc.document,
|
|
126
|
+
mode: aTab.doc.mode,
|
|
127
|
+
selection: aTab.session.selection,
|
|
128
|
+
});
|
|
80
129
|
const tab = S.ui.rightTab;
|
|
81
130
|
|
|
82
131
|
const panelTabs = [
|
|
@@ -90,7 +139,7 @@ function rightPanelTemplate() {
|
|
|
90
139
|
<sp-tabs
|
|
91
140
|
selected=${tab}
|
|
92
141
|
quiet
|
|
93
|
-
@change=${(/** @type {
|
|
142
|
+
@change=${(/** @type {Event & { target: { selected: string } }} */ e) => {
|
|
94
143
|
const sel = e.target.selected;
|
|
95
144
|
if (sel && sel !== tab) {
|
|
96
145
|
updateUi("rightTab", sel);
|
|
@@ -108,19 +157,18 @@ function rightPanelTemplate() {
|
|
|
108
157
|
</div>
|
|
109
158
|
`;
|
|
110
159
|
|
|
111
|
-
/** @type {
|
|
160
|
+
/** @type {import("lit-html").TemplateResult | typeof nothing} */
|
|
112
161
|
let bodyT = nothing;
|
|
113
162
|
if (tab === "properties") {
|
|
114
|
-
bodyT = renderPropertiesPanelTemplate({ navigateToComponent:
|
|
163
|
+
bodyT = renderPropertiesPanelTemplate({ navigateToComponent: ctx.navigateToComponent });
|
|
115
164
|
} else if (tab === "events") {
|
|
116
|
-
bodyT = eventsSidebarTemplate(
|
|
165
|
+
bodyT = eventsSidebarTemplate({
|
|
117
166
|
isCustomElementDoc: () => isCustomElementDoc(S),
|
|
118
|
-
renderCanvas: _ctx.renderCanvas,
|
|
119
167
|
});
|
|
120
168
|
} else if (tab === "style") {
|
|
121
169
|
try {
|
|
122
|
-
bodyT = renderStylePanelTemplate({ getCanvasMode:
|
|
123
|
-
} catch (/** @type {
|
|
170
|
+
bodyT = renderStylePanelTemplate({ getCanvasMode: ctx.getCanvasMode });
|
|
171
|
+
} catch (/** @type {unknown} */ e) {
|
|
124
172
|
console.error("[renderStylePanelTemplate]", e);
|
|
125
173
|
}
|
|
126
174
|
}
|
package/src/panels/shared.js
CHANGED
|
@@ -18,28 +18,6 @@ export function mediaDisplayName(name) {
|
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
/**
|
|
22
|
-
* Ensure Lit's internal ChildPart markers are valid. If corrupted, clears the container so Lit
|
|
23
|
-
* rebuilds from scratch on the next render.
|
|
24
|
-
*
|
|
25
|
-
* @param {HTMLElement} container
|
|
26
|
-
*/
|
|
27
|
-
export function ensureLitState(container) {
|
|
28
|
-
// @ts-ignore — Lit stores a ChildPart on this private property
|
|
29
|
-
const part = container["_$litPart$"];
|
|
30
|
-
if (!part) return;
|
|
31
|
-
const start = part._$startNode;
|
|
32
|
-
const end = part._$endNode;
|
|
33
|
-
const startBad = start && start.parentNode !== container;
|
|
34
|
-
const endBad = (end && end !== container && end.parentNode !== container) || (!end && start);
|
|
35
|
-
if (startBad || endBad) {
|
|
36
|
-
console.warn("ensureLitState: clearing corrupted Lit state on", container.id || container);
|
|
37
|
-
container.textContent = "";
|
|
38
|
-
// @ts-ignore
|
|
39
|
-
delete container["_$litPart$"];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
21
|
export const unsafeTags = new Set(["script", "style", "link", "iframe", "object", "embed"]);
|
|
44
22
|
|
|
45
23
|
/**
|