Skip to content

Commit c3c481c

Browse files
authored
Merge branch 'master' into mkirova/fix-ghost-selection
2 parents 965f553 + dbef411 commit c3c481c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2005
-583
lines changed

.github/PULL_REQUEST_TEMPLATE.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ Closes #
99

1010
### Checklist:
1111
- [ ] All relevant tags have been applied to this PR
12-
- [ ] This PR includes unit tests covering all the new code
13-
- [ ] This PR includes API docs for newly added methods/properties
12+
- [ ] This PR includes unit tests covering all the new code ([test guidelines](https://github.com/IgniteUI/igniteui-angular/wiki/Test-implementation-guidelines-for-Ignite-UI-for-Angular))
13+
- [ ] This PR includes API docs for newly added methods/properties ([api docs guidelines](https://github.com/IgniteUI/igniteui-angular/wiki/Documentation-Guidelines))
1414
- [ ] This PR includes `feature/README.MD` updates for the feature docs
1515
- [ ] This PR includes general feature table updates in the root `README.MD`
1616
- [ ] This PR includes `CHANGELOG.MD` updates for newly added functionality
1717
- [ ] This PR contains breaking changes
18-
- [ ] This PR includes `ng update` migrations for the breaking changes
18+
- [ ] This PR includes `ng update` migrations for the breaking changes ([migrations guidelines](https://github.com/IgniteUI/igniteui-angular/wiki/Update-Migrations))
1919
- [ ] This PR includes behavioral changes and the feature specification has been updated with them
2020

CHANGELOG.md

+12
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@ All notable changes for each version of this project will be documented in this
6464
- `deselectColumns` API method is added for the `IgxGrid`. It allows to deselect columns by passing array of IgxColumnComponent or column fields.
6565
- `deselectAllColumns` API method is added for the `IgxGrid`. It allows to deselect all columns.
6666
- `getSelectedColumnsData` API method is added for the `IgxGrid`. It allows to get the selected columns data.
67+
Added keyBoard navigation support in the IgxGrid headers. Now is possible to navigate with the arrows keys through grid headers. Also we provide a number of key combinations that trigger a different column functionality like filtering, sorting, grouping and etc. You can read more information in the [Grid Specification](https://github.com/IgniteUI/igniteui-angular/wiki/igxGrid-Specification#kb-navigation).
68+
- **Behavioral Change**
69+
- *you can not use* `tab` key to navigate between the cell in the Igx Grid. The navigation is performed only with arrow keys.
70+
- when you are in edit mode with `tab` key you can navigate to the next editable cell.
71+
- `page up` and `page down` keys will perform action only if the focused element is the tbody of the grid.
72+
- The grid introduces the following basic `tab stops`:
73+
- Toolbar / Group by Area if existing;
74+
- The first cell in the header row;
75+
- The first cell in the first body row;
76+
- The first cell in column summary if exists;
77+
- Pager UI;
78+
- `onGridKeydown` event is deprecated. Now you can directly bind to keydown on the IgxGrid component in order to perform custom keyboard navigation.
6779

6880
- `IgxCombo`:
6981
- Added `autoFocusSearch` input that allows to manipulate the combo's opening behavior. When the property is `true` (by default), the combo's search input is focused on open. When set to `false`, the focus goes to the combo items container, which can be used to prevent the software keyboard from activating on mobile devices when opening the combo.

projects/igniteui-angular/src/lib/checkbox/checkbox.component.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<div class="igx-checkbox__ripple"></div>
3535
</div>
3636

37-
<span #placeholderLabel role="label"
37+
<span #placeholderLabel
3838
[class]="labelClass"
3939
[id]="labelId"
4040
(click)="_onLabelClick($event)">

projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-component.scss

+15-1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@
212212
@extend %igx-grid__tr-container !optional;
213213
}
214214

215+
@include e(tr-container, $m: active) {
216+
@extend %igx-grid__tr-container--active !optional;
217+
}
218+
215219
@include e(th) {
216220
@extend %grid-cell-display !optional;
217221
@extend %grid-cell-header !optional;
@@ -253,6 +257,10 @@
253257
@extend %igx-grid__th--selected !optional;
254258
}
255259

260+
@include e(th, $m: active) {
261+
@extend %igx-grid__th--active !optional;
262+
}
263+
256264
@include e(th, $m: number) {
257265
@extend %grid-cell-number !optional;
258266
}
@@ -798,7 +806,7 @@
798806
@include e(hierarchical-expander) {
799807
@extend %igx-grid__hierarchical-expander--compact !optional;
800808
}
801-
809+
802810
@include e(hierarchical-expander, $m: empty) {
803811
@extend %igx-grid__hierarchical-expander--compact !optional;
804812
@extend %igx-grid__hierarchical-expander--empty !optional;
@@ -874,3 +882,9 @@
874882
@extend %igx-group-label__count-badge !optional;
875883
}
876884
}
885+
886+
@include b(igx-grid-summary) {
887+
@include m(active) {
888+
@extend %igx-grid-summary--active !optional;
889+
}
890+
}

projects/igniteui-angular/src/lib/core/styles/components/grid/_grid-theme.scss

+20-3
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@
732732
background: --var($theme, 'header-background');
733733
color: --var($theme, 'header-text-color');
734734
overflow: hidden;
735+
outline-style: none;
735736

736737
%grid-row {
737738
position: relative;
@@ -918,6 +919,7 @@
918919
color: --var($theme, 'content-text-color');
919920
overflow: hidden;
920921
z-index: 1;
922+
outline-style: none;
921923
}
922924

923925
%grid-tbody-container {
@@ -1322,8 +1324,6 @@
13221324
// border-bottom: 0;
13231325

13241326
%igx-grid__tree-grouping-indicator {
1325-
color: --var($theme, 'cell-selected-text-color');
1326-
13271327
&:hover {
13281328
color: --var($theme, 'cell-selected-text-color');
13291329
}
@@ -1543,6 +1543,19 @@
15431543
background: --var($theme, 'header-selected-background');
15441544
}
15451545

1546+
%igx-grid__th--active {
1547+
@extend %grid-cell--active;
1548+
1549+
%igx-grid__th--selected,
1550+
%igx-grid__th--selectable {
1551+
@extend %grid-cell--active
1552+
}
1553+
}
1554+
1555+
%igx-grid-summary--active {
1556+
@extend %grid-cell--active
1557+
}
1558+
15461559
%igx-grid__th--sortable {
15471560
.sort-icon {
15481561
cursor: pointer;
@@ -1842,6 +1855,7 @@
18421855

18431856
%igx-grid__group-row--active {
18441857
background: --var($theme, 'group-row-selected-background');
1858+
@extend %grid-cell--active;
18451859

18461860
%igx-grid__grouping-indicator {
18471861
color: --var($theme, 'expand-icon-color');
@@ -2092,7 +2106,6 @@
20922106
user-select: none;
20932107
justify-content: center;
20942108
align-items: center;
2095-
background: inherit;
20962109
z-index: 1;
20972110
cursor: pointer;
20982111
padding-#{$left}: map-get($grid-grouping-indicator-padding, 'comfortable');
@@ -2484,6 +2497,10 @@
24842497
border-bottom: 1px solid --var($theme, 'row-border-color');
24852498
}
24862499

2500+
%igx-grid__tr-container--active {
2501+
@extend %grid-cell--active;
2502+
}
2503+
24872504
%igx-grid__hierarchical-expander {
24882505
user-select: none;
24892506
background: inherit;

projects/igniteui-angular/src/lib/core/utils.ts

+1
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ export const NAVIGATION_KEYS = new Set([
335335
export const ROW_EXPAND_KEYS = new Set('right down arrowright arrowdown'.split(' '));
336336
export const ROW_COLLAPSE_KEYS = new Set('left up arrowleft arrowup'.split(' '));
337337
export const SUPPORTED_KEYS = new Set([...Array.from(NAVIGATION_KEYS), 'enter', 'f2', 'escape', 'esc', 'pagedown', 'pageup']);
338+
export const HEADER_KEYS = new Set([...Array.from(NAVIGATION_KEYS), 'escape', 'esc' , 'l']);
338339

339340
/**
340341
* @hidden

projects/igniteui-angular/src/lib/grids/columns/column.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ export class IgxColumnComponent implements AfterContentInit {
966966
let vIndex = -1;
967967

968968
if (this.columnGroup) {
969-
col = this.allChildren.filter(c => !c.columnGroup)[0] as any;
969+
col = this.allChildren.filter(c => !c.columnGroup && !c.hidden)[0] as any;
970970
}
971971
if (this.columnLayoutChild) {
972972
return this.parent.childrenVisibleIndexes.find(x => x.column === this).index;

projects/igniteui-angular/src/lib/grids/filtering/base/grid-filtering-cell.component.html

+8-10
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
<ng-template #emptyFilter>
2-
<igx-chips-area [attr.draggable]="false" class="igx-filtering-chips">
3-
<igx-chip #ghostChip [attr.draggable]="false" (click)="onChipClicked()" (keydown.enter)="onChipKeyDown($event)" [displayDensity]="'cosy'">
4-
<igx-icon [attr.draggable]="false" igxPrefix>filter_list</igx-icon>
5-
<span [attr.draggable]="false">{{filteringService.grid.resourceStrings.igx_grid_filter}}</span>
6-
</igx-chip>
7-
</igx-chips-area>
2+
<igx-chips-area [attr.draggable]="false" class="igx-filtering-chips">
3+
<igx-chip #ghostChip [attr.draggable]="false" (click)="onChipClicked()" [displayDensity]="'cosy'">
4+
<igx-icon [attr.draggable]="false" igxPrefix>filter_list</igx-icon>
5+
<span [attr.draggable]="false">{{filteringService.grid.resourceStrings.igx_grid_filter}}</span>
6+
</igx-chip>
7+
</igx-chips-area>
88
</ng-template>
99

1010
<ng-template #defaultFilter>
1111
<igx-chips-area #chipsArea class="igx-filtering-chips">
1212
<ng-container *ngFor="let item of expressionsList; let last = last; let index = index;" >
13-
<igx-chip
14-
*ngIf="isChipVisible(index)"
13+
<igx-chip *ngIf="isChipVisible(index)"
1514
[removable]="true"
1615
[displayDensity]="'cosy'"
1716
(click)="onChipClicked(item.expression)"
18-
(keydown.enter)="onChipKeyDown($event, item.expression)"
1917
(onRemove)="onChipRemoved($event, item)">
2018
<igx-icon igxPrefix
2119
fontSet="filtering-icons"
@@ -27,7 +25,7 @@
2725
</igx-chip>
2826
<span class="igx-filtering-chips__connector" *ngIf="!last && isChipVisible(index + 1)">{{filteringService.getOperatorAsString(item.afterOperator)}}</span>
2927
</ng-container>
30-
<div #moreIcon [ngClass]="filteringIndicatorClass()" (click)="onChipClicked()" (keydown.enter)="onChipKeyDown($event)" tabindex="0">
28+
<div #moreIcon [ngClass]="filteringIndicatorClass()" (click)="onChipClicked()">
3129
<igx-icon>filter_list</igx-icon>
3230
<igx-badge [value]="moreFiltersCount"></igx-badge>
3331
</div>

projects/igniteui-angular/src/lib/grids/filtering/base/grid-filtering-cell.component.ts

+2-62
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import { IgxFilteringService, ExpressionUI } from '../grid-filtering.service';
2828
export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoCheck {
2929

3030
private baseClass = 'igx-grid__filtering-cell-indicator';
31-
private currentTemplate = null;
3231

3332
public expressionsList: ExpressionUI[];
3433
public moreFiltersCount = 0;
@@ -101,27 +100,18 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC
101100

102101
get template(): TemplateRef<any> {
103102
if (!this.column.filterable) {
104-
this.currentTemplate = null;
105103
return null;
106104
}
107-
108105
if (this.column.filterCellTemplate) {
109-
this.currentTemplate = this.column.filterCellTemplate;
110106
return this.column.filterCellTemplate;
111107
}
112-
113108
const expressionTree = this.column.filteringExpressionsTree;
114109
if (!expressionTree || expressionTree.filteringOperands.length === 0) {
115-
this.currentTemplate = this.emptyFilter;
116110
return this.emptyFilter;
117111
}
118-
119112
if (this.filteringService.isFilterComplex(this.column.field)) {
120-
this.currentTemplate = this.complexFilter;
121113
return this.complexFilter;
122114
}
123-
124-
this.currentTemplate = this.defaultFilter;
125115
return this.defaultFilter;
126116
}
127117

@@ -130,9 +120,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC
130120
* @memberof IgxGridFilteringCellComponent
131121
*/
132122
get context() {
133-
return {
134-
column: this.column
135-
};
123+
return { column: this.column };
136124
}
137125

138126
/**
@@ -161,7 +149,7 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC
161149
public onChipRemoved(eventArgs: IBaseChipEventArgs, item: ExpressionUI): void {
162150
const indexToRemove = this.expressionsList.indexOf(item);
163151
this.removeExpression(indexToRemove);
164-
this.focusChip();
152+
this.filteringService.grid.theadRow.nativeElement.focus();
165153
}
166154

167155
/**
@@ -172,14 +160,6 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC
172160
this.cdr.detectChanges();
173161
}
174162

175-
/**
176-
* Chip keydown event handler.
177-
*/
178-
public onChipKeyDown(eventArgs: KeyboardEvent, expression?: IFilteringExpression) {
179-
eventArgs.preventDefault();
180-
this.onChipClicked(expression);
181-
}
182-
183163
/**
184164
* Returns the filtering indicator class.
185165
*/
@@ -190,23 +170,6 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC
190170
};
191171
}
192172

193-
/**
194-
* Focus a chip depending on the current visible template.
195-
*/
196-
public focusChip(focusFirst: boolean = false) {
197-
if (this.currentTemplate === this.defaultFilter) {
198-
if (focusFirst) {
199-
this.focusFirstElement();
200-
} else {
201-
this.focusElement();
202-
}
203-
} else if (this.currentTemplate === this.emptyFilter) {
204-
this.ghostChip.elementRef.nativeElement.querySelector(`.igx-chip__item`).focus();
205-
} else if (this.currentTemplate === this.complexFilter) {
206-
this.complexChip.elementRef.nativeElement.querySelector(`.igx-chip__item`).focus();
207-
}
208-
}
209-
210173
private removeExpression(indexToRemove: number) {
211174
if (indexToRemove === 0 && this.expressionsList.length === 1) {
212175
this.clearFiltering();
@@ -266,27 +229,4 @@ export class IgxGridFilteringCellComponent implements AfterViewInit, OnInit, DoC
266229
this.cdr.detectChanges();
267230
}
268231
}
269-
private focusFirstElement(): void {
270-
if (this.chipsArea.chipsList.length > 0) {
271-
this.chipsArea.chipsList.first.elementRef.nativeElement.querySelector(`.igx-chip__item`).focus();
272-
} else {
273-
this.moreIcon.nativeElement.focus();
274-
}
275-
}
276-
277-
private focusElement(): void {
278-
if (this.filteringService.shouldFocusNext) {
279-
if (!this.isMoreIconHidden() && this.chipsArea.chipsList.length === 0) {
280-
this.moreIcon.nativeElement.focus();
281-
} else {
282-
this.chipsArea.chipsList.first.elementRef.nativeElement.querySelector(`.igx-chip__item`).focus();
283-
}
284-
} else {
285-
if (!this.isMoreIconHidden()) {
286-
this.moreIcon.nativeElement.focus();
287-
} else {
288-
this.chipsArea.chipsList.last.elementRef.nativeElement.querySelector(`.igx-chip__remove`).focus();
289-
}
290-
}
291-
}
292232
}

projects/igniteui-angular/src/lib/grids/filtering/base/grid-filtering-row.component.html

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<!-- Have to apply styles inline because of the overlay outlet ... -->
22
<igx-drop-down #inputGroupConditions [height]="'200px'" (onSelection)="onConditionsChanged($event)">
3-
<igx-drop-down-item
4-
*ngFor="let condition of conditions"
3+
<igx-drop-down-item *ngFor="let condition of conditions"
54
[value]="condition"
65
[selected]="isConditionSelected(condition)">
76
<igx-icon fontSet="filtering-icons" [name]="getCondition(condition).iconName"></igx-icon>

0 commit comments

Comments
 (0)