@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,3 +1,4 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
1
2
|
/**
|
|
2
3
|
* Style panel — CSS property editor with media breakpoint tabs, selector dropdown, section
|
|
3
4
|
* accordion, shorthand expand/compress, and filter.
|
|
@@ -6,14 +7,9 @@
|
|
|
6
7
|
import { html, nothing } from "lit-html";
|
|
7
8
|
import { live } from "lit-html/directives/live.js";
|
|
8
9
|
import { ifDefined } from "lit-html/directives/if-defined.js";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
isNestedSelector,
|
|
13
|
-
debouncedStyleCommit,
|
|
14
|
-
} from "../store.js";
|
|
15
|
-
import { activeTab } from "../workspace/workspace.js";
|
|
16
|
-
import { selectStylebookTag } from "./stylebook-panel.js";
|
|
10
|
+
import { getNodeAtPath, COMMON_SELECTORS, isNestedSelector, debouncedStyleCommit } from "../store";
|
|
11
|
+
import { activeTab } from "../workspace/workspace";
|
|
12
|
+
import { selectStylebookTag } from "./stylebook-panel";
|
|
17
13
|
import {
|
|
18
14
|
transactDoc,
|
|
19
15
|
mutateUpdateStyle,
|
|
@@ -22,13 +18,13 @@ import {
|
|
|
22
18
|
mutateUpdateMediaNestedStyle,
|
|
23
19
|
mutateUpdateNestedStylePath,
|
|
24
20
|
mutateUpdateMediaNestedStylePath,
|
|
25
|
-
} from "../tabs/transact
|
|
26
|
-
import { inferInputType, propLabel } from "../utils/studio-utils
|
|
27
|
-
import { renderFieldRow } from "../ui/field-row
|
|
28
|
-
import { parseMediaEntries } from "../utils/canvas-media
|
|
29
|
-
import { getEffectiveMedia, getEffectiveStyle } from "../site-context
|
|
30
|
-
import { computeInheritedStyle } from "../utils/inherited-style
|
|
31
|
-
import { mediaDisplayName } from "./shared
|
|
21
|
+
} from "../tabs/transact";
|
|
22
|
+
import { inferInputType, propLabel } from "../utils/studio-utils";
|
|
23
|
+
import { renderFieldRow } from "../ui/field-row";
|
|
24
|
+
import { parseMediaEntries } from "../utils/canvas-media";
|
|
25
|
+
import { getEffectiveMedia, getEffectiveStyle } from "../site-context";
|
|
26
|
+
import { computeInheritedStyle } from "../utils/inherited-style";
|
|
27
|
+
import { mediaDisplayName } from "./shared";
|
|
32
28
|
import {
|
|
33
29
|
cssMeta,
|
|
34
30
|
getCssInitialMap,
|
|
@@ -39,18 +35,25 @@ import {
|
|
|
39
35
|
compressShorthand,
|
|
40
36
|
expandBorderSide,
|
|
41
37
|
compressBorderSide,
|
|
42
|
-
} from "./style-utils
|
|
43
|
-
import { widgetForType } from "./style-inputs
|
|
38
|
+
} from "./style-utils";
|
|
39
|
+
import { widgetForType } from "./style-inputs";
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
41
|
+
import type { Tab } from "../tabs/tab";
|
|
42
|
+
import type { JxPath } from "../state";
|
|
43
|
+
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
44
|
+
|
|
45
|
+
interface CssLonghand {
|
|
46
|
+
name: string;
|
|
47
|
+
entry: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type CssPropertyEntry = Record<string, unknown>;
|
|
51
|
+
|
|
52
|
+
type StyleMutateFn = (
|
|
53
|
+
t: Tab,
|
|
54
|
+
prop: string,
|
|
55
|
+
val: string | Record<string, unknown> | undefined,
|
|
56
|
+
) => void;
|
|
54
57
|
|
|
55
58
|
/**
|
|
56
59
|
* Check if a selector is a stylebook tag path (e.g., "table" or "table th"). Tag paths don't start
|
|
@@ -59,7 +62,7 @@ import { widgetForType } from "./style-inputs.js";
|
|
|
59
62
|
* @param {string} selector
|
|
60
63
|
* @returns {boolean}
|
|
61
64
|
*/
|
|
62
|
-
function isTagPath(selector) {
|
|
65
|
+
function isTagPath(selector: string) {
|
|
63
66
|
return /^[a-z]/.test(selector);
|
|
64
67
|
}
|
|
65
68
|
|
|
@@ -70,39 +73,39 @@ function isTagPath(selector) {
|
|
|
70
73
|
* @param {string} tagPath
|
|
71
74
|
* @returns {Record<string, unknown>}
|
|
72
75
|
*/
|
|
73
|
-
function resolveNestedTagStyle(style, tagPath) {
|
|
76
|
+
function resolveNestedTagStyle(style: Record<string, unknown>, tagPath: string) {
|
|
74
77
|
const parts = tagPath.split(" ");
|
|
75
|
-
|
|
76
|
-
let obj = style;
|
|
78
|
+
let obj: unknown = style;
|
|
77
79
|
for (const part of parts) {
|
|
78
80
|
if (!obj || typeof obj !== "object") return {};
|
|
79
|
-
obj =
|
|
81
|
+
obj = (obj as Record<string, unknown>)[part];
|
|
80
82
|
}
|
|
81
|
-
return obj && typeof obj === "object" ?
|
|
83
|
+
return obj && typeof obj === "object" ? (obj as Record<string, unknown>) : {};
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
// ─── Row renderers ──────────────────────────────────────────────────────────
|
|
85
87
|
|
|
86
88
|
function renderStyleRow(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
entry: CssPropertyEntry,
|
|
90
|
+
prop: string,
|
|
91
|
+
value: string,
|
|
92
|
+
onCommit: (v: string | undefined) => void,
|
|
93
|
+
onDelete: () => void,
|
|
94
|
+
isWarning: boolean,
|
|
95
|
+
gridMode: boolean,
|
|
96
|
+
inheritedValue: string | undefined,
|
|
95
97
|
) {
|
|
96
98
|
const type = inferInputType(entry);
|
|
97
99
|
const hasVal = value !== undefined && value !== "";
|
|
98
100
|
const placeholder = !hasVal && inheritedValue ? String(inheritedValue) : "";
|
|
101
|
+
const spanVal = gridMode && (entry as Record<string, unknown>).$span === 2 ? 2 : undefined;
|
|
99
102
|
return renderFieldRow({
|
|
100
103
|
prop,
|
|
101
104
|
label: propLabel(entry, prop),
|
|
102
105
|
hasValue: hasVal,
|
|
103
106
|
onClear: onDelete,
|
|
104
107
|
widget: widgetForType(type, entry, prop, value, onCommit, { placeholder }),
|
|
105
|
-
|
|
108
|
+
...(spanVal != null && { span: spanVal }),
|
|
106
109
|
warning: isWarning,
|
|
107
110
|
});
|
|
108
111
|
}
|
|
@@ -115,17 +118,21 @@ function renderStyleRow(
|
|
|
115
118
|
* @param {() => void} _deleteFn
|
|
116
119
|
* @param {Record<string, string | number>} inherited
|
|
117
120
|
*/
|
|
118
|
-
function renderShorthandRow(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
function renderShorthandRow(
|
|
122
|
+
shortProp: string,
|
|
123
|
+
entry: CssPropertyEntry,
|
|
124
|
+
style: Record<string, unknown>,
|
|
125
|
+
mutateFn: StyleMutateFn,
|
|
126
|
+
_deleteFn: () => void,
|
|
127
|
+
inherited: Record<string, string | number> = {},
|
|
128
|
+
) {
|
|
129
|
+
const tab = activeTab.value!;
|
|
130
|
+
const longhands = getLonghands(shortProp) as CssLonghand[];
|
|
121
131
|
const shortVal = style[shortProp];
|
|
122
|
-
const hasLonghands = longhands.some(
|
|
123
|
-
(/** @type {CssLonghand} */ l) => style[l.name] !== undefined,
|
|
124
|
-
);
|
|
132
|
+
const hasLonghands = longhands.some((l: CssLonghand) => style[l.name] !== undefined);
|
|
125
133
|
const isExpanded = tab.session.ui.styleShorthands[shortProp] ?? hasLonghands;
|
|
126
134
|
const hasAnyVal =
|
|
127
|
-
shortVal !== undefined ||
|
|
128
|
-
longhands.some((/** @type {CssLonghand} */ l) => style[l.name] !== undefined);
|
|
135
|
+
shortVal !== undefined || longhands.some((l: CssLonghand) => style[l.name] !== undefined);
|
|
129
136
|
|
|
130
137
|
return html`
|
|
131
138
|
<div class="style-row" data-prop=${shortProp}>
|
|
@@ -134,7 +141,7 @@ function renderShorthandRow(shortProp, entry, style, mutateFn, _deleteFn, inheri
|
|
|
134
141
|
? html`<span
|
|
135
142
|
class="set-dot"
|
|
136
143
|
title="Clear ${shortProp}"
|
|
137
|
-
@click=${(
|
|
144
|
+
@click=${(e: Event) => {
|
|
138
145
|
e.stopPropagation();
|
|
139
146
|
transactDoc(activeTab.value, (t) => {
|
|
140
147
|
if (shortVal !== undefined) mutateFn(t, shortProp, undefined);
|
|
@@ -152,30 +159,28 @@ function renderShorthandRow(shortProp, entry, style, mutateFn, _deleteFn, inheri
|
|
|
152
159
|
size="s"
|
|
153
160
|
.value=${live(shortVal || "")}
|
|
154
161
|
placeholder=${!shortVal && hasLonghands
|
|
155
|
-
? longhands.map((
|
|
162
|
+
? longhands.map((l: CssLonghand) => style[l.name] || "0").join(" ")
|
|
156
163
|
: !shortVal && inherited[shortProp]
|
|
157
164
|
? inherited[shortProp]
|
|
158
|
-
: !shortVal && longhands.some((
|
|
159
|
-
? longhands
|
|
160
|
-
.map((/** @type {CssLonghand} */ l) => inherited[l.name] || "0")
|
|
161
|
-
.join(" ")
|
|
165
|
+
: !shortVal && longhands.some((l: CssLonghand) => inherited[l.name])
|
|
166
|
+
? longhands.map((l: CssLonghand) => inherited[l.name] || "0").join(" ")
|
|
162
167
|
: ""}
|
|
163
|
-
@input=${debouncedStyleCommit(`short:${shortProp}`, 400, (
|
|
168
|
+
@input=${debouncedStyleCommit(`short:${shortProp}`, 400, (e: Event) => {
|
|
164
169
|
transactDoc(activeTab.value, (t) => {
|
|
165
170
|
for (const l of longhands) {
|
|
166
171
|
if (style[l.name] !== undefined) mutateFn(t, l.name, undefined);
|
|
167
172
|
}
|
|
168
|
-
mutateFn(t, shortProp,
|
|
173
|
+
mutateFn(t, shortProp, (e.target as HTMLInputElement).value || undefined);
|
|
169
174
|
});
|
|
170
175
|
})}
|
|
171
176
|
></sp-textfield>
|
|
172
177
|
<sp-action-button
|
|
173
178
|
size="xs"
|
|
174
179
|
quiet
|
|
175
|
-
@click=${(
|
|
180
|
+
@click=${(e: Event) => {
|
|
176
181
|
e.stopPropagation();
|
|
177
|
-
activeTab.value
|
|
178
|
-
...activeTab.value
|
|
182
|
+
activeTab.value!.session.ui.styleShorthands = {
|
|
183
|
+
...activeTab.value!.session.ui.styleShorthands,
|
|
179
184
|
[shortProp]: !isExpanded,
|
|
180
185
|
};
|
|
181
186
|
}}
|
|
@@ -188,71 +193,64 @@ function renderShorthandRow(shortProp, entry, style, mutateFn, _deleteFn, inheri
|
|
|
188
193
|
</div>
|
|
189
194
|
${isExpanded
|
|
190
195
|
? (() => {
|
|
191
|
-
const isBorderSide =
|
|
192
|
-
"border-side";
|
|
196
|
+
const isBorderSide = (entry as Record<string, unknown>).$shorthandType === "border-side";
|
|
193
197
|
const expanded = shortVal
|
|
194
198
|
? isBorderSide
|
|
195
|
-
? expandBorderSide(
|
|
196
|
-
: expandShorthand(
|
|
199
|
+
? expandBorderSide(shortVal as string)
|
|
200
|
+
: expandShorthand(shortVal as string, longhands.length)
|
|
197
201
|
: null;
|
|
198
202
|
const compress = isBorderSide ? compressBorderSide : compressShorthand;
|
|
199
203
|
const emptyVal = isBorderSide ? "" : "0";
|
|
200
|
-
return longhands.map(
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
<div class="style-row
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
: nothing}
|
|
227
|
-
<sp-field-label size="s" title=${name}
|
|
228
|
-
>${propLabel(lEntry, name)}</sp-field-label
|
|
229
|
-
>
|
|
230
|
-
</div>
|
|
231
|
-
${widgetForType(
|
|
232
|
-
inferInputType(lEntry),
|
|
233
|
-
lEntry,
|
|
234
|
-
name,
|
|
235
|
-
lVal,
|
|
236
|
-
(/** @type {string} */ newVal) => {
|
|
237
|
-
const vals = longhands.map(
|
|
238
|
-
(/** @type {CssLonghand} */ l, /** @type {number} */ i) =>
|
|
239
|
-
i === idx
|
|
240
|
-
? newVal || emptyVal
|
|
241
|
-
: (style[l.name] ?? (expanded ? expanded[i] : emptyVal)),
|
|
242
|
-
);
|
|
243
|
-
transactDoc(activeTab.value, (t) => {
|
|
244
|
-
for (const l of longhands) {
|
|
245
|
-
if (style[l.name] !== undefined) mutateFn(t, l.name, undefined);
|
|
246
|
-
}
|
|
247
|
-
mutateFn(t, shortProp, compress(/** @type {string[]} */ (vals)));
|
|
248
|
-
});
|
|
249
|
-
},
|
|
250
|
-
{ placeholder: !lVal && inherited[name] ? String(inherited[name]) : "" },
|
|
251
|
-
)}
|
|
204
|
+
return longhands.map(({ name, entry: lEntry }: CssLonghand, idx: number) => {
|
|
205
|
+
const lVal = style[name] ?? (expanded ? expanded[idx] : "");
|
|
206
|
+
return html`
|
|
207
|
+
<div class="style-row style-row--child" data-prop=${name}>
|
|
208
|
+
<div class="style-row-label">
|
|
209
|
+
${lVal !== undefined && lVal !== ""
|
|
210
|
+
? html`<span
|
|
211
|
+
class="set-dot"
|
|
212
|
+
title="Clear ${name}"
|
|
213
|
+
@click=${(e: Event) => {
|
|
214
|
+
e.stopPropagation();
|
|
215
|
+
const vals = longhands.map((l: CssLonghand, i: number) =>
|
|
216
|
+
i === idx
|
|
217
|
+
? emptyVal
|
|
218
|
+
: (style[l.name] ?? (expanded ? expanded[i] : emptyVal)),
|
|
219
|
+
);
|
|
220
|
+
transactDoc(activeTab.value, (t) => {
|
|
221
|
+
for (const l of longhands) {
|
|
222
|
+
if (style[l.name] !== undefined) mutateFn(t, l.name, undefined);
|
|
223
|
+
}
|
|
224
|
+
mutateFn(t, shortProp, compress(vals as string[]));
|
|
225
|
+
});
|
|
226
|
+
}}
|
|
227
|
+
></span>`
|
|
228
|
+
: nothing}
|
|
229
|
+
<sp-field-label size="s" title=${name}>${propLabel(lEntry, name)}</sp-field-label>
|
|
252
230
|
</div>
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
231
|
+
${widgetForType(
|
|
232
|
+
inferInputType(lEntry),
|
|
233
|
+
lEntry,
|
|
234
|
+
name,
|
|
235
|
+
lVal,
|
|
236
|
+
(newVal: string) => {
|
|
237
|
+
const vals = longhands.map((l: CssLonghand, i: number) =>
|
|
238
|
+
i === idx
|
|
239
|
+
? newVal || emptyVal
|
|
240
|
+
: (style[l.name] ?? (expanded ? expanded[i] : emptyVal)),
|
|
241
|
+
);
|
|
242
|
+
transactDoc(activeTab.value, (t) => {
|
|
243
|
+
for (const l of longhands) {
|
|
244
|
+
if (style[l.name] !== undefined) mutateFn(t, l.name, undefined);
|
|
245
|
+
}
|
|
246
|
+
mutateFn(t, shortProp, compress(vals as string[]));
|
|
247
|
+
});
|
|
248
|
+
},
|
|
249
|
+
{ placeholder: !lVal && inherited[name] ? String(inherited[name]) : "" },
|
|
250
|
+
)}
|
|
251
|
+
</div>
|
|
252
|
+
`;
|
|
253
|
+
});
|
|
256
254
|
})()
|
|
257
255
|
: nothing}
|
|
258
256
|
`;
|
|
@@ -266,9 +264,14 @@ function renderShorthandRow(shortProp, entry, style, mutateFn, _deleteFn, inheri
|
|
|
266
264
|
* @param {string | null} activeSelector
|
|
267
265
|
* @param {Record<string, unknown>} [effectiveStyle]
|
|
268
266
|
*/
|
|
269
|
-
function styleSidebarTemplate(
|
|
270
|
-
|
|
271
|
-
|
|
267
|
+
function styleSidebarTemplate(
|
|
268
|
+
node: JxMutableNode,
|
|
269
|
+
activeMediaTab: string | null,
|
|
270
|
+
activeSelector: string | null,
|
|
271
|
+
effectiveStyle?: Record<string, unknown>,
|
|
272
|
+
) {
|
|
273
|
+
const tab = activeTab.value!;
|
|
274
|
+
const sel = tab.session.selection as JxPath;
|
|
272
275
|
const style = effectiveStyle || node.style || {};
|
|
273
276
|
const { sizeBreakpoints } = parseMediaEntries(getEffectiveMedia(tab.doc.document.$media));
|
|
274
277
|
const mediaNames = sizeBreakpoints.map((bp) => bp.name);
|
|
@@ -281,8 +284,8 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
281
284
|
<sp-tabs
|
|
282
285
|
size="s"
|
|
283
286
|
selected=${mediaTab || "base"}
|
|
284
|
-
@change=${(
|
|
285
|
-
const val =
|
|
287
|
+
@change=${(e: Event) => {
|
|
288
|
+
const val = (e.target as HTMLElement & { selected: string }).selected;
|
|
286
289
|
const newMedia = val === "base" ? null : val;
|
|
287
290
|
if (newMedia !== tab.session.ui.activeMedia) {
|
|
288
291
|
tab.session.ui.activeMedia = newMedia;
|
|
@@ -298,9 +301,7 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
298
301
|
: nothing;
|
|
299
302
|
|
|
300
303
|
// ── Selector dropdown ──────────────────────────────────────────────────────
|
|
301
|
-
const contextStyle = mediaTab
|
|
302
|
-
? /** @type {Record<string, unknown>} */ (style[`@${mediaTab}`]) || {}
|
|
303
|
-
: style;
|
|
304
|
+
const contextStyle = mediaTab ? (style[`@${mediaTab}`] as Record<string, unknown>) || {} : style;
|
|
304
305
|
const existingSelectors = Object.keys(contextStyle).filter(isNestedSelector);
|
|
305
306
|
const existingSet = new Set(existingSelectors);
|
|
306
307
|
const commonSet = new Set(COMMON_SELECTORS);
|
|
@@ -316,15 +317,14 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
316
317
|
class="selector-select"
|
|
317
318
|
quiet
|
|
318
319
|
.value=${live(_selectorVal)}
|
|
319
|
-
@change=${(
|
|
320
|
-
const val =
|
|
320
|
+
@change=${(e: Event) => {
|
|
321
|
+
const val = (e.target as HTMLElement & { value: string }).value;
|
|
321
322
|
if (val === "__add_custom__") {
|
|
322
323
|
requestAnimationFrame(() => {
|
|
323
|
-
|
|
324
|
-
activeSelector || "__base__";
|
|
324
|
+
(e.target as HTMLElement & { value: string }).value = activeSelector || "__base__";
|
|
325
325
|
});
|
|
326
|
-
const picker =
|
|
327
|
-
const bar =
|
|
326
|
+
const picker = e.target as HTMLElement;
|
|
327
|
+
const bar = picker.closest(".style-toolbar") as HTMLElement;
|
|
328
328
|
picker.style.display = "none";
|
|
329
329
|
const inp = document.createElement("input");
|
|
330
330
|
inp.type = "text";
|
|
@@ -333,14 +333,14 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
333
333
|
bar.appendChild(inp);
|
|
334
334
|
inp.focus();
|
|
335
335
|
let done = false;
|
|
336
|
-
const finish = (
|
|
336
|
+
const finish = (accept: boolean) => {
|
|
337
337
|
if (done) return;
|
|
338
338
|
done = true;
|
|
339
339
|
const v = inp.value.trim();
|
|
340
340
|
inp.remove();
|
|
341
341
|
picker.style.display = "";
|
|
342
342
|
if (accept && v && isNestedSelector(v)) {
|
|
343
|
-
activeTab.value
|
|
343
|
+
activeTab.value!.session.ui.activeSelector = v;
|
|
344
344
|
}
|
|
345
345
|
};
|
|
346
346
|
inp.addEventListener("keydown", (ev) => {
|
|
@@ -351,7 +351,7 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
351
351
|
return;
|
|
352
352
|
}
|
|
353
353
|
const newSelector = val === "__base__" ? null : val;
|
|
354
|
-
activeTab.value
|
|
354
|
+
activeTab.value!.session.ui.activeSelector = newSelector;
|
|
355
355
|
}}
|
|
356
356
|
>
|
|
357
357
|
<sp-menu-item value="__base__">(base)</sp-menu-item>
|
|
@@ -388,8 +388,8 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
388
388
|
class="style-filter-input"
|
|
389
389
|
placeholder="Filter properties…"
|
|
390
390
|
.value=${live(tab.session.ui.styleFilter || "")}
|
|
391
|
-
@input=${(
|
|
392
|
-
activeTab.value
|
|
391
|
+
@input=${(e: Event) => {
|
|
392
|
+
activeTab.value!.session.ui.styleFilter = (e.target as HTMLInputElement).value;
|
|
393
393
|
}}
|
|
394
394
|
></sp-textfield>
|
|
395
395
|
<sp-action-button
|
|
@@ -397,8 +397,8 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
397
397
|
class="style-filter-toggle"
|
|
398
398
|
?selected=${tab.session.ui.styleFilterActive}
|
|
399
399
|
@click=${() => {
|
|
400
|
-
activeTab.value
|
|
401
|
-
!activeTab.value
|
|
400
|
+
activeTab.value!.session.ui.styleFilterActive =
|
|
401
|
+
!activeTab.value!.session.ui.styleFilterActive;
|
|
402
402
|
}}
|
|
403
403
|
>
|
|
404
404
|
Active
|
|
@@ -407,120 +407,78 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
407
407
|
`;
|
|
408
408
|
|
|
409
409
|
// ── Determine the active style object ──────────────────────────────────────
|
|
410
|
-
|
|
411
|
-
let
|
|
412
|
-
|
|
413
|
-
let commitStyle;
|
|
414
|
-
/** @type {(t: Tab, prop: string, val: string | Record<string, unknown> | undefined) => void} */
|
|
415
|
-
let commitMutate;
|
|
410
|
+
let activeStyle: Record<string, unknown>;
|
|
411
|
+
let commitStyle: (prop: string, val: string | Record<string, unknown> | undefined) => void;
|
|
412
|
+
let commitMutate: StyleMutateFn;
|
|
416
413
|
if (activeSelector && isTagPath(activeSelector) && mediaTab && mediaNames.length > 0) {
|
|
417
|
-
const mediaObj =
|
|
414
|
+
const mediaObj = (style[`@${mediaTab}`] as Record<string, unknown>) || {};
|
|
418
415
|
activeStyle = resolveNestedTagStyle(mediaObj, activeSelector);
|
|
419
416
|
const stylePath = activeSelector.split(" ");
|
|
420
|
-
commitMutate = (
|
|
421
|
-
/** @type {Tab} */ t,
|
|
422
|
-
/** @type {string} */ prop,
|
|
423
|
-
/** @type {string | Record<string, unknown> | undefined} */ val,
|
|
424
|
-
) =>
|
|
417
|
+
commitMutate = (t: Tab, prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
425
418
|
mutateUpdateMediaNestedStylePath(
|
|
426
419
|
t,
|
|
427
420
|
sel,
|
|
428
421
|
mediaTab,
|
|
429
422
|
stylePath,
|
|
430
423
|
prop,
|
|
431
|
-
|
|
424
|
+
val as string | undefined,
|
|
432
425
|
);
|
|
433
|
-
commitStyle = (
|
|
434
|
-
|
|
435
|
-
/** @type {string | Record<string, unknown> | undefined} */ val,
|
|
436
|
-
) => transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
426
|
+
commitStyle = (prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
427
|
+
transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
437
428
|
} else if (activeSelector && isTagPath(activeSelector)) {
|
|
438
429
|
activeStyle = resolveNestedTagStyle(style, activeSelector);
|
|
439
430
|
const stylePath = activeSelector.split(" ");
|
|
440
|
-
commitMutate = (
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
) =>
|
|
445
|
-
mutateUpdateNestedStylePath(t, sel, stylePath, prop, /** @type {string | undefined} */ (val));
|
|
446
|
-
commitStyle = (
|
|
447
|
-
/** @type {string} */ prop,
|
|
448
|
-
/** @type {string | Record<string, unknown> | undefined} */ val,
|
|
449
|
-
) => transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
431
|
+
commitMutate = (t: Tab, prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
432
|
+
mutateUpdateNestedStylePath(t, sel, stylePath, prop, val as string | undefined);
|
|
433
|
+
commitStyle = (prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
434
|
+
transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
450
435
|
} else if (activeSelector && mediaTab && mediaNames.length > 0) {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
)
|
|
454
|
-
commitMutate = (
|
|
455
|
-
/** @type {Tab} */ t,
|
|
456
|
-
/** @type {string} */ prop,
|
|
457
|
-
/** @type {string | Record<string, unknown> | undefined} */ val,
|
|
458
|
-
) =>
|
|
436
|
+
const mediaObj = (style[`@${mediaTab}`] || {}) as Record<string, unknown>;
|
|
437
|
+
activeStyle = (mediaObj[activeSelector] as Record<string, unknown>) || {};
|
|
438
|
+
commitMutate = (t: Tab, prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
459
439
|
mutateUpdateMediaNestedStyle(
|
|
460
440
|
t,
|
|
461
441
|
sel,
|
|
462
442
|
mediaTab,
|
|
463
443
|
activeSelector,
|
|
464
444
|
prop,
|
|
465
|
-
|
|
445
|
+
val as string | undefined,
|
|
466
446
|
);
|
|
467
|
-
commitStyle = (
|
|
468
|
-
|
|
469
|
-
/** @type {string | Record<string, unknown> | undefined} */ val,
|
|
470
|
-
) => transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
447
|
+
commitStyle = (prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
448
|
+
transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
471
449
|
} else if (activeSelector) {
|
|
472
|
-
activeStyle =
|
|
473
|
-
commitMutate = (
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
) =>
|
|
478
|
-
mutateUpdateNestedStyle(
|
|
479
|
-
t,
|
|
480
|
-
sel,
|
|
481
|
-
activeSelector,
|
|
482
|
-
prop,
|
|
483
|
-
/** @type {string | undefined} */ (val),
|
|
484
|
-
);
|
|
485
|
-
commitStyle = (
|
|
486
|
-
/** @type {string} */ prop,
|
|
487
|
-
/** @type {string | Record<string, unknown> | undefined} */ val,
|
|
488
|
-
) => transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
450
|
+
activeStyle = (style[activeSelector] as Record<string, unknown>) || {};
|
|
451
|
+
commitMutate = (t: Tab, prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
452
|
+
mutateUpdateNestedStyle(t, sel, activeSelector, prop, val as string | undefined);
|
|
453
|
+
commitStyle = (prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
454
|
+
transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
489
455
|
} else if (mediaTab !== null && mediaNames.length > 0) {
|
|
490
456
|
activeStyle = {};
|
|
491
|
-
for (const [p, v] of Object.entries(
|
|
492
|
-
/** @type {Record<string, unknown>} */ (style[`@${mediaTab}`]) || {},
|
|
493
|
-
)) {
|
|
457
|
+
for (const [p, v] of Object.entries((style[`@${mediaTab}`] as Record<string, unknown>) || {})) {
|
|
494
458
|
if (typeof v !== "object") activeStyle[p] = v;
|
|
495
459
|
}
|
|
496
|
-
commitMutate = (
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
) => mutateUpdateMediaStyle(t, sel, mediaTab, prop, /** @type {string | undefined} */ (val));
|
|
501
|
-
commitStyle = (
|
|
502
|
-
/** @type {string} */ prop,
|
|
503
|
-
/** @type {string | Record<string, unknown> | undefined} */ val,
|
|
504
|
-
) => transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
460
|
+
commitMutate = (t: Tab, prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
461
|
+
mutateUpdateMediaStyle(t, sel, mediaTab, prop, val as string | undefined);
|
|
462
|
+
commitStyle = (prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
463
|
+
transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
505
464
|
} else {
|
|
506
465
|
activeStyle = {};
|
|
507
466
|
for (const [p, v] of Object.entries(style)) {
|
|
508
467
|
if (typeof v !== "object") activeStyle[p] = v;
|
|
509
468
|
}
|
|
510
|
-
commitMutate = (
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
) => mutateUpdateStyle(t, sel, prop, /** @type {string | undefined} */ (val));
|
|
515
|
-
commitStyle = (
|
|
516
|
-
/** @type {string} */ prop,
|
|
517
|
-
/** @type {string | Record<string, unknown> | undefined} */ val,
|
|
518
|
-
) => transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
469
|
+
commitMutate = (t: Tab, prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
470
|
+
mutateUpdateStyle(t, sel, prop, val as string | undefined);
|
|
471
|
+
commitStyle = (prop: string, val: string | Record<string, unknown> | undefined) =>
|
|
472
|
+
transactDoc(activeTab.value, (t) => commitMutate(t, prop, val));
|
|
519
473
|
}
|
|
520
474
|
|
|
521
475
|
// ── Compute inherited style from higher breakpoints ──────────────────────
|
|
522
|
-
|
|
523
|
-
|
|
476
|
+
const inheritedStyle: Record<string, string | number> = computeInheritedStyle(
|
|
477
|
+
style,
|
|
478
|
+
mediaNames,
|
|
479
|
+
mediaTab,
|
|
480
|
+
activeSelector,
|
|
481
|
+
);
|
|
524
482
|
|
|
525
483
|
// Auto-open sections that have properties
|
|
526
484
|
const newSections = autoOpenSections({ style: activeStyle }, tab.session.ui.styleSections);
|
|
@@ -529,40 +487,35 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
529
487
|
}
|
|
530
488
|
|
|
531
489
|
// Partition properties into sections
|
|
532
|
-
const sectionProps =
|
|
533
|
-
/** @type {Record<string, { prop: string; entry: CssPropertyEntry }[]>} */ ({});
|
|
490
|
+
const sectionProps: Record<string, { prop: string; entry: CssPropertyEntry }[]> = {};
|
|
534
491
|
for (const sec of cssMeta.$sections) sectionProps[sec.key] = [];
|
|
535
492
|
|
|
536
|
-
for (const [prop, entry] of
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
if (typeof (/** @type {Record<string, unknown>} */ (entry).$shorthand) === "string") continue;
|
|
540
|
-
const sec = /** @type {string} */ (/** @type {Record<string, unknown>} */ (entry).$section) ||
|
|
541
|
-
"other";
|
|
493
|
+
for (const [prop, entry] of Object.entries(cssMeta.$defs) as [string, CssPropertyEntry][]) {
|
|
494
|
+
if (typeof (entry as Record<string, unknown>).$shorthand === "string") continue;
|
|
495
|
+
const sec = ((entry as Record<string, unknown>).$section as string) || "other";
|
|
542
496
|
sectionProps[sec].push({ prop, entry });
|
|
543
497
|
}
|
|
544
498
|
for (const sec of cssMeta.$sections) {
|
|
545
499
|
sectionProps[sec.key].sort(
|
|
546
500
|
(
|
|
547
|
-
|
|
548
|
-
|
|
501
|
+
a: { prop: string; entry: CssPropertyEntry },
|
|
502
|
+
b: { prop: string; entry: CssPropertyEntry },
|
|
549
503
|
) =>
|
|
550
|
-
|
|
551
|
-
|
|
504
|
+
((a.entry as Record<string, unknown>).$order as number) -
|
|
505
|
+
((b.entry as Record<string, unknown>).$order as number),
|
|
552
506
|
);
|
|
553
507
|
}
|
|
554
508
|
|
|
555
509
|
const otherProps = [];
|
|
556
510
|
for (const prop of Object.keys(activeStyle)) {
|
|
557
|
-
if (!(
|
|
511
|
+
if (!(cssMeta.$defs as Record<string, unknown>)[prop]) {
|
|
558
512
|
const val = activeStyle[prop];
|
|
559
513
|
if (val !== null && typeof val === "object") continue;
|
|
560
514
|
otherProps.push(prop);
|
|
561
515
|
}
|
|
562
516
|
}
|
|
563
517
|
|
|
564
|
-
|
|
565
|
-
const nestedRules = [];
|
|
518
|
+
const nestedRules: string[] = [];
|
|
566
519
|
for (const [prop, val] of Object.entries(activeStyle)) {
|
|
567
520
|
if (val !== null && typeof val === "object" && !Array.isArray(val) && !prop.startsWith("@")) {
|
|
568
521
|
nestedRules.push(prop);
|
|
@@ -581,11 +534,11 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
581
534
|
const entries = sectionProps[sec.key];
|
|
582
535
|
|
|
583
536
|
const sectionActiveProps = entries.filter(
|
|
584
|
-
(
|
|
537
|
+
({ prop, entry }: { prop: string; entry: CssPropertyEntry }) => {
|
|
585
538
|
if (activeStyle[prop] !== undefined) return true;
|
|
586
539
|
if (inferInputType(entry) === "shorthand") {
|
|
587
|
-
return
|
|
588
|
-
(
|
|
540
|
+
return (getLonghands(prop) as CssLonghand[]).some(
|
|
541
|
+
(l: CssLonghand) => activeStyle[l.name] !== undefined,
|
|
589
542
|
);
|
|
590
543
|
}
|
|
591
544
|
return false;
|
|
@@ -599,10 +552,10 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
599
552
|
<sp-accordion-item
|
|
600
553
|
label=${sec.label}
|
|
601
554
|
.open=${false}
|
|
602
|
-
@sp-accordion-item-toggle=${(
|
|
603
|
-
activeTab.value
|
|
604
|
-
...activeTab.value
|
|
605
|
-
[sec.key]:
|
|
555
|
+
@sp-accordion-item-toggle=${(e: Event) => {
|
|
556
|
+
activeTab.value!.session.ui.styleSections = {
|
|
557
|
+
...activeTab.value!.session.ui.styleSections,
|
|
558
|
+
[sec.key]: (e.target as HTMLElement & { open: boolean }).open,
|
|
606
559
|
};
|
|
607
560
|
}}
|
|
608
561
|
>
|
|
@@ -613,14 +566,14 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
613
566
|
<span
|
|
614
567
|
class="set-dot set-dot--section"
|
|
615
568
|
title="Clear all ${sec.label.toLowerCase()} properties"
|
|
616
|
-
@click=${(
|
|
569
|
+
@click=${(e: Event) => {
|
|
617
570
|
e.stopPropagation();
|
|
618
571
|
e.preventDefault();
|
|
619
572
|
transactDoc(activeTab.value, (t) => {
|
|
620
573
|
for (const { prop, entry } of sectionActiveProps) {
|
|
621
574
|
if (activeStyle[prop] !== undefined) commitMutate(t, prop, undefined);
|
|
622
575
|
if (inferInputType(entry) === "shorthand") {
|
|
623
|
-
for (const l of
|
|
576
|
+
for (const l of getLonghands(prop) as CssLonghand[]) {
|
|
624
577
|
if (activeStyle[l.name] !== undefined)
|
|
625
578
|
commitMutate(t, l.name, undefined);
|
|
626
579
|
}
|
|
@@ -650,19 +603,17 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
650
603
|
}
|
|
651
604
|
if (filterActive) {
|
|
652
605
|
if (type === "shorthand") {
|
|
653
|
-
const longhands =
|
|
606
|
+
const longhands = getLonghands(prop) as CssLonghand[];
|
|
654
607
|
const hasAnySet =
|
|
655
|
-
hasVal ||
|
|
656
|
-
longhands.some((/** @type {CssLonghand} */ l) => activeStyle[l.name] !== undefined);
|
|
608
|
+
hasVal || longhands.some((l: CssLonghand) => activeStyle[l.name] !== undefined);
|
|
657
609
|
if (!hasAnySet) continue;
|
|
658
610
|
} else if (!hasVal) continue;
|
|
659
611
|
}
|
|
660
612
|
|
|
661
613
|
if (type === "shorthand") {
|
|
662
|
-
const longhands =
|
|
614
|
+
const longhands = getLonghands(prop) as CssLonghand[];
|
|
663
615
|
const hasAny =
|
|
664
|
-
hasVal ||
|
|
665
|
-
longhands.some((/** @type {CssLonghand} */ l) => activeStyle[l.name] !== undefined);
|
|
616
|
+
hasVal || longhands.some((l: CssLonghand) => activeStyle[l.name] !== undefined);
|
|
666
617
|
if (!hasAny && !condMet) continue;
|
|
667
618
|
rows.push(
|
|
668
619
|
renderShorthandRow(prop, entry, activeStyle, commitMutate, () => {}, inheritedStyle),
|
|
@@ -674,13 +625,12 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
674
625
|
renderStyleRow(
|
|
675
626
|
entry,
|
|
676
627
|
prop,
|
|
677
|
-
|
|
678
|
-
(
|
|
679
|
-
commitStyle(prop, newVal || undefined),
|
|
628
|
+
(val as string) ?? "",
|
|
629
|
+
(newVal: string | undefined) => commitStyle(prop, newVal || undefined),
|
|
680
630
|
() => commitStyle(prop, undefined),
|
|
681
631
|
isWarning,
|
|
682
632
|
sec.$layout === "grid",
|
|
683
|
-
|
|
633
|
+
inheritedStyle[prop] as string | undefined,
|
|
684
634
|
),
|
|
685
635
|
);
|
|
686
636
|
}
|
|
@@ -693,10 +643,10 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
693
643
|
<sp-accordion-item
|
|
694
644
|
label=${sec.label}
|
|
695
645
|
.open=${isOpen}
|
|
696
|
-
@sp-accordion-item-toggle=${(
|
|
697
|
-
activeTab.value
|
|
698
|
-
...activeTab.value
|
|
699
|
-
[sec.key]:
|
|
646
|
+
@sp-accordion-item-toggle=${(e: Event) => {
|
|
647
|
+
activeTab.value!.session.ui.styleSections = {
|
|
648
|
+
...activeTab.value!.session.ui.styleSections,
|
|
649
|
+
[sec.key]: (e.target as HTMLElement & { open: boolean }).open,
|
|
700
650
|
};
|
|
701
651
|
}}
|
|
702
652
|
>
|
|
@@ -707,14 +657,14 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
707
657
|
<span
|
|
708
658
|
class="set-dot set-dot--section"
|
|
709
659
|
title="Clear all ${sec.label.toLowerCase()} properties"
|
|
710
|
-
@click=${(
|
|
660
|
+
@click=${(e: Event) => {
|
|
711
661
|
e.stopPropagation();
|
|
712
662
|
e.preventDefault();
|
|
713
663
|
transactDoc(activeTab.value, (t) => {
|
|
714
664
|
for (const { prop, entry } of sectionActiveProps) {
|
|
715
665
|
if (activeStyle[prop] !== undefined) commitMutate(t, prop, undefined);
|
|
716
666
|
if (inferInputType(entry) === "shorthand") {
|
|
717
|
-
for (const l of
|
|
667
|
+
for (const l of getLonghands(prop) as CssLonghand[]) {
|
|
718
668
|
if (activeStyle[l.name] !== undefined)
|
|
719
669
|
commitMutate(t, l.name, undefined);
|
|
720
670
|
}
|
|
@@ -738,10 +688,10 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
738
688
|
<sp-accordion-item
|
|
739
689
|
label="Custom"
|
|
740
690
|
.open=${customIsOpen}
|
|
741
|
-
@sp-accordion-item-toggle=${(
|
|
742
|
-
activeTab.value
|
|
743
|
-
...activeTab.value
|
|
744
|
-
other:
|
|
691
|
+
@sp-accordion-item-toggle=${(e: Event) => {
|
|
692
|
+
activeTab.value!.session.ui.styleSections = {
|
|
693
|
+
...activeTab.value!.session.ui.styleSections,
|
|
694
|
+
other: (e.target as HTMLElement & { open: boolean }).open,
|
|
745
695
|
};
|
|
746
696
|
}}
|
|
747
697
|
>
|
|
@@ -753,8 +703,8 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
753
703
|
size="s"
|
|
754
704
|
class="kv-key"
|
|
755
705
|
.value=${live(prop)}
|
|
756
|
-
@change=${(
|
|
757
|
-
const newProp =
|
|
706
|
+
@change=${(e: Event) => {
|
|
707
|
+
const newProp = (e.target as HTMLInputElement).value.trim();
|
|
758
708
|
if (newProp && newProp !== prop) {
|
|
759
709
|
transactDoc(activeTab.value, (t) => {
|
|
760
710
|
commitMutate(t, prop, undefined);
|
|
@@ -768,8 +718,8 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
768
718
|
class="kv-val"
|
|
769
719
|
.value=${live(String(activeStyle[prop]))}
|
|
770
720
|
placeholder=${ifDefined(cssInitialMap.get(prop))}
|
|
771
|
-
@input=${debouncedStyleCommit(`custom:${prop}`, 400, (
|
|
772
|
-
commitStyle(prop,
|
|
721
|
+
@input=${debouncedStyleCommit(`custom:${prop}`, 400, (e: Event) => {
|
|
722
|
+
commitStyle(prop, (e.target as HTMLInputElement).value);
|
|
773
723
|
})}
|
|
774
724
|
></sp-textfield>
|
|
775
725
|
<sp-action-button size="xs" quiet @click=${() => commitStyle(prop, undefined)}>
|
|
@@ -783,14 +733,14 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
783
733
|
size="s"
|
|
784
734
|
placeholder="Property name…"
|
|
785
735
|
style="flex:1"
|
|
786
|
-
@keydown=${(
|
|
736
|
+
@keydown=${(e: KeyboardEvent) => {
|
|
787
737
|
if (e.key === "Enter") {
|
|
788
738
|
e.preventDefault();
|
|
789
|
-
const prop =
|
|
739
|
+
const prop = (e.target as HTMLInputElement).value.trim();
|
|
790
740
|
if (prop) {
|
|
791
741
|
const initial = cssInitialMap.get(prop) || "";
|
|
792
742
|
commitStyle(prop, initial || "");
|
|
793
|
-
|
|
743
|
+
(e.target as HTMLInputElement).value = "";
|
|
794
744
|
}
|
|
795
745
|
}
|
|
796
746
|
}}
|
|
@@ -808,10 +758,10 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
808
758
|
<sp-accordion-item
|
|
809
759
|
label="Relative Styling"
|
|
810
760
|
.open=${nestedIsOpen}
|
|
811
|
-
@sp-accordion-item-toggle=${(
|
|
812
|
-
activeTab.value
|
|
813
|
-
...activeTab.value
|
|
814
|
-
nested:
|
|
761
|
+
@sp-accordion-item-toggle=${(e: Event) => {
|
|
762
|
+
activeTab.value!.session.ui.styleSections = {
|
|
763
|
+
...activeTab.value!.session.ui.styleSections,
|
|
764
|
+
nested: (e.target as HTMLElement & { open: boolean }).open,
|
|
815
765
|
};
|
|
816
766
|
}}
|
|
817
767
|
>
|
|
@@ -868,7 +818,7 @@ function styleSidebarTemplate(node, activeMediaTab, activeSelector, effectiveSty
|
|
|
868
818
|
* @param {{ getCanvasMode: () => string }} ctx
|
|
869
819
|
* @returns {import("lit-html").TemplateResult}
|
|
870
820
|
*/
|
|
871
|
-
export function renderStylePanelTemplate(ctx) {
|
|
821
|
+
export function renderStylePanelTemplate(ctx: { getCanvasMode: () => string }) {
|
|
872
822
|
const tab = activeTab.value;
|
|
873
823
|
if (!tab) return html`<div class="empty-state">No document loaded</div>`;
|
|
874
824
|
if (ctx.getCanvasMode() === "stylebook" && tab.session.ui.stylebookSelection) {
|
|
@@ -895,20 +845,16 @@ export function renderStylePanelTemplate(ctx) {
|
|
|
895
845
|
|
|
896
846
|
/** Single property input row (generic field row helper) */
|
|
897
847
|
export function _fieldRow(
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
848
|
+
label: string,
|
|
849
|
+
type: string,
|
|
850
|
+
value: string,
|
|
851
|
+
onChange: (v: string | boolean) => void,
|
|
852
|
+
_datalistId: string | undefined,
|
|
903
853
|
) {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
const onInput = (/** @type {Event} */ e) => {
|
|
854
|
+
let debounceTimer: ReturnType<typeof setTimeout> | undefined;
|
|
855
|
+
const onInput = (e: Event) => {
|
|
907
856
|
clearTimeout(debounceTimer);
|
|
908
|
-
debounceTimer = setTimeout(
|
|
909
|
-
() => onChange(/** @type {HTMLInputElement} */ (e.target).value),
|
|
910
|
-
400,
|
|
911
|
-
);
|
|
857
|
+
debounceTimer = setTimeout(() => onChange((e.target as HTMLInputElement).value), 400);
|
|
912
858
|
};
|
|
913
859
|
const inputTpl =
|
|
914
860
|
type === "textarea"
|
|
@@ -921,8 +867,7 @@ export function _fieldRow(
|
|
|
921
867
|
: type === "checkbox"
|
|
922
868
|
? html`<sp-checkbox
|
|
923
869
|
?checked=${!!value}
|
|
924
|
-
@change=${(
|
|
925
|
-
onChange(/** @type {HTMLInputElement} */ (e.target).checked)}
|
|
870
|
+
@change=${(e: Event) => onChange((e.target as HTMLInputElement).checked)}
|
|
926
871
|
></sp-checkbox>`
|
|
927
872
|
: html`<sp-textfield
|
|
928
873
|
size="s"
|