@vectoriox/iox-builder 1.7.7 → 1.7.8

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.
@@ -1283,9 +1283,13 @@ class InteractionEngineService {
1283
1283
  }
1284
1284
  /** Wire all interactions for a node to its rendered DOM element. */
1285
1285
  attach(node) { this.runOutside(() => this._attach(node)); }
1286
- _attach(node) {
1287
- const ref = this.overlayService.getNodeRef(node);
1288
- if (!ref)
1286
+ /** Attach interactions to a node whose element is NOT overlay-registered — e.g. repeater/slider
1287
+ * PREVIEW CLONES, which are non-selectable but must still animate (parity with the SSR runtime,
1288
+ * which animates every repeated row). See RenderDirective. */
1289
+ attachTo(node, element) { this.runOutside(() => this._attach(node, element)); }
1290
+ _attach(node, elementOverride) {
1291
+ const element = elementOverride ?? this.overlayService.getNodeRef(node)?.element;
1292
+ if (!element)
1289
1293
  return;
1290
1294
  const inBuilder = this.isBuilderMode();
1291
1295
  // Apply any pre-states queued for THIS element by earlier-registered nodes.
@@ -1294,7 +1298,7 @@ class InteractionEngineService {
1294
1298
  const pending = this.pendingPreStates.get(node.id);
1295
1299
  if (pending) {
1296
1300
  for (const action of pending) {
1297
- this.applyPreState(ref.element, action);
1301
+ this.applyPreState(element, action);
1298
1302
  }
1299
1303
  this.pendingPreStates.delete(node.id);
1300
1304
  }
@@ -1312,7 +1316,7 @@ class InteractionEngineService {
1312
1316
  if (!skipPreState) {
1313
1317
  for (const action of ix.actions) {
1314
1318
  if (this.ENTRANCE_TYPES.has(action.type)) {
1315
- const target = this.resolveTarget(node, action);
1319
+ const target = this.resolveTarget(node, action, element);
1316
1320
  if (target) {
1317
1321
  this.applyPreState(target, action);
1318
1322
  }
@@ -1324,7 +1328,7 @@ class InteractionEngineService {
1324
1328
  }
1325
1329
  }
1326
1330
  }
1327
- const cleanup = this.attachInteraction(node, ix, ref.element);
1331
+ const cleanup = this.attachInteraction(node, ix, element);
1328
1332
  cleanups.push({ node, interaction: ix, cleanup });
1329
1333
  }
1330
1334
  this.attached.set(node, cleanups);
@@ -1628,10 +1632,9 @@ class InteractionEngineService {
1628
1632
  break;
1629
1633
  }
1630
1634
  }
1631
- resolveTarget(ownerNode, action) {
1632
- if (action.target === 'self') {
1633
- const ref = this.overlayService.getNodeRef(ownerNode);
1634
- return ref?.element ?? null;
1635
+ resolveTarget(ownerNode, action, selfEl) {
1636
+ if (action.target === 'self' || !action.target) {
1637
+ return selfEl ?? this.overlayService.getNodeRef(ownerNode)?.element ?? null;
1635
1638
  }
1636
1639
  // Find by node ID
1637
1640
  for (const [n, ref] of this.overlayService.getAllNodeEntries()) {
@@ -3078,10 +3081,19 @@ class RenderDirective {
3078
3081
  this.styleRegistry.upsert(cssId, composedBase);
3079
3082
  // Restore per-state overrides saved from a previous session.
3080
3083
  if (node.stateStyles) {
3084
+ const childEl = componentRef.location?.nativeElement;
3081
3085
  for (const state of Object.keys(node.stateStyles)) {
3082
3086
  const stateMap = node.stateStyles[state];
3083
3087
  if (stateMap && Object.keys(stateMap).length) {
3084
- this.styleRegistry.upsert(cssId, composeVirtualTraits(stateMap, initialStyle), state);
3088
+ // Relational states (parent-hover) compile to
3089
+ // `.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
+ }
3096
+ this.styleRegistry.upsert(cssId, composeVirtualTraits(stateMap, initialStyle), state, relativeToId);
3085
3097
  }
3086
3098
  }
3087
3099
  }
@@ -3176,11 +3188,15 @@ class RenderDirective {
3176
3188
  this.overlayService.triggerContextMenu(event.clientX, event.clientY);
3177
3189
  });
3178
3190
  }
3179
- // Wire up interactions (animations) after the element is in the DOM.
3180
- // Preview clones are static rows — no per-clone interaction wiring.
3191
+ // Wire up interactions (animations) after the element is in the DOM. Preview clones are
3192
+ // non-selectable (not overlay-registered) but MUST still animate — parity with the SSR
3193
+ // runtime, which animates every repeated row — so attach by element (issue #2).
3181
3194
  if (!isPreviewClone) {
3182
3195
  this.interactionEngine.attach(node);
3183
3196
  }
3197
+ else if (nativeEl) {
3198
+ this.interactionEngine.attachTo(node, nativeEl);
3199
+ }
3184
3200
  }
3185
3201
  /** Try setInput(); fall back to direct assignment for non-@Input properties. */
3186
3202
  safeSetInput(ref, name, value) {