diff --git a/projects/igniteui-angular/core/src/core/styles/components/grid/_excel-filtering-theme.scss b/projects/igniteui-angular/core/src/core/styles/components/grid/_excel-filtering-theme.scss index cb3070acd29..6c42815d62b 100644 --- a/projects/igniteui-angular/core/src/core/styles/components/grid/_excel-filtering-theme.scss +++ b/projects/igniteui-angular/core/src/core/styles/components/grid/_excel-filtering-theme.scss @@ -153,6 +153,12 @@ padding: 0; } + @if $variant == 'fluent' { + .igx-list__item-base:last-of-type { + border-bottom: rem(1px) solid transparent; + } + } + igx-chips-area { padding-inline: pad-inline(rem(4px), rem(8px), rem(16px)); padding-block-start: pad-block(rem(4px), rem(8px), rem(16px)); @@ -413,17 +419,13 @@ margin-inline: calc(sizable(rem(-16px)) * -1); - // This is the only way to take the gap from the list, - // otherwise we have to hardcoded here - > div { - gap: inherit; + igx-display-container { + padding-inline: pad(rem(8px)); } - igx-display-container { - display: flex; - flex-direction: column; - gap: inherit; - padding: pad(rem(8px)); + // Mirror the Indigo list gap inside the size measured by the virtualizer. + .igx-list__item-base { + padding-block-end: rem(4px); } } @else { margin-inline: calc(sizable(rem(-4px), rem(-8px), rem(-16px)) * -1); diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts index 08d076fc63b..5f9ab620904 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts @@ -188,6 +188,7 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { private _isLoading = true; private _addToCurrentFilterItem: FilterListItem; private _selectAllItem: FilterListItem; + private _measuredItemSize: number; private _hierarchicalSelectedItems: FilterListItem[]; private _focusedItem: ActiveElement = null; private destroy$ = new Subject(); @@ -258,6 +259,12 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { */ public refreshSize = () => { if (this.virtDir) { + const firstItem = this.list?.children.first; + const itemSize = firstItem?.element.getBoundingClientRect().height; + if (itemSize) { + // Excel filter rows are uniform; use the outer size to keep the scrollbar range stable. + this._measuredItemSize = itemSize; + } this.virtDir.igxForContainerSize = this.containerSize; this.virtDir.igxForItemSize = this.itemSize; this.virtDir.recalcUpdateSizes(); @@ -348,6 +355,9 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { */ public get itemSize() { let itemSize = '40px'; + if (this._measuredItemSize) { + return `${this._measuredItemSize}px`; + } const esf = this.esf as any; switch (esf.size) { case ɵSize.Medium: itemSize = '32px'; break; diff --git a/projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts b/projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts index b6135553bb7..387d730c2a9 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts @@ -4092,13 +4092,31 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { await wait(100); const searchComponent = fix.debugElement.query(By.css('igx-excel-style-search')).componentInstance; - const listElement = searchComponent.list.element.nativeElement as HTMLElement; + const listElement = searchComponent.list.element.nativeElement; listElement.style.border = '1px solid transparent'; expect(listElement.offsetHeight).toBeGreaterThan(listElement.clientHeight); expect(searchComponent.containerSize).toBe(listElement.clientHeight); }); + it('Should initialize virtual item sizes from the rendered list item', async () => { + GridFunctions.clickExcelFilterIconFromCodeAsync(fix, grid, 'ProductName'); + fix.detectChanges(); + await wait(100); + + const searchComponent = fix.debugElement.query(By.css('igx-excel-style-search')).componentInstance; + const virtDir = searchComponent.virtDir; + const firstItem = searchComponent.list.children.first.element; + spyOn(firstItem, 'getBoundingClientRect').and.returnValue(DOMRect.fromRect({ height: 37 })); + + searchComponent.refreshSize(); + fix.detectChanges(); + + expect(searchComponent.itemSize).toBe('37px'); + expect(virtDir.igxForItemSize).toBe('37px'); + expect(virtDir.individualSizeCache.at(-1)).toBe(37); + }); + it('Should allow to input commas in excel search component input field when column dataType is number.', async () => { GridFunctions.clickExcelFilterIconFromCodeAsync(fix, grid, 'Downloads'); fix.detectChanges(); @@ -4737,8 +4755,8 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { fix.detectChanges(); verifyExcelStyleFilterAvailableOptions(fix, - ['Select All', '(Blanks)', '0', '20', '100', '127', '254'], - [true, true, true, true, true, true, true]); + ['Select All', '(Blanks)', '0', '20', '100', '127', '254', '702'], + [true, true, true, true, true, true, true, true]); GridFunctions.clickExcelFilterIcon(fix, 'ProductName'); tick(100); @@ -6853,7 +6871,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify items in search have loaded and that the loading indicator is not visible. listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); loadingIndicator = GridFunctions.getExcelFilteringLoadingIndicator(fix); expect(loadingIndicator).toBeNull('esf loading indicator is visible'); })); @@ -6882,7 +6900,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify items in search have loaded and that the loading indicator is not visible. listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); loadingIndicator = GridFunctions.getExcelFilteringLoadingIndicator(fix); expect(loadingIndicator).toBeNull('esf loading indicator is visible'); })); @@ -6911,7 +6929,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify items in search have loaded and that the loading indicator is not visible. listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); loadingIndicator = GridFunctions.getExcelFilteringLoadingIndicator(fix); expect(loadingIndicator).toBeNull('esf loading indicator is visible'); })); @@ -6941,7 +6959,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify items in search have loaded and that the loading indicator is not visible. let listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); for (let i = 2; i < listItems.length; i++) { const label = datePipe.transform(dates[i - 2], formatOptions.format); @@ -6958,7 +6976,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify items in search have loaded and that the loading indicator is not visible. listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); listItems.forEach((item, ind) => { expect(item.innerText).toBe(downloads[ind]); @@ -6989,7 +7007,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify items in search have loaded and that the loading indicator is not visible. const listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); expect(listItems[1].innerText).toBe('(Blanks)'); for (let i = 2; i < listItems.length; i++) { @@ -7022,7 +7040,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { // Verify items in search have loaded and that the loading indicator is not visible. let listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); const checkboxElements = GridFunctions.getExcelStyleFilteringCheckboxes(fix); checkboxElements[2].click(); @@ -7038,7 +7056,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { fix.detectChanges(); listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); expect(listItems[1].innerText).toBe('(Blanks)'); for (let i = 2; i < listItems.length; i++) { @@ -7070,7 +7088,7 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { fix.detectChanges(); expect(compInstance.doneCallbackCounter).toBe(2, 'Incorrect done callback execution count'); listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix); - expect(listItems.length).toBe(7, 'incorrect rendered list items count'); + expect(listItems.length).toBe(8, 'incorrect rendered list items count'); loadingIndicator = GridFunctions.getExcelFilteringLoadingIndicator(fix); expect(loadingIndicator).toBeNull('esf loading indicator is visible'); })); diff --git a/src/app/virtual-for-directive/virtual-for.sample.css b/src/app/virtual-for-directive/virtual-for.sample.css index 180fc1a720e..6482ee2a4d1 100644 --- a/src/app/virtual-for-directive/virtual-for.sample.css +++ b/src/app/virtual-for-directive/virtual-for.sample.css @@ -38,6 +38,10 @@ align-items: center; } +.fixed-size-item > .igx-list__item-content { + height: 100%; +} + .vertical-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); diff --git a/src/app/virtual-for-directive/virtual-for.sample.html b/src/app/virtual-for-directive/virtual-for.sample.html index c6b05e44e0d..a758900cada 100644 --- a/src/app/virtual-for-directive/virtual-for.sample.html +++ b/src/app/virtual-for-directive/virtual-for.sample.html @@ -7,8 +7,8 @@

Vertical Virtualization

- -
{{rowIndex}}: {{item.text}}
+ +
{{rowIndex}}: {{item.text}}
@@ -77,9 +77,10 @@

Variable heights

- -
{{rowIndex}}: {{item.text}}
+ +
{{rowIndex}}: {{item.text}}
@@ -94,8 +95,8 @@

Even Variable

- -
{{rowIndex}} : {{item.text}}
+ +
{{rowIndex}} : {{item.text}}