tree.es5.js 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476
  1. /**
  2. * @license
  3. * Copyright Google LLC All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. import { SelectionModel, isDataSource } from '@angular/cdk/collections';
  9. import { __extends } from 'tslib';
  10. import { Observable, BehaviorSubject, of, Subject } from 'rxjs';
  11. import { take, filter, takeUntil } from 'rxjs/operators';
  12. import { Directive, Inject, InjectionToken, Optional, ViewContainerRef, TemplateRef, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, Input, IterableDiffers, ViewChild, ViewEncapsulation, Renderer2, HostListener, NgModule } from '@angular/core';
  13. import { Directionality } from '@angular/cdk/bidi';
  14. import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
  15. import { FocusMonitor } from '@angular/cdk/a11y';
  16. import { CommonModule } from '@angular/common';
  17. /**
  18. * @fileoverview added by tsickle
  19. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  20. */
  21. /**
  22. * Base tree control. It has basic toggle/expand/collapse operations on a single data node.
  23. * @abstract
  24. * @template T
  25. */
  26. var /**
  27. * Base tree control. It has basic toggle/expand/collapse operations on a single data node.
  28. * @abstract
  29. * @template T
  30. */
  31. BaseTreeControl = /** @class */ (function () {
  32. function BaseTreeControl() {
  33. /**
  34. * A selection model with multi-selection to track expansion status.
  35. */
  36. this.expansionModel = new SelectionModel(true);
  37. }
  38. /** Toggles one single data node's expanded/collapsed state. */
  39. /**
  40. * Toggles one single data node's expanded/collapsed state.
  41. * @param {?} dataNode
  42. * @return {?}
  43. */
  44. BaseTreeControl.prototype.toggle = /**
  45. * Toggles one single data node's expanded/collapsed state.
  46. * @param {?} dataNode
  47. * @return {?}
  48. */
  49. function (dataNode) {
  50. this.expansionModel.toggle(dataNode);
  51. };
  52. /** Expands one single data node. */
  53. /**
  54. * Expands one single data node.
  55. * @param {?} dataNode
  56. * @return {?}
  57. */
  58. BaseTreeControl.prototype.expand = /**
  59. * Expands one single data node.
  60. * @param {?} dataNode
  61. * @return {?}
  62. */
  63. function (dataNode) {
  64. this.expansionModel.select(dataNode);
  65. };
  66. /** Collapses one single data node. */
  67. /**
  68. * Collapses one single data node.
  69. * @param {?} dataNode
  70. * @return {?}
  71. */
  72. BaseTreeControl.prototype.collapse = /**
  73. * Collapses one single data node.
  74. * @param {?} dataNode
  75. * @return {?}
  76. */
  77. function (dataNode) {
  78. this.expansionModel.deselect(dataNode);
  79. };
  80. /** Whether a given data node is expanded or not. Returns true if the data node is expanded. */
  81. /**
  82. * Whether a given data node is expanded or not. Returns true if the data node is expanded.
  83. * @param {?} dataNode
  84. * @return {?}
  85. */
  86. BaseTreeControl.prototype.isExpanded = /**
  87. * Whether a given data node is expanded or not. Returns true if the data node is expanded.
  88. * @param {?} dataNode
  89. * @return {?}
  90. */
  91. function (dataNode) {
  92. return this.expansionModel.isSelected(dataNode);
  93. };
  94. /** Toggles a subtree rooted at `node` recursively. */
  95. /**
  96. * Toggles a subtree rooted at `node` recursively.
  97. * @param {?} dataNode
  98. * @return {?}
  99. */
  100. BaseTreeControl.prototype.toggleDescendants = /**
  101. * Toggles a subtree rooted at `node` recursively.
  102. * @param {?} dataNode
  103. * @return {?}
  104. */
  105. function (dataNode) {
  106. this.expansionModel.isSelected(dataNode)
  107. ? this.collapseDescendants(dataNode)
  108. : this.expandDescendants(dataNode);
  109. };
  110. /** Collapse all dataNodes in the tree. */
  111. /**
  112. * Collapse all dataNodes in the tree.
  113. * @return {?}
  114. */
  115. BaseTreeControl.prototype.collapseAll = /**
  116. * Collapse all dataNodes in the tree.
  117. * @return {?}
  118. */
  119. function () {
  120. this.expansionModel.clear();
  121. };
  122. /** Expands a subtree rooted at given data node recursively. */
  123. /**
  124. * Expands a subtree rooted at given data node recursively.
  125. * @param {?} dataNode
  126. * @return {?}
  127. */
  128. BaseTreeControl.prototype.expandDescendants = /**
  129. * Expands a subtree rooted at given data node recursively.
  130. * @param {?} dataNode
  131. * @return {?}
  132. */
  133. function (dataNode) {
  134. var _a;
  135. /** @type {?} */
  136. var toBeProcessed = [dataNode];
  137. toBeProcessed.push.apply(toBeProcessed, this.getDescendants(dataNode));
  138. (_a = this.expansionModel).select.apply(_a, toBeProcessed);
  139. };
  140. /** Collapses a subtree rooted at given data node recursively. */
  141. /**
  142. * Collapses a subtree rooted at given data node recursively.
  143. * @param {?} dataNode
  144. * @return {?}
  145. */
  146. BaseTreeControl.prototype.collapseDescendants = /**
  147. * Collapses a subtree rooted at given data node recursively.
  148. * @param {?} dataNode
  149. * @return {?}
  150. */
  151. function (dataNode) {
  152. var _a;
  153. /** @type {?} */
  154. var toBeProcessed = [dataNode];
  155. toBeProcessed.push.apply(toBeProcessed, this.getDescendants(dataNode));
  156. (_a = this.expansionModel).deselect.apply(_a, toBeProcessed);
  157. };
  158. return BaseTreeControl;
  159. }());
  160. /**
  161. * @fileoverview added by tsickle
  162. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  163. */
  164. /**
  165. * Flat tree control. Able to expand/collapse a subtree recursively for flattened tree.
  166. * @template T
  167. */
  168. var /**
  169. * Flat tree control. Able to expand/collapse a subtree recursively for flattened tree.
  170. * @template T
  171. */
  172. FlatTreeControl = /** @class */ (function (_super) {
  173. __extends(FlatTreeControl, _super);
  174. /** Construct with flat tree data node functions getLevel and isExpandable. */
  175. function FlatTreeControl(getLevel, isExpandable) {
  176. var _this = _super.call(this) || this;
  177. _this.getLevel = getLevel;
  178. _this.isExpandable = isExpandable;
  179. return _this;
  180. }
  181. /**
  182. * Gets a list of the data node's subtree of descendent data nodes.
  183. *
  184. * To make this working, the `dataNodes` of the TreeControl must be flattened tree nodes
  185. * with correct levels.
  186. */
  187. /**
  188. * Gets a list of the data node's subtree of descendent data nodes.
  189. *
  190. * To make this working, the `dataNodes` of the TreeControl must be flattened tree nodes
  191. * with correct levels.
  192. * @param {?} dataNode
  193. * @return {?}
  194. */
  195. FlatTreeControl.prototype.getDescendants = /**
  196. * Gets a list of the data node's subtree of descendent data nodes.
  197. *
  198. * To make this working, the `dataNodes` of the TreeControl must be flattened tree nodes
  199. * with correct levels.
  200. * @param {?} dataNode
  201. * @return {?}
  202. */
  203. function (dataNode) {
  204. /** @type {?} */
  205. var startIndex = this.dataNodes.indexOf(dataNode);
  206. /** @type {?} */
  207. var results = [];
  208. // Goes through flattened tree nodes in the `dataNodes` array, and get all descendants.
  209. // The level of descendants of a tree node must be greater than the level of the given
  210. // tree node.
  211. // If we reach a node whose level is equal to the level of the tree node, we hit a sibling.
  212. // If we reach a node whose level is greater than the level of the tree node, we hit a
  213. // sibling of an ancestor.
  214. for (var i = startIndex + 1; i < this.dataNodes.length && this.getLevel(dataNode) < this.getLevel(this.dataNodes[i]); i++) {
  215. results.push(this.dataNodes[i]);
  216. }
  217. return results;
  218. };
  219. /**
  220. * Expands all data nodes in the tree.
  221. *
  222. * To make this working, the `dataNodes` variable of the TreeControl must be set to all flattened
  223. * data nodes of the tree.
  224. */
  225. /**
  226. * Expands all data nodes in the tree.
  227. *
  228. * To make this working, the `dataNodes` variable of the TreeControl must be set to all flattened
  229. * data nodes of the tree.
  230. * @return {?}
  231. */
  232. FlatTreeControl.prototype.expandAll = /**
  233. * Expands all data nodes in the tree.
  234. *
  235. * To make this working, the `dataNodes` variable of the TreeControl must be set to all flattened
  236. * data nodes of the tree.
  237. * @return {?}
  238. */
  239. function () {
  240. var _a;
  241. (_a = this.expansionModel).select.apply(_a, this.dataNodes);
  242. };
  243. return FlatTreeControl;
  244. }(BaseTreeControl));
  245. /**
  246. * @fileoverview added by tsickle
  247. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  248. */
  249. /**
  250. * Nested tree control. Able to expand/collapse a subtree recursively for NestedNode type.
  251. * @template T
  252. */
  253. var /**
  254. * Nested tree control. Able to expand/collapse a subtree recursively for NestedNode type.
  255. * @template T
  256. */
  257. NestedTreeControl = /** @class */ (function (_super) {
  258. __extends(NestedTreeControl, _super);
  259. /** Construct with nested tree function getChildren. */
  260. function NestedTreeControl(getChildren) {
  261. var _this = _super.call(this) || this;
  262. _this.getChildren = getChildren;
  263. return _this;
  264. }
  265. /**
  266. * Expands all dataNodes in the tree.
  267. *
  268. * To make this working, the `dataNodes` variable of the TreeControl must be set to all root level
  269. * data nodes of the tree.
  270. */
  271. /**
  272. * Expands all dataNodes in the tree.
  273. *
  274. * To make this working, the `dataNodes` variable of the TreeControl must be set to all root level
  275. * data nodes of the tree.
  276. * @return {?}
  277. */
  278. NestedTreeControl.prototype.expandAll = /**
  279. * Expands all dataNodes in the tree.
  280. *
  281. * To make this working, the `dataNodes` variable of the TreeControl must be set to all root level
  282. * data nodes of the tree.
  283. * @return {?}
  284. */
  285. function () {
  286. var _a;
  287. var _this = this;
  288. this.expansionModel.clear();
  289. /** @type {?} */
  290. var allNodes = this.dataNodes.reduce((/**
  291. * @param {?} accumulator
  292. * @param {?} dataNode
  293. * @return {?}
  294. */
  295. function (accumulator, dataNode) {
  296. return accumulator.concat(_this.getDescendants(dataNode), [dataNode]);
  297. }), []);
  298. (_a = this.expansionModel).select.apply(_a, allNodes);
  299. };
  300. /** Gets a list of descendant dataNodes of a subtree rooted at given data node recursively. */
  301. /**
  302. * Gets a list of descendant dataNodes of a subtree rooted at given data node recursively.
  303. * @param {?} dataNode
  304. * @return {?}
  305. */
  306. NestedTreeControl.prototype.getDescendants = /**
  307. * Gets a list of descendant dataNodes of a subtree rooted at given data node recursively.
  308. * @param {?} dataNode
  309. * @return {?}
  310. */
  311. function (dataNode) {
  312. /** @type {?} */
  313. var descendants = [];
  314. this._getDescendants(descendants, dataNode);
  315. // Remove the node itself
  316. return descendants.splice(1);
  317. };
  318. /** A helper function to get descendants recursively. */
  319. /**
  320. * A helper function to get descendants recursively.
  321. * @protected
  322. * @param {?} descendants
  323. * @param {?} dataNode
  324. * @return {?}
  325. */
  326. NestedTreeControl.prototype._getDescendants = /**
  327. * A helper function to get descendants recursively.
  328. * @protected
  329. * @param {?} descendants
  330. * @param {?} dataNode
  331. * @return {?}
  332. */
  333. function (descendants, dataNode) {
  334. var _this = this;
  335. descendants.push(dataNode);
  336. /** @type {?} */
  337. var childrenNodes = this.getChildren(dataNode);
  338. if (Array.isArray(childrenNodes)) {
  339. childrenNodes.forEach((/**
  340. * @param {?} child
  341. * @return {?}
  342. */
  343. function (child) { return _this._getDescendants(descendants, child); }));
  344. }
  345. else if (childrenNodes instanceof Observable) {
  346. // TypeScript as of version 3.5 doesn't seem to treat `Boolean` like a function that
  347. // returns a `boolean` specifically in the context of `filter`, so we manually clarify that.
  348. childrenNodes.pipe(take(1), filter((/** @type {?} */ (Boolean))))
  349. .subscribe((/**
  350. * @param {?} children
  351. * @return {?}
  352. */
  353. function (children) {
  354. for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
  355. var child = children_1[_i];
  356. _this._getDescendants(descendants, child);
  357. }
  358. }));
  359. }
  360. };
  361. return NestedTreeControl;
  362. }(BaseTreeControl));
  363. /**
  364. * @fileoverview added by tsickle
  365. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  366. */
  367. /**
  368. * @fileoverview added by tsickle
  369. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  370. */
  371. /**
  372. * Injection token used to provide a `CdkTreeNode` to its outlet.
  373. * Used primarily to avoid circular imports.
  374. * \@docs-private
  375. * @type {?}
  376. */
  377. var CDK_TREE_NODE_OUTLET_NODE = new InjectionToken('CDK_TREE_NODE_OUTLET_NODE');
  378. /**
  379. * Outlet for nested CdkNode. Put `[cdkTreeNodeOutlet]` on a tag to place children dataNodes
  380. * inside the outlet.
  381. */
  382. var CdkTreeNodeOutlet = /** @class */ (function () {
  383. function CdkTreeNodeOutlet(viewContainer, _node) {
  384. this.viewContainer = viewContainer;
  385. this._node = _node;
  386. }
  387. CdkTreeNodeOutlet.decorators = [
  388. { type: Directive, args: [{
  389. selector: '[cdkTreeNodeOutlet]'
  390. },] },
  391. ];
  392. /** @nocollapse */
  393. CdkTreeNodeOutlet.ctorParameters = function () { return [
  394. { type: ViewContainerRef },
  395. { type: undefined, decorators: [{ type: Inject, args: [CDK_TREE_NODE_OUTLET_NODE,] }, { type: Optional }] }
  396. ]; };
  397. return CdkTreeNodeOutlet;
  398. }());
  399. /**
  400. * @fileoverview added by tsickle
  401. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  402. */
  403. /**
  404. * Context provided to the tree node component.
  405. * @template T
  406. */
  407. var /**
  408. * Context provided to the tree node component.
  409. * @template T
  410. */
  411. CdkTreeNodeOutletContext = /** @class */ (function () {
  412. function CdkTreeNodeOutletContext(data) {
  413. this.$implicit = data;
  414. }
  415. return CdkTreeNodeOutletContext;
  416. }());
  417. /**
  418. * Data node definition for the CdkTree.
  419. * Captures the node's template and a when predicate that describes when this node should be used.
  420. * @template T
  421. */
  422. var CdkTreeNodeDef = /** @class */ (function () {
  423. /** @docs-private */
  424. function CdkTreeNodeDef(template) {
  425. this.template = template;
  426. }
  427. CdkTreeNodeDef.decorators = [
  428. { type: Directive, args: [{
  429. selector: '[cdkTreeNodeDef]',
  430. inputs: [
  431. 'when: cdkTreeNodeDefWhen'
  432. ],
  433. },] },
  434. ];
  435. /** @nocollapse */
  436. CdkTreeNodeDef.ctorParameters = function () { return [
  437. { type: TemplateRef }
  438. ]; };
  439. return CdkTreeNodeDef;
  440. }());
  441. /**
  442. * @fileoverview added by tsickle
  443. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  444. */
  445. /**
  446. * Returns an error to be thrown when there is no usable data.
  447. * \@docs-private
  448. * @return {?}
  449. */
  450. function getTreeNoValidDataSourceError() {
  451. return Error("A valid data source must be provided.");
  452. }
  453. /**
  454. * Returns an error to be thrown when there are multiple nodes that are missing a when function.
  455. * \@docs-private
  456. * @return {?}
  457. */
  458. function getTreeMultipleDefaultNodeDefsError() {
  459. return Error("There can only be one default row without a when predicate function.");
  460. }
  461. /**
  462. * Returns an error to be thrown when there are no matching node defs for a particular set of data.
  463. * \@docs-private
  464. * @return {?}
  465. */
  466. function getTreeMissingMatchingNodeDefError() {
  467. return Error("Could not find a matching node definition for the provided node data.");
  468. }
  469. /**
  470. * Returns an error to be thrown when there are tree control.
  471. * \@docs-private
  472. * @return {?}
  473. */
  474. function getTreeControlMissingError() {
  475. return Error("Could not find a tree control for the tree.");
  476. }
  477. /**
  478. * Returns an error to be thrown when tree control did not implement functions for flat/nested node.
  479. * \@docs-private
  480. * @return {?}
  481. */
  482. function getTreeControlFunctionsMissingError() {
  483. return Error("Could not find functions for nested/flat tree in tree control.");
  484. }
  485. /**
  486. * @fileoverview added by tsickle
  487. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  488. */
  489. /**
  490. * CDK tree component that connects with a data source to retrieve data of type `T` and renders
  491. * dataNodes with hierarchy. Updates the dataNodes when new data is provided by the data source.
  492. * @template T
  493. */
  494. var CdkTree = /** @class */ (function () {
  495. function CdkTree(_differs, _changeDetectorRef) {
  496. this._differs = _differs;
  497. this._changeDetectorRef = _changeDetectorRef;
  498. /**
  499. * Subject that emits when the component has been destroyed.
  500. */
  501. this._onDestroy = new Subject();
  502. /**
  503. * Level of nodes
  504. */
  505. this._levels = new Map();
  506. // TODO(tinayuangao): Setup a listener for scrolling, emit the calculated view to viewChange.
  507. // Remove the MAX_VALUE in viewChange
  508. /**
  509. * Stream containing the latest information on what rows are being displayed on screen.
  510. * Can be used by the data source to as a heuristic of what data should be provided.
  511. */
  512. this.viewChange = new BehaviorSubject({ start: 0, end: Number.MAX_VALUE });
  513. }
  514. Object.defineProperty(CdkTree.prototype, "dataSource", {
  515. /**
  516. * Provides a stream containing the latest data array to render. Influenced by the tree's
  517. * stream of view window (what dataNodes are currently on screen).
  518. * Data source can be an observable of data array, or a data array to render.
  519. */
  520. get: /**
  521. * Provides a stream containing the latest data array to render. Influenced by the tree's
  522. * stream of view window (what dataNodes are currently on screen).
  523. * Data source can be an observable of data array, or a data array to render.
  524. * @return {?}
  525. */
  526. function () { return this._dataSource; },
  527. set: /**
  528. * @param {?} dataSource
  529. * @return {?}
  530. */
  531. function (dataSource) {
  532. if (this._dataSource !== dataSource) {
  533. this._switchDataSource(dataSource);
  534. }
  535. },
  536. enumerable: true,
  537. configurable: true
  538. });
  539. /**
  540. * @return {?}
  541. */
  542. CdkTree.prototype.ngOnInit = /**
  543. * @return {?}
  544. */
  545. function () {
  546. this._dataDiffer = this._differs.find([]).create(this.trackBy);
  547. if (!this.treeControl) {
  548. throw getTreeControlMissingError();
  549. }
  550. };
  551. /**
  552. * @return {?}
  553. */
  554. CdkTree.prototype.ngOnDestroy = /**
  555. * @return {?}
  556. */
  557. function () {
  558. this._nodeOutlet.viewContainer.clear();
  559. this._onDestroy.next();
  560. this._onDestroy.complete();
  561. if (this._dataSource && typeof ((/** @type {?} */ (this._dataSource))).disconnect === 'function') {
  562. ((/** @type {?} */ (this.dataSource))).disconnect(this);
  563. }
  564. if (this._dataSubscription) {
  565. this._dataSubscription.unsubscribe();
  566. this._dataSubscription = null;
  567. }
  568. };
  569. /**
  570. * @return {?}
  571. */
  572. CdkTree.prototype.ngAfterContentChecked = /**
  573. * @return {?}
  574. */
  575. function () {
  576. /** @type {?} */
  577. var defaultNodeDefs = this._nodeDefs.filter((/**
  578. * @param {?} def
  579. * @return {?}
  580. */
  581. function (def) { return !def.when; }));
  582. if (defaultNodeDefs.length > 1) {
  583. throw getTreeMultipleDefaultNodeDefsError();
  584. }
  585. this._defaultNodeDef = defaultNodeDefs[0];
  586. if (this.dataSource && this._nodeDefs && !this._dataSubscription) {
  587. this._observeRenderChanges();
  588. }
  589. };
  590. // TODO(tinayuangao): Work on keyboard traversal and actions, make sure it's working for RTL
  591. // and nested trees.
  592. /**
  593. * Switch to the provided data source by resetting the data and unsubscribing from the current
  594. * render change subscription if one exists. If the data source is null, interpret this by
  595. * clearing the node outlet. Otherwise start listening for new data.
  596. */
  597. // TODO(tinayuangao): Work on keyboard traversal and actions, make sure it's working for RTL
  598. // and nested trees.
  599. /**
  600. * Switch to the provided data source by resetting the data and unsubscribing from the current
  601. * render change subscription if one exists. If the data source is null, interpret this by
  602. * clearing the node outlet. Otherwise start listening for new data.
  603. * @private
  604. * @param {?} dataSource
  605. * @return {?}
  606. */
  607. CdkTree.prototype._switchDataSource =
  608. // TODO(tinayuangao): Work on keyboard traversal and actions, make sure it's working for RTL
  609. // and nested trees.
  610. /**
  611. * Switch to the provided data source by resetting the data and unsubscribing from the current
  612. * render change subscription if one exists. If the data source is null, interpret this by
  613. * clearing the node outlet. Otherwise start listening for new data.
  614. * @private
  615. * @param {?} dataSource
  616. * @return {?}
  617. */
  618. function (dataSource) {
  619. if (this._dataSource && typeof ((/** @type {?} */ (this._dataSource))).disconnect === 'function') {
  620. ((/** @type {?} */ (this.dataSource))).disconnect(this);
  621. }
  622. if (this._dataSubscription) {
  623. this._dataSubscription.unsubscribe();
  624. this._dataSubscription = null;
  625. }
  626. // Remove the all dataNodes if there is now no data source
  627. if (!dataSource) {
  628. this._nodeOutlet.viewContainer.clear();
  629. }
  630. this._dataSource = dataSource;
  631. if (this._nodeDefs) {
  632. this._observeRenderChanges();
  633. }
  634. };
  635. /** Set up a subscription for the data provided by the data source. */
  636. /**
  637. * Set up a subscription for the data provided by the data source.
  638. * @private
  639. * @return {?}
  640. */
  641. CdkTree.prototype._observeRenderChanges = /**
  642. * Set up a subscription for the data provided by the data source.
  643. * @private
  644. * @return {?}
  645. */
  646. function () {
  647. var _this = this;
  648. /** @type {?} */
  649. var dataStream;
  650. if (isDataSource(this._dataSource)) {
  651. dataStream = this._dataSource.connect(this);
  652. }
  653. else if (this._dataSource instanceof Observable) {
  654. dataStream = this._dataSource;
  655. }
  656. else if (Array.isArray(this._dataSource)) {
  657. dataStream = of(this._dataSource);
  658. }
  659. if (dataStream) {
  660. this._dataSubscription = dataStream.pipe(takeUntil(this._onDestroy))
  661. .subscribe((/**
  662. * @param {?} data
  663. * @return {?}
  664. */
  665. function (data) { return _this.renderNodeChanges(data); }));
  666. }
  667. else {
  668. throw getTreeNoValidDataSourceError();
  669. }
  670. };
  671. /** Check for changes made in the data and render each change (node added/removed/moved). */
  672. /**
  673. * Check for changes made in the data and render each change (node added/removed/moved).
  674. * @param {?} data
  675. * @param {?=} dataDiffer
  676. * @param {?=} viewContainer
  677. * @param {?=} parentData
  678. * @return {?}
  679. */
  680. CdkTree.prototype.renderNodeChanges = /**
  681. * Check for changes made in the data and render each change (node added/removed/moved).
  682. * @param {?} data
  683. * @param {?=} dataDiffer
  684. * @param {?=} viewContainer
  685. * @param {?=} parentData
  686. * @return {?}
  687. */
  688. function (data, dataDiffer, viewContainer, parentData) {
  689. var _this = this;
  690. if (dataDiffer === void 0) { dataDiffer = this._dataDiffer; }
  691. if (viewContainer === void 0) { viewContainer = this._nodeOutlet.viewContainer; }
  692. /** @type {?} */
  693. var changes = dataDiffer.diff(data);
  694. if (!changes) {
  695. return;
  696. }
  697. changes.forEachOperation((/**
  698. * @param {?} item
  699. * @param {?} adjustedPreviousIndex
  700. * @param {?} currentIndex
  701. * @return {?}
  702. */
  703. function (item, adjustedPreviousIndex, currentIndex) {
  704. if (item.previousIndex == null) {
  705. _this.insertNode(data[(/** @type {?} */ (currentIndex))], (/** @type {?} */ (currentIndex)), viewContainer, parentData);
  706. }
  707. else if (currentIndex == null) {
  708. viewContainer.remove((/** @type {?} */ (adjustedPreviousIndex)));
  709. _this._levels.delete(item.item);
  710. }
  711. else {
  712. /** @type {?} */
  713. var view = viewContainer.get((/** @type {?} */ (adjustedPreviousIndex)));
  714. viewContainer.move((/** @type {?} */ (view)), currentIndex);
  715. }
  716. }));
  717. this._changeDetectorRef.detectChanges();
  718. };
  719. /**
  720. * Finds the matching node definition that should be used for this node data. If there is only
  721. * one node definition, it is returned. Otherwise, find the node definition that has a when
  722. * predicate that returns true with the data. If none return true, return the default node
  723. * definition.
  724. */
  725. /**
  726. * Finds the matching node definition that should be used for this node data. If there is only
  727. * one node definition, it is returned. Otherwise, find the node definition that has a when
  728. * predicate that returns true with the data. If none return true, return the default node
  729. * definition.
  730. * @param {?} data
  731. * @param {?} i
  732. * @return {?}
  733. */
  734. CdkTree.prototype._getNodeDef = /**
  735. * Finds the matching node definition that should be used for this node data. If there is only
  736. * one node definition, it is returned. Otherwise, find the node definition that has a when
  737. * predicate that returns true with the data. If none return true, return the default node
  738. * definition.
  739. * @param {?} data
  740. * @param {?} i
  741. * @return {?}
  742. */
  743. function (data, i) {
  744. if (this._nodeDefs.length === 1) {
  745. return this._nodeDefs.first;
  746. }
  747. /** @type {?} */
  748. var nodeDef = this._nodeDefs.find((/**
  749. * @param {?} def
  750. * @return {?}
  751. */
  752. function (def) { return def.when && def.when(i, data); })) || this._defaultNodeDef;
  753. if (!nodeDef) {
  754. throw getTreeMissingMatchingNodeDefError();
  755. }
  756. return nodeDef;
  757. };
  758. /**
  759. * Create the embedded view for the data node template and place it in the correct index location
  760. * within the data node view container.
  761. */
  762. /**
  763. * Create the embedded view for the data node template and place it in the correct index location
  764. * within the data node view container.
  765. * @param {?} nodeData
  766. * @param {?} index
  767. * @param {?=} viewContainer
  768. * @param {?=} parentData
  769. * @return {?}
  770. */
  771. CdkTree.prototype.insertNode = /**
  772. * Create the embedded view for the data node template and place it in the correct index location
  773. * within the data node view container.
  774. * @param {?} nodeData
  775. * @param {?} index
  776. * @param {?=} viewContainer
  777. * @param {?=} parentData
  778. * @return {?}
  779. */
  780. function (nodeData, index, viewContainer, parentData) {
  781. /** @type {?} */
  782. var node = this._getNodeDef(nodeData, index);
  783. // Node context that will be provided to created embedded view
  784. /** @type {?} */
  785. var context = new CdkTreeNodeOutletContext(nodeData);
  786. // If the tree is flat tree, then use the `getLevel` function in flat tree control
  787. // Otherwise, use the level of parent node.
  788. if (this.treeControl.getLevel) {
  789. context.level = this.treeControl.getLevel(nodeData);
  790. }
  791. else if (typeof parentData !== 'undefined' && this._levels.has(parentData)) {
  792. context.level = (/** @type {?} */ (this._levels.get(parentData))) + 1;
  793. }
  794. else {
  795. context.level = 0;
  796. }
  797. this._levels.set(nodeData, context.level);
  798. // Use default tree nodeOutlet, or nested node's nodeOutlet
  799. /** @type {?} */
  800. var container = viewContainer ? viewContainer : this._nodeOutlet.viewContainer;
  801. container.createEmbeddedView(node.template, context, index);
  802. // Set the data to just created `CdkTreeNode`.
  803. // The `CdkTreeNode` created from `createEmbeddedView` will be saved in static variable
  804. // `mostRecentTreeNode`. We get it from static variable and pass the node data to it.
  805. if (CdkTreeNode.mostRecentTreeNode) {
  806. CdkTreeNode.mostRecentTreeNode.data = nodeData;
  807. }
  808. };
  809. CdkTree.decorators = [
  810. { type: Component, args: [{selector: 'cdk-tree',
  811. exportAs: 'cdkTree',
  812. template: "<ng-container cdkTreeNodeOutlet></ng-container>",
  813. host: {
  814. 'class': 'cdk-tree',
  815. 'role': 'tree',
  816. },
  817. encapsulation: ViewEncapsulation.None,
  818. // The "OnPush" status for the `CdkTree` component is effectively a noop, so we are removing it.
  819. // The view for `CdkTree` consists entirely of templates declared in other views. As they are
  820. // declared elsewhere, they are checked when their declaration points are checked.
  821. // tslint:disable-next-line:validate-decorators
  822. changeDetection: ChangeDetectionStrategy.Default
  823. },] },
  824. ];
  825. /** @nocollapse */
  826. CdkTree.ctorParameters = function () { return [
  827. { type: IterableDiffers },
  828. { type: ChangeDetectorRef }
  829. ]; };
  830. CdkTree.propDecorators = {
  831. dataSource: [{ type: Input }],
  832. treeControl: [{ type: Input }],
  833. trackBy: [{ type: Input }],
  834. _nodeOutlet: [{ type: ViewChild, args: [CdkTreeNodeOutlet, { static: true },] }],
  835. _nodeDefs: [{ type: ContentChildren, args: [CdkTreeNodeDef,] }]
  836. };
  837. return CdkTree;
  838. }());
  839. /**
  840. * Tree node for CdkTree. It contains the data in the tree node.
  841. * @template T
  842. */
  843. var CdkTreeNode = /** @class */ (function () {
  844. function CdkTreeNode(_elementRef, _tree) {
  845. this._elementRef = _elementRef;
  846. this._tree = _tree;
  847. /**
  848. * Subject that emits when the component has been destroyed.
  849. */
  850. this._destroyed = new Subject();
  851. /**
  852. * Emits when the node's data has changed.
  853. */
  854. this._dataChanges = new Subject();
  855. /**
  856. * The role of the node should be 'group' if it's an internal node,
  857. * and 'treeitem' if it's a leaf node.
  858. */
  859. this.role = 'treeitem';
  860. CdkTreeNode.mostRecentTreeNode = (/** @type {?} */ (this));
  861. }
  862. Object.defineProperty(CdkTreeNode.prototype, "data", {
  863. /** The tree node's data. */
  864. get: /**
  865. * The tree node's data.
  866. * @return {?}
  867. */
  868. function () { return this._data; },
  869. set: /**
  870. * @param {?} value
  871. * @return {?}
  872. */
  873. function (value) {
  874. if (value !== this._data) {
  875. this._data = value;
  876. this._setRoleFromData();
  877. this._dataChanges.next();
  878. }
  879. },
  880. enumerable: true,
  881. configurable: true
  882. });
  883. Object.defineProperty(CdkTreeNode.prototype, "isExpanded", {
  884. get: /**
  885. * @return {?}
  886. */
  887. function () {
  888. return this._tree.treeControl.isExpanded(this._data);
  889. },
  890. enumerable: true,
  891. configurable: true
  892. });
  893. Object.defineProperty(CdkTreeNode.prototype, "level", {
  894. get: /**
  895. * @return {?}
  896. */
  897. function () {
  898. return this._tree.treeControl.getLevel ? this._tree.treeControl.getLevel(this._data) : 0;
  899. },
  900. enumerable: true,
  901. configurable: true
  902. });
  903. /**
  904. * @return {?}
  905. */
  906. CdkTreeNode.prototype.ngOnDestroy = /**
  907. * @return {?}
  908. */
  909. function () {
  910. // If this is the last tree node being destroyed,
  911. // clear out the reference to avoid leaking memory.
  912. if (CdkTreeNode.mostRecentTreeNode === this) {
  913. CdkTreeNode.mostRecentTreeNode = null;
  914. }
  915. this._dataChanges.complete();
  916. this._destroyed.next();
  917. this._destroyed.complete();
  918. };
  919. /** Focuses the menu item. Implements for FocusableOption. */
  920. /**
  921. * Focuses the menu item. Implements for FocusableOption.
  922. * @return {?}
  923. */
  924. CdkTreeNode.prototype.focus = /**
  925. * Focuses the menu item. Implements for FocusableOption.
  926. * @return {?}
  927. */
  928. function () {
  929. this._elementRef.nativeElement.focus();
  930. };
  931. /**
  932. * @protected
  933. * @return {?}
  934. */
  935. CdkTreeNode.prototype._setRoleFromData = /**
  936. * @protected
  937. * @return {?}
  938. */
  939. function () {
  940. var _this = this;
  941. if (this._tree.treeControl.isExpandable) {
  942. this.role = this._tree.treeControl.isExpandable(this._data) ? 'group' : 'treeitem';
  943. }
  944. else {
  945. if (!this._tree.treeControl.getChildren) {
  946. throw getTreeControlFunctionsMissingError();
  947. }
  948. /** @type {?} */
  949. var childrenNodes = this._tree.treeControl.getChildren(this._data);
  950. if (Array.isArray(childrenNodes)) {
  951. this._setRoleFromChildren((/** @type {?} */ (childrenNodes)));
  952. }
  953. else if (childrenNodes instanceof Observable) {
  954. childrenNodes.pipe(takeUntil(this._destroyed))
  955. .subscribe((/**
  956. * @param {?} children
  957. * @return {?}
  958. */
  959. function (children) { return _this._setRoleFromChildren(children); }));
  960. }
  961. }
  962. };
  963. /**
  964. * @protected
  965. * @param {?} children
  966. * @return {?}
  967. */
  968. CdkTreeNode.prototype._setRoleFromChildren = /**
  969. * @protected
  970. * @param {?} children
  971. * @return {?}
  972. */
  973. function (children) {
  974. this.role = children && children.length ? 'group' : 'treeitem';
  975. };
  976. /**
  977. * The most recently created `CdkTreeNode`. We save it in static variable so we can retrieve it
  978. * in `CdkTree` and set the data to it.
  979. */
  980. CdkTreeNode.mostRecentTreeNode = null;
  981. CdkTreeNode.decorators = [
  982. { type: Directive, args: [{
  983. selector: 'cdk-tree-node',
  984. exportAs: 'cdkTreeNode',
  985. host: {
  986. '[attr.aria-expanded]': 'isExpanded',
  987. '[attr.aria-level]': 'role === "treeitem" ? level : null',
  988. '[attr.role]': 'role',
  989. 'class': 'cdk-tree-node',
  990. },
  991. },] },
  992. ];
  993. /** @nocollapse */
  994. CdkTreeNode.ctorParameters = function () { return [
  995. { type: ElementRef },
  996. { type: CdkTree }
  997. ]; };
  998. CdkTreeNode.propDecorators = {
  999. role: [{ type: Input }]
  1000. };
  1001. return CdkTreeNode;
  1002. }());
  1003. /**
  1004. * @fileoverview added by tsickle
  1005. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1006. */
  1007. /**
  1008. * Nested node is a child of `<cdk-tree>`. It works with nested tree.
  1009. * By using `cdk-nested-tree-node` component in tree node template, children of the parent node will
  1010. * be added in the `cdkTreeNodeOutlet` in tree node template.
  1011. * For example:
  1012. * ```html
  1013. * <cdk-nested-tree-node>
  1014. * {{node.name}}
  1015. * <ng-template cdkTreeNodeOutlet></ng-template>
  1016. * </cdk-nested-tree-node>
  1017. * ```
  1018. * The children of node will be automatically added to `cdkTreeNodeOutlet`, the result dom will be
  1019. * like this:
  1020. * ```html
  1021. * <cdk-nested-tree-node>
  1022. * {{node.name}}
  1023. * <cdk-nested-tree-node>{{child1.name}}</cdk-nested-tree-node>
  1024. * <cdk-nested-tree-node>{{child2.name}}</cdk-nested-tree-node>
  1025. * </cdk-nested-tree-node>
  1026. * ```
  1027. * @template T
  1028. */
  1029. var CdkNestedTreeNode = /** @class */ (function (_super) {
  1030. __extends(CdkNestedTreeNode, _super);
  1031. function CdkNestedTreeNode(_elementRef, _tree, _differs) {
  1032. var _this = _super.call(this, _elementRef, _tree) || this;
  1033. _this._elementRef = _elementRef;
  1034. _this._tree = _tree;
  1035. _this._differs = _differs;
  1036. return _this;
  1037. }
  1038. /**
  1039. * @return {?}
  1040. */
  1041. CdkNestedTreeNode.prototype.ngAfterContentInit = /**
  1042. * @return {?}
  1043. */
  1044. function () {
  1045. var _this = this;
  1046. this._dataDiffer = this._differs.find([]).create(this._tree.trackBy);
  1047. if (!this._tree.treeControl.getChildren) {
  1048. throw getTreeControlFunctionsMissingError();
  1049. }
  1050. /** @type {?} */
  1051. var childrenNodes = this._tree.treeControl.getChildren(this.data);
  1052. if (Array.isArray(childrenNodes)) {
  1053. this.updateChildrenNodes((/** @type {?} */ (childrenNodes)));
  1054. }
  1055. else if (childrenNodes instanceof Observable) {
  1056. childrenNodes.pipe(takeUntil(this._destroyed))
  1057. .subscribe((/**
  1058. * @param {?} result
  1059. * @return {?}
  1060. */
  1061. function (result) { return _this.updateChildrenNodes(result); }));
  1062. }
  1063. this.nodeOutlet.changes.pipe(takeUntil(this._destroyed))
  1064. .subscribe((/**
  1065. * @return {?}
  1066. */
  1067. function () { return _this.updateChildrenNodes(); }));
  1068. };
  1069. /**
  1070. * @return {?}
  1071. */
  1072. CdkNestedTreeNode.prototype.ngOnDestroy = /**
  1073. * @return {?}
  1074. */
  1075. function () {
  1076. this._clear();
  1077. _super.prototype.ngOnDestroy.call(this);
  1078. };
  1079. /** Add children dataNodes to the NodeOutlet */
  1080. /**
  1081. * Add children dataNodes to the NodeOutlet
  1082. * @protected
  1083. * @param {?=} children
  1084. * @return {?}
  1085. */
  1086. CdkNestedTreeNode.prototype.updateChildrenNodes = /**
  1087. * Add children dataNodes to the NodeOutlet
  1088. * @protected
  1089. * @param {?=} children
  1090. * @return {?}
  1091. */
  1092. function (children) {
  1093. /** @type {?} */
  1094. var outlet = this._getNodeOutlet();
  1095. if (children) {
  1096. this._children = children;
  1097. }
  1098. if (outlet && this._children) {
  1099. /** @type {?} */
  1100. var viewContainer = outlet.viewContainer;
  1101. this._tree.renderNodeChanges(this._children, this._dataDiffer, viewContainer, this._data);
  1102. }
  1103. else {
  1104. // Reset the data differ if there's no children nodes displayed
  1105. this._dataDiffer.diff([]);
  1106. }
  1107. };
  1108. /** Clear the children dataNodes. */
  1109. /**
  1110. * Clear the children dataNodes.
  1111. * @protected
  1112. * @return {?}
  1113. */
  1114. CdkNestedTreeNode.prototype._clear = /**
  1115. * Clear the children dataNodes.
  1116. * @protected
  1117. * @return {?}
  1118. */
  1119. function () {
  1120. /** @type {?} */
  1121. var outlet = this._getNodeOutlet();
  1122. if (outlet) {
  1123. outlet.viewContainer.clear();
  1124. this._dataDiffer.diff([]);
  1125. }
  1126. };
  1127. /** Gets the outlet for the current node. */
  1128. /**
  1129. * Gets the outlet for the current node.
  1130. * @private
  1131. * @return {?}
  1132. */
  1133. CdkNestedTreeNode.prototype._getNodeOutlet = /**
  1134. * Gets the outlet for the current node.
  1135. * @private
  1136. * @return {?}
  1137. */
  1138. function () {
  1139. var _this = this;
  1140. /** @type {?} */
  1141. var outlets = this.nodeOutlet;
  1142. // Note that since we use `descendants: true` on the query, we have to ensure
  1143. // that we don't pick up the outlet of a child node by accident.
  1144. return outlets && outlets.find((/**
  1145. * @param {?} outlet
  1146. * @return {?}
  1147. */
  1148. function (outlet) { return !outlet._node || outlet._node === _this; }));
  1149. };
  1150. CdkNestedTreeNode.decorators = [
  1151. { type: Directive, args: [{
  1152. selector: 'cdk-nested-tree-node',
  1153. exportAs: 'cdkNestedTreeNode',
  1154. host: {
  1155. '[attr.aria-expanded]': 'isExpanded',
  1156. '[attr.role]': 'role',
  1157. 'class': 'cdk-tree-node cdk-nested-tree-node',
  1158. },
  1159. providers: [
  1160. { provide: CdkTreeNode, useExisting: CdkNestedTreeNode },
  1161. { provide: CDK_TREE_NODE_OUTLET_NODE, useExisting: CdkNestedTreeNode }
  1162. ]
  1163. },] },
  1164. ];
  1165. /** @nocollapse */
  1166. CdkNestedTreeNode.ctorParameters = function () { return [
  1167. { type: ElementRef },
  1168. { type: CdkTree },
  1169. { type: IterableDiffers }
  1170. ]; };
  1171. CdkNestedTreeNode.propDecorators = {
  1172. nodeOutlet: [{ type: ContentChildren, args: [CdkTreeNodeOutlet, {
  1173. // We need to use `descendants: true`, because Ivy will no longer match
  1174. // indirect descendants if it's left as false.
  1175. descendants: true
  1176. },] }]
  1177. };
  1178. return CdkNestedTreeNode;
  1179. }(CdkTreeNode));
  1180. /**
  1181. * @fileoverview added by tsickle
  1182. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1183. */
  1184. /**
  1185. * Regex used to split a string on its CSS units.
  1186. * @type {?}
  1187. */
  1188. var cssUnitPattern = /([A-Za-z%]+)$/;
  1189. /**
  1190. * Indent for the children tree dataNodes.
  1191. * This directive will add left-padding to the node to show hierarchy.
  1192. * @template T
  1193. */
  1194. var CdkTreeNodePadding = /** @class */ (function () {
  1195. function CdkTreeNodePadding(_treeNode, _tree, _renderer, _element, _dir) {
  1196. var _this = this;
  1197. this._treeNode = _treeNode;
  1198. this._tree = _tree;
  1199. this._renderer = _renderer;
  1200. this._element = _element;
  1201. this._dir = _dir;
  1202. /**
  1203. * Subject that emits when the component has been destroyed.
  1204. */
  1205. this._destroyed = new Subject();
  1206. /**
  1207. * CSS units used for the indentation value.
  1208. */
  1209. this.indentUnits = 'px';
  1210. this._indent = 40;
  1211. this._setPadding();
  1212. if (_dir) {
  1213. _dir.change.pipe(takeUntil(this._destroyed)).subscribe((/**
  1214. * @return {?}
  1215. */
  1216. function () { return _this._setPadding(true); }));
  1217. }
  1218. // In Ivy the indentation binding might be set before the tree node's data has been added,
  1219. // which means that we'll miss the first render. We have to subscribe to changes in the
  1220. // data to ensure that everything is up to date.
  1221. _treeNode._dataChanges.subscribe((/**
  1222. * @return {?}
  1223. */
  1224. function () { return _this._setPadding(); }));
  1225. }
  1226. Object.defineProperty(CdkTreeNodePadding.prototype, "level", {
  1227. /** The level of depth of the tree node. The padding will be `level * indent` pixels. */
  1228. get: /**
  1229. * The level of depth of the tree node. The padding will be `level * indent` pixels.
  1230. * @return {?}
  1231. */
  1232. function () { return this._level; },
  1233. set: /**
  1234. * @param {?} value
  1235. * @return {?}
  1236. */
  1237. function (value) {
  1238. // Set to null as the fallback value so that _setPadding can fall back to the node level if the
  1239. // consumer set the directive as `cdkTreeNodePadding=""`. We still want to take this value if
  1240. // they set 0 explicitly.
  1241. this._level = (/** @type {?} */ (coerceNumberProperty(value, null)));
  1242. this._setPadding();
  1243. },
  1244. enumerable: true,
  1245. configurable: true
  1246. });
  1247. Object.defineProperty(CdkTreeNodePadding.prototype, "indent", {
  1248. /**
  1249. * The indent for each level. Can be a number or a CSS string.
  1250. * Default number 40px from material design menu sub-menu spec.
  1251. */
  1252. get: /**
  1253. * The indent for each level. Can be a number or a CSS string.
  1254. * Default number 40px from material design menu sub-menu spec.
  1255. * @return {?}
  1256. */
  1257. function () { return this._indent; },
  1258. set: /**
  1259. * @param {?} indent
  1260. * @return {?}
  1261. */
  1262. function (indent) {
  1263. /** @type {?} */
  1264. var value = indent;
  1265. /** @type {?} */
  1266. var units = 'px';
  1267. if (typeof indent === 'string') {
  1268. /** @type {?} */
  1269. var parts = indent.split(cssUnitPattern);
  1270. value = parts[0];
  1271. units = parts[1] || units;
  1272. }
  1273. this.indentUnits = units;
  1274. this._indent = coerceNumberProperty(value);
  1275. this._setPadding();
  1276. },
  1277. enumerable: true,
  1278. configurable: true
  1279. });
  1280. /**
  1281. * @return {?}
  1282. */
  1283. CdkTreeNodePadding.prototype.ngOnDestroy = /**
  1284. * @return {?}
  1285. */
  1286. function () {
  1287. this._destroyed.next();
  1288. this._destroyed.complete();
  1289. };
  1290. /** The padding indent value for the tree node. Returns a string with px numbers if not null. */
  1291. /**
  1292. * The padding indent value for the tree node. Returns a string with px numbers if not null.
  1293. * @return {?}
  1294. */
  1295. CdkTreeNodePadding.prototype._paddingIndent = /**
  1296. * The padding indent value for the tree node. Returns a string with px numbers if not null.
  1297. * @return {?}
  1298. */
  1299. function () {
  1300. /** @type {?} */
  1301. var nodeLevel = (this._treeNode.data && this._tree.treeControl.getLevel)
  1302. ? this._tree.treeControl.getLevel(this._treeNode.data)
  1303. : null;
  1304. /** @type {?} */
  1305. var level = this._level == null ? nodeLevel : this._level;
  1306. return typeof level === 'number' ? "" + level * this._indent + this.indentUnits : null;
  1307. };
  1308. /**
  1309. * @param {?=} forceChange
  1310. * @return {?}
  1311. */
  1312. CdkTreeNodePadding.prototype._setPadding = /**
  1313. * @param {?=} forceChange
  1314. * @return {?}
  1315. */
  1316. function (forceChange) {
  1317. if (forceChange === void 0) { forceChange = false; }
  1318. /** @type {?} */
  1319. var padding = this._paddingIndent();
  1320. if (padding !== this._currentPadding || forceChange) {
  1321. /** @type {?} */
  1322. var element = this._element.nativeElement;
  1323. /** @type {?} */
  1324. var paddingProp = this._dir && this._dir.value === 'rtl' ? 'paddingRight' : 'paddingLeft';
  1325. /** @type {?} */
  1326. var resetProp = paddingProp === 'paddingLeft' ? 'paddingRight' : 'paddingLeft';
  1327. this._renderer.setStyle(element, paddingProp, padding);
  1328. this._renderer.setStyle(element, resetProp, null);
  1329. this._currentPadding = padding;
  1330. }
  1331. };
  1332. CdkTreeNodePadding.decorators = [
  1333. { type: Directive, args: [{
  1334. selector: '[cdkTreeNodePadding]',
  1335. },] },
  1336. ];
  1337. /** @nocollapse */
  1338. CdkTreeNodePadding.ctorParameters = function () { return [
  1339. { type: CdkTreeNode },
  1340. { type: CdkTree },
  1341. { type: Renderer2 },
  1342. { type: ElementRef },
  1343. { type: Directionality, decorators: [{ type: Optional }] }
  1344. ]; };
  1345. CdkTreeNodePadding.propDecorators = {
  1346. level: [{ type: Input, args: ['cdkTreeNodePadding',] }],
  1347. indent: [{ type: Input, args: ['cdkTreeNodePaddingIndent',] }]
  1348. };
  1349. return CdkTreeNodePadding;
  1350. }());
  1351. /**
  1352. * @fileoverview added by tsickle
  1353. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1354. */
  1355. /**
  1356. * Node toggle to expand/collapse the node.
  1357. * @template T
  1358. */
  1359. var CdkTreeNodeToggle = /** @class */ (function () {
  1360. function CdkTreeNodeToggle(_tree, _treeNode) {
  1361. this._tree = _tree;
  1362. this._treeNode = _treeNode;
  1363. this._recursive = false;
  1364. }
  1365. Object.defineProperty(CdkTreeNodeToggle.prototype, "recursive", {
  1366. /** Whether expand/collapse the node recursively. */
  1367. get: /**
  1368. * Whether expand/collapse the node recursively.
  1369. * @return {?}
  1370. */
  1371. function () { return this._recursive; },
  1372. set: /**
  1373. * @param {?} value
  1374. * @return {?}
  1375. */
  1376. function (value) { this._recursive = coerceBooleanProperty(value); },
  1377. enumerable: true,
  1378. configurable: true
  1379. });
  1380. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  1381. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  1382. // ViewEngine they're overwritten.
  1383. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  1384. // tslint:disable-next-line:no-host-decorator-in-concrete
  1385. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  1386. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  1387. // ViewEngine they're overwritten.
  1388. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  1389. // tslint:disable-next-line:no-host-decorator-in-concrete
  1390. /**
  1391. * @param {?} event
  1392. * @return {?}
  1393. */
  1394. CdkTreeNodeToggle.prototype._toggle =
  1395. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  1396. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  1397. // ViewEngine they're overwritten.
  1398. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  1399. // tslint:disable-next-line:no-host-decorator-in-concrete
  1400. /**
  1401. * @param {?} event
  1402. * @return {?}
  1403. */
  1404. function (event) {
  1405. this.recursive
  1406. ? this._tree.treeControl.toggleDescendants(this._treeNode.data)
  1407. : this._tree.treeControl.toggle(this._treeNode.data);
  1408. event.stopPropagation();
  1409. };
  1410. CdkTreeNodeToggle.decorators = [
  1411. { type: Directive, args: [{ selector: '[cdkTreeNodeToggle]' },] },
  1412. ];
  1413. /** @nocollapse */
  1414. CdkTreeNodeToggle.ctorParameters = function () { return [
  1415. { type: CdkTree },
  1416. { type: CdkTreeNode }
  1417. ]; };
  1418. CdkTreeNodeToggle.propDecorators = {
  1419. recursive: [{ type: Input, args: ['cdkTreeNodeToggleRecursive',] }],
  1420. _toggle: [{ type: HostListener, args: ['click', ['$event'],] }]
  1421. };
  1422. return CdkTreeNodeToggle;
  1423. }());
  1424. /**
  1425. * @fileoverview added by tsickle
  1426. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1427. */
  1428. /** @type {?} */
  1429. var EXPORTED_DECLARATIONS = [
  1430. CdkNestedTreeNode,
  1431. CdkTreeNodeDef,
  1432. CdkTreeNodePadding,
  1433. CdkTreeNodeToggle,
  1434. CdkTree,
  1435. CdkTreeNode,
  1436. CdkTreeNodeOutlet,
  1437. ];
  1438. var CdkTreeModule = /** @class */ (function () {
  1439. function CdkTreeModule() {
  1440. }
  1441. CdkTreeModule.decorators = [
  1442. { type: NgModule, args: [{
  1443. imports: [CommonModule],
  1444. exports: EXPORTED_DECLARATIONS,
  1445. declarations: EXPORTED_DECLARATIONS,
  1446. providers: [FocusMonitor, CdkTreeNodeDef]
  1447. },] },
  1448. ];
  1449. return CdkTreeModule;
  1450. }());
  1451. /**
  1452. * @fileoverview added by tsickle
  1453. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1454. */
  1455. /**
  1456. * @fileoverview added by tsickle
  1457. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1458. */
  1459. export { BaseTreeControl, FlatTreeControl, NestedTreeControl, CdkNestedTreeNode, CdkTreeNodeOutletContext, CdkTreeNodeDef, CdkTreeNodePadding, CDK_TREE_NODE_OUTLET_NODE, CdkTreeNodeOutlet, CdkTree, CdkTreeNode, getTreeNoValidDataSourceError, getTreeMultipleDefaultNodeDefsError, getTreeMissingMatchingNodeDefError, getTreeControlMissingError, getTreeControlFunctionsMissingError, CdkTreeModule, CdkTreeNodeToggle };
  1460. //# sourceMappingURL=tree.es5.js.map