diff --git a/package-lock.json b/package-lock.json index d164bf43726..d1c9475b89f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,6 +86,7 @@ "karma-chrome-launcher": "~3.2.0", "karma-coverage": "^2.0.3", "karma-jasmine": "~5.1.0", + "karma-jasmine-spec-tags": "^2.0.0", "karma-junit-reporter": "^2.0.1", "karma-parallel": "^0.3.1", "karma-spec-reporter": "^0.0.36", @@ -4750,7 +4751,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4771,7 +4771,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4792,7 +4791,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4813,7 +4811,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4834,7 +4831,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4855,7 +4851,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4876,7 +4871,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4897,7 +4891,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4918,7 +4911,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4939,7 +4931,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4960,7 +4951,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4981,7 +4971,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -5002,7 +4991,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -15820,6 +15808,18 @@ "karma": "^6.0.0" } }, + "node_modules/karma-jasmine-spec-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-spec-tags/-/karma-jasmine-spec-tags-2.0.0.tgz", + "integrity": "sha512-ckTZvS+w9LyYQtI/LY6nNS6oiuQM7bSRzJgLBwde5Ivr6k5uQ1y58HD77YQH9+rWIj048LXBpXk2VY3ws9hE2A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine": ">=4 || >=5", + "karma": ">=6.0.4", + "karma-jasmine": "*" + } + }, "node_modules/karma-jasmine/node_modules/jasmine-core": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", @@ -22254,33 +22254,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==", - "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", @@ -22309,21 +22282,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==", - "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", @@ -22360,36 +22318,6 @@ } } }, - "node_modules/sassdoc-theme-default/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "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", diff --git a/package.json b/package.json index 71392ae88bc..f1471322bc9 100644 --- a/package.json +++ b/package.json @@ -136,6 +136,7 @@ "karma-chrome-launcher": "~3.2.0", "karma-coverage": "^2.0.3", "karma-jasmine": "~5.1.0", + "karma-jasmine-spec-tags": "^2.0.0", "karma-junit-reporter": "^2.0.1", "karma-parallel": "^0.3.1", "karma-spec-reporter": "^0.0.36", diff --git a/projects/igniteui-angular/grids/core/src/columns/column.component.ts b/projects/igniteui-angular/grids/core/src/columns/column.component.ts index d22c329d338..373336c8d42 100644 --- a/projects/igniteui-angular/grids/core/src/columns/column.component.ts +++ b/projects/igniteui-angular/grids/core/src/columns/column.component.ts @@ -2682,7 +2682,7 @@ export class IgxColumnComponent implements AfterContentInit, OnDestroy, ColumnTy } else if (this.minWidth && newSize <= this.userSetMinWidthPx) { this.widthConstrained = true; return this.userSetMinWidthPx; - } else if (!this.minWidth && (!this.widthSetByUser || this.width === 'fit-content') && !this.grid.columnWidthSetByUser && (!newSize || newSize <= this.grid.minColumnWidth)) { + } else if ((this.columnLayout || !this.columnGroup) && !this.minWidth && (!this.widthSetByUser || this.width === 'fit-content') && !this.grid.columnWidthSetByUser && (!newSize || newSize <= this.grid.minColumnWidth)) { return this.grid.minColumnWidth; } else { this.widthConstrained = false; diff --git a/projects/igniteui-angular/grids/grid/src/grid-collapsible-columns.spec.ts b/projects/igniteui-angular/grids/grid/src/grid-collapsible-columns.spec.ts index f4fc2273286..0d829f13036 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-collapsible-columns.spec.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-collapsible-columns.spec.ts @@ -4,7 +4,8 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { CollapsibleColumnGroupTestComponent, CollapsibleGroupsTemplatesTestComponent, - CollapsibleGroupsDynamicColComponent + CollapsibleGroupsDynamicColComponent, + CollapsibleColumnGroupWithExplicitWidthsComponent } from '../../../test-utils/grid-samples.spec'; import { GridFunctions } from '../../../test-utils/grid-functions.spec'; import { UIInteractions, wait } from '../../../test-utils/ui-interactions.spec'; @@ -12,6 +13,44 @@ import { DropPosition } from 'igniteui-angular/grids/core'; import { IgxColumnGroupComponent } from 'igniteui-angular/grids/core'; import { SortingDirection } from 'igniteui-angular/core'; +describe('IgxGrid - collapsible column group with explicit widths regression #17042 #grid', () => { + let fixture; + let grid: IgxGridComponent; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [ + NoopAnimationsModule, + CollapsibleColumnGroupWithExplicitWidthsComponent + ] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CollapsibleColumnGroupWithExplicitWidthsComponent); + fixture.detectChanges(); + grid = fixture.componentInstance.grid; + }); + + it('collapsed column group calcPixelWidth should equal the sum of visible children calcPixelWidth when columns have explicit widths smaller than minColumnWidth', () => { + const colGroup = grid.getColumnByName('ID').parent as IgxColumnGroupComponent; + const visibleChild = grid.getColumnByName('ID'); + + // Group is collapsed by default (expanded=false in the template) + expect(colGroup.collapsible).toBeTrue(); + expect(colGroup.expanded).toBeFalse(); + + // The visible child has explicit width 100px, which is less than the grid's MINIMUM_COLUMN_WIDTH (136px). + // The column group's calcPixelWidth should equal its visible child's calcPixelWidth, + // NOT be inflated to the grid's minimum column width. + const visibleChildWidth = visibleChild.calcPixelWidth; + const groupWidth = colGroup.calcPixelWidth; + + expect(visibleChildWidth).toBe(100); + expect(groupWidth).toBe(visibleChildWidth); + }); +}); + describe('IgxGrid - multi-column headers #grid', () => { let contactInf; let countryInf; diff --git a/projects/igniteui-angular/test-utils/grid-samples.spec.ts b/projects/igniteui-angular/test-utils/grid-samples.spec.ts index 05685a5cd69..4f1d0a558ef 100644 --- a/projects/igniteui-angular/test-utils/grid-samples.spec.ts +++ b/projects/igniteui-angular/test-utils/grid-samples.spec.ts @@ -2009,6 +2009,34 @@ export class CollapsibleGroupsDynamicColComponent { } } +/** + * Test component for verifying that a collapsed collapsible column group with explicit column widths + * smaller than the grid's MINIMUM_COLUMN_WIDTH does not cause header/cell misalignment. + * Regression test for: https://github.com/IgniteUI/igniteui-angular/issues/17042 + */ +@Component({ + template: ` + + + + + + + + + + + + + `, + imports: [IgxGridComponent, IgxColumnComponent, IgxColumnGroupComponent] +}) +export class CollapsibleColumnGroupWithExplicitWidthsComponent { + @ViewChild(IgxGridComponent, { read: IgxGridComponent, static: true }) + public grid: IgxGridComponent; + public data = SampleTestData.contactInfoDataFull(); +} + @Component({ template: `