Skip to content

Commit c6a8892

Browse files
committed
feat(cdk/tree): update tree documentation
1 parent 98a01e0 commit c6a8892

File tree

3 files changed

+216
-82
lines changed

3 files changed

+216
-82
lines changed

src/cdk/tree/tree.md

Lines changed: 66 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,13 @@ The `<cdk-tree>` enables developers to build a customized tree experience for st
22
`<cdk-tree>` provides a foundation to build other features such as filtering on top of tree.
33
For a Material Design styled tree, see `<mat-tree>` which builds on top of the `<cdk-tree>`.
44

5-
There are two types of trees: flat tree and nested Tree. The DOM structures are different for
5+
There are two types of trees: flat and nested. The DOM structures are different for these
66
these two types of trees.
77

88
#### Flat tree
99

10-
<!-- example(cdk-tree-flat) -->
11-
12-
1310
In a flat tree, the hierarchy is flattened; nodes are not rendered inside of each other, but instead
14-
are rendered as siblings in sequence. An instance of `TreeFlattener` is used to generate the flat
15-
list of items from hierarchical data. The "level" of each tree node is read through the `getLevel`
16-
method of the `TreeControl`; this level can be used to style the node such that it is indented to
17-
the appropriate level.
11+
are rendered as siblings in sequence.
1812

1913
```html
2014
<cdk-tree>
@@ -25,16 +19,16 @@ the appropriate level.
2519

2620
```
2721

22+
<!-- example(cdk-tree-flat) -->
23+
2824
Flat trees are generally easier to style and inspect. They are also more friendly to scrolling
2925
variations, such as infinite or virtual scrolling.
3026

3127

3228
#### Nested tree
3329

34-
<!-- example(cdk-tree-nested) -->
35-
36-
In nested tree, children nodes are placed inside their parent node in DOM. The parent node contains
37-
a node outlet into which children are projected.
30+
In a nested tree, children nodes are placed inside their parent node in DOM. The parent node
31+
contains a node outlet into which children are projected.
3832

3933
```html
4034
<cdk-tree>
@@ -46,15 +40,18 @@ a node outlet into which children are projected.
4640
</cdk-tree>
4741
```
4842

43+
<!-- example(cdk-tree-nested) -->
44+
4945
Nested trees are easier to work with when hierarchical relationships are visually represented in
5046
ways that would be difficult to accomplish with flat nodes.
5147

52-
### Using the CDK tree
48+
49+
### Usage
5350

5451
#### Writing your tree template
5552

56-
The only thing you need to define is the tree node template. There are two types of tree nodes,
57-
`<cdk-tree-node>` for flat tree and `<cdk-tree-nested-node>` for nested tree. The tree node
53+
In order to use the tree, you must define a tree node template. There are two types of tree nodes,
54+
`<cdk-tree-node>` for flat tree and `<cdk-nested-tree-node>` for nested tree. The tree node
5855
template defines the look of the tree node, expansion/collapsing control and the structure for
5956
nested children nodes.
6057

@@ -69,9 +66,12 @@ data to be used in any bindings in the node template.
6966

7067
##### Flat tree node template
7168

72-
Flat tree uses each node's `level` to render the hierarchy of the nodes.
73-
The "indent" for a given node is accomplished by adding spacing to each node based on its level.
74-
Spacing can be added either by applying the `cdkNodePadding` directive or by applying custom styles.
69+
Flat trees use the `level` of a node to both render and determine hierarchy of the nodes for screen
70+
readers. This may be provided either via `levelAccessor`, or will be calculated by `CdkTree` if
71+
`childrenAccessor` is provided.
72+
73+
Spacing can be added either by applying the `cdkNodePadding` directive or by applying custom styles
74+
based on the `aria-level` attribute.
7575

7676

7777
##### Nested tree node template
@@ -84,24 +84,16 @@ where the children of the node will be rendered.
8484
{{node.value}}
8585
<ng-container cdkTreeNodeOutlet></ng-container>
8686
</cdk-nested-tree-node>
87-
8887
```
8988

9089
#### Adding expand/collapse
9190

92-
A `cdkTreeNodeToggle` can be added in the tree node template to expand/collapse the tree node.
93-
The toggle toggles the expand/collapse functions in TreeControl and is able to expand/collapse
91+
The `cdkTreeNodeToggle` directive can be used to add expand/collapse functionality for tree nodes.
92+
The toggle calls the expand/collapse functions in the `CdkTree` and is able to expand/collapse
9493
a tree node recursively by setting `[cdkTreeNodeToggleRecursive]` to true.
9594

96-
```html
97-
<cdk-tree-node *cdkNodeDef="let node" cdkTreeNodeToggle [cdkTreeNodeToggleRecursive]="true">
98-
{{node.value}}
99-
</cdk-tree-node>
100-
```
101-
102-
The toggle can be placed anywhere in the tree node, and is only toggled by click action.
103-
For best accessibility, `cdkTreeNodeToggle` should be on a button element and have an appropriate
104-
`aria-label`.
95+
`cdkTreeNodeToggle` should be attached to button elements, and will trigger upon click or keyboard
96+
activation. For icon buttons, ensure that `aria-label` is provided.
10597

10698
```html
10799
<cdk-tree-node *cdkNodeDef="let node">
@@ -114,25 +106,24 @@ For best accessibility, `cdkTreeNodeToggle` should be on a button element and ha
114106

