@angular/cdk 10.0.0-rc.3 → 10.1.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 (242) hide show
  1. package/a11y/aria-describer/aria-describer.d.ts +10 -1
  2. package/a11y/focus-trap/focus-trap.d.ts +4 -2
  3. package/a11y/index.metadata.json +1 -1
  4. package/a11y/interactivity-checker/interactivity-checker.d.ts +11 -1
  5. package/a11y/key-manager/list-key-manager.d.ts +6 -0
  6. package/accordion/accordion.d.ts +7 -1
  7. package/accordion/index.d.ts +1 -0
  8. package/accordion/index.metadata.json +1 -1
  9. package/bundles/cdk-a11y.umd.js +78 -15
  10. package/bundles/cdk-a11y.umd.js.map +1 -1
  11. package/bundles/cdk-a11y.umd.min.js +11 -11
  12. package/bundles/cdk-a11y.umd.min.js.map +1 -1
  13. package/bundles/cdk-accordion.umd.js +12 -4
  14. package/bundles/cdk-accordion.umd.js.map +1 -1
  15. package/bundles/cdk-accordion.umd.min.js +2 -2
  16. package/bundles/cdk-accordion.umd.min.js.map +1 -1
  17. package/bundles/cdk-drag-drop.umd.js +717 -641
  18. package/bundles/cdk-drag-drop.umd.js.map +1 -1
  19. package/bundles/cdk-drag-drop.umd.min.js +8 -16
  20. package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
  21. package/bundles/cdk-overlay.umd.js +199 -42
  22. package/bundles/cdk-overlay.umd.js.map +1 -1
  23. package/bundles/cdk-overlay.umd.min.js +11 -18
  24. package/bundles/cdk-overlay.umd.min.js.map +1 -1
  25. package/bundles/cdk-platform.umd.js +0 -1
  26. package/bundles/cdk-platform.umd.js.map +1 -1
  27. package/bundles/cdk-platform.umd.min.js +2 -2
  28. package/bundles/cdk-platform.umd.min.js.map +1 -1
  29. package/bundles/cdk-scrolling.umd.js +26 -4
  30. package/bundles/cdk-scrolling.umd.js.map +1 -1
  31. package/bundles/cdk-scrolling.umd.min.js +11 -4
  32. package/bundles/cdk-scrolling.umd.min.js.map +1 -1
  33. package/bundles/cdk-testing-protractor.umd.min.js +1 -1
  34. package/bundles/cdk-testing-protractor.umd.min.js.map +1 -1
  35. package/bundles/cdk-testing-testbed.umd.min.js +8 -8
  36. package/bundles/cdk-testing-testbed.umd.min.js.map +1 -1
  37. package/bundles/cdk-testing.umd.js +32 -0
  38. package/bundles/cdk-testing.umd.js.map +1 -1
  39. package/bundles/cdk-testing.umd.min.js +5 -5
  40. package/bundles/cdk-testing.umd.min.js.map +1 -1
  41. package/bundles/cdk-tree.umd.js +6 -2
  42. package/bundles/cdk-tree.umd.js.map +1 -1
  43. package/bundles/cdk-tree.umd.min.js +3 -3
  44. package/bundles/cdk-tree.umd.min.js.map +1 -1
  45. package/bundles/cdk.umd.js +1 -1
  46. package/bundles/cdk.umd.js.map +1 -1
  47. package/bundles/cdk.umd.min.js +1 -1
  48. package/bundles/cdk.umd.min.js.map +1 -1
  49. package/drag-drop/directives/drag-handle.d.ts +7 -1
  50. package/drag-drop/directives/drag-placeholder.d.ts +7 -1
  51. package/drag-drop/directives/drag-preview.d.ts +7 -1
  52. package/drag-drop/directives/drag.d.ts +4 -14
  53. package/drag-drop/directives/drop-list-group.d.ts +7 -1
  54. package/drag-drop/directives/drop-list.d.ts +7 -1
  55. package/drag-drop/drag-ref.d.ts +6 -0
  56. package/drag-drop/drop-list-ref.d.ts +3 -2
  57. package/drag-drop/index.d.ts +2 -2
  58. package/drag-drop/index.metadata.json +1 -1
  59. package/esm2015/a11y/a11y-module.js +15 -19
  60. package/esm2015/a11y/aria-describer/aria-describer.js +177 -167
  61. package/esm2015/a11y/focus-monitor/focus-monitor.js +337 -345
  62. package/esm2015/a11y/focus-trap/configurable-focus-trap-factory.js +30 -34
  63. package/esm2015/a11y/focus-trap/focus-trap-manager.js +36 -40
  64. package/esm2015/a11y/focus-trap/focus-trap.js +85 -82
  65. package/esm2015/a11y/high-contrast-mode/high-contrast-mode-detector.js +56 -60
  66. package/esm2015/a11y/interactivity-checker/interactivity-checker.js +113 -104
  67. package/esm2015/a11y/key-manager/list-key-manager.js +29 -4
  68. package/esm2015/a11y/live-announcer/live-announcer.js +138 -146
  69. package/esm2015/accordion/accordion-item.js +119 -123
  70. package/esm2015/accordion/accordion-module.js +9 -13
  71. package/esm2015/accordion/accordion.js +49 -46
  72. package/esm2015/accordion/index.js +2 -1
  73. package/esm2015/bidi/bidi-module.js +9 -13
  74. package/esm2015/bidi/dir.js +41 -45
  75. package/esm2015/bidi/directionality.js +27 -31
  76. package/esm2015/clipboard/clipboard-module.js +9 -13
  77. package/esm2015/clipboard/clipboard.js +36 -40
  78. package/esm2015/clipboard/copy-to-clipboard.js +71 -75
  79. package/esm2015/collections/unique-selection-dispatcher.js +33 -37
  80. package/esm2015/drag-drop/directives/drag-handle.js +42 -39
  81. package/esm2015/drag-drop/directives/drag-placeholder.js +24 -21
  82. package/esm2015/drag-drop/directives/drag-preview.js +29 -26
  83. package/esm2015/drag-drop/directives/drag.js +313 -319
  84. package/esm2015/drag-drop/directives/drop-list-group.js +32 -29
  85. package/esm2015/drag-drop/directives/drop-list.js +251 -250
  86. package/esm2015/drag-drop/drag-drop-module.js +27 -31
  87. package/esm2015/drag-drop/drag-drop-registry.js +139 -143
  88. package/esm2015/drag-drop/drag-drop.js +33 -37
  89. package/esm2015/drag-drop/drag-ref.js +59 -25
  90. package/esm2015/drag-drop/drop-list-ref.js +15 -9
  91. package/esm2015/drag-drop/index.js +3 -2
  92. package/esm2015/layout/breakpoints-observer.js +81 -85
  93. package/esm2015/layout/layout-module.js +6 -10
  94. package/esm2015/layout/media-matcher.js +28 -32
  95. package/esm2015/observers/observe-content.js +147 -163
  96. package/esm2015/overlay/dispatchers/base-overlay-dispatcher.js +51 -0
  97. package/esm2015/overlay/dispatchers/index.js +10 -0
  98. package/esm2015/overlay/dispatchers/overlay-keyboard-dispatcher.js +79 -0
  99. package/esm2015/overlay/dispatchers/overlay-outside-click-dispatcher.js +94 -0
  100. package/esm2015/overlay/fullscreen-overlay-container.js +70 -74
  101. package/esm2015/overlay/index.js +5 -4
  102. package/esm2015/overlay/overlay-config.js +5 -1
  103. package/esm2015/overlay/overlay-container.js +69 -73
  104. package/esm2015/overlay/overlay-directives.js +245 -243
  105. package/esm2015/overlay/overlay-module.js +15 -19
  106. package/esm2015/overlay/overlay-ref.js +24 -2
  107. package/esm2015/overlay/overlay-reference.js +1 -1
  108. package/esm2015/overlay/overlay.js +93 -92
  109. package/esm2015/overlay/position/connected-position.js +14 -18
  110. package/esm2015/overlay/position/overlay-position-builder.js +43 -47
  111. package/esm2015/overlay/public-api.js +2 -2
  112. package/esm2015/overlay/scroll/scroll-strategy-options.js +33 -37
  113. package/esm2015/platform/features/scrolling.js +1 -2
  114. package/esm2015/platform/platform-module.js +6 -10
  115. package/esm2015/platform/platform.js +48 -52
  116. package/esm2015/portal/portal-directives.js +181 -201
  117. package/esm2015/scrolling/fixed-size-virtual-scroll.js +57 -47
  118. package/esm2015/scrolling/public-api.js +2 -1
  119. package/esm2015/scrolling/scroll-dispatcher.js +139 -143
  120. package/esm2015/scrolling/scrollable.js +135 -139
  121. package/esm2015/scrolling/scrolling-module.js +32 -40
  122. package/esm2015/scrolling/viewport-ruler.js +105 -109
  123. package/esm2015/scrolling/virtual-for-of.js +264 -268
  124. package/esm2015/scrolling/virtual-scroll-repeater.js +8 -0
  125. package/esm2015/scrolling/virtual-scroll-viewport.js +318 -322
  126. package/esm2015/stepper/step-header.js +20 -24
  127. package/esm2015/stepper/step-label.js +13 -17
  128. package/esm2015/stepper/stepper-button.js +59 -67
  129. package/esm2015/stepper/stepper-module.js +24 -28
  130. package/esm2015/stepper/stepper.js +313 -321
  131. package/esm2015/table/cell.js +129 -157
  132. package/esm2015/table/row.js +183 -219
  133. package/esm2015/table/table-module.js +9 -13
  134. package/esm2015/table/table.js +765 -785
  135. package/esm2015/table/text-column.js +85 -89
  136. package/esm2015/testing/component-harness.js +19 -1
  137. package/esm2015/testing/harness-environment.js +7 -1
  138. package/esm2015/text-field/autofill.js +89 -97
  139. package/esm2015/text-field/autosize.js +225 -229
  140. package/esm2015/text-field/text-field-module.js +10 -14
  141. package/esm2015/tree/control/nested-tree-control.js +7 -3
  142. package/esm2015/tree/nested-node.js +79 -83
  143. package/esm2015/tree/node.js +17 -21
  144. package/esm2015/tree/outlet.js +15 -19
  145. package/esm2015/tree/padding.js +88 -92
  146. package/esm2015/tree/toggle.js +32 -36
  147. package/esm2015/tree/tree-module.js +10 -14
  148. package/esm2015/tree/tree.js +266 -274
  149. package/esm2015/version.js +1 -1
  150. package/fesm2015/a11y.js +1021 -996
  151. package/fesm2015/a11y.js.map +1 -1
  152. package/fesm2015/accordion.js +173 -175
  153. package/fesm2015/accordion.js.map +1 -1
  154. package/fesm2015/bidi.js +74 -83
  155. package/fesm2015/bidi.js.map +1 -1
  156. package/fesm2015/cdk.js +1 -1
  157. package/fesm2015/cdk.js.map +1 -1
  158. package/fesm2015/clipboard.js +113 -122
  159. package/fesm2015/clipboard.js.map +1 -1
  160. package/fesm2015/collections.js +32 -35
  161. package/fesm2015/collections.js.map +1 -1
  162. package/fesm2015/drag-drop.js +1005 -961
  163. package/fesm2015/drag-drop.js.map +1 -1
  164. package/fesm2015/layout.js +111 -120
  165. package/fesm2015/layout.js.map +1 -1
  166. package/fesm2015/observers.js +146 -158
  167. package/fesm2015/observers.js.map +1 -1
  168. package/fesm2015/overlay.js +793 -659
  169. package/fesm2015/overlay.js.map +1 -1
  170. package/fesm2015/platform.js +52 -59
  171. package/fesm2015/platform.js.map +1 -1
  172. package/fesm2015/portal.js +180 -195
  173. package/fesm2015/portal.js.map +1 -1
  174. package/fesm2015/scrolling.js +1058 -1060
  175. package/fesm2015/scrolling.js.map +1 -1
  176. package/fesm2015/stepper.js +424 -445
  177. package/fesm2015/stepper.js.map +1 -1
  178. package/fesm2015/table.js +1178 -1247
  179. package/fesm2015/table.js.map +1 -1
  180. package/fesm2015/testing.js +25 -1
  181. package/fesm2015/testing.js.map +1 -1
  182. package/fesm2015/text-field.js +318 -330
  183. package/fesm2015/text-field.js.map +1 -1
  184. package/fesm2015/tree.js +517 -537
  185. package/fesm2015/tree.js.map +1 -1
  186. package/overlay/dispatchers/base-overlay-dispatcher.d.ts +28 -0
  187. package/overlay/dispatchers/index.d.ts +9 -0
  188. package/overlay/{keyboard → dispatchers}/overlay-keyboard-dispatcher.d.ts +4 -10
  189. package/overlay/dispatchers/overlay-outside-click-dispatcher.d.ts +27 -0
  190. package/overlay/index.d.ts +4 -3
  191. package/overlay/index.metadata.json +1 -1
  192. package/overlay/overlay-config.d.ts +4 -0
  193. package/overlay/overlay-directives.d.ts +4 -0
  194. package/overlay/overlay-ref.d.ts +8 -2
  195. package/overlay/overlay-reference.d.ts +1 -0
  196. package/overlay/overlay.d.ts +4 -2
  197. package/overlay/public-api.d.ts +1 -1
  198. package/package.json +3 -3
  199. package/schematics/index.js +1 -1
  200. package/schematics/migration.json +5 -0
  201. package/schematics/ng-add/index.js +1 -1
  202. package/schematics/ng-update/data/index.js +1 -1
  203. package/schematics/ng-update/devkit-file-system.d.ts +5 -5
  204. package/schematics/ng-update/devkit-file-system.js +21 -16
  205. package/schematics/ng-update/devkit-migration-rule.js +13 -20
  206. package/schematics/ng-update/devkit-migration.d.ts +0 -2
  207. package/schematics/ng-update/devkit-migration.js +1 -1
  208. package/schematics/ng-update/find-stylesheets.d.ts +10 -0
  209. package/schematics/ng-update/find-stylesheets.js +31 -0
  210. package/schematics/ng-update/index.d.ts +2 -0
  211. package/schematics/ng-update/index.js +7 -2
  212. package/schematics/ng-update/migrations/attribute-selectors.js +3 -3
  213. package/schematics/ng-update/migrations/css-selectors.js +3 -3
  214. package/schematics/ng-update/migrations/element-selectors.js +3 -3
  215. package/schematics/ng-update/public-api.js +1 -1
  216. package/schematics/update-tool/component-resource-collector.d.ts +1 -1
  217. package/schematics/update-tool/component-resource-collector.js +18 -14
  218. package/schematics/update-tool/file-system.d.ts +19 -14
  219. package/schematics/update-tool/file-system.js +1 -1
  220. package/schematics/update-tool/index.d.ts +21 -3
  221. package/schematics/update-tool/index.js +29 -23
  222. package/schematics/update-tool/public-api.js +1 -1
  223. package/schematics/update-tool/target-version.d.ts +2 -1
  224. package/schematics/update-tool/target-version.js +5 -3
  225. package/schematics/update-tool/utils/parse-tsconfig.d.ts +2 -1
  226. package/schematics/update-tool/utils/parse-tsconfig.js +6 -10
  227. package/schematics/update-tool/utils/virtual-host.d.ts +34 -0
  228. package/schematics/update-tool/utils/virtual-host.js +62 -0
  229. package/schematics/update-tool/version-changes.js +4 -6
  230. package/schematics/utils/index.js +1 -1
  231. package/schematics/utils/project-tsconfig-paths.d.ts +2 -1
  232. package/schematics/utils/project-tsconfig-paths.js +1 -1
  233. package/scrolling/index.metadata.json +1 -1
  234. package/scrolling/public-api.d.ts +1 -0
  235. package/scrolling/virtual-for-of.d.ts +2 -1
  236. package/scrolling/virtual-scroll-repeater.d.ts +16 -0
  237. package/scrolling/virtual-scroll-viewport.d.ts +4 -4
  238. package/testing/component-harness.d.ts +12 -0
  239. package/testing/harness-environment.d.ts +1 -0
  240. package/tree/control/nested-tree-control.d.ts +7 -2
  241. package/tree/index.metadata.json +1 -1
  242. package/esm2015/overlay/keyboard/overlay-keyboard-dispatcher.js +0 -100
