@angular/cdk 21.0.0-next.9 → 21.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/_adev_assets/cdk_drag_drop.json +13 -12
  2. package/_adev_assets/cdk_testing.json +9 -9
  3. package/_adev_assets/cdk_testing_protractor.json +1 -1
  4. package/_adev_assets/cdk_testing_selenium_webdriver.json +1 -1
  5. package/_adev_assets/cdk_testing_testbed.json +1 -1
  6. package/fesm2022/_a11y-module-chunk.mjs +755 -869
  7. package/fesm2022/_a11y-module-chunk.mjs.map +1 -1
  8. package/fesm2022/_activedescendant-key-manager-chunk.mjs +8 -8
  9. package/fesm2022/_activedescendant-key-manager-chunk.mjs.map +1 -1
  10. package/fesm2022/_array-chunk.mjs +1 -1
  11. package/fesm2022/_array-chunk.mjs.map +1 -1
  12. package/fesm2022/_breakpoints-observer-chunk.mjs +149 -152
  13. package/fesm2022/_breakpoints-observer-chunk.mjs.map +1 -1
  14. package/fesm2022/_css-pixel-value-chunk.mjs +4 -5
  15. package/fesm2022/_css-pixel-value-chunk.mjs.map +1 -1
  16. package/fesm2022/_data-source-chunk.mjs +2 -8
  17. package/fesm2022/_data-source-chunk.mjs.map +1 -1
  18. package/fesm2022/_directionality-chunk.mjs +54 -54
  19. package/fesm2022/_directionality-chunk.mjs.map +1 -1
  20. package/fesm2022/_dispose-view-repeater-strategy-chunk.mjs +25 -36
  21. package/fesm2022/_dispose-view-repeater-strategy-chunk.mjs.map +1 -1
  22. package/fesm2022/_element-chunk.mjs +6 -17
  23. package/fesm2022/_element-chunk.mjs.map +1 -1
  24. package/fesm2022/_fake-event-detection-chunk.mjs +3 -17
  25. package/fesm2022/_fake-event-detection-chunk.mjs.map +1 -1
  26. package/fesm2022/_focus-key-manager-chunk.mjs +10 -14
  27. package/fesm2022/_focus-key-manager-chunk.mjs.map +1 -1
  28. package/fesm2022/_focus-monitor-chunk.mjs +376 -566
  29. package/fesm2022/_focus-monitor-chunk.mjs.map +1 -1
  30. package/fesm2022/_id-generator-chunk.mjs +36 -27
  31. package/fesm2022/_id-generator-chunk.mjs.map +1 -1
  32. package/fesm2022/_keycodes-chunk.mjs +9 -9
  33. package/fesm2022/_keycodes-chunk.mjs.map +1 -1
  34. package/fesm2022/_list-key-manager-chunk.mjs +248 -336
  35. package/fesm2022/_list-key-manager-chunk.mjs.map +1 -1
  36. package/fesm2022/_overlay-module-chunk.mjs +2534 -2948
  37. package/fesm2022/_overlay-module-chunk.mjs.map +1 -1
  38. package/fesm2022/_passive-listeners-chunk.mjs +10 -22
  39. package/fesm2022/_passive-listeners-chunk.mjs.map +1 -1
  40. package/fesm2022/_platform-chunk.mjs +42 -65
  41. package/fesm2022/_platform-chunk.mjs.map +1 -1
  42. package/fesm2022/_recycle-view-repeater-strategy-chunk.mjs +78 -134
  43. package/fesm2022/_recycle-view-repeater-strategy-chunk.mjs.map +1 -1
  44. package/fesm2022/_scrolling-chunk.mjs +44 -85
  45. package/fesm2022/_scrolling-chunk.mjs.map +1 -1
  46. package/fesm2022/_selection-model-chunk.mjs +138 -209
  47. package/fesm2022/_selection-model-chunk.mjs.map +1 -1
  48. package/fesm2022/_shadow-dom-chunk.mjs +21 -35
  49. package/fesm2022/_shadow-dom-chunk.mjs.map +1 -1
  50. package/fesm2022/_style-loader-chunk.mjs +50 -37
  51. package/fesm2022/_style-loader-chunk.mjs.map +1 -1
  52. package/fesm2022/_test-environment-chunk.mjs +2 -14
  53. package/fesm2022/_test-environment-chunk.mjs.map +1 -1
  54. package/fesm2022/_tree-key-manager-chunk.mjs +229 -308
  55. package/fesm2022/_tree-key-manager-chunk.mjs.map +1 -1
  56. package/fesm2022/_typeahead-chunk.mjs +52 -74
  57. package/fesm2022/_typeahead-chunk.mjs.map +1 -1
  58. package/fesm2022/_unique-selection-dispatcher-chunk.mjs +43 -40
  59. package/fesm2022/_unique-selection-dispatcher-chunk.mjs.map +1 -1
  60. package/fesm2022/a11y.mjs +351 -449
  61. package/fesm2022/a11y.mjs.map +1 -1
  62. package/fesm2022/accordion.mjs +254 -192
  63. package/fesm2022/accordion.mjs.map +1 -1
  64. package/fesm2022/bidi.mjs +121 -64
  65. package/fesm2022/bidi.mjs.map +1 -1
  66. package/fesm2022/cdk.mjs +1 -2
  67. package/fesm2022/cdk.mjs.map +1 -1
  68. package/fesm2022/clipboard.mjs +208 -186
  69. package/fesm2022/clipboard.mjs.map +1 -1
  70. package/fesm2022/coercion-private.mjs +4 -8
  71. package/fesm2022/coercion-private.mjs.map +1 -1
  72. package/fesm2022/coercion.mjs +11 -29
  73. package/fesm2022/coercion.mjs.map +1 -1
  74. package/fesm2022/dialog.mjs +660 -808
  75. package/fesm2022/dialog.mjs.map +1 -1
  76. package/fesm2022/drag-drop.mjs +3347 -4286
  77. package/fesm2022/drag-drop.mjs.map +1 -1
  78. package/fesm2022/keycodes.mjs +4 -8
  79. package/fesm2022/keycodes.mjs.map +1 -1
  80. package/fesm2022/layout.mjs +44 -26
  81. package/fesm2022/layout.mjs.map +1 -1
  82. package/fesm2022/listbox.mjs +841 -895
  83. package/fesm2022/listbox.mjs.map +1 -1
  84. package/fesm2022/menu.mjs +1942 -1858
  85. package/fesm2022/menu.mjs.map +1 -1
  86. package/fesm2022/observers-private.mjs +88 -106
  87. package/fesm2022/observers-private.mjs.map +1 -1
  88. package/fesm2022/observers.mjs +262 -184
  89. package/fesm2022/observers.mjs.map +1 -1
  90. package/fesm2022/overlay.mjs +72 -68
  91. package/fesm2022/overlay.mjs.map +1 -1
  92. package/fesm2022/platform.mjs +43 -54
  93. package/fesm2022/platform.mjs.map +1 -1
  94. package/fesm2022/portal.mjs +402 -560
  95. package/fesm2022/portal.mjs.map +1 -1
  96. package/fesm2022/private.mjs +38 -10
  97. package/fesm2022/private.mjs.map +1 -1
  98. package/fesm2022/scrolling.mjs +1323 -1400
  99. package/fesm2022/scrolling.mjs.map +1 -1
  100. package/fesm2022/stepper.mjs +758 -590
  101. package/fesm2022/stepper.mjs.map +1 -1
  102. package/fesm2022/table.mjs +2327 -2319
  103. package/fesm2022/table.mjs.map +1 -1
  104. package/fesm2022/testing-selenium-webdriver.mjs +252 -325
  105. package/fesm2022/testing-selenium-webdriver.mjs.map +1 -1
  106. package/fesm2022/testing-testbed.mjs +592 -709
  107. package/fesm2022/testing-testbed.mjs.map +1 -1
  108. package/fesm2022/testing.mjs +368 -889
  109. package/fesm2022/testing.mjs.map +1 -1
  110. package/fesm2022/text-field.mjs +459 -388
  111. package/fesm2022/text-field.mjs.map +1 -1
  112. package/fesm2022/tree.mjs +1483 -1731
  113. package/fesm2022/tree.mjs.map +1 -1
  114. package/overlay/_index.scss +28 -0
  115. package/overlay-prebuilt.css +1 -1
  116. package/package.json +1 -1
  117. package/schematics/ng-add/index.js +1 -1
  118. package/types/_overlay-module-chunk.d.ts +59 -7
  119. package/types/_portal-directives-chunk.d.ts +2 -18
  120. package/types/accordion.d.ts +3 -1
  121. package/types/dialog.d.ts +1 -1
  122. package/types/overlay.d.ts +6 -2
  123. package/types/portal.d.ts +1 -1
package/fesm2022/tree.mjs CHANGED
@@ -10,1791 +10,1543 @@ import { coerceObservable } from './coercion-private.mjs';
10
10
  import './_typeahead-chunk.mjs';
11
11
  import './_keycodes-chunk.mjs';
12
12
 
13
- /**
14
- * Base tree control. It has basic toggle/expand/collapse operations on a single data node.
15
- *
16
- * @deprecated Use one of levelAccessor or childrenAccessor. To be removed in a future version.
17
- * @breaking-change 21.0.0
18
- */
19
13
  class BaseTreeControl {
20
- /** Saved data node for `expandAll` action. */
21
- dataNodes;
22
- /** A selection model with multi-selection to track expansion status. */
23
- expansionModel = new SelectionModel(true);
24
- /**
25
- * Returns the identifier by which a dataNode should be tracked, should its
26
- * reference change.
27
- *
28
- * Similar to trackBy for *ngFor
29
- */
30
- trackBy;
31
- /** Get depth of a given data node, return the level number. This is for flat tree node. */
32
- getLevel;
33
- /**
34
- * Whether the data node is expandable. Returns true if expandable.
35
- * This is for flat tree node.
36
- */
37
- isExpandable;
38
- /** Gets a stream that emits whenever the given data node's children change. */
39
- getChildren;
40
- /** Toggles one single data node's expanded/collapsed state. */
41
- toggle(dataNode) {
42
- this.expansionModel.toggle(this._trackByValue(dataNode));
43
- }
44
- /** Expands one single data node. */
45
- expand(dataNode) {
46
- this.expansionModel.select(this._trackByValue(dataNode));
47
- }
48
- /** Collapses one single data node. */
49
- collapse(dataNode) {
50
- this.expansionModel.deselect(this._trackByValue(dataNode));
51
- }
52
- /** Whether a given data node is expanded or not. Returns true if the data node is expanded. */
53
- isExpanded(dataNode) {
54
- return this.expansionModel.isSelected(this._trackByValue(dataNode));
55
- }
56
- /** Toggles a subtree rooted at `node` recursively. */
57
- toggleDescendants(dataNode) {
58
- this.expansionModel.isSelected(this._trackByValue(dataNode))
59
- ? this.collapseDescendants(dataNode)
60
- : this.expandDescendants(dataNode);
61
- }
62
- /** Collapse all dataNodes in the tree. */
63
- collapseAll() {
64
- this.expansionModel.clear();
65
- }
66
- /** Expands a subtree rooted at given data node recursively. */
67
- expandDescendants(dataNode) {
68
- let toBeProcessed = [dataNode];
69
- toBeProcessed.push(...this.getDescendants(dataNode));
70
- this.expansionModel.select(...toBeProcessed.map(value => this._trackByValue(value)));
71
- }
72
- /** Collapses a subtree rooted at given data node recursively. */
73
- collapseDescendants(dataNode) {
74
- let toBeProcessed = [dataNode];
75
- toBeProcessed.push(...this.getDescendants(dataNode));
76
- this.expansionModel.deselect(...toBeProcessed.map(value => this._trackByValue(value)));
77
- }
78
- _trackByValue(value) {
79
- return this.trackBy ? this.trackBy(value) : value;
80
- }
14
+ dataNodes;
15
+ expansionModel = new SelectionModel(true);
16
+ trackBy;
17
+ getLevel;
18
+ isExpandable;
19
+ getChildren;
20
+ toggle(dataNode) {
21
+ this.expansionModel.toggle(this._trackByValue(dataNode));
22
+ }
23
+ expand(dataNode) {
24
+ this.expansionModel.select(this._trackByValue(dataNode));
25
+ }
26
+ collapse(dataNode) {
27
+ this.expansionModel.deselect(this._trackByValue(dataNode));
28
+ }
29
+ isExpanded(dataNode) {
30
+ return this.expansionModel.isSelected(this._trackByValue(dataNode));
31
+ }
32
+ toggleDescendants(dataNode) {
33
+ this.expansionModel.isSelected(this._trackByValue(dataNode)) ? this.collapseDescendants(dataNode) : this.expandDescendants(dataNode);
34
+ }
35
+ collapseAll() {
36
+ this.expansionModel.clear();
37
+ }
38
+ expandDescendants(dataNode) {
39
+ let toBeProcessed = [dataNode];
40
+ toBeProcessed.push(...this.getDescendants(dataNode));
41
+ this.expansionModel.select(...toBeProcessed.map(value => this._trackByValue(value)));
42
+ }
43
+ collapseDescendants(dataNode) {
44
+ let toBeProcessed = [dataNode];
45
+ toBeProcessed.push(...this.getDescendants(dataNode));
46
+ this.expansionModel.deselect(...toBeProcessed.map(value => this._trackByValue(value)));
47
+ }
48
+ _trackByValue(value) {
49
+ return this.trackBy ? this.trackBy(value) : value;
50
+ }
81
51
  }
82
52
 
83
- /**
84
- * Flat tree control. Able to expand/collapse a subtree recursively for flattened tree.
85
- *
86
- * @deprecated Use one of levelAccessor or childrenAccessor instead. To be removed in a future
87
- * version.
88
- * @breaking-change 21.0.0
89
- */
90
53
  class FlatTreeControl extends BaseTreeControl {
91
- getLevel;
92
- isExpandable;
93
- options;
94
- /** Construct with flat tree data node functions getLevel and isExpandable. */
95
- constructor(getLevel, isExpandable, options) {
96
- super();
97
- this.getLevel = getLevel;
98
- this.isExpandable = isExpandable;
99
- this.options = options;
100
- if (this.options) {
101
- this.trackBy = this.options.trackBy;
102
- }
103
- }
104
- /**
105
- * Gets a list of the data node's subtree of descendent data nodes.
106
- *
107
- * To make this working, the `dataNodes` of the TreeControl must be flattened tree nodes
108
- * with correct levels.
109
- */
110
- getDescendants(dataNode) {
111
- const startIndex = this.dataNodes.indexOf(dataNode);
112
- const results = [];
113
- // Goes through flattened tree nodes in the `dataNodes` array, and get all descendants.
114
- // The level of descendants of a tree node must be greater than the level of the given
115
- // tree node.
116
- // If we reach a node whose level is equal to the level of the tree node, we hit a sibling.
117
- // If we reach a node whose level is greater than the level of the tree node, we hit a
118
- // sibling of an ancestor.
119
- for (let i = startIndex + 1; i < this.dataNodes.length && this.getLevel(dataNode) < this.getLevel(this.dataNodes[i]); i++) {
120
- results.push(this.dataNodes[i]);
121
- }
122
- return results;
123
- }
124
- /**
125
- * Expands all data nodes in the tree.
126
- *
127
- * To make this working, the `dataNodes` variable of the TreeControl must be set to all flattened
128
- * data nodes of the tree.
129
- */
130
- expandAll() {
131
- this.expansionModel.select(...this.dataNodes.map(node => this._trackByValue(node)));
132
- }
54
+ getLevel;
55
+ isExpandable;
56
+ options;
57
+ constructor(getLevel, isExpandable, options) {
58
+ super();
59
+ this.getLevel = getLevel;
60
+ this.isExpandable = isExpandable;
61
+ this.options = options;
62
+ if (this.options) {
63
+ this.trackBy = this.options.trackBy;
64
+ }
65
+ }
66
+ getDescendants(dataNode) {
67
+ const startIndex = this.dataNodes.indexOf(dataNode);
68
+ const results = [];
69
+ for (let i = startIndex + 1; i < this.dataNodes.length && this.getLevel(dataNode) < this.getLevel(this.dataNodes[i]); i++) {
70
+ results.push(this.dataNodes[i]);
71
+ }
72
+ return results;
73
+ }
74
+ expandAll() {
75
+ this.expansionModel.select(...this.dataNodes.map(node => this._trackByValue(node)));
76
+ }
133
77
  }
134
78
 
