@base44-preview/vite-plugin 0.2.22-pr.36.425440e → 0.2.22-pr.36.6dec368

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 (29) hide show
  1. package/dist/injections/layer-dropdown/consts.d.ts +5 -4
  2. package/dist/injections/layer-dropdown/consts.d.ts.map +1 -1
  3. package/dist/injections/layer-dropdown/consts.js +5 -4
  4. package/dist/injections/layer-dropdown/consts.js.map +1 -1
  5. package/dist/injections/layer-dropdown/controller.d.ts +2 -2
  6. package/dist/injections/layer-dropdown/controller.d.ts.map +1 -1
  7. package/dist/injections/layer-dropdown/controller.js +37 -34
  8. package/dist/injections/layer-dropdown/controller.js.map +1 -1
  9. package/dist/injections/layer-dropdown/dropdown-ui.d.ts +3 -3
  10. package/dist/injections/layer-dropdown/dropdown-ui.d.ts.map +1 -1
  11. package/dist/injections/layer-dropdown/dropdown-ui.js +25 -21
  12. package/dist/injections/layer-dropdown/dropdown-ui.js.map +1 -1
  13. package/dist/injections/layer-dropdown/types.d.ts +6 -1
  14. package/dist/injections/layer-dropdown/types.d.ts.map +1 -1
  15. package/dist/injections/layer-dropdown/utils.d.ts +2 -1
  16. package/dist/injections/layer-dropdown/utils.d.ts.map +1 -1
  17. package/dist/injections/layer-dropdown/utils.js +28 -47
  18. package/dist/injections/layer-dropdown/utils.js.map +1 -1
  19. package/dist/injections/visual-edit-agent.js +5 -5
  20. package/dist/injections/visual-edit-agent.js.map +1 -1
  21. package/dist/statics/index.mjs +1 -1
  22. package/dist/statics/index.mjs.map +1 -1
  23. package/package.json +1 -1
  24. package/src/injections/layer-dropdown/consts.ts +6 -4
  25. package/src/injections/layer-dropdown/controller.ts +40 -36
  26. package/src/injections/layer-dropdown/dropdown-ui.ts +28 -33
  27. package/src/injections/layer-dropdown/types.ts +7 -1
  28. package/src/injections/layer-dropdown/utils.ts +30 -53
  29. package/src/injections/visual-edit-agent.ts +5 -5
@@ -8,25 +8,24 @@ import {
8
8
  DROPDOWN_ITEM_ACTIVE_FONT_WEIGHT,
9
9
  DROPDOWN_ITEM_HOVER_BG,
10
10
  DEPTH_INDENT_PX,
11
- LABEL_CHEVRON,
12
- LABEL_CHEVRON_OPEN,
11
+ BASE_PADDING_PX,
12
+ CHEVRON_COLLAPSED,
13
+ CHEVRON_EXPANDED,
13
14
  LAYER_DROPDOWN_ATTR,
14
15
  } from "./consts.js";
15
16
  import { applyStyles, getLayerDisplayName } from "./utils.js";
16
- import type { LayerInfo, OnLayerSelect, OnLayerHover, OnLayerHoverEnd } from "./types.js";
17
+ import type { LayerInfo, DropdownCallbacks } from "./types.js";
17
18
 
18
19
  let activeDropdown: HTMLDivElement | null = null;
19
20
  let activeLabel: HTMLDivElement | null = null;
20
21
  let outsideMousedownHandler: ((e: MouseEvent) => void) | null = null;
21
- let activeOnHoverEnd: OnLayerHoverEnd | null = null;
22
+ let activeOnHoverEnd: (() => void) | null = null;
22
23
  let activeKeydownHandler: ((e: KeyboardEvent) => void) | null = null;
23
24
 
