@vectoriox/iox-builder 1.4.76 → 1.4.77

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.
@@ -1266,11 +1266,9 @@ class InteractionEngineService {
1266
1266
  const cleanups = [];
1267
1267
  for (const ix of node.interactions) {
1268
1268
  // Pre-state: hide target elements before their entrance animation fires.
1269
- // In builder mode: skip pre-state for auto-fire triggers that either are
1270
- // suppressed (pageLoad, scrollProgress) or use a Lenis scroll container
1271
- // where pointer-events:none on canvas elements breaks wheel event routing
1272
- // (viewportEnter). Click/hover triggers are always active.
1273
- const skipPreState = inBuilder && ix.trigger !== 'click' && ix.trigger !== 'hover';
1269
+ // In builder mode: skip only suppressed triggers (pageLoad, scrollProgress).
1270
+ // viewportEnter IS active in builder — elements must be hidden before trigger.
1271
+ const skipPreState = inBuilder && (ix.trigger === 'pageLoad' || ix.trigger === 'scrollProgress');
1274
1272
  if (!skipPreState) {
1275
1273
  for (const action of ix.actions) {
1276
1274
  if (this.ENTRANCE_TYPES.has(action.type)) {
@@ -1446,16 +1444,48 @@ class InteractionEngineService {
1446
1444
  firedSet.add(key);
1447
1445
  this.runActions(node, ix.actions);
1448
1446
  };
1447
+ // IntersectionObserver with no root uses the browser viewport.
1448
+ // It respects overflow:hidden clipping from .preview-scroll so it fires
1449
+ // correctly as Lenis scrolls (Lenis changes scrollTop on .preview-scroll).
1449
1450
  const observer = new IntersectionObserver((entries) => {
1450
1451
  for (const entry of entries) {
1451
1452
  if (entry.isIntersecting) {
1452
- observer.disconnect();
1453
+ cleanup();
1453
1454
  fire();
1454
1455
  }
1455
1456
  }
1456
1457
  }, { threshold: 0.1 });
1457
1458
  observer.observe(element);
1458
- return () => observer.disconnect();
1459
+ // Builder: also listen to Lenis scroll events on .preview-lenis-content
1460
+ // as a fallback in case IntersectionObserver misses elements behind a
1461
+ // CSS transform (scale) on iox-page-component.
1462
+ const lenisEl = this.overlayService.getScrollContainer();
1463
+ let scrollFired = false;
1464
+ const onScroll = () => {
1465
+ if (scrollFired)
1466
+ return;
1467
+ const rootEl = this.overlayService.getIntersectionRoot();
1468
+ if (!rootEl)
1469
+ return;
1470
+ const rootRect = rootEl.getBoundingClientRect();
1471
+ const elRect = element.getBoundingClientRect();
1472
+ const overlapH = Math.min(elRect.bottom, rootRect.bottom) - Math.max(elRect.top, rootRect.top);
1473
+ const elH = elRect.bottom - elRect.top;
1474
+ if (elH > 0 && overlapH / elH >= 0.1) {
1475
+ scrollFired = true;
1476
+ cleanup();
1477
+ fire();
1478
+ }
1479
+ };
1480
+ if (lenisEl)
1481
+ lenisEl.addEventListener('scroll', onScroll, { passive: true });
1482
+ const cleanup = () => {
1483
+ observer.disconnect();
1484
+ scrollFired = true;
1485
+ if (lenisEl)
1486
+ lenisEl.removeEventListener('scroll', onScroll);
1487
+ };
1488
+ return cleanup;
1459
1489
  }
1460
1490
  isBuilderMode() {
1461
1491
  return document.body.classList.contains('builder-active');
@@ -1601,9 +1631,9 @@ class InteractionEngineService {
1601
1631
  * trigger fires. Called for ALL entrance-type actions regardless of trigger so
1602
1632
  * that a click-triggered fadeIn on a menu overlay also starts it hidden.
1603
1633
  *
1604
- * Also sets pointer-events:none so the invisible element does not block clicks
1605
- * on other content beneath it. Pointer events are restored in executeAction()
1606
- * once the entrance animation finishes.
1634
+ * In production also sets pointer-events:none. In builder mode pointer-events
1635
+ * are left as-is so wheel events still reach the Lenis scroll container;
1636
+ * the data-iox-hidden guard in render.directive.ts prevents overlay selection.
1607
1637
  */
1608
1638
  applyPreState(element, action) {
1609
1639
  const { keyframes } = this.buildAnimation(action);
@@ -1613,10 +1643,10 @@ class InteractionEngineService {
1613
1643
  for (const [prop, val] of Object.entries(first)) {
1614
1644
  element.style[prop] = String(val);
1615
1645
  }
1616
- // Mark as hidden so the builder overlay and drag engine can ignore this element
1617
- // and all of its children regardless of which entrance animation type is used.
1618
1646
  element.setAttribute('data-iox-hidden', '');
1619
- element.style.setProperty('pointer-events', 'none');
1647
+ if (!this.isBuilderMode()) {
1648
+ element.style.setProperty('pointer-events', 'none');
1649
+ }
1620
1650
  this.preStatedElements.add(element);
1621
1651
  }
1622
1652
  clearInlineAnimationStyles(element) {