135
- /**
136
- * Nested tree control. Able to expand/collapse a subtree recursively for NestedNode type.
137
- *
138
- * @deprecated Use one of levelAccessor or childrenAccessor instead. To be removed in a future
139
- * version.
140
- * @breaking-change 21.0.0
141
- */
142
79
  class NestedTreeControl extends BaseTreeControl {
143
- getChildren;
144
- options;
145
- /** Construct with nested tree function getChildren. */
146
- constructor(getChildren, options) {
147
- super();
148
- this.getChildren = getChildren;
149
- this.options = options;
150
- if (this.options) {
151
- this.trackBy = this.options.trackBy;
152
- }
153
- if (this.options?.isExpandable) {
154
- this.isExpandable = this.options.isExpandable;
155
- }
156
- }
157
- /**
158
- * Expands all dataNodes in the tree.
159
- *
160
- * To make this working, the `dataNodes` variable of the TreeControl must be set to all root level
161
- * data nodes of the tree.
162
- */
163
- expandAll() {
164
- this.expansionModel.clear();
165
- const allNodes = this.dataNodes.reduce((accumulator, dataNode) => [...accumulator, ...this.getDescendants(dataNode), dataNode], []);
166
- this.expansionModel.select(...allNodes.map(node => this._trackByValue(node)));
167
- }
168
- /** Gets a list of descendant dataNodes of a subtree rooted at given data node recursively. */
169
- getDescendants(dataNode) {
170
- const descendants = [];
171
- this._getDescendants(descendants, dataNode);
172
- // Remove the node itself
173
- return descendants.splice(1);
174
- }
175
- /** A helper function to get descendants recursively. */
176
- _getDescendants(descendants, dataNode) {
177
- descendants.push(dataNode);
178
- const childrenNodes = this.getChildren(dataNode);
179
- if (Array.isArray(childrenNodes)) {
180
- childrenNodes.forEach((child) => this._getDescendants(descendants, child));
181
- }
182
- else if (isObservable(childrenNodes)) {
183
- // TypeScript as of version 3.5 doesn't seem to treat `Boolean` like a function that
184
- // returns a `boolean` specifically in the context of `filter`, so we manually clarify that.
185
- childrenNodes.pipe(take(1), filter(Boolean)).subscribe(children => {
186
- for (const child of children) {
187
- this._getDescendants(descendants, child);
188
- }
189
- });
190
- }
191
- }
80
+ getChildren;
81
+ options;
82
+ constructor(getChildren, options) {
83
+ super();
84
+ this.getChildren = getChildren;
85
+ this.options = options;
86
+ if (this.options) {
87
+ this.trackBy = this.options.trackBy;
88
+ }
89
+ if (this.options?.isExpandable) {
90
+ this.isExpandable = this.options.isExpandable;
91
+ }
92
+ }
93
+ expandAll() {
94
+ this.expansionModel.clear();
95
+ const allNodes = this.dataNodes.reduce((accumulator, dataNode) => [...accumulator, ...this.getDescendants(dataNode), dataNode], []);
96
+ this.expansionModel.select(...allNodes.map(node => this._trackByValue(node)));
97
+ }
98
+ getDescendants(dataNode) {
99
+ const descendants = [];
100
+ this._getDescendants(descendants, dataNode);
101
+ return descendants.splice(1);
102
+ }
103
+ _getDescendants(descendants, dataNode) {
104
+ descendants.push(dataNode);
105
+ const childrenNodes = this.getChildren(dataNode);
106
+ if (Array.isArray(childrenNodes)) {
107
+ childrenNodes.forEach(child => this._getDescendants(descendants, child));
108
+ } else if (isObservable(childrenNodes)) {
109
+ childrenNodes.pipe(take(1), filter(Boolean)).subscribe(children => {
110
+ for (const child of children) {
111
+ this._getDescendants(descendants, child);
112
+ }
113
+ });
114
+ }
115
+ }
192
116
  }
193
117
 
194
- /**
195
- * Injection token used to provide a `CdkTreeNode` to its outlet.
196
- * Used primarily to avoid circular imports.
197
- * @docs-private
198
- */
199
118
  const CDK_TREE_NODE_OUTLET_NODE = new InjectionToken('CDK_TREE_NODE_OUTLET_NODE');
200
- /**
201
- * Outlet for nested CdkNode. Put `[cdkTreeNodeOutlet]` on a tag to place children dataNodes
202
- * inside the outlet.
203
- */
204
119
  class CdkTreeNodeOutlet {
205
- viewContainer = inject(ViewContainerRef);
206
- _node = inject(CDK_TREE_NODE_OUTLET_NODE, { optional: true });
207
- constructor() { }
208
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNodeOutlet, deps: [], target: i0.ɵɵFactoryTarget.Directive });
209
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.0-next.2", type: CdkTreeNodeOutlet, isStandalone: true, selector: "[cdkTreeNodeOutlet]", ngImport: i0 });
120
+ viewContainer = inject(ViewContainerRef);
121
+ _node = inject(CDK_TREE_NODE_OUTLET_NODE, {
122
+ optional: true
123
+ });
124
+ constructor() {}
125
+ static ɵfac = i0.ɵɵngDeclareFactory({
126
+ minVersion: "12.0.0",
127
+ version: "20.2.0-next.2",
128
+ ngImport: i0,
129
+ type: CdkTreeNodeOutlet,
130
+ deps: [],
131
+ target: i0.ɵɵFactoryTarget.Directive
132
+ });
133
+ static ɵdir = i0.ɵɵngDeclareDirective({
134
+ minVersion: "14.0.0",
135
+ version: "20.2.0-next.2",
136
+ type: CdkTreeNodeOutlet,
137
+ isStandalone: true,
138
+ selector: "[cdkTreeNodeOutlet]",
139
+ ngImport: i0
140
+ });
210
141
  }
211
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNodeOutlet, decorators: [{
212
- type: Directive,
213
- args: [{
214
- selector: '[cdkTreeNodeOutlet]',
215
- }]
216
- }], ctorParameters: () => [] });
142
+ i0.ɵɵngDeclareClassMetadata({
143
+ minVersion: "12.0.0",
144
+ version: "20.2.0-next.2",
145
+ ngImport: i0,
146
+ type: CdkTreeNodeOutlet,
147
+ decorators: [{
148
+ type: Directive,
149
+ args: [{
150
+ selector: '[cdkTreeNodeOutlet]'
151
+ }]
152
+ }],
153
+ ctorParameters: () => []
154
+ });
217
155
 
218
- /** Context provided to the tree node component. */
219
156
  class CdkTreeNodeOutletContext {
220
- /** Data for the node. */
221
- $implicit;
222
- /** Depth of the node. */
223
- level;
224
- /** Index location of the node. */
225
- index;
226
- /** Length of the number of total dataNodes. */
227
- count;
228
- constructor(data) {
229
- this.$implicit = data;
230
- }
157
+ $implicit;
158
+ level;
159
+ index;
160
+ count;
161
+ constructor(data) {
162
+ this.$implicit = data;
163
+ }
231
164
  }
232
- /**
233
- * Data node definition for the CdkTree.
234
- * Captures the node's template and a when predicate that describes when this node should be used.
235
- */
236
165
  class CdkTreeNodeDef {
237
- /** @docs-private */
238
- template = inject(TemplateRef);
239
- /**
240
- * Function that should return true if this node template should be used for the provided node
241
- * data and index. If left undefined, this node will be considered the default node template to
242
- * use when no other when functions return true for the data.
243
- * For every node, there must be at least one when function that passes or an undefined to
244
- * default.
245
- */
246
- when;
247
- constructor() { }
248
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNodeDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
249
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.0-next.2", type: CdkTreeNodeDef, isStandalone: true, selector: "[cdkTreeNodeDef]", inputs: { when: ["cdkTreeNodeDefWhen", "when"] }, ngImport: i0 });
166
+ template = inject(TemplateRef);
167
+ when;
168
+ constructor() {}
169
+ static ɵfac = i0.ɵɵngDeclareFactory({
170
+ minVersion: "12.0.0",
171
+ version: "20.2.0-next.2",
172
+ ngImport: i0,
173
+ type: CdkTreeNodeDef,
174
+ deps: [],
175
+ target: i0.ɵɵFactoryTarget.Directive
176
+ });
177
+ static ɵdir = i0.ɵɵngDeclareDirective({
178
+ minVersion: "14.0.0",
179
+ version: "20.2.0-next.2",
180
+ type: CdkTreeNodeDef,
181
+ isStandalone: true,
182
+ selector: "[cdkTreeNodeDef]",
183
+ inputs: {
184
+ when: ["cdkTreeNodeDefWhen", "when"]
185
+ },
186
+ ngImport: i0
187
+ });
250
188
  }
251
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNodeDef, decorators: [{
252
- type: Directive,
253
- args: [{
254
- selector: '[cdkTreeNodeDef]',
255
- inputs: [{ name: 'when', alias: 'cdkTreeNodeDefWhen' }],
256
- }]
257
- }], ctorParameters: () => [] });
189
+ i0.ɵɵngDeclareClassMetadata({
190
+ minVersion: "12.0.0",
191
+ version: "20.2.0-next.2",
192
+ ngImport: i0,
193
+ type: CdkTreeNodeDef,
194
+ decorators: [{
195
+ type: Directive,
196
+ args: [{
197
+ selector: '[cdkTreeNodeDef]',
198
+ inputs: [{
199
+ name: 'when',
200
+ alias: 'cdkTreeNodeDefWhen'
201
+ }]
202
+ }]
203
+ }],
204
+ ctorParameters: () => []
205
+ });
258
206
 
259
- /**
260
- * Returns an error to be thrown when there is no usable data.
261
- * @docs-private
262
- */
263
207
  function getTreeNoValidDataSourceError() {
264
- return Error(`A valid data source must be provided.`);
208
+ return Error(`A valid data source must be provided.`);
265
209
  }
266
- /**
267
- * Returns an error to be thrown when there are multiple nodes that are missing a when function.
268
- * @docs-private
269
- */
270
210
  function getTreeMultipleDefaultNodeDefsError() {
271
- return Error(`There can only be one default row without a when predicate function.`);
211
+ return Error(`There can only be one default row without a when predicate function.`);
272
212
  }
273
- /**
274
- * Returns an error to be thrown when there are no matching node defs for a particular set of data.
275
- * @docs-private
276
- */
277
213
  function getTreeMissingMatchingNodeDefError() {
278
- return Error(`Could not find a matching node definition for the provided node data.`);
214
+ return Error(`Could not find a matching node definition for the provided node data.`);
279
215
  }
280
- /**
281
- * Returns an error to be thrown when there is no tree control.
282
- * @docs-private
283
- */
284
216
  function getTreeControlMissingError() {
285
- return Error(`Could not find a tree control, levelAccessor, or childrenAccessor for the tree.`);
217
+ return Error(`Could not find a tree control, levelAccessor, or childrenAccessor for the tree.`);
286
218
  }
287
- /**
288
- * Returns an error to be thrown when there are multiple ways of specifying children or level
289
- * provided to the tree.
290
- * @docs-private
291
- */
292
219
  function getMultipleTreeControlsError() {
293
- return Error(`More than one of tree control, levelAccessor, or childrenAccessor were provided.`);
220
+ return Error(`More than one of tree control, levelAccessor, or childrenAccessor were provided.`);
294
221
  }
295
222
 
