@jxsuite/studio 0.32.0 → 0.34.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 (94) hide show
  1. package/dist/iframe-entry.js +6230 -0
  2. package/dist/iframe-entry.js.map +35 -0
  3. package/dist/studio.js +22791 -13709
  4. package/dist/studio.js.map +181 -74
  5. package/package.json +12 -7
  6. package/src/browse/browse.ts +11 -4
  7. package/src/canvas/canvas-helpers.ts +2 -56
  8. package/src/canvas/canvas-live-render.ts +102 -435
  9. package/src/canvas/canvas-origin.ts +66 -0
  10. package/src/canvas/canvas-patcher.ts +63 -403
  11. package/src/canvas/canvas-render.ts +70 -212
  12. package/src/canvas/canvas-utils.ts +37 -65
  13. package/src/canvas/iframe-channel.ts +154 -0
  14. package/src/canvas/iframe-drop.ts +484 -0
  15. package/src/canvas/iframe-entry.ts +600 -0
  16. package/src/canvas/iframe-host.ts +1373 -0
  17. package/src/canvas/iframe-inline-edit.ts +367 -0
  18. package/src/canvas/iframe-insert.ts +164 -0
  19. package/src/canvas/iframe-interaction.ts +176 -0
  20. package/src/canvas/iframe-keys.ts +85 -0
  21. package/src/canvas/iframe-overlay.ts +218 -0
  22. package/src/canvas/iframe-patch.ts +363 -0
  23. package/src/canvas/iframe-protocol.ts +361 -0
  24. package/src/canvas/iframe-render.ts +458 -0
  25. package/src/canvas/iframe-slash.ts +114 -0
  26. package/src/canvas/iframe-subtree.ts +113 -0
  27. package/src/canvas/path-mapping.ts +86 -0
  28. package/src/canvas/serialize-scope.ts +65 -0
  29. package/src/editor/canvas-context-menu.ts +40 -0
  30. package/src/editor/canvas-slash-bridge.ts +21 -0
  31. package/src/editor/context-menu.ts +2 -1
  32. package/src/editor/inline-edit-apply.ts +183 -0
  33. package/src/editor/inline-edit.ts +99 -21
  34. package/src/editor/inline-link.ts +89 -0
  35. package/src/editor/insert-zone-action.ts +35 -0
  36. package/src/editor/merge-tags.ts +26 -2
  37. package/src/editor/repeater-scope.ts +144 -0
  38. package/src/editor/shortcuts.ts +14 -28
  39. package/src/editor/slash-menu.ts +73 -42
  40. package/src/files/files.ts +2 -1
  41. package/src/page-params.ts +383 -0
  42. package/src/panels/ai-panel.ts +386 -328
  43. package/src/panels/block-action-bar.ts +296 -138
  44. package/src/panels/canvas-dnd-bridge.ts +397 -0
  45. package/src/panels/component-preview.ts +56 -0
  46. package/src/panels/dnd.ts +41 -17
  47. package/src/panels/drag-ghost.ts +62 -0
  48. package/src/panels/editors.ts +1 -1
  49. package/src/panels/overlays.ts +10 -125
  50. package/src/panels/properties-panel.ts +210 -0
  51. package/src/panels/right-panel.ts +0 -2
  52. package/src/panels/signals-panel.ts +136 -22
  53. package/src/panels/stylebook-doc.ts +373 -0
  54. package/src/panels/stylebook-panel.ts +46 -689
  55. package/src/panels/tab-bar.ts +159 -13
  56. package/src/panels/toolbar.ts +3 -2
  57. package/src/platforms/devserver.ts +18 -47
  58. package/src/services/ai-settings.ts +107 -0
  59. package/src/services/ai-system-prompt.ts +617 -0
  60. package/src/services/ai-tools.ts +854 -0
  61. package/src/services/context-manager.ts +200 -0
  62. package/src/services/document-assistant.ts +183 -0
  63. package/src/services/jx-validate.ts +65 -0
  64. package/src/services/monaco-setup.ts +12 -0
  65. package/src/services/render-critic.ts +75 -0
  66. package/src/services/token-lint.ts +140 -0
  67. package/src/services/tool-executor.ts +156 -0
  68. package/src/settings/css-vars-editor.ts +2 -2
  69. package/src/state.ts +29 -0
  70. package/src/store.ts +4 -62
  71. package/src/studio.ts +90 -40
  72. package/src/tabs/doc-op-apply.ts +89 -0
  73. package/src/tabs/patch-ops.ts +6 -2
  74. package/src/tabs/tab.ts +23 -4
  75. package/src/tabs/transact.ts +33 -69
  76. package/src/types.ts +16 -24
  77. package/src/ui/jx-theme.ts +63 -0
  78. package/src/ui/media-picker.ts +6 -4
  79. package/src/ui/spectrum.ts +5 -0
  80. package/src/utils/canvas-media.ts +0 -137
  81. package/src/utils/edit-display.ts +23 -3
  82. package/src/utils/geometry.ts +43 -0
  83. package/src/utils/link-target.ts +93 -0
  84. package/src/utils/strip-events.ts +54 -0
  85. package/src/view.ts +0 -23
  86. package/src/workspace/workspace.ts +14 -1
  87. package/src/canvas/canvas-subtree-render.ts +0 -113
  88. package/src/editor/component-inline-edit.ts +0 -349
  89. package/src/editor/content-inline-edit.ts +0 -207
  90. package/src/editor/insertion-helper.ts +0 -308
  91. package/src/panels/canvas-dnd.ts +0 -329
  92. package/src/panels/panel-events.ts +0 -306
  93. package/src/panels/preview-render.ts +0 -132
  94. package/src/panels/pseudo-preview.ts +0 -75
