@amplifyup/sdk 0.1.16 → 0.1.18

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.
package/dist/index.js CHANGED
@@ -360,6 +360,9 @@ var AmplifyUpSDK = class {
360
360
  this.attachedEventListeners = [];
361
361
  this.trackingIntervals = [];
362
362
  this.trackingCleanup = null;
363
+ this.componentViewObservers = [];
364
+ this.componentViewSeen = /* @__PURE__ */ new Set();
365
+ this.pageEngagementActive = false;
363
366
  this.adapter = adapter || new AWSAdapter();
364
367
  if (typeof window !== "undefined") {
365
368
  this.isVisualEditorMode = this.detectVisualEditorMode();
@@ -532,6 +535,7 @@ var AmplifyUpSDK = class {
532
535
  this.initialPageSent = true;
533
536
  const url = window.location.pathname;
534
537
  this.page(url);
538
+ this.setupPageEngagement();
535
539
  }
536
540
  }
537
541
  if (this.config?.debug && this.initialized) {
@@ -564,6 +568,168 @@ var AmplifyUpSDK = class {
564
568
  }
565
569
  this.trackingIntervals.forEach((id) => clearInterval(id));
566
570
  this.trackingIntervals = [];
571
+ this.cleanupComponentViewTracking();
572
+ this.pageEngagementActive = false;
573
+ }
574
+ /** Current page path for engagement attribution. */
575
+ currentPath() {
576
+ if (typeof window === "undefined") return "/";
577
+ return window.location.pathname || "/";
578
+ }
579
+ /**
580
+ * Automatic page-level Scroll Depth + Time on Page (dwell heartbeat).
581
+ */
582
+ setupPageEngagement() {
583
+ if (typeof window === "undefined" || typeof document === "undefined") return;
584
+ if (this.isPreviewMode() || this.pageEngagementActive) return;
585
+ this.pageEngagementActive = true;
586
+ const milestones = [25, 50, 75, 100];
587
+ const reached = /* @__PURE__ */ new Set();
588
+ let visibleMs = 0;
589
+ let visibleSince = document.visibilityState === "visible" ? Date.now() : null;
590
+ let lastDwellSecondsSent = 0;
591
+ let scrollRaf = null;
592
+ const path = () => this.currentPath();
593
+ const measureScrollPercent = () => {
594
+ const doc = document.documentElement;
595
+ const body = document.body;
596
+ const scrollTop = window.scrollY || doc.scrollTop || body?.scrollTop || 0;
597
+ const scrollHeight = Math.max(
598
+ doc.scrollHeight,
599
+ body?.scrollHeight || 0,
600
+ doc.offsetHeight,
601
+ body?.offsetHeight || 0
602
+ );
603
+ const clientHeight = window.innerHeight || doc.clientHeight || 0;
604
+ const traversable = Math.max(scrollHeight - clientHeight, 0);
605
+ if (traversable <= 0) return 100;
606
+ return Math.min(100, Math.round(scrollTop / traversable * 100));
607
+ };
608
+ const checkScroll = () => {
609
+ if (this.isPreviewMode()) return;
610
+ const pct = measureScrollPercent();
611
+ for (const milestone of milestones) {
612
+ if (pct >= milestone && !reached.has(milestone)) {
613
+ reached.add(milestone);
614
+ this.track("Scroll Depth", {
615
+ percentage: milestone,
616
+ path: path()
617
+ });
618
+ }
619
+ }
620
+ };
621
+ const onScroll = () => {
622
+ if (scrollRaf != null) return;
623
+ scrollRaf = window.requestAnimationFrame(() => {
624
+ scrollRaf = null;
625
+ checkScroll();
626
+ });
627
+ };
628
+ const accumulateVisible = () => {
629
+ if (visibleSince == null) return;
630
+ visibleMs += Date.now() - visibleSince;
631
+ visibleSince = Date.now();
632
+ };
633
+ const emitDwell = (force = false) => {
634
+ if (this.isPreviewMode()) return;
635
+ accumulateVisible();
636
+ const seconds = Math.floor(visibleMs / 1e3);
637
+ if (seconds <= 0) return;
638
+ if (!force && seconds <= lastDwellSecondsSent) return;
639
+ lastDwellSecondsSent = seconds;
640
+ this.track("Time on Page", {
641
+ seconds,
642
+ path: path()
643
+ });
644
+ };
645
+ const onVisibility = () => {
646
+ if (document.visibilityState === "visible") {
647
+ visibleSince = Date.now();
648
+ } else {
649
+ emitDwell(true);
650
+ visibleSince = null;
651
+ }
652
+ };
653
+ const onPageHide = () => {
654
+ emitDwell(true);
655
+ };
656
+ window.addEventListener("scroll", onScroll, { passive: true });
657
+ document.addEventListener("visibilitychange", onVisibility);
658
+ window.addEventListener("pagehide", onPageHide);
659
+ checkScroll();
660
+ const heartbeat = setInterval(() => {
661
+ if (document.visibilityState === "visible") {
662
+ emitDwell(false);
663
+ }
664
+ }, 15e3);
665
+ this.trackingIntervals.push(heartbeat);
666
+ const previousCleanup = this.trackingCleanup;
667
+ this.trackingCleanup = () => {
668
+ window.removeEventListener("scroll", onScroll);
669
+ document.removeEventListener("visibilitychange", onVisibility);
670
+ window.removeEventListener("pagehide", onPageHide);
671
+ if (scrollRaf != null) {
672
+ window.cancelAnimationFrame(scrollRaf);
673
+ scrollRaf = null;
674
+ }
675
+ previousCleanup?.();
676
+ this.pageEngagementActive = false;
677
+ };
678
+ if (this.config?.debug) {
679
+ console.log("[AmplifyUp SDK] Page engagement tracking enabled");
680
+ }
681
+ }
682
+ /**
683
+ * Automatic Component View when component hosts enter the viewport.
684
+ */
685
+ setupComponentViewTracking() {
686
+ if (typeof document === "undefined" || typeof IntersectionObserver === "undefined") {
687
+ return;
688
+ }
689
+ if (this.isPreviewMode()) return;
690
+ this.cleanupComponentViewTracking();
691
+ const hosts = document.querySelectorAll("[data-amplifyup-component]");
692
+ if (hosts.length === 0) {
693
+ if (this.config?.debug) {
694
+ console.log("[AmplifyUp SDK] No component hosts found for Component View");
695
+ }
696
+ return;
697
+ }
698
+ const observer = new IntersectionObserver(
699
+ (entries) => {
700
+ entries.forEach((entry) => {
701
+ if (!entry.isIntersecting) return;
702
+ const el = entry.target;
703
+ const componentId = el.getAttribute("data-amplifyup-component") || el.getAttribute("data-component-id");
704
+ if (!componentId || this.componentViewSeen.has(componentId)) {
705
+ observer.unobserve(el);
706
+ return;
707
+ }
708
+ this.componentViewSeen.add(componentId);
709
+ const componentName = el.getAttribute("data-component-name") || void 0;
710
+ this.track("Component View", {
711
+ componentId,
712
+ componentName,
713
+ path: this.currentPath()
714
+ });
715
+ observer.unobserve(el);
716
+ });
717
+ },
718
+ { threshold: 0.5 }
719
+ );
720
+ hosts.forEach((host) => observer.observe(host));
721
+ this.componentViewObservers.push(observer);
722
+ if (this.config?.debug) {
723
+ console.log(
724
+ "[AmplifyUp SDK] Component View tracking enabled for",
725
+ hosts.length,
726
+ "hosts"
727
+ );
728
+ }
729
+ }
730
+ cleanupComponentViewTracking() {
731
+ this.componentViewObservers.forEach((obs) => obs.disconnect());
732
+ this.componentViewObservers = [];
567
733
  }
568
734
  /**
569
735
  * Track a page view
@@ -603,9 +769,13 @@ var AmplifyUpSDK = class {
603
769
  instanceId,
604
770
  trackingId: this.config?.trackingId,
605
771
  url: typeof window !== "undefined" ? window.location.href : void 0,
772
+ path: properties?.path || (typeof window !== "undefined" ? window.location.pathname : void 0),
606
773
  // Timestamp is included in event payload
607
774
  ...properties
608
775
  };
776
+ if (!trackProperties.path && typeof window !== "undefined") {
777
+ trackProperties.path = window.location.pathname;
778
+ }
609
779
  this.adapter.track(eventName, trackProperties);
610
780
  }
611
781
  /**
@@ -894,6 +1064,13 @@ Available Console Commands:
894
1064
  if (pageConfig?.eventTracking) {
895
1065
  this.setupEventTracking(pageConfig.eventTracking);
896
1066
  }
1067
+ if (typeof window !== "undefined") {
1068
+ window.setTimeout(() => this.setupComponentViewTracking(), 150);
1069
+ window.setTimeout(() => {
1070
+ this.setupComponentViewTracking();
1071
+ this.refreshEventTracking();
1072
+ }, 800);
1073
+ }
897
1074
  return pageConfig;
898
1075
  }
899
1076
  /**
@@ -901,10 +1078,10 @@ Available Console Commands:
901
1078
  */
902
1079
  setupEventTracking(eventConfig) {
903
1080
  if (typeof document === "undefined") return;
904
- this.cleanupEventTracking();
905
- this.eventTrackingConfig = eventConfig;
1081
+ this.detachEventListeners();
1082
+ this.eventTrackingConfig = Array.isArray(eventConfig) ? [...eventConfig] : [];
906
1083
  if (this.config?.debug) {
907
- console.log("[AmplifyUp SDK] Setting up event tracking:", eventConfig.length, "events");
1084
+ console.log("[AmplifyUp SDK] Setting up event tracking:", this.eventTrackingConfig.length, "events");
908
1085
  }
909
1086
  if (document.readyState === "loading") {
910
1087
  document.addEventListener("DOMContentLoaded", () => this.attachEventListeners());
@@ -919,19 +1096,35 @@ Available Console Commands:
919
1096
  if (typeof document === "undefined") return;
920
1097
  this.eventTrackingConfig.forEach((eventConfig) => {
921
1098
  if (eventConfig.enabled === false) return;
1099
+ if (!eventConfig.selector) {
1100
+ if (this.config?.debug) {
1101
+ console.warn(`[AmplifyUp SDK] Event ${eventConfig.eventName} has no selector, skipping`);
1102
+ }
1103
+ return;
1104
+ }
922
1105
  let targetElements = [];
923
- if (eventConfig.selector) {
924
- try {
925
- targetElements = document.querySelectorAll(eventConfig.selector);
926
- } catch (e) {
1106
+ try {
1107
+ const escapeAttr = (value) => typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(value) : value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1108
+ const scopeRoot = eventConfig.componentId ? document.querySelector(
1109
+ `[data-amplifyup-component="${escapeAttr(eventConfig.componentId)}"], [data-component-id="${escapeAttr(eventConfig.componentId)}"]`
1110
+ ) : document;
1111
+ if (!scopeRoot) {
927
1112
  if (this.config?.debug) {
928
- console.warn(`[AmplifyUp SDK] Invalid selector: ${eventConfig.selector}`, e);
1113
+ console.log(
1114
+ `[AmplifyUp SDK] Component host not found for ${eventConfig.componentId}`
1115
+ );
929
1116
  }
930
1117
  return;
931
1118
  }
932
- } else {
1119
+ targetElements = Array.from(
1120
+ scopeRoot.querySelectorAll(eventConfig.selector)
1121
+ );
1122
+ if (scopeRoot instanceof Element && scopeRoot !== document.documentElement && scopeRoot.matches?.(eventConfig.selector)) {
1123
+ targetElements.unshift(scopeRoot);
1124
+ }
1125
+ } catch (e) {
933
1126
  if (this.config?.debug) {
934
- console.warn(`[AmplifyUp SDK] Event ${eventConfig.eventName} has no selector, skipping`);
1127
+ console.warn(`[AmplifyUp SDK] Invalid selector: ${eventConfig.selector}`, e);
935
1128
  }
936
1129
  return;
937
1130
  }
@@ -987,8 +1180,15 @@ Available Console Commands:
987
1180
  handleTrackedEvent(event, config, element) {
988
1181
  const properties = {
989
1182
  eventType: config.eventType,
990
- selector: config.selector
1183
+ selector: config.selector,
1184
+ path: this.currentPath()
991
1185
  };
1186
+ if (config.componentId) {
1187
+ properties.componentId = config.componentId;
1188
+ }
1189
+ if (config.componentName) {
1190
+ properties.componentName = config.componentName;
1191
+ }
992
1192
  if (config.properties && config.properties.length > 0) {
993
1193
  config.properties.forEach((prop) => {
994
1194
  const dataAttrValue = element.getAttribute(`data-${prop}`);
@@ -1059,9 +1259,9 @@ Available Console Commands:
1059
1259
  element._amplifyupViewObserver = observer;
1060
1260
  }
1061
1261
  /**
1062
- * Clean up all attached event listeners
1262
+ * Detach listeners/observers without clearing the saved event config.
1063
1263
  */
1064
- cleanupEventTracking() {
1264
+ detachEventListeners() {
1065
1265
  this.attachedEventListeners.forEach(({ element, eventType, handler }) => {
1066
1266
  element.removeEventListener(eventType, handler);
1067
1267
  });
@@ -1075,6 +1275,12 @@ Available Console Commands:
1075
1275
  }
1076
1276
  });
1077
1277
  }
1278
+ }
1279
+ /**
1280
+ * Clean up all attached event listeners and clear config
1281
+ */
1282
+ cleanupEventTracking() {
1283
+ this.detachEventListeners();
1078
1284
  this.eventTrackingConfig = [];
1079
1285
  if (this.config?.debug) {
1080
1286
  console.log("[AmplifyUp SDK] Cleaned up event tracking");
@@ -1084,11 +1290,13 @@ Available Console Commands:
1084
1290
  * Manually trigger event tracking setup (useful after dynamic content loads)
1085
1291
  */
1086
1292
  refreshEventTracking() {
1087
- if (this.eventTrackingConfig.length > 0) {
1088
- this.cleanupEventTracking();
1089
- const config = [...this.eventTrackingConfig];
1090
- this.eventTrackingConfig = config;
1091
- this.attachEventListeners();
1293
+ if (this.eventTrackingConfig.length === 0) return;
1294
+ const config = [...this.eventTrackingConfig];
1295
+ this.detachEventListeners();
1296
+ this.eventTrackingConfig = config;
1297
+ this.attachEventListeners();
1298
+ if (this.config?.debug) {
1299
+ console.log("[AmplifyUp SDK] Refreshed event tracking:", config.length, "events");
1092
1300
  }
1093
1301
  }
1094
1302
  /** Origins allowed to send Composer postMessage commands to the SDK. */
@@ -1199,6 +1407,10 @@ Available Console Commands:
1199
1407
  this.clearComposerDragHighlight();
1200
1408
  return;
1201
1409
  }
1410
+ if (event.data?.type === "CLEAR_SELECTION") {
1411
+ this.clearComposerSelection();
1412
+ return;
1413
+ }
1202
1414
  if (event.data?.type === "GET_ELEMENT_POSITION") {
1203
1415
  const { componentId, slotName, nodeId, isPageSlot } = event.data;
1204
1416
  let element = null;
@@ -1240,6 +1452,7 @@ Available Console Commands:
1240
1452
  found: !!element
1241
1453
  });
1242
1454
  if (element) {
1455
+ this.markComposerSelection(element);
1243
1456
  const rect = element.getBoundingClientRect();
1244
1457
  const position = {
1245
1458
  x: rect.left + rect.width / 2,
@@ -1307,6 +1520,7 @@ Available Console Commands:
1307
1520
  break;
1308
1521
  case "SHOW_COMPONENT_TOOLTIP":
1309
1522
  case "HIDE_ALL_TOOLTIPS":
1523
+ this.clearComposerSelection();
1310
1524
  break;
1311
1525
  case "ENABLE_EVENT_SELECTION":
1312
1526
  console.log("[AmplifyUp SDK] Enable event selection mode:", message.enabled);
@@ -1544,29 +1758,46 @@ Available Console Commands:
1544
1758
  */
1545
1759
  enableHighlighting(componentRegistry, highlightComponents, showZones) {
1546
1760
  if (typeof document === "undefined") return;
1761
+ const previouslySelected = Array.from(
1762
+ document.querySelectorAll(".amplifyup-selected")
1763
+ );
1547
1764
  this.componentRegistry = componentRegistry;
1548
1765
  this.highlightingEnabled = true;
1549
1766
  this.highlightComponentsEnabled = highlightComponents;
1550
1767
  this.showZonesEnabled = showZones;
1551
- this.disableHighlighting();
1768
+ this.disableHighlighting({ clearSelection: false });
1552
1769
  this.highlightingEnabled = true;
1553
1770
  this.injectComposerHighlightStyles(highlightComponents, showZones);
1554
1771
  if (highlightComponents || showZones) {
1555
1772
  this.applyComponentHighlights(highlightComponents, showZones);
1556
1773
  this.setupMutationObserver();
1557
- }
1558
- if (showZones) {
1559
1774
  this.setupComposerDragDrop();
1560
1775
  }
1776
+ previouslySelected.forEach((el) => {
1777
+ if (document.contains(el)) {
1778
+ el.classList.add("amplifyup-selected");
1779
+ }
1780
+ });
1561
1781
  }
1562
1782
  /** Document-level drag/drop for cross-iframe drags from Composer sidebar. */
1563
1783
  setupComposerDragDrop() {
1564
1784
  if (typeof document === "undefined") return;
1565
1785
  this.teardownComposerDragDrop();
1566
1786
  const slotSelector = "[data-slot-id], [data-amplifyup-slot]";
1787
+ const componentSelector = "[data-amplifyup-component], [data-component-id]";
1567
1788
  const clearDragOverState = () => {
1568
1789
  this.clearComposerDragHighlight();
1569
1790
  };
1791
+ const clearComponentHover = () => {
1792
+ document.querySelectorAll(".amplifyup-component-hover").forEach((el) => {
1793
+ el.classList.remove("amplifyup-component-hover");
1794
+ });
1795
+ };
1796
+ const clearSlotHover = () => {
1797
+ document.querySelectorAll(`${slotSelector}.amplifyup-slot-hover`).forEach((el) => {
1798
+ el.classList.remove("amplifyup-slot-hover");
1799
+ });
1800
+ };
1570
1801
  const dragenter = (e) => {
1571
1802
  e.preventDefault();
1572
1803
  };
@@ -1597,31 +1828,59 @@ Available Console Commands:
1597
1828
  this.postDropOnSlot(slot);
1598
1829
  };
1599
1830
  const mouseover = (e) => {
1600
- if (!this.showZonesEnabled) return;
1831
+ if (!this.highlightComponentsEnabled && !this.showZonesEnabled) return;
1601
1832
  const target = e.target;
1602
- const slot = target?.closest?.(slotSelector);
1603
- if (!slot) return;
1604
- document.querySelectorAll(`${slotSelector}.amplifyup-slot-hover`).forEach((el) => {
1605
- el.classList.remove("amplifyup-slot-hover");
1606
- });
1607
- slot.classList.add("amplifyup-slot-hover");
1833
+ if (!target?.closest) return;
1834
+ const component = target.closest(componentSelector);
1835
+ const slot = target.closest(slotSelector);
1836
+ if (this.highlightComponentsEnabled && component) {
1837
+ if (!component.classList.contains("amplifyup-component-hover")) {
1838
+ clearComponentHover();
1839
+ component.classList.add("amplifyup-component-hover");
1840
+ }
1841
+ if (slot && !component.contains(slot)) {
1842
+ clearSlotHover();
1843
+ }
1844
+ return;
1845
+ }
1846
+ clearComponentHover();
1847
+ if (this.showZonesEnabled && slot) {
1848
+ if (!slot.classList.contains("amplifyup-slot-hover")) {
1849
+ clearSlotHover();
1850
+ slot.classList.add("amplifyup-slot-hover");
1851
+ }
1852
+ }
1608
1853
  };
1609
1854
  const mouseout = (e) => {
1610
- if (!this.showZonesEnabled) return;
1855
+ if (!this.highlightComponentsEnabled && !this.showZonesEnabled) return;
1611
1856
  const related = e.relatedTarget;
1612
- if (!related?.closest?.(slotSelector)) {
1613
- document.querySelectorAll(`${slotSelector}.amplifyup-slot-hover`).forEach((el) => {
1614
- el.classList.remove("amplifyup-slot-hover");
1615
- });
1857
+ if (this.highlightComponentsEnabled) {
1858
+ if (!related?.closest?.(componentSelector)) {
1859
+ clearComponentHover();
1860
+ }
1861
+ }
1862
+ if (this.showZonesEnabled) {
1863
+ if (!related?.closest?.(slotSelector)) {
1864
+ clearSlotHover();
1865
+ }
1616
1866
  }
1617
1867
  };
1618
- document.addEventListener("dragenter", dragenter, false);
1619
- document.addEventListener("dragover", dragover, false);
1620
- document.addEventListener("dragleave", dragleave, false);
1621
- document.addEventListener("drop", drop, false);
1622
1868
  document.addEventListener("mouseover", mouseover, true);
1623
1869
  document.addEventListener("mouseout", mouseout, true);
1624
- this.composerDragHandlers = { dragenter, dragover, dragleave, drop, mouseover, mouseout };
1870
+ if (this.showZonesEnabled) {
1871
+ document.addEventListener("dragenter", dragenter, false);
1872
+ document.addEventListener("dragover", dragover, false);
1873
+ document.addEventListener("dragleave", dragleave, false);
1874
+ document.addEventListener("drop", drop, false);
1875
+ }
1876
+ this.composerDragHandlers = {
1877
+ dragenter,
1878
+ dragover,
1879
+ dragleave,
1880
+ drop,
1881
+ mouseover,
1882
+ mouseout
1883
+ };
1625
1884
  }
1626
1885
  teardownComposerDragDrop() {
1627
1886
  if (!this.composerDragHandlers || typeof document === "undefined") return;
@@ -1644,6 +1903,20 @@ Available Console Commands:
1644
1903
  document.querySelectorAll("[data-slot-id].amplifyup-slot-hover, [data-amplifyup-slot].amplifyup-slot-hover").forEach((el) => {
1645
1904
  el.classList.remove("amplifyup-slot-hover");
1646
1905
  });
1906
+ document.querySelectorAll(".amplifyup-component-hover").forEach((el) => {
1907
+ el.classList.remove("amplifyup-component-hover");
1908
+ });
1909
+ }
1910
+ clearComposerSelection() {
1911
+ if (typeof document === "undefined") return;
1912
+ document.querySelectorAll(
1913
+ "[data-slot-id].amplifyup-selected, [data-amplifyup-slot].amplifyup-selected, [data-amplifyup-component].amplifyup-selected, [data-component-id].amplifyup-selected"
1914
+ ).forEach((el) => el.classList.remove("amplifyup-selected"));
1915
+ }
1916
+ markComposerSelection(element) {
1917
+ if (typeof document === "undefined") return;
1918
+ this.clearComposerSelection();
1919
+ element.classList.add("amplifyup-selected");
1647
1920
  }
1648
1921
  /** Visual outlines for Composer (direct iframe path — no preview-frame proxy). */
1649
1922
  injectComposerHighlightStyles(highlightComponents, showZones) {
@@ -1651,16 +1924,29 @@ Available Console Commands:
1651
1924
  if (!highlightComponents && !showZones) return;
1652
1925
  const existing = document.getElementById("amplifyup-preview-highlights");
1653
1926
  if (existing) existing.remove();
1927
+ const primary = "hsl(82 92% 42%)";
1654
1928
  const lines = [];
1655
1929
  if (highlightComponents) {
1656
1930
  lines.push(
1657
1931
  "[data-amplifyup-component], [data-component-id] {",
1658
- " outline: 1px dashed rgba(59, 130, 246, 0.8) !important;",
1659
- " outline-offset: 2px !important;",
1660
1932
  " cursor: pointer !important;",
1661
1933
  "}",
1662
- "[data-amplifyup-component]:hover, [data-component-id]:hover {",
1663
- " outline-color: rgba(59, 130, 246, 1) !important;",
1934
+ "[data-amplifyup-component].amplifyup-selected, [data-component-id].amplifyup-selected {",
1935
+ ` outline: 2px solid ${primary} !important;`,
1936
+ " outline-offset: -2px !important;",
1937
+ " box-shadow: inset 0 0 0 1px hsl(82 92% 42% / 0.25) !important;",
1938
+ "}",
1939
+ "[data-amplifyup-component].amplifyup-component-hover:not(.amplifyup-selected),",
1940
+ "[data-component-id].amplifyup-component-hover:not(.amplifyup-selected) {",
1941
+ ` outline: 2px solid ${primary} !important;`,
1942
+ " outline-offset: -2px !important;",
1943
+ "}"
1944
+ );
1945
+ }
1946
+ if (highlightComponents || showZones) {
1947
+ lines.push(
1948
+ "[data-slot-id].amplifyup-selected, [data-amplifyup-slot].amplifyup-selected {",
1949
+ " background-color: rgba(245, 245, 220, 0.35) !important;",
1664
1950
  "}"
1665
1951
  );
1666
1952
  }
@@ -1795,8 +2081,9 @@ Available Console Commands:
1795
2081
  /**
1796
2082
  * Disable component highlighting
1797
2083
  */
1798
- disableHighlighting() {
2084
+ disableHighlighting(opts) {
1799
2085
  if (typeof document === "undefined") return;
2086
+ const clearSelection = opts?.clearSelection !== false;
1800
2087
  this.highlightingEnabled = false;
1801
2088
  this.teardownComposerDragDrop();
1802
2089
  if (this.mutationObserver) {
@@ -1825,10 +2112,10 @@ Available Console Commands:
1825
2112
  delete htmlEl._amplifyupSlotHandlers;
1826
2113
  htmlEl.classList.remove("amplifyup-slot-highlight");
1827
2114
  });
2115
+ if (clearSelection) {
2116
+ this.clearComposerSelection();
2117
+ }
1828
2118
  }
1829
- /**
1830
- * Build component hierarchy for ancestor selection
1831
- */
1832
2119
  buildComponentHierarchy(element) {
1833
2120
  const hierarchy = [];
1834
2121
  let current = element;
@@ -1892,6 +2179,7 @@ Available Console Commands:
1892
2179
  window.parent.postMessage(message, "*");
1893
2180
  console.log("[AmplifyUp SDK] Sent selection message:", message);
1894
2181
  }
2182
+ this.markComposerSelection(element);
1895
2183
  }
1896
2184
  /**
1897
2185
  * Send component tree to orchestrator
@@ -2024,6 +2312,7 @@ var fetchPageConfig = (route, preview) => getSDK().fetchPageConfig(route, previe
2024
2312
  var setupEventTracking = (config) => getSDK().setupEventTracking(config);
2025
2313
  var cleanupEventTracking = () => getSDK().cleanupEventTracking();
2026
2314
  var refreshEventTracking = () => getSDK().refreshEventTracking();
2315
+ var setupComponentViewTracking = () => getSDK().setupComponentViewTracking();
2027
2316
  var getDiagnostics = () => getSDK().getDiagnostics();
2028
2317
  var getStatus = () => {
2029
2318
  const status = getSDK().getStatus();
@@ -2064,6 +2353,7 @@ exports.refreshEventTracking = refreshEventTracking;
2064
2353
  exports.reset = reset;
2065
2354
  exports.resolveAmplifyUpTarget = resolveAmplifyUpTarget;
2066
2355
  exports.resolveAmplifyUpUrls = resolveAmplifyUpUrls;
2356
+ exports.setupComponentViewTracking = setupComponentViewTracking;
2067
2357
  exports.setupEventTracking = setupEventTracking;
2068
2358
  exports.testTracking = testTracking;
2069
2359
  exports.track = track;