296
- /**
297
- * CDK tree component that connects with a data source to retrieve data of type `T` and renders
298
- * dataNodes with hierarchy. Updates the dataNodes when new data is provided by the data source.
299
- */
300
223
  class CdkTree {
301
- _differs = inject(IterableDiffers);
302
- _changeDetectorRef = inject(ChangeDetectorRef);
303
- _elementRef = inject(ElementRef);
304
- _dir = inject(Directionality);
305
- /** Subject that emits when the component has been destroyed. */
306
- _onDestroy = new Subject();
307
- /** Differ used to find the changes in the data provided by the data source. */
308
- _dataDiffer;
309
- /** Stores the node definition that does not have a when predicate. */
310
- _defaultNodeDef;
311
- /** Data subscription */
312
- _dataSubscription;
313
- /** Level of nodes */
314
- _levels = new Map();
315
- /** The immediate parents for a node. This is `null` if there is no parent. */
316
- _parents = new Map();
317
- /**
318
- * Nodes grouped into each set, which is a list of nodes displayed together in the DOM.
319
- *
320
- * Lookup key is the parent of a set. Root nodes have key of null.
321
- *
322
- * Values is a 'set' of tree nodes. Each tree node maps to a treeitem element. Sets are in the
323
- * order that it is rendered. Each set maps directly to aria-posinset and aria-setsize attributes.
324
- */
325
- _ariaSets = new Map();
326
- /**
327
- * Provides a stream containing the latest data array to render. Influenced by the tree's
328
- * stream of view window (what dataNodes are currently on screen).
329
- * Data source can be an observable of data array, or a data array to render.
330
- */
331
- get dataSource() {
332
- return this._dataSource;
333
- }
334
- set dataSource(dataSource) {
335
- if (this._dataSource !== dataSource) {
336
- this._switchDataSource(dataSource);
337
- }
338
- }
339
- _dataSource;
340
- /**
341
- * The tree controller
342
- *
343
- * @deprecated Use one of `levelAccessor` or `childrenAccessor` instead. To be removed in a
344
- * future version.
345
- * @breaking-change 21.0.0
346
- */
347
- treeControl;
348
- /**
349
- * Given a data node, determines what tree level the node is at.
350
- *
351
- * One of levelAccessor or childrenAccessor must be specified, not both.
352
- * This is enforced at run-time.
353
- */
354
- levelAccessor;
355
- /**
356
- * Given a data node, determines what the children of that node are.
357
- *
358
- * One of levelAccessor or childrenAccessor must be specified, not both.
359
- * This is enforced at run-time.
360
- */
361
- childrenAccessor;
362
- /**
363
- * Tracking function that will be used to check the differences in data changes. Used similarly
364
- * to `ngFor` `trackBy` function. Optimize node operations by identifying a node based on its data
365
- * relative to the function to know if a node should be added/removed/moved.
366
- * Accepts a function that takes two parameters, `index` and `item`.
367
- */
368
- trackBy;
369
- /**
370
- * Given a data node, determines the key by which we determine whether or not this node is expanded.
371
- */
372
- expansionKey;
373
- // Outlets within the tree's template where the dataNodes will be inserted.
374
- _nodeOutlet;
375
- /** The tree node template for the tree */
376
- _nodeDefs;
377
- // TODO(tinayuangao): Setup a listener for scrolling, emit the calculated view to viewChange.
378
- // Remove the MAX_VALUE in viewChange
379
- /**
380
- * Stream containing the latest information on what rows are being displayed on screen.
381
- * Can be used by the data source to as a heuristic of what data should be provided.
382
- */
383
- viewChange = new BehaviorSubject({
384
- start: 0,
385
- end: Number.MAX_VALUE,
224
+ _differs = inject(IterableDiffers);
225
+ _changeDetectorRef = inject(ChangeDetectorRef);
226
+ _elementRef = inject(ElementRef);
227
+ _dir = inject(Directionality);
228
+ _onDestroy = new Subject();
229
+ _dataDiffer;
230
+ _defaultNodeDef;
231
+ _dataSubscription;
232
+ _levels = new Map();
233
+ _parents = new Map();
234
+ _ariaSets = new Map();
235
+ get dataSource() {
236
+ return this._dataSource;
237
+ }
238
+ set dataSource(dataSource) {
239
+ if (this._dataSource !== dataSource) {
240
+ this._switchDataSource(dataSource);
241
+ }
242
+ }
243
+ _dataSource;
244
+ treeControl;
245
+ levelAccessor;
246
+ childrenAccessor;
247
+ trackBy;
248
+ expansionKey;
249
+ _nodeOutlet;
250
+ _nodeDefs;
251
+ viewChange = new BehaviorSubject({
252
+ start: 0,
253
+ end: Number.MAX_VALUE
254
+ });
255
+ _expansionModel;
256
+ _flattenedNodes = new BehaviorSubject([]);
257
+ _nodeType = new BehaviorSubject(null);
258
+ _nodes = new BehaviorSubject(new Map());
259
+ _keyManagerNodes = new BehaviorSubject([]);
260
+ _keyManagerFactory = inject(TREE_KEY_MANAGER);
261
+ _keyManager;
262
+ _viewInit = false;
263
+ constructor() {}
264
+ ngAfterContentInit() {
265
+ this._initializeKeyManager();
266
+ }
267
+ ngAfterContentChecked() {
268
+ this._updateDefaultNodeDefinition();
269
+ this._subscribeToDataChanges();
270
+ }
271
+ ngOnDestroy() {
272
+ this._nodeOutlet.viewContainer.clear();
273
+ this._nodes.complete();
274
+ this._keyManagerNodes.complete();
275
+ this._nodeType.complete();
276
+ this._flattenedNodes.complete();
277
+ this.viewChange.complete();
278
+ this._onDestroy.next();
279
+ this._onDestroy.complete();
280
+ if (this._dataSource && typeof this._dataSource.disconnect === 'function') {
281
+ this.dataSource.disconnect(this);
282
+ }
283
+ if (this._dataSubscription) {
284
+ this._dataSubscription.unsubscribe();
285
+ this._dataSubscription = null;
286
+ }
287
+ this._keyManager?.destroy();
288
+ }
289
+ ngOnInit() {
290
+ this._checkTreeControlUsage();
291
+ this._initializeDataDiffer();
292
+ }
293
+ ngAfterViewInit() {
294
+ this._viewInit = true;
295
+ }
296
+ _updateDefaultNodeDefinition() {
297
+ const defaultNodeDefs = this._nodeDefs.filter(def => !def.when);
298
+ if (defaultNodeDefs.length > 1 && (typeof ngDevMode === 'undefined' || ngDevMode)) {
299
+ throw getTreeMultipleDefaultNodeDefsError();
300
+ }
301
+ this._defaultNodeDef = defaultNodeDefs[0];
302
+ }
303
+ _setNodeTypeIfUnset(newType) {
304
+ const currentType = this._nodeType.value;
305
+ if (currentType === null) {
306
+ this._nodeType.next(newType);
307
+ } else if ((typeof ngDevMode === 'undefined' || ngDevMode) && currentType !== newType) {
308
+ console.warn(`Tree is using conflicting node types which can cause unexpected behavior. ` + `Please use tree nodes of the same type (e.g. only flat or only nested). ` + `Current node type: "${currentType}", new node type "${newType}".`);
309
+ }
310
+ }
311
+ _switchDataSource(dataSource) {
312
+ if (this._dataSource && typeof this._dataSource.disconnect === 'function') {
313
+ this.dataSource.disconnect(this);
314
+ }
315
+ if (this._dataSubscription) {
316
+ this._dataSubscription.unsubscribe();
317
+ this._dataSubscription = null;
318
+ }
319
+ if (!dataSource) {
320
+ this._nodeOutlet.viewContainer.clear();
321
+ }
322
+ this._dataSource = dataSource;
323
+ if (this._nodeDefs) {
324
+ this._subscribeToDataChanges();
325
+ }
326
+ }
327
+ _getExpansionModel() {
328
+ if (!this.treeControl) {
329
+ this._expansionModel ??= new SelectionModel(true);
330
+ return this._expansionModel;
331
+ }
332
+ return this.treeControl.expansionModel;
333
+ }
334
+ _subscribeToDataChanges() {
335
+ if (this._dataSubscription) {
336
+ return;
337
+ }
338
+ let dataStream;
339
+ if (isDataSource(this._dataSource)) {
340
+ dataStream = this._dataSource.connect(this);
341
+ } else if (isObservable(this._dataSource)) {
342
+ dataStream = this._dataSource;
343
+ } else if (Array.isArray(this._dataSource)) {
344
+ dataStream = of(this._dataSource);
345
+ }
346
+ if (!dataStream) {
347
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
348
+ throw getTreeNoValidDataSourceError();
349
+ }
350
+ return;
351
+ }
352
+ this._dataSubscription = this._getRenderData(dataStream).pipe(takeUntil(this._onDestroy)).subscribe(renderingData => {
353
+ this._renderDataChanges(renderingData);
386
354
  });
387
- /** Keep track of which nodes are expanded. */
388
- _expansionModel;
389
- /**
390
- * Maintain a synchronous cache of flattened data nodes. This will only be
391
- * populated after initial render, and in certain cases, will be delayed due to
392
- * relying on Observable `getChildren` calls.
393
- */
394
- _flattenedNodes = new BehaviorSubject([]);
395
- /** The automatically determined node type for the tree. */
396
- _nodeType = new BehaviorSubject(null);
397
- /** The mapping between data and the node that is rendered. */
398
- _nodes = new BehaviorSubject(new Map());
399
- /**
400
- * Synchronous cache of nodes for the `TreeKeyManager`. This is separate
401
- * from `_flattenedNodes` so they can be independently updated at different
402
- * times.
403
- */
404
- _keyManagerNodes = new BehaviorSubject([]);
405
- _keyManagerFactory = inject(TREE_KEY_MANAGER);
406
- /** The key manager for this tree. Handles focus and activation based on user keyboard input. */
407
- _keyManager;
408
- _viewInit = false;
409
- constructor() { }
410
- ngAfterContentInit() {
411
- this._initializeKeyManager();
412
- }
413
- ngAfterContentChecked() {
414
- this._updateDefaultNodeDefinition();
415
- this._subscribeToDataChanges();
416
- }
417
- ngOnDestroy() {
418
- this._nodeOutlet.viewContainer.clear();
419
- this._nodes.complete();
420
- this._keyManagerNodes.complete();
421
- this._nodeType.complete();
422
- this._flattenedNodes.complete();
423
- this.viewChange.complete();
424
- this._onDestroy.next();
425
- this._onDestroy.complete();
426
- if (this._dataSource && typeof this._dataSource.disconnect === 'function') {
427
- this.dataSource.disconnect(this);
428
- }
429
- if (this._dataSubscription) {
430
- this._dataSubscription.unsubscribe();
431
- this._dataSubscription = null;
432
- }
433
- // In certain tests, the tree might be destroyed before this is initialized
434
- // in `ngAfterContentInit`.
435
- this._keyManager?.destroy();
436
- }
437
- ngOnInit() {
438
- this._checkTreeControlUsage();
439
- this._initializeDataDiffer();
440
- }
441
- ngAfterViewInit() {
442
- this._viewInit = true;
443
- }
444
- _updateDefaultNodeDefinition() {
445
- const defaultNodeDefs = this._nodeDefs.filter(def => !def.when);
446
- if (defaultNodeDefs.length > 1 && (typeof ngDevMode === 'undefined' || ngDevMode)) {
447
- throw getTreeMultipleDefaultNodeDefsError();
448
- }
449
- this._defaultNodeDef = defaultNodeDefs[0];
450
- }
451
- /**
452
- * Sets the node type for the tree, if it hasn't been set yet.
453
- *
454
- * This will be called by the first node that's rendered in order for the tree
455
- * to determine what data transformations are required.
456
- */
457
- _setNodeTypeIfUnset(newType) {
458
- const currentType = this._nodeType.value;
459
- if (currentType === null) {
460
- this._nodeType.next(newType);
461
- }
462
- else if ((typeof ngDevMode === 'undefined' || ngDevMode) && currentType !== newType) {
463
- console.warn(`Tree is using conflicting node types which can cause unexpected behavior. ` +
464
- `Please use tree nodes of the same type (e.g. only flat or only nested). ` +
465
- `Current node type: "${currentType}", new node type "${newType}".`);
466
- }
467
- }
468
- /**
469
- * Switch to the provided data source by resetting the data and unsubscribing from the current
470
- * render change subscription if one exists. If the data source is null, interpret this by
471
- * clearing the node outlet. Otherwise start listening for new data.
472
- */
473
- _switchDataSource(dataSource) {
474
- if (this._dataSource && typeof this._dataSource.disconnect === 'function') {
475
- this.dataSource.disconnect(this);
476
- }
477
- if (this._dataSubscription) {
478
- this._dataSubscription.unsubscribe();
479
- this._dataSubscription = null;
480
- }
481
- // Remove the all dataNodes if there is now no data source
482
- if (!dataSource) {
483
- this._nodeOutlet.viewContainer.clear();
484
- }
485
- this._dataSource = dataSource;
486
- if (this._nodeDefs) {
487
- this._subscribeToDataChanges();
488
- }
489
- }
490
- _getExpansionModel() {
491
- if (!this.treeControl) {
492
- this._expansionModel ??= new SelectionModel(true);
493
- return this._expansionModel;
494
- }
495
- return this.treeControl.expansionModel;
496
- }
497
- /** Set up a subscription for the data provided by the data source. */
498
- _subscribeToDataChanges() {
499
- if (this._dataSubscription) {
500
- return;
501
- }
502
- let dataStream;
503
- if (isDataSource(this._dataSource)) {
504
- dataStream = this._dataSource.connect(this);
505
- }
506
- else if (isObservable(this._dataSource)) {
507
- dataStream = this._dataSource;
508
- }
509
- else if (Array.isArray(this._dataSource)) {
510
- dataStream = of(this._dataSource);
511
- }
512
- if (!dataStream) {
513
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
514
- throw getTreeNoValidDataSourceError();
515
- }
516
- return;
517
- }
518
- this._dataSubscription = this._getRenderData(dataStream)
519
- .pipe(takeUntil(this._onDestroy))
520
- .subscribe(renderingData => {
521
- this._renderDataChanges(renderingData);
522
- });
523
- }
524
- /** Given an Observable containing a stream of the raw data, returns an Observable containing the RenderingData */
525
- _getRenderData(dataStream) {
526
- const expansionModel = this._getExpansionModel();
527
- return combineLatest([
528
- dataStream,
529
- this._nodeType,
530
- // We don't use the expansion data directly, however we add it here to essentially
531
- // trigger data rendering when expansion changes occur.
532
- expansionModel.changed.pipe(startWith(null), tap(expansionChanges => {
533
- this._emitExpansionChanges(expansionChanges);
534
- })),
535
- ]).pipe(switchMap(([data, nodeType]) => {
536
- if (nodeType === null) {
537
- return of({ renderNodes: data, flattenedNodes: null, nodeType });
538
- }
539
- // If we're here, then we know what our node type is, and therefore can
540
- // perform our usual rendering pipeline, which necessitates converting the data
541
- return this._computeRenderingData(data, nodeType).pipe(map(convertedData => ({ ...convertedData, nodeType })));
542
- }));
543
- }
544
- _renderDataChanges(data) {
545
- if (data.nodeType === null) {
546
- this.renderNodeChanges(data.renderNodes);
547
- return;
548
- }
549
- // If we're here, then we know what our node type is, and therefore can
550
- // perform our usual rendering pipeline.
551
- this._updateCachedData(data.flattenedNodes);
552
- this.renderNodeChanges(data.renderNodes);
553
- this._updateKeyManagerItems(data.flattenedNodes);
554
- }
555
- _emitExpansionChanges(expansionChanges) {
556
- if (!expansionChanges) {
557
- return;
558
- }
559
- const nodes = this._nodes.value;
560
- for (const added of expansionChanges.added) {
561
- const node = nodes.get(added);
562
- node?._emitExpansionState(true);
563
- }
564
- for (const removed of expansionChanges.removed) {
565
- const node = nodes.get(removed);
566
- node?._emitExpansionState(false);
567
- }
568
- }
569
- _initializeKeyManager() {
570
- const items = combineLatest([this._keyManagerNodes, this._nodes]).pipe(map(([keyManagerNodes, renderNodes]) => keyManagerNodes.reduce((items, data) => {
571
- const node = renderNodes.get(this._getExpansionKey(data));
572
- if (node) {
573
- items.push(node);
574
- }
575
- return items;
576
- }, [])));
577
- const keyManagerOptions = {
578
- trackBy: node => this._getExpansionKey(node.data),
579
- skipPredicate: node => !!node.isDisabled,
580
- typeAheadDebounceInterval: true,
581
- horizontalOrientation: this._dir.value,
582
- };
583
- this._keyManager = this._keyManagerFactory(items, keyManagerOptions);
584
- }
585
- _initializeDataDiffer() {
586
- // Provide a default trackBy based on `_getExpansionKey` if one isn't provided.
587
- const trackBy = this.trackBy ?? ((_index, item) => this._getExpansionKey(item));
588
- this._dataDiffer = this._differs.find([]).create(trackBy);
589
- }
590
- _checkTreeControlUsage() {
591
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
592
- // Verify that Tree follows API contract of using one of TreeControl, levelAccessor or
593
- // childrenAccessor. Throw an appropriate error if contract is not met.
594
- let numTreeControls = 0;
595
- if (this.treeControl) {
596
- numTreeControls++;
597
- }
598
- if (this.levelAccessor) {
599
- numTreeControls++;
600
- }
601
- if (this.childrenAccessor) {
602
- numTreeControls++;
603
- }
604
- if (!numTreeControls) {
605
- throw getTreeControlMissingError();
606
- }
607
- else if (numTreeControls > 1) {
608
- throw getMultipleTreeControlsError();
609
- }
610
- }
611
- }
612
- /** Check for changes made in the data and render each change (node added/removed/moved). */
613
- renderNodeChanges(data, dataDiffer = this._dataDiffer, viewContainer = this._nodeOutlet.viewContainer, parentData) {
614
- const changes = dataDiffer.diff(data);
615
- // Some tree consumers expect change detection to propagate to nodes
616
- // even when the array itself hasn't changed; we explicitly detect changes
617
- // anyways in order for nodes to update their data.
618
- //
619
- // However, if change detection is called while the component's view is
620
- // still initing, then the order of child views initing will be incorrect;
621
- // to prevent this, we only exit early if the view hasn't initialized yet.
622
- if (!changes && !this._viewInit) {
623
- return;
624
- }
625
- changes?.forEachOperation((item, adjustedPreviousIndex, currentIndex) => {
626
- if (item.previousIndex == null) {
627
- this.insertNode(data[currentIndex], currentIndex, viewContainer, parentData);
628
- }
629
- else if (currentIndex == null) {
630
- viewContainer.remove(adjustedPreviousIndex);
631
- }
632
- else {
633
- const view = viewContainer.get(adjustedPreviousIndex);
634
- viewContainer.move(view, currentIndex);
635
- }
636
- });
637
- // If the data itself changes, but keeps the same trackBy, we need to update the templates'
638
- // context to reflect the new object.
639
- changes?.forEachIdentityChange((record) => {
640
- const newData = record.item;
641
- if (record.currentIndex != undefined) {
642
- const view = viewContainer.get(record.currentIndex);
643
- view.context.$implicit = newData;
644
- }
355
+ }
356
+ _getRenderData(dataStream) {
357
+ const expansionModel = this._getExpansionModel();
358
+ return combineLatest([dataStream, this._nodeType, expansionModel.changed.pipe(startWith(null), tap(expansionChanges => {
359
+ this._emitExpansionChanges(expansionChanges);
360
+ }))]).pipe(switchMap(([data, nodeType]) => {
361
+ if (nodeType === null) {
362
+ return of({
363
+ renderNodes: data,
364
+ flattenedNodes: null,
365
+ nodeType
645
366
  });
646
- // Note: we only `detectChanges` from a top-level call, otherwise we risk overflowing
647
- // the call stack since this method is called recursively (see #29733.)
648
- // TODO: change to `this._changeDetectorRef.markForCheck()`,
649
- // or just switch this component to use signals.
650
- if (parentData) {
651
- this._changeDetectorRef.markForCheck();
652
- }
653
- else {
654
- this._changeDetectorRef.detectChanges();
655
- }
656
- }
657
- /**
658
- * Finds the matching node definition that should be used for this node data. If there is only
659
- * one node definition, it is returned. Otherwise, find the node definition that has a when
660
- * predicate that returns true with the data. If none return true, return the default node
661
- * definition.
662
- */
663
- _getNodeDef(data, i) {
664
- if (this._nodeDefs.length === 1) {
665
- return this._nodeDefs.first;
666
- }
667
- const nodeDef = this._nodeDefs.find(def => def.when && def.when(i, data)) || this._defaultNodeDef;
668
- if (!nodeDef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
669
- throw getTreeMissingMatchingNodeDefError();
670
- }
671
- return nodeDef;
672
- }
673
- /**
674
- * Create the embedded view for the data node template and place it in the correct index location
675
- * within the data node view container.
676
- */
677
- insertNode(nodeData, index, viewContainer, parentData) {
678
- const levelAccessor = this._getLevelAccessor();
679
- const node = this._getNodeDef(nodeData, index);
680
- const key = this._getExpansionKey(nodeData);
681
- // Node context that will be provided to created embedded view
682
- const context = new CdkTreeNodeOutletContext(nodeData);
683
- context.index = index;
684
- parentData ??= this._parents.get(key) ?? undefined;
685
- // If the tree is flat tree, then use the `getLevel` function in flat tree control
686
- // Otherwise, use the level of parent node.
687
- if (levelAccessor) {
688
- context.level = levelAccessor(nodeData);
689
- }
690
- else if (parentData !== undefined && this._levels.has(this._getExpansionKey(parentData))) {
691
- context.level = this._levels.get(this._getExpansionKey(parentData)) + 1;
692
- }
693
- else {
694
- context.level = 0;
695
- }
696
- this._levels.set(key, context.level);
697
- // Use default tree nodeOutlet, or nested node's nodeOutlet
698
- const container = viewContainer ? viewContainer : this._nodeOutlet.viewContainer;
699
- container.createEmbeddedView(node.template, context, index);
700
- // Set the data to just created `CdkTreeNode`.
701
- // The `CdkTreeNode` created from `createEmbeddedView` will be saved in static variable
702
- // `mostRecentTreeNode`. We get it from static variable and pass the node data to it.
703
- if (CdkTreeNode.mostRecentTreeNode) {
704
- CdkTreeNode.mostRecentTreeNode.data = nodeData;
705
- }
706
- }
707
- /** Whether the data node is expanded or collapsed. Returns true if it's expanded. */
708
- isExpanded(dataNode) {
709
- return !!(this.treeControl?.isExpanded(dataNode) ||
710
- this._expansionModel?.isSelected(this._getExpansionKey(dataNode)));
711
- }
712
- /** If the data node is currently expanded, collapse it. Otherwise, expand it. */
713
- toggle(dataNode) {
714
- if (this.treeControl) {
715
- this.treeControl.toggle(dataNode);
716
- }
717
- else if (this._expansionModel) {
718
- this._expansionModel.toggle(this._getExpansionKey(dataNode));
719
- }
720
- }
721
- /** Expand the data node. If it is already expanded, does nothing. */
722
- expand(dataNode) {
723
- if (this.treeControl) {
724
- this.treeControl.expand(dataNode);
725
- }
726
- else if (this._expansionModel) {
727
- this._expansionModel.select(this._getExpansionKey(dataNode));
728
- }
729
- }
730
- /** Collapse the data node. If it is already collapsed, does nothing. */
731
- collapse(dataNode) {
732
- if (this.treeControl) {
733
- this.treeControl.collapse(dataNode);
734
- }
735
- else if (this._expansionModel) {
736
- this._expansionModel.deselect(this._getExpansionKey(dataNode));
737
- }
738
- }
739
- /**
740
- * If the data node is currently expanded, collapse it and all its descendants.
741
- * Otherwise, expand it and all its descendants.
742
- */
743
- toggleDescendants(dataNode) {
744
- if (this.treeControl) {
745
- this.treeControl.toggleDescendants(dataNode);
746
- }
747
- else if (this._expansionModel) {
748
- if (this.isExpanded(dataNode)) {
749
- this.collapseDescendants(dataNode);
750
- }
751
- else {
752
- this.expandDescendants(dataNode);
753
- }
754
- }
755
- }
756
- /**
757
- * Expand the data node and all its descendants. If they are already expanded, does nothing.
758
- */
759
- expandDescendants(dataNode) {
760
- if (this.treeControl) {
761
- this.treeControl.expandDescendants(dataNode);
762
- }
763
- else if (this._expansionModel) {
764
- const expansionModel = this._expansionModel;
765
- expansionModel.select(this._getExpansionKey(dataNode));
766
- this._getDescendants(dataNode)
767
- .pipe(take(1), takeUntil(this._onDestroy))
768
- .subscribe(children => {
769
- expansionModel.select(...children.map(child => this._getExpansionKey(child)));
770
- });
771
- }
772
- }
773
- /** Collapse the data node and all its descendants. If it is already collapsed, does nothing. */
774
- collapseDescendants(dataNode) {
775
- if (this.treeControl) {
776
- this.treeControl.collapseDescendants(dataNode);
777
- }
778
- else if (this._expansionModel) {
779
- const expansionModel = this._expansionModel;
780
- expansionModel.deselect(this._getExpansionKey(dataNode));
781
- this._getDescendants(dataNode)
782
- .pipe(take(1), takeUntil(this._onDestroy))
783
- .subscribe(children => {
784
- expansionModel.deselect(...children.map(child => this._getExpansionKey(child)));
785
- });
786
- }
787
- }
788
- /** Expands all data nodes in the tree. */
789
- expandAll() {
790
- if (this.treeControl) {
791
- this.treeControl.expandAll();
792
- }
793
- else if (this._expansionModel) {
794
- this._forEachExpansionKey(keys => this._expansionModel?.select(...keys));
795
- }
796
- }
797
- /** Collapse all data nodes in the tree. */
798
- collapseAll() {
799
- if (this.treeControl) {
800
- this.treeControl.collapseAll();
801
- }
802
- else if (this._expansionModel) {
803
- this._forEachExpansionKey(keys => this._expansionModel?.deselect(...keys));
804
- }
805
- }
806
- /** Level accessor, used for compatibility between the old Tree and new Tree */
807
- _getLevelAccessor() {
808
- return this.treeControl?.getLevel?.bind(this.treeControl) ?? this.levelAccessor;
809
- }
810
- /** Children accessor, used for compatibility between the old Tree and new Tree */
811
- _getChildrenAccessor() {
812
- return this.treeControl?.getChildren?.bind(this.treeControl) ?? this.childrenAccessor;
813
- }
814
- /**
815
- * Gets the direct children of a node; used for compatibility between the old tree and the
816
- * new tree.
817
- */
818
- _getDirectChildren(dataNode) {
819
- const levelAccessor = this._getLevelAccessor();
820
- const expansionModel = this._expansionModel ?? this.treeControl?.expansionModel;
821
- if (!expansionModel) {
822
- return of([]);
823
- }
824
- const key = this._getExpansionKey(dataNode);
825
- const isExpanded = expansionModel.changed.pipe(switchMap(changes => {
826
- if (changes.added.includes(key)) {
827
- return of(true);
828
- }
829
- else if (changes.removed.includes(key)) {
830
- return of(false);
831
- }
832
- return EMPTY;
833
- }), startWith(this.isExpanded(dataNode)));
834
- if (levelAccessor) {
835
- return combineLatest([isExpanded, this._flattenedNodes]).pipe(map(([expanded, flattenedNodes]) => {
836
- if (!expanded) {
837
- return [];
838
- }
839
- return this._findChildrenByLevel(levelAccessor, flattenedNodes, dataNode, 1);
840
- }));
841
- }
842
- const childrenAccessor = this._getChildrenAccessor();
843
- if (childrenAccessor) {
844
- return coerceObservable(childrenAccessor(dataNode) ?? []);
845
- }
367
+ }
368
+ return this._computeRenderingData(data, nodeType).pipe(map(convertedData => ({
369
+ ...convertedData,
370
+ nodeType
371
+ })));
372
+ }));
373
+ }
374
+ _renderDataChanges(data) {
375
+ if (data.nodeType === null) {
376
+ this.renderNodeChanges(data.renderNodes);
377
+ return;
378
+ }
379
+ this._updateCachedData(data.flattenedNodes);
380
+ this.renderNodeChanges(data.renderNodes);
381
+ this._updateKeyManagerItems(data.flattenedNodes);
382
+ }
383
+ _emitExpansionChanges(expansionChanges) {
384
+ if (!expansionChanges) {
385
+ return;
386
+ }
387
+ const nodes = this._nodes.value;
388
+ for (const added of expansionChanges.added) {
389
+ const node = nodes.get(added);
390
+ node?._emitExpansionState(true);
391
+ }
392
+ for (const removed of expansionChanges.removed) {
393
+ const node = nodes.get(removed);
394
+ node?._emitExpansionState(false);
395
+ }
396
+ }
397
+ _initializeKeyManager() {
398
+ const items = combineLatest([this._keyManagerNodes, this._nodes]).pipe(map(([keyManagerNodes, renderNodes]) => keyManagerNodes.reduce((items, data) => {
399
+ const node = renderNodes.get(this._getExpansionKey(data));
400
+ if (node) {
401
+ items.push(node);
402
+ }
403
+ return items;
404
+ }, [])));
405
+ const keyManagerOptions = {
406
+ trackBy: node => this._getExpansionKey(node.data),
407
+ skipPredicate: node => !!node.isDisabled,
408
+ typeAheadDebounceInterval: true,
409
+ horizontalOrientation: this._dir.value
410
+ };
411
+ this._keyManager = this._keyManagerFactory(items, keyManagerOptions);
412
+ }
413
+ _initializeDataDiffer() {
414
+ const trackBy = this.trackBy ?? ((_index, item) => this._getExpansionKey(item));
415
+ this._dataDiffer = this._differs.find([]).create(trackBy);
416
+ }
417
+ _checkTreeControlUsage() {
418
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
419
+ let numTreeControls = 0;
420
+ if (this.treeControl) {
421
+ numTreeControls++;
422
+ }
423
+ if (this.levelAccessor) {
424
+ numTreeControls++;
425
+ }
426
+ if (this.childrenAccessor) {
427
+ numTreeControls++;
428
+ }
429
+ if (!numTreeControls) {
846
430
  throw getTreeControlMissingError();
847
- }
848
- /**
849
- * Given the list of flattened nodes, the level accessor, and the level range within
850
- * which to consider children, finds the children for a given node.
851
- *
852
- * For example, for direct children, `levelDelta` would be 1. For all descendants,
853
- * `levelDelta` would be Infinity.
854
- */
855
- _findChildrenByLevel(levelAccessor, flattenedNodes, dataNode, levelDelta) {
856
- const key = this._getExpansionKey(dataNode);
857
- const startIndex = flattenedNodes.findIndex(node => this._getExpansionKey(node) === key);
858
- const dataNodeLevel = levelAccessor(dataNode);
859
- const expectedLevel = dataNodeLevel + levelDelta;
860
- const results = [];
861
- // Goes through flattened tree nodes in the `flattenedNodes` array, and get all
862
- // descendants within a certain level range.
863
- //
864
- // If we reach a node whose level is equal to or less than the level of the tree node,
865
- // we hit a sibling or parent's sibling, and should stop.
866
- for (let i = startIndex + 1; i < flattenedNodes.length; i++) {
867
- const currentLevel = levelAccessor(flattenedNodes[i]);
868
- if (currentLevel <= dataNodeLevel) {
869
- break;
870
- }
871
- if (currentLevel <= expectedLevel) {
872
- results.push(flattenedNodes[i]);
873
- }
874
- }
875
- return results;
876
- }
877
- /**
878
- * Adds the specified node component to the tree's internal registry.
879
- *
880
- * This primarily facilitates keyboard navigation.
881
- */
882
- _registerNode(node) {
883
- this._nodes.value.set(this._getExpansionKey(node.data), node);
884
- this._nodes.next(this._nodes.value);
885
- }
886
- /** Removes the specified node component from the tree's internal registry. */
887
- _unregisterNode(node) {
888
- this._nodes.value.delete(this._getExpansionKey(node.data));
889
- this._nodes.next(this._nodes.value);
890
- }
891
- /**
892
- * For the given node, determine the level where this node appears in the tree.
893
- *
894
- * This is intended to be used for `aria-level` but is 0-indexed.
895
- */
896
- _getLevel(node) {
897
- return this._levels.get(this._getExpansionKey(node));
898
- }
899
- /**
900
- * For the given node, determine the size of the parent's child set.
901
- *
902
- * This is intended to be used for `aria-setsize`.
903
- */
904
- _getSetSize(dataNode) {
905
- const set = this._getAriaSet(dataNode);
906
- return set.length;
907
- }
908
- /**
909
- * For the given node, determine the index (starting from 1) of the node in its parent's child set.
910
- *
911
- * This is intended to be used for `aria-posinset`.
912
- */
913
- _getPositionInSet(dataNode) {
914
- const set = this._getAriaSet(dataNode);
915
- const key = this._getExpansionKey(dataNode);
916
- return set.findIndex(node => this._getExpansionKey(node) === key) + 1;
917
- }
918
- /** Given a CdkTreeNode, gets the node that renders that node's parent's data. */
919
- _getNodeParent(node) {
920
- const parent = this._parents.get(this._getExpansionKey(node.data));
921
- return parent && this._nodes.value.get(this._getExpansionKey(parent));
922
- }
923
- /** Given a CdkTreeNode, gets the nodes that renders that node's child data. */
924
- _getNodeChildren(node) {
925
- return this._getDirectChildren(node.data).pipe(map(children => children.reduce((nodes, child) => {
926
- const value = this._nodes.value.get(this._getExpansionKey(child));
927
- if (value) {
928
- nodes.push(value);
929
- }
930
- return nodes;
931
- }, [])));
932
- }
933
- /** `keydown` event handler; this just passes the event to the `TreeKeyManager`. */
934
- _sendKeydownToKeyManager(event) {
935
- // Only handle events directly on the tree or directly on one of the nodes, otherwise
936
- // we risk interfering with events in the projected content (see #29828).
937
- if (event.target === this._elementRef.nativeElement) {
938
- this._keyManager.onKeydown(event);
939
- }
940
- else {
941
- const nodes = this._nodes.getValue();
942
- for (const [, node] of nodes) {
943
- if (event.target === node._elementRef.nativeElement) {
944
- this._keyManager.onKeydown(event);
945
- break;
946
- }
947
- }
948
- }
949
- }
950
- /** Gets all nested descendants of a given node. */
951
- _getDescendants(dataNode) {
952
- if (this.treeControl) {
953
- return of(this.treeControl.getDescendants(dataNode));
954
- }
955
- if (this.levelAccessor) {
956
- const results = this._findChildrenByLevel(this.levelAccessor, this._flattenedNodes.value, dataNode, Infinity);
957
- return of(results);
958
- }
959
- if (this.childrenAccessor) {
960
- return this._getAllChildrenRecursively(dataNode).pipe(reduce((allChildren, nextChildren) => {
961
- allChildren.push(...nextChildren);
962
- return allChildren;
963
- }, []));
964
- }
965
- throw getTreeControlMissingError();
966
- }
967
- /**
968
- * Gets all children and sub-children of the provided node.
969
- *
970
- * This will emit multiple times, in the order that the children will appear
971
- * in the tree, and can be combined with a `reduce` operator.
972
- */
973
- _getAllChildrenRecursively(dataNode) {
974
- if (!this.childrenAccessor) {
975
- return of([]);
976
- }
977
- return coerceObservable(this.childrenAccessor(dataNode)).pipe(take(1), switchMap(children => {
978
- // Here, we cache the parents of a particular child so that we can compute the levels.
979
- for (const child of children) {
980
- this._parents.set(this._getExpansionKey(child), dataNode);
981
- }
982
- return of(...children).pipe(concatMap(child => concat(of([child]), this._getAllChildrenRecursively(child))));
983
- }));
984
- }
985
- _getExpansionKey(dataNode) {
986
- // In the case that a key accessor function was not provided by the
987
- // tree user, we'll default to using the node object itself as the key.
988
- //
989
- // This cast is safe since:
990
- // - if an expansionKey is provided, TS will infer the type of K to be
991
- // the return type.
992
- // - if it's not, then K will be defaulted to T.
993
- return this.expansionKey?.(dataNode) ?? dataNode;
994
- }
995
- _getAriaSet(node) {
996
- const key = this._getExpansionKey(node);
997
- const parent = this._parents.get(key);
998
- const parentKey = parent ? this._getExpansionKey(parent) : null;
999
- const set = this._ariaSets.get(parentKey);
1000
- return set ?? [node];
1001
- }
1002
- /**
1003
- * Finds the parent for the given node. If this is a root node, this
1004
- * returns null. If we're unable to determine the parent, for example,
1005
- * if we don't have cached node data, this returns undefined.
1006
- */
1007
- _findParentForNode(node, index, cachedNodes) {
1008
- // In all cases, we have a mapping from node to level; all we need to do here is backtrack in
1009
- // our flattened list of nodes to determine the first node that's of a level lower than the
1010
- // provided node.
1011
- if (!cachedNodes.length) {
1012
- return null;
1013
- }
1014
- const currentLevel = this._levels.get(this._getExpansionKey(node)) ?? 0;
1015
- for (let parentIndex = index - 1; parentIndex >= 0; parentIndex--) {
1016
- const parentNode = cachedNodes[parentIndex];
1017
- const parentLevel = this._levels.get(this._getExpansionKey(parentNode)) ?? 0;
1018
- if (parentLevel < currentLevel) {
1019
- return parentNode;
1020
- }
1021
- }
1022
- return null;
1023
- }
1024
- /**
1025
- * Given a set of root nodes and the current node level, flattens any nested
1026
- * nodes into a single array.
1027
- *
1028
- * If any nodes are not expanded, then their children will not be added into the array.
1029
- * This will still traverse all nested children in order to build up our internal data
1030
- * models, but will not include them in the returned array.
1031
- */
1032
- _flattenNestedNodesWithExpansion(nodes, level = 0) {
1033
- const childrenAccessor = this._getChildrenAccessor();
1034
- // If we're using a level accessor, we don't need to flatten anything.
1035
- if (!childrenAccessor) {
1036
- return of([...nodes]);
1037
- }
1038
- return of(...nodes).pipe(concatMap(node => {
1039
- const parentKey = this._getExpansionKey(node);
1040
- if (!this._parents.has(parentKey)) {
1041
- this._parents.set(parentKey, null);
1042
- }
1043
- this._levels.set(parentKey, level);
1044
- const children = coerceObservable(childrenAccessor(node));
1045
- return concat(of([node]), children.pipe(take(1), tap(childNodes => {
1046
- this._ariaSets.set(parentKey, [...(childNodes ?? [])]);
1047
- for (const child of childNodes ?? []) {
1048
- const childKey = this._getExpansionKey(child);
1049
- this._parents.set(childKey, node);
1050
- this._levels.set(childKey, level + 1);
1051
- }
1052
- }), switchMap(childNodes => {
1053
- if (!childNodes) {
1054
- return of([]);
1055
- }
1056
- return this._flattenNestedNodesWithExpansion(childNodes, level + 1).pipe(map(nestedNodes => (this.isExpanded(node) ? nestedNodes : [])));
1057
- })));
1058
- }), reduce((results, children) => {
1059
- results.push(...children);
1060
- return results;
1061
- }, []));
1062
- }
1063
- /**
1064
- * Converts children for certain tree configurations.
1065
- *
1066
- * This also computes parent, level, and group data.
1067
- */
1068
- _computeRenderingData(nodes, nodeType) {
1069
- // The only situations where we have to convert children types is when
1070
- // they're mismatched; i.e. if the tree is using a childrenAccessor and the
1071
- // nodes are flat, or if the tree is using a levelAccessor and the nodes are
1072
- // nested.
1073
- if (this.childrenAccessor && nodeType === 'flat') {
1074
- // clear previously generated data so we don't keep end up retaining data overtime causing
1075
- // memory leaks.
1076
- this._clearPreviousCache();
1077
- // This flattens children into a single array.
1078
- this._ariaSets.set(null, [...nodes]);
1079
- return this._flattenNestedNodesWithExpansion(nodes).pipe(map(flattenedNodes => ({
1080
- renderNodes: flattenedNodes,
1081
- flattenedNodes,
1082
- })));
1083
- }
1084
- else if (this.levelAccessor && nodeType === 'nested') {
1085
- // In the nested case, we only look for root nodes. The CdkNestedNode
1086
- // itself will handle rendering each individual node's children.
1087
- const levelAccessor = this.levelAccessor;
1088
- return of(nodes.filter(node => levelAccessor(node) === 0)).pipe(map(rootNodes => ({
1089
- renderNodes: rootNodes,
1090
- flattenedNodes: nodes,
1091
- })), tap(({ flattenedNodes }) => {
1092
- this._calculateParents(flattenedNodes);
1093
- }));
1094
- }
1095
- else if (nodeType === 'flat') {
1096
- // In the case of a TreeControl, we know that the node type matches up
1097
- // with the TreeControl, and so no conversions are necessary. Otherwise,
1098
- // we've already confirmed that the data model matches up with the
1099
- // desired node type here.
1100
- return of({ renderNodes: nodes, flattenedNodes: nodes }).pipe(tap(({ flattenedNodes }) => {
1101
- this._calculateParents(flattenedNodes);
1102
- }));
1103
- }
1104
- else {
1105
- // clear previously generated data so we don't keep end up retaining data overtime causing
1106
- // memory leaks.
1107
- this._clearPreviousCache();
1108
- // For nested nodes, we still need to perform the node flattening in order
1109
- // to maintain our caches for various tree operations.
1110
- this._ariaSets.set(null, [...nodes]);
1111
- return this._flattenNestedNodesWithExpansion(nodes).pipe(map(flattenedNodes => ({
1112
- renderNodes: nodes,
1113
- flattenedNodes,
1114
- })));
1115
- }
1116
- }
1117
- _updateCachedData(flattenedNodes) {
1118
- this._flattenedNodes.next(flattenedNodes);
1119
- }
1120
- _updateKeyManagerItems(flattenedNodes) {
1121
- this._keyManagerNodes.next(flattenedNodes);
1122
- }
1123
- /** Traverse the flattened node data and compute parents, levels, and group data. */
1124
- _calculateParents(flattenedNodes) {
1125
- const levelAccessor = this._getLevelAccessor();
1126
- if (!levelAccessor) {
1127
- return;
1128
- }
1129
- // clear previously generated data so we don't keep end up retaining data overtime causing
1130
- // memory leaks.
1131
- this._clearPreviousCache();
1132
- for (let index = 0; index < flattenedNodes.length; index++) {
1133
- const dataNode = flattenedNodes[index];
1134
- const key = this._getExpansionKey(dataNode);
1135
- this._levels.set(key, levelAccessor(dataNode));
1136
- const parent = this._findParentForNode(dataNode, index, flattenedNodes);
1137
- this._parents.set(key, parent);
1138
- const parentKey = parent ? this._getExpansionKey(parent) : null;
1139
- const group = this._ariaSets.get(parentKey) ?? [];
1140
- group.splice(index, 0, dataNode);
1141
- this._ariaSets.set(parentKey, group);
1142
- }
1143
- }
1144
- /** Invokes a callback with all node expansion keys. */
1145
- _forEachExpansionKey(callback) {
1146
- const toToggle = [];
1147
- const observables = [];
1148
- this._nodes.value.forEach(node => {
1149
- toToggle.push(this._getExpansionKey(node.data));
1150
- observables.push(this._getDescendants(node.data));
1151
- });
1152
- if (observables.length > 0) {
1153
- combineLatest(observables)
1154
- .pipe(take(1), takeUntil(this._onDestroy))
1155
- .subscribe(results => {
1156
- results.forEach(inner => inner.forEach(r => toToggle.push(this._getExpansionKey(r))));
1157
- callback(toToggle);
1158
- });
1159
- }
1160
- else {
1161
- callback(toToggle);
1162
- }
1163
- }
1164
- /** Clears the maps we use to store parents, level & aria-sets in. */
1165
- _clearPreviousCache() {
1166
- this._parents.clear();
1167
- this._levels.clear();
1168
- this._ariaSets.clear();
1169
- }
1170
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTree, deps: [], target: i0.ɵɵFactoryTarget.Component });
1171
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.0-next.2", type: CdkTree, isStandalone: true, selector: "cdk-tree", inputs: { dataSource: "dataSource", treeControl: "treeControl", levelAccessor: "levelAccessor", childrenAccessor: "childrenAccessor", trackBy: "trackBy", expansionKey: "expansionKey" }, host: { attributes: { "role": "tree" }, listeners: { "keydown": "_sendKeydownToKeyManager($event)" }, classAttribute: "cdk-tree" }, queries: [{ propertyName: "_nodeDefs", predicate: CdkTreeNodeDef, descendants: true }], viewQueries: [{ propertyName: "_nodeOutlet", first: true, predicate: CdkTreeNodeOutlet, descendants: true, static: true }], exportAs: ["cdkTree"], ngImport: i0, template: `<ng-container cdkTreeNodeOutlet></ng-container>`, isInline: true, dependencies: [{ kind: "directive", type: CdkTreeNodeOutlet, selector: "[cdkTreeNodeOutlet]" }], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None });
431
+ } else if (numTreeControls > 1) {
432
+ throw getMultipleTreeControlsError();
433
+ }
434
+ }
435
+ }
436
+ renderNodeChanges(data, dataDiffer = this._dataDiffer, viewContainer = this._nodeOutlet.viewContainer, parentData) {
437
+ const changes = dataDiffer.diff(data);
438
+ if (!changes && !this._viewInit) {
439
+ return;
440
+ }
441
+ changes?.forEachOperation((item, adjustedPreviousIndex, currentIndex) => {
442
+ if (item.previousIndex == null) {
443
+ this.insertNode(data[currentIndex], currentIndex, viewContainer, parentData);
444
+ } else if (currentIndex == null) {
445
+ viewContainer.remove(adjustedPreviousIndex);
446
+ } else {
447
+ const view = viewContainer.get(adjustedPreviousIndex);
448
+ viewContainer.move(view, currentIndex);
449
+ }
450
+ });
451
+ changes?.forEachIdentityChange(record => {
452
+ const newData = record.item;
453
+ if (record.currentIndex != undefined) {
454
+ const view = viewContainer.get(record.currentIndex);
455
+ view.context.$implicit = newData;
456
+ }
457
+ });
458
+ if (parentData) {
459
+ this._changeDetectorRef.markForCheck();
460
+ } else {
461
+ this._changeDetectorRef.detectChanges();
462
+ }
463
+ }
464
+ _getNodeDef(data, i) {
465
+ if (this._nodeDefs.length === 1) {
466
+ return this._nodeDefs.first;
467
+ }
468
+ const nodeDef = this._nodeDefs.find(def => def.when && def.when(i, data)) || this._defaultNodeDef;
469
+ if (!nodeDef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
470
+ throw getTreeMissingMatchingNodeDefError();
471
+ }
472
+ return nodeDef;
473
+ }
474
+ insertNode(nodeData, index, viewContainer, parentData) {
475
+ const levelAccessor = this._getLevelAccessor();
476
+ const node = this._getNodeDef(nodeData, index);
477
+ const key = this._getExpansionKey(nodeData);
478
+ const context = new CdkTreeNodeOutletContext(nodeData);
479
+ context.index = index;
480
+ parentData ??= this._parents.get(key) ?? undefined;
481
+ if (levelAccessor) {
482
+ context.level = levelAccessor(nodeData);
483
+ } else if (parentData !== undefined && this._levels.has(this._getExpansionKey(parentData))) {
484
+ context.level = this._levels.get(this._getExpansionKey(parentData)) + 1;
485
+ } else {
486
+ context.level = 0;
487
+ }
488
+ this._levels.set(key, context.level);
489
+ const container = viewContainer ? viewContainer : this._nodeOutlet.viewContainer;
490
+ container.createEmbeddedView(node.template, context, index);
491
+ if (CdkTreeNode.mostRecentTreeNode) {
492
+ CdkTreeNode.mostRecentTreeNode.data = nodeData;
493
+ }
494
+ }
495
+ isExpanded(dataNode) {
496
+ return !!(this.treeControl?.isExpanded(dataNode) || this._expansionModel?.isSelected(this._getExpansionKey(dataNode)));
497
+ }
498
+ toggle(dataNode) {
499
+ if (this.treeControl) {
500
+ this.treeControl.toggle(dataNode);
501
+ } else if (this._expansionModel) {
502
+ this._expansionModel.toggle(this._getExpansionKey(dataNode));
503
+ }
504
+ }
505
+ expand(dataNode) {
506
+ if (this.treeControl) {
507
+ this.treeControl.expand(dataNode);
508
+ } else if (this._expansionModel) {
509
+ this._expansionModel.select(this._getExpansionKey(dataNode));
510
+ }
511
+ }
512
+ collapse(dataNode) {
513
+ if (this.treeControl) {
514
+ this.treeControl.collapse(dataNode);
515
+ } else if (this._expansionModel) {
516
+ this._expansionModel.deselect(this._getExpansionKey(dataNode));
517
+ }
518
+ }
519
+ toggleDescendants(dataNode) {
520
+ if (this.treeControl) {
521
+ this.treeControl.toggleDescendants(dataNode);
522
+ } else if (this._expansionModel) {
523
+ if (this.isExpanded(dataNode)) {
524
+ this.collapseDescendants(dataNode);
525
+ } else {
526
+ this.expandDescendants(dataNode);
527
+ }
528
+ }
529
+ }
530
+ expandDescendants(dataNode) {
531
+ if (this.treeControl) {
532
+ this.treeControl.expandDescendants(dataNode);
533
+ } else if (this._expansionModel) {
534
+ const expansionModel = this._expansionModel;
535
+ expansionModel.select(this._getExpansionKey(dataNode));
536
+ this._getDescendants(dataNode).pipe(take(1), takeUntil(this._onDestroy)).subscribe(children => {
537
+ expansionModel.select(...children.map(child => this._getExpansionKey(child)));
538
+ });
539
+ }
540
+ }
541
+ collapseDescendants(dataNode) {
542
+ if (this.treeControl) {
543
+ this.treeControl.collapseDescendants(dataNode);
544
+ } else if (this._expansionModel) {
545
+ const expansionModel = this._expansionModel;
546
+ expansionModel.deselect(this._getExpansionKey(dataNode));
547
+ this._getDescendants(dataNode).pipe(take(1), takeUntil(this._onDestroy)).subscribe(children => {
548
+ expansionModel.deselect(...children.map(child => this._getExpansionKey(child)));
549
+ });
550
+ }
551
+ }
552
+ expandAll() {
553
+ if (this.treeControl) {
554
+ this.treeControl.expandAll();
555
+ } else if (this._expansionModel) {
556
+ this._forEachExpansionKey(keys => this._expansionModel?.select(...keys));
557
+ }
558
+ }
559
+ collapseAll() {
560
+ if (this.treeControl) {
561
+ this.treeControl.collapseAll();
562
+ } else if (this._expansionModel) {
563
+ this._forEachExpansionKey(keys => this._expansionModel?.deselect(...keys));
564
+ }
565
+ }
566
+ _getLevelAccessor() {
567
+ return this.treeControl?.getLevel?.bind(this.treeControl) ?? this.levelAccessor;
568
+ }
569
+ _getChildrenAccessor() {
570
+ return this.treeControl?.getChildren?.bind(this.treeControl) ?? this.childrenAccessor;
571
+ }
572
+ _getDirectChildren(dataNode) {
573
+ const levelAccessor = this._getLevelAccessor();
574
+ const expansionModel = this._expansionModel ?? this.treeControl?.expansionModel;
575
+ if (!expansionModel) {
576
+ return of([]);
577
+ }
578
+ const key = this._getExpansionKey(dataNode);
579
+ const isExpanded = expansionModel.changed.pipe(switchMap(changes => {
580
+ if (changes.added.includes(key)) {
581
+ return of(true);
582
+ } else if (changes.removed.includes(key)) {
583
+ return of(false);
584
+ }
585
+ return EMPTY;
586
+ }), startWith(this.isExpanded(dataNode)));
587
+ if (levelAccessor) {
588
+ return combineLatest([isExpanded, this._flattenedNodes]).pipe(map(([expanded, flattenedNodes]) => {
589
+ if (!expanded) {
590
+ return [];
591
+ }
592
+ return this._findChildrenByLevel(levelAccessor, flattenedNodes, dataNode, 1);
593
+ }));
594
+ }
595
+ const childrenAccessor = this._getChildrenAccessor();
596
+ if (childrenAccessor) {
597
+ return coerceObservable(childrenAccessor(dataNode) ?? []);
598
+ }
599
+ throw getTreeControlMissingError();
600
+ }
601
+ _findChildrenByLevel(levelAccessor, flattenedNodes, dataNode, levelDelta) {
602
+ const key = this._getExpansionKey(dataNode);
603
+ const startIndex = flattenedNodes.findIndex(node => this._getExpansionKey(node) === key);
604
+ const dataNodeLevel = levelAccessor(dataNode);
605
+ const expectedLevel = dataNodeLevel + levelDelta;
606
+ const results = [];
607
+ for (let i = startIndex + 1; i < flattenedNodes.length; i++) {
608
+ const currentLevel = levelAccessor(flattenedNodes[i]);
609
+ if (currentLevel <= dataNodeLevel) {
610
+ break;
611
+ }
612
+ if (currentLevel <= expectedLevel) {
613
+ results.push(flattenedNodes[i]);
614
+ }
615
+ }
616
+ return results;
617
+ }
618
+ _registerNode(node) {
619
+ this._nodes.value.set(this._getExpansionKey(node.data), node);
620
+ this._nodes.next(this._nodes.value);
621
+ }
622
+ _unregisterNode(node) {
623
+ this._nodes.value.delete(this._getExpansionKey(node.data));
624
+ this._nodes.next(this._nodes.value);
625
+ }
626
+ _getLevel(node) {
627
+ return this._levels.get(this._getExpansionKey(node));
628
+ }
629
+ _getSetSize(dataNode) {
630
+ const set = this._getAriaSet(dataNode);
631
+ return set.length;
632
+ }
633
+ _getPositionInSet(dataNode) {
634
+ const set = this._getAriaSet(dataNode);
635
+ const key = this._getExpansionKey(dataNode);
636
+ return set.findIndex(node => this._getExpansionKey(node) === key) + 1;
637
+ }
638
+ _getNodeParent(node) {
639
+ const parent = this._parents.get(this._getExpansionKey(node.data));
640
+ return parent && this._nodes.value.get(this._getExpansionKey(parent));
641
+ }
642
+ _getNodeChildren(node) {
643
+ return this._getDirectChildren(node.data).pipe(map(children => children.reduce((nodes, child) => {
644
+ const value = this._nodes.value.get(this._getExpansionKey(child));
645
+ if (value) {
646
+ nodes.push(value);
647
+ }
648
+ return nodes;
649
+ }, [])));
650
+ }
651
+ _sendKeydownToKeyManager(event) {
652
+ if (event.target === this._elementRef.nativeElement) {
653
+ this._keyManager.onKeydown(event);
654
+ } else {
655
+ const nodes = this._nodes.getValue();
656
+ for (const [, node] of nodes) {
657
+ if (event.target === node._elementRef.nativeElement) {
658
+ this._keyManager.onKeydown(event);
659
+ break;
660
+ }
661
+ }
662
+ }
663
+ }
664
+ _getDescendants(dataNode) {
665
+ if (this.treeControl) {
666
+ return of(this.treeControl.getDescendants(dataNode));
667
+ }
668
+ if (this.levelAccessor) {
669
+ const results = this._findChildrenByLevel(this.levelAccessor, this._flattenedNodes.value, dataNode, Infinity);
670
+ return of(results);
671
+ }
672
+ if (this.childrenAccessor) {
673
+ return this._getAllChildrenRecursively(dataNode).pipe(reduce((allChildren, nextChildren) => {
674
+ allChildren.push(...nextChildren);
675
+ return allChildren;
676
+ }, []));
677
+ }
678
+ throw getTreeControlMissingError();
679
+ }
680
+ _getAllChildrenRecursively(dataNode) {
681
+ if (!this.childrenAccessor) {
682
+ return of([]);
683
+ }
684
+ return coerceObservable(this.childrenAccessor(dataNode)).pipe(take(1), switchMap(children => {
685
+ for (const child of children) {
686
+ this._parents.set(this._getExpansionKey(child), dataNode);
687
+ }
688
+ return of(...children).pipe(concatMap(child => concat(of([child]), this._getAllChildrenRecursively(child))));
689
+ }));
690
+ }
691
+ _getExpansionKey(dataNode) {
692
+ return this.expansionKey?.(dataNode) ?? dataNode;
693
+ }
694
+ _getAriaSet(node) {
695
+ const key = this._getExpansionKey(node);
696
+ const parent = this._parents.get(key);
697
+ const parentKey = parent ? this._getExpansionKey(parent) : null;
698
+ const set = this._ariaSets.get(parentKey);
699
+ return set ?? [node];
700
+ }
701
+ _findParentForNode(node, index, cachedNodes) {
702
+ if (!cachedNodes.length) {
703
+ return null;
704
+ }
705
+ const currentLevel = this._levels.get(this._getExpansionKey(node)) ?? 0;
706
+ for (let parentIndex = index - 1; parentIndex >= 0; parentIndex--) {
707
+ const parentNode = cachedNodes[parentIndex];
708
+ const parentLevel = this._levels.get(this._getExpansionKey(parentNode)) ?? 0;
709
+ if (parentLevel < currentLevel) {
710
+ return parentNode;
711
+ }
712
+ }
713
+ return null;
714
+ }
715
+ _flattenNestedNodesWithExpansion(nodes, level = 0) {
716
+ const childrenAccessor = this._getChildrenAccessor();
717
+ if (!childrenAccessor) {
718
+ return of([...nodes]);
719
+ }
720
+ return of(...nodes).pipe(concatMap(node => {
721
+ const parentKey = this._getExpansionKey(node);
722
+ if (!this._parents.has(parentKey)) {
723
+ this._parents.set(parentKey, null);
724
+ }
725
+ this._levels.set(parentKey, level);
726
+ const children = coerceObservable(childrenAccessor(node));
727
+ return concat(of([node]), children.pipe(take(1), tap(childNodes => {
728
+ this._ariaSets.set(parentKey, [...(childNodes ?? [])]);
729
+ for (const child of childNodes ?? []) {
730
+ const childKey = this._getExpansionKey(child);
731
+ this._parents.set(childKey, node);
732
+ this._levels.set(childKey, level + 1);
733
+ }
734
+ }), switchMap(childNodes => {
735
+ if (!childNodes) {
736
+ return of([]);
737
+ }
738
+ return this._flattenNestedNodesWithExpansion(childNodes, level + 1).pipe(map(nestedNodes => this.isExpanded(node) ? nestedNodes : []));
739
+ })));
740
+ }), reduce((results, children) => {
741
+ results.push(...children);
742
+ return results;
743
+ }, []));
744
+ }
745
+ _computeRenderingData(nodes, nodeType) {
746
+ if (this.childrenAccessor && nodeType === 'flat') {
747
+ this._clearPreviousCache();
748
+ this._ariaSets.set(null, [...nodes]);
749
+ return this._flattenNestedNodesWithExpansion(nodes).pipe(map(flattenedNodes => ({
750
+ renderNodes: flattenedNodes,
751
+ flattenedNodes
752
+ })));
753
+ } else if (this.levelAccessor && nodeType === 'nested') {
754
+ const levelAccessor = this.levelAccessor;
755
+ return of(nodes.filter(node => levelAccessor(node) === 0)).pipe(map(rootNodes => ({
756
+ renderNodes: rootNodes,
757
+ flattenedNodes: nodes
758
+ })), tap(({
759
+ flattenedNodes
760
+ }) => {
761
+ this._calculateParents(flattenedNodes);
762
+ }));
763
+ } else if (nodeType === 'flat') {
764
+ return of({
765
+ renderNodes: nodes,
766
+ flattenedNodes: nodes
767
+ }).pipe(tap(({
768
+ flattenedNodes
769
+ }) => {
770
+ this._calculateParents(flattenedNodes);
771
+ }));
772
+ } else {
773
+ this._clearPreviousCache();
774
+ this._ariaSets.set(null, [...nodes]);
775
+ return this._flattenNestedNodesWithExpansion(nodes).pipe(map(flattenedNodes => ({
776
+ renderNodes: nodes,
777
+ flattenedNodes
778
+ })));
779
+ }
780
+ }
781
+ _updateCachedData(flattenedNodes) {
782
+ this._flattenedNodes.next(flattenedNodes);
783
+ }
784
+ _updateKeyManagerItems(flattenedNodes) {
785
+ this._keyManagerNodes.next(flattenedNodes);
786
+ }
787
+ _calculateParents(flattenedNodes) {
788
+ const levelAccessor = this._getLevelAccessor();
789
+ if (!levelAccessor) {
790
+ return;
791
+ }
792
+ this._clearPreviousCache();
793
+ for (let index = 0; index < flattenedNodes.length; index++) {
794
+ const dataNode = flattenedNodes[index];
795
+ const key = this._getExpansionKey(dataNode);
796
+ this._levels.set(key, levelAccessor(dataNode));
797
+ const parent = this._findParentForNode(dataNode, index, flattenedNodes);
798
+ this._parents.set(key, parent);
799
+ const parentKey = parent ? this._getExpansionKey(parent) : null;
800
+ const group = this._ariaSets.get(parentKey) ?? [];
801
+ group.splice(index, 0, dataNode);
802
+ this._ariaSets.set(parentKey, group);
803
+ }
804
+ }
805
+ _forEachExpansionKey(callback) {
806
+ const toToggle = [];
807
+ const observables = [];
808
+ this._nodes.value.forEach(node => {
809
+ toToggle.push(this._getExpansionKey(node.data));
810
+ observables.push(this._getDescendants(node.data));
811
+ });
812
+ if (observables.length > 0) {
813
+ combineLatest(observables).pipe(take(1), takeUntil(this._onDestroy)).subscribe(results => {
814
+ results.forEach(inner => inner.forEach(r => toToggle.push(this._getExpansionKey(r))));
815
+ callback(toToggle);
816
+ });
817
+ } else {
818
+ callback(toToggle);
819
+ }
820
+ }
821
+ _clearPreviousCache() {
822
+ this._parents.clear();
823
+ this._levels.clear();
824
+ this._ariaSets.clear();
825
+ }
826
+ static ɵfac = i0.ɵɵngDeclareFactory({
827
+ minVersion: "12.0.0",
828
+ version: "20.2.0-next.2",
829
+ ngImport: i0,
830
+ type: CdkTree,
831
+ deps: [],
832
+ target: i0.ɵɵFactoryTarget.Component
833
+ });
834
+ static ɵcmp = i0.ɵɵngDeclareComponent({
835
+ minVersion: "14.0.0",
836
+ version: "20.2.0-next.2",
837
+ type: CdkTree,
838
+ isStandalone: true,
839
+ selector: "cdk-tree",
840
+ inputs: {
841
+ dataSource: "dataSource",
842
+ treeControl: "treeControl",
843
+ levelAccessor: "levelAccessor",
844
+ childrenAccessor: "childrenAccessor",
845
+ trackBy: "trackBy",
846
+ expansionKey: "expansionKey"
847
+ },
848
+ host: {
849
+ attributes: {
850
+ "role": "tree"
851
+ },
852
+ listeners: {
853
+ "keydown": "_sendKeydownToKeyManager($event)"
854
+ },
855
+ classAttribute: "cdk-tree"
856
+ },
857
+ queries: [{
858
+ propertyName: "_nodeDefs",
859
+ predicate: CdkTreeNodeDef,
860
+ descendants: true
861
+ }],
862
+ viewQueries: [{
863
+ propertyName: "_nodeOutlet",
864
+ first: true,
865
+ predicate: CdkTreeNodeOutlet,
866
+ descendants: true,
867
+ static: true
868
+ }],
869
+ exportAs: ["cdkTree"],
870
+ ngImport: i0,
871
+ template: `<ng-container cdkTreeNodeOutlet></ng-container>`,
872
+ isInline: true,
873
+ dependencies: [{
874
+ kind: "directive",
875
+ type: CdkTreeNodeOutlet,
876
+ selector: "[cdkTreeNodeOutlet]"
877
+ }],
878
+ changeDetection: i0.ChangeDetectionStrategy.Default,
879
+ encapsulation: i0.ViewEncapsulation.None
880
+ });
1172
881
  }
