Skip to content

Refactor how the grid calculates the size of the body. #15603

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,8 @@
overflow: hidden;
z-index: 1;
outline-style: none;
flex-grow: 1;
width: 100%;
}

%grid-tbody-container {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -2084,7 +2087,7 @@

.sort-icon {
color: var-get($theme, 'header-selected-text-color');

::after {
background: var-get($theme, 'header-selected-background');
}
Expand Down Expand Up @@ -2112,15 +2115,15 @@
&%igx-grid-th--sorted {
.sort-icon {
color: var-get($theme, 'header-selected-text-color');

> igx-icon {
color: inherit;
}

&:focus,
&:hover {
color: var-get($theme, 'header-selected-text-color');

> igx-icon {
color: inherit;
}
Expand Down Expand Up @@ -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;
}
Expand Down
76 changes: 9 additions & 67 deletions projects/igniteui-angular/src/lib/grids/grid-base.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6511,16 +6511,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;
Expand All @@ -6529,7 +6525,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) {
Expand Down Expand Up @@ -6906,59 +6902,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
Expand All @@ -6978,21 +6927,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;
Expand All @@ -7001,7 +6941,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;
Expand All @@ -7019,12 +6959,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.
Expand Down
30 changes: 15 additions & 15 deletions projects/igniteui-angular/src/lib/grids/grid/column-group.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,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.', () => {
Expand Down Expand Up @@ -554,13 +554,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 () => {
Expand All @@ -576,8 +576,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;
Expand All @@ -600,8 +600,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<CellType>).toArray()[1].nativeElement;
Expand Down Expand Up @@ -654,13 +654,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.', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2068,7 +2068,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);
Expand Down Expand Up @@ -2581,7 +2581,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');
Expand Down Expand Up @@ -2614,7 +2614,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);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<div class="igx-grid__tbody-content" tabindex="0" [attr.role]="dataView.length ? null : 'row'" (keydown)="navigation.handleNavigation($event)" (focus)="navigation.focusTbody($event)"
(dragStop)="selectionService.dragMode = $event" (scroll)="preventContainerScroll($event)"
(dragScroll)="dragScroll($event)" [igxGridDragSelect]="selectionService.dragMode"
[style.height.px]="totalHeight" [style.width.px]="calcWidth || null" #tbody [attr.aria-activedescendant]="activeDescendant">
[style.height.px]="totalHeight" #tbody [attr.aria-activedescendant]="activeDescendant">
@if (moving && columnInDrag && pinnedColumns.length <= 0) {
<span
[igxColumnMovingDrop]="headerContainer" [attr.droppable]="true" id="left"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1270,13 +1270,6 @@ export class IgxGridComponent extends IgxGridBaseDirective implements GridType,
this.paginator ? Math.min(allItems, this.perPage) : allItems);
}

/**
* @hidden @internal
*/
protected override getGroupAreaHeight(): number {
return this.groupArea ? this.getComputedHeight(this.groupArea.nativeElement) : 0;
}

/**
* @hidden @internal
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ describe('IgxGrid - multi-row-layout Integration #grid - ', () => {
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);

});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<div class="igx-grid__tbody-content" tabindex="0" (focus)="navigation.focusTbody($event)"
(keydown)="navigation.handleNavigation($event)" (dragStop)="selectionService.dragMode = $event"
(dragScroll)="dragScroll($event)" [igxGridDragSelect]="selectionService.dragMode" [attr.aria-activedescendant]="activeDescendant" [attr.role]="dataView.length ? null : 'row'"
[style.height.px]="totalHeight" [style.width.px]="calcWidth" #tbody (scroll)="preventContainerScroll($event)">
[style.height.px]="totalHeight" #tbody (scroll)="preventContainerScroll($event)">
@if (moving && columnInDrag && pinnedColumns.length <= 0) {
<span
[igxColumnMovingDrop]="headerContainer" [attr.droppable]="true" id="left"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1159,11 +1159,11 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
});
}

protected override _shouldAutoSize(renderedHeight) {
protected override _shouldAutoSize() {
if (this.isPercentHeight && this.parent) {
return true;
}
return super._shouldAutoSize(renderedHeight);
return super._shouldAutoSize();
}

private updateColumnList(recalcColSizes = true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,9 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<div class="igx-grid__tbody-content" tabindex="0" [attr.role]="dataView.length ? null : 'row'" (keydown)="navigation.handleNavigation($event)" (focus)="navigation.focusTbody($event)"
(dragStop)="selectionService.dragMode = $event" (scroll)="preventContainerScroll($event)"
(dragScroll)="dragScroll($event)" [igxGridDragSelect]="selectionService.dragMode"
[style.height.px]="totalHeight" [style.width.px]="pivotContentCalcWidth || null" #tbody [attr.aria-activedescendant]="activeDescendant">
[style.height.px]="totalHeight" #tbody [attr.aria-activedescendant]="activeDescendant">
@if (hasMovableColumns && columnInDrag && pinnedColumns.length <= 0) {
<span [igxColumnMovingDrop]="headerContainer" [attr.droppable]="true" id="left"
class="igx-grid__scroll-on-drag-left"></span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2517,4 +2517,10 @@ export class IgxPivotGridComponent extends IgxGridBaseDirective implements OnIni
this.regroupTrigger++;
}
}

protected override getUnpinnedWidth(takeHidden = false) {
return this.isPercentWidth ?
this.calcWidth :
super.getUnpinnedWidth(takeHidden);
}
}
Loading
Loading