5
5
* Use of this source code is governed by an MIT-style license that can be
6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
+ import { FocusableOption } from '@angular/cdk/a11y' ;
8
9
import { CollectionViewer , DataSource } from '@angular/cdk/collections' ;
9
10
import {
10
11
ChangeDetectionStrategy ,
11
12
ChangeDetectorRef ,
12
13
Component ,
13
14
ContentChildren ,
15
+ Directive ,
16
+ ElementRef ,
14
17
Input ,
15
18
IterableDiffers ,
16
19
IterableDiffer ,
@@ -26,15 +29,91 @@ import {BehaviorSubject} from 'rxjs/BehaviorSubject';
26
29
import { takeUntil } from 'rxjs/operators/takeUntil' ;
27
30
import { Subject } from 'rxjs/Subject' ;
28
31
import { Subscription } from 'rxjs/Subscription' ;
29
- import { CdkTreeNodeDef , CdkTreeNode , CdkTreeNodeOutletContext } from './node' ;
32
+ import { CdkTreeNodeDef , CdkTreeNodeOutletContext } from './node' ;
30
33
import { CdkTreeNodeOutlet } from './outlet' ;
31
34
import { TreeControl } from './control/tree-control' ;
32
35
import {
33
36
getTreeControlMissingError ,
34
37
getTreeMissingMatchingNodeDefError ,
35
- getTreeMultipleDefaultNodeDefsError
38
+ getTreeMultipleDefaultNodeDefsError ,
39
+ getTreeControlFunctionsMissingError
36
40
} from './tree-errors' ;
37
41
42
+ /**
43
+ * Tree node for CdkTree. It contains the data in the tree node.
44
+ */
45
+ @Directive ( {
46
+ selector : 'cdk-tree-node' ,
47
+ exportAs : 'cdkTreeNode' ,
48
+ host : {
49
+ '[attr.aria-expanded]' : 'isExpanded' ,
50
+ '[attr.aria-level]' : 'level' ,
51
+ '[attr.role]' : 'role' ,
52
+ 'class' : 'cdk-tree-node' ,
53
+ } ,
54
+ } )
55
+ export class CdkTreeNode < T > implements FocusableOption , OnDestroy {
56
+ /**
57
+ * The most recently created `CdkTreeNode`. We save it in static variable so we can retrieve it
58
+ * in `CdkTree` and set the data to it.
59
+ */
60
+ static mostRecentTreeNode : CdkTreeNode < any > | null = null ;
61
+
62
+ /** Subject that emits when the component has been destroyed. */
63
+ protected _destroyed = new Subject < void > ( ) ;
64
+
65
+ /** The tree node's data. */
66
+ get data ( ) : T { return this . _data ; }
67
+ set data ( value : T ) {
68
+ this . _data = value ;
69
+ this . _setRoleFromData ( ) ;
70
+ }
71
+ protected _data : T ;
72
+
73
+ get isExpanded ( ) : boolean {
74
+ return this . _tree . treeControl . isExpanded ( this . _data ) ;
75
+ }
76
+
77
+ get level ( ) : number {
78
+ return this . _tree . treeControl . getLevel ? this . _tree . treeControl . getLevel ( this . _data ) : 0 ;
79
+ }
80
+
81
+ /**
82
+ * The role of the node should be 'group' if it's an internal node,
83
+ * and 'treeitem' if it's a leaf node.
84
+ */
85
+ @Input ( ) role : 'treeitem' | 'group' = 'treeitem' ;
86
+
87
+ constructor ( protected _elementRef : ElementRef ,
88
+ protected _tree : CdkTree < T > ) {
89
+ CdkTreeNode . mostRecentTreeNode = this ;
90
+ }
91
+
92
+ ngOnDestroy ( ) {
93
+ this . _destroyed . next ( ) ;
94
+ this . _destroyed . complete ( ) ;
95
+ }
96
+
97
+ /** Focuses the menu item. Implements for FocusableOption. */
98
+ focus ( ) : void {
99
+ this . _elementRef . nativeElement . focus ( ) ;
100
+ }
101
+
102
+ private _setRoleFromData ( ) : void {
103
+ if ( this . _tree . treeControl . isExpandable ) {
104
+ this . role = this . _tree . treeControl . isExpandable ( this . _data ) ? 'group' : 'treeitem' ;
105
+ } else {
106
+ if ( ! this . _tree . treeControl . getChildren ) {
107
+ throw getTreeControlFunctionsMissingError ( ) ;
108
+ }
109
+ this . _tree . treeControl . getChildren ( this . _data ) . pipe ( takeUntil ( this . _destroyed ) )
110
+ . subscribe ( children => {
111
+ this . role = children && children . length ? 'group' : 'treeitem' ;
112
+ } ) ;
113
+ }
114
+ }
115
+ }
116
+
38
117
39
118
/**
40
119
* CDK tree component that connects with a data source to retrieve data of type `T` and renders
@@ -67,7 +146,7 @@ export class CdkTree<T> implements CollectionViewer, OnInit, OnDestroy {
67
146
private _defaultNodeDef : CdkTreeNodeDef < T > | null ;
68
147
69
148
/** Data subscription */
70
- private _dataSubscription : Subscription | null ;
149
+ private _dataSubscription : Subscription | null ;
71
150
72
151
/**
73
152
* Provides a stream containing the latest data array to render. Influenced by the tree's
@@ -91,9 +170,6 @@ export class CdkTree<T> implements CollectionViewer, OnInit, OnDestroy {
91
170
/** The tree node template for the tree */
92
171
@ContentChildren ( CdkTreeNodeDef ) _nodeDefs : QueryList < CdkTreeNodeDef < T > > ;
93
172
94
- /** The tree node inside the tree */
95
- @ContentChildren ( CdkTreeNode , { descendants : true } ) items : QueryList < CdkTreeNode < T > > ;
96
-
97
173
// TODO(tinayuangao): Setup a listener for scrolling, emit the calculated view to viewChange.
98
174
// Remove the MAX_VALUE in viewChange
99
175
/**
0 commit comments