@jxsuite/studio 0.23.2 → 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 +2230 -714
- 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} +109 -84
- 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} +35 -23
- 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,16 +1,17 @@
|
|
|
1
1
|
/** Style utilities — pure CSS helper functions used by the style panel. */
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import {
|
|
3
|
+
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
4
|
+
|
|
5
|
+
import { getNodeAtPath } from "../store";
|
|
6
|
+
import { activeTab } from "../workspace/workspace";
|
|
7
|
+
import { camelToKebab } from "../utils/studio-utils";
|
|
6
8
|
import cssMeta from "../../data/css-meta.json";
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
let cssInitialMap = new Map();
|
|
10
|
+
let cssInitialMap: Map<string, string> = new Map();
|
|
10
11
|
|
|
11
12
|
/** Initialise cssInitialMap from webdata — call once during bootstrap. */
|
|
12
|
-
export function initCssData(
|
|
13
|
-
cssInitialMap = new Map(
|
|
13
|
+
export function initCssData(webdata: { cssProps: string[][] }) {
|
|
14
|
+
cssInitialMap = new Map(webdata.cssProps as [string, string][]);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
/** Get the CSS initial-value map (populated by initCssData). */
|
|
@@ -21,8 +22,11 @@ export function getCssInitialMap() {
|
|
|
21
22
|
// ─── Condition helpers ──────────────────────────────────────────────────────
|
|
22
23
|
|
|
23
24
|
/** @param {{ prop: string; values: string[] }} cond @param {Record<string, unknown>} styles */
|
|
24
|
-
export function conditionPasses(
|
|
25
|
-
|
|
25
|
+
export function conditionPasses(
|
|
26
|
+
cond: { prop: string; values: string[] },
|
|
27
|
+
styles: Record<string, unknown>,
|
|
28
|
+
) {
|
|
29
|
+
const val = (styles[cond.prop] ?? "") as string;
|
|
26
30
|
if (cond.values.length === 0) return val !== "" && val !== "initial";
|
|
27
31
|
return cond.values.includes(val);
|
|
28
32
|
}
|
|
@@ -31,7 +35,10 @@ export function conditionPasses(cond, styles) {
|
|
|
31
35
|
* @param {{ $show?: { prop: string; values: string[] }[] }} entry @param {Record<string, unknown>}
|
|
32
36
|
* styles
|
|
33
37
|
*/
|
|
34
|
-
export function allConditionsPass(
|
|
38
|
+
export function allConditionsPass(
|
|
39
|
+
entry: { $show?: { prop: string; values: string[] }[] },
|
|
40
|
+
styles: Record<string, unknown>,
|
|
41
|
+
) {
|
|
35
42
|
return (entry.$show ?? []).every((/** @type {{ prop: string; values: string[] }} */ c) =>
|
|
36
43
|
conditionPasses(c, styles),
|
|
37
44
|
);
|
|
@@ -40,13 +47,13 @@ export function allConditionsPass(entry, styles) {
|
|
|
40
47
|
// ─── Auto-open sections ─────────────────────────────────────────────────────
|
|
41
48
|
|
|
42
49
|
/** @param {JxMutableNode} node @param {Record<string, boolean>} currentSections */
|
|
43
|
-
export function autoOpenSections(node, currentSections) {
|
|
50
|
+
export function autoOpenSections(node: JxMutableNode, currentSections: Record<string, boolean>) {
|
|
44
51
|
const style = node.style || {};
|
|
45
52
|
const result = { ...currentSections };
|
|
46
53
|
for (const prop of Object.keys(style)) {
|
|
47
54
|
if (typeof style[prop] === "object") continue;
|
|
48
|
-
const entry =
|
|
49
|
-
const section =
|
|
55
|
+
const entry = (cssMeta.$defs as Record<string, Record<string, unknown>>)[prop];
|
|
56
|
+
const section = (entry?.$section as string) ?? "other";
|
|
50
57
|
if (!result[section]) result[section] = true;
|
|
51
58
|
}
|
|
52
59
|
return result;
|
|
@@ -55,15 +62,13 @@ export function autoOpenSections(node, currentSections) {
|
|
|
55
62
|
// ─── Shorthand expand/compress ──────────────────────────────────────────────
|
|
56
63
|
|
|
57
64
|
/** Get longhands for a shorthand property from css-meta */
|
|
58
|
-
export function getLonghands(
|
|
59
|
-
const entry =
|
|
60
|
-
shorthandProp
|
|
61
|
-
];
|
|
65
|
+
export function getLonghands(shorthandProp: string) {
|
|
66
|
+
const entry = (cssMeta.$defs as Record<string, Record<string, unknown>>)[shorthandProp];
|
|
62
67
|
if (entry?.$longhands) {
|
|
63
|
-
return
|
|
64
|
-
.map((
|
|
68
|
+
return (entry.$longhands as string[])
|
|
69
|
+
.map((name: string) => ({
|
|
65
70
|
name,
|
|
66
|
-
entry:
|
|
71
|
+
entry: (cssMeta.$defs as Record<string, Record<string, unknown>>)[name] || {
|
|
67
72
|
$order: 0,
|
|
68
73
|
},
|
|
69
74
|
}))
|
|
@@ -71,18 +76,14 @@ export function getLonghands(/** @type {string} */ shorthandProp) {
|
|
|
71
76
|
(
|
|
72
77
|
/** @type {{ entry: Record<string, unknown> }} */ a,
|
|
73
78
|
/** @type {{ entry: Record<string, unknown> }} */ b,
|
|
74
|
-
) =>
|
|
79
|
+
) => (a.entry.$order as number) - (b.entry.$order as number),
|
|
75
80
|
);
|
|
76
81
|
}
|
|
77
82
|
const result = [];
|
|
78
|
-
for (const [name, e] of
|
|
79
|
-
Object.entries(cssMeta.$defs)
|
|
80
|
-
)) {
|
|
83
|
+
for (const [name, e] of Object.entries(cssMeta.$defs) as [string, Record<string, unknown>][]) {
|
|
81
84
|
if (e.$shorthand === shorthandProp) result.push({ name, entry: e });
|
|
82
85
|
}
|
|
83
|
-
result.sort(
|
|
84
|
-
(a, b) => /** @type {number} */ (a.entry.$order) - /** @type {number} */ (b.entry.$order),
|
|
85
|
-
);
|
|
86
|
+
result.sort((a, b) => (a.entry.$order as number) - (b.entry.$order as number));
|
|
86
87
|
return result;
|
|
87
88
|
}
|
|
88
89
|
|
|
@@ -90,7 +91,7 @@ export function getLonghands(/** @type {string} */ shorthandProp) {
|
|
|
90
91
|
* Expand a CSS shorthand value into individual longhand values following the standard 1–4 value
|
|
91
92
|
* TRBL pattern.
|
|
92
93
|
*/
|
|
93
|
-
export function expandShorthand(
|
|
94
|
+
export function expandShorthand(shortVal: string, count: number) {
|
|
94
95
|
if (!shortVal) return Array(count).fill("");
|
|
95
96
|
const parts = shortVal.trim().split(/\s+/);
|
|
96
97
|
if (count !== 4 || parts.length === 0) return Array(count).fill("");
|
|
@@ -101,7 +102,7 @@ export function expandShorthand(/** @type {string} */ shortVal, /** @type {numbe
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
/** Compress 4 TRBL values back into the shortest valid CSS shorthand string. */
|
|
104
|
-
export function compressShorthand(
|
|
105
|
+
export function compressShorthand(vals: string[]) {
|
|
105
106
|
const [t, r, b, l] = vals;
|
|
106
107
|
if (t === r && r === b && b === l) return t;
|
|
107
108
|
if (t === b && r === l) return `${t} ${r}`;
|
|
@@ -130,7 +131,7 @@ export const BORDER_STYLES = new Set([
|
|
|
130
131
|
* @param {string} value
|
|
131
132
|
* @returns {string[]}
|
|
132
133
|
*/
|
|
133
|
-
export function expandBorderSide(value) {
|
|
134
|
+
export function expandBorderSide(value: string) {
|
|
134
135
|
if (!value) return ["", "", ""];
|
|
135
136
|
const tokens = [];
|
|
136
137
|
let current = "";
|
|
@@ -170,7 +171,7 @@ export function expandBorderSide(value) {
|
|
|
170
171
|
* @param {string[]} vals
|
|
171
172
|
* @returns {string}
|
|
172
173
|
*/
|
|
173
|
-
export function compressBorderSide(
|
|
174
|
+
export function compressBorderSide(vals: string[]) {
|
|
174
175
|
return vals.filter((v) => v && v.trim()).join(" ");
|
|
175
176
|
}
|
|
176
177
|
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
1
2
|
/** Stylebook layers panel — shows element/variable tree when in stylebook (settings) mode. */
|
|
2
3
|
|
|
3
4
|
import { html, nothing } from "lit-html";
|
|
4
5
|
import { classMap } from "lit-html/directives/class-map.js";
|
|
5
|
-
import { activeTab } from "../workspace/workspace
|
|
6
|
-
import { componentRegistry } from "../files/components
|
|
6
|
+
import { activeTab } from "../workspace/workspace";
|
|
7
|
+
import { componentRegistry } from "../files/components";
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
import type { StylebookEntry } from "./stylebook-panel";
|
|
10
|
+
import type { JxStyle } from "@jxsuite/schema/types";
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* @param {JxStyle} rootStyle
|
|
12
14
|
* @param {string} tag
|
|
13
15
|
*/
|
|
14
|
-
function hasTagStyle(rootStyle, tag) {
|
|
16
|
+
function hasTagStyle(rootStyle: JxStyle, tag: string) {
|
|
15
17
|
const s = rootStyle[`& ${tag}`];
|
|
16
18
|
return s && typeof s === "object" && Object.keys(s).length > 0;
|
|
17
19
|
}
|
|
@@ -27,7 +29,10 @@ function hasTagStyle(rootStyle, tag) {
|
|
|
27
29
|
* }} ctx
|
|
28
30
|
* @returns {import("lit-html").TemplateResult}
|
|
29
31
|
*/
|
|
30
|
-
export function renderStylebookLayersTemplate(ctx
|
|
32
|
+
export function renderStylebookLayersTemplate(ctx: {
|
|
33
|
+
selectStylebookTag: (tag: string, media?: string | null, opts?: { panCanvas?: boolean }) => void;
|
|
34
|
+
stylebookMeta: { $sections: { label: string; elements: StylebookEntry[] }[] };
|
|
35
|
+
}) {
|
|
31
36
|
const tab = activeTab.value;
|
|
32
37
|
const rootStyle = tab?.doc.document?.style || {};
|
|
33
38
|
const selectedTag = tab?.session.ui.stylebookSelection;
|
|
@@ -40,17 +45,21 @@ export function renderStylebookLayersTemplate(ctx) {
|
|
|
40
45
|
* @param {string} parentPath
|
|
41
46
|
* @returns {import("lit-html").TemplateResult}
|
|
42
47
|
*/
|
|
43
|
-
const renderEntryRow = (
|
|
48
|
+
const renderEntryRow = (
|
|
49
|
+
entry: StylebookEntry,
|
|
50
|
+
depth: number = 0,
|
|
51
|
+
parentPath: string = "",
|
|
52
|
+
): import("lit-html").TemplateResult => {
|
|
44
53
|
const tag = entry.tag;
|
|
45
54
|
const fullPath = parentPath ? `${parentPath} ${tag}` : tag;
|
|
46
55
|
const uniqueChildren = entry.children
|
|
47
|
-
? [...new Map(entry.children.map((
|
|
56
|
+
? [...new Map(entry.children.map((c: StylebookEntry) => [c.tag, c])).values()]
|
|
48
57
|
: [];
|
|
49
58
|
return html`
|
|
50
59
|
<div
|
|
51
60
|
class=${classMap({ "layer-row": true, selected: tag === selectedLeaf })}
|
|
52
61
|
style="padding-left:${8 + depth * 16}px"
|
|
53
|
-
@click=${(
|
|
62
|
+
@click=${(e: MouseEvent) => {
|
|
54
63
|
e.stopPropagation();
|
|
55
64
|
ctx.selectStylebookTag(fullPath, undefined, { panCanvas: true });
|
|
56
65
|
}}
|
|
@@ -67,21 +76,20 @@ export function renderStylebookLayersTemplate(ctx) {
|
|
|
67
76
|
></span>`
|
|
68
77
|
: nothing}
|
|
69
78
|
</div>
|
|
70
|
-
${uniqueChildren.map((
|
|
71
|
-
renderEntryRow(child, depth + 1, fullPath),
|
|
72
|
-
)}
|
|
79
|
+
${uniqueChildren.map((child: StylebookEntry) => renderEntryRow(child, depth + 1, fullPath))}
|
|
73
80
|
`;
|
|
74
81
|
};
|
|
75
82
|
|
|
76
|
-
|
|
77
|
-
const elementRows = [];
|
|
83
|
+
const elementRows: import("lit-html").TemplateResult[] = [];
|
|
78
84
|
for (const section of ctx.stylebookMeta.$sections) {
|
|
79
85
|
for (const entry of section.elements) {
|
|
80
86
|
elementRows.push(renderEntryRow(entry, 0));
|
|
81
87
|
}
|
|
82
88
|
}
|
|
83
89
|
const compRows = componentRegistry.map(
|
|
84
|
-
/** @param {import("../files/components.js").ComponentEntry} comp */ (
|
|
90
|
+
/** @param {import("../files/components.js").ComponentEntry} comp */ (
|
|
91
|
+
comp: import("../files/components.js").ComponentEntry,
|
|
92
|
+
) => html`
|
|
85
93
|
<div
|
|
86
94
|
class=${classMap({ "layer-row": true, selected: comp.tagName === selectedTag })}
|
|
87
95
|
@click=${() => ctx.selectStylebookTag(comp.tagName, undefined, { panCanvas: true })}
|