@vectoriox/iox-builder 1.7.8 → 1.7.10

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.
@@ -1466,10 +1466,10 @@ class InteractionEngineService {
1466
1466
  attachPageLoad(node, ix, element) {
1467
1467
  const timer = setTimeout(() => {
1468
1468
  if (this.hasPreStatedAncestor(element)) {
1469
- this.deferUntilVisible(element, () => this.runActions(node, ix.actions));
1469
+ this.deferUntilVisible(element, () => this.runActions(node, ix.actions, element));
1470
1470
  }
1471
1471
  else {
1472
- this.runActions(node, ix.actions);
1472
+ this.runActions(node, ix.actions, element);
1473
1473
  }
1474
1474
  }, 50);
1475
1475
  return () => clearTimeout(timer);
@@ -1485,12 +1485,12 @@ class InteractionEngineService {
1485
1485
  if (ix.actions.some(a => a.once) && firedSet.has(key))
1486
1486
  return;
1487
1487
  firedSet.add(key);
1488
- this.runActions(node, ix.actions);
1488
+ this.runActions(node, ix.actions, element);
1489
1489
  });
1490
1490
  return;
1491
1491
  }
1492
1492
  firedSet.add(key);
1493
- this.runActions(node, ix.actions);
1493
+ this.runActions(node, ix.actions, element);
1494
1494
  };
1495
1495
  // IntersectionObserver with no root uses the browser viewport.
1496
1496
  // It respects overflow:hidden clipping from .preview-scroll so it fires
@@ -1565,22 +1565,22 @@ class InteractionEngineService {
1565
1565
  if (ix.reverseActions?.length) {
1566
1566
  // Toggle: alternate between primary and reverse actions on each click.
1567
1567
  const isToggled = this.toggleStates.get(ix.id) ?? false;
1568
- this.runActions(node, isToggled ? ix.reverseActions : ix.actions);
1568
+ this.runActions(node, isToggled ? ix.reverseActions : ix.actions, element);
1569
1569
  this.toggleStates.set(ix.id, !isToggled);
1570
1570
  }
1571
1571
  else {
1572
- this.runActions(node, ix.actions);
1572
+ this.runActions(node, ix.actions, element);
1573
1573
  }
1574
1574
  };
1575
1575
  element.addEventListener('click', handler);
1576
1576
  return () => element.removeEventListener('click', handler);
1577
1577
  }
1578
1578
  attachHover(node, ix, element) {
1579
- const enterHandler = () => this.runActions(node, ix.actions);
1579
+ const enterHandler = () => this.runActions(node, ix.actions, element);
1580
1580
  const leaveHandler = () => {
1581
1581
  // Reverse animations on leave for hover triggers
1582
1582
  for (const action of ix.actions) {
1583
- const target = this.resolveTarget(node, action);
1583
+ const target = this.resolveTarget(node, action, element);
1584
1584
  if (!target)
1585
1585
  continue;
1586
1586
  this.reverseAction(target, action);
@@ -1594,13 +1594,15 @@ class InteractionEngineService {
1594
1594
  };
1595
1595
  }
1596
1596
  // ── Actions ──────────────────────────────────────────────
1597
- runActions(node, actions) {
1597
+ runActions(node, actions, selfEl) {
1598
1598
  for (const action of actions) {
1599
1599
  if (this.SWIPER_ACTIONS.has(action.type)) {
1600
1600
  this.executeSwiperAction(action);
1601
1601
  continue;
1602
1602
  }
1603
- const target = this.resolveTarget(node, action);
1603
+ // selfEl lets 'self'-targeted actions resolve for preview CLONES, which aren't
1604
+ // overlay-registered (getNodeRef would return undefined) — see attachTo. (issue #2)
1605
+ const target = this.resolveTarget(node, action, selfEl);
1604
1606
  if (!target)
1605
1607
  continue;
1606
1608
  this.executeAction(target, action);
@@ -3017,6 +3019,23 @@ class RenderDirective {
3017
3019
  * Returns { element, node } if found, or null if the target is outside
3018
3020
  * all known builder components (e.g. the canvas background).
3019
3021
  */
3022
+ /**
3023
+ * The nearest ancestor node's cssId, read from the DOM `iox-node-{id}` classes (NOT the overlay
3024
+ * registry — at state-restore time the parent isn't registered yet, since it registers only
3025
+ * AFTER rendering its children). Used to key relational (parent-hover) rules. (issue #1)
3026
+ */
3027
+ resolveParentNodeId(childEl) {
3028
+ let el = childEl?.parentElement ?? null;
3029
+ while (el) {
3030
+ for (let i = 0; i < el.classList.length; i++) {
3031
+ const c = el.classList[i];
3032
+ if (c.startsWith('iox-node-'))
3033
+ return c.slice('iox-node-'.length);
3034
+ }
3035
+ el = el.parentElement;
3036
+ }
3037
+ return undefined;
3038
+ }
3020
3039
  findParentNodeElement(target) {
3021
3040
  let el = target;
3022
3041
  while (el) {
@@ -3084,17 +3103,23 @@ class RenderDirective {
3084
3103
  const childEl = componentRef.location?.nativeElement;
3085
3104
  for (const state of Object.keys(node.stateStyles)) {
3086
3105
  const stateMap = node.stateStyles[state];
3087
- if (stateMap && Object.keys(stateMap).length) {
3106
+ if (!stateMap || !Object.keys(stateMap).length)
3107
+ continue;
3108
+ if (RELATIONAL_STATES.includes(state)) {
3088
3109
  // Relational states (parent-hover) compile to
3089
3110
  // `.iox-node-{parentId}:hover .iox-node-{childId}` — they need the CURRENT parent id.
3090
- // Resolve it from the DOM on EVERY render, so the rule is correct on load AND after a
3091
- // cross-container move (which re-renders the child with a fresh instance). (issue #1)
3092
- let relativeToId;
3093
- if (RELATIONAL_STATES.includes(state) && childEl?.parentElement) {
3094
- relativeToId = this.findParentNodeElement(childEl.parentElement)?.node?.id;
3095
- }
3111
+ // Resolve it from the DOM so the rule re-resolves after a cross-container MOVE (which
3112
+ // re-renders the child). If it can't be resolved yet (initial load: the parent registers
3113
+ // its class only after rendering its children), SKIP — do NOT clobber the correct rule
3114
+ // that page-ui's applyStateEnhancements already produced from the node tree. (issue #1)
3115
+ const relativeToId = this.resolveParentNodeId(childEl);
3116
+ if (!relativeToId)
3117
+ continue;
3096
3118
  this.styleRegistry.upsert(cssId, composeVirtualTraits(stateMap, initialStyle), state, relativeToId);
3097
3119
  }
3120
+ else {
3121
+ this.styleRegistry.upsert(cssId, composeVirtualTraits(stateMap, initialStyle), state);
3122
+ }
3098
3123
  }
3099
3124
  }
3100
3125
  }