diff --git a/src/cdk/tree/control/base-tree-control.ts b/src/cdk/tree/control/base-tree-control.ts index 278e65a41d0e..239f24c01315 100644 --- a/src/cdk/tree/control/base-tree-control.ts +++ b/src/cdk/tree/control/base-tree-control.ts @@ -6,8 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ import {SelectionModel} from '@angular/cdk/collections'; -import {Observable} from 'rxjs'; import {TreeControl} from './tree-control'; +import {GetChildrenFn} from './types'; /** Base tree control. It has basic toggle/expand/collapse operations on a single data node. */ export abstract class BaseTreeControl implements TreeControl { @@ -19,7 +19,7 @@ export abstract class BaseTreeControl implements TreeControl { abstract expandAll(): void; /** Saved data node for `expandAll` action. */ - dataNodes: T[]; + dataNodes: T[] | ReadonlyArray; /** A selection model with multi-selection to track expansion status. */ expansionModel: SelectionModel = new SelectionModel(true); @@ -42,7 +42,7 @@ export abstract class BaseTreeControl implements TreeControl { isExpandable: (dataNode: T) => boolean; /** Gets a stream that emits whenever the given data node's children change. */ - getChildren: (dataNode: T) => (Observable | T[] | undefined | null); + getChildren: GetChildrenFn; /** Toggles one single data node's expanded/collapsed state. */ toggle(dataNode: T): void { diff --git a/src/cdk/tree/control/flat-tree-control.ts b/src/cdk/tree/control/flat-tree-control.ts index e291eeed21ac..38cd0cda5d35 100644 --- a/src/cdk/tree/control/flat-tree-control.ts +++ b/src/cdk/tree/control/flat-tree-control.ts @@ -58,6 +58,6 @@ export class FlatTreeControl extends BaseTreeControl { * data nodes of the tree. */ expandAll(): void { - this.expansionModel.select(...this.dataNodes.map(node => this._trackByValue(node))); + this.expansionModel.select(...(this.dataNodes as T[]).map(node => this._trackByValue(node))); } } diff --git a/src/cdk/tree/control/nested-tree-control.ts b/src/cdk/tree/control/nested-tree-control.ts index c7fa57db2b4a..dbf6399eea9e 100644 --- a/src/cdk/tree/control/nested-tree-control.ts +++ b/src/cdk/tree/control/nested-tree-control.ts @@ -5,9 +5,10 @@ * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -import {Observable, isObservable} from 'rxjs'; +import {isObservable} from 'rxjs'; import {take, filter} from 'rxjs/operators'; import {BaseTreeControl} from './base-tree-control'; +import {GetChildrenFn} from './types'; /** Optional set of configuration that can be provided to the NestedTreeControl. */ export interface NestedTreeControlOptions { @@ -18,7 +19,7 @@ export interface NestedTreeControlOptions { export class NestedTreeControl extends BaseTreeControl { /** Construct with nested tree function getChildren. */ constructor( - public getChildren: (dataNode: T) => (Observable| T[] | undefined | null), + public getChildren: GetChildrenFn, public options?: NestedTreeControlOptions) { super(); @@ -35,7 +36,7 @@ export class NestedTreeControl extends BaseTreeControl { */ expandAll(): void { this.expansionModel.clear(); - const allNodes = this.dataNodes.reduce((accumulator: T[], dataNode) => + const allNodes = (this.dataNodes as ReadonlyArray).reduce((accumulator: T[], dataNode) => [...accumulator, ...this.getDescendants(dataNode), dataNode], []); this.expansionModel.select(...allNodes.map(node => this._trackByValue(node))); } diff --git a/src/cdk/tree/control/tree-control.ts b/src/cdk/tree/control/tree-control.ts index f32e0f4c5852..0459f108b881 100644 --- a/src/cdk/tree/control/tree-control.ts +++ b/src/cdk/tree/control/tree-control.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import {SelectionModel} from '@angular/cdk/collections'; -import {Observable} from 'rxjs'; +import {GetChildrenFn} from './types'; /** * Tree control interface. User can implement TreeControl to expand/collapse dataNodes in the tree. @@ -15,7 +15,7 @@ import {Observable} from 'rxjs'; */ export interface TreeControl { /** The saved tree nodes data for `expandAll` action. */ - dataNodes: T[]; + dataNodes: T[] | ReadonlyArray; /** The expansion model */ expansionModel: SelectionModel; @@ -60,5 +60,5 @@ export interface TreeControl { readonly isExpandable: (dataNode: T) => boolean; /** Gets a stream that emits whenever the given data node's children change. */ - readonly getChildren: (dataNode: T) => Observable | T[] | undefined | null; + readonly getChildren: GetChildrenFn; } diff --git a/src/cdk/tree/control/types.ts b/src/cdk/tree/control/types.ts new file mode 100644 index 000000000000..177feb32f6f7 --- /dev/null +++ b/src/cdk/tree/control/types.ts @@ -0,0 +1,13 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {Observable} from 'rxjs'; + +/** Function that can be used to get the children of a tree node. */ +export type GetChildrenFn = (node: T) => + Observable> | T[] | ReadonlyArray | undefined | null; diff --git a/src/cdk/tree/nested-node.ts b/src/cdk/tree/nested-node.ts index 75108b1c2539..f1217cebbe62 100644 --- a/src/cdk/tree/nested-node.ts +++ b/src/cdk/tree/nested-node.ts @@ -46,7 +46,7 @@ export class CdkNestedTreeNode extends CdkTreeNode implements AfterContent private _dataDiffer: IterableDiffer; /** The children data dataNodes of current node. They will be placed in `CdkTreeNodeOutlet`. */ - protected _children: T[]; + protected _children: T[] | ReadonlyArray; /** The children node placeholder. */ @ContentChildren(CdkTreeNodeOutlet, { @@ -84,7 +84,7 @@ export class CdkNestedTreeNode extends CdkTreeNode implements AfterContent } /** Add children dataNodes to the NodeOutlet */ - protected updateChildrenNodes(children?: T[]): void { + protected updateChildrenNodes(children?: T[] | ReadonlyArray): void { const outlet = this._getNodeOutlet(); if (children) { this._children = children; diff --git a/src/cdk/tree/public-api.ts b/src/cdk/tree/public-api.ts index 0b803e560f17..3e26db34219c 100644 --- a/src/cdk/tree/public-api.ts +++ b/src/cdk/tree/public-api.ts @@ -10,6 +10,7 @@ export * from './control/base-tree-control'; export * from './control/flat-tree-control'; export * from './control/nested-tree-control'; export * from './control/tree-control'; +export * from './control/types'; export * from './nested-node'; export * from './node'; export * from './padding'; diff --git a/src/cdk/tree/tree.ts b/src/cdk/tree/tree.ts index 585e3734cf5e..a8519dd164a6 100644 --- a/src/cdk/tree/tree.ts +++ b/src/cdk/tree/tree.ts @@ -381,7 +381,7 @@ export class CdkTreeNode implements FocusableOption, OnDestroy { } } - protected _setRoleFromChildren(children: T[]) { + protected _setRoleFromChildren(children: T[] | ReadonlyArray) { this.role = children && children.length ? 'group' : 'treeitem'; } } diff --git a/src/material/tree/data-source/flat-data-source.ts b/src/material/tree/data-source/flat-data-source.ts index 6a5c56a42440..66f359672419 100644 --- a/src/material/tree/data-source/flat-data-source.ts +++ b/src/material/tree/data-source/flat-data-source.ts @@ -7,7 +7,7 @@ */ import {CollectionViewer, DataSource} from '@angular/cdk/collections'; -import {FlatTreeControl, TreeControl} from '@angular/cdk/tree'; +import {FlatTreeControl, TreeControl, GetChildrenFn} from '@angular/cdk/tree'; import {BehaviorSubject, merge, Observable} from 'rxjs'; import {map, take} from 'rxjs/operators'; @@ -50,8 +50,7 @@ export class MatTreeFlattener { constructor(public transformFunction: (node: T, level: number) => F, public getLevel: (node: F) => number, public isExpandable: (node: F) => boolean, - public getChildren: (node: T) => - Observable | T[] | undefined | null) {} + public getChildren: GetChildrenFn) {} _flattenNode(node: T, level: number, resultNodes: F[], parentMap: boolean[]): F[] { @@ -64,7 +63,7 @@ export class MatTreeFlattener { if (Array.isArray(childrenNodes)) { this._flattenChildren(childrenNodes, level, resultNodes, parentMap); } else { - childrenNodes.pipe(take(1)).subscribe(children => { + (childrenNodes as Observable).pipe(take(1)).subscribe(children => { this._flattenChildren(children, level, resultNodes, parentMap); }); } diff --git a/tools/public_api_guard/cdk/tree.d.ts b/tools/public_api_guard/cdk/tree.d.ts index 108112677ac3..a1fd0a1451f8 100644 --- a/tools/public_api_guard/cdk/tree.d.ts +++ b/tools/public_api_guard/cdk/tree.d.ts @@ -1,7 +1,7 @@ export declare abstract class BaseTreeControl implements TreeControl { - dataNodes: T[]; + dataNodes: T[] | ReadonlyArray; expansionModel: SelectionModel; - getChildren: (dataNode: T) => (Observable | T[] | undefined | null); + getChildren: GetChildrenFn; getLevel: (dataNode: T) => number; isExpandable: (dataNode: T) => boolean; trackBy?: (dataNode: T) => K; @@ -21,7 +21,7 @@ export declare abstract class BaseTreeControl implements TreeControl; export declare class CdkNestedTreeNode extends CdkTreeNode implements AfterContentInit, OnDestroy { - protected _children: T[]; + protected _children: T[] | ReadonlyArray; protected _differs: IterableDiffers; protected _elementRef: ElementRef; protected _tree: CdkTree; @@ -30,7 +30,7 @@ export declare class CdkNestedTreeNode extends CdkTreeNode implements Afte protected _clear(): void; ngAfterContentInit(): void; ngOnDestroy(): void; - protected updateChildrenNodes(children?: T[]): void; + protected updateChildrenNodes(children?: T[] | ReadonlyArray): void; static ɵdir: i0.ɵɵDirectiveDefWithMeta, "cdk-nested-tree-node", ["cdkNestedTreeNode"], {}, {}, ["nodeOutlet"]>; static ɵfac: i0.ɵɵFactoryDef, never>; } @@ -74,7 +74,7 @@ export declare class CdkTreeNode implements FocusableOption, OnDestroy { get level(): number; role: 'treeitem' | 'group'; constructor(_elementRef: ElementRef, _tree: CdkTree); - protected _setRoleFromChildren(children: T[]): void; + protected _setRoleFromChildren(children: T[] | ReadonlyArray): void; protected _setRoleFromData(): void; focus(): void; ngOnDestroy(): void; @@ -151,6 +151,8 @@ export interface FlatTreeControlOptions { trackBy?: (dataNode: T) => K; } +export declare type GetChildrenFn = (node: T) => Observable> | T[] | ReadonlyArray | undefined | null; + export declare function getTreeControlFunctionsMissingError(): Error; export declare function getTreeControlMissingError(): Error; @@ -162,9 +164,9 @@ export declare function getTreeMultipleDefaultNodeDefsError(): Error; export declare function getTreeNoValidDataSourceError(): Error; export declare class NestedTreeControl extends BaseTreeControl { - getChildren: (dataNode: T) => (Observable | T[] | undefined | null); + getChildren: GetChildrenFn; options?: NestedTreeControlOptions | undefined; - constructor(getChildren: (dataNode: T) => (Observable | T[] | undefined | null), options?: NestedTreeControlOptions | undefined); + constructor(getChildren: GetChildrenFn, options?: NestedTreeControlOptions | undefined); protected _getDescendants(descendants: T[], dataNode: T): void; expandAll(): void; getDescendants(dataNode: T): T[]; @@ -175,9 +177,9 @@ export interface NestedTreeControlOptions { } export interface TreeControl { - dataNodes: T[]; + dataNodes: T[] | ReadonlyArray; expansionModel: SelectionModel; - readonly getChildren: (dataNode: T) => Observable | T[] | undefined | null; + readonly getChildren: GetChildrenFn; readonly getLevel: (dataNode: T) => number; readonly isExpandable: (dataNode: T) => boolean; collapse(dataNode: T): void; diff --git a/tools/public_api_guard/material/tree.d.ts b/tools/public_api_guard/material/tree.d.ts index 255d99997c97..6cf4cc51862e 100644 --- a/tools/public_api_guard/material/tree.d.ts +++ b/tools/public_api_guard/material/tree.d.ts @@ -33,11 +33,11 @@ export declare class MatTreeFlatDataSource extends DataSource { } export declare class MatTreeFlattener { - getChildren: (node: T) => Observable | T[] | undefined | null; + getChildren: GetChildrenFn; getLevel: (node: F) => number; isExpandable: (node: F) => boolean; transformFunction: (node: T, level: number) => F; - constructor(transformFunction: (node: T, level: number) => F, getLevel: (node: F) => number, isExpandable: (node: F) => boolean, getChildren: (node: T) => Observable | T[] | undefined | null); + constructor(transformFunction: (node: T, level: number) => F, getLevel: (node: F) => number, isExpandable: (node: F) => boolean, getChildren: GetChildrenFn); _flattenChildren(children: T[], level: number, resultNodes: F[], parentMap: boolean[]): void; _flattenNode(node: T, level: number, resultNodes: F[], parentMap: boolean[]): F[]; expandFlattenedNodes(nodes: F[], treeControl: TreeControl): F[];