Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
eb9878b
Initial plan
Copilot Mar 23, 2026
5c19548
feat(grids/filtering): add percent suffix to filter row and ESF dialo…
Copilot Mar 23, 2026
34290e3
refactor(grids/filtering): use specific CSS class for percent hint in…
Copilot Mar 23, 2026
cf9a296
chore(*): updating package-lock
Mar 24, 2026
77b01ec
refactor(grids/filtering): extract INPUT_DEBOUNCE_TIME_DEFAULT consta…
Copilot Mar 24, 2026
bd20cb6
Merge branch 'master' into copilot/clarify-percent-filter-ui
kdinev Mar 24, 2026
6f3f7ea
chore(*): updating package-lock
Mar 24, 2026
8cc5cfe
style(grids/filtering): constrain percent hint span in filter row to …
Copilot Mar 24, 2026
04e5afe
chore(*): Adjust max-width for input in filter row.
MayaKirova Mar 25, 2026
e9fd8c7
Merge branch 'master' into copilot/clarify-percent-filter-ui
kdinev Mar 25, 2026
adf58e6
Merge branch 'master' of https://github.com/IgniteUI/igniteui-angular…
Mar 30, 2026
8eed898
chore(*): fixing demos used for test
Mar 30, 2026
8ea0c5f
chore(*): fixing package-lock
Mar 30, 2026
043e555
Merge branch 'master' into copilot/clarify-percent-filter-ui
kdinev Mar 30, 2026
787eb4c
test(grids/filtering): increase grid width in chip scroll test to acc…
Copilot Mar 30, 2026
0f70345
Merge branch 'master' into copilot/clarify-percent-filter-ui
kdinev Mar 30, 2026
c15d579
chore(*): fixing package-lock
Mar 30, 2026
a5f99d0
Merge branch 'copilot/clarify-percent-filter-ui' of https://github.co…
Mar 30, 2026
f61f871
Merge branch 'master' into copilot/clarify-percent-filter-ui
kdinev Mar 31, 2026
9353257
Merge branch 'master' into copilot/clarify-percent-filter-ui
kdinev Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
328 changes: 166 additions & 162 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@
%filtering-row-input-overrides {
igx-input-group {
width: 100%;
max-width: rem(200px);
max-width: rem(240px);
min-width: rem(140px);

@if $variant != 'fluent' {
Expand Down Expand Up @@ -2482,6 +2482,16 @@
margin: rem(4px);
}
}

.igx-grid__filtering-row-percent-hint {
display: inline-block;
max-width: rem(56px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: middle;
flex-shrink: 1;
}
}

%igx-grid__filtering-dropdown-items {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
(keyup)="onInputKeyUp()"/>
@if (value || value === 0) {
<igx-suffix>
@if (column.dataType === 'percent') {
<span class="igx-grid__filtering-row-percent-hint">{{ value | percent:column.pipeArgs.digitsInfo:filteringService.grid.locale }}</span>
}
<igx-icon
(keydown)="onCommitKeyDown($event)"
(click)="onCommitClick()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,22 @@ import { IBaseChipEventArgs, IgxChipComponent, IgxChipsAreaComponent } from 'ign
import { IgxIconComponent } from 'igniteui-angular/icon';
import { IgxInputDirective, IgxInputGroupComponent, IgxPrefixDirective, IgxSuffixDirective } from 'igniteui-angular/input-group';
import { IgxDatePickerComponent } from 'igniteui-angular/date-picker';
import { AbsoluteScrollStrategy, ColumnType, ConnectedPositioningStrategy, DataUtil, FilteringLogic, GridColumnDataType, HorizontalAlignment, IFilteringExpression, IFilteringOperation, IgxPickerClearComponent, IgxPickerToggleComponent, isEqual, OverlaySettings, PlatformUtil, ɵSize, VerticalAlignment } from 'igniteui-angular/core';
import { AbsoluteScrollStrategy, ColumnType, ConnectedPositioningStrategy, DataUtil, FilteringLogic, GridColumnDataType, HorizontalAlignment, IFilteringExpression, IFilteringOperation, IgxPercentFormatterPipe, IgxPickerClearComponent, IgxPickerToggleComponent, isEqual, OverlaySettings, PlatformUtil, ɵSize, VerticalAlignment } from 'igniteui-angular/core';
import { IgxTimePickerComponent } from 'igniteui-angular/time-picker';
import { IgxButtonDirective, IgxDateTimeEditorDirective, IgxIconButtonDirective, IgxRippleDirective } from 'igniteui-angular/directives';

/**
* Default debounce time (ms) for filtering row inputs.
* @hidden
*/
export const INPUT_DEBOUNCE_TIME_DEFAULT = 350;

/**
* Injection token for setting the debounce time used in filtering row inputs.
* @hidden
*/
export const INPUT_DEBOUNCE_TIME = /*@__PURE__*/new InjectionToken<number>('INPUT_DEBOUNCE_TIME', {
factory: () => 350
factory: () => INPUT_DEBOUNCE_TIME_DEFAULT
});

/**
Expand Down Expand Up @@ -65,7 +71,8 @@ export const INPUT_DEBOUNCE_TIME = /*@__PURE__*/new InjectionToken<number>('INPU
IgxButtonDirective,
NgClass,
IgxRippleDirective,
IgxIconButtonDirective
IgxIconButtonDirective,
IgxPercentFormatterPipe
]
})
export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDestroy {
Expand Down Expand Up @@ -280,6 +287,7 @@ export class IgxGridFilteringRowComponent implements OnInit, AfterViewInit, OnDe
return 'text';
case GridColumnDataType.Number:
case GridColumnDataType.Currency:
case GridColumnDataType.Percent:
return 'number';
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
[(ngModel)]="expressionUI.expression.searchVal"
(blur)="updateSearchValueOnBlur($event)"
/>
@if (column.dataType === 'percent' && (expressionUI.expression.searchVal || expressionUI.expression.searchVal === 0)) {
<igx-suffix>
<span class="igx-grid__filtering-row-percent-hint">{{ expressionUI.expression.searchVal | percent:column.pipeArgs.digitsInfo:grid.locale }}</span>
</igx-suffix>
}
</igx-input-group>

@if (!isSingle) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Component, AfterViewInit, Input, Output, EventEmitter, ChangeDetectorRef, ViewChild, inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ExpressionUI } from './common';
import { AbsoluteScrollStrategy, ColumnType, ConnectedPositioningStrategy, DataUtil, FilteringLogic, GridColumnDataType, IBaseEventArgs, IFilteringOperation, IgxOverlayOutletDirective, OverlaySettings, PlatformUtil } from 'igniteui-angular/core';
import { AbsoluteScrollStrategy, ColumnType, ConnectedPositioningStrategy, DataUtil, FilteringLogic, GridColumnDataType, IBaseEventArgs, IFilteringOperation, IgxOverlayOutletDirective, IgxPercentFormatterPipe, OverlaySettings, PlatformUtil } from 'igniteui-angular/core';
import { IgxSelectComponent, IgxSelectItemComponent } from 'igniteui-angular/select';
import { IgxInputDirective, IgxInputGroupComponent, IgxPrefixDirective } from 'igniteui-angular/input-group';
import { IgxInputDirective, IgxInputGroupComponent, IgxPrefixDirective, IgxSuffixDirective } from 'igniteui-angular/input-group';
import { IgxIconComponent } from 'igniteui-angular/icon';
import { IgxButtonDirective, IgxIconButtonDirective } from 'igniteui-angular/directives';
import { IgxButtonGroupComponent } from 'igniteui-angular/button-group';
Expand All @@ -22,7 +22,7 @@ export interface ILogicOperatorChangedArgs extends IBaseEventArgs {
@Component({
selector: 'igx-excel-style-default-expression',
templateUrl: './excel-style-default-expression.component.html',
imports: [FormsModule, IgxSelectComponent, IgxPrefixDirective, IgxIconComponent, IgxSelectItemComponent, IgxInputGroupComponent, IgxInputDirective, IgxButtonDirective, IgxButtonGroupComponent, IgxOverlayOutletDirective, IgxIconButtonDirective]
imports: [FormsModule, IgxSelectComponent, IgxPrefixDirective, IgxIconComponent, IgxSelectItemComponent, IgxInputGroupComponent, IgxInputDirective, IgxSuffixDirective, IgxButtonDirective, IgxButtonGroupComponent, IgxOverlayOutletDirective, IgxIconButtonDirective, IgxPercentFormatterPipe]
})
export class IgxExcelStyleDefaultExpressionComponent implements AfterViewInit {
public cdr = inject(ChangeDetectorRef);
Expand Down
73 changes: 72 additions & 1 deletion projects/igniteui-angular/grids/grid/src/column.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { UIInteractions, wait } from '../../../test-utils/ui-interactions.spec';
import { GridFunctions, GridSummaryFunctions } from '../../../test-utils/grid-functions.spec';
import { IgxCellFooterTemplateDirective, IgxCellHeaderTemplateDirective, IgxCellTemplateDirective, IgxColumnComponent, IgxSummaryTemplateDirective } from 'igniteui-angular/grids/core';
import { IgxCellFooterTemplateDirective, IgxCellHeaderTemplateDirective, IgxCellTemplateDirective, IgxColumnComponent, INPUT_DEBOUNCE_TIME_DEFAULT, IgxSummaryTemplateDirective } from 'igniteui-angular/grids/core';
import { IgxGridRowComponent } from './grid-row.component';
import { GridColumnDataType, IgxStringFilteringOperand, SortingDirection } from 'igniteui-angular/core';
import { IgxButtonDirective, IgxDateTimeEditorDirective } from 'igniteui-angular/directives';
Expand Down Expand Up @@ -838,6 +838,77 @@ describe('IgxGrid - Column properties #grid', () => {
expect((checkBoxes[3].querySelector('.igx-checkbox__label') as HTMLElement).innerText).toEqual('002.700%');
}));

it('should show percent suffix in filter row when filtering a percent column', fakeAsync(() => {
const fix = TestBed.createComponent(IgxGridPercentColumnComponent);
fix.detectChanges();

const grid = fix.componentInstance.grid;
const discountColumn = grid.getColumnByName('Discount');
grid.allowFiltering = true;
fix.detectChanges();

GridFunctions.clickFilterCellChip(fix, discountColumn.field);
tick(100);
fix.detectChanges();

const filterUIRow = fix.debugElement.query(By.css('igx-grid-filtering-row'));
const input = filterUIRow.query(By.directive(IgxInputDirective));

// Suffix should not be visible before entering a value
let percentLabel = filterUIRow.query(By.css('.igx-grid__filtering-row-percent-hint'));
expect(percentLabel).toBeNull();

// Enter a value to trigger the suffix; wait for the filter row input debounce
GridFunctions.typeValueInFilterRowInput(0.03, fix, input);
tick(INPUT_DEBOUNCE_TIME_DEFAULT);
fix.detectChanges();

percentLabel = filterUIRow.query(By.css('.igx-grid__filtering-row-percent-hint'));
expect(percentLabel).not.toBeNull();
expect(percentLabel.nativeElement.textContent.trim()).toEqual('3%');
}));

it('should show percent suffix in ESF custom dialog when filtering a percent column', fakeAsync(() => {
const fix = TestBed.createComponent(IgxGridPercentColumnComponent);
tick();
fix.detectChanges();

const grid = fix.componentInstance.grid;
const discountColumn = grid.getColumnByName('Discount');
grid.allowFiltering = true;
grid.filterMode = 'excelStyleFilter';
fix.detectChanges();

GridFunctions.clickExcelFilterIcon(fix, discountColumn.field);
tick(100);
fix.detectChanges();

GridFunctions.clickExcelFilterCascadeButton(fix);
tick(100);
fix.detectChanges();

// Open custom filter dialog by selecting first operator (Equals)
GridFunctions.clickOperatorFromCascadeMenu(fix, 0);
tick(200);
fix.detectChanges();

const exprComponents = GridFunctions.getExcelCustomFilteringDefaultExpressions(fix);
expect(exprComponents.length).toBeGreaterThan(0);

// Percent label should not be visible before entering a value
let percentLabel = exprComponents[0].querySelector('.igx-grid__filtering-row-percent-hint');
expect(percentLabel).toBeNull();

// Enter a value to trigger the suffix
GridFunctions.setInputValueESF(fix, 0, 0.05);
tick(100);
fix.detectChanges();

percentLabel = exprComponents[0].querySelector('.igx-grid__filtering-row-percent-hint');
expect(percentLabel).not.toBeNull();
expect(percentLabel.textContent.trim()).toEqual('5%');
}));

});

