@vectoriox/iox-builder 9.11.4 → 10.0.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.
|
@@ -167,9 +167,17 @@ var PanelEventTypes;
|
|
|
167
167
|
* would (`string` component type, or a block / symbol object). The builder resolves WHERE from
|
|
168
168
|
* the current selection — see `resolveInsertTarget`. */
|
|
169
169
|
PanelEventTypes["INSERT_COMPONENT"] = "insertcomponent";
|
|
170
|
-
/** Insert prebuilt node(s) as GLOBAL elements (data = ComponentNode[]) — the consent preset's
|
|
171
|
-
*
|
|
170
|
+
/** Insert prebuilt node(s) as GLOBAL elements (data = ComponentNode[]) — the consent preset's click and
|
|
171
|
+
* the site header's click or drop (CC1.1). The HOST handles it (it owns the globals, their undo step and
|
|
172
|
+
* the one-header rule); the builder only routes a dropped global payload here (`globalInsert$`). */
|
|
172
173
|
PanelEventTypes["INSERT_GLOBAL"] = "insertglobal";
|
|
174
|
+
/** A panel makes `data.node` a GLOBAL element at `data.position` (default before) — the same move as the
|
|
175
|
+
* toolbar's Make Global (the Style panel's Global switch, Bindings ▸ Phone menu ▸ "Make it the site header"). */
|
|
176
|
+
PanelEventTypes["MAKE_GLOBAL"] = "make-global";
|
|
177
|
+
/** A panel returns the global `data.node` to the page — the toolbar's Remove Global. */
|
|
178
|
+
PanelEventTypes["REMOVE_GLOBAL"] = "remove-global";
|
|
179
|
+
/** A panel moved the global `data.node` to `data.position` (before / after the page content). */
|
|
180
|
+
PanelEventTypes["GLOBAL_POSITION"] = "update-global-position";
|
|
173
181
|
/** A click on a compound component's PART (Field label/control/help/…) — the style panel
|
|
174
182
|
* activates that part (data = { part }). Doron 2026-10-10: "both shall be selectable". */
|
|
175
183
|
PanelEventTypes["PART_SELECT"] = "partselect";
|
|
@@ -2523,6 +2531,8 @@ class DragEngineService {
|
|
|
2523
2531
|
this.deepTarget$ = new BehaviorSubject(null);
|
|
2524
2532
|
/** Emits the dropped/inserted ComponentNode after every successful drop. */
|
|
2525
2533
|
this.dropComplete$ = new Subject();
|
|
2534
|
+
/** A fresh GLOBAL node from the palette (the site header) — dropped or clicked, never placed in a zone. */
|
|
2535
|
+
this.globalInsert$ = new Subject();
|
|
2526
2536
|
// ── Active drag state ─────────────────────────────────────
|
|
2527
2537
|
this._isDragging = false;
|
|
2528
2538
|
this._payload = null;
|
|
@@ -2633,6 +2643,10 @@ class DragEngineService {
|
|
|
2633
2643
|
// ── Shared drop handler — used by all layout components ───────────────────
|
|
2634
2644
|
handleDrop(children, event, dropListId, cdr, afterDrop) {
|
|
2635
2645
|
const { payload, insertIndex } = event;
|
|
2646
|
+
if (this.routeGlobalPayload(payload.data)) {
|
|
2647
|
+
afterDrop?.();
|
|
2648
|
+
return;
|
|
2649
|
+
}
|
|
2636
2650
|
const changesParent = payload.type === 'external' || payload.sourceId !== dropListId;
|
|
2637
2651
|
if (changesParent && this.refuseInsert(payload.data, this.dropzoneAncestors(dropListId))) {
|
|
2638
2652
|
afterDrop?.();
|
|
@@ -2712,6 +2726,8 @@ class DragEngineService {
|
|
|
2712
2726
|
* step through the same path. Returns the inserted node, or null if the payload was unusable.
|
|
2713
2727
|
*/
|
|
2714
2728
|
insertPayload(children, index, data, ancestors = []) {
|
|
2729
|
+
if (this.routeGlobalPayload(data))
|
|
2730
|
+
return null;
|
|
2715
2731
|
if (this.refuseInsert(data, ancestors))
|
|
2716
2732
|
return null;
|
|
2717
2733
|
const node = this.materialize(data);
|
|
@@ -2722,6 +2738,29 @@ class DragEngineService {
|
|
|
2722
2738
|
this.dropComplete$.next(node);
|
|
2723
2739
|
return node;
|
|
2724
2740
|
}
|
|
2741
|
+
/**
|
|
2742
|
+
* A palette payload born GLOBAL (the site header, CC1.1) is not placed where it was dropped or clicked:
|
|
2743
|
+
* it is handed to `globalInsert$` (the builder hands it to the host, which owns the globals). True when
|
|
2744
|
+
* the payload was routed there. Only an EXTERNAL payload can be one — a node already on the canvas that
|
|
2745
|
+
* is global moves through the globals' own paths.
|
|
2746
|
+
*/
|
|
2747
|
+
routeGlobalPayload(data) {
|
|
2748
|
+
if (!data || typeof data !== 'object' || !this.payloadNode(data)?.isGlobal)
|
|
2749
|
+
return false;
|
|
2750
|
+
if (this.isOnCanvas(data))
|
|
2751
|
+
return false;
|
|
2752
|
+
const node = this.materialize(data);
|
|
2753
|
+
if (!node)
|
|
2754
|
+
return false;
|
|
2755
|
+
this.globalInsert$.next(node);
|
|
2756
|
+
return true;
|
|
2757
|
+
}
|
|
2758
|
+
isOnCanvas(data) {
|
|
2759
|
+
for (const list of this.dataMap.values())
|
|
2760
|
+
if (list.includes(data))
|
|
2761
|
+
return true;
|
|
2762
|
+
return false;
|
|
2763
|
+
}
|
|
2725
2764
|
/** True when `children` is a registered drop zone's array — i.e. a real container that can hold
|
|
2726
2765
|
* children. Click-to-insert uses the same test a drag does, so it can't insert where a drop
|
|
2727
2766
|
* couldn't. */
|
|
@@ -9077,6 +9116,12 @@ class BuilderComponent {
|
|
|
9077
9116
|
this._selectAfterDrop(node);
|
|
9078
9117
|
this.panelEventService.emit(PanelEventTypes.LAYOUT_CHANGED, this.layout);
|
|
9079
9118
|
}));
|
|
9119
|
+
// A palette payload born GLOBAL (the site header) never lands where it was dropped: the host owns
|
|
9120
|
+
// the globals, their undo step and the one-header rule (CC1.1) — the same event a click sends.
|
|
9121
|
+
this.sub.add(this.dragEngine.globalInsert$.subscribe((node) => {
|
|
9122
|
+
this.autoLabel(node);
|
|
9123
|
+
this.panelEventService.emit(PanelEventTypes.INSERT_GLOBAL, [node]);
|
|
9124
|
+
}));
|
|
9080
9125
|
this.panelEventService.emit(PanelEventTypes.PANEL_OPEN, PanelTypes.STYLES);
|
|
9081
9126
|
this.viewportSub = this.viewportService.state$.subscribe(state => {
|
|
9082
9127
|
this.activeBreakpoint = state.breakpoint;
|
|
@@ -9511,6 +9556,21 @@ class BuilderComponent {
|
|
|
9511
9556
|
this.selectPanel(PanelTypes.STYLES);
|
|
9512
9557
|
this._emitElementSelect(event.node, event.componentRef);
|
|
9513
9558
|
}
|
|
9559
|
+
/**
|
|
9560
|
+
* Make / Remove global moved `node` between the page and the globals: keep it selected in its new place,
|
|
9561
|
+
* so the breadcrumb (its Global chip) and every panel describe where it is NOW. Clearing the selection
|
|
9562
|
+
* left the crumb and the Bindings panel on the old node until a reload (CC1.1, Doron's report).
|
|
9563
|
+
*/
|
|
9564
|
+
reselectMoved(node) {
|
|
9565
|
+
this.overlayService.clearSelect();
|
|
9566
|
+
this.cdr.detectChanges();
|
|
9567
|
+
setTimeout(() => this._withNodeRef(node, ref => {
|
|
9568
|
+
this.selectedItem = node;
|
|
9569
|
+
this.overlayService.setSelect(ref.element, node.type, this.activeMode, node, ref.componentRef);
|
|
9570
|
+
this._emitElementSelect(node, ref.componentRef);
|
|
9571
|
+
this.cdr.markForCheck();
|
|
9572
|
+
}));
|
|
9573
|
+
}
|
|
9514
9574
|
_selectAfterDrop(node) {
|
|
9515
9575
|
// Wait one tick for Angular to render the new component and register it
|
|
9516
9576
|
// in the overlay before attempting to select it.
|
|
@@ -9737,9 +9797,7 @@ class BuilderComponent {
|
|
|
9737
9797
|
node.globalPosition = event.position ?? 'before';
|
|
9738
9798
|
this.globalElements.push(node);
|
|
9739
9799
|
this.globalElementsChange.emit([...this.globalElements]);
|
|
9740
|
-
this.
|
|
9741
|
-
this.overlayService.clearSelect();
|
|
9742
|
-
this.cdr.markForCheck();
|
|
9800
|
+
this.reselectMoved(node);
|
|
9743
9801
|
this.panelEventService.emit(PanelEventTypes.LAYOUT_CHANGED, this.layout);
|
|
9744
9802
|
}
|
|
9745
9803
|
break;
|
|
@@ -9752,9 +9810,7 @@ class BuilderComponent {
|
|
|
9752
9810
|
node.globalPosition = undefined;
|
|
9753
9811
|
this.layout.push(node);
|
|
9754
9812
|
this.globalElementsChange.emit([...this.globalElements]);
|
|
9755
|
-
this.
|
|
9756
|
-
this.overlayService.clearSelect();
|
|
9757
|
-
this.cdr.markForCheck();
|
|
9813
|
+
this.reselectMoved(node);
|
|
9758
9814
|
this.panelEventService.emit(PanelEventTypes.LAYOUT_CHANGED, this.layout);
|
|
9759
9815
|
}
|
|
9760
9816
|
break;
|
|
@@ -10119,21 +10175,21 @@ class BuilderComponent {
|
|
|
10119
10175
|
this.insertFromPanel(panelEvent.data);
|
|
10120
10176
|
return;
|
|
10121
10177
|
}
|
|
10122
|
-
//
|
|
10123
|
-
|
|
10124
|
-
|
|
10125
|
-
const
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10130
|
-
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
|
|
10178
|
+
// A panel moves a node between the page and the globals — the toolbar's own Make / Remove Global.
|
|
10179
|
+
if (panelEvent.type === PanelEventTypes.MAKE_GLOBAL || panelEvent.type === PanelEventTypes.REMOVE_GLOBAL) {
|
|
10180
|
+
const node = panelEvent.data?.node;
|
|
10181
|
+
const action = panelEvent.type === PanelEventTypes.MAKE_GLOBAL ? ToolbarAction.MakeGlobal : ToolbarAction.RemoveGlobal;
|
|
10182
|
+
if (node)
|
|
10183
|
+
this.onToolbarAction({ action, entry: { node }, position: panelEvent.data?.position });
|
|
10184
|
+
return;
|
|
10185
|
+
}
|
|
10186
|
+
if (panelEvent.type === PanelEventTypes.GLOBAL_POSITION) {
|
|
10187
|
+
const node = panelEvent.data?.node;
|
|
10188
|
+
if (!node?.isGlobal || !this.globalElements.includes(node))
|
|
10189
|
+
return;
|
|
10190
|
+
node.globalPosition = panelEvent.data?.position === 'after' ? 'after' : 'before';
|
|
10134
10191
|
this.globalElementsChange.emit([...this.globalElements]);
|
|
10135
|
-
this.
|
|
10136
|
-
this.panelEventService.emit(PanelEventTypes.LAYOUT_CHANGED, this.layout);
|
|
10192
|
+
this.reselectMoved(node);
|
|
10137
10193
|
return;
|
|
10138
10194
|
}
|
|
10139
10195
|
// A panel rewrote a subtree in place (a Card's Parts / Layout / Link): re-render it, re-register
|