@@ -1,132 +0,0 @@
1
- /// <reference lib="dom" />
2
- /**
3
- * Preview render — extracted from studio.js (Phase 4m). Structural preview renderer that creates
4
- * DOM from Jx node trees as a fallback when runtime rendering fails.
5
- */
6
-
7
- import { elToPath } from "../store";
8
- import { isMappedArray, isRef } from "@jxsuite/schema/guards";
9
- import { activeTab } from "../workspace/workspace";
10
- import { applyCanvasStyle } from "../utils/canvas-media";
11
- import { resolveDefaultForCanvas } from "../panels/signals-panel";
12
- import type { JxPath } from "../state";
13
- import type { JxMutableNode } from "@jxsuite/schema/types";
14
-
15
- /**
16
- * Recursively render a Jx node to the canvas DOM. Media-aware: applies base styles + active
17
- * breakpoint/feature overrides.
18
- *
19
- * @param {JxMutableNode | string | number | boolean | null | undefined} node
20
- * @param {JxPath} path
21
- * @param {HTMLElement} parent
22
- * @param {Set<string>} activeBreakpoints
23
- * @param {Record<string, boolean>} featureToggles
24
- */
25
- export function renderCanvasNode(
26
- node: JxMutableNode | string | number | boolean | null | undefined,
27
- path: JxPath,
28
- parent: HTMLElement,
29
- activeBreakpoints: Set<string>,
30
- featureToggles: Record<string, boolean>,
31
- ) {
32
- if (typeof node === "string" || typeof node === "number" || typeof node === "boolean") {
33
- parent.append(document.createTextNode(String(node)));
34
- return;
35
- }
36
- if (!node || typeof node !== "object") {
37
- return;
38
- }
39
-
40
- // Array pseudo-element: render as a repeater perimeter at the array's own path, with a single
41
- // Template instance inside (matches the edit-mode visual).
42
- if (isMappedArray(node)) {
43
- const wrapper = document.createElement("div");
44
- wrapper.className = "repeater-perimeter";
45
- elToPath.set(wrapper, path);
46
- const template = node.map;
47
- if (template && typeof template === "object") {
48
- renderCanvasNode(template, [...path, "map"], wrapper, activeBreakpoints, featureToggles);
49
- }
50
- wrapper.style.pointerEvents = "none";
51
- parent.append(wrapper);
52
- return wrapper;
53
- }
54
-
55
- const tag = node.tagName || "div";
56
- const el = document.createElement(tag);
57
-
58
- elToPath.set(el, path);
59
-
60
- if (typeof node.textContent === "string") {
61
- el.textContent = node.textContent;
62
- } else if (isRef(node.textContent)) {
63
- const tc = node.textContent;
64
- const resolved = resolveDefaultForCanvas(tc, activeTab.value?.doc.document?.state);
65
- el.textContent = typeof resolved === "string" ? resolved : null;
66
- el.style.opacity = "0.7";
67
- el.style.fontStyle = "italic";
68
- el.title = `Bound: ${tc.$ref}`;
69
- }
70
-
71
- if (node.id) {
72
- el.id = node.id;
73
- }
74
- if (node.className) {
75
- el.className = node.className;
76
- }
77
-
78
- applyCanvasStyle(el, node.style, activeBreakpoints, featureToggles);
79
-
80
- if (node.attributes && typeof node.attributes === "object") {
81
- for (const [attr, val] of Object.entries(node.attributes)) {
82
- try {
83
- if (isRef(val)) {
84
- const resolved = resolveDefaultForCanvas(val, activeTab.value?.doc.document?.state);
85
- el.setAttribute(attr, String(resolved ?? ""));
86
- } else {
87
- el.setAttribute(attr, String(val));
88
- }
89
- } catch {}
90
- }
91
- }
92
-
93
- if (Array.isArray(node.children)) {
94
- for (let i = 0; i < node.children.length; i++) {
95
- renderCanvasNode(
96
- node.children[i],
97
- [...path, "children", i],
98
- el,
99
- activeBreakpoints,
100
- featureToggles,
101
- );
102
- }
103
- } else if (isMappedArray(node.children)) {
104
- const template = node.children.map;
105
- if (template && typeof template === "object") {
106
- const wrapper = document.createElement("div");
107
- wrapper.className = "repeater-perimeter";
108
- elToPath.set(wrapper, [...path, "children"]);
109
- renderCanvasNode(
110
- template,
111
- [...path, "children", "map"],
112
- wrapper,
113
- activeBreakpoints,
114
- featureToggles,
115
- );
116
- el.append(wrapper);
117
- }
118
- }
119
-
120
- if (node.$switch && node.cases && typeof node.cases === "object") {
121
- const keys = Object.keys(node.cases);
122
- const placeholder = document.createElement("div");
123
- placeholder.textContent = `[$switch: ${keys.join(" | ")}]`;
124
- placeholder.style.cssText =
125
- "font-family:var(--font-mono);font-size:var(--spectrum-font-size-50,11px);padding:6px 10px;background:color-mix(in srgb, var(--danger) 8%, transparent);border:1px dashed color-mix(in srgb, var(--danger) 40%, transparent);border-radius:var(--radius);color:var(--danger);font-style:italic";
126
- el.append(placeholder);
127
- }
128
-
129
- el.style.pointerEvents = "none";
130
- parent.append(el);
131
- return el;
132
- }
@@ -1,75 +0,0 @@
1
- /// <reference lib="dom" />
2
- /**
3
- * Pseudo-state preview — extracted from studio.js (Phase 4m). When a pseudo-selector (:hover,
4
- * :focus, etc.) is active in the style sidebar, force those styles onto the selected element.
5
- */
6
-
7
- import { getNodeAtPath } from "../store";
8
- import { getNestedStyle } from "@jxsuite/schema/guards";
9
- import { activeTab } from "../workspace/workspace";
10
- import { view } from "../view";
11
- import { findCanvasElement, getActivePanel } from "../canvas/canvas-helpers";
12
-
13
- import type { JxStyle } from "@jxsuite/schema/types";
14
-
15
- const pseudoStyleHost = document.createElement("div");
16
- pseudoStyleHost.style.display = "contents";
17
- (document.querySelector("sp-theme") || document.body).append(pseudoStyleHost);
18
-
19
- export function updateForcedPseudoPreview() {
20
- if (view.forcedStyleTag) {
21
- view.forcedStyleTag.remove();
22
- view.forcedStyleTag = null;
23
- }
24
- if (view.forcedAttrEl) {
25
- delete view.forcedAttrEl.dataset.studioForced;
26
- view.forcedAttrEl = null;
27
- }
28
-
29
- const tab = activeTab.value;
30
- const sel = tab?.session.ui?.activeSelector;
31
- if (!sel || !sel.startsWith(":") || !tab?.session.selection) {
32
- return;
33
- }
34
-
35
- const panel = getActivePanel();
36
- if (!panel) {
37
- return;
38
- }
39
- const el = findCanvasElement(tab.session.selection, panel.canvas);
40
- if (!el) {
41
- return;
42
- }
43
-
44
- const node = getNodeAtPath(tab.doc.document, tab.session.selection);
45
- if (!node?.style) {
46
- return;
47
- }
48
- const { activeMedia } = tab.session.ui;
49
- const ctx: JxStyle = activeMedia
50
- ? (getNestedStyle(node.style, `@${activeMedia}`) ?? {})
51
- : node.style;
52
- const rules = getNestedStyle(ctx, sel);
53
- if (!rules) {
54
- return;
55
- }
56
-
57
- const cssProps = Object.entries(rules)
58
- .filter(([k]) => typeof rules[k] === "string" || typeof rules[k] === "number")
59
- .map(
60
- ([k, v]) =>
61
- `${k.replaceAll(/[A-Z]/g, (c: string) => `-${c.toLowerCase()}`)}: ${v} !important`,
62
- )
63
- .join("; ");
64
- if (!cssProps) {
65
- return;
66
- }
67
-
68
- el.dataset.studioForced = "1";
69
- view.forcedAttrEl = el;
70
-
71
- const tag = document.createElement("style");
72
- tag.textContent = `[data-studio-forced] { ${cssProps} }`;
73
- pseudoStyleHost.append(tag);
74
- view.forcedStyleTag = tag;
75
- }