describe('Date, DateTime and Time column tests', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1977,7 +1977,7 @@ describe('IgxGrid - Filtering Row UI actions #grid', () => {
}));

it('should scroll correct chip in view when one is deleted', async () => {
grid.width = '800px';
grid.width = '840px';
fix.detectChanges();
await wait(DEBOUNCE_TIME);

Expand Down
11 changes: 9 additions & 2 deletions src/app/grid-filtering/grid-filtering.sample.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, ViewChild, OnInit, HostBinding } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { FilterMode, FilteringExpressionsTree, FilteringLogic, FormattedValuesFilteringStrategy, GridSelectionMode, IChangeCheckboxEventArgs, IGX_GRID_DIRECTIVES, IgxButtonGroupComponent, IgxCheckboxComponent, IgxGridComponent, IgxIconComponent, IgxStringFilteringOperand } from 'igniteui-angular';
import { FilterMode, FilteringExpressionsTree, FilteringLogic, FormattedValuesFilteringStrategy, GridSelectionMode, IChangeCheckboxEventArgs, IGX_GRID_DIRECTIVES, IgxButtonDirective, IgxButtonGroupComponent, IgxCheckboxComponent, IgxGridComponent, IgxIconComponent, IgxStringFilteringOperand } from 'igniteui-angular';
import { SAMPLE_DATA } from '../shared/sample-data';


Expand All @@ -9,7 +9,14 @@ import { SAMPLE_DATA } from '../shared/sample-data';
selector: 'app-grid-filtering-sample',
styleUrls: ['grid-filtering.sample.scss'],
templateUrl: 'grid-filtering.sample.html',
imports: [FormsModule, IGX_GRID_DIRECTIVES, IgxCheckboxComponent, IgxButtonGroupComponent, IgxIconComponent]
imports: [
FormsModule,
IGX_GRID_DIRECTIVES,
IgxCheckboxComponent,
IgxButtonGroupComponent,
IgxIconComponent,
IgxButtonDirective
]
})
export class GridFilteringComponent implements OnInit {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="wrapper">
<div class="sample-content">
<div class="sample-column">
<igx-grid [data]="data" [locale]="locale" [allowFiltering]="true" [moving]="true" [filterMode]="'excelStyleFilter'" width="420px" height="600px">
<igx-grid [data]="data" [locale]="locale" [allowFiltering]="true" [moving]="true" [filterMode]="'excelStyleFilter'" width="100%" height="600px">
<igx-column field="ProductName" [pinned]="false" header="Product Name" width="20%" [dataType]="'string'" [sortable]="true" [hasSummary]="false" [editable]="true" [filterable]="true" >
</igx-column>
<igx-column field="UnitsInStock" [pinned]="false" header="Units In Stock" width="20%" dataType="currency" [pipeArgs]="pipeArgs" [sortable]="true" [hasSummary]="true" [editable]="true" [filterable]="true" >
Expand All @@ -11,10 +11,10 @@
{{val | date:'dd/MM/yyyy'}}
</ng-template>
</igx-column>
<igx-column field="Discontinued" header="Discontinued" width="10%" [dataType]="'boolean'" minWidth="20px"
<igx-column field="Discontinued" header="Discontinued" width="10%" [dataType]="'boolean'" minWidth="20px"
[sortable]="false" [hasSummary]="false" [editable]="true" [filterable]="false">
</igx-column>
<igx-column field="ReorderLevel" header="Reorder Level" dataType="percent" [pipeArgs]="pipeArgs" [hasSummary]="true" width="10%" [sortable]="false" [editable]="true" >
<igx-column field="ReorderLevel" header="Reorder Level" dataType="percent" [pipeArgs]="pipeArgs" [hasSummary]="true" width="10%" [sortable]="false" [editable]="true" >
</igx-column>
<igx-column field="SupplierID" header="SupplierID" width="10%" [sortable]="false" [editable]="true">
</igx-column>
Expand Down
Loading