@jxsuite/studio 0.19.0 → 0.20.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.
Files changed (93) hide show
  1. package/dist/studio.css +98 -98
  2. package/dist/studio.js +12577 -12183
  3. package/dist/studio.js.map +146 -144
  4. package/dist/workers/editor.worker.js +79 -79
  5. package/dist/workers/json.worker.js +109 -109
  6. package/dist/workers/ts.worker.js +82 -82
  7. package/package.json +17 -6
  8. package/src/browse/browse.js +25 -19
  9. package/src/canvas/canvas-diff.js +24 -16
  10. package/src/canvas/canvas-helpers.js +24 -19
  11. package/src/canvas/canvas-live-render.js +94 -39
  12. package/src/canvas/canvas-render.js +119 -73
  13. package/src/canvas/canvas-utils.js +38 -15
  14. package/src/canvas/nested-site-style.js +50 -0
  15. package/src/editor/component-inline-edit.js +14 -13
  16. package/src/editor/content-inline-edit.js +22 -10
  17. package/src/editor/context-menu.js +1 -1
  18. package/src/editor/convert-to-component.js +12 -10
  19. package/src/editor/inline-edit.js +66 -28
  20. package/src/editor/insertion-helper.js +16 -12
  21. package/src/editor/shortcuts.js +4 -2
  22. package/src/editor/slash-menu.js +6 -4
  23. package/src/files/components.js +1 -1
  24. package/src/files/file-ops.js +37 -16
  25. package/src/files/files.js +78 -52
  26. package/src/github/github-auth.js +122 -0
  27. package/src/github/github-publish.js +115 -0
  28. package/src/markdown/md-convert.js +172 -107
  29. package/src/new-project/new-project-modal.js +204 -0
  30. package/src/panels/activity-bar.js +22 -20
  31. package/src/panels/ai-panel.js +399 -0
  32. package/src/panels/block-action-bar.js +5 -5
  33. package/src/panels/canvas-dnd.js +8 -2
  34. package/src/panels/data-explorer.js +19 -13
  35. package/src/panels/dnd.js +144 -92
  36. package/src/panels/editors.js +55 -35
  37. package/src/panels/elements-panel.js +33 -19
  38. package/src/panels/events-panel.js +15 -10
  39. package/src/panels/git-panel.js +469 -98
  40. package/src/panels/head-panel.js +121 -81
  41. package/src/panels/imports-panel.js +88 -64
  42. package/src/panels/layers-panel.js +64 -43
  43. package/src/panels/left-panel.js +85 -47
  44. package/src/panels/overlays.js +1 -0
  45. package/src/panels/panel-events.js +45 -30
  46. package/src/panels/preview-render.js +23 -18
  47. package/src/panels/properties-panel.js +365 -249
  48. package/src/panels/pseudo-preview.js +2 -2
  49. package/src/panels/quick-search.js +7 -5
  50. package/src/panels/right-panel.js +26 -2
  51. package/src/panels/shared.js +4 -4
  52. package/src/panels/signals-panel.js +295 -166
  53. package/src/panels/statusbar.js +4 -4
  54. package/src/panels/style-inputs.js +67 -35
  55. package/src/panels/style-panel.js +233 -132
  56. package/src/panels/style-utils.js +34 -16
  57. package/src/panels/stylebook-layers-panel.js +12 -10
  58. package/src/panels/stylebook-panel.js +134 -66
  59. package/src/panels/toolbar.js +333 -109
  60. package/src/panels/welcome-screen.js +121 -0
  61. package/src/platform.js +2 -4
  62. package/src/platforms/devserver.js +113 -7
  63. package/src/resize-edges.js +98 -0
  64. package/src/services/cem-export.js +12 -7
  65. package/src/services/code-services.js +30 -12
  66. package/src/settings/content-types-editor.js +7 -7
  67. package/src/settings/css-vars-editor.js +30 -24
  68. package/src/settings/defs-editor.js +12 -7
  69. package/src/settings/general-settings.js +85 -3
  70. package/src/settings/head-editor.js +30 -24
  71. package/src/settings/schema-field-ui.js +58 -39
  72. package/src/site-context.js +41 -31
  73. package/src/state.js +70 -29
  74. package/src/store.js +21 -26
  75. package/src/studio.js +103 -81
  76. package/src/tabs/tab.js +67 -43
  77. package/src/tabs/transact.js +23 -13
  78. package/src/ui/button-group.js +24 -24
  79. package/src/ui/color-selector.js +28 -23
  80. package/src/ui/field-row.js +3 -3
  81. package/src/ui/icons.js +2 -2
  82. package/src/ui/media-picker.js +7 -7
  83. package/src/ui/spectrum.js +5 -1
  84. package/src/ui/unit-selector.js +18 -16
  85. package/src/ui/value-selector.js +21 -15
  86. package/src/ui/widgets.js +22 -19
  87. package/src/utils/canvas-media.js +5 -4
  88. package/src/utils/edit-display.js +31 -20
  89. package/src/utils/google-fonts.js +11 -11
  90. package/src/utils/inherited-style.js +9 -8
  91. package/src/utils/studio-utils.js +7 -7
  92. package/src/view.js +58 -1
  93. package/src/workspace/workspace.js +10 -7
