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..15612dba182 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(); 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}}