Skip to content

Commit b79e1b9

Browse files
Merge branch '17.2.x' into ganastasov/fix-14262-17.2.x
2 parents 5a1baf4 + 3307119 commit b79e1b9

File tree

6 files changed

+159
-42
lines changed

6 files changed

+159
-42
lines changed

projects/igniteui-angular/src/lib/core/styles/components/query-builder/_query-builder-theme.scss

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@
225225
.igx-filter-tree__expression-column {
226226
padding-inline: pad-inline(rem(3px), rem(6px), rem(8px));
227227
}
228-
228+
229229
igx-prefix {
230230
display: flex;
231231
}
@@ -239,20 +239,10 @@
239239
%filter-tree__expression-actions {
240240
display: inline-flex;
241241
margin: 0 rem(8px);
242+
gap: rem(8px);
242243

243-
igx-icon {
244-
cursor: pointer;
245-
color: color(null, 'gray', 500);
246-
outline-style: none;
247-
248-
&:hover,
249-
&:focus {
250-
color: color(null, 'gray', 800);
251-
}
252-
}
253-
254-
igx-icon + igx-icon {
255-
margin-inline-start: rem(8px);
244+
%igx-icon-button-display {
245+
--size: #{sizable(rem(20px), rem(24px), rem(32px))};
256246
}
257247
}
258248

projects/igniteui-angular/src/lib/grids/grid/grid-filtering-advanced.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3001,6 +3001,40 @@ describe('IgxGrid - Advanced Filtering #grid - ', () => {
30013001
verifyContextMenuVisibility(fix, false);
30023002
}));
30033003

3004+
it('Should navigate with Tab/Shift+Tab through chips" "edit", "cancel" and "adding" buttons, fields of a condition in edit mode.', fakeAsync(() => {
3005+
// Apply advanced filter through API.
3006+
const tree = new FilteringExpressionsTree(FilteringLogic.Or);
3007+
tree.filteringOperands.push({
3008+
fieldName: 'ProductName', searchVal: 'angular', condition: IgxStringFilteringOperand.instance().condition('contains'),
3009+
ignoreCase: true
3010+
});
3011+
tree.filteringOperands.push({
3012+
fieldName: 'ProductName', searchVal: 'script', condition: IgxStringFilteringOperand.instance().condition('contains'),
3013+
ignoreCase: true
3014+
});
3015+
grid.advancedFilteringExpressionsTree = tree;
3016+
fix.detectChanges();
3017+
3018+
// Open Advanced Filtering dialog.
3019+
grid.openAdvancedFilteringDialog();
3020+
fix.detectChanges();
3021+
3022+
// Press 'Enter' on the second chip and verify it is selected.
3023+
UIInteractions.triggerKeyDownEvtUponElem('Enter', GridFunctions.getAdvancedFilteringTreeExpressionChip(fix, [0]));
3024+
tick(200);
3025+
fix.detectChanges();
3026+
3027+
let chipActions = fix.debugElement.query(By.css('.igx-filter-tree'));
3028+
GridFunctions.verifyTabbableElements(chipActions);
3029+
3030+
// Press 'Enter' on the edit button.
3031+
UIInteractions.triggerKeyDownEvtUponElem('Enter', GridFunctions.getAdvancedFilteringTreeExpressionEditIcon(fix, [0]));
3032+
fix.detectChanges();
3033+
3034+
chipActions = fix.debugElement.query(By.css('.igx-filter-tree'));
3035+
GridFunctions.verifyInEditTabbableElements(chipActions);
3036+
}));
3037+
30043038
});
30053039

30063040
});

projects/igniteui-angular/src/lib/grids/grid/grid.groupby.spec.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,6 +2175,28 @@ describe('IgxGrid - GroupBy #grid', () => {
21752175
expect(fix.componentInstance.onGroupByRowClick).toHaveBeenCalledWith(fix.componentInstance.groupByRowClick, contextUnselect);
21762176
}));
21772177

