diff --git a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts index 40c06f19ee8..22436de3e71 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts @@ -38,6 +38,7 @@ import { import { areEqualArrays, columnFieldPath, + getResizeObserver, resizeObservable, Transaction, TransactionType, @@ -3297,6 +3298,8 @@ export abstract class IgxGridBaseDirective implements GridType, protected _expansionStates: Map = new Map(); protected _defaultExpandState = false; protected _headerFeaturesWidth = NaN; + private _headerFeaturesObserver: ResizeObserver | null = null; + private _observedHeaderFeatures: HTMLElement[] = []; protected _init = true; protected _firstAutoResize = true; protected _autoSizeColumnsNotify = new Subject(); @@ -4449,6 +4452,7 @@ export abstract class IgxGridBaseDirective implements GridType, this.transactionChange$.next(); this.transactionChange$.complete(); this._destroyed = true; + this._headerFeaturesObserver?.disconnect(); this.textHighlightService.destroyGroup(this.id); @@ -4726,10 +4730,33 @@ export abstract class IgxGridBaseDirective implements GridType, this.headerGroupContainer.nativeElement.getBoundingClientRect().width : 0; const expanderWidth = expander?.nativeElement?.getBoundingClientRect ? expander.nativeElement.getBoundingClientRect().width : 0; this._headerFeaturesWidth = rowSelectArea + rowDragArea + groupableArea + expanderWidth; + this.observeHeaderFeatures([this.headerSelectorContainer, this.headerDragContainer, this.headerGroupContainer, expander]); } return this._headerFeaturesWidth; } + private observeHeaderFeatures(refs: (ElementRef | undefined)[]) { + const elements = refs.map(ref => ref?.nativeElement).filter((el): el is HTMLElement => !!el); + const ResizeObserverCtor = getResizeObserver(); + if (!ResizeObserverCtor || this._destroyed || + (elements.length === this._observedHeaderFeatures.length && elements.every((el, i) => el === this._observedHeaderFeatures[i]))) { + return; + } + this._observedHeaderFeatures = elements; + this._headerFeaturesObserver?.disconnect(); + this._headerFeaturesObserver ??= this.zone.runOutsideAngular(() => new ResizeObserverCtor(() => { + const width = this._headerFeaturesWidth; + if (Number.isNaN(width) || this._destroyed) { + return; + } + this._headerFeaturesWidth = NaN; + if (this.featureColumnsWidth() !== width) { + this.resizeNotify.next(); + } + })); + elements.forEach(el => this._headerFeaturesObserver!.observe(el, { box: 'border-box' })); + } + /** * @hidden @internal */ diff --git a/projects/igniteui-angular/grids/grid/src/grid-row-selection.spec.ts b/projects/igniteui-angular/grids/grid/src/grid-row-selection.spec.ts index d19e55643c8..a2e0eebcb30 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-row-selection.spec.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-row-selection.spec.ts @@ -1945,6 +1945,26 @@ describe('IgxGrid - Row Selection #grid', () => { expect(grid.summariesMargin).toBe(grid.featureColumnsWidth()); }); + it('Summaries integration: should align the summary row when the header border width changes', async () => { + fix.componentInstance.height = null; + grid.getColumnByName('ProductID').hasSummary = true; + fix.detectChanges(); + await wait(50); + fix.detectChanges(); + + const initialWidth = grid.featureColumnsWidth(); + grid.nativeElement.style.setProperty('--ig-grid-header-border-width', '10px'); + const newWidth = grid.headerSelectorContainer.nativeElement.getBoundingClientRect().width; + expect(newWidth).toBeGreaterThan(initialWidth); + + await wait(100); + fix.detectChanges(); + + expect(grid.featureColumnsWidth()).toBe(newWidth); + const summaryPatch = fix.nativeElement.querySelector('.igx-grid__summaries-patch') as HTMLElement; + expect(summaryPatch.getBoundingClientRect().width).toBe(newWidth); + }); + it('Filtering: Should properly check the header checkbox state when filtering, #2469', () => { vi.spyOn(grid.rowSelectionChanging, 'emit');