@@ -9,8 +9,8 @@ import cssMeta from "../../data/css-meta.json";
9
9
  let cssInitialMap = new Map();
10
10
 
11
11
  /** Initialise cssInitialMap from webdata — call once during bootstrap. */
12
- export function initCssData(/** @type {any} */ webdata) {
13
- cssInitialMap = new Map(/** @type {any} */ (webdata.cssProps));
12
+ export function initCssData(/** @type {{ cssProps: string[][] }} */ webdata) {
13
+ cssInitialMap = new Map(/** @type {[string, string][]} */ (webdata.cssProps));
14
14
  }
15
15
 
16
16
  /** Get the CSS initial-value map (populated by initCssData). */
@@ -20,28 +20,33 @@ export function getCssInitialMap() {
20
20
 
21
21
  // ─── Condition helpers ──────────────────────────────────────────────────────
22
22
 
23
- /** @param {any} cond @param {any} styles */
23
+ /** @param {{ prop: string; values: string[] }} cond @param {Record<string, unknown>} styles */
24
24
  export function conditionPasses(cond, styles) {
25
- const val = styles[cond.prop] ?? "";
25
+ const val = /** @type {string} */ (styles[cond.prop] ?? "");
26
26
  if (cond.values.length === 0) return val !== "" && val !== "initial";
27
27
  return cond.values.includes(val);
28
28
  }
29
29
 
30
- /** @param {any} entry @param {any} styles */
30
+ /**
31
+ * @param {{ $show?: { prop: string; values: string[] }[] }} entry @param {Record<string, unknown>}
32
+ * styles
33
+ */
31
34
  export function allConditionsPass(entry, styles) {
32
- return (entry.$show ?? []).every((/** @type {any} */ c) => conditionPasses(c, styles));
35
+ return (entry.$show ?? []).every((/** @type {{ prop: string; values: string[] }} */ c) =>
36
+ conditionPasses(c, styles),
37
+ );
33
38
  }
34
39
 
35
40
  // ─── Auto-open sections ─────────────────────────────────────────────────────
36
41
 
37
- /** @param {any} node @param {any} currentSections */
42
+ /** @param {JxMutableNode} node @param {Record<string, boolean>} currentSections */
38
43
  export function autoOpenSections(node, currentSections) {
39
44
  const style = node.style || {};
40
45
  const result = { ...currentSections };
41
46
  for (const prop of Object.keys(style)) {
42
47
  if (typeof style[prop] === "object") continue;
43
- const entry = /** @type {Record<string, any>} */ (cssMeta.$defs)[prop];
44
- const section = entry?.$section ?? "other";
48
+ const entry = /** @type {Record<string, Record<string, unknown>>} */ (cssMeta.$defs)[prop];
49
+ const section = /** @type {string} */ (entry?.$section) ?? "other";
45
50
  if (!result[section]) result[section] = true;
46
51
  }
47
52
  return result;
@@ -50,21 +55,34 @@ export function autoOpenSections(node, currentSections) {
50
55
  // ─── Shorthand expand/compress ──────────────────────────────────────────────
51
56
 
52
57
  /** Get longhands for a shorthand property from css-meta */
53
- export function getLonghands(/** @type {any} */ shorthandProp) {
54
- const entry = /** @type {Record<string, any>} */ (cssMeta.$defs)[shorthandProp];
58
+ export function getLonghands(/** @type {string} */ shorthandProp) {
59
+ const entry = /** @type {Record<string, Record<string, unknown>>} */ (cssMeta.$defs)[
60
+ shorthandProp
61
+ ];
55
62
  if (entry?.$longhands) {
56
- return entry.$longhands
63
+ return /** @type {string[]} */ (entry.$longhands)
57
64
  .map((/** @type {string} */ name) => ({
58
65
  name,
59
- entry: /** @type {Record<string, any>} */ (cssMeta.$defs)[name] || { $order: 0 },
66
+ entry: /** @type {Record<string, Record<string, unknown>>} */ (cssMeta.$defs)[name] || {
67
+ $order: 0,
68
+ },
60
69
  }))
61
- .sort((/** @type {any} */ a, /** @type {any} */ b) => a.entry.$order - b.entry.$order);
70
+ .sort(
71
+ (
72
+ /** @type {{ entry: Record<string, unknown> }} */ a,
73
+ /** @type {{ entry: Record<string, unknown> }} */ b,
74
+ ) => /** @type {number} */ (a.entry.$order) - /** @type {number} */ (b.entry.$order),
75
+ );
62
76
  }
63
77
  const result = [];
64
- for (const [name, e] of /** @type {[string, any][]} */ (Object.entries(cssMeta.$defs))) {
78
+ for (const [name, e] of /** @type {[string, Record<string, unknown>][]} */ (
79
+ Object.entries(cssMeta.$defs)
80
+ )) {
65
81
  if (e.$shorthand === shorthandProp) result.push({ name, entry: e });
66
82
  }
67
- result.sort((a, b) => a.entry.$order - b.entry.$order);
83
+ result.sort(
84
+ (a, b) => /** @type {number} */ (a.entry.$order) - /** @type {number} */ (b.entry.$order),
85
+ );
68
86
  return result;
69
87
  }
70
88
 
@@ -5,8 +5,10 @@ import { classMap } from "lit-html/directives/class-map.js";
5
5
  import { activeTab } from "../workspace/workspace.js";
6
6
  import { componentRegistry } from "../files/components.js";
7
7
 
8
+ /** @typedef {import("./stylebook-panel.js").StylebookEntry} StylebookEntry */
9
+
8
10
  /**
9
- * @param {any} rootStyle
11
+ * @param {JxStyle} rootStyle
10
12
  * @param {string} tag
11
13
  */
12
14
  function hasTagStyle(rootStyle, tag) {
@@ -21,7 +23,7 @@ function hasTagStyle(rootStyle, tag) {
21
23
  * media?: string | null,
22
24
  * opts?: { panCanvas?: boolean },
23
25
  * ) => void;
24
- * stylebookMeta: any;
26
+ * stylebookMeta: { $sections: { label: string; elements: StylebookEntry[] }[] };
25
27
  * }} ctx
26
28
  * @returns {import("lit-html").TemplateResult}
27
29
  */
@@ -33,22 +35,22 @@ export function renderStylebookLayersTemplate(ctx) {
33
35
 
34
36
  if (tab?.session.ui.stylebookTab === "elements") {
35
37
  /**
36
- * @param {any} entry
38
+ * @param {StylebookEntry} entry
37
39
  * @param {number} depth
38
40
  * @param {string} parentPath
39
- * @returns {any}
41
+ * @returns {import("lit-html").TemplateResult}
40
42
  */
41
43
  const renderEntryRow = (entry, depth = 0, parentPath = "") => {
42
44
  const tag = entry.tag;
43
45
  const fullPath = parentPath ? `${parentPath} ${tag}` : tag;
44
46
  const uniqueChildren = entry.children
45
- ? [...new Map(entry.children.map((/** @type {any} */ c) => [c.tag, c])).values()]
47
+ ? [...new Map(entry.children.map((/** @type {StylebookEntry} */ c) => [c.tag, c])).values()]
46
48
  : [];
47
49
  return html`
48
50
  <div
49
51
  class=${classMap({ "layer-row": true, selected: tag === selectedLeaf })}
50
52
  style="padding-left:${8 + depth * 16}px"
51
- @click=${(/** @type {any} */ e) => {
53
+ @click=${(/** @type {MouseEvent} */ e) => {
52
54
  e.stopPropagation();
53
55
  ctx.selectStylebookTag(fullPath, undefined, { panCanvas: true });
54
56
  }}
@@ -65,21 +67,21 @@ export function renderStylebookLayersTemplate(ctx) {
65
67
  ></span>`
66
68
  : nothing}
67
69
  </div>
68
- ${uniqueChildren.map((/** @type {any} */ child) =>
70
+ ${uniqueChildren.map((/** @type {StylebookEntry} */ child) =>
69
71
  renderEntryRow(child, depth + 1, fullPath),
70
72
  )}
71
73
  `;
72
74
  };
73
75
 
74
- /** @type {any[]} */
76
+ /** @type {import("lit-html").TemplateResult[]} */
75
77
  const elementRows = [];
76
78
  for (const section of ctx.stylebookMeta.$sections) {
77
- for (const entry of /** @type {any[]} */ (section.elements)) {
79
+ for (const entry of section.elements) {
78
80
  elementRows.push(renderEntryRow(entry, 0));
79
81
  }
80
82
  }
81
83
  const compRows = componentRegistry.map(
82
- /** @param {any} comp */ (comp) => html`
84
+ /** @param {import("../files/components.js").ComponentEntry} comp */ (comp) => html`
83
85
  <div
84
86
  class=${classMap({ "layer-row": true, selected: comp.tagName === selectedTag })}
85
87
  @click=${() => ctx.selectStylebookTag(comp.tagName, undefined, { panCanvas: true })}
@@ -29,30 +29,76 @@ import stylebookMeta from "../../data/stylebook-meta.json";
29
29
 
30
30
  export { stylebookMeta };
31
31
 
32
+ /**
33
+ * @typedef {{
34
+ * tag: string;
35
+ * text?: string;
36
+ * attributes?: Record<string, string>;
37
+ * style?: string;
38
+ * children?: StylebookEntry[];
39
+ * }} StylebookEntry
40
+ */
41
+
42
+ /**
43
+ * @typedef {{
44
+ * mediaName: string | null;
45
+ * element: HTMLElement | null;
46
+ * canvas: HTMLElement;
47
+ * overlay: HTMLElement;
48
+ * overlayClk: HTMLElement;
49
+ * viewport: HTMLElement | null;
50
+ * scrollContainer: HTMLElement | null;
51
+ * dropLine: HTMLElement | null;
52
+ * _width: number | null;
53
+ * _lastHoverTag?: string | null;
54
+ * }} StylebookPanel
55
+ */
56
+
57
+ /**
58
+ * @typedef {{
59
+ * canvasPanelTemplate: Function;
60
+ * applyTransform: Function;
61
+ * observeCenterUntilStable: Function;
62
+ * renderZoomIndicator: Function;
63
+ * updateActivePanelHeaders: Function;
64
+ * overlayBoxDescriptor: Function;
65
+ * effectiveZoom: Function;
66
+ * }} StylebookCtx
67
+ */
68
+
69
+ /**
70
+ * @typedef {{
71
+ * source?: string;
72
+ * tagName: string;
73
+ * path?: string;
74
+ * props?: Array<{ name: string; default?: string }>;
75
+ * }} ComponentEntry
76
+ */
77
+
32
78
  /**
33
79
  * Resolve a nested tag path in a style object. e.g., "table th" → style["table"]["th"]
34
80
  *
35
- * @param {Record<string, any>} style
81
+ * @param {Record<string, unknown>} style
36
82
  * @param {string} tagPath
37
- * @returns {Record<string, any> | null}
83
+ * @returns {Record<string, unknown> | null}
38
84
  */
39
85
  function _resolveNestedStyle(style, tagPath) {
40
86
  const parts = tagPath.split(" ");
41
87
  let obj = style;
42
88
  for (const part of parts) {
43
89
  if (!obj || typeof obj !== "object") return null;
44
- obj = obj[part];
90
+ obj = /** @type {Record<string, unknown>} */ (obj[part]);
45
91
  }
46
- return obj && typeof obj === "object" ? /** @type {Record<string, any>} */ (obj) : null;
92
+ return obj && typeof obj === "object" ? /** @type {Record<string, unknown>} */ (obj) : null;
47
93
  }
48
94
 
49
- /** @type {any} */
95
+ /** @type {StylebookCtx | null} */
50
96
  let _ctx = null;
51
97
 
52
98
  /** Lookup: tag → entry from stylebookMeta (built once) */
53
99
  const _entryByTag = new Map();
54
100
  for (const section of stylebookMeta.$sections) {
55
- for (const entry of /** @type {any} */ (section.elements)) {
101
+ for (const entry of /** @type {StylebookEntry[]} */ (section.elements)) {
56
102
  _entryByTag.set(entry.tag, entry);
57
103
  }
58
104
  }
@@ -60,15 +106,7 @@ for (const section of stylebookMeta.$sections) {
60
106
  /**
61
107
  * Render the stylebook/settings mode into the canvas.
62
108
  *
63
- * @param {{
64
- * canvasPanelTemplate: Function;
65
- * applyTransform: Function;
66
- * observeCenterUntilStable: Function;
67
- * renderZoomIndicator: Function;
68
- * updateActivePanelHeaders: Function;
69
- * overlayBoxDescriptor: Function;
70
- * effectiveZoom: Function;
71
- * }} ctx
109
+ * @param {StylebookCtx} ctx
72
110
  */
73
111
  export function renderStylebookMode(ctx) {
74
112
  _ctx = ctx;
@@ -85,8 +123,8 @@ export function renderStylebookMode(ctx) {
85
123
  );
86
124
  const hasMedia = sizeBreakpoints.length > 0;
87
125
 
88
- const onFilterInput = (/** @type {any} */ e) => {
89
- updateUi("stylebookFilter", e.target.value);
126
+ const onFilterInput = (/** @type {Event} */ e) => {
127
+ updateUi("stylebookFilter", /** @type {HTMLInputElement} */ (e.target).value);
90
128
  };
91
129
 
92
130
  const onCustomizedToggle = () => {
@@ -116,9 +154,9 @@ export function renderStylebookMode(ctx) {
116
154
  </div>
117
155
  `;
118
156
 
119
- /** @type {any} */ (canvasWrap).style.overflow = "hidden";
157
+ /** @type {HTMLElement} */ (canvasWrap).style.overflow = "hidden";
120
158
 
121
- /** @type {any[]} */
159
+ /** @type {{ name: string; displayName: string; width: number; activeSet: Set<string> }[]} */
122
160
  const allPanelDefs = [];
123
161
  if (hasMedia) {
124
162
  allPanelDefs.push({
@@ -137,7 +175,10 @@ export function renderStylebookMode(ctx) {
137
175
  }
138
176
  }
139
177
 
140
- const renderIntoPanel = (/** @type {any} */ panel, /** @type {any} */ activeBreakpoints) => {
178
+ const renderIntoPanel = (
179
+ /** @type {StylebookPanel} */ panel,
180
+ /** @type {Set<string>} */ activeBreakpoints,
181
+ ) => {
141
182
  panel.canvas.classList.add("sb-canvas");
142
183
  renderStylebookElementsIntoCanvas(
143
184
  panel.canvas,
@@ -147,12 +188,18 @@ export function renderStylebookMode(ctx) {
147
188
  activeBreakpoints,
148
189
  );
149
190
  for (const child of panel.canvas.querySelectorAll("*")) {
150
- child.style.pointerEvents = "none";
191
+ /** @type {HTMLElement} */ (child).style.pointerEvents = "none";
151
192
  }
152
193
  registerStylebookPanelEvents(panel);
153
194
  };
154
195
 
155
- /** @type {{ tpl: any; panel: any; activeSet: any }[]} */
196
+ /**
197
+ * @type {{
198
+ * tpl: import("lit-html").TemplateResult;
199
+ * panel: StylebookPanel;
200
+ * activeSet: Set<string>;
201
+ * }[]}
202
+ */
156
203
  let panelEntries;
157
204
  if (!hasMedia) {
158
205
  const effectiveMedia = getEffectiveMedia(tab?.doc.document?.$media);
@@ -186,11 +233,11 @@ export function renderStylebookMode(ctx) {
186
233
  ${panelEntries.map((e) => e.tpl)}
187
234
  </div>
188
235
  `,
189
- /** @type {any} */ (canvasWrap),
236
+ /** @type {HTMLElement} */ (canvasWrap),
190
237
  );
191
238
 
192
239
  for (const { panel, activeSet } of panelEntries) {
193
- canvasPanels.push(panel);
240
+ canvasPanels.push(/** @type {import("./canvas-dnd.js").CanvasPanel} */ (panel));
194
241
  renderIntoPanel(panel, activeSet);
195
242
  }
196
243
  if (hasMedia) {
@@ -242,7 +289,9 @@ export function refreshStylebookStyles() {
242
289
  for (const [prop, val] of Object.entries(tagStyle)) {
243
290
  if (typeof val === "string" || typeof val === "number") {
244
291
  try {
245
- /** @type {any} */ (htmlEl.style)[prop] = val;
292
+ /** @type {Record<string, string | number>} */ (
293
+ /** @type {unknown} */ (htmlEl.style)
294
+ )[prop] = val;
246
295
  } catch {}
247
296
  }
248
297
  }
@@ -253,10 +302,14 @@ export function refreshStylebookStyles() {
253
302
  const mediaName = key.slice(1);
254
303
  if (mediaName === "--") continue;
255
304
  if (activeBreakpoints.has(mediaName)) {
256
- for (const [prop, v] of Object.entries(/** @type {any} */ (val))) {
305
+ for (const [prop, v] of Object.entries(
306
+ /** @type {Record<string, unknown>} */ (val),
307
+ )) {
257
308
  if (typeof v === "string" || typeof v === "number") {
258
309
  try {
259
- /** @type {any} */ (htmlEl.style)[prop] = v;
310
+ /** @type {Record<string, string | number>} */ (
311
+ /** @type {unknown} */ (htmlEl.style)
312
+ )[prop] = v;
260
313
  } catch {}
261
314
  }
262
315
  }
@@ -271,12 +324,17 @@ export function refreshStylebookStyles() {
271
324
  const mediaName = key.slice(1);
272
325
  if (mediaName === "--") continue;
273
326
  if (activeBreakpoints.has(mediaName)) {
274
- const mediaTagStyle = _resolveNestedStyle(/** @type {any} */ (val), tag);
327
+ const mediaTagStyle = _resolveNestedStyle(
328
+ /** @type {Record<string, unknown>} */ (val),
329
+ tag,
330
+ );
275
331
  if (mediaTagStyle && typeof mediaTagStyle === "object") {
276
332
  for (const [prop, v] of Object.entries(mediaTagStyle)) {
277
333
  if (typeof v === "string" || typeof v === "number") {
278
334
  try {
279
- /** @type {any} */ (htmlEl.style)[prop] = v;
335
+ /** @type {Record<string, string | number>} */ (
336
+ /** @type {unknown} */ (htmlEl.style)
337
+ )[prop] = v;
280
338
  } catch {}
281
339
  }
282
340
  }
@@ -322,7 +380,7 @@ export function renderStylebookOverlays() {
322
380
  const selectedTag = activeTab.value?.session.ui.stylebookSelection;
323
381
 
324
382
  for (const panel of canvasPanels) {
325
- const hoverTag = /** @type {any} */ (panel)._lastHoverTag;
383
+ const hoverTag = /** @type {StylebookPanel} */ (panel)._lastHoverTag;
326
384
  /**
327
385
  * @type {{
328
386
  * cls: string;
@@ -373,9 +431,9 @@ export function renderStylebookOverlays() {
373
431
  /**
374
432
  * Build a DOM element tree from a stylebook-meta.json entry.
375
433
  *
376
- * @param {any} entry
377
- * @param {any} rootStyle
378
- * @param {any} activeBreakpoints
434
+ * @param {StylebookEntry} entry
435
+ * @param {Record<string, unknown>} rootStyle
436
+ * @param {Set<string> | null} activeBreakpoints
379
437
  * @param {string | null} [parentTag]
380
438
  */
381
439
  export function buildStylebookElement(entry, rootStyle, activeBreakpoints, parentTag = null) {
@@ -397,7 +455,8 @@ export function buildStylebookElement(entry, rootStyle, activeBreakpoints, paren
397
455
  for (const [prop, val] of Object.entries(tagStyle)) {
398
456
  if (typeof val === "string" || typeof val === "number") {
399
457
  try {
400
- /** @type {any} */ (el.style)[prop] = val;
458
+ /** @type {Record<string, string | number>} */ (/** @type {unknown} */ (el.style))[prop] =
459
+ val;
401
460
  } catch {}
402
461
  }
403
462
  }
@@ -408,10 +467,12 @@ export function buildStylebookElement(entry, rootStyle, activeBreakpoints, paren
408
467
  const mediaName = key.slice(1);
409
468
  if (mediaName === "--") continue;
410
469
  if (activeBreakpoints.has(mediaName)) {
411
- for (const [prop, v] of Object.entries(/** @type {any} */ (val))) {
470
+ for (const [prop, v] of Object.entries(/** @type {Record<string, unknown>} */ (val))) {
412
471
  if (typeof v === "string" || typeof v === "number") {
413
472
  try {
414
- /** @type {any} */ (el.style)[prop] = v;
473
+ /** @type {Record<string, string | number>} */ (/** @type {unknown} */ (el.style))[
474
+ prop
475
+ ] = v;
415
476
  } catch {}
416
477
  }
417
478
  }
@@ -427,12 +488,17 @@ export function buildStylebookElement(entry, rootStyle, activeBreakpoints, paren
427
488
  const mediaName = key.slice(1);
428
489
  if (mediaName === "--") continue;
429
490
  if (activeBreakpoints.has(mediaName)) {
430
- const mediaTagStyle = _resolveNestedStyle(/** @type {any} */ (val), tagPath);
491
+ const mediaTagStyle = _resolveNestedStyle(
492
+ /** @type {Record<string, unknown>} */ (val),
493
+ tagPath,
494
+ );
431
495
  if (mediaTagStyle && typeof mediaTagStyle === "object") {
432
496
  for (const [prop, v] of Object.entries(mediaTagStyle)) {
433
497
  if (typeof v === "string" || typeof v === "number") {
434
498
  try {
435
- /** @type {any} */ (el.style)[prop] = v;
499
+ /** @type {Record<string, string | number>} */ (/** @type {unknown} */ (el.style))[
500
+ prop
501
+ ] = v;
436
502
  } catch {}
437
503
  }
438
504
  }
@@ -451,7 +517,7 @@ export function buildStylebookElement(entry, rootStyle, activeBreakpoints, paren
451
517
  /**
452
518
  * Render a live component preview by registering its custom element and instantiating it.
453
519
  *
454
- * @param {any} comp
520
+ * @param {ComponentEntry} comp
455
521
  * @returns {Promise<HTMLElement>}
456
522
  */
457
523
  export async function renderComponentPreview(comp) {
@@ -477,7 +543,7 @@ export async function renderComponentPreview(comp) {
477
543
  }
478
544
  }
479
545
  return el;
480
- } catch (/** @type {any} */ e) {
546
+ } catch (/** @type {unknown} */ e) {
481
547
  console.warn("Component preview failed:", comp.tagName, e);
482
548
  return _componentFallback(comp.tagName);
483
549
  }
@@ -493,26 +559,26 @@ function _componentFallback(tagName) {
493
559
  }
494
560
 
495
561
  /**
496
- * @param {any} rootStyle
497
- * @param {any} tag
562
+ * @param {Record<string, unknown>} rootStyle
563
+ * @param {string} tag
498
564
  */
499
565
  function hasTagStyle(rootStyle, tag) {
500
566
  const s = _resolveNestedStyle(rootStyle, tag);
501
567
  if (s && typeof s === "object" && Object.keys(s).length > 0) return true;
502
568
  for (const [key, val] of Object.entries(rootStyle)) {
503
569
  if (!key.startsWith("@") || typeof val !== "object") continue;
504
- const ms = _resolveNestedStyle(/** @type {any} */ (val), tag);
570
+ const ms = _resolveNestedStyle(/** @type {Record<string, unknown>} */ (val), tag);
505
571
  if (ms && typeof ms === "object" && Object.keys(ms).length > 0) return true;
506
572
  }
507
573
  return false;
508
574
  }
509
575
 
510
576
  /**
511
- * @param {any} canvasEl
512
- * @param {any} rootStyle
513
- * @param {any} filter
514
- * @param {any} customizedOnly
515
- * @param {any} activeBreakpoints
577
+ * @param {HTMLElement} canvasEl
578
+ * @param {Record<string, unknown>} rootStyle
579
+ * @param {string} filter
580
+ * @param {boolean | undefined} customizedOnly
581
+ * @param {Set<string> | null} activeBreakpoints
516
582
  */
517
583
  export function renderStylebookElementsIntoCanvas(
518
584
  canvasEl,
@@ -531,19 +597,19 @@ export function renderStylebookElementsIntoCanvas(
531
597
  const sectionTemplates = [];
532
598
 
533
599
  for (const section of stylebookMeta.$sections) {
534
- let entries = /** @type {any} */ (section.elements);
600
+ let entries = /** @type {StylebookEntry[]} */ (section.elements);
535
601
  if (filter) {
536
602
  entries = entries.filter(
537
- (/** @type {any} */ e) =>
603
+ (/** @type {StylebookEntry} */ e) =>
538
604
  e.tag.includes(filter) || section.label.toLowerCase().includes(filter),
539
605
  );
540
606
  }
541
607
  if (customizedOnly) {
542
- entries = entries.filter((/** @type {any} */ e) => hasTagStyle(rootStyle, e.tag));
608
+ entries = entries.filter((/** @type {StylebookEntry} */ e) => hasTagStyle(rootStyle, e.tag));
543
609
  }
544
610
  if (entries.length === 0) continue;
545
611
 
546
- const cardTemplates = entries.map((/** @type {any} */ entry) => {
612
+ const cardTemplates = entries.map((/** @type {StylebookEntry} */ entry) => {
547
613
  const el = buildStylebookElement(entry, rootStyle, activeBreakpoints);
548
614
  return html`
549
615
  <div
@@ -588,11 +654,13 @@ export function renderStylebookElementsIntoCanvas(
588
654
  if (componentRegistry.length > 0) {
589
655
  let comps = componentRegistry;
590
656
  if (filter)
591
- comps = comps.filter((/** @type {any} */ c) => c.tagName.toLowerCase().includes(filter));
657
+ comps = comps.filter((/** @type {ComponentEntry} */ c) =>
658
+ c.tagName.toLowerCase().includes(filter),
659
+ );
592
660
  if (customizedOnly)
593
- comps = comps.filter((/** @type {any} */ c) => hasTagStyle(rootStyle, c.tagName));
661
+ comps = comps.filter((/** @type {ComponentEntry} */ c) => hasTagStyle(rootStyle, c.tagName));
594
662
  if (comps.length > 0) {
595
- const compCards = comps.map((/** @type {any} */ comp) => {
663
+ const compCards = comps.map((/** @type {ComponentEntry} */ comp) => {
596
664
  /** @type {HTMLDivElement | null} */
597
665
  let previewEl = null;
598
666
  const cardTpl = html`
@@ -648,22 +716,22 @@ export function renderStylebookElementsIntoCanvas(
648
716
  /**
649
717
  * Click handler for stylebook canvas — selects elements via elToPath/view.stylebookElToTag mapping
650
718
  *
651
- * @param {any} panel
719
+ * @param {StylebookPanel} panel
652
720
  */
653
721
  function registerStylebookPanelEvents(panel) {
654
722
  const { canvas, overlayClk } = panel;
655
723
 
656
- overlayClk.addEventListener("click", (/** @type {any} */ e) => {
724
+ overlayClk.addEventListener("click", (/** @type {MouseEvent} */ e) => {
657
725
  const els = canvas.querySelectorAll("*");
658
- for (const el of els) el.style.pointerEvents = "auto";
726
+ for (const el of els) /** @type {HTMLElement} */ (el).style.pointerEvents = "auto";
659
727
  overlayClk.style.display = "none";
660
728
  const elements = document.elementsFromPoint(e.clientX, e.clientY);
661
729
  overlayClk.style.display = "";
662
- for (const el of els) el.style.pointerEvents = "none";
730
+ for (const el of els) /** @type {HTMLElement} */ (el).style.pointerEvents = "none";
663
731
 
664
732
  for (const el of elements) {
665
733
  if (!canvas.contains(el) || el === canvas) continue;
666
- let cur = /** @type {any} */ (el);
734
+ let cur = /** @type {Element | null} */ (el);
667
735
  while (cur && cur !== canvas) {
668
736
  const tag = view.stylebookElToTag.get(cur);
669
737
  if (tag) {
@@ -679,18 +747,18 @@ function registerStylebookPanelEvents(panel) {
679
747
  renderStylebookOverlays();
680
748
  });
681
749
 
682
- overlayClk.addEventListener("mousemove", (/** @type {any} */ e) => {
750
+ overlayClk.addEventListener("mousemove", (/** @type {MouseEvent} */ e) => {
683
751
  const els = canvas.querySelectorAll("*");
684
- for (const el of els) el.style.pointerEvents = "auto";
752
+ for (const el of els) /** @type {HTMLElement} */ (el).style.pointerEvents = "auto";
685
753
  overlayClk.style.display = "none";
686
754
  const elements = document.elementsFromPoint(e.clientX, e.clientY);
687
755
  overlayClk.style.display = "";
688
- for (const el of els) el.style.pointerEvents = "none";
756
+ for (const el of els) /** @type {HTMLElement} */ (el).style.pointerEvents = "none";
689
757
 
690
758
  let hoverTag = null;
691
759
  for (const el of elements) {
692
760
  if (!canvas.contains(el) || el === canvas) continue;
693
- let cur = /** @type {any} */ (el);
761
+ let cur = /** @type {Element | null} */ (el);
694
762
  while (cur && cur !== canvas) {
695
763
  const tag = view.stylebookElToTag.get(cur);
696
764
  if (tag) {
@@ -710,9 +778,9 @@ function registerStylebookPanelEvents(panel) {
710
778
  }
711
779
 
712
780
  /** Find a stylebook element by tag in the canvas */
713
- function findStylebookEl(/** @type {any} */ canvasEl, /** @type {any} */ tag) {
781
+ function findStylebookEl(/** @type {HTMLElement} */ canvasEl, /** @type {string} */ tag) {
714
782
  for (const child of canvasEl.querySelectorAll("*")) {
715
- if (view.stylebookElToTag.get(child) === tag) return child;
783
+ if (view.stylebookElToTag.get(child) === tag) return /** @type {HTMLElement} */ (child);
716
784
  }
717
785
  return null;
718
786
  }