@jxsuite/studio 0.28.2 → 0.28.4

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 (104) hide show
  1. package/dist/studio.js +86144 -83971
  2. package/dist/studio.js.map +229 -219
  3. package/package.json +5 -5
  4. package/src/browse/browse-modal.ts +9 -3
  5. package/src/browse/browse.ts +139 -82
  6. package/src/canvas/canvas-diff.ts +35 -18
  7. package/src/canvas/canvas-helpers.ts +55 -21
  8. package/src/canvas/canvas-live-render.ts +140 -89
  9. package/src/canvas/canvas-render.ts +127 -82
  10. package/src/canvas/canvas-utils.ts +68 -42
  11. package/src/canvas/nested-site-style.ts +15 -7
  12. package/src/editor/component-inline-edit.ts +90 -51
  13. package/src/editor/content-inline-edit.ts +75 -72
  14. package/src/editor/context-menu.ts +125 -71
  15. package/src/editor/convert-targets.ts +17 -13
  16. package/src/editor/convert-to-component.ts +51 -28
  17. package/src/editor/convert-to-repeater.ts +44 -19
  18. package/src/editor/inline-edit.ts +107 -52
  19. package/src/editor/inline-format.ts +128 -60
  20. package/src/editor/insertion-helper.ts +26 -14
  21. package/src/editor/shortcuts.ts +89 -43
  22. package/src/editor/slash-menu.ts +41 -26
  23. package/src/files/components.ts +9 -7
  24. package/src/files/file-ops.ts +53 -33
  25. package/src/files/files.ts +246 -143
  26. package/src/format/constraints.ts +25 -15
  27. package/src/format/format-host.ts +33 -10
  28. package/src/github/github-auth.ts +24 -14
  29. package/src/github/github-publish.ts +20 -14
  30. package/src/new-project/new-project-modal.ts +27 -18
  31. package/src/panels/activity-bar.ts +27 -26
  32. package/src/panels/ai-panel.ts +100 -44
  33. package/src/panels/block-action-bar.ts +84 -52
  34. package/src/panels/canvas-dnd.ts +47 -28
  35. package/src/panels/data-explorer.ts +24 -11
  36. package/src/panels/dnd.ts +148 -100
  37. package/src/panels/editors.ts +54 -37
  38. package/src/panels/elements-panel.ts +23 -13
  39. package/src/panels/events-panel.ts +48 -38
  40. package/src/panels/git-panel.ts +95 -60
  41. package/src/panels/head-panel.ts +138 -84
  42. package/src/panels/imports-panel.ts +66 -29
  43. package/src/panels/layers-panel.ts +80 -36
  44. package/src/panels/left-panel.ts +86 -53
  45. package/src/panels/overlays.ts +36 -19
  46. package/src/panels/panel-events.ts +48 -27
  47. package/src/panels/panel-scheduler.ts +41 -23
  48. package/src/panels/preview-render.ts +26 -26
  49. package/src/panels/properties-panel.ts +155 -118
  50. package/src/panels/pseudo-preview.ts +31 -15
  51. package/src/panels/quick-search.ts +28 -13
  52. package/src/panels/right-panel.ts +35 -24
  53. package/src/panels/shared.ts +46 -29
  54. package/src/panels/signals-panel.ts +303 -186
  55. package/src/panels/statusbar.ts +27 -12
  56. package/src/panels/style-inputs.ts +30 -24
  57. package/src/panels/style-panel.ts +130 -90
  58. package/src/panels/style-utils.ts +63 -23
  59. package/src/panels/stylebook-layers-panel.ts +27 -30
  60. package/src/panels/stylebook-panel.ts +140 -72
  61. package/src/panels/tab-strip.ts +21 -10
  62. package/src/panels/toolbar.ts +52 -40
  63. package/src/panels/welcome-screen.ts +1 -1
  64. package/src/platform.ts +2 -1
  65. package/src/platforms/devserver.ts +221 -105
  66. package/src/recent-projects.ts +15 -7
  67. package/src/resize-edges.ts +7 -5
  68. package/src/services/cem-export.ts +73 -57
  69. package/src/services/code-services.ts +52 -25
  70. package/src/services/monaco-setup.ts +5 -5
  71. package/src/settings/content-types-editor.ts +133 -62
  72. package/src/settings/css-vars-editor.ts +31 -14
  73. package/src/settings/defs-editor.ts +125 -63
  74. package/src/settings/general-settings.ts +11 -6
  75. package/src/settings/head-editor.ts +30 -15
  76. package/src/settings/schema-field-ui.ts +75 -35
  77. package/src/settings/settings-modal.ts +35 -17
  78. package/src/site-context.ts +80 -47
  79. package/src/state.ts +98 -65
  80. package/src/store.ts +42 -23
  81. package/src/studio.ts +165 -144
  82. package/src/tabs/tab.ts +51 -45
  83. package/src/tabs/transact.ts +230 -109
  84. package/src/types.ts +60 -51
  85. package/src/ui/button-group.ts +3 -2
  86. package/src/ui/color-selector.ts +33 -15
  87. package/src/ui/expression-editor.ts +139 -86
  88. package/src/ui/field-input.ts +35 -18
  89. package/src/ui/field-row.ts +1 -1
  90. package/src/ui/icons.ts +5 -6
  91. package/src/ui/layers.ts +33 -26
  92. package/src/ui/media-picker.ts +13 -7
  93. package/src/ui/panel-resize.ts +39 -20
  94. package/src/ui/spectrum.ts +4 -2
  95. package/src/ui/unit-selector.ts +20 -11
  96. package/src/ui/value-selector.ts +13 -7
  97. package/src/ui/widgets.ts +34 -18
  98. package/src/utils/canvas-media.ts +66 -33
  99. package/src/utils/edit-display.ts +43 -44
  100. package/src/utils/google-fonts.ts +10 -6
  101. package/src/utils/inherited-style.ts +22 -8
  102. package/src/utils/studio-utils.ts +88 -45
  103. package/src/view.ts +9 -5
  104. package/src/workspace/workspace.ts +49 -29
