@eric-emg/symphiq-components 1.2.45 → 1.2.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.
@@ -21632,27 +21632,23 @@ class SymphiqFunnelAnalysisDashboardComponent {
21632
21632
  // Manage overall assessment loading state during view mode transitions
21633
21633
  }
21634
21634
  ngAfterViewInit() {
21635
- console.log('[DASHBOARD v5] ngAfterViewInit called', {
21636
- embedded: this.embedded(),
21637
- scrollContainerId: this.scrollContainerId(),
21638
- isScrolled: this.isScrolled(),
21639
- viewMode: this.viewMode()
21640
- });
21635
+ console.log('[DASHBOARD v6] ngAfterViewInit - event-driven scroll approach');
21641
21636
  // Ensure modal has data after view is initialized
21642
21637
  if (this.modalComponent) {
21643
21638
  this.modalComponent.setMetricsAndInsights(this.allMetrics(), this.insights(), this.allCharts());
21644
21639
  }
21645
- // Set up container scroll listener when in embedded mode
21640
+ // v6 - Pure event-driven scroll detection
21641
+ // No initial state checking, no timeouts, no ResizeObserver
21642
+ // Header state only updates on actual scroll events
21646
21643
  if (this.embedded()) {
21647
21644
  let container = null;
21648
- // If a scroll container ID is provided, use that element
21649
21645
  if (this.scrollContainerId()) {
21650
21646
  const setupScrollContainer = () => {
21651
21647
  const element = document.getElementById(this.scrollContainerId());
21652
- console.log('[SCROLL DEBUG v2] setupScrollContainer attempt', {
21648
+ console.log('[SCROLL v6] Setup attempt', {
21653
21649
  scrollContainerId: this.scrollContainerId(),
21654
- elementFound: !!element,
21655
- elementTag: element?.tagName
21650
+ found: !!element,
21651
+ tag: element?.tagName
21656
21652
  });
21657
21653
  if (!element) {
21658
21654
  return false;
@@ -21660,248 +21656,42 @@ class SymphiqFunnelAnalysisDashboardComponent {
21660
21656
  // Check if this is an Ionic ion-content element
21661
21657
  if (element.tagName.toLowerCase() === 'ion-content') {
21662
21658
  const ionContent = element;
21663
- // Get the scrollable element from Ionic
21664
21659
  if (typeof ionContent.getScrollElement === 'function') {
21665
21660
  ionContent.getScrollElement().then((scrollElement) => {
21666
- console.log('[SCROLL DEBUG v2] Ionic scroll element found', {
21667
- scrollTop: scrollElement.scrollTop,
21668
- scrollHeight: scrollElement.scrollHeight,
21669
- clientHeight: scrollElement.clientHeight
21670
- });
21671
- // Store reference for use in scrollToSection and tooltips
21661
+ console.log('[SCROLL v6] Ionic scroll element ready - attaching listeners');
21662
+ // Store reference for tooltips and programmatic scrolling
21672
21663
  this.embeddedScrollContainer = scrollElement;
21673
21664
  this.tooltipService.setScrollContainer(scrollElement);
21674
- // Helper function to check and update scroll state
21675
- const checkInitialScroll = () => {
21676
- const currentScrollTop = scrollElement.scrollTop;
21677
- const scrollHeight = scrollElement.scrollHeight;
21678
- const clientHeight = scrollElement.clientHeight;
21679
- console.log('[SCROLL DEBUG v5] Checking initial scroll position', {
21680
- scrollTop: currentScrollTop,
21681
- scrollHeight,
21682
- clientHeight,
21683
- shouldCollapse: currentScrollTop > 50
21684
- });
21685
- // Only make a decision if we have substantial content
21686
- if (scrollHeight < 500) {
21687
- console.log('[SCROLL DEBUG v5] Content too small, skipping check');
21688
- return;
21689
- }
21690
- if (currentScrollTop > 50) {
21691
- console.log('[SCROLL DEBUG v5] Collapsing header due to scroll position', { currentScrollTop });
21692
- this.isScrolled.set(true);
21693
- }
21694
- else {
21695
- console.log('[SCROLL DEBUG v5] Expanding header due to scroll position', { currentScrollTop });
21696
- this.isScrolled.set(false);
21697
- }
21698
- };
21699
- // Use ResizeObserver to detect when content has finished rendering
21700
- // Only check scroll position once content has substantial height
21701
- const MIN_CONTENT_HEIGHT = 500; // Content should be at least this tall before we check scroll
21702
- let lastHeight = scrollElement.scrollHeight;
21703
- let stableCount = 0;
21704
- let scrollCheckTimeout = null;
21705
- const resizeObserver = new ResizeObserver(() => {
21706
- const currentHeight = scrollElement.scrollHeight;
21707
- console.log('[SCROLL DEBUG v5] Content height changed', {
21708
- lastHeight,
21709
- currentHeight,
21710
- stableCount,
21711
- minHeightReached: currentHeight >= MIN_CONTENT_HEIGHT
21712
- });
21713
- // Clear any pending scroll check
21714
- if (scrollCheckTimeout) {
21715
- clearTimeout(scrollCheckTimeout);
21716
- }
21717
- // Only start checking when we have substantial content
21718
- if (currentHeight >= MIN_CONTENT_HEIGHT) {
21719
- if (currentHeight === lastHeight) {
21720
- stableCount++;
21721
- // Height has been stable for 2 consecutive observations
21722
- if (stableCount >= 2) {
21723
- console.log('[SCROLL DEBUG v5] Content height stabilized, scheduling scroll check');
21724
- // Wait longer for Ionic to restore scroll position
21725
- scrollCheckTimeout = setTimeout(() => {
21726
- console.log('[SCROLL DEBUG v5] Performing delayed scroll check after stabilization');
21727
- checkInitialScroll();
21728
- }, 150);
21729
- resizeObserver.disconnect();
21730
- }
21731
- }
21732
- else {
21733
- stableCount = 0;
21734
- lastHeight = currentHeight;
21735
- // Schedule a check after height change
21736
- scrollCheckTimeout = setTimeout(() => {
21737
- console.log('[SCROLL DEBUG v5] Checking scroll after height change');
21738
- checkInitialScroll();
21739
- }, 100);
21740
- }
21741
- }
21742
- else {
21743
- // Reset tracking if height drops below threshold (component being destroyed)
21744
- stableCount = 0;
21745
- lastHeight = currentHeight;
21746
- }
21747
- });
21748
- // Observe the scroll element for size changes
21749
- resizeObserver.observe(scrollElement);
21750
- // Check immediately if we already have content, but allow time for scroll restoration
21751
- if (scrollElement.scrollHeight >= MIN_CONTENT_HEIGHT) {
21752
- scrollCheckTimeout = setTimeout(() => {
21753
- console.log('[SCROLL DEBUG v5] Initial scroll check after delay');
21754
- checkInitialScroll();
21755
- }, 200);
21756
- }
21757
- // Attach scroll listeners
21665
+ // v6 - Only attach scroll event listeners, no initial state setting
21758
21666
  scrollElement.addEventListener('scroll', () => this.onContainerScroll(scrollElement), { passive: true });
21759
21667
  ionContent.addEventListener('ionScroll', () => this.onContainerScroll(scrollElement), { passive: true });
21760
- // Polling fallback for reliable scroll detection
21761
- let lastScrollTop = 0;
21762
- const pollScroll = () => {
21763
- const currentScrollTop = scrollElement.scrollTop;
21764
- if (currentScrollTop !== lastScrollTop) {
21765
- lastScrollTop = currentScrollTop;
21766
- this.onContainerScroll(scrollElement);
21767
- }
21768
- requestAnimationFrame(pollScroll);
21769
- };
21770
- requestAnimationFrame(pollScroll);
21668
+ console.log('[SCROLL v6] Event listeners attached - header responsive to scroll');
21771
21669
  }).catch((error) => {
21772
- console.error('Error getting Ionic scroll element:', error);
21670
+ console.error('[SCROLL v6] Error getting Ionic scroll element:', error);
21773
21671
  });
21774
21672
  return true;
21775
21673
  }
21776
21674
  else {
21777
21675
  // Fallback for older Ionic versions
21778
- console.log('[SCROLL DEBUG v2] Using fallback for older Ionic', {
21779
- scrollTop: element.scrollTop
21780
- });
21676
+ console.log('[SCROLL v6] Using fallback for older Ionic');
21781
21677
  this.embeddedScrollContainer = element;
21782
21678
  this.tooltipService.setScrollContainer(element);
21783
- // Helper function to check and update scroll state
21784
- const checkInitialScroll = () => {
21785
- const currentScrollTop = element.scrollTop;
21786
- console.log('[SCROLL DEBUG v2] Checking initial scroll position (fallback)', {
21787
- scrollTop: currentScrollTop,
21788
- shouldCollapse: currentScrollTop > 50
21789
- });
21790
- if (currentScrollTop > 50) {
21791
- console.log('[SCROLL DEBUG v2] Collapsing header due to scroll position', { currentScrollTop });
21792
- this.isScrolled.set(true);
21793
- }
21794
- else {
21795
- console.log('[SCROLL DEBUG v2] Expanding header due to scroll position', { currentScrollTop });
21796
- this.isScrolled.set(false);
21797
- }
21798
- };
21799
- // Use ResizeObserver to detect when content has finished rendering
21800
- const MIN_CONTENT_HEIGHT = 500;
21801
- let lastHeight = element.scrollHeight;
21802
- let stableCount = 0;
21803
- const resizeObserver = new ResizeObserver(() => {
21804
- const currentHeight = element.scrollHeight;
21805
- console.log('[SCROLL DEBUG v2] Content height changed (fallback)', {
21806
- lastHeight,
21807
- currentHeight,
21808
- stableCount,
21809
- minHeightReached: currentHeight >= MIN_CONTENT_HEIGHT
21810
- });
21811
- if (currentHeight >= MIN_CONTENT_HEIGHT) {
21812
- if (currentHeight === lastHeight) {
21813
- stableCount++;
21814
- if (stableCount >= 2) {
21815
- console.log('[SCROLL DEBUG v2] Content height stabilized (fallback), checking scroll position');
21816
- checkInitialScroll();
21817
- resizeObserver.disconnect();
21818
- }
21819
- }
21820
- else {
21821
- stableCount = 0;
21822
- lastHeight = currentHeight;
21823
- checkInitialScroll();
21824
- }
21825
- }
21826
- else {
21827
- stableCount = 0;
21828
- lastHeight = currentHeight;
21829
- }
21830
- });
21831
- resizeObserver.observe(element);
21832
- if (element.scrollHeight >= MIN_CONTENT_HEIGHT) {
21833
- checkInitialScroll();
21834
- }
21835
21679
  element.addEventListener('scroll', () => this.onContainerScroll(element), { passive: true });
21836
21680
  return true;
21837
21681
  }
21838
21682
  }
21839
21683
  else {
21840
21684
  // Regular HTML element
21841
- console.log('[SCROLL DEBUG v2] Regular HTML element setup', {
21842
- scrollTop: element.scrollTop
21843
- });
21685
+ console.log('[SCROLL v6] Regular HTML element');
21844
21686
  this.embeddedScrollContainer = element;
21845
21687
  this.tooltipService.setScrollContainer(element);
21846
- // Helper function to check and update scroll state
21847
- const checkInitialScroll = () => {
21848
- const currentScrollTop = element.scrollTop;
21849
- console.log('[SCROLL DEBUG v2] Checking initial scroll position (regular)', {
21850
- scrollTop: currentScrollTop,
21851
- shouldCollapse: currentScrollTop > 50
21852
- });
21853
- if (currentScrollTop > 50) {
21854
- console.log('[SCROLL DEBUG v2] Collapsing header due to scroll position', { currentScrollTop });
21855
- this.isScrolled.set(true);
21856
- }
21857
- else {
21858
- console.log('[SCROLL DEBUG v2] Expanding header due to scroll position', { currentScrollTop });
21859
- this.isScrolled.set(false);
21860
- }
21861
- };
21862
- // Use ResizeObserver to detect when content has finished rendering
21863
- const MIN_CONTENT_HEIGHT = 500;
21864
- let lastHeight = element.scrollHeight;
21865
- let stableCount = 0;
21866
- const resizeObserver = new ResizeObserver(() => {
21867
- const currentHeight = element.scrollHeight;
21868
- console.log('[SCROLL DEBUG v2] Content height changed (regular)', {
21869
- lastHeight,
21870
- currentHeight,
21871
- stableCount,
21872
- minHeightReached: currentHeight >= MIN_CONTENT_HEIGHT
21873
- });
21874
- if (currentHeight >= MIN_CONTENT_HEIGHT) {
21875
- if (currentHeight === lastHeight) {
21876
- stableCount++;
21877
- if (stableCount >= 2) {
21878
- console.log('[SCROLL DEBUG v2] Content height stabilized (regular), checking scroll position');
21879
- checkInitialScroll();
21880
- resizeObserver.disconnect();
21881
- }
21882
- }
21883
- else {
21884
- stableCount = 0;
21885
- lastHeight = currentHeight;
21886
- checkInitialScroll();
21887
- }
21888
- }
21889
- else {
21890
- stableCount = 0;
21891
- lastHeight = currentHeight;
21892
- }
21893
- });
21894
- resizeObserver.observe(element);
21895
- if (element.scrollHeight >= MIN_CONTENT_HEIGHT) {
21896
- checkInitialScroll();
21897
- }
21898
21688
  element.addEventListener('scroll', () => this.onContainerScroll(element), { passive: true });
21899
21689
  return true;
21900
21690
  }
21901
21691
  };
21902
21692
  // Try to set up immediately
21903
21693
  if (!setupScrollContainer()) {
21904
- // If not found, retry with delays (element might not be in DOM yet)
21694
+ // Retry if element not found yet
21905
21695
  let retries = 0;
21906
21696
  const maxRetries = 10;
21907
21697
  const retryInterval = setInterval(() => {
@@ -21909,7 +21699,7 @@ class SymphiqFunnelAnalysisDashboardComponent {
21909
21699
  if (setupScrollContainer() || retries >= maxRetries) {
21910
21700
  clearInterval(retryInterval);
21911
21701
  if (retries >= maxRetries) {
21912
- console.warn(`Scroll container with id "${this.scrollContainerId()}" not found after ${maxRetries} retries.`);
21702
+ console.warn(`[SCROLL v6] Container "${this.scrollContainerId()}" not found after ${maxRetries} retries`);
21913
21703
  }
21914
21704
  }
21915
21705
  }, 100);
@@ -22134,11 +21924,9 @@ class SymphiqFunnelAnalysisDashboardComponent {
22134
21924
  return;
22135
21925
  }
22136
21926
  const scrollPosition = container.scrollTop;
22137
- console.log('[SCROLL DEBUG] onContainerScroll', {
21927
+ console.log('[SCROLL v6] onContainerScroll', {
22138
21928
  scrollPosition,
22139
- isScrolled: this.isScrolled(),
22140
- isProgrammaticScroll: this.isProgrammaticScroll,
22141
- lastScrollPosition: this.lastScrollPosition
21929
+ currentState: this.isScrolled()
22142
21930
  });
22143
21931
  // Update scroll progress for smooth bar animation
22144
21932
  const containerHeight = container.clientHeight;
@@ -22146,39 +21934,23 @@ class SymphiqFunnelAnalysisDashboardComponent {
22146
21934
  const maxScroll = scrollHeight - containerHeight;
22147
21935
  const progress = maxScroll > 0 ? (scrollPosition / maxScroll) * 100 : 0;
22148
21936
  this.scrollProgress.set(Math.min(100, Math.max(0, progress)));
22149
- // Skip header state updates during programmatic scrolling or cooldown
21937
+ // Skip header state updates during programmatic scrolling
22150
21938
  if (this.isProgrammaticScroll) {
22151
- console.log('[SCROLL DEBUG] Skipping - programmatic scroll');
21939
+ console.log('[SCROLL v6] Skipping - programmatic scroll');
22152
21940
  return;
22153
21941
  }
22154
- const now = Date.now();
22155
- const timeSinceLastChange = now - this.lastStateChangeTime;
22156
- if (timeSinceLastChange < this.STATE_CHANGE_COOLDOWN) {
22157
- console.log('[SCROLL DEBUG] Skipping - within cooldown', { timeSinceLastChange });
22158
- return;
22159
- }
22160
- if (this.scrollTimeout) {
22161
- clearTimeout(this.scrollTimeout);
22162
- }
22163
- // Use hysteresis to prevent bounce
21942
+ // v6 - Simple threshold-based state changes with hysteresis
22164
21943
  const COLLAPSE_THRESHOLD = 50;
22165
21944
  const EXPAND_THRESHOLD = 30;
22166
21945
  const currentState = this.isScrolled();
22167
- let newState = currentState;
22168
21946
  if (!currentState && scrollPosition > COLLAPSE_THRESHOLD) {
22169
- newState = true;
22170
- console.log('[SCROLL DEBUG] Should collapse header', { scrollPosition, COLLAPSE_THRESHOLD });
21947
+ console.log('[SCROLL v6] Collapsing header', { scrollPosition });
21948
+ this.isScrolled.set(true);
22171
21949
  }
22172
21950
  else if (currentState && scrollPosition < EXPAND_THRESHOLD) {
22173
- newState = false;
22174
- console.log('[SCROLL DEBUG] Should expand header', { scrollPosition, EXPAND_THRESHOLD });
22175
- }
22176
- if (newState !== currentState) {
22177
- console.log('[SCROLL DEBUG] Changing header state', { from: currentState, to: newState });
22178
- this.isScrolled.set(newState);
22179
- this.lastStateChangeTime = Date.now();
21951
+ console.log('[SCROLL v6] Expanding header', { scrollPosition });
21952
+ this.isScrolled.set(false);
22180
21953
  }
22181
- this.lastScrollPosition = scrollPosition;
22182
21954
  }
22183
21955
  onScroll() {
22184
21956
  if (this.embedded()) {