2178+
it('should update chips state when columns are added/removed', fakeAsync(() => {
2179+
const fix = TestBed.createComponent(GroupByDataMoreColumnsComponent);
2180+
const cols = fix.componentInstance.columns;
2181+
fix.componentInstance.columns = [];
2182+
fix.componentInstance.instance.groupingExpressions = [
2183+
{
2184+
dir: SortingDirection.Asc,
2185+
fieldName: 'A',
2186+
ignoreCase: false,
2187+
strategy: DefaultSortingStrategy.instance()
2188+
}
2189+
];
2190+
fix.detectChanges();
2191+
const chips = fix.componentInstance.instance.groupArea.chips;
2192+
let chipContent = chips.first.nativeElement.querySelector('.igx-chip__content').textContent.trim();
2193+
expect(chipContent).toBe('A');
2194+
fix.componentInstance.columns = cols;
2195+
fix.detectChanges();
2196+
chipContent = chips.first.nativeElement.querySelector('.igx-chip__content').textContent.trim();
2197+
expect(chipContent).toBe('AA');
2198+
}));
2199+
21782200
// GroupBy Row Formatting
21792201
it('should properly apply formatters, both custom and default ones for the default row value template', fakeAsync(() => {
21802202
const fix = TestBed.createComponent(GroupableGridComponent);
@@ -4103,7 +4125,7 @@ export class CustomTemplateGridComponent extends DataParent {
41034125
[width]='width'
41044126
[height]='height'
41054127
[data]="testData">
4106-
<igx-column *ngFor="let c of columns" [groupable]="true" [field]="c.field" [header]="c.field" [width]="c.width + 'px'">
4128+
<igx-column *ngFor="let c of columns" [groupable]="true" [field]="c.field" [header]="c.header || c.field" [width]="c.width + 'px'">
41074129
</igx-column>
41084130
</igx-grid>
41094131
`,
@@ -4119,7 +4141,7 @@ export class GroupByDataMoreColumnsComponent extends DataParent {
41194141
public testData = [];
41204142

41214143
public columns = [
4122-
{ field: 'A', width: 100 },
4144+
{ field: 'A', header: 'AA', width: 100 },
41234145
{ field: 'B', width: 100 },
41244146
{ field: 'C', width: 100 },
41254147
{ field: 'D', width: 100 },

projects/igniteui-angular/src/lib/grids/grouping/group-by-area.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<ng-container *ngFor="let expression of chipExpressions; let last = last;">
33
<igx-chip
44
[id]="expression.fieldName"
5-
[title]="(expression.fieldName | igxGroupByMeta:grid).title"
5+
[title]="(expression.fieldName | igxGroupByMeta:grid:grid.groupablePipeTrigger).title"
66
[displayDensity]="grid.displayDensity"
77
[removable]="(expression.fieldName | igxGroupByMeta:grid:grid.groupablePipeTrigger).groupable"
88
[draggable]="(expression.fieldName | igxGroupByMeta:grid:grid.groupablePipeTrigger).groupable"
@@ -11,7 +11,7 @@
1111
(remove)="clearGrouping($event.owner.id)"
1212
(chipClick)="handleClick(expression.fieldName)"
1313
>
14-
<span>{{ (expression.fieldName | igxGroupByMeta:grid).title }}</span>
14+
<span>{{ (expression.fieldName | igxGroupByMeta:grid:grid.groupablePipeTrigger).title }}</span>
1515
<igx-icon igxSuffix>{{ expression.dir === 1 ? 'arrow_upward' : 'arrow_downward' }}</igx-icon>
1616
</igx-chip>
1717

projects/igniteui-angular/src/lib/query-builder/query-builder.component.html

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -147,30 +147,32 @@ <h6 class="igx-filter-empty__title">
147147
expressionItem.hovered
148148
"
149149
>
150-
<span tabindex="0">
151-
<igx-icon
152-
(keydown)="invokeClick($event)"
153-
(click)="enterExpressionEdit(expressionItem)"
154-
>
155-
edit
156-
</igx-icon>
157-
</span>
158-
<span tabindex="0">
159-
<igx-icon
160-
(keydown)="invokeClick($event)"
161-
(click)="enterExpressionAdd(expressionItem)"
162-
*ngIf="
163-
!expressionItem.inAddMode &&
164-
(expressionItem.parent !== currentGroup ||
165-
expressionItem !==
166-
currentGroup.children[
167-
currentGroup.children.length - 1
168-
])
169-
"
170-
>
171-
add
172-
</igx-icon>
173-
</span>
150+
<button
151+
igxIconButton="flat"
152+
aria-labelledby="edit-expression"
153+
[style.--component-size]="getComponentSizeStyles()"
154+
(keydown)="invokeClick($event)"
155+
(click)="enterExpressionEdit(expressionItem)">
156+
<igx-icon id="edit-expression">edit</igx-icon>
157+
</button>
158+
159+
<button
160+
igxIconButton="flat"
161+
aria-labelledby="add-expression"
162+
[style.--component-size]="getComponentSizeStyles()"
163+
(keydown)="invokeClick($event)"
164+
(click)="enterExpressionAdd(expressionItem)"
165+
*ngIf="
166+
!expressionItem.inAddMode &&
167+
(expressionItem.parent !== currentGroup ||
168+
expressionItem !==
169+
currentGroup.children[
170+
currentGroup.children.length - 1
171+
])
172+
"
173+
>
174+
<igx-icon id="add-expression">add</igx-icon>
175+
</button>
174176
</div>
175177
</div>
176178

projects/igniteui-angular/src/lib/test-utils/grid-functions.spec.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2082,6 +2082,75 @@ export class GridFunctions {
20822082
expect(cell.isInvalid).toEqual(!valid);
20832083
expect(cell.nativeElement.classList.contains(CELL_INVALID_CSS_CLASS)).not.toEqual(valid);
20842084
}
2085+
2086+
public static verifyTabbableElements = (chipActions: DebugElement) => {
2087+
const tabElements = this.getTabbableElements(chipActions.nativeElement);
2088+
2089+
let i = 0;
2090+
tabElements.forEach((element: HTMLElement) => {
2091+
switch (i) {
2092+
case 0: expect(element).toHaveClass('igx-filter-tree__line--or'); break;
2093+
case 1: expect(element).toHaveClass('igx-chip'); break;
2094+
case 2: expect(element).toHaveClass('igx-chip__remove'); break;
2095+
case 3: expect(element.firstChild).toHaveClass('igx-icon');
2096+
expect(element.firstChild.textContent).toContain('edit');
2097+
break;
2098+
case 4: expect(element.firstChild).toHaveClass('igx-icon');
2099+
expect(element.firstChild.textContent).toContain('add');
2100+
break;
2101+
case 5: expect(element).toHaveClass('igx-chip'); break;
2102+
case 6: expect(element).toHaveClass('igx-chip__remove'); break;
2103+
case 7: expect(element).toHaveClass('igx-button');
2104+
expect(element.innerText).toContain('Condition');
2105+
break;
2106+
case 8: expect(element).toHaveClass('igx-button');
2107+
expect(element.innerText).toContain('"And" Group');
2108+
break;
2109+
case 9: expect(element).toHaveClass('igx-button');
2110+
expect(element.innerText).toContain('"Or" Group');
2111+
break;
2112+
}
2113+
i++;
2114+
});
2115+
};
2116+
2117+
public static verifyInEditTabbableElements = (chipActions: DebugElement) => {
2118+
const tabElements = this.getTabbableElements(chipActions.nativeElement);
2119+
2120+
let i = 0;
2121+
tabElements.forEach((element: HTMLElement) => {
2122+
switch (i) {
2123+
case 0: expect(element).toHaveClass('igx-filter-tree__line--or'); break;
2124+
case 1: expect(element).toHaveClass('igx-input-group__input'); break;
2125+
case 2: expect(element).toHaveClass('igx-input-group__input'); break;
2126+
case 3: expect(element).toHaveClass('igx-input-group__input'); break;
2127+
case 4: expect(element).toHaveClass('igx-icon-button');
2128+
expect(element.innerText).toContain('check');
2129+
break;
2130+
case 5: expect(element).toHaveClass('igx-icon-button');
2131+
expect(element.innerText).toContain('close');
2132+
break;
2133+
case 6: expect(element).toHaveClass('igx-chip'); break;
2134+
case 7: expect(element).toHaveClass('igx-chip__remove'); break;
2135+
}
2136+
i++;
2137+
});
2138+
};
2139+
2140+
/*
2141+
* Get tabbable elements in a container element. Result is returned as node elements ordered the way they will be tabbed
2142+
*/
2143+
public static getTabbableElements(inElement: HTMLElement) {
2144+
const focusableElements =
2145+
'a:not([disabled]), button:not([disabled]), input[type=text]:not([disabled]), [tabindex]:not([disabled]):not([tabindex="-1"])';
2146+
2147+
return Array.prototype.filter.call(
2148+
inElement.querySelectorAll(focusableElements),
2149+
element => {
2150+
return (element.offsetWidth > 0 || element.offsetHeight > 0);
2151+
}
2152+
);
2153+
}
20852154
}
20862155
export class GridSummaryFunctions {
20872156
public static getRootSummaryRow(fix): DebugElement {

0 commit comments

Comments
 (0)