@jxsuite/studio 0.23.1 → 0.24.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.js +2231 -715
- package/dist/studio.js.map +121 -104
- package/package.json +8 -7
- package/src/browse/{browse-modal.js → browse-modal.ts} +9 -10
- package/src/browse/{browse.js → browse.ts} +110 -85
- package/src/canvas/{canvas-diff.js → canvas-diff.ts} +42 -35
- package/src/canvas/{canvas-helpers.js → canvas-helpers.ts} +25 -19
- package/src/canvas/{canvas-live-render.js → canvas-live-render.ts} +53 -63
- package/src/canvas/{canvas-render.js → canvas-render.ts} +110 -121
- package/src/canvas/{canvas-utils.js → canvas-utils.ts} +48 -44
- package/src/canvas/{nested-site-style.js → nested-site-style.ts} +3 -3
- package/src/editor/{component-inline-edit.js → component-inline-edit.ts} +45 -33
- package/src/editor/{content-inline-edit.js → content-inline-edit.ts} +27 -45
- package/src/editor/{context-menu.js → context-menu.ts} +38 -36
- package/src/editor/{convert-targets.js → convert-targets.ts} +15 -12
- package/src/editor/{convert-to-component.js → convert-to-component.ts} +25 -26
- package/src/editor/{convert-to-repeater.js → convert-to-repeater.ts} +60 -40
- package/src/editor/{inline-edit.js → inline-edit.ts} +91 -55
- package/src/editor/{inline-format.js → inline-format.ts} +46 -51
- package/src/editor/{insertion-helper.js → insertion-helper.ts} +47 -63
- package/src/editor/{shortcuts.js → shortcuts.ts} +45 -31
- package/src/editor/{slash-menu.js → slash-menu.ts} +34 -35
- package/src/files/{components.js → components.ts} +12 -15
- package/src/files/{file-ops.js → file-ops.ts} +36 -29
- package/src/files/{files.js → files.ts} +102 -84
- package/src/github/{github-auth.js → github-auth.ts} +3 -3
- package/src/github/{github-publish.js → github-publish.ts} +20 -18
- package/src/markdown/{md-allowlist.js → md-allowlist.ts} +5 -2
- package/src/markdown/{md-convert.js → md-convert.ts} +146 -169
- package/src/new-project/{new-project-modal.js → new-project-modal.ts} +16 -18
- package/src/panels/{activity-bar.js → activity-bar.ts} +26 -34
- package/src/panels/{ai-panel.js → ai-panel.ts} +30 -30
- package/src/panels/{block-action-bar.js → block-action-bar.ts} +64 -73
- package/src/panels/{canvas-dnd.js → canvas-dnd.ts} +44 -49
- package/src/panels/{data-explorer.js → data-explorer.ts} +21 -15
- package/src/panels/dnd.ts +417 -0
- package/src/panels/{editors.js → editors.ts} +43 -50
- package/src/panels/{elements-panel.js → elements-panel.ts} +30 -27
- package/src/panels/{events-panel.js → events-panel.ts} +33 -25
- package/src/panels/{git-panel.js → git-panel.ts} +97 -83
- package/src/panels/{head-panel.js → head-panel.ts} +117 -139
- package/src/panels/{imports-panel.js → imports-panel.ts} +69 -89
- package/src/panels/{layers-panel.js → layers-panel.ts} +61 -57
- package/src/panels/{left-panel.js → left-panel.ts} +56 -63
- package/src/panels/{overlays.js → overlays.ts} +28 -36
- package/src/panels/{panel-events.js → panel-events.ts} +53 -51
- package/src/panels/{preview-render.js → preview-render.ts} +20 -15
- package/src/panels/{properties-panel.js → properties-panel.ts} +212 -246
- package/src/panels/{pseudo-preview.js → pseudo-preview.ts} +9 -8
- package/src/panels/{quick-search.js → quick-search.ts} +16 -17
- package/src/panels/{right-panel.js → right-panel.ts} +41 -59
- package/src/panels/{shared.js → shared.ts} +7 -5
- package/src/panels/{signals-panel.js → signals-panel.ts} +322 -362
- package/src/panels/{statusbar.js → statusbar.ts} +14 -14
- package/src/panels/{style-inputs.js → style-inputs.ts} +66 -48
- package/src/panels/{style-panel.js → style-panel.ts} +235 -290
- package/src/panels/{style-utils.js → style-utils.ts} +32 -31
- package/src/panels/{stylebook-layers-panel.js → stylebook-layers-panel.ts} +22 -14
- package/src/panels/{stylebook-panel.js → stylebook-panel.ts} +127 -140
- package/src/panels/{tab-strip.js → tab-strip.ts} +12 -14
- package/src/panels/{toolbar.js → toolbar.ts} +68 -70
- package/src/panels/{welcome-screen.js → welcome-screen.ts} +14 -16
- package/src/{platform.js → platform.ts} +5 -3
- package/src/platforms/{devserver.js → devserver.ts} +53 -44
- package/src/{recent-projects.js → recent-projects.ts} +17 -12
- package/src/{resize-edges.js → resize-edges.ts} +18 -13
- package/src/services/{cem-export.js → cem-export.ts} +14 -7
- package/src/services/{code-services.js → code-services.ts} +29 -20
- package/src/services/{monaco-setup.js → monaco-setup.ts} +2 -3
- package/src/settings/{content-types-editor.js → content-types-editor.ts} +88 -67
- package/src/settings/{css-vars-editor.js → css-vars-editor.ts} +78 -51
- package/src/settings/{defs-editor.js → defs-editor.ts} +70 -56
- package/src/settings/{general-settings.js → general-settings.ts} +29 -28
- package/src/settings/{head-editor.js → head-editor.ts} +37 -35
- package/src/settings/{schema-field-ui.js → schema-field-ui.ts} +86 -76
- package/src/settings/{settings-modal.js → settings-modal.ts} +14 -16
- package/src/{site-context.js → site-context.ts} +35 -32
- package/src/{state.js → state.ts} +95 -78
- package/src/{store.js → store.ts} +60 -63
- package/src/{studio.js → studio.ts} +117 -119
- package/src/tabs/tab.ts +196 -0
- package/src/tabs/{transact.js → transact.ts} +107 -60
- package/src/types.ts +185 -0
- package/src/ui/{button-group.js → button-group.ts} +21 -21
- package/src/ui/{color-selector.js → color-selector.ts} +44 -37
- package/src/ui/{expression-editor.js → expression-editor.ts} +65 -40
- package/src/ui/{field-row.js → field-row.ts} +19 -2
- package/src/ui/{icons.js → icons.ts} +2 -2
- package/src/ui/{layers.js → layers.ts} +33 -24
- package/src/ui/{media-picker.js → media-picker.ts} +13 -9
- package/src/ui/{panel-resize.js → panel-resize.ts} +9 -4
- package/src/ui/{spectrum.js → spectrum.ts} +4 -4
- package/src/ui/{unit-selector.js → unit-selector.ts} +16 -19
- package/src/ui/{value-selector.js → value-selector.ts} +28 -28
- package/src/ui/{widgets.js → widgets.ts} +62 -15
- package/src/utils/{canvas-media.js → canvas-media.ts} +29 -14
- package/src/utils/{edit-display.js → edit-display.ts} +23 -20
- package/src/utils/{google-fonts.js → google-fonts.ts} +14 -13
- package/src/utils/{inherited-style.js → inherited-style.ts} +15 -10
- package/src/utils/{studio-utils.js → studio-utils.ts} +38 -26
- package/src/{view.js → view.ts} +53 -55
- package/src/workspace/{workspace.js → workspace.ts} +44 -33
- package/src/panels/dnd.js +0 -426
- package/src/tabs/tab.js +0 -192
- /package/src/{reactivity.js → reactivity.ts} +0 -0
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
1
2
|
/**
|
|
2
3
|
* Pseudo-state preview — extracted from studio.js (Phase 4m). When a pseudo-selector (:hover,
|
|
3
4
|
* :focus, etc.) is active in the style sidebar, force those styles onto the selected element.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
|
-
import { getNodeAtPath } from "../store
|
|
7
|
-
import { activeTab } from "../workspace/workspace
|
|
8
|
-
import { view } from "../view
|
|
9
|
-
import { getActivePanel, findCanvasElement } from "../canvas/canvas-helpers
|
|
7
|
+
import { getNodeAtPath } from "../store";
|
|
8
|
+
import { activeTab } from "../workspace/workspace";
|
|
9
|
+
import { view } from "../view";
|
|
10
|
+
import { getActivePanel, findCanvasElement } from "../canvas/canvas-helpers";
|
|
11
|
+
|
|
12
|
+
import type { JxStyle } from "@jxsuite/schema/types";
|
|
10
13
|
|
|
11
14
|
const pseudoStyleHost = document.createElement("div");
|
|
12
15
|
pseudoStyleHost.style.display = "contents";
|
|
@@ -34,16 +37,14 @@ export function updateForcedPseudoPreview() {
|
|
|
34
37
|
const node = getNodeAtPath(tab.doc.document, tab.session.selection);
|
|
35
38
|
if (!node?.style) return;
|
|
36
39
|
const activeMedia = tab.session.ui.activeMedia;
|
|
37
|
-
|
|
38
|
-
const ctx = activeMedia ? node.style[`@${activeMedia}`] || {} : node.style;
|
|
40
|
+
const ctx: JxStyle = activeMedia ? node.style[`@${activeMedia}`] || {} : node.style;
|
|
39
41
|
const rules = ctx[sel];
|
|
40
42
|
if (!rules || typeof rules !== "object") return;
|
|
41
43
|
|
|
42
44
|
const cssProps = Object.entries(rules)
|
|
43
45
|
.filter(([k]) => typeof rules[k] === "string" || typeof rules[k] === "number")
|
|
44
46
|
.map(
|
|
45
|
-
([k, v]) =>
|
|
46
|
-
`${k.replace(/[A-Z]/g, (/** @type {string} */ c) => `-${c.toLowerCase()}`)}: ${v} !important`,
|
|
47
|
+
([k, v]) => `${k.replace(/[A-Z]/g, (c: string) => `-${c.toLowerCase()}`)}: ${v} !important`,
|
|
47
48
|
)
|
|
48
49
|
.join("; ");
|
|
49
50
|
if (!cssProps) return;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
1
2
|
import { html, render as litRender, nothing } from "lit-html";
|
|
2
3
|
import { classMap } from "lit-html/directives/class-map.js";
|
|
3
4
|
import { live } from "lit-html/directives/live.js";
|
|
4
5
|
import { ref } from "lit-html/directives/ref.js";
|
|
5
|
-
import { getPlatform } from "../platform
|
|
6
|
-
import { openFileInTab } from "../files/files
|
|
7
|
-
import { getRecentFiles, trackRecentFile } from "../recent-projects
|
|
8
|
-
import { getLayerSlot } from "../ui/layers
|
|
6
|
+
import { getPlatform } from "../platform";
|
|
7
|
+
import { openFileInTab } from "../files/files";
|
|
8
|
+
import { getRecentFiles, trackRecentFile } from "../recent-projects";
|
|
9
|
+
import { getLayerSlot } from "../ui/layers";
|
|
9
10
|
|
|
10
11
|
let _open = false;
|
|
11
12
|
let _query = "";
|
|
12
13
|
/** @type {{ path: string; name?: string }[]} */
|
|
13
|
-
let _results = [];
|
|
14
|
+
let _results: { path: string; name?: string }[] = [];
|
|
14
15
|
let _selectedIndex = 0;
|
|
15
16
|
let _debounceTimer = 0;
|
|
16
17
|
|
|
@@ -36,7 +37,7 @@ export function closeQuickSearch() {
|
|
|
36
37
|
renderOverlay();
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
async function doSearch(
|
|
40
|
+
async function doSearch(query: string) {
|
|
40
41
|
if (!query.trim()) {
|
|
41
42
|
_results = [];
|
|
42
43
|
_selectedIndex = 0;
|
|
@@ -54,16 +55,14 @@ async function doSearch(/** @type {string} */ query) {
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
function onInput(
|
|
58
|
-
_query =
|
|
58
|
+
function onInput(e: Event) {
|
|
59
|
+
_query = (e.target as HTMLInputElement).value;
|
|
59
60
|
clearTimeout(_debounceTimer);
|
|
60
|
-
_debounceTimer =
|
|
61
|
-
/** @type {unknown} */ (setTimeout(() => doSearch(_query), 150))
|
|
62
|
-
);
|
|
61
|
+
_debounceTimer = setTimeout(() => doSearch(_query), 150) as unknown as number;
|
|
63
62
|
renderOverlay();
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
function onKeydown(
|
|
65
|
+
function onKeydown(e: KeyboardEvent) {
|
|
67
66
|
const items = _query.trim() ? _results : getRecentFiles();
|
|
68
67
|
switch (e.key) {
|
|
69
68
|
case "ArrowDown":
|
|
@@ -87,14 +86,14 @@ function onKeydown(/** @type {KeyboardEvent} */ e) {
|
|
|
87
86
|
}
|
|
88
87
|
}
|
|
89
88
|
|
|
90
|
-
function selectItem(
|
|
89
|
+
function selectItem(item: { path: string; name?: string }) {
|
|
91
90
|
closeQuickSearch();
|
|
92
91
|
const path = item.path;
|
|
93
92
|
trackRecentFile({ path, name: path.split("/").pop() || "" });
|
|
94
93
|
openFileInTab(path);
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
function fileIcon(
|
|
96
|
+
function fileIcon(name: string) {
|
|
98
97
|
const ext = name.split(".").pop()?.toLowerCase();
|
|
99
98
|
switch (ext) {
|
|
100
99
|
case "json":
|
|
@@ -106,7 +105,7 @@ function fileIcon(/** @type {string} */ name) {
|
|
|
106
105
|
}
|
|
107
106
|
}
|
|
108
107
|
|
|
109
|
-
function dirPart(
|
|
108
|
+
function dirPart(path: string) {
|
|
110
109
|
const parts = path.split("/");
|
|
111
110
|
parts.pop();
|
|
112
111
|
return parts.length ? parts.join("/") : "";
|
|
@@ -125,7 +124,7 @@ function renderOverlay() {
|
|
|
125
124
|
|
|
126
125
|
const tpl = html`
|
|
127
126
|
<div class="quick-search-overlay" @click=${closeQuickSearch}>
|
|
128
|
-
<div class="quick-search-panel" @click=${(
|
|
127
|
+
<div class="quick-search-panel" @click=${(e: Event) => e.stopPropagation()}>
|
|
129
128
|
<input
|
|
130
129
|
class="quick-search-input"
|
|
131
130
|
type="text"
|
|
@@ -134,7 +133,7 @@ function renderOverlay() {
|
|
|
134
133
|
@input=${onInput}
|
|
135
134
|
@keydown=${onKeydown}
|
|
136
135
|
${ref((el) => {
|
|
137
|
-
if (el) requestAnimationFrame(() =>
|
|
136
|
+
if (el) requestAnimationFrame(() => (el as HTMLInputElement).focus());
|
|
138
137
|
})}
|
|
139
138
|
/>
|
|
140
139
|
<div class="quick-search-results">
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
1
2
|
/**
|
|
2
3
|
* Right panel — orchestrates Properties / Events / Style tabs. The heavy sub-templates
|
|
3
4
|
* (propertiesSidebarTemplate, renderStylePanelTemplate) remain in studio.js and are passed via ctx
|
|
@@ -5,43 +6,39 @@
|
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
import { html, render as litRender } from "lit-html";
|
|
8
|
-
import { updateUi, rightPanel } from "../store
|
|
9
|
-
import { effect, effectScope } from "../reactivity
|
|
10
|
-
import { activeTab } from "../workspace/workspace
|
|
11
|
-
import { tabIcon } from "./activity-bar
|
|
12
|
-
import { eventsSidebarTemplate } from "./events-panel
|
|
13
|
-
import { isCustomElementDoc } from "./signals-panel
|
|
9
|
+
import { updateUi, rightPanel } from "../store";
|
|
10
|
+
import { effect, effectScope } from "../reactivity";
|
|
11
|
+
import { activeTab } from "../workspace/workspace";
|
|
12
|
+
import { tabIcon } from "./activity-bar";
|
|
13
|
+
import { eventsSidebarTemplate } from "./events-panel";
|
|
14
|
+
import { isCustomElementDoc } from "./signals-panel";
|
|
15
|
+
|
|
16
|
+
import { isColorPopoverOpen } from "../ui/color-selector";
|
|
17
|
+
import { renderStylePanelTemplate } from "./style-panel";
|
|
18
|
+
import { renderPropertiesPanelTemplate } from "./properties-panel";
|
|
19
|
+
interface RightPanelCtx {
|
|
20
|
+
navigateToComponent: (path: string) => void;
|
|
21
|
+
getCanvasMode: () => string;
|
|
22
|
+
renderCanvas: () => void;
|
|
23
|
+
updateForcedPseudoPreview: () => void;
|
|
24
|
+
}
|
|
14
25
|
|
|
15
|
-
import { isColorPopoverOpen } from "../ui/color-selector.js";
|
|
16
|
-
import { renderStylePanelTemplate } from "./style-panel.js";
|
|
17
|
-
import { renderPropertiesPanelTemplate } from "./properties-panel.js";
|
|
18
26
|
import {
|
|
19
27
|
renderAiPanelTemplate,
|
|
20
28
|
mountAiPanel,
|
|
21
29
|
mountQuikChat,
|
|
22
30
|
registerRightPanelRender,
|
|
23
|
-
} from "./ai-panel
|
|
31
|
+
} from "./ai-panel";
|
|
24
32
|
|
|
25
|
-
|
|
26
|
-
* @typedef {{
|
|
27
|
-
* navigateToComponent: (path: string) => void;
|
|
28
|
-
* getCanvasMode: () => string;
|
|
29
|
-
* renderCanvas: () => void;
|
|
30
|
-
* updateForcedPseudoPreview: () => void;
|
|
31
|
-
* }} RightPanelCtx
|
|
32
|
-
*/
|
|
33
|
+
let _ctx: RightPanelCtx | null = null;
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
let _ctx = null;
|
|
36
|
-
|
|
37
|
-
/** @type {import("@vue/reactivity").EffectScope | null} */
|
|
38
|
-
let _scope = null;
|
|
35
|
+
let _scope: import("@vue/reactivity").EffectScope | null = null;
|
|
39
36
|
|
|
40
37
|
let _rendering = false;
|
|
41
38
|
let _scheduled = false;
|
|
42
39
|
let _hasFocus = false;
|
|
43
40
|
|
|
44
|
-
function _isTextInput(
|
|
41
|
+
function _isTextInput(el: Element | null) {
|
|
45
42
|
if (!el) return false;
|
|
46
43
|
const tag = el.tagName.toLowerCase();
|
|
47
44
|
if (tag === "input" || tag === "textarea") return true;
|
|
@@ -50,8 +47,8 @@ function _isTextInput(/** @type {Element | null} */ el) {
|
|
|
50
47
|
return false;
|
|
51
48
|
}
|
|
52
49
|
|
|
53
|
-
function _onFocusIn(
|
|
54
|
-
_hasFocus = _isTextInput(
|
|
50
|
+
function _onFocusIn(e: FocusEvent) {
|
|
51
|
+
_hasFocus = _isTextInput(e.target as Element);
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
function _onFocusOut() {
|
|
@@ -64,7 +61,7 @@ function _onFocusOut() {
|
|
|
64
61
|
*
|
|
65
62
|
* @param {RightPanelCtx} ctx
|
|
66
63
|
*/
|
|
67
|
-
export function mount(ctx) {
|
|
64
|
+
export function mount(ctx: RightPanelCtx) {
|
|
68
65
|
_ctx = ctx;
|
|
69
66
|
mountAiPanel();
|
|
70
67
|
registerRightPanelRender(render);
|
|
@@ -119,16 +116,11 @@ export function render() {
|
|
|
119
116
|
}
|
|
120
117
|
}
|
|
121
118
|
|
|
122
|
-
|
|
123
|
-
let
|
|
124
|
-
|
|
125
|
-
let
|
|
126
|
-
|
|
127
|
-
let _styleContainer = null;
|
|
128
|
-
/** @type {HTMLElement | null} */
|
|
129
|
-
let _assistantContainer = null;
|
|
130
|
-
/** @type {string | null} */
|
|
131
|
-
let _lastTab = null;
|
|
119
|
+
let _propsContainer: HTMLElement | null = null;
|
|
120
|
+
let _eventsContainer: HTMLElement | null = null;
|
|
121
|
+
let _styleContainer: HTMLElement | null = null;
|
|
122
|
+
let _assistantContainer: HTMLElement | null = null;
|
|
123
|
+
let _lastTab: string | null = null;
|
|
132
124
|
|
|
133
125
|
function _ensureContainers() {
|
|
134
126
|
if (_propsContainer) return;
|
|
@@ -151,26 +143,19 @@ function _flush() {
|
|
|
151
143
|
if (_hasFocus || isColorPopoverOpen()) return;
|
|
152
144
|
_rendering = true;
|
|
153
145
|
try {
|
|
154
|
-
const ctx =
|
|
146
|
+
const ctx = _ctx as RightPanelCtx;
|
|
155
147
|
const aTab = activeTab.value;
|
|
156
148
|
if (!aTab) {
|
|
157
149
|
rightPanel.textContent = "";
|
|
158
150
|
return;
|
|
159
151
|
}
|
|
160
|
-
const S =
|
|
161
|
-
* @type {{
|
|
162
|
-
* ui: Record<string, unknown>;
|
|
163
|
-
* document: JxMutableNode;
|
|
164
|
-
* mode: string;
|
|
165
|
-
* selection: (string | number)[] | null;
|
|
166
|
-
* }}
|
|
167
|
-
*/ ({
|
|
152
|
+
const S = {
|
|
168
153
|
ui: aTab.session.ui,
|
|
169
154
|
document: aTab.doc.document,
|
|
170
155
|
mode: aTab.doc.mode,
|
|
171
156
|
selection: aTab.session.selection,
|
|
172
|
-
}
|
|
173
|
-
const tab =
|
|
157
|
+
};
|
|
158
|
+
const tab = S.ui.rightTab;
|
|
174
159
|
|
|
175
160
|
// Render tabs header
|
|
176
161
|
const panelTabs = [
|
|
@@ -184,7 +169,7 @@ function _flush() {
|
|
|
184
169
|
<sp-tabs
|
|
185
170
|
selected=${tab}
|
|
186
171
|
quiet
|
|
187
|
-
@change=${(
|
|
172
|
+
@change=${(e: Event & { target: { selected: string } }) => {
|
|
188
173
|
const sel = e.target.selected;
|
|
189
174
|
if (sel && sel !== tab) {
|
|
190
175
|
updateUi("rightTab", sel);
|
|
@@ -204,12 +189,12 @@ function _flush() {
|
|
|
204
189
|
`;
|
|
205
190
|
|
|
206
191
|
_ensureContainers();
|
|
207
|
-
const containers =
|
|
192
|
+
const containers = [
|
|
208
193
|
_propsContainer,
|
|
209
194
|
_eventsContainer,
|
|
210
195
|
_styleContainer,
|
|
211
196
|
_assistantContainer,
|
|
212
|
-
]
|
|
197
|
+
] as HTMLElement[];
|
|
213
198
|
const tabKeys = ["properties", "events", "style", "assistant"];
|
|
214
199
|
|
|
215
200
|
// Show/hide containers
|
|
@@ -231,24 +216,21 @@ function _flush() {
|
|
|
231
216
|
if (tab === "properties") {
|
|
232
217
|
litRender(
|
|
233
218
|
renderPropertiesPanelTemplate({ navigateToComponent: ctx.navigateToComponent }),
|
|
234
|
-
|
|
219
|
+
_propsContainer!,
|
|
235
220
|
);
|
|
236
221
|
} else if (tab === "events") {
|
|
237
222
|
litRender(
|
|
238
223
|
eventsSidebarTemplate({ isCustomElementDoc: () => isCustomElementDoc(S) }),
|
|
239
|
-
|
|
224
|
+
_eventsContainer!,
|
|
240
225
|
);
|
|
241
226
|
} else if (tab === "style") {
|
|
242
227
|
try {
|
|
243
|
-
litRender(
|
|
244
|
-
|
|
245
|
-
/** @type {HTMLElement} */ (_styleContainer),
|
|
246
|
-
);
|
|
247
|
-
} catch (/** @type {unknown} */ e) {
|
|
228
|
+
litRender(renderStylePanelTemplate({ getCanvasMode: ctx.getCanvasMode }), _styleContainer!);
|
|
229
|
+
} catch (e) {
|
|
248
230
|
console.error("[renderStylePanelTemplate]", e);
|
|
249
231
|
}
|
|
250
232
|
} else if (tab === "assistant") {
|
|
251
|
-
litRender(renderAiPanelTemplate(),
|
|
233
|
+
litRender(renderAiPanelTemplate(), _assistantContainer!);
|
|
252
234
|
}
|
|
253
235
|
|
|
254
236
|
_lastTab = tab;
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
1
2
|
/**
|
|
2
3
|
* Shared panel utilities — portable helpers extracted from studio.js. These functions depend only
|
|
3
4
|
* on store.js / state.js exports (no circular deps).
|
|
4
5
|
*/
|
|
5
6
|
|
|
7
|
+
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
8
|
+
|
|
6
9
|
/**
|
|
7
10
|
* Convert a $media key like "--tablet" to a friendly display name "Tablet". "--" returns "Base".
|
|
8
11
|
*
|
|
9
12
|
* @param {string} name
|
|
10
13
|
*/
|
|
11
|
-
export function mediaDisplayName(name) {
|
|
14
|
+
export function mediaDisplayName(name: string) {
|
|
12
15
|
if (name === "--") return "Base";
|
|
13
16
|
return (
|
|
14
17
|
name
|
|
15
18
|
.replace(/^--/, "")
|
|
16
19
|
.replace(/-/g, " ")
|
|
17
|
-
.replace(/\b\w/g, (
|
|
20
|
+
.replace(/\b\w/g, (c: string) => c.toUpperCase()) || name
|
|
18
21
|
);
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -25,9 +28,8 @@ export const unsafeTags = new Set(["script", "style", "link", "iframe", "object"
|
|
|
25
28
|
*
|
|
26
29
|
* @param {string} tag
|
|
27
30
|
*/
|
|
28
|
-
export function defaultDef(tag) {
|
|
29
|
-
|
|
30
|
-
const def = { tagName: tag };
|
|
31
|
+
export function defaultDef(tag: string) {
|
|
32
|
+
const def: JxMutableNode = { tagName: tag };
|
|
31
33
|
if (/^h[1-6]$/.test(tag)) def.textContent = "Heading";
|
|
32
34
|
else if (tag === "p") def.textContent = "Paragraph text";
|
|
33
35
|
else if (
|