115107
#### Padding (Flat tree only)
116108

117-
The cdkTreeNodePadding can be placed in a flat tree's node template to display the level
109+
The `cdkTreeNodePadding` directive can be placed in a flat tree's node template to display the level
118110
information of a flat tree node.
119111

120112
```html
121113
<cdk-tree-node *cdkNodeDef="let node" cdkNodePadding>
122114
{{node.value}}
123115
</cdk-tree-node>
124-
125116
```
126117

127-
Nested tree does not need this padding since padding can be easily added to the hierarchy structure
128-
in DOM.
118+
This is unnecessary for a nested tree, since the hierarchical structure of the DOM allows for
119+
padding to be added via CSS.
129120

130121

131122
#### Conditional template
123+
132124
The tree may include multiple node templates, where a template is chosen
133125
for a particular data node via the `when` predicate of the template.
134126

135-
136127
```html
137128
<cdk-tree-node *cdkNodeDef="let node" cdkTreeNodePadding>
138129
{{node.value}}
@@ -154,20 +145,30 @@ Because the data source provides this stream, it bears the responsibility of tog
154145
updates. This can be based on anything: tree node expansion change, websocket connections, user
155146
interaction, model updates, time-based intervals, etc.
156147

148+
There are two main methods of providing data to the tree:
157149

158-
#### Flat tree
150+
* flattened data, combined with `levelAccessor`. This should be used if the data source already
151+
flattens the nested data structure into a single array.
152+
* only root data, combined with `childrenAccessor`. This should be used if the data source is
153+
already provided as a nested data structure.
159154

160-
The flat tree data source is responsible for the node expansion/collapsing events, since when
161-
the expansion status changes, the data nodes feed to the tree are changed. A new list of visible
162-
nodes should be sent to tree component based on current expansion status.
155+
#### `levelAccessor`
163156

157+
`levelAccessor` is a function that when provided a datum, returns the level the data sits at in the
158+
tree structure. If `levelAccessor` is provided, the data provided by `dataSource` should contain all
159+
renderable nodes in a single array.
164160

165-
#### Nested tree
161+
The data source is responsible for handling node expand/collapse events and providing an updated
162+
array of renderable nodes, if applicable. This can be listened to via the `(expansionChange)` event
163+
on `cdk-tree-node` and `cdk-nested-tree-node`.
164+
165+
#### `childrenAccessor`
166166

167-
The data source for nested tree has an option to leave the node expansion/collapsing event for each
168-
tree node component to handle.
167+
`childrenAccessor` is a function that when provided a datum, returns the children of that particular
168+
datum. If `childrenAccessor` is provided, the data provided by `dataSource` should _only_ contain
169+
the root nodes of the tree.
169170

170-
##### `trackBy`
171+
#### `trackBy`
171172

172173
To improve performance, a `trackBy` function can be provided to the tree similar to Angular’s
173174
[`ngFor` `trackBy`](https://angular.io/api/common/NgForOf#change-propagation). This informs the
@@ -176,3 +177,25 @@ tree how to uniquely identify nodes to track how the data changes with each upda
176177
```html
177178
<cdk-tree [dataSource]="dataSource" [treeControl]="treeControl" [trackBy]="trackByFn">
178179
```
180+
181+
### Accessibility
182+
183+
The `<cdk-tree>` implements the [`tree` widget](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/),
184+
including keyboard navigation and appropriate roles and ARIA attributes.
185+
186+
#### Activation actions
187+
188+
For trees with nodes that have actions upon activation or click, `<cdk-tree-node>` will emit
189+
`(activation)` events that can be listened to when the user activates a node via keyboard
190+
interaction.
191+
192+
```html
193+
<cdk-tree-node
194+
*cdkNodeDef="let node"
195+
(click)="performAction(node)"
196+
(activation)="performAction($event)">
197+
</cdk-tree-node>
198+
```
199+
200+
In this example, `$event` contains the node's data and is equivalent to the implicit data passed in
201+
the `cdkNodeDef` context.

src/cdk/tree/tree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ export class CdkTreeNode<T, K = T> implements OnDestroy, OnInit, TreeKeyManagerI
11411141
*/
11421142
@Input() isDisabled?: boolean;
11431143

1144-
/** This emits when the node has been programatically activated. */
1144+
/** This emits when the node has been programatically activated or activated by keyboard. */
11451145
@Output()
11461146
readonly activation: EventEmitter<T> = new EventEmitter<T>();
11471147

0 commit comments

Comments
 (0)