@vectoriox/iox-builder 1.4.45 → 1.4.46

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.
@@ -1150,9 +1150,10 @@ class InteractionEngineService {
1150
1150
  const ref = this.overlayService.getNodeRef(node);
1151
1151
  if (!ref)
1152
1152
  return;
1153
- // Apply any pre-states that were queued by other nodes that target THIS
1154
- // element with an entrance animation but registered before we did.
1155
- if (node.id) {
1153
+ const inBuilder = this.isBuilderMode();
1154
+ // Apply any pre-states queued for THIS element by earlier-registered nodes.
1155
+ // Skip in builder mode — all elements must remain visible for editing.
1156
+ if (!inBuilder && node.id) {
1156
1157
  const pending = this.pendingPreStates.get(node.id);
1157
1158
  if (pending) {
1158
1159
  for (const action of pending) {
@@ -1165,21 +1166,20 @@ class InteractionEngineService {
1165
1166
  return;
1166
1167
  const cleanups = [];
1167
1168
  for (const ix of node.interactions) {
1168
- // Apply pre-state to targets of ANY entrance animation so the element
1169
- // starts hidden regardless of whether the trigger is automatic (pageLoad,
1170
- // viewportEnter) or user-driven (click).
1171
- for (const action of ix.actions) {
1172
- if (this.ENTRANCE_TYPES.has(action.type)) {
1173
- const target = this.resolveTarget(node, action);
1174
- if (target) {
1175
- this.applyPreState(target, action);
1176
- }
1177
- else if (action.target && action.target !== 'self') {
1178
- // Target element not registered yet — queue the pre-state so
1179
- // it gets applied the moment that element's attach() fires.
1180
- const list = this.pendingPreStates.get(action.target) ?? [];
1181
- list.push(action);
1182
- this.pendingPreStates.set(action.target, list);
1169
+ // Pre-state: hide elements before their entrance animation fires.
1170
+ // Skipped in builder so elements are always editable on the canvas.
1171
+ if (!inBuilder) {
1172
+ for (const action of ix.actions) {
1173
+ if (this.ENTRANCE_TYPES.has(action.type)) {
1174
+ const target = this.resolveTarget(node, action);
1175
+ if (target) {
1176
+ this.applyPreState(target, action);
1177
+ }
1178
+ else if (action.target && action.target !== 'self') {
1179
+ const list = this.pendingPreStates.get(action.target) ?? [];
1180
+ list.push(action);
1181
+ this.pendingPreStates.set(action.target, list);
1182
+ }
1183
1183
  }
1184
1184
  }
1185
1185
  }
@@ -1251,10 +1251,23 @@ class InteractionEngineService {
1251
1251
  replay(node) {
1252
1252
  if (!node.interactions?.length)
1253
1253
  return;
1254
- // Cancel any in-progress animations first to reset the element cleanly.
1255
1254
  const ref = this.overlayService.getNodeRef(node);
1256
1255
  if (ref) {
1257
1256
  ref.element.getAnimations().forEach(a => a.cancel());
1257
+ // Clear any leftover inline styles so the pre-state applies cleanly.
1258
+ this.clearInlineAnimationStyles(ref.element);
1259
+ }
1260
+ // In builder mode pre-state is never applied on attach, so apply it now
1261
+ // to give an accurate hidden→visible preview. It is cleaned up via
1262
+ // executeAction's anim.finished handler once the animation completes.
1263
+ for (const ix of node.interactions) {
1264
+ for (const action of ix.actions) {
1265
+ if (this.ENTRANCE_TYPES.has(action.type)) {
1266
+ const target = this.resolveTarget(node, action);
1267
+ if (target)
1268
+ this.applyPreState(target, action);
1269
+ }
1270
+ }
1258
1271
  }
1259
1272
  for (const ix of node.interactions) {
1260
1273
  this.runActions(node, ix.actions);
@@ -1262,6 +1275,11 @@ class InteractionEngineService {
1262
1275
  }
1263
1276
  // ── Private ──────────────────────────────────────────────
1264
1277
  attachInteraction(node, ix, element) {
1278
+ // In builder mode, automatic triggers don't auto-fire — use the play button instead.
1279
+ // Click/hover remain active so users can test those interactions on the canvas.
1280
+ if (this.isBuilderMode() && (ix.trigger === 'pageLoad' || ix.trigger === 'viewportEnter' || ix.trigger === 'scrollProgress')) {
1281
+ return () => { };
1282
+ }
1265
1283
  switch (ix.trigger) {
1266
1284
  case 'pageLoad':
1267
1285
  return this.attachPageLoad(node, ix, element);
@@ -1317,6 +1335,9 @@ class InteractionEngineService {
1317
1335
  observer.observe(element);
1318
1336
  return () => observer.disconnect();
1319
1337
  }
1338
+ isBuilderMode() {
1339
+ return document.body.classList.contains('builder-active');
1340
+ }
1320
1341
  /** Returns true if any DOM ancestor of element is currently faded out via pre-state. */
1321
1342
  hasPreStatedAncestor(element) {
1322
1343
  let el = element.parentElement;
@@ -1405,12 +1426,13 @@ class InteractionEngineService {
1405
1426
  fill: 'both',
1406
1427
  });
1407
1428
  if (this.ENTRANCE_TYPES.has(action.type)) {
1408
- // Once the entrance animation finishes the element is fully visible —
1409
- // restore pointer events and clear the pre-state tracker so children
1410
- // waiting on this ancestor can fire their deferred animations.
1411
1429
  anim.finished.then(() => {
1412
1430
  element.style.removeProperty('pointer-events');
1413
1431
  this.preStatedElements.delete(element);
1432
+ // Builder: clear inline pre-state so cancelling animations later
1433
+ // doesn't leave the element invisible after a play preview.
1434
+ if (this.isBuilderMode())
1435
+ this.clearInlineAnimationStyles(element);
1414
1436
  }).catch(() => { });
1415
1437
  }
1416
1438
  else if (this.EXIT_TYPES.has(action.type)) {