1173
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTree, decorators: [{
1174
- type: Component,
1175
- args: [{
1176
- selector: 'cdk-tree',
1177
- exportAs: 'cdkTree',
1178
- template: `<ng-container cdkTreeNodeOutlet></ng-container>`,
1179
- host: {
1180
- 'class': 'cdk-tree',
1181
- 'role': 'tree',
1182
- '(keydown)': '_sendKeydownToKeyManager($event)',
1183
- },
1184
- encapsulation: ViewEncapsulation.None,
1185
- // The "OnPush" status for the `CdkTree` component is effectively a noop, so we are removing it.
1186
- // The view for `CdkTree` consists entirely of templates declared in other views. As they are
1187
- // declared elsewhere, they are checked when their declaration points are checked.
1188
- // tslint:disable-next-line:validate-decorators
1189
- changeDetection: ChangeDetectionStrategy.Default,
1190
- imports: [CdkTreeNodeOutlet],
1191
- }]
1192
- }], ctorParameters: () => [], propDecorators: { dataSource: [{
1193
- type: Input
1194
- }], treeControl: [{
1195
- type: Input
1196
- }], levelAccessor: [{
1197
- type: Input
1198
- }], childrenAccessor: [{
1199
- type: Input
1200
- }], trackBy: [{
1201
- type: Input
1202
- }], expansionKey: [{
1203
- type: Input
1204
- }], _nodeOutlet: [{
1205
- type: ViewChild,
1206
- args: [CdkTreeNodeOutlet, { static: true }]
1207
- }], _nodeDefs: [{
1208
- type: ContentChildren,
1209
- args: [CdkTreeNodeDef, {
1210
- // We need to use `descendants: true`, because Ivy will no longer match
1211
- // indirect descendants if it's left as false.
1212
- descendants: true,
1213
- }]
1214
- }] } });
1215
- /**
1216
- * Tree node for CdkTree. It contains the data in the tree node.
1217
- */
882
+ i0.ɵɵngDeclareClassMetadata({
883
+ minVersion: "12.0.0",
884
+ version: "20.2.0-next.2",
885
+ ngImport: i0,
886
+ type: CdkTree,
887
+ decorators: [{
888
+ type: Component,
889
+ args: [{
890
+ selector: 'cdk-tree',
891
+ exportAs: 'cdkTree',
892
+ template: `<ng-container cdkTreeNodeOutlet></ng-container>`,
893
+ host: {
894
+ 'class': 'cdk-tree',
895
+ 'role': 'tree',
896
+ '(keydown)': '_sendKeydownToKeyManager($event)'
897
+ },
898
+ encapsulation: ViewEncapsulation.None,
899
+ changeDetection: ChangeDetectionStrategy.Default,
900
+ imports: [CdkTreeNodeOutlet]
901
+ }]
902
+ }],
903
+ ctorParameters: () => [],
904
+ propDecorators: {
905
+ dataSource: [{
906
+ type: Input
907
+ }],
908
+ treeControl: [{
909
+ type: Input
910
+ }],
911
+ levelAccessor: [{
912
+ type: Input
913
+ }],
914
+ childrenAccessor: [{
915
+ type: Input
916
+ }],
917
+ trackBy: [{
918
+ type: Input
919
+ }],
920
+ expansionKey: [{
921
+ type: Input
922
+ }],
923
+ _nodeOutlet: [{
924
+ type: ViewChild,
925
+ args: [CdkTreeNodeOutlet, {
926
+ static: true
927
+ }]
928
+ }],
929
+ _nodeDefs: [{
930
+ type: ContentChildren,
931
+ args: [CdkTreeNodeDef, {
932
+ descendants: true
933
+ }]
934
+ }]
935
+ }
936
+ });
1218
937
  class CdkTreeNode {
1219
- _elementRef = inject(ElementRef);
1220
- _tree = inject(CdkTree);
1221
- _tabindex = -1;
1222
- _type = 'flat';
1223
- /**
1224
- * The role of the tree node.
1225
- *
1226
- * @deprecated This will be ignored; the tree will automatically determine the appropriate role
1227
- * for tree node. This input will be removed in a future version.
1228
- * @breaking-change 21.0.0
1229
- */
1230
- get role() {
1231
- return 'treeitem';
1232
- }
1233
- set role(_role) {
1234
- // ignore any role setting, we handle this internally.
1235
- }
1236
- /**
1237
- * Whether or not this node is expandable.
1238
- *
1239
- * If not using `FlatTreeControl`, or if `isExpandable` is not provided to
1240
- * `NestedTreeControl`, this should be provided for correct node a11y.
1241
- */
1242
- get isExpandable() {
1243
- return this._isExpandable();
1244
- }
1245
- set isExpandable(isExpandable) {
1246
- this._inputIsExpandable = isExpandable;
1247
- if ((this.data && !this._isExpandable) || !this._inputIsExpandable) {
1248
- return;
1249
- }
1250
- // If the node is being set to expandable, ensure that the status of the
1251
- // node is propagated
1252
- if (this._inputIsExpanded) {
1253
- this.expand();
1254
- }
1255
- else if (this._inputIsExpanded === false) {
1256
- this.collapse();
1257
- }
1258
- }
1259
- get isExpanded() {
1260
- return this._tree.isExpanded(this._data);
1261
- }
1262
- set isExpanded(isExpanded) {
1263
- this._inputIsExpanded = isExpanded;
1264
- if (isExpanded) {
1265
- this.expand();
1266
- }
1267
- else {
1268
- this.collapse();
1269
- }
1270
- }
1271
- /**
1272
- * Whether or not this node is disabled. If it's disabled, then the user won't be able to focus
1273
- * or activate this node.
1274
- */
1275
- isDisabled;
1276
- /**
1277
- * The text used to locate this item during typeahead. If not specified, the `textContent` will
1278
- * will be used.
1279
- */
1280
- typeaheadLabel;
1281
- getLabel() {
1282
- return this.typeaheadLabel || this._elementRef.nativeElement.textContent?.trim() || '';
1283
- }
1284
- /** This emits when the node has been programatically activated or activated by keyboard. */
1285
- activation = new EventEmitter();
1286
- /** This emits when the node's expansion status has been changed. */
1287
- expandedChange = new EventEmitter();
1288
- /**
1289
- * The most recently created `CdkTreeNode`. We save it in static variable so we can retrieve it
1290
- * in `CdkTree` and set the data to it.
1291
- */
1292
- static mostRecentTreeNode = null;
1293
- /** Subject that emits when the component has been destroyed. */
1294
- _destroyed = new Subject();
1295
- /** Emits when the node's data has changed. */
1296
- _dataChanges = new Subject();
1297
- _inputIsExpandable = false;
1298
- _inputIsExpanded = undefined;
1299
- /**
1300
- * Flag used to determine whether or not we should be focusing the actual element based on
1301
- * some user interaction (click or focus). On click, we don't forcibly focus the element
1302
- * since the click could trigger some other component that wants to grab its own focus
1303
- * (e.g. menu, dialog).
1304
- */
1305
- _shouldFocus = true;
1306
- _parentNodeAriaLevel;
1307
- /** The tree node's data. */
1308
- get data() {
1309
- return this._data;
1310
- }
1311
- set data(value) {
1312
- if (value !== this._data) {
1313
- this._data = value;
1314
- this._dataChanges.next();
1315
- }
1316
- }
1317
- _data;
1318
- /* If leaf node, return true to not assign aria-expanded attribute */
1319
- get isLeafNode() {
1320
- // If flat tree node data returns false for expandable property, it's a leaf node
1321
- if (this._tree.treeControl?.isExpandable !== undefined &&
1322
- !this._tree.treeControl.isExpandable(this._data)) {
1323
- return true;
1324
- // If nested tree node data returns 0 descendants, it's a leaf node
1325
- }
1326
- else if (this._tree.treeControl?.isExpandable === undefined &&
1327
- this._tree.treeControl?.getDescendants(this._data).length === 0) {
1328
- return true;
1329
- }
938
+ _elementRef = inject(ElementRef);
939
+ _tree = inject(CdkTree);
940
+ _tabindex = -1;
941
+ _type = 'flat';
942
+ get role() {
943
+ return 'treeitem';
944
+ }
945
+ set role(_role) {}
946
+ get isExpandable() {
947
+ return this._isExpandable();
948
+ }
949
+ set isExpandable(isExpandable) {
950
+ this._inputIsExpandable = isExpandable;
951
+ if (this.data && !this._isExpandable || !this._inputIsExpandable) {
952
+ return;
953
+ }
954
+ if (this._inputIsExpanded) {
955
+ this.expand();
956
+ } else if (this._inputIsExpanded === false) {
957
+ this.collapse();
958
+ }
959
+ }
960
+ get isExpanded() {
961
+ return this._tree.isExpanded(this._data);
962
+ }
963
+ set isExpanded(isExpanded) {
964
+ this._inputIsExpanded = isExpanded;
965
+ if (isExpanded) {
966
+ this.expand();
967
+ } else {
968
+ this.collapse();
969
+ }
970
+ }
971
+ isDisabled;
972
+ typeaheadLabel;
973
+ getLabel() {
974
+ return this.typeaheadLabel || this._elementRef.nativeElement.textContent?.trim() || '';
975
+ }
976
+ activation = new EventEmitter();
977
+ expandedChange = new EventEmitter();
978
+ static mostRecentTreeNode = null;
979
+ _destroyed = new Subject();
980
+ _dataChanges = new Subject();
981
+ _inputIsExpandable = false;
982
+ _inputIsExpanded = undefined;
983
+ _shouldFocus = true;
984
+ _parentNodeAriaLevel;
985
+ get data() {
986
+ return this._data;
987
+ }
988
+ set data(value) {
989
+ if (value !== this._data) {
990
+ this._data = value;
991
+ this._dataChanges.next();
992
+ }
993
+ }
994
+ _data;
995
+ get isLeafNode() {
996
+ if (this._tree.treeControl?.isExpandable !== undefined && !this._tree.treeControl.isExpandable(this._data)) {
997
+ return true;
998
+ } else if (this._tree.treeControl?.isExpandable === undefined && this._tree.treeControl?.getDescendants(this._data).length === 0) {
999
+ return true;
1000
+ }
1001
+ return false;
1002
+ }
1003
+ get level() {
1004
+ return this._tree._getLevel(this._data) ?? this._parentNodeAriaLevel;
1005
+ }
1006
+ _isExpandable() {
1007
+ if (this._tree.treeControl) {
1008
+ if (this.isLeafNode) {
1330
1009
  return false;
1331
- }
1332
- get level() {
1333
- // If the tree has a levelAccessor, use it to get the level. Otherwise read the
1334
- // aria-level off the parent node and use it as the level for this node (note aria-level is
1335
- // 1-indexed, while this property is 0-indexed, so we don't need to increment).
1336
- return this._tree._getLevel(this._data) ?? this._parentNodeAriaLevel;
1337
- }
1338
- /** Determines if the tree node is expandable. */
1339
- _isExpandable() {
1340
- if (this._tree.treeControl) {
1341
- if (this.isLeafNode) {
1342
- return false;
1343
- }
1344
- // For compatibility with trees created using TreeControl before we added
1345
- // CdkTreeNode#isExpandable.
1346
- return true;
1347
- }
1348
- return this._inputIsExpandable;
1349
- }
1350
- /**
1351
- * Determines the value for `aria-expanded`.
1352
- *
1353
- * For non-expandable nodes, this is `null`.
1354
- */
1355
- _getAriaExpanded() {
1356
- if (!this._isExpandable()) {
1357
- return null;
1358
- }
1359
- return String(this.isExpanded);
1360
- }
1361
- /**
1362
- * Determines the size of this node's parent's child set.
1363
- *
1364
- * This is intended to be used for `aria-setsize`.
1365
- */
1366
- _getSetSize() {
1367
- return this._tree._getSetSize(this._data);
1368
- }
1369
- /**
1370
- * Determines the index (starting from 1) of this node in its parent's child set.
1371
- *
1372
- * This is intended to be used for `aria-posinset`.
1373
- */
1374
- _getPositionInSet() {
1375
- return this._tree._getPositionInSet(this._data);
1376
- }
1377
- _changeDetectorRef = inject(ChangeDetectorRef);
1378
- constructor() {
1379
- CdkTreeNode.mostRecentTreeNode = this;
1380
- }
1381
- ngOnInit() {
1382
- this._parentNodeAriaLevel = getParentNodeAriaLevel(this._elementRef.nativeElement);
1383
- this._tree
1384
- ._getExpansionModel()
1385
- .changed.pipe(map(() => this.isExpanded), distinctUntilChanged(), takeUntil(this._destroyed))
1386
- .pipe(takeUntil(this._destroyed))
1387
- .subscribe(() => this._changeDetectorRef.markForCheck());
1388
- this._tree._setNodeTypeIfUnset(this._type);
1389
- this._tree._registerNode(this);
1390
- }
1391
- ngOnDestroy() {
1392
- // If this is the last tree node being destroyed,
1393
- // clear out the reference to avoid leaking memory.
1394
- if (CdkTreeNode.mostRecentTreeNode === this) {
1395
- CdkTreeNode.mostRecentTreeNode = null;
1396
- }
1397
- this._dataChanges.complete();
1398
- this._destroyed.next();
1399
- this._destroyed.complete();
1400
- }
1401
- getParent() {
1402
- return this._tree._getNodeParent(this) ?? null;
1403
- }
1404
- getChildren() {
1405
- return this._tree._getNodeChildren(this);
1406
- }
1407
- /** Focuses this data node. Implemented for TreeKeyManagerItem. */
1408
- focus() {
1409
- this._tabindex = 0;
1410
- if (this._shouldFocus) {
1411
- this._elementRef.nativeElement.focus();
1412
- }
1413
- this._changeDetectorRef.markForCheck();
1414
- }
1415
- /** Defocus this data node. */
1416
- unfocus() {
1417
- this._tabindex = -1;
1418
- this._changeDetectorRef.markForCheck();
1419
- }
1420
- /** Emits an activation event. Implemented for TreeKeyManagerItem. */
1421
- activate() {
1422
- if (this.isDisabled) {
1423
- return;
1424
- }
1425
- this.activation.next(this._data);
1426
- }
1427
- /** Collapses this data node. Implemented for TreeKeyManagerItem. */
1428
- collapse() {
1429
- if (this.isExpandable) {
1430
- this._tree.collapse(this._data);
1431
- }
1432
- }
1433
- /** Expands this data node. Implemented for TreeKeyManagerItem. */
1434
- expand() {
1435
- if (this.isExpandable) {
1436
- this._tree.expand(this._data);
1437
- }
1438
- }
1439
- /** Makes the node focusable. Implemented for TreeKeyManagerItem. */
1440
- makeFocusable() {
1441
- this._tabindex = 0;
1442
- this._changeDetectorRef.markForCheck();
1443
- }
1444
- _focusItem() {
1445
- if (this.isDisabled) {
1446
- return;
1447
- }
1448
- this._tree._keyManager.focusItem(this);
1449
- }
1450
- _setActiveItem() {
1451
- if (this.isDisabled) {
1452
- return;
1453
- }
1454
- this._shouldFocus = false;
1455
- this._tree._keyManager.focusItem(this);
1456
- this._shouldFocus = true;
1457
- }
1458
- _emitExpansionState(expanded) {
1459
- this.expandedChange.emit(expanded);
1460
- }
1461
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNode, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1462
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.2.0-next.2", type: CdkTreeNode, isStandalone: true, selector: "cdk-tree-node", inputs: { role: "role", isExpandable: ["isExpandable", "isExpandable", booleanAttribute], isExpanded: "isExpanded", isDisabled: ["isDisabled", "isDisabled", booleanAttribute], typeaheadLabel: ["cdkTreeNodeTypeaheadLabel", "typeaheadLabel"] }, outputs: { activation: "activation", expandedChange: "expandedChange" }, host: { attributes: { "role": "treeitem" }, listeners: { "click": "_setActiveItem()", "focus": "_focusItem()" }, properties: { "attr.aria-expanded": "_getAriaExpanded()", "attr.aria-level": "level + 1", "attr.aria-posinset": "_getPositionInSet()", "attr.aria-setsize": "_getSetSize()", "tabindex": "_tabindex" }, classAttribute: "cdk-tree-node" }, exportAs: ["cdkTreeNode"], ngImport: i0 });
1010
+ }
1011
+ return true;
1012
+ }
1013
+ return this._inputIsExpandable;
1014
+ }
1015
+ _getAriaExpanded() {
1016
+ if (!this._isExpandable()) {
1017
+ return null;
1018
+ }
1019
+ return String(this.isExpanded);
1020
+ }
1021
+ _getSetSize() {
1022
+ return this._tree._getSetSize(this._data);
1023
+ }
1024
+ _getPositionInSet() {
1025
+ return this._tree._getPositionInSet(this._data);
1026
+ }
1027
+ _changeDetectorRef = inject(ChangeDetectorRef);
1028
+ constructor() {
1029
+ CdkTreeNode.mostRecentTreeNode = this;
1030
+ }
1031
+ ngOnInit() {
1032
+ this._parentNodeAriaLevel = getParentNodeAriaLevel(this._elementRef.nativeElement);
1033
+ this._tree._getExpansionModel().changed.pipe(map(() => this.isExpanded), distinctUntilChanged(), takeUntil(this._destroyed)).pipe(takeUntil(this._destroyed)).subscribe(() => this._changeDetectorRef.markForCheck());
1034
+ this._tree._setNodeTypeIfUnset(this._type);
1035
+ this._tree._registerNode(this);
1036
+ }
1037
+ ngOnDestroy() {
1038
+ if (CdkTreeNode.mostRecentTreeNode === this) {
1039
+ CdkTreeNode.mostRecentTreeNode = null;
1040
+ }
1041
+ this._dataChanges.complete();
1042
+ this._destroyed.next();
1043
+ this._destroyed.complete();
1044
+ }
1045
+ getParent() {
1046
+ return this._tree._getNodeParent(this) ?? null;
1047
+ }
1048
+ getChildren() {
1049
+ return this._tree._getNodeChildren(this);
1050
+ }
1051
+ focus() {
1052
+ this._tabindex = 0;
1053
+ if (this._shouldFocus) {
1054
+ this._elementRef.nativeElement.focus();
1055
+ }
1056
+ this._changeDetectorRef.markForCheck();
1057
+ }
1058
+ unfocus() {
1059
+ this._tabindex = -1;
1060
+ this._changeDetectorRef.markForCheck();
1061
+ }
1062
+ activate() {
1063
+ if (this.isDisabled) {
1064
+ return;
1065
+ }
1066
+ this.activation.next(this._data);
1067
+ }
1068
+ collapse() {
1069
+ if (this.isExpandable) {
1070
+ this._tree.collapse(this._data);
1071
+ }
1072
+ }
1073
+ expand() {
1074
+ if (this.isExpandable) {
1075
+ this._tree.expand(this._data);
1076
+ }
1077
+ }
1078
+ makeFocusable() {
1079
+ this._tabindex = 0;
1080
+ this._changeDetectorRef.markForCheck();
1081
+ }
1082
+ _focusItem() {
1083
+ if (this.isDisabled) {
1084
+ return;
1085
+ }
1086
+ this._tree._keyManager.focusItem(this);
1087
+ }
1088
+ _setActiveItem() {
1089
+ if (this.isDisabled) {
1090
+ return;
1091
+ }
1092
+ this._shouldFocus = false;
1093
+ this._tree._keyManager.focusItem(this);
1094
+ this._shouldFocus = true;
1095
+ }
1096
+ _emitExpansionState(expanded) {
1097
+ this.expandedChange.emit(expanded);
1098
+ }
1099
+ static ɵfac = i0.ɵɵngDeclareFactory({
1100
+ minVersion: "12.0.0",
1101
+ version: "20.2.0-next.2",
1102
+ ngImport: i0,
1103
+ type: CdkTreeNode,
1104
+ deps: [],
1105
+ target: i0.ɵɵFactoryTarget.Directive
1106
+ });
1107
+ static ɵdir = i0.ɵɵngDeclareDirective({
1108
+ minVersion: "16.1.0",
1109
+ version: "20.2.0-next.2",
1110
+ type: CdkTreeNode,
1111
+ isStandalone: true,
1112
+ selector: "cdk-tree-node",
1113
+ inputs: {
1114
+ role: "role",
1115
+ isExpandable: ["isExpandable", "isExpandable", booleanAttribute],
1116
+ isExpanded: "isExpanded",
1117
+ isDisabled: ["isDisabled", "isDisabled", booleanAttribute],
1118
+ typeaheadLabel: ["cdkTreeNodeTypeaheadLabel", "typeaheadLabel"]
1119
+ },
1120
+ outputs: {
1121
+ activation: "activation",
1122
+ expandedChange: "expandedChange"
1123
+ },
1124
+ host: {
1125
+ attributes: {
1126
+ "role": "treeitem"
1127
+ },
1128
+ listeners: {
1129
+ "click": "_setActiveItem()",
1130
+ "focus": "_focusItem()"
1131
+ },
1132
+ properties: {
1133
+ "attr.aria-expanded": "_getAriaExpanded()",
1134
+ "attr.aria-level": "level + 1",
1135
+ "attr.aria-posinset": "_getPositionInSet()",
1136
+ "attr.aria-setsize": "_getSetSize()",
1137
+ "tabindex": "_tabindex"
1138
+ },
1139
+ classAttribute: "cdk-tree-node"
1140
+ },
1141
+ exportAs: ["cdkTreeNode"],
1142
+ ngImport: i0
1143
+ });
1463
1144
  }
