@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.
- package/a11y/aria-describer/aria-describer.d.ts +10 -1
- package/a11y/focus-trap/focus-trap.d.ts +4 -2
- package/a11y/index.metadata.json +1 -1
- package/a11y/interactivity-checker/interactivity-checker.d.ts +11 -1
- package/a11y/key-manager/list-key-manager.d.ts +6 -0
- package/accordion/accordion.d.ts +7 -1
- package/accordion/index.d.ts +1 -0
- package/accordion/index.metadata.json +1 -1
- package/bundles/cdk-a11y.umd.js +78 -15
- package/bundles/cdk-a11y.umd.js.map +1 -1
- package/bundles/cdk-a11y.umd.min.js +11 -11
- package/bundles/cdk-a11y.umd.min.js.map +1 -1
- package/bundles/cdk-accordion.umd.js +12 -4
- package/bundles/cdk-accordion.umd.js.map +1 -1
- package/bundles/cdk-accordion.umd.min.js +2 -2
- package/bundles/cdk-accordion.umd.min.js.map +1 -1
- package/bundles/cdk-drag-drop.umd.js +717 -641
- package/bundles/cdk-drag-drop.umd.js.map +1 -1
- package/bundles/cdk-drag-drop.umd.min.js +8 -16
- package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
- package/bundles/cdk-overlay.umd.js +199 -42
- package/bundles/cdk-overlay.umd.js.map +1 -1
- package/bundles/cdk-overlay.umd.min.js +11 -18
- package/bundles/cdk-overlay.umd.min.js.map +1 -1
- package/bundles/cdk-platform.umd.js +0 -1
- package/bundles/cdk-platform.umd.js.map +1 -1
- package/bundles/cdk-platform.umd.min.js +2 -2
- package/bundles/cdk-platform.umd.min.js.map +1 -1
- package/bundles/cdk-scrolling.umd.js +26 -4
- package/bundles/cdk-scrolling.umd.js.map +1 -1
- package/bundles/cdk-scrolling.umd.min.js +11 -4
- package/bundles/cdk-scrolling.umd.min.js.map +1 -1
- package/bundles/cdk-testing-protractor.umd.min.js +1 -1
- package/bundles/cdk-testing-protractor.umd.min.js.map +1 -1
- package/bundles/cdk-testing-testbed.umd.min.js +8 -8
- package/bundles/cdk-testing-testbed.umd.min.js.map +1 -1
- package/bundles/cdk-testing.umd.js +32 -0
- package/bundles/cdk-testing.umd.js.map +1 -1
- package/bundles/cdk-testing.umd.min.js +5 -5
- package/bundles/cdk-testing.umd.min.js.map +1 -1
- package/bundles/cdk-tree.umd.js +6 -2
- package/bundles/cdk-tree.umd.js.map +1 -1
- package/bundles/cdk-tree.umd.min.js +3 -3
- package/bundles/cdk-tree.umd.min.js.map +1 -1
- package/bundles/cdk.umd.js +1 -1
- package/bundles/cdk.umd.js.map +1 -1
- package/bundles/cdk.umd.min.js +1 -1
- package/bundles/cdk.umd.min.js.map +1 -1
- package/drag-drop/directives/drag-handle.d.ts +7 -1
- package/drag-drop/directives/drag-placeholder.d.ts +7 -1
- package/drag-drop/directives/drag-preview.d.ts +7 -1
- package/drag-drop/directives/drag.d.ts +4 -14
- package/drag-drop/directives/drop-list-group.d.ts +7 -1
- package/drag-drop/directives/drop-list.d.ts +7 -1
- package/drag-drop/drag-ref.d.ts +6 -0
- package/drag-drop/drop-list-ref.d.ts +3 -2
- package/drag-drop/index.d.ts +2 -2
- package/drag-drop/index.metadata.json +1 -1
- package/esm2015/a11y/a11y-module.js +15 -19
- package/esm2015/a11y/aria-describer/aria-describer.js +177 -167
- package/esm2015/a11y/focus-monitor/focus-monitor.js +337 -345
- package/esm2015/a11y/focus-trap/configurable-focus-trap-factory.js +30 -34
- package/esm2015/a11y/focus-trap/focus-trap-manager.js +36 -40
- package/esm2015/a11y/focus-trap/focus-trap.js +85 -82
- package/esm2015/a11y/high-contrast-mode/high-contrast-mode-detector.js +56 -60
- package/esm2015/a11y/interactivity-checker/interactivity-checker.js +113 -104
- package/esm2015/a11y/key-manager/list-key-manager.js +29 -4
- package/esm2015/a11y/live-announcer/live-announcer.js +138 -146
- package/esm2015/accordion/accordion-item.js +119 -123
- package/esm2015/accordion/accordion-module.js +9 -13
- package/esm2015/accordion/accordion.js +49 -46
- package/esm2015/accordion/index.js +2 -1
- package/esm2015/bidi/bidi-module.js +9 -13
- package/esm2015/bidi/dir.js +41 -45
- package/esm2015/bidi/directionality.js +27 -31
- package/esm2015/clipboard/clipboard-module.js +9 -13
- package/esm2015/clipboard/clipboard.js +36 -40
- package/esm2015/clipboard/copy-to-clipboard.js +71 -75
- package/esm2015/collections/unique-selection-dispatcher.js +33 -37
- package/esm2015/drag-drop/directives/drag-handle.js +42 -39
- package/esm2015/drag-drop/directives/drag-placeholder.js +24 -21
- package/esm2015/drag-drop/directives/drag-preview.js +29 -26
- package/esm2015/drag-drop/directives/drag.js +313 -319
- package/esm2015/drag-drop/directives/drop-list-group.js +32 -29
- package/esm2015/drag-drop/directives/drop-list.js +251 -250
- package/esm2015/drag-drop/drag-drop-module.js +27 -31
- package/esm2015/drag-drop/drag-drop-registry.js +139 -143
- package/esm2015/drag-drop/drag-drop.js +33 -37
- package/esm2015/drag-drop/drag-ref.js +59 -25
- package/esm2015/drag-drop/drop-list-ref.js +15 -9
- package/esm2015/drag-drop/index.js +3 -2
- package/esm2015/layout/breakpoints-observer.js +81 -85
- package/esm2015/layout/layout-module.js +6 -10
- package/esm2015/layout/media-matcher.js +28 -32
- package/esm2015/observers/observe-content.js +147 -163
- package/esm2015/overlay/dispatchers/base-overlay-dispatcher.js +51 -0
- package/esm2015/overlay/dispatchers/index.js +10 -0
- package/esm2015/overlay/dispatchers/overlay-keyboard-dispatcher.js +79 -0
- package/esm2015/overlay/dispatchers/overlay-outside-click-dispatcher.js +94 -0
- package/esm2015/overlay/fullscreen-overlay-container.js +70 -74
- package/esm2015/overlay/index.js +5 -4
- package/esm2015/overlay/overlay-config.js +5 -1
- package/esm2015/overlay/overlay-container.js +69 -73
- package/esm2015/overlay/overlay-directives.js +245 -243
- package/esm2015/overlay/overlay-module.js +15 -19
- package/esm2015/overlay/overlay-ref.js +24 -2
- package/esm2015/overlay/overlay-reference.js +1 -1
- package/esm2015/overlay/overlay.js +93 -92
- package/esm2015/overlay/position/connected-position.js +14 -18
- package/esm2015/overlay/position/overlay-position-builder.js +43 -47
- package/esm2015/overlay/public-api.js +2 -2
- package/esm2015/overlay/scroll/scroll-strategy-options.js +33 -37
- package/esm2015/platform/features/scrolling.js +1 -2
- package/esm2015/platform/platform-module.js +6 -10
- package/esm2015/platform/platform.js +48 -52
- package/esm2015/portal/portal-directives.js +181 -201
- package/esm2015/scrolling/fixed-size-virtual-scroll.js +57 -47
- package/esm2015/scrolling/public-api.js +2 -1
- package/esm2015/scrolling/scroll-dispatcher.js +139 -143
- package/esm2015/scrolling/scrollable.js +135 -139
- package/esm2015/scrolling/scrolling-module.js +32 -40
- package/esm2015/scrolling/viewport-ruler.js +105 -109
- package/esm2015/scrolling/virtual-for-of.js +264 -268
- package/esm2015/scrolling/virtual-scroll-repeater.js +8 -0
- package/esm2015/scrolling/virtual-scroll-viewport.js +318 -322
- package/esm2015/stepper/step-header.js +20 -24
- package/esm2015/stepper/step-label.js +13 -17
- package/esm2015/stepper/stepper-button.js +59 -67
- package/esm2015/stepper/stepper-module.js +24 -28
- package/esm2015/stepper/stepper.js +313 -321
- package/esm2015/table/cell.js +129 -157
- package/esm2015/table/row.js +183 -219
- package/esm2015/table/table-module.js +9 -13
- package/esm2015/table/table.js +765 -785
- package/esm2015/table/text-column.js +85 -89
- package/esm2015/testing/component-harness.js +19 -1
- package/esm2015/testing/harness-environment.js +7 -1
- package/esm2015/text-field/autofill.js +89 -97
- package/esm2015/text-field/autosize.js +225 -229
- package/esm2015/text-field/text-field-module.js +10 -14
- package/esm2015/tree/control/nested-tree-control.js +7 -3
- package/esm2015/tree/nested-node.js +79 -83
- package/esm2015/tree/node.js +17 -21
- package/esm2015/tree/outlet.js +15 -19
- package/esm2015/tree/padding.js +88 -92
- package/esm2015/tree/toggle.js +32 -36
- package/esm2015/tree/tree-module.js +10 -14
- package/esm2015/tree/tree.js +266 -274
- package/esm2015/version.js +1 -1
- package/fesm2015/a11y.js +1021 -996
- package/fesm2015/a11y.js.map +1 -1
- package/fesm2015/accordion.js +173 -175
- package/fesm2015/accordion.js.map +1 -1
- package/fesm2015/bidi.js +74 -83
- package/fesm2015/bidi.js.map +1 -1
- package/fesm2015/cdk.js +1 -1
- package/fesm2015/cdk.js.map +1 -1
- package/fesm2015/clipboard.js +113 -122
- package/fesm2015/clipboard.js.map +1 -1
- package/fesm2015/collections.js +32 -35
- package/fesm2015/collections.js.map +1 -1
- package/fesm2015/drag-drop.js +1005 -961
- package/fesm2015/drag-drop.js.map +1 -1
- package/fesm2015/layout.js +111 -120
- package/fesm2015/layout.js.map +1 -1
- package/fesm2015/observers.js +146 -158
- package/fesm2015/observers.js.map +1 -1
- package/fesm2015/overlay.js +793 -659
- package/fesm2015/overlay.js.map +1 -1
- package/fesm2015/platform.js +52 -59
- package/fesm2015/platform.js.map +1 -1
- package/fesm2015/portal.js +180 -195
- package/fesm2015/portal.js.map +1 -1
- package/fesm2015/scrolling.js +1058 -1060
- package/fesm2015/scrolling.js.map +1 -1
- package/fesm2015/stepper.js +424 -445
- package/fesm2015/stepper.js.map +1 -1
- package/fesm2015/table.js +1178 -1247
- package/fesm2015/table.js.map +1 -1
- package/fesm2015/testing.js +25 -1
- package/fesm2015/testing.js.map +1 -1
- package/fesm2015/text-field.js +318 -330
- package/fesm2015/text-field.js.map +1 -1
- package/fesm2015/tree.js +517 -537
- package/fesm2015/tree.js.map +1 -1
- package/overlay/dispatchers/base-overlay-dispatcher.d.ts +28 -0
- package/overlay/dispatchers/index.d.ts +9 -0
- package/overlay/{keyboard → dispatchers}/overlay-keyboard-dispatcher.d.ts +4 -10
- package/overlay/dispatchers/overlay-outside-click-dispatcher.d.ts +27 -0
- package/overlay/index.d.ts +4 -3
- package/overlay/index.metadata.json +1 -1
- package/overlay/overlay-config.d.ts +4 -0
- package/overlay/overlay-directives.d.ts +4 -0
- package/overlay/overlay-ref.d.ts +8 -2
- package/overlay/overlay-reference.d.ts +1 -0
- package/overlay/overlay.d.ts +4 -2
- package/overlay/public-api.d.ts +1 -1
- package/package.json +3 -3
- package/schematics/index.js +1 -1
- package/schematics/migration.json +5 -0
- package/schematics/ng-add/index.js +1 -1
- package/schematics/ng-update/data/index.js +1 -1
- package/schematics/ng-update/devkit-file-system.d.ts +5 -5
- package/schematics/ng-update/devkit-file-system.js +21 -16
- package/schematics/ng-update/devkit-migration-rule.js +13 -20
- package/schematics/ng-update/devkit-migration.d.ts +0 -2
- package/schematics/ng-update/devkit-migration.js +1 -1
- package/schematics/ng-update/find-stylesheets.d.ts +10 -0
- package/schematics/ng-update/find-stylesheets.js +31 -0
- package/schematics/ng-update/index.d.ts +2 -0
- package/schematics/ng-update/index.js +7 -2
- package/schematics/ng-update/migrations/attribute-selectors.js +3 -3
- package/schematics/ng-update/migrations/css-selectors.js +3 -3
- package/schematics/ng-update/migrations/element-selectors.js +3 -3
- package/schematics/ng-update/public-api.js +1 -1
- package/schematics/update-tool/component-resource-collector.d.ts +1 -1
- package/schematics/update-tool/component-resource-collector.js +18 -14
- package/schematics/update-tool/file-system.d.ts +19 -14
- package/schematics/update-tool/file-system.js +1 -1
- package/schematics/update-tool/index.d.ts +21 -3
- package/schematics/update-tool/index.js +29 -23
- package/schematics/update-tool/public-api.js +1 -1
- package/schematics/update-tool/target-version.d.ts +2 -1
- package/schematics/update-tool/target-version.js +5 -3
- package/schematics/update-tool/utils/parse-tsconfig.d.ts +2 -1
- package/schematics/update-tool/utils/parse-tsconfig.js +6 -10
- package/schematics/update-tool/utils/virtual-host.d.ts +34 -0
- package/schematics/update-tool/utils/virtual-host.js +62 -0
- package/schematics/update-tool/version-changes.js +4 -6
- package/schematics/utils/index.js +1 -1
- package/schematics/utils/project-tsconfig-paths.d.ts +2 -1
- package/schematics/utils/project-tsconfig-paths.js +1 -1
- package/scrolling/index.metadata.json +1 -1
- package/scrolling/public-api.d.ts +1 -0
- package/scrolling/virtual-for-of.d.ts +2 -1
- package/scrolling/virtual-scroll-repeater.d.ts +16 -0
- package/scrolling/virtual-scroll-viewport.d.ts +4 -4
- package/testing/component-harness.d.ts +12 -0
- package/testing/harness-environment.d.ts +1 -0
- package/tree/control/nested-tree-control.d.ts +7 -2
- package/tree/index.metadata.json +1 -1
- 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
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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
|
-
*
|
|
307
|
-
*
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
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
|
-
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
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
|
-
|
|
370
|
-
|
|
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
|
-
|
|
390
|
-
|
|
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
|
-
|
|
412
|
-
|
|
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
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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 (
|
|
440
|
-
|
|
396
|
+
else if (currentIndex == null) {
|
|
397
|
+
viewContainer.remove(adjustedPreviousIndex);
|
|
398
|
+
this._levels.delete(item.item);
|
|
441
399
|
}
|
|
442
400
|
else {
|
|
443
|
-
|
|
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
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
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
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
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
|
-
|
|
523
|
-
|
|
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
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (CdkTreeNode.mostRecentTreeNode === this) {
|
|
529
|
-
CdkTreeNode.mostRecentTreeNode = null;
|
|
537
|
+
else {
|
|
538
|
+
if (!this._tree.treeControl.getChildren) {
|
|
539
|
+
throw getTreeControlFunctionsMissingError();
|
|
530
540
|
}
|
|
531
|
-
this.
|
|
532
|
-
|
|
533
|
-
|
|
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
|
-
|
|
545
|
-
|
|
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
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
}
|
|
585
|
-
|
|
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
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
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
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
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
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
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
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
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
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
]
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
}
|
|
795
|
-
|
|
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
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
this.
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
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
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
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
|