diff --git a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss index 0166b635863..25bae775955 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss @@ -1303,6 +1303,8 @@ overflow: hidden; z-index: 1; outline-style: none; + flex-grow: 1; + width: 100%; } %grid-tbody-container { @@ -1361,6 +1363,7 @@ background: var-get($theme, 'content-background'); border-inline-start: rem(1px) solid var-get($theme, 'row-border-color'); position: relative; + grid-column: 2 } %grid-tbody-scrollbar-start { @@ -2084,7 +2087,7 @@ .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + ::after { background: var-get($theme, 'header-selected-background'); } @@ -2112,7 +2115,7 @@ &%igx-grid-th--sorted { .sort-icon { color: var-get($theme, 'header-selected-text-color'); - + > igx-icon { color: inherit; } @@ -2120,7 +2123,7 @@ &:focus, &:hover { color: var-get($theme, 'header-selected-text-color'); - + > igx-icon { color: inherit; } @@ -2177,14 +2180,14 @@ .sort-icon { opacity: 1; color: var-get($theme, 'sorted-header-icon-color'); - + > igx-icon { color: inherit; } &:hover { color: var-get($theme, 'sortable-header-icon-hover-color'); - + > igx-icon { color: inherit; } diff --git a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts index 3482a5076f1..bcf660006d0 100644 --- a/projects/igniteui-angular/src/lib/grids/columns/column.component.ts +++ b/projects/igniteui-angular/src/lib/grids/columns/column.component.ts @@ -63,6 +63,7 @@ const DEFAULT_DATE_FORMAT = 'mediumDate'; const DEFAULT_TIME_FORMAT = 'mediumTime'; const DEFAULT_DATE_TIME_FORMAT = 'medium'; const DEFAULT_DIGITS_INFO = '1.0-3'; +const CELL_CONTENT_MIN = 32; /* blazorElement */ /* contentParent: ColumnGroup */ @@ -1234,14 +1235,8 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy if (!this.grid) { return '80'; } - switch (this.grid.gridSize) { - case Size.Medium: - return '64'; - case Size.Small: - return '56'; - default: - return '80'; - } + // the paddings + the min allowed cell content + return (this.grid.defaultHeaderGroupMinWidth + CELL_CONTENT_MIN).toString(); } /** * Returns a reference to the `summaryTemplate`. diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 5213151e54e..cdc50be9ec9 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -3228,7 +3228,7 @@ export abstract class IgxGridBaseDirective implements GridType, private overlayIDs = []; private _sortingStrategy: IGridSortingStrategy; private _pinning: IPinningConfig = { columns: ColumnPinningPosition.Start }; - private _shouldRecalcRowHeight = false; + private _shouldRecalcDefaultSizes = false; private _hostWidth; private _advancedFilteringOverlayId: string; @@ -3302,6 +3302,7 @@ export abstract class IgxGridBaseDirective implements GridType, private _sortDescendingHeaderIconTemplate: TemplateRef = null; private _gridSize: Size = Size.Large; private _defaultRowHeight = 50; + private _defaultCellPadding = 48; /** * @hidden @internal @@ -3720,7 +3721,7 @@ export abstract class IgxGridBaseDirective implements GridType, if (this.shouldResize) { // resizing occurs due to the change of --ig-size css var this._gridSize = this.gridSize; - this.updateDefaultRowHeight(); + this.updateDefaultSizes(); this._autoSize = this.isPercentHeight && this.calcHeight !== this.getDataBasedBodyHeight(); this.crudService.endEdit(false); if (this._summaryRowHeight === 0) { @@ -3956,7 +3957,7 @@ export abstract class IgxGridBaseDirective implements GridType, */ public dataRebinding(event: IForOfDataChangeEventArgs) { if (event.state.chunkSize == 0) { - this._shouldRecalcRowHeight = true; + this._shouldRecalcDefaultSizes = true; } this.dataChanging.emit(event); } @@ -3966,9 +3967,9 @@ export abstract class IgxGridBaseDirective implements GridType, */ public dataRebound(event: IForOfDataChangeEventArgs) { this.selectionService.clearHeaderCBState(); - if (this._shouldRecalcRowHeight) { - this._shouldRecalcRowHeight = false; - this.updateDefaultRowHeight(); + if (this._shouldRecalcDefaultSizes) { + this._shouldRecalcDefaultSizes = false; + this.updateDefaultSizes(); } this.dataChanged.emit(event); } @@ -4400,14 +4401,7 @@ export abstract class IgxGridBaseDirective implements GridType, * The values below depend on the header cell default right/left padding values. */ public get defaultHeaderGroupMinWidth(): number { - switch (this.gridSize) { - case Size.Medium: - return 32; - case Size.Small: - return 24; - default: - return 48; - } + return this._defaultCellPadding; } /** @hidden @internal */ @@ -6575,16 +6569,12 @@ export abstract class IgxGridBaseDirective implements GridType, if (this.isPercentWidth) { /* width in %*/ - const computed = this.document.defaultView.getComputedStyle(this.nativeElement).getPropertyValue('width'); + const computed = this.document.defaultView.getComputedStyle(this.tbody.nativeElement).getPropertyValue('width'); width = computed.indexOf('%') === -1 ? parseFloat(computed) : null; } else { width = parseInt(this.width, 10); } - if (!width && this.nativeElement) { - width = this.nativeElement.offsetWidth; - } - if (this.width === null || !width) { this.isColumnWidthSum = true; @@ -6593,7 +6583,7 @@ export abstract class IgxGridBaseDirective implements GridType, this.isColumnWidthSum = false; } - if (this.hasVerticalScroll() && this.width !== null) { + if (!this.isPercentWidth && this.hasVerticalScroll() && this.width !== null) { width -= this.scrollSize; } if ((Number.isFinite(width) || width === null) && width !== this.calcWidth) { @@ -6976,59 +6966,12 @@ export abstract class IgxGridBaseDirective implements GridType, } } - /** - * @hidden - */ - protected getGroupAreaHeight(): number { - return 0; - } - /** * @hidden */ protected getComputedHeight(elem) { return elem.offsetHeight ? parseFloat(this.document.defaultView.getComputedStyle(elem).getPropertyValue('height')) : 0; } - /** - * @hidden - */ - protected getFooterHeight(): number { - return this.summaryRowHeight || this.getComputedHeight(this.tfoot.nativeElement); - } - /** - * @hidden - */ - protected getTheadRowHeight(): number { - // D.P.: Before CSS loads,theadRow computed height will be 'auto'->NaN, so use 0 fallback - const height = this.getComputedHeight(this.theadRow.nativeElement) || 0; - return (!this.allowFiltering || (this.allowFiltering && this.filterMode !== FilterMode.quickFilter)) ? - height - this.getFilterCellHeight() : - height; - } - - /** - * @hidden - */ - protected getToolbarHeight(): number { - let toolbarHeight = 0; - if (this.toolbar.first) { - toolbarHeight = this.getComputedHeight(this.toolbar.first.nativeElement); - } - return toolbarHeight; - } - - /** - * @hidden - */ - protected getPagingFooterHeight(): number { - let pagingHeight = 0; - if (this.footer) { - const height = this.getComputedHeight(this.footer.nativeElement); - pagingHeight = this.footer.nativeElement.firstElementChild ? - height : 0; - } - return pagingHeight; - } /** * @hidden @@ -7048,21 +6991,12 @@ export abstract class IgxGridBaseDirective implements GridType, if (!this._height) { return null; } - const actualTheadRow = this.getTheadRowHeight(); - const footerHeight = this.getFooterHeight(); - const toolbarHeight = this.getToolbarHeight(); - const pagingHeight = this.getPagingFooterHeight(); - const groupAreaHeight = this.getGroupAreaHeight(); - const scrHeight = this.getComputedHeight(this.scr.nativeElement); - const renderedHeight = toolbarHeight + actualTheadRow + - footerHeight + pagingHeight + groupAreaHeight + - scrHeight; let gridHeight = 0; if (this.isPercentHeight) { const computed = this.document.defaultView.getComputedStyle(this.nativeElement).getPropertyValue('height'); - const autoSize = this._shouldAutoSize(renderedHeight); + const autoSize = this._shouldAutoSize(); if (autoSize || computed.indexOf('%') !== -1) { const bodyHeight = this.getDataBasedBodyHeight(); return bodyHeight > 0 ? bodyHeight : null; @@ -7071,7 +7005,7 @@ export abstract class IgxGridBaseDirective implements GridType, } else { gridHeight = parseInt(this._height, 10); } - const height = Math.abs(gridHeight - renderedHeight); + const height = this.getComputedHeight(this.tbodyContainer.nativeElement) || gridHeight || 0; if (Math.round(height) === 0 || isNaN(gridHeight)) { const bodyHeight = this.defaultTargetBodyHeight; @@ -7089,12 +7023,14 @@ export abstract class IgxGridBaseDirective implements GridType, return origHeight !== height; } - protected _shouldAutoSize(renderedHeight) { - this.tbody.nativeElement.style.display = 'none'; + protected _shouldAutoSize() { + const parentElement = this.nativeElement.parentElement || (this.nativeElement.getRootNode() as any).host; + const parentHeight = parentElement?.clientHeight; + this.tbody.nativeElement.style.display = 'none'; let res = !parentElement || parentElement.clientHeight === 0 || - parentElement.clientHeight === renderedHeight; + parentElement.clientHeight !== parentHeight; if (parentElement && (res || this._autoSize)) { // If grid causes the parent container to extend (for example when container is flex) // we should always auto-size since the actual size of the container will continuously change as the grid renders elements. @@ -7896,13 +7832,15 @@ export abstract class IgxGridBaseDirective implements GridType, this._lastSearchInfo.matchCount = this._lastSearchInfo.matchInfoCache.length; } - protected updateDefaultRowHeight() { + protected updateDefaultSizes() { if (this.dataRowList.length > 0 && this.dataRowList.first.cells && this.dataRowList.first.cells.length > 0) { const height = parseFloat(this.document.defaultView.getComputedStyle(this.dataRowList.first.cells.first.nativeElement)?.getPropertyValue('height')); - if (height) { + const padding = parseFloat(this.document.defaultView.getComputedStyle(this.dataRowList.first.cells.first.nativeElement)?.getPropertyValue('padding-left')); + if (height && padding) { this._defaultRowHeight = height; + this._defaultCellPadding = padding * 2; } else { - this._shouldRecalcRowHeight = true; + this._shouldRecalcDefaultSizes = true; } } } diff --git a/projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts index e78c32fe29c..a32856ea6fe 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts @@ -458,10 +458,10 @@ describe('IgxGrid - multi-column headers #grid', () => { const locationColGroup = getColGroup(grid, 'Location'); const gridWidthInPx = ((parseInt(gridWidth, 10) / 100) * - parseInt(componentInstance.gridWrapperWidthPx, 10) - grid.scrollSize) + 'px'; - expect(locationColGroup.width).toBe(gridWidthInPx); + parseInt(componentInstance.gridWrapperWidthPx, 10) - grid.scrollSize); + expect((parseFloat(locationColGroup.width))).toBeCloseTo(gridWidthInPx, 0); const cityColumn = grid.getColumnByName('City'); - expect(cityColumn.width).toBe(gridWidthInPx); + expect(parseFloat(cityColumn.width)).toBeCloseTo(gridWidthInPx, 0); }); it('Width should be correct. Column group with column. Column width in px.', () => { @@ -553,13 +553,13 @@ describe('IgxGrid - multi-column headers #grid', () => { const colWidth = gridWidthInPx / 3; const colWidthPx = colWidth + 'px'; const locationColGroup = getColGroup(grid, 'Location'); - expect(locationColGroup.width).toBe(colWidth * 3 + 'px'); + expect((parseFloat(locationColGroup.width))).toBeCloseTo(colWidth * 3, 0); const countryColumn = grid.getColumnByName('Country'); - expect(countryColumn.width).toBe(colWidthPx); + expect(parseFloat(countryColumn.width)).toBeCloseTo(colWidth, 0); const regionColumn = grid.getColumnByName('Region'); - expect(regionColumn.width).toBe(colWidthPx); + expect(parseFloat(regionColumn.width)).toBeCloseTo(colWidth, 0); const cityColumn = grid.getColumnByName('City'); - expect(cityColumn.width).toBe(colWidthPx); + expect(parseFloat(cityColumn.width)).toBeCloseTo(colWidth, 0); }); it('Width should be correct. Column group with three columns. Columns with mixed width - px and percent.', async () => { @@ -575,8 +575,8 @@ describe('IgxGrid - multi-column headers #grid', () => { // check group has correct size. let locationColGroup = getColGroup(grid, 'Location'); - let expectedWidth = (200 + grid.calcWidth * 0.7) + 'px'; - expect(locationColGroup.width).toBe(expectedWidth); + let expectedWidth = (200 + grid.calcWidth * 0.7); + expect(parseFloat(locationColGroup.width)).toBeCloseTo(expectedWidth, 0); // check header and content have same size. const col1Header = grid.getColumnByName('Country').headerCell.nativeElement; @@ -599,8 +599,8 @@ describe('IgxGrid - multi-column headers #grid', () => { fixture.detectChanges(); locationColGroup = getColGroup(grid, 'Location'); - expectedWidth = (200 + grid.calcWidth * 0.7) + 'px'; - expect(locationColGroup.width).toBe(expectedWidth); + expectedWidth = (200 + grid.calcWidth * 0.7); + expect(parseFloat(locationColGroup.width)).toBeCloseTo(expectedWidth, 0); col2Header = grid.getColumnByName('Region').headerCell.nativeElement; cell2 = (grid.gridAPI.get_row_by_index(0).cells as QueryList).toArray()[1].nativeElement; @@ -653,13 +653,13 @@ describe('IgxGrid - multi-column headers #grid', () => { const colWidth = gridWidthInPx / 3; const colWidthPx = colWidth + 'px'; const locationColGroup = getColGroup(grid, 'Location'); - expect(locationColGroup.width).toBe((colWidth * 3) + 'px'); + expect(parseFloat(locationColGroup.width)).toBeCloseTo((colWidth * 3), 0); const countryColumn = grid.getColumnByName('Country'); - expect(countryColumn.width).toBe(colWidthPx); + expect((parseFloat(countryColumn.width))).toBeCloseTo(colWidth, 0); const regionColumn = grid.getColumnByName('Region'); - expect(regionColumn.width).toBe(colWidthPx); + expect(parseFloat(regionColumn.width)).toBeCloseTo(colWidth, 0); const cityColumn = grid.getColumnByName('City'); - expect(cityColumn.width).toBe(colWidthPx); + expect((parseFloat(cityColumn.width))).toBeCloseTo(colWidth, 0); }); it('Width should be correct. Column group with three columns. Column width in px.', () => { diff --git a/projects/igniteui-angular/src/lib/grids/grid/column-resizing.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/column-resizing.spec.ts index 98a1950e2a4..46fb7dc5147 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/column-resizing.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/column-resizing.spec.ts @@ -199,9 +199,10 @@ describe('IgxGrid - Deferred Column Resizing #grid', () => { fixture.detectChanges(); expect(column.width).toEqual('80px'); - setElementSize(grid.nativeElement, Size.Medium) + setElementSize(grid.nativeElement, Size.Medium); tick(16); // needed because of the throttleTime of the resize obserer fixture.detectChanges(); + (grid as any).updateDefaultSizes(); expect(column.defaultMinWidth).toBe('64'); UIInteractions.simulateMouseEvent('mousedown', headerResArea, 80, 0); @@ -214,9 +215,10 @@ describe('IgxGrid - Deferred Column Resizing #grid', () => { fixture.detectChanges(); expect(column.width).toEqual('64px'); - setElementSize(grid.nativeElement, Size.Small) + setElementSize(grid.nativeElement, Size.Small); tick(16); // needed because of the throttleTime of the resize obserer fixture.detectChanges(); + (grid as any).updateDefaultSizes(); expect(column.defaultMinWidth).toBe('56'); UIInteractions.simulateMouseEvent('mousedown', headerResArea, 64, 0); diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts index 13fa654dde0..c3bc4851d1f 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-mrl-keyboard-nav.spec.ts @@ -2065,7 +2065,7 @@ describe('IgxGrid Multi Row Layout - Keyboard navigation #grid', () => { expect(lastCell.active).toBe(true); expect(grid.headerContainer.getScroll().scrollLeft).toBeGreaterThan(800); let diff = lastCell.nativeElement.getBoundingClientRect().right - grid.tbody.nativeElement.getBoundingClientRect().right; - expect(diff).toBe(0); + expect(Math.ceil(diff)).toBe(0); // ctrl+arrow left GridFunctions.simulateGridContentKeydown(fix, 'ArrowLeft', false, false, true); @@ -2578,7 +2578,7 @@ describe('IgxGrid Multi Row Layout - Keyboard navigation #grid', () => { // check if cell right edge is visible diff = cell.nativeElement.getBoundingClientRect().right - grid.tbody.nativeElement.getBoundingClientRect().right; await wait(); - expect(diff).toBe(0); + expect(Math.ceil(diff)).toBe(0); // navigate left to cell in column that is in DOM but is not in view col = grid.getColumnByName('CompanyName'); @@ -2611,7 +2611,7 @@ describe('IgxGrid Multi Row Layout - Keyboard navigation #grid', () => { expect(grid.headerContainer.getScroll().scrollLeft).toBeGreaterThan(250); // check if cell right right is visible diff = cell.nativeElement.getBoundingClientRect().right - grid.tbody.nativeElement.getBoundingClientRect().right; - expect(diff).toBe(0); + expect(Math.ceil(diff)).toBe(0); }); }); }); 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 38c010bae76..92df10c98c3 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.component.html @@ -34,7 +34,7 @@
+ [style.height.px]="totalHeight" #tbody [attr.aria-activedescendant]="activeDescendant"> @if (moving && columnInDrag && pinnedColumns.length <= 0) { { expect(lastCell.column.field).toBe('Address'); expect(lastCell.column.parent.field).toBe('group4'); expect(lastCell.nativeElement.getBoundingClientRect().right) - .toEqual(grid.tbody.nativeElement.getBoundingClientRect().right); + .toBeCloseTo(grid.tbody.nativeElement.getBoundingClientRect().right, 0); }); diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html index d5f31ada6b4..91298ce1ba7 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.html @@ -20,7 +20,7 @@
+ [style.height.px]="totalHeight" #tbody (scroll)="preventContainerScroll($event)"> @if (moving && columnInDrag && pinnedColumns.length <= 0) { { UIInteractions.simulateClickAndSelectEvent(row.expander); const childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row')); const childGrid = childGrids[0].query(By.css('igx-hierarchical-grid')).componentInstance; - expect(childGrid.calcWidth - 370 - childGrid.scrollSize).toBeLessThanOrEqual(5); + // child should be parent width - the child grid indentations + var indents = window.getComputedStyle(fixture.debugElement.queryAll(By.css('.igx-grid__hierarchical-indent'))[0].nativeElement); + expect(childGrid.calcWidth).toBe(parseFloat(hierarchicalGrid.width) - parseFloat(indents.marginLeft) - parseFloat(indents.marginRight)); hierarchicalGrid.clearFilter(); // Required to recalculate and reflect child grid size diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.html b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.html index 9ca659192f9..62f536190db 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.html @@ -22,7 +22,7 @@
+ [style.height.px]="totalHeight" #tbody [attr.aria-activedescendant]="activeDescendant"> @if (hasMovableColumns && columnInDrag && pinnedColumns.length <= 0) { diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts index 441771d3df2..e78418073de 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-grid.component.ts @@ -2514,11 +2514,17 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni this.theadRow.nativeElement.offsetHeight; } - protected override updateDefaultRowHeight() { - super.updateDefaultRowHeight(); + protected override updateDefaultSizes() { + super.updateDefaultSizes(); if (this.hasHorizontalLayout) { // Trigger pipes to recalc heights for the horizontal layout mrl rows. this.regroupTrigger++; } } + + protected override getUnpinnedWidth(takeHidden = false) { + return this.isPercentWidth ? + this.calcWidth : + super.getUnpinnedWidth(takeHidden); + } } diff --git a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.html b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.html index b238803b861..6218b134207 100644 --- a/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.html +++ b/projects/igniteui-angular/src/lib/grids/pivot-grid/pivot-header-row.component.html @@ -1,6 +1,6 @@ -
-
-
+
+
+
@if (grid.pivotUI.showConfiguration) {
-
-
+
@if (!grid.pivotUI.showRowHeaders || grid.rowDimensions.length === 0) {
diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html index 2521cc28e58..cf909f1d90e 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid.component.html @@ -19,7 +19,7 @@
+ [style.height.px]='totalHeight' #tbody (scroll)='preventContainerScroll($event)'> @if (moving && columnInDrag && pinnedColumns.length <= 0) {