diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.component.ts b/projects/igniteui-angular/src/lib/grids/grid-base.component.ts index 7956451b69c..2ade98b1d12 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.component.ts @@ -229,6 +229,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements private _observer: MutationObserver; protected _destroyed = false; private overlayIDs = []; + private _hostWidth; /** * An accessor that sets the resource strings. * By default it uses EN resources. @@ -595,6 +596,13 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements } } + /** + * @hidden + */ + @HostBinding('style.width') + get hostWidth() { + return this._width || this._hostWidth; + } /** * Returns the width of the `IgxGridComponent`. * ```typescript @@ -603,7 +611,6 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements * @memberof IgxGridBaseComponent */ @WatchChanges() - @HostBinding('style.width') @Input() public get width() { return this._width; @@ -2921,6 +2928,11 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements return this._unpinnedWidth; } + get isHorizontalScrollHidden() { + const diff = this.unpinnedWidth - this.totalWidth; + return this.width === null || diff >= 0; + } + /** * @hidden */ @@ -3849,7 +3861,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements */ protected _derivePossibleWidth() { if (!this._columnWidthSetByUser) { - this._columnWidth = this.getPossibleColumnWidth(); + this._columnWidth = this.width !== null ? this.getPossibleColumnWidth() : MINIMUM_COLUMN_WIDTH + 'px'; this.columnList.forEach((column: IgxColumnComponent) => { column.defaultWidth = this._columnWidth; }); @@ -4042,20 +4054,39 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements } - if (!width) { - width = this.columnList.reduce((sum, item) => sum + parseInt((item.width || item.defaultWidth), 10), 0); + if (this.width === null || !width) { + width = this.getColumnWidthSum(); } - if (this.hasVerticalSroll()) { + if (this.hasVerticalSroll() && this.width !== null) { width -= this.scrollWidth; } - if (Number.isFinite(width) && width !== this.calcWidth) { + if ((Number.isFinite(width) || width === null) && width !== this.calcWidth) { this.calcWidth = width; this.cdr.detectChanges(); } this._derivePossibleWidth(); } + private getColumnWidthSum(): number { + let colSum = 0; + const cols = this.visibleColumns + .filter(x => !x.columnGroup); + cols.forEach((item) => { + const isWidthInPercent = item.width && typeof item.width === 'string' && item.width.indexOf('%') !== -1; + if (isWidthInPercent) { + item.width = MINIMUM_COLUMN_WIDTH + 'px'; + } + colSum += parseInt((item.width || item.defaultWidth), 10) || MINIMUM_COLUMN_WIDTH; + }); + if (!colSum) { + return null; + } + this.cdr.detectChanges(); + colSum += this.getFeatureColumnsWidth(); + return colSum; + } + public hasVerticalSroll() { if (!this._ngAfterViewInitPassed) { return false; } const isScrollable = this.verticalScrollContainer.isScrollable(); @@ -4148,6 +4179,48 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements this.cdr.detectChanges(); this.resetCaches(); } + + if (this.zone.isStable) { + this.zone.run(() => { + this._applyWidthHostBinding(); + this.cdr.detectChanges(); + }); + } else { + this.zone.onStable.pipe(first()).subscribe(() => { + this.zone.run(() => { + this._applyWidthHostBinding(); + }); + }); + } + } + + private _applyWidthHostBinding() { + let width = this._width; + if (width === null) { + let currentWidth = this.calcWidth; + if (this.hasVerticalSroll()) { + currentWidth += this.scrollWidth; + } + width = currentWidth + 'px'; + this.resetCaches(); + } + this._hostWidth = width; + this.cdr.markForCheck(); + } + + /** + * @hidden + * Gets the combined width of the columns that are specific to the enabled grid features. They are fixed. + * Method used to override the calculations. + */ + public getFeatureColumnsWidth() { + let width = 0; + + if (this.headerCheckboxContainer) { + width += this.headerCheckboxContainer.nativeElement.getBoundingClientRect().width; + } + + return width; } /** @@ -4182,7 +4255,7 @@ export abstract class IgxGridBaseComponent extends DisplayDensityBase implements protected getUnpinnedWidth(takeHidden = false) { let width = this.isPercentWidth ? this.calcWidth : - parseInt(this._width, 10); + parseInt(this.width, 10) || parseInt(this.hostWidth, 10) || this.calcWidth; if (this.hasVerticalSroll() && !this.isPercentWidth) { width -= this.scrollWidth; } diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts index bcd52c7661f..5ec62265129 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-filtering-ui.spec.ts @@ -3565,7 +3565,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering', () => { fix.detectChanges(); const headers: DebugElement[] = fix.debugElement.queryAll(By.directive(IgxGridHeaderGroupComponent)); - const headerResArea = headers[2].children[0].nativeElement; + const headerResArea = headers[2].children[1].nativeElement; const filterIcon = headerResArea.querySelector('.igx-excel-filter__icon'); filterIcon.click(); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html index d7023a04be9..011547823ae 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html @@ -77,7 +77,7 @@