Skip to content

Commit f711713

Browse files
authored
Merge branch 'master' into dpetev/date-time-editor-misc
2 parents c30a0d2 + c797ee3 commit f711713

33 files changed

+441
-169
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 3 additions & 3 deletions
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

Lines changed: 12 additions & 0 deletions
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/combo/combo.component.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,19 +1216,21 @@ describe('igxCombo', () => {
12161216
fixture.detectChanges();
12171217
let items = fixture.debugElement.queryAll(By.css(`.${CSS_CLASS_DROPDOWNLISTITEM}`));
12181218
let lastItem = items[items.length - 1].componentInstance;
1219+
let lastItemIndex = lastItem.index;
12191220
expect(lastItem).toBeDefined();
12201221
lastItem.clicked(mockClick);
12211222
await wait(30);
12221223
fixture.detectChanges();
1223-
expect(dropdown.focusedItem).toEqual(lastItem);
1224+
expect(dropdown.focusedItem.index).toEqual(lastItemIndex);
12241225
dropdown.navigateItem(-1);
12251226
await wait(30);
12261227
fixture.detectChanges();
12271228
expect(virtualMockDOWN).toHaveBeenCalledTimes(0);
1229+
lastItemIndex = lastItem.index;
12281230
lastItem.clicked(mockClick);
12291231
await wait(30);
12301232
fixture.detectChanges();
1231-
expect(dropdown.focusedItem).toEqual(lastItem);
1233+
expect(dropdown.focusedItem.index).toEqual(lastItemIndex);
12321234
dropdown.navigateNext();
12331235
await wait(30);
12341236
fixture.detectChanges();

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

Lines changed: 15 additions & 1 deletion
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

Lines changed: 20 additions & 3 deletions
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/directives/for-of/for_of.directive.ts

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -853,63 +853,17 @@ export class IgxForOfDirective<T> implements OnInit, OnChanges, DoCheck, OnDestr
853853
if (newStart + this.state.chunkSize > count) {
854854
newStart = count - this.state.chunkSize;
855855
}
856-
const prevStart = this.state.startIndex;
857856
const diff = newStart - this.state.startIndex;
858857
this.state.startIndex = newStart;
859858
if (diff) {
860859
this.onChunkPreload.emit(this.state);
861860
if (!this.isRemote) {
862-
/*recalculate and apply page size.*/
863-
if (diff > 0 && diff <= this.MAX_PERF_SCROLL_DIFF) {
864-
this.moveApplyScrollNext(prevStart);
865-
} else if (diff < 0 && Math.abs(diff) <= this.MAX_PERF_SCROLL_DIFF) {
866-
this.moveApplyScrollPrev(prevStart);
867-
} else {
868-
this.fixedApplyScroll();
869-
}
861+
this.fixedApplyScroll();
870862
}
871863
}
872864
return inScrollTop - this.sizesCache[this.state.startIndex];
873865
}
874866

875-
/**
876-
* @hidden
877-
* The function applies an optimized state change for scrolling down/right employing context change with view rearrangement
878-
*/
879-
protected moveApplyScrollNext(prevIndex: number): void {
880-
const start = prevIndex + this.state.chunkSize;
881-
for (let i = start; i < start + this.state.startIndex - prevIndex && this.igxForOf[i] !== undefined; i++) {
882-
this._moveApply(i);
883-
}
884-
}
885-
886-
/**
887-
*
888-
*/
889-
protected _moveApply(contextIndex: number, topPosition = false) {
890-
const context = this.igxForOf[contextIndex];
891-
const forOfContext = new IgxForOfContext<T>(context, this.getContextIndex(context), this.igxForOf.length);
892-
const view = this.dc.instance._vcr.createEmbeddedView(this._template, forOfContext, topPosition ? 0 : undefined);
893-
this.dc.instance._vcr.detach(topPosition ? this.dc.instance._vcr.length - 1 : 0);
894-
if (topPosition) {
895-
this._embeddedViews.pop();
896-
this._embeddedViews.unshift(view);
897-
} else {
898-
this._embeddedViews.shift();
899-
this._embeddedViews.push(view);
900-
}
901-
}
902-
903-
/**
904-
* @hidden
905-
* The function applies an optimized state change for scrolling up/left employing context change with view rearrangement
906-
*/
907-
protected moveApplyScrollPrev(prevIndex: number): void {
908-
for (let i = prevIndex - 1; i >= this.state.startIndex && this.igxForOf[i] !== undefined; i--) {
909-
this._moveApply(i, true);
910-
}
911-
}
912-
913867
/**
914868
* @hidden
915869
*/

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@
1111
<ng-template #inlineEditor let-cell="cell">
1212
<ng-container *ngIf="column.dataType === 'string'">
1313
<igx-input-group displayDensity="compact">
14-
<input igxInput [value]="editValue" (input)="editValue = $event.target.value" [igxFocus]="true" />
14+
<input igxInput [value]="editValue" (input)="editValue = $event.target.value" [igxFocus]="focused" />
1515
</igx-input-group>
1616
</ng-container>
1717
<ng-container *ngIf="column.dataType === 'number'">
1818
<igx-input-group displayDensity="compact">
19-
<input igxInput [value]="editValue" (input)="editValue = $event.target.value" [igxFocus]="true" type="number">
19+
<input igxInput [value]="editValue" (input)="editValue = $event.target.value" [igxFocus]="focused" type="number">
2020
</igx-input-group>
2121
</ng-container>
2222
<ng-container *ngIf="column.dataType === 'boolean'">
2323
<igx-checkbox (change)="editValue = $event.checked" [value]="editValue" [checked]="editValue"
24-
[igxFocus]="true" [disableRipple]="true"></igx-checkbox>
24+
[igxFocus]="focused" [disableRipple]="true"></igx-checkbox>
2525
</ng-container>
2626
<ng-container *ngIf="column.dataType === 'date'">
2727
<igx-date-picker [style.width.%]="100" [outlet]="grid.outletDirective" mode="dropdown"
28-
[locale]="grid.locale" [(value)]="editValue" [igxFocus]="true" [labelVisibility]="false">
28+
[locale]="grid.locale" [(value)]="editValue" [igxFocus]="focused" [labelVisibility]="false">
2929
</igx-date-picker>
3030
</ng-container>
3131
</ng-template>

projects/igniteui-angular/src/lib/grids/common/pipes.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,17 +227,17 @@ export class IgxGridRowPinningPipe implements PipeTransform {
227227
public transform(collection: any[] , id: string, isPinned = false, pipeTrigger: number) {
228228
const grid = this.gridAPI.grid;
229229

230-
if (!grid.hasPinnedRecords) {
231-
return isPinned ? [] : collection;
232-
}
233-
234230
if (grid.hasPinnedRecords && isPinned) {
235231
const result = collection.filter(rec => grid.isRecordPinned(rec));
236232
result.sort((rec1, rec2) => grid.pinRecordIndex(rec1) - grid.pinRecordIndex(rec2));
237233
return result;
238234
}
239235

240236
grid.unpinnedRecords = collection;
237+
if (!grid.hasPinnedRecords) {
238+
grid.pinnedRecords = [];
239+
return isPinned ? [] : collection;
240+
}
241241

242242
return collection.map((rec) => {
243243
return grid.isRecordPinned(rec) ? { recordRef: rec, ghostRecord: true} : rec;

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { IForOfState } from '../../directives/for-of/for_of.directive';
1010
import { IgxColumnComponent } from '../columns/column.component';
1111
import { IFilteringOperation } from '../../data-operations/filtering-condition';
1212
import { GridBaseAPIService } from '../api.service';
13-
import { IColumnVisibilityChangedEventArgs } from '../grid';
1413
import { IColumnResizeEventArgs } from '../common/events';
1514
import { GridType } from '../common/grid.interface';
1615
import { IgxDatePipeComponent } from '../common/pipes';
@@ -20,7 +19,6 @@ import { useAnimation } from '@angular/animations';
2019
import { fadeIn, fadeOut } from '../../animations/main';
2120
import { ExcelStylePositionStrategy } from './excel-style/excel-style-position-strategy';
2221
import { AbsoluteScrollStrategy } from '../../services/overlay/scroll/absolute-scroll-strategy';
23-
import { IgxGridExcelStyleFilteringComponent } from './excel-style/grid.excel-style-filtering.component';
2422

2523
const FILTERING_ICONS_FONT_SET = 'filtering-icons';
2624

@@ -69,7 +67,7 @@ export class IgxFilteringService implements OnDestroy {
6967
this.destroy$.complete();
7068
}
7169

72-
public toggleFilterDropdown(element, column) {
70+
public toggleFilterDropdown(element, column, classRef) {
7371
if (!this._componentOverlayId || (this.column && this.column.field !== column.field)) {
7472
this.column = column;
7573
const filterIcon = this.column.filteringExpressionsTree ? 'igx-excel-filter__icon--filtered' : 'igx-excel-filter__icon';
@@ -78,7 +76,7 @@ export class IgxFilteringService implements OnDestroy {
7876
this._filterMenuOverlaySettings.positionStrategy.settings.target = filterIconTarget;
7977
this._filterMenuOverlaySettings.outlet = (this.grid as any).outlet;
8078
this._componentOverlayId =
81-
this._overlayService.attach(IgxGridExcelStyleFilteringComponent, this._filterMenuOverlaySettings, this._moduleRef);
79+
this._overlayService.attach(classRef, this._filterMenuOverlaySettings, this._moduleRef);
8280
this._overlayService.show(this._componentOverlayId, this._filterMenuOverlaySettings);
8381
}
8482
}
@@ -98,7 +96,7 @@ export class IgxFilteringService implements OnDestroy {
9896
this._overlayService.onOpening.pipe(
9997
filter((overlay) => overlay.id === this._componentOverlayId),
10098
takeUntil(this.destroy$)).subscribe((eventArgs) => {
101-
const instance = eventArgs.componentRef.instance as IgxGridExcelStyleFilteringComponent;
99+
const instance = eventArgs.componentRef.instance as any;
102100
if (instance) {
103101
instance.initialize(this.column, this._overlayService, eventArgs.id);
104102
}
@@ -107,7 +105,6 @@ export class IgxFilteringService implements OnDestroy {
107105
this._overlayService.onClosed.pipe(
108106
filter(overlay => overlay.id === this._componentOverlayId),
109107
takeUntil(this.destroy$)).subscribe(() => {
110-
console.log('Close');
111108
this._componentOverlayId = null;
112109
this.grid.theadRow.nativeElement.focus();
113110
});

0 commit comments

Comments
 (0)