24
25
  function createDropdownItem(
25
26
  layer: LayerInfo,
26
27
  isActive: boolean,
27
- onSelect: OnLayerSelect,
28
- onHover?: OnLayerHover,
29
- onHoverEnd?: OnLayerHoverEnd
28
+ { onSelect, onHover, onHoverEnd }: DropdownCallbacks
30
29
  ): HTMLDivElement {
31
30
  const item = document.createElement("div");
32
31
  item.textContent = getLayerDisplayName(layer);
@@ -34,7 +33,7 @@ function createDropdownItem(
34
33
 
35
34
  const depth = layer.depth ?? 0;
36
35
  if (depth > 0) {
37
- item.style.paddingLeft = `${12 + depth * DEPTH_INDENT_PX}px`;
36
+ item.style.paddingLeft = `${BASE_PADDING_PX + depth * DEPTH_INDENT_PX}px`;
38
37
  }
39
38
 
40
39
  if (isActive) {
@@ -66,9 +65,7 @@ function createDropdownItem(
66
65
  export function createDropdownElement(
67
66
  layers: LayerInfo[],
68
67
  currentSelectorId: string | null,
69
- onSelect: OnLayerSelect,
70
- onHover?: OnLayerHover,
71
- onHoverEnd?: OnLayerHoverEnd
68
+ callbacks: DropdownCallbacks
72
69
  ): HTMLDivElement {
73
70
  const container = document.createElement("div");
74
71
  container.setAttribute(LAYER_DROPDOWN_ATTR, "true");
@@ -76,7 +73,7 @@ export function createDropdownElement(
76
73
 
77
74
  layers.forEach((layer) => {
78
75
  const isActive = layer.selectorId === currentSelectorId;
79
- container.appendChild(createDropdownItem(layer, isActive, onSelect, onHover, onHoverEnd));
76
+ container.appendChild(createDropdownItem(layer, isActive, callbacks));
80
77
  });
81
78
 
82
79
  return container;
@@ -85,11 +82,12 @@ export function createDropdownElement(
85
82
  /** Add chevron indicator and pointer-events to the label */
86
83
  export function enhanceLabelWithChevron(label: HTMLDivElement): void {
87
84
  const t = label.textContent ?? "";
88
- if (t.endsWith(LABEL_CHEVRON) || t.endsWith(LABEL_CHEVRON_OPEN)) return;
85
+ if (t.endsWith(CHEVRON_COLLAPSED) || t.endsWith(CHEVRON_EXPANDED)) return;
89
86
 
90
- label.textContent = t + LABEL_CHEVRON;
87
+ label.textContent = t + CHEVRON_COLLAPSED;
91
88
  label.style.cursor = "pointer";
92
89
  label.style.userSelect = "none";
90
+ label.style.whiteSpace = "nowrap";
93
91
  label.style.pointerEvents = "auto";
94
92
  label.setAttribute(LAYER_DROPDOWN_ATTR, "true");
95
93
  }
@@ -98,9 +96,7 @@ function setupKeyboardNavigation(
98
96
  dropdown: HTMLDivElement,
99
97
  layers: LayerInfo[],
100
98
  currentSelectorId: string | null,
101
- onSelect: OnLayerSelect,
102
- onHover?: OnLayerHover,
103
- onHoverEnd?: OnLayerHoverEnd
99
+ { onSelect, onHover, onHoverEnd }: DropdownCallbacks
104
100
  ): void {
105
101
  const items = Array.from(dropdown.children) as HTMLDivElement[];
106
102
  let focusedIndex = layers.findIndex((l) => l.selectorId === currentSelectorId);
@@ -163,22 +159,21 @@ export function showDropdown(
163
159
  label: HTMLDivElement,
164
160
  layers: LayerInfo[],
165
161
  currentSelectorId: string | null,
166
- onSelect: OnLayerSelect,
167
- onHover?: OnLayerHover,
168
- onHoverEnd?: OnLayerHoverEnd
162
+ callbacks: DropdownCallbacks
169
163
  ): void {
170
164
  closeDropdown();
171
165
 
172
166
  const dropdown = createDropdownElement(
173
167
  layers,
174
168
  currentSelectorId,
175
- (layer) => {
176
- if (onHoverEnd) onHoverEnd();
177
- onSelect(layer);
178
- closeDropdown();
179
- },
180
- onHover,
181
- onHoverEnd
169
+ {
170
+ ...callbacks,
171
+ onSelect: (layer) => {
172
+ if (callbacks.onHoverEnd) callbacks.onHoverEnd();
173
+ callbacks.onSelect(layer);
174
+ closeDropdown();
175
+ },
176
+ }
182
177
  );
183
178
 
184
179
  const overlay = label.parentElement;
@@ -190,19 +185,19 @@ export function showDropdown(
190
185
  overlay.appendChild(dropdown);
191
186
  activeDropdown = dropdown;
192
187
  activeLabel = label;
193
- if (label.textContent?.endsWith(LABEL_CHEVRON.trim())) {
194
- label.textContent = label.textContent.slice(0, -LABEL_CHEVRON.length) + LABEL_CHEVRON_OPEN;
188
+ if (label.textContent?.endsWith(CHEVRON_COLLAPSED.trim())) {
189
+ label.textContent = label.textContent.slice(0, -CHEVRON_COLLAPSED.length) + CHEVRON_EXPANDED;
195
190
  }
196
- activeOnHoverEnd = onHoverEnd ?? null;
191
+ activeOnHoverEnd = callbacks.onHoverEnd ?? null;
197
192
 
198
- setupKeyboardNavigation(dropdown, layers, currentSelectorId, onSelect, onHover, onHoverEnd);
193
+ setupKeyboardNavigation(dropdown, layers, currentSelectorId, callbacks);
199
194
  setupOutsideClickHandler(dropdown, label);
200
195
  }
201
196
 
202
197
  /** Close the active dropdown and clean up listeners */
203
198
  export function closeDropdown(): void {
204
- if (activeLabel?.textContent?.includes(LABEL_CHEVRON_OPEN)) {
205
- activeLabel.textContent = activeLabel.textContent.replace(LABEL_CHEVRON_OPEN, LABEL_CHEVRON);
199
+ if (activeLabel?.textContent?.includes(CHEVRON_EXPANDED)) {
200
+ activeLabel.textContent = activeLabel.textContent.replace(CHEVRON_EXPANDED, CHEVRON_COLLAPSED);
206
201
  }
207
202
  activeLabel = null;
208
203
 
@@ -11,7 +11,13 @@ export type OnLayerSelect = (layer: LayerInfo) => void;
11
11
  export type OnLayerHover = (layer: LayerInfo) => void;
12
12
  export type OnLayerHoverEnd = () => void;
13
13
 
14
- export interface LayerControllerDeps {
14
+ export interface DropdownCallbacks {
15
+ onSelect: OnLayerSelect;
16
+ onHover?: OnLayerHover;
17
+ onHoverEnd?: OnLayerHoverEnd;
18
+ }
19
+
20
+ export interface LayerControllerConfig {
15
21
  createPreviewOverlay: (element: Element) => HTMLDivElement;
16
22
  getSelectedElementId: () => string | null;
17
23
  selectElement: (element: Element) => HTMLDivElement | undefined;
@@ -15,14 +15,26 @@ export function getLayerDisplayName(layer: LayerInfo): string {
15
15
  return layer.tagName;
16
16
  }
17
17
 
18
+ function toLayerInfo(element: Element, depth?: number): LayerInfo {
19
+ const info: LayerInfo = {
20
+ element,
21
+ tagName: element.tagName.toLowerCase(),
22
+ selectorId: getElementSelectorId(element),
23
+ };
24
+ if (depth !== undefined) info.depth = depth;
25
+ return info;
26
+ }
27
+
18
28
  /**
19
29
  * Collect instrumented descendants up to `maxDepth` instrumented nesting levels.
20
30
  * Non-instrumented wrappers are walked through without counting toward depth.
21
31
  * Results are in DOM order.
32
+ * When `startDepth` is provided, assigns `depth` to each item during collection.
22
33
  */
23
34
  export function getInstrumentedDescendants(
24
35
  parent: Element,
25
- maxDepth: number
36
+ maxDepth: number,
37
+ startDepth?: number
26
38
  ): LayerInfo[] {
27
39
  const result: LayerInfo[] = [];
28
40
 
@@ -31,11 +43,15 @@ export function getInstrumentedDescendants(
31
43
  for (let i = 0; i < el.children.length; i++) {
32
44
  const child = el.children[i]!;
33
45
  if (isInstrumentedElement(child)) {
34
- result.push({
46
+ const info: LayerInfo = {
35
47
  element: child,
36
48
  tagName: child.tagName.toLowerCase(),
37
49
  selectorId: getElementSelectorId(child),
38
- });
50
+ };
51
+ if (startDepth !== undefined) {
52
+ info.depth = startDepth + instrDepth - 1;
53
+ }
54
+ result.push(info);
39
55
  walk(child, instrDepth + 1);
40
56
  } else {
41
57
  walk(child, instrDepth);
@@ -47,16 +63,6 @@ export function getInstrumentedDescendants(
47
63
  return result;
48
64
  }
49
65
 
50
- function toLayerInfo(element: Element, depth?: number): LayerInfo {
51
- const info: LayerInfo = {
52
- element,
53
- tagName: element.tagName.toLowerCase(),
54
- selectorId: getElementSelectorId(element),
55
- };
56
- if (depth !== undefined) info.depth = depth;
57
- return info;
58
- }
59
-
60
66
  /** Collect instrumented ancestors from selected element up to MAX_PARENT_DEPTH (outermost first). */
61
67
  function collectInstrumentedParents(selectedElement: Element): LayerInfo[] {
62
68
  const parents: LayerInfo[] = [];
@@ -76,16 +82,16 @@ function collectInstrumentedParents(selectedElement: Element): LayerInfo[] {
76
82
  return parents;
77
83
  }
78
84
 
79
- /** Append parents to chain with depth 0, 1, …; returns depth of selected (parents.length). */
80
- function appendParentsWithDepth(chain: LayerInfo[], parents: LayerInfo[]): number {
85
+ /** Add parents to chain with depth 0, 1, …; returns depth of selected (parents.length). */
86
+ function addParentsToChain(chain: LayerInfo[], parents: LayerInfo[]): number {
81
87
  parents.forEach((p, i) => {
82
88
  chain.push({ ...p, depth: i });
83
89
  });
84
90
  return parents.length;
85
91
  }
86
92
 
87
- /** Append selected element and its descendants at the given depth. */
88
- function appendSelfAndDescendants(
93
+ /** Add selected element and its descendants at the given depth. */
94
+ function addSelfAndDescendantsToChain(
89
95
  chain: LayerInfo[],
90
96
  selectedElement: Element,
91
97
  selfDepth: number
@@ -93,15 +99,15 @@ function appendSelfAndDescendants(
93
99
  chain.push(toLayerInfo(selectedElement, selfDepth));
94
100
  const descendants = getInstrumentedDescendants(
95
101
  selectedElement,
96
- MAX_CHILD_DEPTH
102
+ MAX_CHILD_DEPTH,
103
+ selfDepth + 1
97
104
  );
98
- assignDescendantDepths(selectedElement, descendants, selfDepth + 1);
99
105
  chain.push(...descendants);
100
106
  }
101
107
 
102
108
  /** Get the innermost instrumented parent's DOM element, or null if none. */
103
109
  function getImmediateInstrParent(parents: LayerInfo[]): Element | null {
104
- return parents.length > 0 ? parents[parents.length - 1]!.element : null;
110
+ return parents.at(-1)?.element ?? null;
105
111
  }
106
112
 
107
113
  /** Collect instrumented siblings of the selected element from its parent (DOM order). */
@@ -113,7 +119,7 @@ function collectSiblings(parent: Element, selectedElement: Element): LayerInfo[]
113
119
  return siblings;
114
120
  }
115
121
 
116
- /** Append siblings at selfDepth, expanding children only for the selected element. */
122
+ /** Add siblings at selfDepth, expanding children only for the selected element. */
117
123
  function appendSiblingsWithSelected(
118
124
  chain: LayerInfo[],
119
125
  siblings: LayerInfo[],
@@ -122,7 +128,7 @@ function appendSiblingsWithSelected(
122
128
  ): void {
123
129
  for (const sibling of siblings) {
124
130
  if (sibling.element === selectedElement) {
125
- appendSelfAndDescendants(chain, selectedElement, selfDepth);
131
+ addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);
126
132
  } else {
127
133
  chain.push({ ...sibling, depth: selfDepth });
128
134
  }
@@ -142,44 +148,15 @@ function appendSiblingsWithSelected(
142
148
  export function buildLayerChain(selectedElement: Element): LayerInfo[] {
143
149
  const parents = collectInstrumentedParents(selectedElement);
144
150
  const chain: LayerInfo[] = [];
145
- const selfDepth = appendParentsWithDepth(chain, parents);
151
+ const selfDepth = addParentsToChain(chain, parents);
146
152
 
147
153
  const instrParent = getImmediateInstrParent(parents);
148
154
  if (instrParent) {
149
155
  const siblings = collectSiblings(instrParent, selectedElement);
150
156
  appendSiblingsWithSelected(chain, siblings, selectedElement, selfDepth);
151
157
  } else {
152
- appendSelfAndDescendants(chain, selectedElement, selfDepth);
158
+ addSelfAndDescendantsToChain(chain, selectedElement, selfDepth);
153
159
  }
154
160
 
155
161
  return chain;
156
162
  }
157
-
158
- /**
159
- * Walk the DOM tree again to assign correct visual depth to each descendant.
160
- * This avoids storing depth during collection and keeps the API simple.
161
- */
162
- function assignDescendantDepths(
163
- root: Element,
164
- descendants: LayerInfo[],
165
- startDepth: number
166
- ): void {
167
- // Build a set for O(1) lookup
168
- const descSet = new Set(descendants.map((d) => d.element));
169
- // Map element → LayerInfo for mutation
170
- const descMap = new Map(descendants.map((d) => [d.element, d]));
171
-
172
- function walk(el: Element, instrDepth: number): void {
173
- for (let i = 0; i < el.children.length; i++) {
174
- const child = el.children[i]!;
175
- if (descSet.has(child)) {
176
- descMap.get(child)!.depth = startDepth + instrDepth - 1;
177
- walk(child, instrDepth + 1);
178
- } else {
179
- walk(child, instrDepth);
180
- }
181
- }
182
- }
183
-
184
- walk(root, 1);
185
- }
@@ -140,7 +140,7 @@ export function setupVisualEditAgent() {
140
140
  return selectedOverlays[0];
141
141
  };
142
142
 
143
- const unSelectElement = (): void => {
143
+ const notifyDeselection = (): void => {
144
144
  selectedElementId = null;
145
145
  window.parent.postMessage({ type: "unselect-element" }, "*");
146
146
  };
@@ -248,8 +248,8 @@ export function setupVisualEditAgent() {
248
248
  layerController.attachToOverlay(selectedOverlay, element);
249
249
  };
250
250
 
251
- // Unselect the current element
252
- const unselectElement = () => {
251
+ // Clear the current selection
252
+ const clearSelection = () => {
253
253
  clearSelectedOverlays();
254
254
  selectedElementId = null;
255
255
  };
@@ -320,7 +320,7 @@ export function setupVisualEditAgent() {
320
320
  },
321
321
  getSelectedElementId: () => selectedElementId,
322
322
  selectElement,
323
- onDeselect: unSelectElement,
323
+ onDeselect: notifyDeselection,
324
324
  });
325
325
 
326
326
  // Toggle visual edit mode
@@ -411,7 +411,7 @@ export function setupVisualEditAgent() {
411
411
  break;
412
412
 
413
413
  case "unselect-element":
414
- unselectElement();
414
+ clearSelection();
415
415
  break;
416
416
 
417
417
  case "refresh-page":