1464
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNode, decorators: [{
1465
- type: Directive,
1466
- args: [{
1467
- selector: 'cdk-tree-node',
1468
- exportAs: 'cdkTreeNode',
1469
- host: {
1470
- 'class': 'cdk-tree-node',
1471
- '[attr.aria-expanded]': '_getAriaExpanded()',
1472
- '[attr.aria-level]': 'level + 1',
1473
- '[attr.aria-posinset]': '_getPositionInSet()',
1474
- '[attr.aria-setsize]': '_getSetSize()',
1475
- '[tabindex]': '_tabindex',
1476
- 'role': 'treeitem',
1477
- '(click)': '_setActiveItem()',
1478
- '(focus)': '_focusItem()',
1479
- },
1480
- }]
1481
- }], ctorParameters: () => [], propDecorators: { role: [{
1482
- type: Input
1483
- }], isExpandable: [{
1484
- type: Input,
1485
- args: [{ transform: booleanAttribute }]
1486
- }], isExpanded: [{
1487
- type: Input
1488
- }], isDisabled: [{
1489
- type: Input,
1490
- args: [{ transform: booleanAttribute }]
1491
- }], typeaheadLabel: [{
1492
- type: Input,
1493
- args: ['cdkTreeNodeTypeaheadLabel']
1494
- }], activation: [{
1495
- type: Output
1496
- }], expandedChange: [{
1497
- type: Output
1498
- }] } });
1145
+ i0.ɵɵngDeclareClassMetadata({
1146
+ minVersion: "12.0.0",
1147
+ version: "20.2.0-next.2",
1148
+ ngImport: i0,
1149
+ type: CdkTreeNode,
1150
+ decorators: [{
1151
+ type: Directive,
1152
+ args: [{
1153
+ selector: 'cdk-tree-node',
1154
+ exportAs: 'cdkTreeNode',
1155
+ host: {
1156
+ 'class': 'cdk-tree-node',
1157
+ '[attr.aria-expanded]': '_getAriaExpanded()',
1158
+ '[attr.aria-level]': 'level + 1',
1159
+ '[attr.aria-posinset]': '_getPositionInSet()',
1160
+ '[attr.aria-setsize]': '_getSetSize()',
1161
+ '[tabindex]': '_tabindex',
1162
+ 'role': 'treeitem',
1163
+ '(click)': '_setActiveItem()',
1164
+ '(focus)': '_focusItem()'
1165
+ }
1166
+ }]
1167
+ }],
1168
+ ctorParameters: () => [],
1169
+ propDecorators: {
1170
+ role: [{
1171
+ type: Input
1172
+ }],
1173
+ isExpandable: [{
1174
+ type: Input,
1175
+ args: [{
1176
+ transform: booleanAttribute
1177
+ }]
1178
+ }],
1179
+ isExpanded: [{
1180
+ type: Input
1181
+ }],
1182
+ isDisabled: [{
1183
+ type: Input,
1184
+ args: [{
1185
+ transform: booleanAttribute
1186
+ }]
1187
+ }],
1188
+ typeaheadLabel: [{
1189
+ type: Input,
1190
+ args: ['cdkTreeNodeTypeaheadLabel']
1191
+ }],
1192
+ activation: [{
1193
+ type: Output
1194
+ }],
1195
+ expandedChange: [{
1196
+ type: Output
1197
+ }]
1198
+ }
1199
+ });
1499
1200
  function getParentNodeAriaLevel(nodeElement) {
1500
- let parent = nodeElement.parentElement;
1501
- while (parent && !isNodeElement(parent)) {
1502
- parent = parent.parentElement;
1503
- }
1504
- if (!parent) {
1505
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
1506
- throw Error('Incorrect tree structure containing detached node.');
1507
- }
1508
- else {
1509
- return -1;
1510
- }
1511
- }
1512
- else if (parent.classList.contains('cdk-nested-tree-node')) {
1513
- return numberAttribute(parent.getAttribute('aria-level'));
1514
- }
1515
- else {
1516
- // The ancestor element is the cdk-tree itself
1517
- return 0;
1518
- }
1201
+ let parent = nodeElement.parentElement;
1202
+ while (parent && !isNodeElement(parent)) {
1203
+ parent = parent.parentElement;
1204
+ }
1205
+ if (!parent) {
1206
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
1207
+ throw Error('Incorrect tree structure containing detached node.');
1208
+ } else {
1209
+ return -1;
1210
+ }
1211
+ } else if (parent.classList.contains('cdk-nested-tree-node')) {
1212
+ return numberAttribute(parent.getAttribute('aria-level'));
1213
+ } else {
1214
+ return 0;
1215
+ }
1519
1216
  }
