Skip to content

Commit 7786e99

Browse files
committed
refactor(material/tree): docs updates and rename variables
Make miscelaneous fixes to documentation. Rename variables. Responding to PR feedback. * remove comment about API contract of CdkTreeNodeToggle * rename CdkTree#_groups to CdkTree#_ariaSets * move documentation about default key manager configuration from TreeKeyManagerStrategy interface to TreeKeyManager class. * add JSDoc style comments for NoopTreeKeyManager
1 parent 4bc94e0 commit 7786e99

File tree

6 files changed

+69
-43
lines changed

6 files changed

+69
-43
lines changed

src/cdk/a11y/key-manager/noop-tree-key-manager.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ import {
2222
/**
2323
* @docs-private
2424
*
25+
* Opt-out of Tree of key manager behavior.
26+
*
27+
* When provided, Tree has same focus management behavior as before TreeKeyManager was introduced.
28+
* - Tree does not respond to keyboard interaction
29+
* - Tree node allows tabindex to be set by Input binding
30+
* - Tree node allows tabindex to be set by attribute binding
31+
*
2532
* @deprecated NoopTreeKeyManager deprecated. Use TreeKeyManager or inject a
2633
* TreeKeyManagerStrategy instead. To be removed in a future version.
2734
*
@@ -62,6 +69,13 @@ export class NoopTreeKeyManager<T extends TreeKeyManagerItem> implements TreeKey
6269
/**
6370
* @docs-private
6471
*
72+
* Opt-out of Tree of key manager behavior.
73+
*
74+
* When provided, Tree has same focus management behavior as before TreeKeyManager was introduced.
75+
* - Tree does not respond to keyboard interaction
76+
* - Tree node allows tabindex to be set by Input binding
77+
* - Tree node allows tabindex to be set by attribute binding
78+
*
6579
* @deprecated NoopTreeKeyManager deprecated. Use TreeKeyManager or inject a
6680
* TreeKeyManagerStrategy instead. To be removed in a future version.
6781
*
@@ -76,6 +90,13 @@ export function NOOP_TREE_KEY_MANAGER_FACTORY<
7690
/**
7791
* @docs-private
7892
*
93+
* Opt-out of Tree of key manager behavior.
94+
*
95+
* When provided, Tree has same focus management behavior as before TreeKeyManager was introduced.
96+
* - Tree does not respond to keyboard interaction
97+
* - Tree node allows tabindex to be set by Input binding
98+
* - Tree node allows tabindex to be set by attribute binding
99+
*
79100
* @deprecated NoopTreeKeyManager deprecated. Use TreeKeyManager or inject a
80101
* TreeKeyManagerStrategy instead. To be removed in a future version.
81102
*

src/cdk/a11y/key-manager/tree-key-manager-strategy.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,20 @@ export interface TreeKeyManagerItem {
5252
export interface TreeKeyManagerOptions<T extends TreeKeyManagerItem> {
5353
/**
5454
* If true, then the key manager will call `activate` in addition to calling `focus` when a
55-
* particular item is focused. By default, this is false.
55+
* particular item is focused.
5656
*/
57-
activationFollowsFocus?: boolean;
57+
shouldActivationFollowFocus?: boolean;
5858

5959
/**
6060
* The direction in which the tree items are laid out horizontally. This influences which key
61-
* will be interpreted as expand or collapse. Defaults to 'ltr'.
61+
* will be interpreted as expand or collapse.
6262
*/
6363
horizontalOrientation?: 'rtl' | 'ltr';
6464

6565
/**
66-
* Sets the predicate function that determines which items should be skipped by the tree key
67-
* manager. By default, disabled items are skipped.
66+
* If provided, navigation "skips" over items that pass the given predicate.
6867
*
69-
* If the item is to be skipped, this function should return false.
68+
* If the item is to be skipped, predicate function should return false.
7069
*/
7170
skipPredicate?: (item: T) => boolean;
7271

src/cdk/a11y/key-manager/tree-key-manager.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ function coerceObservable<T>(data: T | Observable<T>): Observable<T> {
4343
export class TreeKeyManager<T extends TreeKeyManagerItem> implements TreeKeyManagerStrategy<T> {
4444
private _activeItemIndex = -1;
4545
private _activeItem: T | null = null;
46-
private _activationFollowsFocus = false;
47-
private _horizontal: 'ltr' | 'rtl' = 'ltr';
46+
private _shouldActivationFollowFocus = false;
47+
private _horizontalOrientation: 'ltr' | 'rtl' = 'ltr';
4848

4949
// Keep tree items focusable when disabled. Align with
5050
// https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols.
@@ -85,6 +85,14 @@ export class TreeKeyManager<T extends TreeKeyManagerItem> implements TreeKeyMana
8585
this._hasInitialFocused = true;
8686
}
8787

88+
/**
89+
*
90+
* @param items List of TreeKeyManager options. Can be synchronous or asynchronous.
91+
* @param config Optional configuration options. By default, use 'ltr' horizontal orientation. By
92+
* default, do not skip any nodes. By default, key manager only calls `focus` method when items
93+
* are focused and does not call `activate`. If `typeaheadDefaultInterval` is `true`, use a
94+
* default interval of 200ms.
95+
*/
8896
constructor(items: Observable<T[]> | QueryList<T> | T[], config: TreeKeyManagerOptions<T>) {
8997
// We allow for the items to be an array or Observable because, in some cases, the consumer may
9098
// not have access to a QueryList of the items they want to manage (e.g. when the
@@ -109,11 +117,11 @@ export class TreeKeyManager<T extends TreeKeyManagerItem> implements TreeKeyMana
109117
this._initialFocus();
110118
}
111119

112-
if (typeof config.activationFollowsFocus === 'boolean') {
113-
this._activationFollowsFocus = config.activationFollowsFocus;
120+
if (typeof config.shouldActivationFollowFocus === 'boolean') {
121+
this._shouldActivationFollowFocus = config.shouldActivationFollowFocus;
114122
}
115123
if (config.horizontalOrientation) {
116-
this._horizontal = config.horizontalOrientation;
124+
this._horizontalOrientation = config.horizontalOrientation;
117125
}
118126
if (config.skipPredicate) {
119127
this._skipPredicateFn = config.skipPredicate;
@@ -157,11 +165,15 @@ export class TreeKeyManager<T extends TreeKeyManagerItem> implements TreeKeyMana
157165
break;
158166

159167
case RIGHT_ARROW:
160-
this._horizontal === 'rtl' ? this._collapseCurrentItem() : this._expandCurrentItem();
168+
this._horizontalOrientation === 'rtl'
169+
? this._collapseCurrentItem()
170+
: this._expandCurrentItem();
161171
break;
162172

163173
case LEFT_ARROW:
164-
this._horizontal === 'rtl' ? this._expandCurrentItem() : this._collapseCurrentItem();
174+
this._horizontalOrientation === 'rtl'
175+
? this._expandCurrentItem()
176+
: this._collapseCurrentItem();
165177
break;
166178

167179
case HOME:
@@ -264,11 +276,10 @@ export class TreeKeyManager<T extends TreeKeyManagerItem> implements TreeKeyMana
264276
previousActiveItem?.unfocus();
265277

266278
if (options.emitChangeEvent) {
267-
// Emit to `change` stream as required by TreeKeyManagerStrategy interface.
268279
this.change.next(this._activeItem);
269280
}
270281

271-
if (this._activationFollowsFocus) {
282+
if (this._shouldActivationFollowFocus) {
272283
this._activateCurrentItem();
273284
}
274285
}

src/cdk/tree/toggle.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ import {CdkTree, CdkTreeNode} from './tree';
1212

1313
/**
1414
* Node toggle to expand and collapse the node.
15-
*
16-
* CdkTreeNodeToggle is intended only to be used on native button elements, elements with button role,
17-
* or elements with treeitem role.
1815
*/
1916
@Directive({
2017
selector: '[cdkTreeNodeToggle]',

src/cdk/tree/tree.ts

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,14 @@ export class CdkTree<T, K = T>
132132
private _parents: Map<K, T | null> = new Map<K, T | null>();
133133

134134
/**
135-
* The internal node groupings for each node; we use this to determine where
136-
* a particular node is within each group. This allows us to compute the
137-
* correct aria attribute values.
135+
* Nodes grouped into each set, which is a list of nodes displayed together in the DOM.
138136
*
139-
* The structure of this is that:
140-
* - the outer index is the level
141-
* - the inner index is the parent node for this particular group. If there is no parent node, we
142-
* use `null`.
137+
* Lookup key is the parent of a set. Root nodes have key of null.
138+
*
139+
* Values is a 'set' of tree nodes. Each tree node maps to a treeitem element. Sets are in the
140+
* order that it is rendered. Each set maps directly to aria-posinset and aria-setsize attributes.
143141
*/
144-
private _groups: Map<K | null, T[]> = new Map<K | null, T[]>();
142+
private _ariaSets: Map<K | null, T[]> = new Map<K | null, T[]>();
145143

146144
/**
147145
* Provides a stream containing the latest data array to render. Influenced by the tree's
@@ -500,10 +498,10 @@ export class CdkTree<T, K = T>
500498
this.insertNode(data[currentIndex!], currentIndex!, viewContainer, parentData);
501499
} else if (currentIndex == null) {
502500
viewContainer.remove(adjustedPreviousIndex!);
503-
const group = this._getNodeGroup(item.item);
501+
const set = this._getAriaSet(item.item);
504502
const key = this._getExpansionKey(item.item);
505-
group.splice(
506-
group.findIndex(groupItem => this._getExpansionKey(groupItem) === key),
503+
set.splice(
504+
set.findIndex(groupItem => this._getExpansionKey(groupItem) === key),
507505
1,
508506
);
509507
} else {
@@ -784,8 +782,8 @@ export class CdkTree<T, K = T>
784782
* This is intended to be used for `aria-setsize`.
785783
*/
786784
_getSetSize(dataNode: T) {
787-
const group = this._getNodeGroup(dataNode);
788-
return group.length;
785+
const set = this._getAriaSet(dataNode);
786+
return set.length;
789787
}
790788

791789
/**
@@ -794,9 +792,9 @@ export class CdkTree<T, K = T>
794792
* This is intended to be used for `aria-posinset`.
795793
*/
796794
_getPositionInSet(dataNode: T) {
797-
const group = this._getNodeGroup(dataNode);
795+
const set = this._getAriaSet(dataNode);
798796
const key = this._getExpansionKey(dataNode);
799-
return group.findIndex(node => this._getExpansionKey(node) === key) + 1;
797+
return set.findIndex(node => this._getExpansionKey(node) === key) + 1;
800798
}
801799

802800
/** Given a CdkTreeNode, gets the node that renders that node's parent's data. */
@@ -902,12 +900,12 @@ export class CdkTree<T, K = T>
902900
return this.expansionKey?.(dataNode) ?? (dataNode as unknown as K);
903901
}
904902

905-
private _getNodeGroup(node: T) {
903+
private _getAriaSet(node: T) {
906904
const key = this._getExpansionKey(node);
907905
const parent = this._parents.get(key);
908906
const parentKey = parent ? this._getExpansionKey(parent) : null;
909-
const group = this._groups.get(parentKey);
910-
return group ?? [node];
907+
const set = this._ariaSets.get(parentKey);
908+
return set ?? [node];
911909
}
912910

913911
/**
@@ -963,7 +961,7 @@ export class CdkTree<T, K = T>
963961
children.pipe(
964962
take(1),
965963
tap(childNodes => {
966-
this._groups.set(parentKey, [...(childNodes ?? [])]);
964+
this._ariaSets.set(parentKey, [...(childNodes ?? [])]);
967965
for (const child of childNodes ?? []) {
968966
const childKey = this._getExpansionKey(child);
969967
this._parents.set(childKey, node);
@@ -1006,7 +1004,7 @@ export class CdkTree<T, K = T>
10061004
// nested.
10071005
if (this.childrenAccessor && nodeType === 'flat') {
10081006
// This flattens children into a single array.
1009-
this._groups.set(null, [...nodes]);
1007+
this._ariaSets.set(null, [...nodes]);
10101008
return this._flattenNestedNodesWithExpansion(nodes).pipe(
10111009
map(flattenedNodes => ({
10121010
renderNodes: flattenedNodes,
@@ -1039,7 +1037,7 @@ export class CdkTree<T, K = T>
10391037
} else {
10401038
// For nested nodes, we still need to perform the node flattening in order
10411039
// to maintain our caches for various tree operations.
1042-
this._groups.set(null, [...nodes]);
1040+
this._ariaSets.set(null, [...nodes]);
10431041
return this._flattenNestedNodesWithExpansion(nodes).pipe(
10441042
map(flattenedNodes => ({
10451043
renderNodes: nodes,
@@ -1065,7 +1063,7 @@ export class CdkTree<T, K = T>
10651063
}
10661064

10671065
this._parents.clear();
1068-
this._groups.clear();
1066+
this._ariaSets.clear();
10691067

10701068
for (let index = 0; index < flattenedNodes.length; index++) {
10711069
const dataNode = flattenedNodes[index];
@@ -1075,9 +1073,9 @@ export class CdkTree<T, K = T>
10751073
this._parents.set(key, parent);
10761074
const parentKey = parent ? this._getExpansionKey(parent) : null;
10771075

1078-
const group = this._groups.get(parentKey) ?? [];
1076+
const group = this._ariaSets.get(parentKey) ?? [];
10791077
group.splice(index, 0, dataNode);
1080-
this._groups.set(parentKey, group);
1078+
this._ariaSets.set(parentKey, group);
10811079
}
10821080
}
10831081
}

tools/public_api_guard/cdk/a11y.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,8 @@ export interface TreeKeyManagerItem {
505505

506506
// @public
507507
export interface TreeKeyManagerOptions<T extends TreeKeyManagerItem> {
508-
activationFollowsFocus?: boolean;
509508
horizontalOrientation?: 'rtl' | 'ltr';
509+
shouldActivationFollowFocus?: boolean;
510510
skipPredicate?: (item: T) => boolean;
511511
trackBy?: (treeItem: T) => unknown;
512512
typeAheadDebounceInterval?: true | number;

0 commit comments

Comments
 (0)