From d3e1911f187fcc785821f520aeef672b247ad775 Mon Sep 17 00:00:00 2001 From: MKirova Date: Mon, 16 Feb 2026 14:30:41 +0200 Subject: [PATCH 1/5] fix(Grid): Add border to rendered height calc. --- .../grids/grid/src/grid-base.directive.ts | 8 ++++++-- src/app/grid-auto-size/grid-auto-size.sample.scss | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) 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 508dbbf873c..6b86a65e19a 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts @@ -7223,20 +7223,24 @@ export abstract class IgxGridBaseDirective implements GridType, if (!this._height) { return null; } + const styles = this.document.defaultView.getComputedStyle(this.nativeElement); 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 borderTop = parseFloat(styles.getPropertyValue('border-top')); + const borderBottom = parseFloat(styles.getPropertyValue('border-bottom')); + const renderedHeight = toolbarHeight + actualTheadRow + footerHeight + pagingHeight + groupAreaHeight + - scrHeight; + scrHeight + borderTop + borderBottom; let gridHeight = 0; if (this.isPercentHeight) { - const computed = this.document.defaultView.getComputedStyle(this.nativeElement).getPropertyValue('height'); + const computed = styles.getPropertyValue('height'); const autoSize = this._shouldAutoSize(renderedHeight); if (autoSize || computed.indexOf('%') !== -1) { const bodyHeight = this.getDataBasedBodyHeight(); diff --git a/src/app/grid-auto-size/grid-auto-size.sample.scss b/src/app/grid-auto-size/grid-auto-size.sample.scss index 5e9b37fd2f3..ba31d96c318 100644 --- a/src/app/grid-auto-size/grid-auto-size.sample.scss +++ b/src/app/grid-auto-size/grid-auto-size.sample.scss @@ -11,3 +11,8 @@ margin-bottom: 16px; max-width: 900px; } + + +igx-grid { + border: 1px solid lightgray; + } From 4a1f99cdc359743d3fd6568c44695d5b4ac1b806 Mon Sep 17 00:00:00 2001 From: MKirova Date: Mon, 16 Feb 2026 14:49:03 +0200 Subject: [PATCH 2/5] chore(*): Fallback in case of no border. --- .../igniteui-angular/grids/grid/src/grid-base.directive.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 6b86a65e19a..5c1c5e7becf 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts @@ -7230,8 +7230,8 @@ export abstract class IgxGridBaseDirective implements GridType, const pagingHeight = this.getPagingFooterHeight(); const groupAreaHeight = this.getGroupAreaHeight(); const scrHeight = this.getComputedHeight(this.scr.nativeElement); - const borderTop = parseFloat(styles.getPropertyValue('border-top')); - const borderBottom = parseFloat(styles.getPropertyValue('border-bottom')); + const borderTop = parseFloat(styles.getPropertyValue('border-top')) || 0; + const borderBottom = parseFloat(styles.getPropertyValue('border-bottom')) || 0; const renderedHeight = toolbarHeight + actualTheadRow + footerHeight + pagingHeight + groupAreaHeight + From 87337dd83c45ddd966a7fc9e027960da9f211e43 Mon Sep 17 00:00:00 2001 From: Maya Date: Fri, 3 Apr 2026 15:22:57 +0300 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../igniteui-angular/grids/grid/src/grid-base.directive.ts | 4 ++-- src/app/grid-auto-size/grid-auto-size.sample.scss | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) 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 f6693e7a61d..04482ff38fc 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-base.directive.ts @@ -7253,8 +7253,8 @@ export abstract class IgxGridBaseDirective implements GridType, const pagingHeight = this.getPagingFooterHeight(); const groupAreaHeight = this.getGroupAreaHeight(); const scrHeight = this.getComputedHeight(this.scr.nativeElement); - const borderTop = parseFloat(styles.getPropertyValue('border-top')) || 0; - const borderBottom = parseFloat(styles.getPropertyValue('border-bottom')) || 0; + const borderTop = parseFloat(styles.getPropertyValue('border-top-width')) || 0; + const borderBottom = parseFloat(styles.getPropertyValue('border-bottom-width')) || 0; const renderedHeight = toolbarHeight + actualTheadRow + footerHeight + pagingHeight + groupAreaHeight + diff --git a/src/app/grid-auto-size/grid-auto-size.sample.scss b/src/app/grid-auto-size/grid-auto-size.sample.scss index ba31d96c318..381adfb8f86 100644 --- a/src/app/grid-auto-size/grid-auto-size.sample.scss +++ b/src/app/grid-auto-size/grid-auto-size.sample.scss @@ -12,7 +12,6 @@ max-width: 900px; } - igx-grid { border: 1px solid lightgray; - } +} From 3f2f189bead33032a6d098575470199d4da8e5c8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Apr 2026 08:21:24 +0000 Subject: [PATCH 4/5] test(grid): add unit test for border width in body height calculation with percent height #16640 Agent-Logs-Url: https://github.com/IgniteUI/igniteui-angular/sessions/e7e33240-acb0-4254-a7c2-186b9168a9f2 Co-authored-by: MayaKirova <10397980+MayaKirova@users.noreply.github.com> --- package-lock.json | 64 ------------------- .../grids/grid/src/grid.component.spec.ts | 24 +++++++ 2 files changed, 24 insertions(+), 64 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd645501a94..2fe194e0d9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22409,31 +22409,6 @@ "sassdoc-extras": "^2.5.0" } }, - "node_modules/sassdoc-theme-default/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/sassdoc-theme-default/node_modules/commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", @@ -22462,19 +22437,6 @@ "jsonfile": "^2.1.0" } }, - "node_modules/sassdoc-theme-default/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "extraneous": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/sassdoc-theme-default/node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -22511,32 +22473,6 @@ } } }, - "node_modules/sassdoc-theme-default/node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "extraneous": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/sassdoc-theme-default/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/sassdoc/node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", diff --git a/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts b/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts index 3dbf7acad9b..2ccd8f07ee0 100644 --- a/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts +++ b/projects/igniteui-angular/grids/grid/src/grid.component.spec.ts @@ -1307,6 +1307,30 @@ describe('IgxGrid Component Tests #grid', () => { expect(parseInt(window.getComputedStyle(domGrid).height, 10)).toBe(300); })); + it('should account for CSS border widths in body height calculation when height is percent #16640', fakeAsync(() => { + const fix = TestBed.createComponent(IgxGridWrappedInContComponent); + fix.componentInstance.outerHeight = 600; + fix.componentInstance.data = fix.componentInstance.fullData; + tick(); + fix.detectChanges(); + + const grid = fix.componentInstance.grid; + const calcHeightNoBorder = grid.calcHeight; + expect(calcHeightNoBorder).not.toBeNull(); + + // Apply a 2px border (top and bottom) to the grid's native element + grid.nativeElement.style.borderTop = '2px solid black'; + grid.nativeElement.style.borderBottom = '2px solid black'; + + // Trigger height recalculation + grid.reflow(); + fix.detectChanges(); + + // The fix ensures border widths are included in the rendered height calculation, + // reducing the available body height accordingly and preventing continuous reflow growth + expect(grid.calcHeight).toBe(calcHeightNoBorder - 4); + })); + it('should keep auto-sizing if initial data is empty then set to a new array', fakeAsync(() => { const fix = TestBed.createComponent(IgxGridWrappedInContComponent); tick(); From 7756bfd0d1f6ea44299423b5b3fcafb1dd47a0f8 Mon Sep 17 00:00:00 2001 From: Deyan Kamburov Date: Thu, 9 Apr 2026 18:11:08 +0300 Subject: [PATCH 5/5] fix(package-lock): revert removed deps: chokidar, glob-parent, picomatch --- package-lock.json | 85 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/package-lock.json b/package-lock.json index 8a58105b573..95f69ce683b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4730,6 +4730,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4750,6 +4751,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4770,6 +4772,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4790,6 +4793,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4810,6 +4814,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4830,6 +4835,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4850,6 +4856,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4870,6 +4877,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4890,6 +4898,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4910,6 +4919,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4930,6 +4940,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4950,6 +4961,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4970,6 +4982,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -22368,6 +22381,33 @@ "sassdoc-extras": "^2.5.0" } }, + "node_modules/sassdoc-theme-default/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/sassdoc-theme-default/node_modules/commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", @@ -22396,6 +22436,21 @@ "jsonfile": "^2.1.0" } }, + "node_modules/sassdoc-theme-default/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/sassdoc-theme-default/node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -22432,6 +22487,36 @@ } } }, + "node_modules/sassdoc-theme-default/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/sassdoc-theme-default/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/sassdoc/node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",