1520
1217
  function isNodeElement(element) {
1521
- const classList = element.classList;
1522
- return !!(classList?.contains('cdk-nested-tree-node') || classList?.contains('cdk-tree'));
1218
+ const classList = element.classList;
1219
+ return !!(classList?.contains('cdk-nested-tree-node') || classList?.contains('cdk-tree'));
1523
1220
  }
1524
1221
 
1525
- /**
1526
- * Nested node is a child of `<cdk-tree>`. It works with nested tree.
1527
- * By using `cdk-nested-tree-node` component in tree node template, children of the parent node will
1528
- * be added in the `cdkTreeNodeOutlet` in tree node template.
1529
- * The children of node will be automatically added to `cdkTreeNodeOutlet`.
1530
- */
1531
1222
  class CdkNestedTreeNode extends CdkTreeNode {
1532
- _type = 'nested';
1533
- _differs = inject(IterableDiffers);
1534
- /** Differ used to find the changes in the data provided by the data source. */
1535
- _dataDiffer;
1536
- /** The children data dataNodes of current node. They will be placed in `CdkTreeNodeOutlet`. */
1537
- _children;
1538
- /** The children node placeholder. */
1539
- nodeOutlet;
1540
- constructor() {
1541
- super();
1542
- }
1543
- ngAfterContentInit() {
1544
- this._dataDiffer = this._differs.find([]).create(this._tree.trackBy);
1545
- this._tree
1546
- ._getDirectChildren(this.data)
1547
- .pipe(takeUntil(this._destroyed))
1548
- .subscribe(result => this.updateChildrenNodes(result));
1549
- this.nodeOutlet.changes
1550
- .pipe(takeUntil(this._destroyed))
1551
- .subscribe(() => this.updateChildrenNodes());
1552
- }
1553
- ngOnDestroy() {
1554
- this._clear();
1555
- super.ngOnDestroy();
1556
- }
1557
- /** Add children dataNodes to the NodeOutlet */
1558
- updateChildrenNodes(children) {
1559
- const outlet = this._getNodeOutlet();
1560
- if (children) {
1561
- this._children = children;
1562
- }
1563
- if (outlet && this._children) {
1564
- const viewContainer = outlet.viewContainer;
1565
- this._tree.renderNodeChanges(this._children, this._dataDiffer, viewContainer, this._data);
1566
- }
1567
- else {
1568
- // Reset the data differ if there's no children nodes displayed
1569
- this._dataDiffer.diff([]);
1570
- }
1571
- }
1572
- /** Clear the children dataNodes. */
1573
- _clear() {
1574
- const outlet = this._getNodeOutlet();
1575
- if (outlet) {
1576
- outlet.viewContainer.clear();
1577
- this._dataDiffer.diff([]);
1578
- }
1579
- }
1580
- /** Gets the outlet for the current node. */
1581
- _getNodeOutlet() {
1582
- const outlets = this.nodeOutlet;
1583
- // Note that since we use `descendants: true` on the query, we have to ensure
1584
- // that we don't pick up the outlet of a child node by accident.
1585
- return outlets && outlets.find(outlet => !outlet._node || outlet._node === this);
1586
- }
1587
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkNestedTreeNode, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1588
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.2.0-next.2", type: CdkNestedTreeNode, isStandalone: true, selector: "cdk-nested-tree-node", host: { classAttribute: "cdk-nested-tree-node" }, providers: [
1589
- { provide: CdkTreeNode, useExisting: CdkNestedTreeNode },
1590
- { provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: CdkNestedTreeNode },
1591
- ], queries: [{ propertyName: "nodeOutlet", predicate: CdkTreeNodeOutlet, descendants: true }], exportAs: ["cdkNestedTreeNode"], usesInheritance: true, ngImport: i0 });
1223
+ _type = 'nested';
1224
+ _differs = inject(IterableDiffers);
1225
+ _dataDiffer;
1226
+ _children;
1227
+ nodeOutlet;
1228
+ constructor() {
1229
+ super();
1230
+ }
1231
+ ngAfterContentInit() {
1232
+ this._dataDiffer = this._differs.find([]).create(this._tree.trackBy);
1233
+ this._tree._getDirectChildren(this.data).pipe(takeUntil(this._destroyed)).subscribe(result => this.updateChildrenNodes(result));
1234
+ this.nodeOutlet.changes.pipe(takeUntil(this._destroyed)).subscribe(() => this.updateChildrenNodes());
1235
+ }
1236
+ ngOnDestroy() {
1237
+ this._clear();
1238
+ super.ngOnDestroy();
1239
+ }
1240
+ updateChildrenNodes(children) {
1241
+ const outlet = this._getNodeOutlet();
1242
+ if (children) {
1243
+ this._children = children;
1244
+ }
1245
+ if (outlet && this._children) {
1246
+ const viewContainer = outlet.viewContainer;
1247
+ this._tree.renderNodeChanges(this._children, this._dataDiffer, viewContainer, this._data);
1248
+ } else {
1249
+ this._dataDiffer.diff([]);
1250
+ }
1251
+ }
1252
+ _clear() {
1253
+ const outlet = this._getNodeOutlet();
1254
+ if (outlet) {
1255
+ outlet.viewContainer.clear();
1256
+ this._dataDiffer.diff([]);
1257
+ }
1258
+ }
1259
+ _getNodeOutlet() {
1260
+ const outlets = this.nodeOutlet;
1261
+ return outlets && outlets.find(outlet => !outlet._node || outlet._node === this);
1262
+ }
1263
+ static ɵfac = i0.ɵɵngDeclareFactory({
1264
+ minVersion: "12.0.0",
1265
+ version: "20.2.0-next.2",
1266
+ ngImport: i0,
1267
+ type: CdkNestedTreeNode,
1268
+ deps: [],
1269
+ target: i0.ɵɵFactoryTarget.Directive
1270
+ });
1271
+ static ɵdir = i0.ɵɵngDeclareDirective({
1272
+ minVersion: "14.0.0",
1273
+ version: "20.2.0-next.2",
1274
+ type: CdkNestedTreeNode,
1275
+ isStandalone: true,
1276
+ selector: "cdk-nested-tree-node",
1277
+ host: {
1278
+ classAttribute: "cdk-nested-tree-node"
1279
+ },
1280
+ providers: [{
1281
+ provide: CdkTreeNode,
1282
+ useExisting: CdkNestedTreeNode
1283
+ }, {
1284
+ provide: CDK_TREE_NODE_OUTLET_NODE,
1285
+ useExisting: CdkNestedTreeNode
1286
+ }],
1287
+ queries: [{
1288
+ propertyName: "nodeOutlet",
1289
+ predicate: CdkTreeNodeOutlet,
1290
+ descendants: true
1291
+ }],
1292
+ exportAs: ["cdkNestedTreeNode"],
1293
+ usesInheritance: true,
1294
+ ngImport: i0
1295
+ });
1592
1296
  }