@@ -8,6 +8,8 @@ import { componentRegistry } from "../files/components";
8
8
 
9
9
  import type { StylebookEntry } from "./stylebook-panel";
10
10
  import type { JxStyle } from "@jxsuite/schema/types";
11
+ import type { TemplateResult } from "lit-html";
12
+ import type { ComponentEntry } from "../files/components.js";
11
13
 
12
14
  /**
13
15
  * @param {JxStyle} rootStyle
@@ -45,12 +47,8 @@ export function renderStylebookLayersTemplate(ctx: {
45
47
  * @param {string} parentPath
46
48
  * @returns {import("lit-html").TemplateResult}
47
49
  */
48
- const renderEntryRow = (
49
- entry: StylebookEntry,
50
- depth: number = 0,
51
- parentPath: string = "",
52
- ): import("lit-html").TemplateResult => {
53
- const tag = entry.tag;
50
+ const renderEntryRow = (entry: StylebookEntry, depth = 0, parentPath = ""): TemplateResult => {
51
+ const { tag } = entry;
54
52
  const fullPath = parentPath ? `${parentPath} ${tag}` : tag;
55
53
  const uniqueChildren = entry.children
56
54
  ? [...new Map(entry.children.map((c: StylebookEntry) => [c.tag, c])).values()]
@@ -83,7 +81,7 @@ export function renderStylebookLayersTemplate(ctx: {
83
81
  `;
84
82
  };
85
83
 
86
- const elementRows: import("lit-html").TemplateResult[] = [];
84
+ const elementRows: TemplateResult[] = [];
87
85
  for (const section of ctx.stylebookMeta.$sections) {
88
86
  for (const entry of section.elements) {
89
87
  elementRows.push(renderEntryRow(entry, 0));
@@ -91,7 +89,7 @@ export function renderStylebookLayersTemplate(ctx: {
91
89
  }
92
90
  const compRows = componentRegistry.map(
93
91
  /** @param {import("../files/components.js").ComponentEntry} comp */ (
94
- comp: import("../files/components.js").ComponentEntry,
92
+ comp: ComponentEntry,
95
93
  ) => html`
96
94
  <div
97
95
  class=${classMap({
@@ -109,27 +107,26 @@ export function renderStylebookLayersTemplate(ctx: {
109
107
  `,
110
108
  );
111
109
  return html`${elementRows}${compRows}`;
112
- } else {
113
- const style = rootStyle;
114
- const vars = Object.entries(style).filter(([k]) => k.startsWith("--"));
115
- if (vars.length === 0) {
116
- return html`<div style="padding:16px;text-align:center;color:var(--fg-dim);font-size:12px">
117
- No variables defined
118
- </div>`;
119
- }
120
- return html`${vars.map(
121
- ([k, v]) => html`
122
- <div class="layer-row">
123
- <span class="layer-tag" style="font-size:10px;font-family:'SF Mono','Fira Code',monospace"
124
- >var</span
125
- >
126
- <span class="layer-label">${k}</span>
127
- <span
128
- style="font-size:11px;color:var(--fg-dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:80px"
129
- >${String(v)}</span
130
- >
131
- </div>
132
- `,
133
- )}`;
134
110
  }
111
+ const style = rootStyle;
112
+ const vars = Object.entries(style).filter(([k]) => k.startsWith("--"));
113
+ if (vars.length === 0) {
114
+ return html`<div style="padding:16px;text-align:center;color:var(--fg-dim);font-size:12px">
115
+ No variables defined
116
+ </div>`;
117
+ }
118
+ return html`${vars.map(
119
+ ([k, v]) => html`
120
+ <div class="layer-row">
121
+ <span class="layer-tag" style="font-size:10px;font-family:'SF Mono','Fira Code',monospace"
122
+ >var</span
123
+ >
124
+ <span class="layer-label">${k}</span>
125
+ <span
126
+ style="font-size:11px;color:var(--fg-dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:80px"
127
+ >${String(v)}</span
128
+ >
129
+ </div>
130
+ `,
131
+ )}`;
135
132
  }
@@ -12,22 +12,25 @@ import { styleMap } from "lit-html/directives/style-map.js";
12
12
  import { live } from "lit-html/directives/live.js";
13
13
 
14
14
  import {
15
- updateSession,
16
- updateUi,
17
- canvasWrap,
18
15
  canvasPanels,
16
+ canvasWrap,
19
17
  elToPath,
20
18
  projectState,
19
+ updateSession,
20
+ updateUi,
21
21
  } from "../store";
22
22
  import { activeTab } from "../workspace/workspace";
23
23
  import { view } from "../view";
24
24
  import { defineElement, setSkipServerFunctions } from "@jxsuite/runtime";
25
25
  import { componentRegistry } from "../files/components";
26
- import { getEffectiveStyle, getEffectiveMedia } from "../site-context";
27
- import { parseMediaEntries, activeBreakpointsForWidth } from "../utils/canvas-media";
26
+ import type { ComponentEntry } from "../files/components";
27
+ import { getEffectiveMedia, getEffectiveStyle } from "../site-context";
28
+ import { activeBreakpointsForWidth, parseMediaEntries } from "../utils/canvas-media";
28
29
  import { mediaDisplayName } from "./shared";
29
30
  import { panToCanvasEl } from "../canvas/canvas-utils";
30
31
  import stylebookMeta from "../../data/stylebook-meta.json";
32
+ import type { TemplateResult } from "lit-html";
33
+ import type { CanvasPanel } from "../types";
31
34
 
32
35
  export interface StylebookEntry {
33
36
  tag: string;
@@ -56,7 +59,7 @@ interface StylebookCtx {
56
59
  label: string | null,
57
60
  fullWidth: boolean,
58
61
  width?: number | null,
59
- ) => { tpl: import("lit-html").TemplateResult; panel: any };
62
+ ) => { tpl: TemplateResult; panel: CanvasPanel };
60
63
  applyTransform: () => void;
61
64
  observeCenterUntilStable: () => void;
62
65
  renderZoomIndicator: () => void;
@@ -64,7 +67,7 @@ interface StylebookCtx {
64
67
  overlayBoxDescriptor: (
65
68
  el: Element,
66
69
  type: string,
67
- panel: any,
70
+ panel: CanvasPanel,
68
71
  ) => {
69
72
  cls: string;
70
73
  top: string;
@@ -75,13 +78,6 @@ interface StylebookCtx {
75
78
  effectiveZoom: () => number;
76
79
  }
77
80
 
78
- interface ComponentEntry {
79
- source?: string;
80
- tagName: string;
81
- path?: string;
82
- props?: Array<{ name: string; default?: string }>;
83
- }
84
-
85
81
  export { stylebookMeta };
86
82
 
87
83
  /**
@@ -95,7 +91,9 @@ function _resolveNestedStyle(style: Record<string, unknown>, tagPath: string) {
95
91
  const parts = tagPath.split(" ");
96
92
  let obj = style;
97
93
  for (const part of parts) {
98
- if (!obj || typeof obj !== "object") return null;
94
+ if (!obj || typeof obj !== "object") {
95
+ return null;
96
+ }
99
97
  obj = obj[part] as Record<string, unknown>;
100
98
  }
101
99
  return obj && typeof obj === "object" ? (obj as Record<string, unknown>) : null;
@@ -154,8 +152,8 @@ export function renderStylebookMode(ctx: StylebookCtx) {
154
152
  />
155
153
  <button
156
154
  class=${classMap({
155
+ active: Boolean(tab?.session.ui.stylebookCustomizedOnly),
157
156
  "tb-toggle": true,
158
- active: !!tab?.session.ui.stylebookCustomizedOnly,
159
157
  })}
160
158
  @click=${onCustomizedToggle}
161
159
  >
@@ -171,17 +169,17 @@ export function renderStylebookMode(ctx: StylebookCtx) {
171
169
  const allPanelDefs = [];
172
170
  if (hasMedia) {
173
171
  allPanelDefs.push({
174
- name: "base",
172
+ activeSet: activeBreakpointsForWidth(sizeBreakpoints, baseWidth),
175
173
  displayName: mediaDisplayName("--"),
174
+ name: "base",
176
175
  width: baseWidth,
177
- activeSet: activeBreakpointsForWidth(sizeBreakpoints, baseWidth),
178
176
  });
179
177
  for (const bp of sizeBreakpoints) {
180
178
  allPanelDefs.push({
181
- name: bp.name,
179
+ activeSet: activeBreakpointsForWidth(sizeBreakpoints, bp.width),
182
180
  displayName: mediaDisplayName(bp.name),
181
+ name: bp.name,
183
182
  width: bp.width,
184
- activeSet: activeBreakpointsForWidth(sizeBreakpoints, bp.width),
185
183
  });
186
184
  }
187
185
  }
@@ -219,12 +217,12 @@ export function renderStylebookMode(ctx: StylebookCtx) {
219
217
  !hasBaseWidth,
220
218
  hasBaseWidth ? baseWidth : undefined,
221
219
  );
222
- panelEntries = [{ tpl: entry.tpl, panel: entry.panel, activeSet: new Set<string>() }];
220
+ panelEntries = [{ activeSet: new Set<string>(), panel: entry.panel, tpl: entry.tpl }];
223
221
  } else {
224
222
  panelEntries = allPanelDefs.map((def) => {
225
223
  const label = `${def.displayName} (${def.width}px)`;
226
224
  const { tpl, panel } = ctx.canvasPanelTemplate(def.name, label, false, def.width);
227
- return { tpl, panel, activeSet: def.activeSet };
225
+ return { activeSet: def.activeSet, panel, tpl };
228
226
  });
229
227
  }
230
228
 
@@ -235,7 +233,9 @@ export function renderStylebookMode(ctx: StylebookCtx) {
235
233
  class="panzoom-wrap"
236
234
  style="transform-origin:0 0;padding-top:40px"
237
235
  ${ref((el) => {
238
- if (el) view.panzoomWrap = el as HTMLDivElement;
236
+ if (el) {
237
+ view.panzoomWrap = el as HTMLDivElement;
238
+ }
239
239
  })}
240
240
  >
241
241
  ${panelEntries.map((e) => e.tpl)}
@@ -260,7 +260,9 @@ export function renderStylebookMode(ctx: StylebookCtx) {
260
260
  /** Fast-path: re-apply styles to existing stylebook elements without rebuilding the DOM. */
261
261
  export function refreshStylebookStyles() {
262
262
  const tab = activeTab.value;
263
- if (!tab) return;
263
+ if (!tab) {
264
+ return;
265
+ }
264
266
  const rootStyle = getEffectiveStyle(tab.doc.document?.style);
265
267
 
266
268
  for (const panel of canvasPanels) {
@@ -281,11 +283,13 @@ export function refreshStylebookStyles() {
281
283
  const allEls = canvas.querySelectorAll("*");
282
284
  for (const el of allEls) {
283
285
  const tag = view.stylebookElToTag.get(el);
284
- if (!tag) continue;
286
+ if (!tag) {
287
+ continue;
288
+ }
285
289
  const htmlEl = el as HTMLElement;
286
290
  // Determine if it's a compound selector (e.g. "ul li") or simple tag
287
291
  const parts = tag.split(" ");
288
- const leafTag = parts[parts.length - 1];
292
+ const leafTag = parts.at(-1);
289
293
  const entry = _entryByTag.get(leafTag);
290
294
 
291
295
  // Reset to base style
@@ -304,9 +308,13 @@ export function refreshStylebookStyles() {
304
308
  // Media overrides nested in tag style
305
309
  if (activeBreakpoints.size > 0) {
306
310
  for (const [key, val] of Object.entries(tagStyle)) {
307
- if (!key.startsWith("@") || typeof val !== "object" || val === null) continue;
311
+ if (!key.startsWith("@") || typeof val !== "object" || val === null) {
312
+ continue;
313
+ }
308
314
  const mediaName = key.slice(1);
309
- if (mediaName === "--") continue;
315
+ if (mediaName === "--") {
316
+ continue;
317
+ }
310
318
  if (activeBreakpoints.has(mediaName)) {
311
319
  for (const [prop, v] of Object.entries(val as Record<string, unknown>)) {
312
320
  if (typeof v === "string" || typeof v === "number") {
@@ -322,9 +330,13 @@ export function refreshStylebookStyles() {
322
330
  // Top-level @media keys
323
331
  if (activeBreakpoints.size > 0) {
324
332
  for (const [key, val] of Object.entries(rootStyle)) {
325
- if (!key.startsWith("@") || typeof val !== "object" || val === null) continue;
333
+ if (!key.startsWith("@") || typeof val !== "object" || val === null) {
334
+ continue;
335
+ }
326
336
  const mediaName = key.slice(1);
327
- if (mediaName === "--") continue;
337
+ if (mediaName === "--") {
338
+ continue;
339
+ }
328
340
  if (activeBreakpoints.has(mediaName)) {
329
341
  const mediaTagStyle = _resolveNestedStyle(
330
342
  /** @type {Record<string, unknown>} */ val,
@@ -358,9 +370,9 @@ export function selectStylebookTag(tag: string, media?: string | null, { panCanv
358
370
  updateSession({
359
371
  selection: [],
360
372
  ui: {
361
- stylebookSelection: tag,
362
- rightTab: "style",
363
373
  activeSelector: tag,
374
+ rightTab: "style",
375
+ stylebookSelection: tag,
364
376
  ...(media !== undefined ? { activeMedia: media } : {}),
365
377
  },
366
378
  });
@@ -368,14 +380,20 @@ export function selectStylebookTag(tag: string, media?: string | null, { panCanv
368
380
 
369
381
  if (tag && panCanvas && canvasPanels.length > 0) {
370
382
  const el = findStylebookEl(canvasPanels[0].canvas, tag);
371
- if (el) panToCanvasEl(el);
383
+ if (el) {
384
+ panToCanvasEl(el);
385
+ }
372
386
  }
373
387
  }
374
388
 
375
389
  /** Draw selection + hover overlays for stylebook elements */
376
390
  export function renderStylebookOverlays() {
377
- if (!_ctx) return;
378
- if (canvasPanels.length === 0) return;
391
+ if (!_ctx) {
392
+ return;
393
+ }
394
+ if (canvasPanels.length === 0) {
395
+ return;
396
+ }
379
397
 
380
398
  const selectedTag = activeTab.value?.session.ui.stylebookSelection;
381
399
 
@@ -395,20 +413,22 @@ export function renderStylebookOverlays() {
395
413
 
396
414
  if (hoverTag && hoverTag !== selectedTag) {
397
415
  const el = findStylebookEl(panel.canvas, hoverTag);
398
- if (el)
416
+ if (el) {
399
417
  boxes.push({
400
418
  ..._ctx.overlayBoxDescriptor(el, "hover", panel),
401
419
  label: undefined,
402
420
  });
421
+ }
403
422
  }
404
423
 
405
424
  if (selectedTag) {
406
425
  const el = findStylebookEl(panel.canvas, selectedTag);
407
- if (el)
426
+ if (el) {
408
427
  boxes.push({
409
428
  ..._ctx.overlayBoxDescriptor(el, "selection", panel),
410
429
  label: `<${selectedTag}>`,
411
430
  });
431
+ }
412
432
  }
413
433
 
414
434
  litRender(
@@ -419,10 +439,10 @@ export function renderStylebookOverlays() {
419
439
  <div
420
440
  class=${b.cls}
421
441
  style=${styleMap({
422
- top: b.top,
442
+ height: b.height,
423
443
  left: b.left,
444
+ top: b.top,
424
445
  width: b.width,
425
- height: b.height,
426
446
  })}
427
447
  >
428
448
  ${b.label ? html`<div class="overlay-label">${b.label}</div>` : nothing}
@@ -452,7 +472,9 @@ export function buildStylebookElement(
452
472
  parentTag: string | null = null,
453
473
  ) {
454
474
  const el = document.createElement(entry.tag);
455
- if (entry.text) el.textContent = entry.text;
475
+ if (entry.text) {
476
+ el.textContent = entry.text;
477
+ }
456
478
  if (entry.attributes) {
457
479
  for (const [k, v] of Object.entries(entry.attributes)) {
458
480
  try {
@@ -460,7 +482,9 @@ export function buildStylebookElement(
460
482
  } catch {}
461
483
  }
462
484
  }
463
- if (entry.style) el.style.cssText = entry.style;
485
+ if (entry.style) {
486
+ el.style.cssText = entry.style;
487
+ }
464
488
  const compoundTag = parentTag && parentTag !== entry.tag ? `${parentTag} ${entry.tag}` : null;
465
489
  const tagStyle =
466
490
  (compoundTag && _resolveNestedStyle(rootStyle, compoundTag)) ||
@@ -476,9 +500,13 @@ export function buildStylebookElement(
476
500
  if (activeBreakpoints) {
477
501
  // Check media overrides nested inside the tag style (selector wraps media)
478
502
  for (const [key, val] of Object.entries(tagStyle)) {
479
- if (!key.startsWith("@") || typeof val !== "object" || val === null) continue;
503
+ if (!key.startsWith("@") || typeof val !== "object" || val === null) {
504
+ continue;
505
+ }
480
506
  const mediaName = key.slice(1);
481
- if (mediaName === "--") continue;
507
+ if (mediaName === "--") {
508
+ continue;
509
+ }
482
510
  if (activeBreakpoints.has(mediaName)) {
483
511
  for (const [prop, v] of Object.entries(val as Record<string, unknown>)) {
484
512
  if (typeof v === "string" || typeof v === "number") {
@@ -495,9 +523,13 @@ export function buildStylebookElement(
495
523
  if (activeBreakpoints) {
496
524
  const tagPath = compoundTag || entry.tag;
497
525
  for (const [key, val] of Object.entries(rootStyle)) {
498
- if (!key.startsWith("@") || typeof val !== "object" || val === null) continue;
526
+ if (!key.startsWith("@") || typeof val !== "object" || val === null) {
527
+ continue;
528
+ }
499
529
  const mediaName = key.slice(1);
500
- if (mediaName === "--") continue;
530
+ if (mediaName === "--") {
531
+ continue;
532
+ }
501
533
  if (activeBreakpoints.has(mediaName)) {
502
534
  const mediaTagStyle = _resolveNestedStyle(val as Record<string, unknown>, tagPath);
503
535
  if (mediaTagStyle && typeof mediaTagStyle === "object") {
@@ -514,7 +546,7 @@ export function buildStylebookElement(
514
546
  }
515
547
  if (entry.children) {
516
548
  for (const child of entry.children) {
517
- el.appendChild(buildStylebookElement(child, rootStyle, activeBreakpoints, entry.tag));
549
+ el.append(buildStylebookElement(child, rootStyle, activeBreakpoints, entry.tag));
518
550
  }
519
551
  }
520
552
  return el;
@@ -539,19 +571,19 @@ export async function renderComponentPreview(comp: ComponentEntry) {
539
571
  return _componentFallback(comp.tagName);
540
572
  }
541
573
  const root = projectState?.projectRoot;
542
- const url = `${location.origin}/${root ? root + "/" : ""}${comp.path}`;
574
+ const url = `${location.origin}/${root ? `${root}/` : ""}${comp.path}`;
543
575
  await defineElement(url);
544
576
  }
545
577
  const el = document.createElement(comp.tagName);
546
578
  for (const p of comp.props || []) {
547
579
  if (p.default !== undefined && p.default !== "false" && p.default !== "''") {
548
- const val = String(p.default).replace(/^'|'$/g, "");
580
+ const val = String(p.default).replaceAll(/^'|'$/g, "");
549
581
  el.setAttribute(p.name, val);
550
582
  }
551
583
  }
552
584
  return el;
553
- } catch (e) {
554
- console.warn("Component preview failed:", comp.tagName, e);
585
+ } catch (error) {
586
+ console.warn("Component preview failed:", comp.tagName, error);
555
587
  return _componentFallback(comp.tagName);
556
588
  }
557
589
  }
@@ -571,11 +603,17 @@ function _componentFallback(tagName: string) {
571
603
  */
572
604
  function hasTagStyle(rootStyle: Record<string, unknown>, tag: string) {
573
605
  const s = _resolveNestedStyle(rootStyle, tag);
574
- if (s && typeof s === "object" && Object.keys(s).length > 0) return true;
606
+ if (s && typeof s === "object" && Object.keys(s).length > 0) {
607
+ return true;
608
+ }
575
609
  for (const [key, val] of Object.entries(rootStyle)) {
576
- if (!key.startsWith("@") || typeof val !== "object" || val === null) continue;
610
+ if (!key.startsWith("@") || typeof val !== "object" || val === null) {
611
+ continue;
612
+ }
577
613
  const ms = _resolveNestedStyle(val as Record<string, unknown>, tag);
578
- if (ms && typeof ms === "object" && Object.keys(ms).length > 0) return true;
614
+ if (ms && typeof ms === "object" && Object.keys(ms).length > 0) {
615
+ return true;
616
+ }
579
617
  }
580
618
  return false;
581
619
  }
@@ -600,7 +638,7 @@ export function renderStylebookElementsIntoCanvas(
600
638
  }
601
639
  }
602
640
 
603
- const sectionTemplates: import("lit-html").TemplateResult[] = [];
641
+ const sectionTemplates: TemplateResult[] = [];
604
642
 
605
643
  for (const section of stylebookMeta.$sections) {
606
644
  let entries = section.elements as StylebookEntry[];
@@ -613,7 +651,9 @@ export function renderStylebookElementsIntoCanvas(
613
651
  if (customizedOnly) {
614
652
  entries = entries.filter((e: StylebookEntry) => hasTagStyle(rootStyle, e.tag));
615
653
  }
616
- if (entries.length === 0) continue;
654
+ if (entries.length === 0) {
655
+ continue;
656
+ }
617
657
 
618
658
  const cardTemplates = entries.map((entry: StylebookEntry) => {
619
659
  const el = buildStylebookElement(entry, rootStyle, activeBreakpoints);
@@ -621,7 +661,9 @@ export function renderStylebookElementsIntoCanvas(
621
661
  <div
622
662
  class="element-card"
623
663
  ${ref((card) => {
624
- if (!card) return;
664
+ if (!card) {
665
+ return;
666
+ }
625
667
  view.stylebookElToTag.set(card, entry.tag);
626
668
  elToPath.set(card, ["__sb", entry.tag]);
627
669
  for (const child of el.querySelectorAll("*")) {
@@ -639,7 +681,7 @@ export function renderStylebookElementsIntoCanvas(
639
681
  ${ref((c) => {
640
682
  if (c) {
641
683
  c.textContent = "";
642
- c.appendChild(el);
684
+ c.append(el);
643
685
  }
644
686
  })}
645
687
  ></div>
@@ -659,10 +701,12 @@ export function renderStylebookElementsIntoCanvas(
659
701
  // Custom components from registry
660
702
  if (componentRegistry.length > 0) {
661
703
  let comps = componentRegistry;
662
- if (filter)
704
+ if (filter) {
663
705
  comps = comps.filter((c: ComponentEntry) => c.tagName.toLowerCase().includes(filter));
664
- if (customizedOnly)
706
+ }
707
+ if (customizedOnly) {
665
708
  comps = comps.filter((c: ComponentEntry) => hasTagStyle(rootStyle, c.tagName));
709
+ }
666
710
  if (comps.length > 0) {
667
711
  const compCards = comps.map((comp: ComponentEntry) => {
668
712
  let previewEl: HTMLDivElement | null = null;
@@ -671,7 +715,9 @@ export function renderStylebookElementsIntoCanvas(
671
715
  class="element-card"
672
716
  style="display:inline-flex;width:auto"
673
717
  ${ref((card) => {
674
- if (!card) return;
718
+ if (!card) {
719
+ return;
720
+ }
675
721
  view.stylebookElToTag.set(card, comp.tagName);
676
722
  elToPath.set(card, ["__sb", comp.tagName]);
677
723
  })}
@@ -679,7 +725,9 @@ export function renderStylebookElementsIntoCanvas(
679
725
  <div
680
726
  class="element-card-preview"
681
727
  ${ref((c) => {
682
- if (c) previewEl = c as HTMLDivElement;
728
+ if (c) {
729
+ previewEl = c as HTMLDivElement;
730
+ }
683
731
  })}
684
732
  ></div>
685
733
  <div class="element-card-label">&lt;${comp.tagName}&gt;</div>
@@ -687,7 +735,9 @@ export function renderStylebookElementsIntoCanvas(
687
735
  `;
688
736
  renderComponentPreview(comp)
689
737
  .then((el) => {
690
- if (previewEl) previewEl.appendChild(el);
738
+ if (previewEl) {
739
+ previewEl.append(el);
740
+ }
691
741
  })
692
742
  .catch(() => {});
693
743
  return cardTpl;
@@ -726,41 +776,55 @@ function registerStylebookPanelEvents(panel: StylebookPanel) {
726
776
 
727
777
  overlayClk.addEventListener("click", (e: MouseEvent) => {
728
778
  const els = canvas.querySelectorAll("*");
729
- for (const el of els) (el as HTMLElement).style.pointerEvents = "auto";
779
+ for (const el of els) {
780
+ (el as HTMLElement).style.pointerEvents = "auto";
781
+ }
730
782
  overlayClk.style.display = "none";
731
783
  const elements = document.elementsFromPoint(e.clientX, e.clientY);
732
784
  overlayClk.style.display = "";
733
- for (const el of els) (el as HTMLElement).style.pointerEvents = "none";
785
+ for (const el of els) {
786
+ (el as HTMLElement).style.pointerEvents = "none";
787
+ }
734
788
 
735
789
  for (const el of elements) {
736
- if (!canvas.contains(el) || el === canvas) continue;
790
+ if (!canvas.contains(el) || el === canvas) {
791
+ continue;
792
+ }
737
793
  let cur = el as Element | null;
738
794
  while (cur && cur !== canvas) {
739
795
  const tag = view.stylebookElToTag.get(cur);
740
796
  if (tag) {
741
797
  const newMedia = panel.mediaName === "base" ? null : (panel.mediaName ?? null);
742
798
  selectStylebookTag(tag, newMedia);
743
- if (_ctx) _ctx.updateActivePanelHeaders();
799
+ if (_ctx) {
800
+ _ctx.updateActivePanelHeaders();
801
+ }
744
802
  return;
745
803
  }
746
804
  cur = cur.parentElement;
747
805
  }
748
806
  }
749
- updateSession({ ui: { stylebookSelection: null, activeSelector: null } });
807
+ updateSession({ ui: { activeSelector: null, stylebookSelection: null } });
750
808
  renderStylebookOverlays();
751
809
  });
752
810
 
753
811
  overlayClk.addEventListener("mousemove", (e: MouseEvent) => {
754
812
  const els = canvas.querySelectorAll("*");
755
- for (const el of els) (el as HTMLElement).style.pointerEvents = "auto";
813
+ for (const el of els) {
814
+ (el as HTMLElement).style.pointerEvents = "auto";
815
+ }
756
816
  overlayClk.style.display = "none";
757
817
  const elements = document.elementsFromPoint(e.clientX, e.clientY);
758
818
  overlayClk.style.display = "";
759
- for (const el of els) (el as HTMLElement).style.pointerEvents = "none";
819
+ for (const el of els) {
820
+ (el as HTMLElement).style.pointerEvents = "none";
821
+ }
760
822
 
761
823
  let hoverTag = null;
762
824
  for (const el of elements) {
763
- if (!canvas.contains(el) || el === canvas) continue;
825
+ if (!canvas.contains(el) || el === canvas) {
826
+ continue;
827
+ }
764
828
  let cur = el as Element | null;
765
829
  while (cur && cur !== canvas) {
766
830
  const tag = view.stylebookElToTag.get(cur);
@@ -770,7 +834,9 @@ function registerStylebookPanelEvents(panel: StylebookPanel) {
770
834
  }
771
835
  cur = cur.parentElement;
772
836
  }
773
- if (hoverTag) break;
837
+ if (hoverTag) {
838
+ break;
839
+ }
774
840
  }
775
841
 
776
842
  if (hoverTag !== panel._lastHoverTag) {
@@ -783,7 +849,9 @@ function registerStylebookPanelEvents(panel: StylebookPanel) {
783
849
  /** Find a stylebook element by tag in the canvas */
784
850
  function findStylebookEl(canvasEl: HTMLElement, tag: string) {
785
851
  for (const child of canvasEl.querySelectorAll("*")) {
786
- if (view.stylebookElToTag.get(child) === tag) return child as HTMLElement;
852
+ if (view.stylebookElToTag.get(child) === tag) {
853
+ return child as HTMLElement;
854
+ }
787
855
  }
788
856
  return null;
789
857
  }