package/fesm2015/tree.js CHANGED
@@ -122,9 +122,13 @@ class FlatTreeControl extends BaseTreeControl {
122
122
  /** Nested tree control. Able to expand/collapse a subtree recursively for NestedNode type. */
123
123
  class NestedTreeControl extends BaseTreeControl {
124
124
  /** Construct with nested tree function getChildren. */
125
- constructor(getChildren) {
125
+ constructor(getChildren, options) {
126
126
  super();
127
127
  this.getChildren = getChildren;
128
+ this.options = options;
129
+ if (this.options) {
130
+ this.trackBy = this.options.trackBy;
131
+ }
128
132
  }
129
133
  /**
130
134
  * Expands all dataNodes in the tree.
@@ -135,7 +139,7 @@ class NestedTreeControl extends BaseTreeControl {
135
139
  expandAll() {
136
140
  this.expansionModel.clear();
137
141
  const allNodes = this.dataNodes.reduce((accumulator, dataNode) => [...accumulator, ...this.getDescendants(dataNode), dataNode], []);
138
- this.expansionModel.select(...allNodes);
142
+ this.expansionModel.select(...allNodes.map(node => this._trackByValue(node)));
139
143
  }
140
144
  /** Gets a list of descendant dataNodes of a subtree rooted at given data node recursively. */
141
145
  getDescendants(dataNode) {
@@ -181,24 +185,21 @@ const CDK_TREE_NODE_OUTLET_NODE = new InjectionToken('CDK_TREE_NODE_OUTLET_NODE'
181
185
  * Outlet for nested CdkNode. Put `[cdkTreeNodeOutlet]` on a tag to place children dataNodes
182
186
  * inside the outlet.
183
187
  */
184
- let CdkTreeNodeOutlet = /** @class */ (() => {
185
- class CdkTreeNodeOutlet {
186
- constructor(viewContainer, _node) {
187
- this.viewContainer = viewContainer;
188
- this._node = _node;
189
- }
190
- }
191
- CdkTreeNodeOutlet.decorators = [
192
- { type: Directive, args: [{
193
- selector: '[cdkTreeNodeOutlet]'
194
- },] }
195
- ];
196
- CdkTreeNodeOutlet.ctorParameters = () => [
197
- { type: ViewContainerRef },
198
- { type: undefined, decorators: [{ type: Inject, args: [CDK_TREE_NODE_OUTLET_NODE,] }, { type: Optional }] }
199
- ];
200
- return CdkTreeNodeOutlet;
201
- })();
188
+ class CdkTreeNodeOutlet {
189
+ constructor(viewContainer, _node) {
190
+ this.viewContainer = viewContainer;
191
+ this._node = _node;
192
+ }
193
+ }
194
+ CdkTreeNodeOutlet.decorators = [
195
+ { type: Directive, args: [{
196
+ selector: '[cdkTreeNodeOutlet]'
197
+ },] }
198
+ ];
199
+ CdkTreeNodeOutlet.ctorParameters = () => [
200
+ { type: ViewContainerRef },
201
+ { type: undefined, decorators: [{ type: Inject, args: [CDK_TREE_NODE_OUTLET_NODE,] }, { type: Optional }] }
202
+ ];
202
203
 
203
204
  /**
204
205
  * @license
@@ -217,26 +218,23 @@ class CdkTreeNodeOutletContext {
217
218
  * Data node definition for the CdkTree.
218
219
  * Captures the node's template and a when predicate that describes when this node should be used.
219
220
  */
220
- let CdkTreeNodeDef = /** @class */ (() => {
221
- class CdkTreeNodeDef {
222
- /** @docs-private */
223
- constructor(template) {
224
- this.template = template;
225
- }
226
- }
227
- CdkTreeNodeDef.decorators = [
228
- { type: Directive, args: [{
229
- selector: '[cdkTreeNodeDef]',
230
- inputs: [
231
- 'when: cdkTreeNodeDefWhen'
232
- ],
233
- },] }
234
- ];
235
- CdkTreeNodeDef.ctorParameters = () => [
236
- { type: TemplateRef }
237
- ];
238
- return CdkTreeNodeDef;
239
- })();
221
+ class CdkTreeNodeDef {
222
+ /** @docs-private */
223
+ constructor(template) {
224
+ this.template = template;
225
+ }
226
+ }
227
+ CdkTreeNodeDef.decorators = [
228
+ { type: Directive, args: [{
229
+ selector: '[cdkTreeNodeDef]',
230
+ inputs: [
231
+ 'when: cdkTreeNodeDefWhen'
232
+ ],
233
+ },] }
234
+ ];
235
+ CdkTreeNodeDef.ctorParameters = () => [
236
+ { type: TemplateRef }
237
+ ];
240
238
 
241
239
  /**
242
240
  * @license
@@ -285,305 +283,299 @@ function getTreeControlFunctionsMissingError() {
285
283
  * CDK tree component that connects with a data source to retrieve data of type `T` and renders
286
284
  * dataNodes with hierarchy. Updates the dataNodes when new data is provided by the data source.
287
285
  */
288
- let CdkTree = /** @class */ (() => {
289
- class CdkTree {
290
- constructor(_differs, _changeDetectorRef) {
291
- this._differs = _differs;
292
- this._changeDetectorRef = _changeDetectorRef;
293
- /** Subject that emits when the component has been destroyed. */
294
- this._onDestroy = new Subject();
295
- /** Level of nodes */
296
- this._levels = new Map();
297
- // TODO(tinayuangao): Setup a listener for scrolling, emit the calculated view to viewChange.
298
- // Remove the MAX_VALUE in viewChange
299
- /**
300
- * Stream containing the latest information on what rows are being displayed on screen.
301
- * Can be used by the data source to as a heuristic of what data should be provided.
302
- */
303
- this.viewChange = new BehaviorSubject({ start: 0, end: Number.MAX_VALUE });
304
- }
286
+ class CdkTree {
287
+ constructor(_differs, _changeDetectorRef) {
288
+ this._differs = _differs;
289
+ this._changeDetectorRef = _changeDetectorRef;
290
+ /** Subject that emits when the component has been destroyed. */
291
+ this._onDestroy = new Subject();
292
+ /** Level of nodes */
293
+ this._levels = new Map();
294
+ // TODO(tinayuangao): Setup a listener for scrolling, emit the calculated view to viewChange.
295
+ // Remove the MAX_VALUE in viewChange
305
296
  /**
306
- * Provides a stream containing the latest data array to render. Influenced by the tree's
307
- * stream of view window (what dataNodes are currently on screen).
308
- * Data source can be an observable of data array, or a data array to render.
297
+ * Stream containing the latest information on what rows are being displayed on screen.
298
+ * Can be used by the data source to as a heuristic of what data should be provided.
309
299
  */
310
- get dataSource() { return this._dataSource; }
311
- set dataSource(dataSource) {
312
- if (this._dataSource !== dataSource) {
313
- this._switchDataSource(dataSource);
314
- }
300
+ this.viewChange = new BehaviorSubject({ start: 0, end: Number.MAX_VALUE });
301
+ }
302
+ /**
303
+ * Provides a stream containing the latest data array to render. Influenced by the tree's
304
+ * stream of view window (what dataNodes are currently on screen).
305
+ * Data source can be an observable of data array, or a data array to render.
306
+ */
307
+ get dataSource() { return this._dataSource; }
308
+ set dataSource(dataSource) {
309
+ if (this._dataSource !== dataSource) {
310
+ this._switchDataSource(dataSource);
315
311
  }
316
- ngOnInit() {
317
- this._dataDiffer = this._differs.find([]).create(this.trackBy);
318
- if (!this.treeControl) {
319
- throw getTreeControlMissingError();
320
- }
312
+ }
313
+ ngOnInit() {
314
+ this._dataDiffer = this._differs.find([]).create(this.trackBy);
315
+ if (!this.treeControl) {
316
+ throw getTreeControlMissingError();
317
+ }
318
+ }
319
+ ngOnDestroy() {
320
+ this._nodeOutlet.viewContainer.clear();
321
+ this.viewChange.complete();
322
+ this._onDestroy.next();
323
+ this._onDestroy.complete();
324
+ if (this._dataSource && typeof this._dataSource.disconnect === 'function') {
325
+ this.dataSource.disconnect(this);
326
+ }
327
+ if (this._dataSubscription) {
328
+ this._dataSubscription.unsubscribe();
329
+ this._dataSubscription = null;
330
+ }
331
+ }
332
+ ngAfterContentChecked() {
333
+ const defaultNodeDefs = this._nodeDefs.filter(def => !def.when);
334
+ if (defaultNodeDefs.length > 1) {
335
+ throw getTreeMultipleDefaultNodeDefsError();
336
+ }
337
+ this._defaultNodeDef = defaultNodeDefs[0];
338
+ if (this.dataSource && this._nodeDefs && !this._dataSubscription) {
339
+ this._observeRenderChanges();
340
+ }
341
+ }
342
+ // TODO(tinayuangao): Work on keyboard traversal and actions, make sure it's working for RTL
343
+ // and nested trees.
344
+ /**
345
+ * Switch to the provided data source by resetting the data and unsubscribing from the current
346
+ * render change subscription if one exists. If the data source is null, interpret this by
347
+ * clearing the node outlet. Otherwise start listening for new data.
348
+ */
349
+ _switchDataSource(dataSource) {
350
+ if (this._dataSource && typeof this._dataSource.disconnect === 'function') {
351
+ this.dataSource.disconnect(this);
321
352
  }
322
- ngOnDestroy() {
353
+ if (this._dataSubscription) {
354
+ this._dataSubscription.unsubscribe();
355
+ this._dataSubscription = null;
356
+ }
357
+ // Remove the all dataNodes if there is now no data source
358
+ if (!dataSource) {
323
359
  this._nodeOutlet.viewContainer.clear();
324
- this.viewChange.complete();
325
- this._onDestroy.next();
326
- this._onDestroy.complete();
327
- if (this._dataSource && typeof this._dataSource.disconnect === 'function') {
328
- this.dataSource.disconnect(this);
329
- }
330
- if (this._dataSubscription) {
331
- this._dataSubscription.unsubscribe();
332
- this._dataSubscription = null;
333
- }
334
360
  }
335
- ngAfterContentChecked() {
336
- const defaultNodeDefs = this._nodeDefs.filter(def => !def.when);
337
- if (defaultNodeDefs.length > 1) {
338
- throw getTreeMultipleDefaultNodeDefsError();
339
- }
340
- this._defaultNodeDef = defaultNodeDefs[0];
341
- if (this.dataSource && this._nodeDefs && !this._dataSubscription) {
342
- this._observeRenderChanges();
343
- }
361
+ this._dataSource = dataSource;
362
+ if (this._nodeDefs) {
363
+ this._observeRenderChanges();
344
364
  }
345
- // TODO(tinayuangao): Work on keyboard traversal and actions, make sure it's working for RTL
346
- // and nested trees.
347
- /**
348
- * Switch to the provided data source by resetting the data and unsubscribing from the current
349
- * render change subscription if one exists. If the data source is null, interpret this by
350
- * clearing the node outlet. Otherwise start listening for new data.
351
- */
352
- _switchDataSource(dataSource) {
353
- if (this._dataSource && typeof this._dataSource.disconnect === 'function') {
354
- this.dataSource.disconnect(this);
355
- }
356
- if (this._dataSubscription) {
357
- this._dataSubscription.unsubscribe();
358
- this._dataSubscription = null;
359
- }
360
- // Remove the all dataNodes if there is now no data source
361
- if (!dataSource) {
362
- this._nodeOutlet.viewContainer.clear();
363
- }
364
- this._dataSource = dataSource;
365
- if (this._nodeDefs) {
366
- this._observeRenderChanges();
367
- }
365
+ }
366
+ /** Set up a subscription for the data provided by the data source. */
367
+ _observeRenderChanges() {
368
+ let dataStream;
369
+ if (isDataSource(this._dataSource)) {
370
+ dataStream = this._dataSource.connect(this);
368
371
  }
369
- /** Set up a subscription for the data provided by the data source. */
370
- _observeRenderChanges() {
371
- let dataStream;
372
- if (isDataSource(this._dataSource)) {
373
- dataStream = this._dataSource.connect(this);
374
- }
375
- else if (isObservable(this._dataSource)) {
376
- dataStream = this._dataSource;
377
- }
378
- else if (Array.isArray(this._dataSource)) {
379
- dataStream = of(this._dataSource);
380
- }
381
- if (dataStream) {
382
- this._dataSubscription = dataStream.pipe(takeUntil(this._onDestroy))
383
- .subscribe(data => this.renderNodeChanges(data));
384
- }
385
- else {
386
- throw getTreeNoValidDataSourceError();
387
- }
372
+ else if (isObservable(this._dataSource)) {
373
+ dataStream = this._dataSource;
388
374
  }
389
- /** Check for changes made in the data and render each change (node added/removed/moved). */
390
- renderNodeChanges(data, dataDiffer = this._dataDiffer, viewContainer = this._nodeOutlet.viewContainer, parentData) {
391
- const changes = dataDiffer.diff(data);
392
- if (!changes) {
393
- return;
394
- }
395
- changes.forEachOperation((item, adjustedPreviousIndex, currentIndex) => {
396
- if (item.previousIndex == null) {
397
- this.insertNode(data[currentIndex], currentIndex, viewContainer, parentData);
398
- }
399
- else if (currentIndex == null) {
400
- viewContainer.remove(adjustedPreviousIndex);
401
- this._levels.delete(item.item);
402
- }
403
- else {
404
- const view = viewContainer.get(adjustedPreviousIndex);
405
- viewContainer.move(view, currentIndex);
406
- }
407
- });
408
- this._changeDetectorRef.detectChanges();
375
+ else if (Array.isArray(this._dataSource)) {
376
+ dataStream = of(this._dataSource);
409
377
  }
410
- /**
411
- * Finds the matching node definition that should be used for this node data. If there is only
412
- * one node definition, it is returned. Otherwise, find the node definition that has a when
413
- * predicate that returns true with the data. If none return true, return the default node
414
- * definition.
415
- */
416
- _getNodeDef(data, i) {
417
- if (this._nodeDefs.length === 1) {
418
- return this._nodeDefs.first;
419
- }
420
- const nodeDef = this._nodeDefs.find(def => def.when && def.when(i, data)) || this._defaultNodeDef;
421
- if (!nodeDef) {
422
- throw getTreeMissingMatchingNodeDefError();
423
- }
424
- return nodeDef;
378
+ if (dataStream) {
379
+ this._dataSubscription = dataStream.pipe(takeUntil(this._onDestroy))
380
+ .subscribe(data => this.renderNodeChanges(data));
425
381
  }
426
- /**
427
- * Create the embedded view for the data node template and place it in the correct index location
428
- * within the data node view container.
429
- */
430
- insertNode(nodeData, index, viewContainer, parentData) {
431
- const node = this._getNodeDef(nodeData, index);
432
- // Node context that will be provided to created embedded view
433
- const context = new CdkTreeNodeOutletContext(nodeData);
434
- // If the tree is flat tree, then use the `getLevel` function in flat tree control
435
- // Otherwise, use the level of parent node.
436
- if (this.treeControl.getLevel) {
437
- context.level = this.treeControl.getLevel(nodeData);
382
+ else {
383
+ throw getTreeNoValidDataSourceError();
384
+ }
385
+ }
386
+ /** Check for changes made in the data and render each change (node added/removed/moved). */
387
+ renderNodeChanges(data, dataDiffer = this._dataDiffer, viewContainer = this._nodeOutlet.viewContainer, parentData) {
388
+ const changes = dataDiffer.diff(data);
389
+ if (!changes) {
390
+ return;
391
+ }
392
+ changes.forEachOperation((item, adjustedPreviousIndex, currentIndex) => {
393
+ if (item.previousIndex == null) {
394
+ this.insertNode(data[currentIndex], currentIndex, viewContainer, parentData);
438
395
  }
439
- else if (typeof parentData !== 'undefined' && this._levels.has(parentData)) {
440
- context.level = this._levels.get(parentData) + 1;
396
+ else if (currentIndex == null) {
397
+ viewContainer.remove(adjustedPreviousIndex);
398
+ this._levels.delete(item.item);
441
399
  }
442
400
  else {
443
- context.level = 0;
444
- }
445
- this._levels.set(nodeData, context.level);
446
- // Use default tree nodeOutlet, or nested node's nodeOutlet
447
- const container = viewContainer ? viewContainer : this._nodeOutlet.viewContainer;
448
- container.createEmbeddedView(node.template, context, index);
449
- // Set the data to just created `CdkTreeNode`.
450
- // The `CdkTreeNode` created from `createEmbeddedView` will be saved in static variable
451
- // `mostRecentTreeNode`. We get it from static variable and pass the node data to it.
452
- if (CdkTreeNode.mostRecentTreeNode) {
453
- CdkTreeNode.mostRecentTreeNode.data = nodeData;
401
+ const view = viewContainer.get(adjustedPreviousIndex);
402
+ viewContainer.move(view, currentIndex);
454
403
  }
404
+ });
405
+ this._changeDetectorRef.detectChanges();
406
+ }
407
+ /**
408
+ * Finds the matching node definition that should be used for this node data. If there is only
409
+ * one node definition, it is returned. Otherwise, find the node definition that has a when
410
+ * predicate that returns true with the data. If none return true, return the default node
411
+ * definition.
412
+ */
413
+ _getNodeDef(data, i) {
414
+ if (this._nodeDefs.length === 1) {
415
+ return this._nodeDefs.first;
416
+ }
417
+ const nodeDef = this._nodeDefs.find(def => def.when && def.when(i, data)) || this._defaultNodeDef;
418
+ if (!nodeDef) {
419
+ throw getTreeMissingMatchingNodeDefError();
455
420
  }
421
+ return nodeDef;
456
422
  }
457
- CdkTree.decorators = [
458
- { type: Component, args: [{
459
- selector: 'cdk-tree',
460
- exportAs: 'cdkTree',
461
- template: `<ng-container cdkTreeNodeOutlet></ng-container>`,
462
- host: {
463
- 'class': 'cdk-tree',
464
- 'role': 'tree',
465
- },
466
- encapsulation: ViewEncapsulation.None,
467
- // The "OnPush" status for the `CdkTree` component is effectively a noop, so we are removing it.
468
- // The view for `CdkTree` consists entirely of templates declared in other views. As they are
469
- // declared elsewhere, they are checked when their declaration points are checked.
470
- // tslint:disable-next-line:validate-decorators
471
- changeDetection: ChangeDetectionStrategy.Default
472
- },] }
473
- ];
474
- CdkTree.ctorParameters = () => [
475
- { type: IterableDiffers },
476
- { type: ChangeDetectorRef }
477
- ];
478
- CdkTree.propDecorators = {
479
- dataSource: [{ type: Input }],
480
- treeControl: [{ type: Input }],
481
- trackBy: [{ type: Input }],
482
- _nodeOutlet: [{ type: ViewChild, args: [CdkTreeNodeOutlet, { static: true },] }],
483
- _nodeDefs: [{ type: ContentChildren, args: [CdkTreeNodeDef, {
484
- // We need to use `descendants: true`, because Ivy will no longer match
485
- // indirect descendants if it's left as false.
486
- descendants: true
487
- },] }]
488
- };
489
- return CdkTree;
490
- })();
423
+ /**
424
+ * Create the embedded view for the data node template and place it in the correct index location
425
+ * within the data node view container.
426
+ */
427
+ insertNode(nodeData, index, viewContainer, parentData) {
428
+ const node = this._getNodeDef(nodeData, index);
429
+ // Node context that will be provided to created embedded view
430
+ const context = new CdkTreeNodeOutletContext(nodeData);
431
+ // If the tree is flat tree, then use the `getLevel` function in flat tree control
432
+ // Otherwise, use the level of parent node.
433
+ if (this.treeControl.getLevel) {
434
+ context.level = this.treeControl.getLevel(nodeData);
435
+ }
436
+ else if (typeof parentData !== 'undefined' && this._levels.has(parentData)) {
437
+ context.level = this._levels.get(parentData) + 1;
438
+ }
439
+ else {
440
+ context.level = 0;
441
+ }
442
+ this._levels.set(nodeData, context.level);
443
+ // Use default tree nodeOutlet, or nested node's nodeOutlet
444
+ const container = viewContainer ? viewContainer : this._nodeOutlet.viewContainer;
445
+ container.createEmbeddedView(node.template, context, index);
446
+ // Set the data to just created `CdkTreeNode`.
447
+ // The `CdkTreeNode` created from `createEmbeddedView` will be saved in static variable
448
+ // `mostRecentTreeNode`. We get it from static variable and pass the node data to it.
449
+ if (CdkTreeNode.mostRecentTreeNode) {
450
+ CdkTreeNode.mostRecentTreeNode.data = nodeData;
451
+ }
452
+ }
453
+ }
454
+ CdkTree.decorators = [
455
+ { type: Component, args: [{
456
+ selector: 'cdk-tree',
457
+ exportAs: 'cdkTree',
458
+ template: `<ng-container cdkTreeNodeOutlet></ng-container>`,
459
+ host: {
460
+ 'class': 'cdk-tree',
461
+ 'role': 'tree',
462
+ },
463
+ encapsulation: ViewEncapsulation.None,
464
+ // The "OnPush" status for the `CdkTree` component is effectively a noop, so we are removing it.
465
+ // The view for `CdkTree` consists entirely of templates declared in other views. As they are
466
+ // declared elsewhere, they are checked when their declaration points are checked.
467
+ // tslint:disable-next-line:validate-decorators
468
+ changeDetection: ChangeDetectionStrategy.Default
469
+ },] }
470
+ ];
471
+ CdkTree.ctorParameters = () => [
472
+ { type: IterableDiffers },
473
+ { type: ChangeDetectorRef }
474
+ ];
475
+ CdkTree.propDecorators = {
476
+ dataSource: [{ type: Input }],
477
+ treeControl: [{ type: Input }],
478
+ trackBy: [{ type: Input }],
479
+ _nodeOutlet: [{ type: ViewChild, args: [CdkTreeNodeOutlet, { static: true },] }],
480
+ _nodeDefs: [{ type: ContentChildren, args: [CdkTreeNodeDef, {
481
+ // We need to use `descendants: true`, because Ivy will no longer match
482
+ // indirect descendants if it's left as false.
483
+ descendants: true
484
+ },] }]
485
+ };
491
486
  /**
492
487
  * Tree node for CdkTree. It contains the data in the tree node.
493
488
  */
494
- let CdkTreeNode = /** @class */ (() => {
495
- class CdkTreeNode {
496
- constructor(_elementRef, _tree) {
497
- this._elementRef = _elementRef;
498
- this._tree = _tree;
499
- /** Subject that emits when the component has been destroyed. */
500
- this._destroyed = new Subject();
501
- /** Emits when the node's data has changed. */
502
- this._dataChanges = new Subject();
503
- /**
504
- * The role of the node should be 'group' if it's an internal node,
505
- * and 'treeitem' if it's a leaf node.
506
- */
507
- this.role = 'treeitem';
508
- CdkTreeNode.mostRecentTreeNode = this;
509
- }
510
- /** The tree node's data. */
511
- get data() { return this._data; }
512
- set data(value) {
513
- if (value !== this._data) {
514
- this._data = value;
515
- this._setRoleFromData();
516
- this._dataChanges.next();
517
- }
518
- }
519
- get isExpanded() {
520
- return this._tree.treeControl.isExpanded(this._data);
489
+ class CdkTreeNode {
490
+ constructor(_elementRef, _tree) {
491
+ this._elementRef = _elementRef;
492
+ this._tree = _tree;
493
+ /** Subject that emits when the component has been destroyed. */
494
+ this._destroyed = new Subject();
495
+ /** Emits when the node's data has changed. */
496
+ this._dataChanges = new Subject();
497
+ /**
498
+ * The role of the node should be 'group' if it's an internal node,
499
+ * and 'treeitem' if it's a leaf node.
500
+ */
501
+ this.role = 'treeitem';
502
+ CdkTreeNode.mostRecentTreeNode = this;
503
+ }
504
+ /** The tree node's data. */
505
+ get data() { return this._data; }
506
+ set data(value) {
507
+ if (value !== this._data) {
508
+ this._data = value;
509
+ this._setRoleFromData();
510
+ this._dataChanges.next();
521
511
  }
522
- get level() {
523
- return this._tree.treeControl.getLevel ? this._tree.treeControl.getLevel(this._data) : 0;
512
+ }
513
+ get isExpanded() {
514
+ return this._tree.treeControl.isExpanded(this._data);
515
+ }
516
+ get level() {
517
+ return this._tree.treeControl.getLevel ? this._tree.treeControl.getLevel(this._data) : 0;
518
+ }
519
+ ngOnDestroy() {
520
+ // If this is the last tree node being destroyed,
521
+ // clear out the reference to avoid leaking memory.
522
+ if (CdkTreeNode.mostRecentTreeNode === this) {
523
+ CdkTreeNode.mostRecentTreeNode = null;
524
+ }
525
+ this._dataChanges.complete();
526
+ this._destroyed.next();
527
+ this._destroyed.complete();
528
+ }
529
+ /** Focuses the menu item. Implements for FocusableOption. */
530
+ focus() {
531
+ this._elementRef.nativeElement.focus();
532
+ }
533
+ _setRoleFromData() {
534
+ if (this._tree.treeControl.isExpandable) {
535
+ this.role = this._tree.treeControl.isExpandable(this._data) ? 'group' : 'treeitem';
524
536
  }
525
- ngOnDestroy() {
526
- // If this is the last tree node being destroyed,
527
- // clear out the reference to avoid leaking memory.
528
- if (CdkTreeNode.mostRecentTreeNode === this) {
529
- CdkTreeNode.mostRecentTreeNode = null;
537
+ else {
538
+ if (!this._tree.treeControl.getChildren) {
539
+ throw getTreeControlFunctionsMissingError();
530
540
  }
531
- this._dataChanges.complete();
532
- this._destroyed.next();
533
- this._destroyed.complete();
534
- }
535
- /** Focuses the menu item. Implements for FocusableOption. */
536
- focus() {
537
- this._elementRef.nativeElement.focus();
538
- }
539
- _setRoleFromData() {
540
- if (this._tree.treeControl.isExpandable) {
541
- this.role = this._tree.treeControl.isExpandable(this._data) ? 'group' : 'treeitem';
541
+ const childrenNodes = this._tree.treeControl.getChildren(this._data);
542
+ if (Array.isArray(childrenNodes)) {
543
+ this._setRoleFromChildren(childrenNodes);
542
544
  }
543
- else {
544
- if (!this._tree.treeControl.getChildren) {
545
- throw getTreeControlFunctionsMissingError();
546
- }
547
- const childrenNodes = this._tree.treeControl.getChildren(this._data);
548
- if (Array.isArray(childrenNodes)) {
549
- this._setRoleFromChildren(childrenNodes);
550
- }
551
- else if (isObservable(childrenNodes)) {
552
- childrenNodes.pipe(takeUntil(this._destroyed))
553
- .subscribe(children => this._setRoleFromChildren(children));
554
- }
545
+ else if (isObservable(childrenNodes)) {
546
+ childrenNodes.pipe(takeUntil(this._destroyed))
547
+ .subscribe(children => this._setRoleFromChildren(children));
555
548
  }
556
549
  }
557
- _setRoleFromChildren(children) {
558
- this.role = children && children.length ? 'group' : 'treeitem';
559
- }
560
550
  }
561
- /**
562
- * The most recently created `CdkTreeNode`. We save it in static variable so we can retrieve it
563
- * in `CdkTree` and set the data to it.
564
- */
565
- CdkTreeNode.mostRecentTreeNode = null;
566
- CdkTreeNode.decorators = [
567
- { type: Directive, args: [{
568
- selector: 'cdk-tree-node',
569
- exportAs: 'cdkTreeNode',
570
- host: {
571
- '[attr.aria-expanded]': 'isExpanded',
572
- '[attr.aria-level]': 'role === "treeitem" ? level : null',
573
- '[attr.role]': 'role',
574
- 'class': 'cdk-tree-node',
575
- },
576
- },] }
577
- ];
578
- CdkTreeNode.ctorParameters = () => [
579
- { type: ElementRef },
580
- { type: CdkTree }
581
- ];
582
- CdkTreeNode.propDecorators = {
583
- role: [{ type: Input }]
584
- };
585
- return CdkTreeNode;
586
- })();
551
+ _setRoleFromChildren(children) {
552
+ this.role = children && children.length ? 'group' : 'treeitem';
553
+ }
554
+ }
555
+ /**
556
+ * The most recently created `CdkTreeNode`. We save it in static variable so we can retrieve it
557
+ * in `CdkTree` and set the data to it.
558
+ */
559
+ CdkTreeNode.mostRecentTreeNode = null;
560
+ CdkTreeNode.decorators = [
561
+ { type: Directive, args: [{
562
+ selector: 'cdk-tree-node',
563
+ exportAs: 'cdkTreeNode',
564
+ host: {
565
+ '[attr.aria-expanded]': 'isExpanded',
566
+ '[attr.aria-level]': 'role === "treeitem" ? level : null',
567
+ '[attr.role]': 'role',
568
+ 'class': 'cdk-tree-node',
569
+ },
570
+ },] }
571
+ ];
572
+ CdkTreeNode.ctorParameters = () => [
573
+ { type: ElementRef },
574
+ { type: CdkTree }
575
+ ];
576
+ CdkTreeNode.propDecorators = {
577
+ role: [{ type: Input }]
578
+ };
587
579
 
588
580
  /**
589
581
  * @license
@@ -598,94 +590,91 @@ let CdkTreeNode = /** @class */ (() => {
598
590
  * be added in the `cdkTreeNodeOutlet` in tree node template.
599
591
  * The children of node will be automatically added to `cdkTreeNodeOutlet`.
600
592
  */
601
- let CdkNestedTreeNode = /** @class */ (() => {
602
- class CdkNestedTreeNode extends CdkTreeNode {
603
- constructor(_elementRef, _tree, _differs) {
604
- super(_elementRef, _tree);
605
- this._elementRef = _elementRef;
606
- this._tree = _tree;
607
- this._differs = _differs;
608
- }
609
- ngAfterContentInit() {
610
- this._dataDiffer = this._differs.find([]).create(this._tree.trackBy);
611
- if (!this._tree.treeControl.getChildren) {
612
- throw getTreeControlFunctionsMissingError();
613
- }
614
- const childrenNodes = this._tree.treeControl.getChildren(this.data);
615
- if (Array.isArray(childrenNodes)) {
616
- this.updateChildrenNodes(childrenNodes);
617
- }
618
- else if (isObservable(childrenNodes)) {
619
- childrenNodes.pipe(takeUntil(this._destroyed))
620
- .subscribe(result => this.updateChildrenNodes(result));
621
- }
622
- this.nodeOutlet.changes.pipe(takeUntil(this._destroyed))
623
- .subscribe(() => this.updateChildrenNodes());
624
- }
625
- ngOnDestroy() {
626
- this._clear();
627
- super.ngOnDestroy();
628
- }
629
- /** Add children dataNodes to the NodeOutlet */
630
- updateChildrenNodes(children) {
631
- const outlet = this._getNodeOutlet();
632
- if (children) {
633
- this._children = children;
634
- }
635
- if (outlet && this._children) {
636
- const viewContainer = outlet.viewContainer;
637
- this._tree.renderNodeChanges(this._children, this._dataDiffer, viewContainer, this._data);
638
- }
639
- else {
640
- // Reset the data differ if there's no children nodes displayed
641
- this._dataDiffer.diff([]);
642
- }
593
+ class CdkNestedTreeNode extends CdkTreeNode {
594
+ constructor(_elementRef, _tree, _differs) {
595
+ super(_elementRef, _tree);
596
+ this._elementRef = _elementRef;
597
+ this._tree = _tree;
598
+ this._differs = _differs;
599
+ }
600
+ ngAfterContentInit() {
601
+ this._dataDiffer = this._differs.find([]).create(this._tree.trackBy);
602
+ if (!this._tree.treeControl.getChildren) {
603
+ throw getTreeControlFunctionsMissingError();
643
604
  }
644
- /** Clear the children dataNodes. */
645
- _clear() {
646
- const outlet = this._getNodeOutlet();
647
- if (outlet) {
648
- outlet.viewContainer.clear();
649
- this._dataDiffer.diff([]);
650
- }
605
+ const childrenNodes = this._tree.treeControl.getChildren(this.data);
606
+ if (Array.isArray(childrenNodes)) {
607
+ this.updateChildrenNodes(childrenNodes);
608
+ }
609
+ else if (isObservable(childrenNodes)) {
610
+ childrenNodes.pipe(takeUntil(this._destroyed))
611
+ .subscribe(result => this.updateChildrenNodes(result));
651
612
  }
652
- /** Gets the outlet for the current node. */
653
- _getNodeOutlet() {
654
- const outlets = this.nodeOutlet;
655
- // Note that since we use `descendants: true` on the query, we have to ensure
656
- // that we don't pick up the outlet of a child node by accident.
657
- return outlets && outlets.find(outlet => !outlet._node || outlet._node === this);
658
- }
659
- }
660
- CdkNestedTreeNode.decorators = [
661
- { type: Directive, args: [{
662
- selector: 'cdk-nested-tree-node',
663
- exportAs: 'cdkNestedTreeNode',
664
- host: {
665
- '[attr.aria-expanded]': 'isExpanded',
666
- '[attr.role]': 'role',
667
- 'class': 'cdk-tree-node cdk-nested-tree-node',
668
- },
669
- providers: [
670
- { provide: CdkTreeNode, useExisting: CdkNestedTreeNode },
671
- { provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: CdkNestedTreeNode }
672
- ]
673
- },] }
674
- ];
675
- CdkNestedTreeNode.ctorParameters = () => [
676
- { type: ElementRef },
677
- { type: CdkTree },
678
- { type: IterableDiffers }
679
- ];
680
- CdkNestedTreeNode.propDecorators = {
681
- nodeOutlet: [{ type: ContentChildren, args: [CdkTreeNodeOutlet, {
682
- // We need to use `descendants: true`, because Ivy will no longer match
683
- // indirect descendants if it's left as false.
684
- descendants: true
685
- },] }]
686
- };
687
- return CdkNestedTreeNode;
688
- })();
613
+ this.nodeOutlet.changes.pipe(takeUntil(this._destroyed))
614
+ .subscribe(() => this.updateChildrenNodes());
615
+ }
616
+ ngOnDestroy() {
617
+ this._clear();
618
+ super.ngOnDestroy();
619
+ }
620
+ /** Add children dataNodes to the NodeOutlet */
621
+ updateChildrenNodes(children) {
622
+ const outlet = this._getNodeOutlet();
623
+ if (children) {
624
+ this._children = children;
625
+ }
626
+ if (outlet && this._children) {
627
+ const viewContainer = outlet.viewContainer;
628
+ this._tree.renderNodeChanges(this._children, this._dataDiffer, viewContainer, this._data);
629
+ }
630
+ else {
631
+ // Reset the data differ if there's no children nodes displayed
632
+ this._dataDiffer.diff([]);
633
+ }
634
+ }
635
+ /** Clear the children dataNodes. */
636
+ _clear() {
637
+ const outlet = this._getNodeOutlet();
638
+ if (outlet) {
639
+ outlet.viewContainer.clear();
640
+ this._dataDiffer.diff([]);
641
+ }
642
+ }
643
+ /** Gets the outlet for the current node. */
644
+ _getNodeOutlet() {
645
+ const outlets = this.nodeOutlet;
646
+ // Note that since we use `descendants: true` on the query, we have to ensure
647
+ // that we don't pick up the outlet of a child node by accident.
648
+ return outlets && outlets.find(outlet => !outlet._node || outlet._node === this);
649
+ }
650
+ }
651
+ CdkNestedTreeNode.decorators = [
652
+ { type: Directive, args: [{
653
+ selector: 'cdk-nested-tree-node',
654
+ exportAs: 'cdkNestedTreeNode',
655
+ host: {
656
+ '[attr.aria-expanded]': 'isExpanded',
657
+ '[attr.role]': 'role',
658
+ 'class': 'cdk-tree-node cdk-nested-tree-node',
659
+ },
660
+ providers: [
661
+ { provide: CdkTreeNode, useExisting: CdkNestedTreeNode },
662
+ { provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: CdkNestedTreeNode }
663
+ ]
664
+ },] }
665
+ ];
666
+ CdkNestedTreeNode.ctorParameters = () => [
667
+ { type: ElementRef },
668
+ { type: CdkTree },
669
+ { type: IterableDiffers }
670
+ ];
671
+ CdkNestedTreeNode.propDecorators = {
672
+ nodeOutlet: [{ type: ContentChildren, args: [CdkTreeNodeOutlet, {
673
+ // We need to use `descendants: true`, because Ivy will no longer match
674
+ // indirect descendants if it's left as false.
675
+ descendants: true
676
+ },] }]
677
+ };
689
678
 
690
679
  /**
691
680
  * @license
@@ -700,100 +689,97 @@ const cssUnitPattern = /([A-Za-z%]+)$/;
700
689
  * Indent for the children tree dataNodes.
701
690
  * This directive will add left-padding to the node to show hierarchy.
702
691
  */
703
- let CdkTreeNodePadding = /** @class */ (() => {
704
- class CdkTreeNodePadding {
705
- constructor(_treeNode, _tree,
706
- /**
707
- * @deprecated _renderer parameter no longer being used. To be removed.
708
- * @breaking-change 11.0.0
709
- */
710
- _renderer, _element, _dir) {
711
- this._treeNode = _treeNode;
712
- this._tree = _tree;
713
- this._element = _element;
714
- this._dir = _dir;
715
- /** Subject that emits when the component has been destroyed. */
716
- this._destroyed = new Subject();
717
- /** CSS units used for the indentation value. */
718
- this.indentUnits = 'px';
719
- this._indent = 40;
720
- this._setPadding();
721
- if (_dir) {
722
- _dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => this._setPadding(true));
723
- }
724
- // In Ivy the indentation binding might be set before the tree node's data has been added,
725
- // which means that we'll miss the first render. We have to subscribe to changes in the
726
- // data to ensure that everything is up to date.
727
- _treeNode._dataChanges.subscribe(() => this._setPadding());
728
- }
729
- /** The level of depth of the tree node. The padding will be `level * indent` pixels. */
730
- get level() { return this._level; }
731
- set level(value) {
732
- // Set to null as the fallback value so that _setPadding can fall back to the node level if the
733
- // consumer set the directive as `cdkTreeNodePadding=""`. We still want to take this value if
734
- // they set 0 explicitly.
735
- this._level = coerceNumberProperty(value, null);
736
- this._setPadding();
737
- }
738
- /**
739
- * The indent for each level. Can be a number or a CSS string.
740
- * Default number 40px from material design menu sub-menu spec.
741
- */
742
- get indent() { return this._indent; }
743
- set indent(indent) {
744
- let value = indent;
745
- let units = 'px';
746
- if (typeof indent === 'string') {
747
- const parts = indent.split(cssUnitPattern);
748
- value = parts[0];
749
- units = parts[1] || units;
750
- }
751
- this.indentUnits = units;
752
- this._indent = coerceNumberProperty(value);
753
- this._setPadding();
754
- }
755
- ngOnDestroy() {
756
- this._destroyed.next();
757
- this._destroyed.complete();
758
- }
759
- /** The padding indent value for the tree node. Returns a string with px numbers if not null. */
760
- _paddingIndent() {
761
- const nodeLevel = (this._treeNode.data && this._tree.treeControl.getLevel)
762
- ? this._tree.treeControl.getLevel(this._treeNode.data)
763
- : null;
764
- const level = this._level == null ? nodeLevel : this._level;
765
- return typeof level === 'number' ? `${level * this._indent}${this.indentUnits}` : null;
766
- }
767
- _setPadding(forceChange = false) {
768
- const padding = this._paddingIndent();
769
- if (padding !== this._currentPadding || forceChange) {
770
- const element = this._element.nativeElement;
771
- const paddingProp = this._dir && this._dir.value === 'rtl' ? 'paddingRight' : 'paddingLeft';
772
- const resetProp = paddingProp === 'paddingLeft' ? 'paddingRight' : 'paddingLeft';
773
- element.style[paddingProp] = padding || '';
774
- element.style[resetProp] = '';
775
- this._currentPadding = padding;
776
- }
692
+ class CdkTreeNodePadding {
693
+ constructor(_treeNode, _tree,
694
+ /**
695
+ * @deprecated _renderer parameter no longer being used. To be removed.
696
+ * @breaking-change 11.0.0
697
+ */
698
+ _renderer, _element, _dir) {
699
+ this._treeNode = _treeNode;
700
+ this._tree = _tree;
701
+ this._element = _element;
702
+ this._dir = _dir;
703
+ /** Subject that emits when the component has been destroyed. */
704
+ this._destroyed = new Subject();
705
+ /** CSS units used for the indentation value. */
706
+ this.indentUnits = 'px';
707
+ this._indent = 40;
708
+ this._setPadding();
709
+ if (_dir) {
710
+ _dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => this._setPadding(true));
711
+ }
712
+ // In Ivy the indentation binding might be set before the tree node's data has been added,
713
+ // which means that we'll miss the first render. We have to subscribe to changes in the
714
+ // data to ensure that everything is up to date.
715
+ _treeNode._dataChanges.subscribe(() => this._setPadding());
716
+ }
717
+ /** The level of depth of the tree node. The padding will be `level * indent` pixels. */
718
+ get level() { return this._level; }
719
+ set level(value) {
720
+ // Set to null as the fallback value so that _setPadding can fall back to the node level if the
721
+ // consumer set the directive as `cdkTreeNodePadding=""`. We still want to take this value if
722
+ // they set 0 explicitly.
723
+ this._level = coerceNumberProperty(value, null);
724
+ this._setPadding();
725
+ }
726
+ /**
727
+ * The indent for each level. Can be a number or a CSS string.
728
+ * Default number 40px from material design menu sub-menu spec.
729
+ */
730
+ get indent() { return this._indent; }
731
+ set indent(indent) {
732
+ let value = indent;
733
+ let units = 'px';
734
+ if (typeof indent === 'string') {
735
+ const parts = indent.split(cssUnitPattern);
736
+ value = parts[0];
737
+ units = parts[1] || units;
738
+ }
739
+ this.indentUnits = units;
740
+ this._indent = coerceNumberProperty(value);
741
+ this._setPadding();
742
+ }
743
+ ngOnDestroy() {
744
+ this._destroyed.next();
745
+ this._destroyed.complete();
746
+ }
747
+ /** The padding indent value for the tree node. Returns a string with px numbers if not null. */
748
+ _paddingIndent() {
749
+ const nodeLevel = (this._treeNode.data && this._tree.treeControl.getLevel)
750
+ ? this._tree.treeControl.getLevel(this._treeNode.data)
751
+ : null;
752
+ const level = this._level == null ? nodeLevel : this._level;
753
+ return typeof level === 'number' ? `${level * this._indent}${this.indentUnits}` : null;
754
+ }
755
+ _setPadding(forceChange = false) {
756
+ const padding = this._paddingIndent();
757
+ if (padding !== this._currentPadding || forceChange) {
758
+ const element = this._element.nativeElement;
759
+ const paddingProp = this._dir && this._dir.value === 'rtl' ? 'paddingRight' : 'paddingLeft';
760
+ const resetProp = paddingProp === 'paddingLeft' ? 'paddingRight' : 'paddingLeft';
761
+ element.style[paddingProp] = padding || '';
762
+ element.style[resetProp] = '';
763
+ this._currentPadding = padding;
777
764
  }
778
765
  }
779
- CdkTreeNodePadding.decorators = [
780
- { type: Directive, args: [{
781
- selector: '[cdkTreeNodePadding]',
782
- },] }
783
- ];
784
- CdkTreeNodePadding.ctorParameters = () => [
785
- { type: CdkTreeNode },
786
- { type: CdkTree },
787
- { type: Renderer2 },
788
- { type: ElementRef },
789
- { type: Directionality, decorators: [{ type: Optional }] }
790
- ];
791
- CdkTreeNodePadding.propDecorators = {
792
- level: [{ type: Input, args: ['cdkTreeNodePadding',] }],
793
- indent: [{ type: Input, args: ['cdkTreeNodePaddingIndent',] }]
794
- };
795
- return CdkTreeNodePadding;
796
- })();
766
+ }
767
+ CdkTreeNodePadding.decorators = [
768
+ { type: Directive, args: [{
769
+ selector: '[cdkTreeNodePadding]',
770
+ },] }
771
+ ];
772
+ CdkTreeNodePadding.ctorParameters = () => [
773
+ { type: CdkTreeNode },
774
+ { type: CdkTree },
775
+ { type: Renderer2 },
776
+ { type: ElementRef },
777
+ { type: Directionality, decorators: [{ type: Optional }] }
778
+ ];
779
+ CdkTreeNodePadding.propDecorators = {
780
+ level: [{ type: Input, args: ['cdkTreeNodePadding',] }],
781
+ indent: [{ type: Input, args: ['cdkTreeNodePaddingIndent',] }]
782
+ };
797
783
 
798
784
  /**
799
785
  * @license
@@ -805,41 +791,38 @@ let CdkTreeNodePadding = /** @class */ (() => {
805
791
  /**
806
792
  * Node toggle to expand/collapse the node.
807
793
  */
808
- let CdkTreeNodeToggle = /** @class */ (() => {
809
- class CdkTreeNodeToggle {
810
- constructor(_tree, _treeNode) {
811
- this._tree = _tree;
812
- this._treeNode = _treeNode;
813
- this._recursive = false;
814
- }
815
- /** Whether expand/collapse the node recursively. */
816
- get recursive() { return this._recursive; }
817
- set recursive(value) { this._recursive = coerceBooleanProperty(value); }
818
- // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
819
- // In Ivy the `host` bindings will be merged when this class is extended, whereas in
820
- // ViewEngine they're overwritten.
821
- // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
822
- // tslint:disable-next-line:no-host-decorator-in-concrete
823
- _toggle(event) {
824
- this.recursive
825
- ? this._tree.treeControl.toggleDescendants(this._treeNode.data)
826
- : this._tree.treeControl.toggle(this._treeNode.data);
827
- event.stopPropagation();
828
- }
829
- }
830
- CdkTreeNodeToggle.decorators = [
831
- { type: Directive, args: [{ selector: '[cdkTreeNodeToggle]' },] }
832
- ];
833
- CdkTreeNodeToggle.ctorParameters = () => [
834
- { type: CdkTree },
835
- { type: CdkTreeNode }
836
- ];
837
- CdkTreeNodeToggle.propDecorators = {
838
- recursive: [{ type: Input, args: ['cdkTreeNodeToggleRecursive',] }],
839
- _toggle: [{ type: HostListener, args: ['click', ['$event'],] }]
840
- };
841
- return CdkTreeNodeToggle;
842
- })();
794
+ class CdkTreeNodeToggle {
795
+ constructor(_tree, _treeNode) {
796
+ this._tree = _tree;
797
+ this._treeNode = _treeNode;
798
+ this._recursive = false;
799
+ }
800
+ /** Whether expand/collapse the node recursively. */
801
+ get recursive() { return this._recursive; }
802
+ set recursive(value) { this._recursive = coerceBooleanProperty(value); }
803
+ // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
804
+ // In Ivy the `host` bindings will be merged when this class is extended, whereas in
805
+ // ViewEngine they're overwritten.
806
+ // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
807
+ // tslint:disable-next-line:no-host-decorator-in-concrete
808
+ _toggle(event) {
809
+ this.recursive
810
+ ? this._tree.treeControl.toggleDescendants(this._treeNode.data)
811
+ : this._tree.treeControl.toggle(this._treeNode.data);
812
+ event.stopPropagation();
813
+ }
814
+ }
815
+ CdkTreeNodeToggle.decorators = [
816
+ { type: Directive, args: [{ selector: '[cdkTreeNodeToggle]' },] }
817
+ ];
818
+ CdkTreeNodeToggle.ctorParameters = () => [
819
+ { type: CdkTree },
820
+ { type: CdkTreeNode }
821
+ ];
822
+ CdkTreeNodeToggle.propDecorators = {
823
+ recursive: [{ type: Input, args: ['cdkTreeNodeToggleRecursive',] }],
824
+ _toggle: [{ type: HostListener, args: ['click', ['$event'],] }]
825
+ };
843
826
 
844
827
  /**
845
828
  * @license
@@ -857,18 +840,15 @@ const EXPORTED_DECLARATIONS = [
857
840
  CdkTreeNode,
858
841
  CdkTreeNodeOutlet,
859
842
  ];
860
- let CdkTreeModule = /** @class */ (() => {
861
- class CdkTreeModule {
862
- }
863
- CdkTreeModule.decorators = [
864
- { type: NgModule, args: [{
865
- exports: EXPORTED_DECLARATIONS,
866
- declarations: EXPORTED_DECLARATIONS,
867
- providers: [FocusMonitor, CdkTreeNodeDef]
868
- },] }
869
- ];
870
- return CdkTreeModule;
871
- })();
843
+ class CdkTreeModule {
844
+ }
845
+ CdkTreeModule.decorators = [
846
+ { type: NgModule, args: [{
847
+ exports: EXPORTED_DECLARATIONS,
848
+ declarations: EXPORTED_DECLARATIONS,
849
+ providers: [FocusMonitor, CdkTreeNodeDef]
850
+ },] }
851
+ ];
872
852
 
873
853
  /**
874
854
  * @license