1593
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkNestedTreeNode, decorators: [{
1594
- type: Directive,
1595
- args: [{
1596
- selector: 'cdk-nested-tree-node',
1597
- exportAs: 'cdkNestedTreeNode',
1598
- providers: [
1599
- { provide: CdkTreeNode, useExisting: CdkNestedTreeNode },
1600
- { provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: CdkNestedTreeNode },
1601
- ],
1602
- host: {
1603
- 'class': 'cdk-nested-tree-node',
1604
- },
1605
- }]
1606
- }], ctorParameters: () => [], propDecorators: { nodeOutlet: [{
1607
- type: ContentChildren,
1608
- args: [CdkTreeNodeOutlet, {
1609
- // We need to use `descendants: true`, because Ivy will no longer match
1610
- // indirect descendants if it's left as false.
1611
- descendants: true,
1612
- }]
1613
- }] } });
1297
+ i0.ɵɵngDeclareClassMetadata({
1298
+ minVersion: "12.0.0",
1299
+ version: "20.2.0-next.2",
1300
+ ngImport: i0,
1301
+ type: CdkNestedTreeNode,
1302
+ decorators: [{
1303
+ type: Directive,
1304
+ args: [{
1305
+ selector: 'cdk-nested-tree-node',
1306
+ exportAs: 'cdkNestedTreeNode',
1307
+ providers: [{
1308
+ provide: CdkTreeNode,
1309
+ useExisting: CdkNestedTreeNode
1310
+ }, {
1311
+ provide: CDK_TREE_NODE_OUTLET_NODE,
1312
+ useExisting: CdkNestedTreeNode
1313
+ }],
1314
+ host: {
1315
+ 'class': 'cdk-nested-tree-node'
1316
+ }
1317
+ }]
1318
+ }],
1319
+ ctorParameters: () => [],
1320
+ propDecorators: {
1321
+ nodeOutlet: [{
1322
+ type: ContentChildren,
1323
+ args: [CdkTreeNodeOutlet, {
1324
+ descendants: true
1325
+ }]
1326
+ }]
1327
+ }
1328
+ });
1614
1329
 
1615
- /** Regex used to split a string on its CSS units. */
1616
1330
  const cssUnitPattern = /([A-Za-z%]+)$/;
