@ascentgl/ads-ui 21.94.0 → 21.96.0

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.
@@ -8448,6 +8448,17 @@ class AdsTableComponent {
8448
8448
  this.uniqueColumnValuesCache = new Map();
8449
8449
  /** @ignore - Data version to invalidate unique values cache when rowData changes */
8450
8450
  this.dataVersion = 0;
8451
+ /** @ignore - Cache for getProcessedColumnDefs() to avoid producing new array references on every CD cycle */
8452
+ this._processedColDefsCache = [];
8453
+ this._processedColDefsSrc = null;
8454
+ this._processedColDefsConfigRef = null;
8455
+ /** @ignore - Cache for getAgGridIcons() to avoid producing new object references on every CD cycle */
8456
+ this._agGridIconsCache = null;
8457
+ this._agGridIconsDirty = true;
8458
+ /** @ignore - Number of list items to render synchronously on the first frame when toggling to list view */
8459
+ this.INITIAL_LIST_RENDER_COUNT = 12;
8460
+ /** @ignore - Handle for the pending rAF that fills the first batch, so it can be cancelled on destroy or re-toggle */
8461
+ this._listRenderRafId = null;
8451
8462
  /** @ignore - Wrapper for getFilteredColumnValues that can be passed to filter menu */
8452
8463
  this.getFilterOptionsForFieldFn = (field) => {
8453
8464
  return this.getFilteredColumnValues(field);
@@ -8562,11 +8573,21 @@ class AdsTableComponent {
8562
8573
  /** @ignore */
8563
8574
  getProcessedColumnDefs() {
8564
8575
  const columns = this.tableColumnDefs();
8576
+ // Return cached result if neither the column defs nor the sort/filter config reference changed.
8577
+ // This prevents ag-grid from receiving a new array reference on every CD cycle
8578
+ // (which would cause expensive internal column diffing even when the grid is hidden).
8579
+ if (columns === this._processedColDefsSrc &&
8580
+ this.columnSortFilterConfigs === this._processedColDefsConfigRef) {
8581
+ return this._processedColDefsCache;
8582
+ }
8565
8583
  if (!this.enableCustomSortFilter) {
8584
+ this._processedColDefsSrc = columns;
8585
+ this._processedColDefsConfigRef = this.columnSortFilterConfigs;
8586
+ this._processedColDefsCache = columns;
8566
8587
  return columns;
8567
8588
  }
8568
8589
  // Import the custom header component dynamically
8569
- return columns.map(col => {
8590
+ const result = columns.map(col => {
8570
8591
  const field = col.field || '';
8571
8592
  const config = this.getColumnSortFilterConfig(field);
8572
8593
  if (config) {
@@ -8594,6 +8615,10 @@ class AdsTableComponent {
8594
8615
  }
8595
8616
  return col;
8596
8617
  });
8618
+ this._processedColDefsSrc = columns;
8619
+ this._processedColDefsConfigRef = this.columnSortFilterConfigs;
8620
+ this._processedColDefsCache = result;
8621
+ return result;
8597
8622
  }
8598
8623
  /** @ignore */
8599
8624
  createComparator(config) {
@@ -8628,6 +8653,10 @@ class AdsTableComponent {
8628
8653
  }
8629
8654
  /** @ignore */
8630
8655
  ngOnChanges(changes) {
8656
+ // Invalidate icons cache when icons input changes
8657
+ if (changes['icons']) {
8658
+ this._agGridIconsDirty = true;
8659
+ }
8631
8660
  if (changes['defaultViewMode']) {
8632
8661
  const newViewMode = changes['defaultViewMode'].currentValue;
8633
8662
  const isListMode = newViewMode === 'list';
@@ -8968,9 +8997,28 @@ class AdsTableComponent {
8968
8997
  }
8969
8998
  /** @ignore - Toggle between grid view and list view */
8970
8999
  toggleView() {
9000
+ // Cancel any pending progressive-render frame from a previous toggle
9001
+ this.cancelListRenderRaf();
8971
9002
  this.isListView.update(v => !v);
8972
9003
  if (this.isListView()) {
8973
- this.refreshListView();
9004
+ // Populate the full data cache immediately so sorting/filtering state is captured
9005
+ this.listRowDataCache.set(this.getFilteredRowData());
9006
+ // Render a small initial batch synchronously for instant visual feedback,
9007
+ // then schedule the full batch size in the next animation frame.
9008
+ // This splits the DOM creation across two frames and prevents the UI freeze
9009
+ // that occurs when many complex list-item components are instantiated at once.
9010
+ const total = this.listRowDataCache().length;
9011
+ const initialCount = Math.min(this.INITIAL_LIST_RENDER_COUNT, total);
9012
+ this.renderedListCount.set(initialCount);
9013
+ if (initialCount < Math.min(this.listBatchSize, total)) {
9014
+ this._listRenderRafId = requestAnimationFrame(() => {
9015
+ this._listRenderRafId = null;
9016
+ if (this.isListView()) {
9017
+ this.renderedListCount.set(Math.min(this.listBatchSize, this.listRowDataCache().length));
9018
+ this.cdr.detectChanges();
9019
+ }
9020
+ });
9021
+ }
8974
9022
  }
8975
9023
  else {
8976
9024
  this.listSentinelObserver?.disconnect();
@@ -8985,6 +9033,13 @@ class AdsTableComponent {
8985
9033
  }
8986
9034
  this.viewChanged.emit(this.isListView() ? 'list' : 'grid');
8987
9035
  }
9036
+ /** @ignore - Cancel pending rAF for progressive list rendering */
9037
+ cancelListRenderRaf() {
9038
+ if (this._listRenderRafId !== null) {
9039
+ cancelAnimationFrame(this._listRenderRafId);
9040
+ this._listRenderRafId = null;
9041
+ }
9042
+ }
8988
9043
  /** @ignore - Refresh the list view data cache and reset rendered count */
8989
9044
  refreshListView() {
8990
9045
  this.listRowDataCache.set(this.getFilteredRowData());
@@ -9548,6 +9603,11 @@ class AdsTableComponent {
9548
9603
  }
9549
9604
  /** @ignore */
9550
9605
  getAgGridIcons() {
9606
+ // Return cached icons if nothing changed — prevents ag-grid from receiving
9607
+ // a new object reference on every change detection cycle.
9608
+ if (!this._agGridIconsDirty && this._agGridIconsCache) {
9609
+ return this._agGridIconsCache;
9610
+ }
9551
9611
  const icons = {
9552
9612
  sortAscending: '<svg xmlns="http://www.w3.org/2000/svg" width="7" height="13" viewBox="0 0 7 13" fill="none">\n' +
9553
9613
  ' <path d="M3.5 2.29227L5.12266 4.70574L1.87734 4.70574L3.5 2.29227Z" stroke-width="2"/>\n' +
@@ -9566,6 +9626,8 @@ class AdsTableComponent {
9566
9626
  if (this.icons) {
9567
9627
  Object.assign(icons, this.icons);
9568
9628
  }
9629
+ this._agGridIconsCache = icons;
9630
+ this._agGridIconsDirty = false;
9569
9631
  return icons;
9570
9632
  }
9571
9633
  /** @ignore */
@@ -9758,6 +9820,7 @@ class AdsTableComponent {
9758
9820
  this.resizeObserver?.disconnect();
9759
9821
  this.listSentinelObserver?.disconnect();
9760
9822
  this.observedSentinelEl = undefined;
9823
+ this.cancelListRenderRaf();
9761
9824
  this.unsubscribeFromControls();
9762
9825
  }
9763
9826
  /** @ignore - serialize any cell value into a stable string key */