Skip to content

Commit 9c10ee7

Browse files
committed
cleanup
1 parent e85fc61 commit 9c10ee7

File tree

3 files changed

+52
-20
lines changed

3 files changed

+52
-20
lines changed

src/cdk-experimental/popover-edit/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export const CELL_SELECTOR = '.cdk-popover-edit-cell, .mat-popover-edit-cell';
1212
/** Selector for finding table rows. */
1313
export const ROW_SELECTOR = '.cdk-row, .mat-row, tr';
1414

15-
export const TABLE_SELECOR = 'table, cdk-table, mat-table';
15+
/** Selector for finding the table element. */
16+
export const TABLE_SELECTOR = 'table, cdk-table, mat-table';
1617

1718
/** CSS class added to the edit lens pane. */
1819
export const EDIT_PANE_CLASS = 'cdk-edit-pane';

src/cdk-experimental/popover-edit/focus-dispatcher.ts

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,63 @@ import {PartialObserver} from 'rxjs';
1313
import {CELL_SELECTOR, ROW_SELECTOR, TABLE_SELECTOR} from './constants';
1414
import {closest} from './polyfill';
1515

16-
/** Service responsible for moving cell focus around in response to keyboard events. */
17-
@Injectable()
16+
/**
17+
* Service responsible for moving cell focus around in response to keyboard events.
18+
* May be overridden to customize the keyboard behavior of popover edit.
19+
*/
20+
@Injectable({providedIn: 'root'})
1821
export class FocusDispatcher {
22+
/** Observes keydown events triggered from the table. */
1923
readonly keyObserver: PartialObserver<KeyboardEvent>;
2024

21-
constructor(private readonly _directionality: Directionality) {
22-
this.keyObserver = {next: (evt) => this.handleKey(evt)};
25+
constructor(protected readonly directionality: Directionality) {
26+
this.keyObserver = {next: (evt) => this.handleKeyboardEvent(evt)};
2327
}
2428

25-
moveFocusHorizontally(currentCell, offset: number) {
26-
const allCells =
27-
Array.from(closest(currentCell, TABLE_SELECTOR).querySelectorAll(CELL_SELECTOR));
28-
const currentIndex = allCells.indexOf(currentCell);
29+
/**
30+
* Moves focus to earlier or later cells (in dom order) by offset cells relative to
31+
* currentCell.
32+
*/
33+
moveFocusHorizontally(currentCell: HTMLElement, offset: number): void {
34+
const cells =
35+
Array.from(closest(currentCell, TABLE_SELECTOR)!.querySelectorAll(CELL_SELECTOR)) as
36+
HTMLElement[];
37+
const currentIndex = cells.indexOf(currentCell);
2938
const newIndex = currentIndex + offset;
3039

3140
if (cells[newIndex]) {
3241
cells[newIndex].focus();
3342
}
3443
}
3544

36-
moveFocusVertically(currentCell: HTMLElement, offset: number) {
37-
const currentRow = closest(currentCell, ROW_SELECTOR);
38-
const rows = Array.from(closest(currentRow, TABLE_SELECTOR).querySelectorAll(ROW_SELECTOR));
39-
const currentRowIndex = rows.indexOf(currentRowIndex);
40-
const currentIndexWithinRow = Array.from(currentRow.querySelectorAll(CELL_SELECTOR));
45+
/** Moves focus to up or down by row by offset cells relative to currentCell. */
46+
moveFocusVertically(currentCell: HTMLElement, offset: number): void {
47+
const currentRow = closest(currentCell, ROW_SELECTOR)!;
48+
const rows = Array.from(closest(currentRow, TABLE_SELECTOR)!.querySelectorAll(ROW_SELECTOR));
49+
const currentRowIndex = rows.indexOf(currentRow);
50+
const currentIndexWithinRow =
51+
Array.from(currentRow.querySelectorAll(CELL_SELECTOR)).indexOf(currentCell);
4152
const newRowIndex = currentRowIndex + offset;
4253

43-
if (rows[newRowIndex] && rows[newRowIndex][currentIndexWithinRow]) {
44-
rows[newRowIndex][currentIndexWithinRow].focus();
54+
if (rows[newRowIndex]) {
55+
const rowToFocus =
56+
Array.from(rows[newRowIndex].querySelectorAll(CELL_SELECTOR)) as HTMLElement[];
57+
58+
if (rowToFocus[currentIndexWithinRow]) {
59+
rowToFocus[currentIndexWithinRow].focus();
60+
}
4561
}
4662
}
4763

48-
protected handleKey(key: string, cell: HTMLElement) {
49-
switch (key) {
64+
/** Translates arrow keydown events into focus move operations. */
65+
protected handleKeyboardEvent(evt: KeyboardEvent): void {
66+
const cell = closest(evt.target, CELL_SELECTOR) as HTMLElement | null;
67+
68+
if (!cell) {
69+
return;
70+
}
71+
72+
switch (evt.key) {
5073
case 'ArrowUp':
5174
this.moveFocusVertically(cell, -1);
5275
break;
@@ -59,7 +82,10 @@ export class FocusDispatcher {
5982
case 'ArrowRight':
6083
this.moveFocusHorizontally(cell, this.directionality.value === 'ltr' ? 1 : -1);
6184
break;
62-
defualt: break;
85+
default:
86+
return;
6387
}
88+
89+
evt.preventDefault();
6490
}
6591
}

src/cdk-experimental/popover-edit/table-directives.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {debounceTime, filter, map, mapTo, takeUntil} from 'rxjs/operators';
2424

2525
import {CELL_SELECTOR, EDIT_PANE_CLASS, EDIT_PANE_SELECTOR, ROW_SELECTOR} from './constants';
2626
import {EditEventDispatcher} from './edit-event-dispatcher';
27+
import {FocusDispatcher} from './focus-dispatcher';
2728
import {closest} from './polyfill';
2829
import {PopoverEditPositionStrategyFactory} from './popover-edit-position-strategy-factory';
2930

@@ -48,7 +49,7 @@ export class CdkEditable implements AfterViewInit, OnDestroy {
4849
constructor(
4950
protected readonly elementRef: ElementRef,
5051
protected readonly editEventDispatcher: EditEventDispatcher,
51-
protected readonly ngZone: NgZone) {}
52+
protected readonly focusDispatcher: FocusDispatcher, protected readonly ngZone: NgZone) {}
5253

5354
ngAfterViewInit(): void {
5455
this._listenForTableEvents();
@@ -85,6 +86,10 @@ export class CdkEditable implements AfterViewInit, OnDestroy {
8586
filter(event => event.key === 'Enter'),
8687
toClosest(CELL_SELECTOR),
8788
).subscribe(this.editEventDispatcher.editing);
89+
90+
fromEvent<KeyboardEvent>(element, 'keydown')
91+
.pipe(takeUntil(this.destroyed))
92+
.subscribe(this.focusDispatcher.keyObserver);
8893
});
8994
}
9095
}

0 commit comments

Comments
 (0)