1617
- /**
1618
- * Indent for the children tree dataNodes.
1619
- * This directive will add left-padding to the node to show hierarchy.
1620
- */
1621
1331
  class CdkTreeNodePadding {
1622
- _treeNode = inject(CdkTreeNode);
1623
- _tree = inject(CdkTree);
1624
- _element = inject(ElementRef);
1625
- _dir = inject(Directionality, { optional: true });
1626
- /** Current padding value applied to the element. Used to avoid unnecessarily hitting the DOM. */
1627
- _currentPadding;
1628
- /** Subject that emits when the component has been destroyed. */
1629
- _destroyed = new Subject();
1630
- /** CSS units used for the indentation value. */
1631
- indentUnits = 'px';
1632
- /** The level of depth of the tree node. The padding will be `level * indent` pixels. */
1633
- get level() {
1634
- return this._level;
1635
- }
1636
- set level(value) {
1637
- this._setLevelInput(value);
1638
- }
1639
- _level;
1640
- /**
1641
- * The indent for each level. Can be a number or a CSS string.
1642
- * Default number 40px from material design menu sub-menu spec.
1643
- */
1644
- get indent() {
1645
- return this._indent;
1646
- }
1647
- set indent(indent) {
1648
- this._setIndentInput(indent);
1649
- }
1650
- _indent = 40;
1651
- constructor() {
1652
- this._setPadding();
1653
- this._dir?.change.pipe(takeUntil(this._destroyed)).subscribe(() => this._setPadding(true));
1654
- // In Ivy the indentation binding might be set before the tree node's data has been added,
1655
- // which means that we'll miss the first render. We have to subscribe to changes in the
1656
- // data to ensure that everything is up to date.
1657
- this._treeNode._dataChanges.subscribe(() => this._setPadding());
1658
- }
1659
- ngOnDestroy() {
1660
- this._destroyed.next();
1661
- this._destroyed.complete();
1662
- }
1663
- /** The padding indent value for the tree node. Returns a string with px numbers if not null. */
1664
- _paddingIndent() {
1665
- const nodeLevel = (this._treeNode.data && this._tree._getLevel(this._treeNode.data)) ?? null;
1666
- const level = this._level == null ? nodeLevel : this._level;
1667
- return typeof level === 'number' ? `${level * this._indent}${this.indentUnits}` : null;
1668
- }
1669
- _setPadding(forceChange = false) {
1670
- const padding = this._paddingIndent();
1671
- if (padding !== this._currentPadding || forceChange) {
1672
- const element = this._element.nativeElement;
1673
- const paddingProp = this._dir && this._dir.value === 'rtl' ? 'paddingRight' : 'paddingLeft';
1674
- const resetProp = paddingProp === 'paddingLeft' ? 'paddingRight' : 'paddingLeft';
1675
- element.style[paddingProp] = padding || '';
1676
- element.style[resetProp] = '';
1677
- this._currentPadding = padding;
1678
- }
1679
- }
1680
- /**
1681
- * This has been extracted to a util because of TS 4 and VE.
1682
- * View Engine doesn't support property rename inheritance.
1683
- * TS 4.0 doesn't allow properties to override accessors or vice-versa.
1684
- * @docs-private
1685
- */
1686
- _setLevelInput(value) {
1687
- // Set to null as the fallback value so that _setPadding can fall back to the node level if the
1688
- // consumer set the directive as `cdkTreeNodePadding=""`. We still want to take this value if
1689
- // they set 0 explicitly.
1690
- this._level = isNaN(value) ? null : value;
1691
- this._setPadding();
1692
- }
1693
- /**
1694
- * This has been extracted to a util because of TS 4 and VE.
1695
- * View Engine doesn't support property rename inheritance.
1696
- * TS 4.0 doesn't allow properties to override accessors or vice-versa.
1697
- * @docs-private
1698
- */
1699
- _setIndentInput(indent) {
1700
- let value = indent;
1701
- let units = 'px';
1702
- if (typeof indent === 'string') {
1703
- const parts = indent.split(cssUnitPattern);
1704
- value = parts[0];
1705
- units = parts[1] || units;
1706
- }
1707
- this.indentUnits = units;
1708
- this._indent = numberAttribute(value);
1709
- this._setPadding();
1710
- }
1711
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNodePadding, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1712
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.2.0-next.2", type: CdkTreeNodePadding, isStandalone: true, selector: "[cdkTreeNodePadding]", inputs: { level: ["cdkTreeNodePadding", "level", numberAttribute], indent: ["cdkTreeNodePaddingIndent", "indent"] }, ngImport: i0 });
1332
+ _treeNode = inject(CdkTreeNode);
1333
+ _tree = inject(CdkTree);
1334
+ _element = inject(ElementRef);
1335
+ _dir = inject(Directionality, {
1336
+ optional: true
1337
+ });
1338
+ _currentPadding;
1339
+ _destroyed = new Subject();
1340
+ indentUnits = 'px';
1341
+ get level() {
1342
+ return this._level;
1343
+ }
1344
+ set level(value) {
1345
+ this._setLevelInput(value);
1346
+ }
1347
+ _level;
1348
+ get indent() {
1349
+ return this._indent;
1350
+ }
1351
+ set indent(indent) {
1352
+ this._setIndentInput(indent);
1353
+ }
1354
+ _indent = 40;
1355
+ constructor() {
1356
+ this._setPadding();
1357
+ this._dir?.change.pipe(takeUntil(this._destroyed)).subscribe(() => this._setPadding(true));
1358
+ this._treeNode._dataChanges.subscribe(() => this._setPadding());
1359
+ }
1360
+ ngOnDestroy() {
1361
+ this._destroyed.next();
1362
+ this._destroyed.complete();
1363
+ }
1364
+ _paddingIndent() {
1365
+ const nodeLevel = (this._treeNode.data && this._tree._getLevel(this._treeNode.data)) ?? null;
1366
+ const level = this._level == null ? nodeLevel : this._level;
1367
+ return typeof level === 'number' ? `${level * this._indent}${this.indentUnits}` : null;
1368
+ }
1369
+ _setPadding(forceChange = false) {
1370
+ const padding = this._paddingIndent();
1371
+ if (padding !== this._currentPadding || forceChange) {
1372
+ const element = this._element.nativeElement;
1373
+ const paddingProp = this._dir && this._dir.value === 'rtl' ? 'paddingRight' : 'paddingLeft';
1374
+ const resetProp = paddingProp === 'paddingLeft' ? 'paddingRight' : 'paddingLeft';
1375
+ element.style[paddingProp] = padding || '';
1376
+ element.style[resetProp] = '';
1377
+ this._currentPadding = padding;
1378
+ }
1379
+ }
1380
+ _setLevelInput(value) {
1381
+ this._level = isNaN(value) ? null : value;
1382
+ this._setPadding();
1383
+ }
1384
+ _setIndentInput(indent) {
1385
+ let value = indent;
1386
+ let units = 'px';
1387
+ if (typeof indent === 'string') {
1388
+ const parts = indent.split(cssUnitPattern);
1389
+ value = parts[0];
1390
+ units = parts[1] || units;
1391
+ }
1392
+ this.indentUnits = units;
1393
+ this._indent = numberAttribute(value);
1394
+ this._setPadding();
1395
+ }
1396
+ static ɵfac = i0.ɵɵngDeclareFactory({
1397
+ minVersion: "12.0.0",
1398
+ version: "20.2.0-next.2",
1399
+ ngImport: i0,
1400
+ type: CdkTreeNodePadding,
1401
+ deps: [],
1402
+ target: i0.ɵɵFactoryTarget.Directive
1403
+ });
1404
+ static ɵdir = i0.ɵɵngDeclareDirective({
1405
+ minVersion: "16.1.0",
1406
+ version: "20.2.0-next.2",
1407
+ type: CdkTreeNodePadding,
1408
+ isStandalone: true,
1409
+ selector: "[cdkTreeNodePadding]",
1410
+ inputs: {
1411
+ level: ["cdkTreeNodePadding", "level", numberAttribute],
1412
+ indent: ["cdkTreeNodePaddingIndent", "indent"]
1413
+ },
1414
+ ngImport: i0
1415
+ });
1713
1416
  }
1714
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNodePadding, decorators: [{
1715
- type: Directive,
1716
- args: [{
1717
- selector: '[cdkTreeNodePadding]',
1718
- }]
1719
- }], ctorParameters: () => [], propDecorators: { level: [{
1720
- type: Input,
1721
- args: [{ alias: 'cdkTreeNodePadding', transform: numberAttribute }]
1722
- }], indent: [{
1723
- type: Input,
1724
- args: ['cdkTreeNodePaddingIndent']
1725
- }] } });
1417
+ i0.ɵɵngDeclareClassMetadata({
1418
+ minVersion: "12.0.0",
1419
+ version: "20.2.0-next.2",
1420
+ ngImport: i0,
1421
+ type: CdkTreeNodePadding,
1422
+ decorators: [{
1423
+ type: Directive,
1424
+ args: [{
1425
+ selector: '[cdkTreeNodePadding]'
1426
+ }]
1427
+ }],
1428
+ ctorParameters: () => [],
1429
+ propDecorators: {
1430
+ level: [{
1431
+ type: Input,
1432
+ args: [{
1433
+ alias: 'cdkTreeNodePadding',
1434
+ transform: numberAttribute
1435
+ }]
1436
+ }],
1437
+ indent: [{
1438
+ type: Input,
1439
+ args: ['cdkTreeNodePaddingIndent']
1440
+ }]
1441
+ }
1442
+ });
1726
1443
 
1727
- /**
1728
- * Node toggle to expand and collapse the node.
1729
- */
1730
1444
  class CdkTreeNodeToggle {
1731
- _tree = inject(CdkTree);
1732
- _treeNode = inject(CdkTreeNode);
1733
- /** Whether expand/collapse the node recursively. */
1734
- recursive = false;
1735
- constructor() { }
1736
- // Toggle the expanded or collapsed state of this node.
1737
- //
1738
- // Focus this node with expanding or collapsing it. This ensures that the active node will always
1739
- // be visible when expanding and collapsing.
1740
- _toggle() {
1741
- this.recursive
1742
- ? this._tree.toggleDescendants(this._treeNode.data)
1743
- : this._tree.toggle(this._treeNode.data);
1744
- this._tree._keyManager.focusItem(this._treeNode);
1745
- }
1746
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNodeToggle, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1747
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.2.0-next.2", type: CdkTreeNodeToggle, isStandalone: true, selector: "[cdkTreeNodeToggle]", inputs: { recursive: ["cdkTreeNodeToggleRecursive", "recursive", booleanAttribute] }, host: { attributes: { "tabindex": "-1" }, listeners: { "click": "_toggle(); $event.stopPropagation();", "keydown.Enter": "_toggle(); $event.preventDefault();", "keydown.Space": "_toggle(); $event.preventDefault();" } }, ngImport: i0 });
1445
+ _tree = inject(CdkTree);
1446
+ _treeNode = inject(CdkTreeNode);
1447
+ recursive = false;
1448
+ constructor() {}
1449
+ _toggle() {
1450
+ this.recursive ? this._tree.toggleDescendants(this._treeNode.data) : this._tree.toggle(this._treeNode.data);
1451
+ this._tree._keyManager.focusItem(this._treeNode);
1452
+ }
1453
+ static ɵfac = i0.ɵɵngDeclareFactory({
1454
+ minVersion: "12.0.0",
1455
+ version: "20.2.0-next.2",
1456
+ ngImport: i0,
1457
+ type: CdkTreeNodeToggle,
1458
+ deps: [],
1459
+ target: i0.ɵɵFactoryTarget.Directive
1460
+ });
1461
+ static ɵdir = i0.ɵɵngDeclareDirective({
1462
+ minVersion: "16.1.0",
1463
+ version: "20.2.0-next.2",
1464
+ type: CdkTreeNodeToggle,
1465
+ isStandalone: true,
1466
+ selector: "[cdkTreeNodeToggle]",
1467
+ inputs: {
1468
+ recursive: ["cdkTreeNodeToggleRecursive", "recursive", booleanAttribute]
1469
+ },
1470
+ host: {
1471
+ attributes: {
1472
+ "tabindex": "-1"
1473
+ },
1474
+ listeners: {
1475
+ "click": "_toggle(); $event.stopPropagation();",
1476
+ "keydown.Enter": "_toggle(); $event.preventDefault();",
1477
+ "keydown.Space": "_toggle(); $event.preventDefault();"
1478
+ }
1479
+ },
1480
+ ngImport: i0
1481
+ });
1748
1482
  }
1749
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeNodeToggle, decorators: [{
1750
- type: Directive,
1751
- args: [{
1752
- selector: '[cdkTreeNodeToggle]',
1753
- host: {
1754
- '(click)': '_toggle(); $event.stopPropagation();',
1755
- '(keydown.Enter)': '_toggle(); $event.preventDefault();',
1756
- '(keydown.Space)': '_toggle(); $event.preventDefault();',
1757
- 'tabindex': '-1',
1758
- },
1759
- }]
1760
- }], ctorParameters: () => [], propDecorators: { recursive: [{
1761
- type: Input,
1762
- args: [{ alias: 'cdkTreeNodeToggleRecursive', transform: booleanAttribute }]
1763
- }] } });
1483
+ i0.ɵɵngDeclareClassMetadata({
1484
+ minVersion: "12.0.0",
1485
+ version: "20.2.0-next.2",
1486
+ ngImport: i0,
1487
+ type: CdkTreeNodeToggle,
1488
+ decorators: [{
1489
+ type: Directive,
1490
+ args: [{
1491
+ selector: '[cdkTreeNodeToggle]',
1492
+ host: {
1493
+ '(click)': '_toggle(); $event.stopPropagation();',
1494
+ '(keydown.Enter)': '_toggle(); $event.preventDefault();',
1495
+ '(keydown.Space)': '_toggle(); $event.preventDefault();',
1496
+ 'tabindex': '-1'
1497
+ }
1498
+ }]
1499
+ }],
1500
+ ctorParameters: () => [],
1501
+ propDecorators: {
1502
+ recursive: [{
1503
+ type: Input,
1504
+ args: [{
1505
+ alias: 'cdkTreeNodeToggleRecursive',
1506
+ transform: booleanAttribute
1507
+ }]
1508
+ }]
1509
+ }
1510
+ });
1764
1511
 
1765
- const EXPORTED_DECLARATIONS = [
1766
- CdkNestedTreeNode,
1767
- CdkTreeNodeDef,
1768
- CdkTreeNodePadding,
1769
- CdkTreeNodeToggle,
1770
- CdkTree,
1771
- CdkTreeNode,
1772
- CdkTreeNodeOutlet,
1773
- ];
1512
+ const EXPORTED_DECLARATIONS = [CdkNestedTreeNode, CdkTreeNodeDef, CdkTreeNodePadding, CdkTreeNodeToggle, CdkTree, CdkTreeNode, CdkTreeNodeOutlet];
1774
1513
  class CdkTreeModule {
1775
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1776
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeModule, imports: [CdkNestedTreeNode,
1777
- CdkTreeNodeDef,
1778
- CdkTreeNodePadding,
1779
- CdkTreeNodeToggle,
1780
- CdkTree,
1781
- CdkTreeNode,
1782
- CdkTreeNodeOutlet], exports: [CdkNestedTreeNode,
1783
- CdkTreeNodeDef,
1784
- CdkTreeNodePadding,
1785
- CdkTreeNodeToggle,
1786
- CdkTree,
1787
- CdkTreeNode,
1788
- CdkTreeNodeOutlet] });
1789
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeModule });
1514
+ static ɵfac = i0.ɵɵngDeclareFactory({
1515
+ minVersion: "12.0.0",
1516
+ version: "20.2.0-next.2",
1517
+ ngImport: i0,
1518
+ type: CdkTreeModule,
1519
+ deps: [],
1520
+ target: i0.ɵɵFactoryTarget.NgModule
1521
+ });
1522
+ static ɵmod = i0.ɵɵngDeclareNgModule({
1523
+ minVersion: "14.0.0",
1524
+ version: "20.2.0-next.2",
1525
+ ngImport: i0,
1526
+ type: CdkTreeModule,
1527
+ imports: [CdkNestedTreeNode, CdkTreeNodeDef, CdkTreeNodePadding, CdkTreeNodeToggle, CdkTree, CdkTreeNode, CdkTreeNodeOutlet],
1528
+ exports: [CdkNestedTreeNode, CdkTreeNodeDef, CdkTreeNodePadding, CdkTreeNodeToggle, CdkTree, CdkTreeNode, CdkTreeNodeOutlet]
1529
+ });
1530
+ static ɵinj = i0.ɵɵngDeclareInjector({
1531
+ minVersion: "12.0.0",
1532
+ version: "20.2.0-next.2",
1533
+ ngImport: i0,
1534
+ type: CdkTreeModule
1535
+ });
1790
1536
  }
1791
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.0-next.2", ngImport: i0, type: CdkTreeModule, decorators: [{
1792
- type: NgModule,
1793
- args: [{
1794
- imports: EXPORTED_DECLARATIONS,
1795
- exports: EXPORTED_DECLARATIONS,
1796
- }]
1797
- }] });
1537
+ i0.ɵɵngDeclareClassMetadata({
1538
+ minVersion: "12.0.0",
1539
+ version: "20.2.0-next.2",
1540
+ ngImport: i0,
1541
+ type: CdkTreeModule,
1542
+ decorators: [{
1543
+ type: NgModule,
1544
+ args: [{
1545
+ imports: EXPORTED_DECLARATIONS,
1546
+ exports: EXPORTED_DECLARATIONS
1547
+ }]
1548
+ }]
1549
+ });
1798
1550
 
1799
1551
  export { BaseTreeControl, CDK_TREE_NODE_OUTLET_NODE, CdkNestedTreeNode, CdkTree, CdkTreeModule, CdkTreeNode, CdkTreeNodeDef, CdkTreeNodeOutlet, CdkTreeNodeOutletContext, CdkTreeNodePadding, CdkTreeNodeToggle, FlatTreeControl, NestedTreeControl, getMultipleTreeControlsError, getTreeControlMissingError, getTreeMissingMatchingNodeDefError, getTreeMultipleDefaultNodeDefsError, getTreeNoValidDataSourceError };
1800
1552
  //# sourceMappingURL=tree.mjs.map