@vectoriox/iox-builder 1.4.74 → 1.4.76

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,12 +1266,11 @@ 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 only for pageLoad and scrollProgress —
1270
- // those triggers are suppressed in the canvas so elements would stay hidden.
1271
- // viewportEnter uses IntersectionObserver with .preview-scroll as its root,
1272
- // so it fires correctly when the canvas scrolls — pre-state is safe to apply.
1273
- // Click/hover triggers are always active so their pre-state is applied too.
1274
- const skipPreState = inBuilder && (ix.trigger === 'pageLoad' || ix.trigger === 'scrollProgress');
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';
1275
1274
  if (!skipPreState) {
1276
1275
  for (const action of ix.actions) {
1277
1276
  if (this.ENTRANCE_TYPES.has(action.type)) {
@@ -1447,53 +1446,10 @@ class InteractionEngineService {
1447
1446
  firedSet.add(key);
1448
1447
  this.runActions(node, ix.actions);
1449
1448
  };
1450
- const canvasRoot = this.overlayService.getIntersectionRoot();
1451
- if (canvasRoot) {
1452
- // Builder mode: IntersectionObserver with a scaled/transformed canvas root is unreliable.
1453
- // Use getBoundingClientRect against the canvas clipping container instead.
1454
- const isInCanvasViewport = () => {
1455
- const rootRect = canvasRoot.getBoundingClientRect();
1456
- const elRect = element.getBoundingClientRect();
1457
- const overlapH = Math.min(elRect.bottom, rootRect.bottom) - Math.max(elRect.top, rootRect.top);
1458
- const elH = elRect.bottom - elRect.top;
1459
- return elH > 0 && overlapH / elH >= 0.1;
1460
- };
1461
- let fired = false;
1462
- const checkAndFire = () => {
1463
- if (fired)
1464
- return;
1465
- if (isInCanvasViewport()) {
1466
- fired = true;
1467
- fire();
1468
- }
1469
- };
1470
- // Initial checks: a single RAF fires before deeply-nested Angular components
1471
- // have settled their layout. Schedule retries so above-fold elements are
1472
- // detected even when render takes a few frames.
1473
- const rafId = requestAnimationFrame(checkAndFire);
1474
- const t1 = window.setTimeout(checkAndFire, 100);
1475
- const t2 = window.setTimeout(checkAndFire, 400);
1476
- // Lenis changes scrollTop on .preview-scroll → native scroll event fires.
1477
- // Builder also dispatches a synthetic scroll on .preview-lenis-content.
1478
- // Listen on both so we catch all scroll notifications.
1479
- const lenisEl = this.overlayService.getScrollContainer();
1480
- canvasRoot.addEventListener('scroll', checkAndFire, { passive: true });
1481
- if (lenisEl)
1482
- lenisEl.addEventListener('scroll', checkAndFire, { passive: true });
1483
- return () => {
1484
- fired = true; // stop any pending checks
1485
- cancelAnimationFrame(rafId);
1486
- clearTimeout(t1);
1487
- clearTimeout(t2);
1488
- canvasRoot.removeEventListener('scroll', checkAndFire);
1489
- if (lenisEl)
1490
- lenisEl.removeEventListener('scroll', checkAndFire);
1491
- };
1492
- }
1493
- // Production mode: standard IntersectionObserver against browser viewport.
1494
1449
  const observer = new IntersectionObserver((entries) => {
1495
1450
  for (const entry of entries) {
1496
1451
  if (entry.isIntersecting) {
1452
+ observer.disconnect();
1497
1453
  fire();
1498
1454
  }
1499
1455
  }
@@ -1660,11 +1616,7 @@ class InteractionEngineService {
1660
1616
  // Mark as hidden so the builder overlay and drag engine can ignore this element
1661
1617
  // and all of its children regardless of which entrance animation type is used.
1662
1618
  element.setAttribute('data-iox-hidden', '');
1663
- // In builder mode the overlay handles all pointer interaction — omit
1664
- // pointer-events:none so wheel events still reach Lenis and canvas scroll works.
1665
- if (!this.isBuilderMode()) {
1666
- element.style.setProperty('pointer-events', 'none');
1667
- }
1619
+ element.style.setProperty('pointer-events', 'none');
1668
1620
  this.preStatedElements.add(element);
1669
1621
  }
1670
1622
  clearInlineAnimationStyles(element) {
@@ -2774,9 +2726,13 @@ class RenderDirective {
2774
2726
  nativeEl.addEventListener('mouseenter', (event) => {
2775
2727
  if (event._fromClick)
2776
2728
  return;
2729
+ if (nativeEl.hasAttribute('data-iox-hidden'))
2730
+ return;
2777
2731
  this.onMouseEnter.emit({ element: nativeEl, node });
2778
2732
  });
2779
2733
  nativeEl.addEventListener('mouseleave', (event) => {
2734
+ if (nativeEl.hasAttribute('data-iox-hidden'))
2735
+ return;
2780
2736
  // When leaving a child component, check if the mouse moved to a
2781
2737
  // parent component (e.g. card → section). If so, emit mouseenter
2782
2738
  // for that parent instead of clearing hover entirely.
@@ -2792,12 +2748,15 @@ class RenderDirective {
2792
2748
  });
2793
2749
  nativeEl.addEventListener('click', (event) => {
2794
2750
  event.stopPropagation();
2751
+ if (nativeEl.hasAttribute('data-iox-hidden'))
2752
+ return;
2795
2753
  this.onClick.emit({ element: nativeEl, node, componentRef });
2796
2754
  });
2797
2755
  nativeEl.addEventListener('contextmenu', (event) => {
2798
2756
  event.preventDefault();
2799
2757
  event.stopPropagation();
2800
- // Select the element first, then open the more menu at cursor position.
2758
+ if (nativeEl.hasAttribute('data-iox-hidden'))
2759
+ return;
2801
2760
  this.onClick.emit({ element: nativeEl, node, componentRef });
2802
2761
  this.overlayService.triggerContextMenu(event.clientX, event.clientY);
2803
2762
  });