From 23bc6bd4eea4a19b4c518339c5eee544b2c3c780 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 7 Mar 2025 13:32:50 +0100 Subject: [PATCH] docs(cdk/tree): examples not working when forked to Stackblitz The tree examples were breaking down when forked to Stackblitz, because of a couple of reasons: 1. They had their sample data in a separate file which the build process wasn't picking up. 2. They had compilation errors only with rxjs 7+ which we didn't notice, because our local setup is on rxjs 6. I also went through all the examples and moved the sample data further down so it doesn't distract from the actual code. Fixes #30600. --- .../cdk-tree-complex-example.ts | 76 +++++------ .../cdk-tree-custom-key-manager-example.ts | 124 +++++++++--------- ...ree-flat-children-accessor-example-data.ts | 28 ---- ...cdk-tree-flat-children-accessor-example.ts | 34 ++++- ...k-tree-flat-level-accessor-example-data.ts | 65 --------- .../cdk-tree-flat-level-accessor-example.ts | 75 ++++++++++- .../cdk-tree-flat/cdk-tree-flat-example.ts | 106 +++++++-------- ...e-nested-children-accessor-example-data.ts | 28 ---- ...k-tree-nested-children-accessor-example.ts | 34 ++++- ...tree-nested-level-accessor-example-data.ts | 65 --------- .../cdk-tree-nested-level-accessor-example.ts | 75 ++++++++++- .../cdk-tree-nested-example.ts | 36 ++--- .../tree/tree-dynamic/tree-dynamic-example.ts | 2 +- ...ee-flat-child-accessor-overview-example.ts | 36 ++--- .../tree-flat-overview-example.ts | 42 +++--- .../tree/tree-harness/tree-harness-example.ts | 34 ++--- .../tree-legacy-keyboard-interface-example.ts | 84 ++++++------ .../tree-loadmore/tree-loadmore-example.ts | 5 +- ...-nested-child-accessor-overview-example.ts | 38 +++--- .../tree-nested-overview-example.ts | 42 +++--- 20 files changed, 514 insertions(+), 515 deletions(-) delete mode 100644 src/components-examples/cdk/tree/cdk-tree-flat-children-accessor/cdk-tree-flat-children-accessor-example-data.ts delete mode 100644 src/components-examples/cdk/tree/cdk-tree-flat-level-accessor/cdk-tree-flat-level-accessor-example-data.ts delete mode 100644 src/components-examples/cdk/tree/cdk-tree-nested-children-accessor/cdk-tree-nested-children-accessor-example-data.ts delete mode 100644 src/components-examples/cdk/tree/cdk-tree-nested-level-accessor/cdk-tree-nested-level-accessor-example-data.ts diff --git a/src/components-examples/cdk/tree/cdk-tree-complex/cdk-tree-complex-example.ts b/src/components-examples/cdk/tree/cdk-tree-complex/cdk-tree-complex-example.ts index ae28c30ecdf6..9164277e240d 100644 --- a/src/components-examples/cdk/tree/cdk-tree-complex/cdk-tree-complex-example.ts +++ b/src/components-examples/cdk/tree/cdk-tree-complex/cdk-tree-complex-example.ts @@ -14,40 +14,6 @@ interface BackendData { children?: string[]; } -const TREE_DATA: Map = new Map( - [ - { - id: '1', - name: 'Fruit', - children: ['1-1', '1-2', '1-3'], - }, - {id: '1-1', name: 'Apple', parent: '1'}, - {id: '1-2', name: 'Banana', parent: '1'}, - {id: '1-3', name: 'Fruit Loops', parent: '1'}, - { - id: '2', - name: 'Vegetables', - children: ['2-1', '2-2'], - }, - { - id: '2-1', - name: 'Green', - parent: '2', - children: ['2-1-1', '2-1-2'], - }, - { - id: '2-2', - name: 'Orange', - parent: '2', - children: ['2-2-1', '2-2-2'], - }, - {id: '2-1-1', name: 'Broccoli', parent: '2-1'}, - {id: '2-1-2', name: 'Brussel sprouts', parent: '2-1'}, - {id: '2-2-1', name: 'Pumpkins', parent: '2-2'}, - {id: '2-2-2', name: 'Carrots', parent: '2-2'}, - ].map(datum => [datum.id, datum]), -); - class FakeDataBackend { private _getRandomDelayTime() { // anywhere from 100 to 500ms. @@ -56,16 +22,16 @@ class FakeDataBackend { getChildren(id: string): Observable { // first, find the specified ID in our tree - const item = TREE_DATA.get(id); + const item = EXAMPLE_DATA.get(id); const children = item?.children ?? []; - return observableOf(children.map(childId => TREE_DATA.get(childId)!)).pipe( + return observableOf(children.map(childId => EXAMPLE_DATA.get(childId)!)).pipe( delay(this._getRandomDelayTime()), ); } getRoots(): Observable { - return observableOf([...TREE_DATA.values()].filter(datum => !datum.parent)).pipe( + return observableOf([...EXAMPLE_DATA.values()].filter(datum => !datum.parent)).pipe( delay(this._getRandomDelayTime()), ); } @@ -268,7 +234,7 @@ class ComplexDataStore { const transformFn = sourcesAndTransform[sourcesAndTransform.length - 1] as TransformFn; return combineLatest([...sources, this._state]).pipe( - map(args => transformFn(...(args as [...ObservedValuesOf, State]))), + map(args => transformFn(...(args as unknown as [...ObservedValuesOf, State]))), shareReplay({refCount: true, bufferSize: 1}), ); } @@ -305,3 +271,37 @@ export class CdkTreeComplexExample implements OnInit { } } } + +const EXAMPLE_DATA = new Map( + [ + { + id: '1', + name: 'Fruit', + children: ['1-1', '1-2', '1-3'], + }, + {id: '1-1', name: 'Apple', parent: '1'}, + {id: '1-2', name: 'Banana', parent: '1'}, + {id: '1-3', name: 'Fruit Loops', parent: '1'}, + { + id: '2', + name: 'Vegetables', + children: ['2-1', '2-2'], + }, + { + id: '2-1', + name: 'Green', + parent: '2', + children: ['2-1-1', '2-1-2'], + }, + { + id: '2-2', + name: 'Orange', + parent: '2', + children: ['2-2-1', '2-2-2'], + }, + {id: '2-1-1', name: 'Broccoli', parent: '2-1'}, + {id: '2-1-2', name: 'Brussel sprouts', parent: '2-1'}, + {id: '2-2-1', name: 'Pumpkins', parent: '2-2'}, + {id: '2-2-2', name: 'Carrots', parent: '2-2'}, + ].map(datum => [datum.id, datum]), +); diff --git a/src/components-examples/cdk/tree/cdk-tree-custom-key-manager/cdk-tree-custom-key-manager-example.ts b/src/components-examples/cdk/tree/cdk-tree-custom-key-manager/cdk-tree-custom-key-manager-example.ts index 65a7185ae72c..bc66a7a4eb95 100644 --- a/src/components-examples/cdk/tree/cdk-tree-custom-key-manager/cdk-tree-custom-key-manager-example.ts +++ b/src/components-examples/cdk/tree/cdk-tree-custom-key-manager/cdk-tree-custom-key-manager-example.ts @@ -28,64 +28,6 @@ import { import {Subject, isObservable, Observable} from 'rxjs'; import {take} from 'rxjs/operators'; -const TREE_DATA: ExampleFlatNode[] = [ - { - name: 'Fruit', - expandable: true, - level: 0, - }, - { - name: 'Apple', - expandable: false, - level: 1, - }, - { - name: 'Banana', - expandable: false, - level: 1, - }, - { - name: 'Fruit loops', - expandable: false, - level: 1, - }, - { - name: 'Vegetables', - expandable: true, - level: 0, - }, - { - name: 'Green', - expandable: true, - level: 1, - }, - { - name: 'Broccoli', - expandable: false, - level: 2, - }, - { - name: 'Brussels sprouts', - expandable: false, - level: 2, - }, - { - name: 'Orange', - expandable: true, - level: 1, - }, - { - name: 'Pumpkins', - expandable: false, - level: 2, - }, - { - name: 'Carrots', - expandable: false, - level: 2, - }, -]; - /** Flat node with expandable and level information */ interface ExampleFlatNode { expandable: boolean; @@ -379,16 +321,16 @@ export class CdkTreeCustomKeyManagerExample { node => node.expandable, ); - dataSource = new ArrayDataSource(TREE_DATA); + dataSource = new ArrayDataSource(EXAMPLE_DATA); hasChild = (_: number, node: ExampleFlatNode) => node.expandable; getParentNode(node: ExampleFlatNode) { - const nodeIndex = TREE_DATA.indexOf(node); + const nodeIndex = EXAMPLE_DATA.indexOf(node); for (let i = nodeIndex - 1; i >= 0; i--) { - if (TREE_DATA[i].level === node.level - 1) { - return TREE_DATA[i]; + if (EXAMPLE_DATA[i].level === node.level - 1) { + return EXAMPLE_DATA[i]; } } @@ -406,3 +348,61 @@ export class CdkTreeCustomKeyManagerExample { return true; } } + +const EXAMPLE_DATA: ExampleFlatNode[] = [ + { + name: 'Fruit', + expandable: true, + level: 0, + }, + { + name: 'Apple', + expandable: false, + level: 1, + }, + { + name: 'Banana', + expandable: false, + level: 1, + }, + { + name: 'Fruit loops', + expandable: false, + level: 1, + }, + { + name: 'Vegetables', + expandable: true, + level: 0, + }, + { + name: 'Green', + expandable: true, + level: 1, + }, + { + name: 'Broccoli', + expandable: false, + level: 2, + }, + { + name: 'Brussels sprouts', + expandable: false, + level: 2, + }, + { + name: 'Orange', + expandable: true, + level: 1, + }, + { + name: 'Pumpkins', + expandable: false, + level: 2, + }, + { + name: 'Carrots', + expandable: false, + level: 2, + }, +]; diff --git a/src/components-examples/cdk/tree/cdk-tree-flat-children-accessor/cdk-tree-flat-children-accessor-example-data.ts b/src/components-examples/cdk/tree/cdk-tree-flat-children-accessor/cdk-tree-flat-children-accessor-example-data.ts deleted file mode 100644 index acac71a54292..000000000000 --- a/src/components-examples/cdk/tree/cdk-tree-flat-children-accessor/cdk-tree-flat-children-accessor-example-data.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Food data with nested structure. - * Each node has a name and an optional list of children. - */ -export interface NestedFoodNode { - name: string; - children?: NestedFoodNode[]; -} - -export const NESTED_DATA: NestedFoodNode[] = [ - { - name: 'Fruit', - children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], - }, - { - name: 'Vegetables', - children: [ - { - name: 'Green', - children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}], - }, - { - name: 'Orange', - children: [{name: 'Pumpkins'}, {name: 'Carrots'}], - }, - ], - }, -]; diff --git a/src/components-examples/cdk/tree/cdk-tree-flat-children-accessor/cdk-tree-flat-children-accessor-example.ts b/src/components-examples/cdk/tree/cdk-tree-flat-children-accessor/cdk-tree-flat-children-accessor-example.ts index 05afa9bc04a7..cb5ecbbd3d8e 100644 --- a/src/components-examples/cdk/tree/cdk-tree-flat-children-accessor/cdk-tree-flat-children-accessor-example.ts +++ b/src/components-examples/cdk/tree/cdk-tree-flat-children-accessor/cdk-tree-flat-children-accessor-example.ts @@ -5,7 +5,15 @@ import {MatButtonModule} from '@angular/material/button'; import {MatIconModule} from '@angular/material/icon'; import {timer} from 'rxjs'; import {mapTo} from 'rxjs/operators'; -import {NestedFoodNode, NESTED_DATA} from './cdk-tree-flat-children-accessor-example-data'; + +/** + * Food data with nested structure. + * Each node has a name and an optional list of children. + */ +interface NestedFoodNode { + name: string; + children?: NestedFoodNode[]; +} function flattenNodes(nodes: NestedFoodNode[]): NestedFoodNode[] { const flattenedNodes = []; @@ -34,12 +42,12 @@ export class CdkTreeFlatChildrenAccessorExample { childrenAccessor = (dataNode: NestedFoodNode) => timer(100).pipe(mapTo(dataNode.children ?? [])); - dataSource = new ArrayDataSource(NESTED_DATA); + dataSource = new ArrayDataSource(EXAMPLE_DATA); hasChild = (_: number, node: NestedFoodNode) => !!node.children?.length; getParentNode(node: NestedFoodNode) { - for (const parent of flattenNodes(NESTED_DATA)) { + for (const parent of flattenNodes(EXAMPLE_DATA)) { if (parent.children?.includes(node)) { return parent; } @@ -59,3 +67,23 @@ export class CdkTreeFlatChildrenAccessorExample { return true; } } + +const EXAMPLE_DATA: NestedFoodNode[] = [ + { + name: 'Fruit', + children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], + }, + { + name: 'Vegetables', + children: [ + { + name: 'Green', + children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}], + }, + { + name: 'Orange', + children: [{name: 'Pumpkins'}, {name: 'Carrots'}], + }, + ], + }, +]; diff --git a/src/components-examples/cdk/tree/cdk-tree-flat-level-accessor/cdk-tree-flat-level-accessor-example-data.ts b/src/components-examples/cdk/tree/cdk-tree-flat-level-accessor/cdk-tree-flat-level-accessor-example-data.ts deleted file mode 100644 index 7adbadfd8412..000000000000 --- a/src/components-examples/cdk/tree/cdk-tree-flat-level-accessor/cdk-tree-flat-level-accessor-example-data.ts +++ /dev/null @@ -1,65 +0,0 @@ -/** Flat node with expandable and level information */ -export interface FlatFoodNode { - expandable: boolean; - name: string; - level: number; - isExpanded?: boolean; -} - -export const FLAT_DATA: FlatFoodNode[] = [ - { - name: 'Fruit', - expandable: true, - level: 0, - }, - { - name: 'Apple', - expandable: false, - level: 1, - }, - { - name: 'Banana', - expandable: false, - level: 1, - }, - { - name: 'Fruit loops', - expandable: false, - level: 1, - }, - { - name: 'Vegetables', - expandable: true, - level: 0, - }, - { - name: 'Green', - expandable: true, - level: 1, - }, - { - name: 'Broccoli', - expandable: false, - level: 2, - }, - { - name: 'Brussels sprouts', - expandable: false, - level: 2, - }, - { - name: 'Orange', - expandable: true, - level: 1, - }, - { - name: 'Pumpkins', - expandable: false, - level: 2, - }, - { - name: 'Carrots', - expandable: false, - level: 2, - }, -]; diff --git a/src/components-examples/cdk/tree/cdk-tree-flat-level-accessor/cdk-tree-flat-level-accessor-example.ts b/src/components-examples/cdk/tree/cdk-tree-flat-level-accessor/cdk-tree-flat-level-accessor-example.ts index 0c43535778d6..9c4b6da9d73d 100644 --- a/src/components-examples/cdk/tree/cdk-tree-flat-level-accessor/cdk-tree-flat-level-accessor-example.ts +++ b/src/components-examples/cdk/tree/cdk-tree-flat-level-accessor/cdk-tree-flat-level-accessor-example.ts @@ -3,7 +3,14 @@ import {CdkTree, CdkTreeModule} from '@angular/cdk/tree'; import {ChangeDetectionStrategy, Component, ViewChild} from '@angular/core'; import {MatButtonModule} from '@angular/material/button'; import {MatIconModule} from '@angular/material/icon'; -import {FlatFoodNode, FLAT_DATA} from './cdk-tree-flat-level-accessor-example-data'; + +/** Flat node with expandable and level information */ +interface FlatFoodNode { + expandable: boolean; + name: string; + level: number; + isExpanded?: boolean; +} /** * @title Tree with flat nodes @@ -21,18 +28,18 @@ export class CdkTreeFlatLevelAccessorExample { levelAccessor = (dataNode: FlatFoodNode) => dataNode.level; - dataSource = new ArrayDataSource(FLAT_DATA); + dataSource = new ArrayDataSource(EXAMPLE_DATA); hasChild = (_: number, node: FlatFoodNode) => node.expandable; getParentNode(node: FlatFoodNode) { - const nodeIndex = FLAT_DATA.indexOf(node); + const nodeIndex = EXAMPLE_DATA.indexOf(node); // Determine the node's parent by finding the first preceding node that's // one level shallower. for (let i = nodeIndex - 1; i >= 0; i--) { - if (FLAT_DATA[i].level === node.level - 1) { - return FLAT_DATA[i]; + if (EXAMPLE_DATA[i].level === node.level - 1) { + return EXAMPLE_DATA[i]; } } @@ -45,3 +52,61 @@ export class CdkTreeFlatLevelAccessorExample { return !parent || (!!this.tree?.isExpanded(parent) && this.shouldRender(parent)); } } + +const EXAMPLE_DATA: FlatFoodNode[] = [ + { + name: 'Fruit', + expandable: true, + level: 0, + }, + { + name: 'Apple', + expandable: false, + level: 1, + }, + { + name: 'Banana', + expandable: false, + level: 1, + }, + { + name: 'Fruit loops', + expandable: false, + level: 1, + }, + { + name: 'Vegetables', + expandable: true, + level: 0, + }, + { + name: 'Green', + expandable: true, + level: 1, + }, + { + name: 'Broccoli', + expandable: false, + level: 2, + }, + { + name: 'Brussels sprouts', + expandable: false, + level: 2, + }, + { + name: 'Orange', + expandable: true, + level: 1, + }, + { + name: 'Pumpkins', + expandable: false, + level: 2, + }, + { + name: 'Carrots', + expandable: false, + level: 2, + }, +]; diff --git a/src/components-examples/cdk/tree/cdk-tree-flat/cdk-tree-flat-example.ts b/src/components-examples/cdk/tree/cdk-tree-flat/cdk-tree-flat-example.ts index 6593af4b5043..8cd723ace64d 100644 --- a/src/components-examples/cdk/tree/cdk-tree-flat/cdk-tree-flat-example.ts +++ b/src/components-examples/cdk/tree/cdk-tree-flat/cdk-tree-flat-example.ts @@ -4,7 +4,59 @@ import {FlatTreeControl, CdkTreeModule} from '@angular/cdk/tree'; import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; -const TREE_DATA: ExampleFlatNode[] = [ +/** Flat node with expandable and level information */ +interface ExampleFlatNode { + expandable: boolean; + name: string; + level: number; + isExpanded?: boolean; +} + +/** + * @title Tree with flat nodes + */ +@Component({ + selector: 'cdk-tree-flat-example', + templateUrl: 'cdk-tree-flat-example.html', + styleUrl: 'cdk-tree-flat-example.css', + imports: [CdkTreeModule, MatButtonModule, MatIconModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class CdkTreeFlatExample { + treeControl = new FlatTreeControl( + node => node.level, + node => node.expandable, + ); + + dataSource = new ArrayDataSource(EXAMPLE_DATA); + + hasChild = (_: number, node: ExampleFlatNode) => node.expandable; + + getParentNode(node: ExampleFlatNode) { + const nodeIndex = EXAMPLE_DATA.indexOf(node); + + for (let i = nodeIndex - 1; i >= 0; i--) { + if (EXAMPLE_DATA[i].level === node.level - 1) { + return EXAMPLE_DATA[i]; + } + } + + return null; + } + + shouldRender(node: ExampleFlatNode) { + let parent = this.getParentNode(node); + while (parent) { + if (!parent.isExpanded) { + return false; + } + parent = this.getParentNode(parent); + } + return true; + } +} + +const EXAMPLE_DATA: ExampleFlatNode[] = [ { name: 'Fruit', expandable: true, @@ -61,55 +113,3 @@ const TREE_DATA: ExampleFlatNode[] = [ level: 2, }, ]; - -/** Flat node with expandable and level information */ -interface ExampleFlatNode { - expandable: boolean; - name: string; - level: number; - isExpanded?: boolean; -} - -/** - * @title Tree with flat nodes - */ -@Component({ - selector: 'cdk-tree-flat-example', - templateUrl: 'cdk-tree-flat-example.html', - styleUrl: 'cdk-tree-flat-example.css', - imports: [CdkTreeModule, MatButtonModule, MatIconModule], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class CdkTreeFlatExample { - treeControl = new FlatTreeControl( - node => node.level, - node => node.expandable, - ); - - dataSource = new ArrayDataSource(TREE_DATA); - - hasChild = (_: number, node: ExampleFlatNode) => node.expandable; - - getParentNode(node: ExampleFlatNode) { - const nodeIndex = TREE_DATA.indexOf(node); - - for (let i = nodeIndex - 1; i >= 0; i--) { - if (TREE_DATA[i].level === node.level - 1) { - return TREE_DATA[i]; - } - } - - return null; - } - - shouldRender(node: ExampleFlatNode) { - let parent = this.getParentNode(node); - while (parent) { - if (!parent.isExpanded) { - return false; - } - parent = this.getParentNode(parent); - } - return true; - } -} diff --git a/src/components-examples/cdk/tree/cdk-tree-nested-children-accessor/cdk-tree-nested-children-accessor-example-data.ts b/src/components-examples/cdk/tree/cdk-tree-nested-children-accessor/cdk-tree-nested-children-accessor-example-data.ts deleted file mode 100644 index acac71a54292..000000000000 --- a/src/components-examples/cdk/tree/cdk-tree-nested-children-accessor/cdk-tree-nested-children-accessor-example-data.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Food data with nested structure. - * Each node has a name and an optional list of children. - */ -export interface NestedFoodNode { - name: string; - children?: NestedFoodNode[]; -} - -export const NESTED_DATA: NestedFoodNode[] = [ - { - name: 'Fruit', - children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], - }, - { - name: 'Vegetables', - children: [ - { - name: 'Green', - children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}], - }, - { - name: 'Orange', - children: [{name: 'Pumpkins'}, {name: 'Carrots'}], - }, - ], - }, -]; diff --git a/src/components-examples/cdk/tree/cdk-tree-nested-children-accessor/cdk-tree-nested-children-accessor-example.ts b/src/components-examples/cdk/tree/cdk-tree-nested-children-accessor/cdk-tree-nested-children-accessor-example.ts index 910aafbf9343..c839d255fadf 100644 --- a/src/components-examples/cdk/tree/cdk-tree-nested-children-accessor/cdk-tree-nested-children-accessor-example.ts +++ b/src/components-examples/cdk/tree/cdk-tree-nested-children-accessor/cdk-tree-nested-children-accessor-example.ts @@ -3,7 +3,15 @@ import {CdkTree, CdkTreeModule} from '@angular/cdk/tree'; import {ChangeDetectionStrategy, Component, ViewChild} from '@angular/core'; import {MatButtonModule} from '@angular/material/button'; import {MatIconModule} from '@angular/material/icon'; -import {NestedFoodNode, NESTED_DATA} from './cdk-tree-nested-children-accessor-example-data'; + +/** + * Food data with nested structure. + * Each node has a name and an optional list of children. + */ +interface NestedFoodNode { + name: string; + children?: NestedFoodNode[]; +} function flattenNodes(nodes: NestedFoodNode[]): NestedFoodNode[] { const flattenedNodes = []; @@ -31,12 +39,12 @@ export class CdkTreeNestedChildrenAccessorExample { childrenAccessor = (dataNode: NestedFoodNode) => dataNode.children ?? []; - dataSource = new ArrayDataSource(NESTED_DATA); + dataSource = new ArrayDataSource(EXAMPLE_DATA); hasChild = (_: number, node: NestedFoodNode) => !!node.children && node.children.length > 0; getParentNode(node: NestedFoodNode) { - for (const parent of flattenNodes(NESTED_DATA)) { + for (const parent of flattenNodes(EXAMPLE_DATA)) { if (parent.children?.includes(node)) { return parent; } @@ -51,3 +59,23 @@ export class CdkTreeNestedChildrenAccessorExample { return !parent || (!!this.tree?.isExpanded(parent) && this.shouldRender(parent)); } } + +const EXAMPLE_DATA: NestedFoodNode[] = [ + { + name: 'Fruit', + children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], + }, + { + name: 'Vegetables', + children: [ + { + name: 'Green', + children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}], + }, + { + name: 'Orange', + children: [{name: 'Pumpkins'}, {name: 'Carrots'}], + }, + ], + }, +]; diff --git a/src/components-examples/cdk/tree/cdk-tree-nested-level-accessor/cdk-tree-nested-level-accessor-example-data.ts b/src/components-examples/cdk/tree/cdk-tree-nested-level-accessor/cdk-tree-nested-level-accessor-example-data.ts deleted file mode 100644 index 7adbadfd8412..000000000000 --- a/src/components-examples/cdk/tree/cdk-tree-nested-level-accessor/cdk-tree-nested-level-accessor-example-data.ts +++ /dev/null @@ -1,65 +0,0 @@ -/** Flat node with expandable and level information */ -export interface FlatFoodNode { - expandable: boolean; - name: string; - level: number; - isExpanded?: boolean; -} - -export const FLAT_DATA: FlatFoodNode[] = [ - { - name: 'Fruit', - expandable: true, - level: 0, - }, - { - name: 'Apple', - expandable: false, - level: 1, - }, - { - name: 'Banana', - expandable: false, - level: 1, - }, - { - name: 'Fruit loops', - expandable: false, - level: 1, - }, - { - name: 'Vegetables', - expandable: true, - level: 0, - }, - { - name: 'Green', - expandable: true, - level: 1, - }, - { - name: 'Broccoli', - expandable: false, - level: 2, - }, - { - name: 'Brussels sprouts', - expandable: false, - level: 2, - }, - { - name: 'Orange', - expandable: true, - level: 1, - }, - { - name: 'Pumpkins', - expandable: false, - level: 2, - }, - { - name: 'Carrots', - expandable: false, - level: 2, - }, -]; diff --git a/src/components-examples/cdk/tree/cdk-tree-nested-level-accessor/cdk-tree-nested-level-accessor-example.ts b/src/components-examples/cdk/tree/cdk-tree-nested-level-accessor/cdk-tree-nested-level-accessor-example.ts index 4b2c9b641c6d..1809bc1a1598 100644 --- a/src/components-examples/cdk/tree/cdk-tree-nested-level-accessor/cdk-tree-nested-level-accessor-example.ts +++ b/src/components-examples/cdk/tree/cdk-tree-nested-level-accessor/cdk-tree-nested-level-accessor-example.ts @@ -3,7 +3,14 @@ import {CdkTree, CdkTreeModule} from '@angular/cdk/tree'; import {ChangeDetectionStrategy, Component, ViewChild} from '@angular/core'; import {MatButtonModule} from '@angular/material/button'; import {MatIconModule} from '@angular/material/icon'; -import {FLAT_DATA, FlatFoodNode} from './cdk-tree-nested-level-accessor-example-data'; + +/** Flat node with expandable and level information */ +interface FlatFoodNode { + expandable: boolean; + name: string; + level: number; + isExpanded?: boolean; +} /** * @title Tree with nested nodes and level accessor @@ -20,18 +27,18 @@ export class CdkTreeNestedLevelAccessorExample { levelAccessor = (dataNode: FlatFoodNode) => dataNode.level; - dataSource = new ArrayDataSource(FLAT_DATA); + dataSource = new ArrayDataSource(EXAMPLE_DATA); hasChild = (_: number, node: FlatFoodNode) => node.expandable; getParentNode(node: FlatFoodNode) { - const nodeIndex = FLAT_DATA.indexOf(node); + const nodeIndex = EXAMPLE_DATA.indexOf(node); // Determine the node's parent by finding the first preceding node that's // one level shallower. for (let i = nodeIndex - 1; i >= 0; i--) { - if (FLAT_DATA[i].level === node.level - 1) { - return FLAT_DATA[i]; + if (EXAMPLE_DATA[i].level === node.level - 1) { + return EXAMPLE_DATA[i]; } } @@ -44,3 +51,61 @@ export class CdkTreeNestedLevelAccessorExample { return !parent || (!!this.tree?.isExpanded(parent) && this.shouldRender(parent)); } } + +const EXAMPLE_DATA: FlatFoodNode[] = [ + { + name: 'Fruit', + expandable: true, + level: 0, + }, + { + name: 'Apple', + expandable: false, + level: 1, + }, + { + name: 'Banana', + expandable: false, + level: 1, + }, + { + name: 'Fruit loops', + expandable: false, + level: 1, + }, + { + name: 'Vegetables', + expandable: true, + level: 0, + }, + { + name: 'Green', + expandable: true, + level: 1, + }, + { + name: 'Broccoli', + expandable: false, + level: 2, + }, + { + name: 'Brussels sprouts', + expandable: false, + level: 2, + }, + { + name: 'Orange', + expandable: true, + level: 1, + }, + { + name: 'Pumpkins', + expandable: false, + level: 2, + }, + { + name: 'Carrots', + expandable: false, + level: 2, + }, +]; diff --git a/src/components-examples/cdk/tree/cdk-tree-nested/cdk-tree-nested-example.ts b/src/components-examples/cdk/tree/cdk-tree-nested/cdk-tree-nested-example.ts index d468d27a764b..622cb919236c 100644 --- a/src/components-examples/cdk/tree/cdk-tree-nested/cdk-tree-nested-example.ts +++ b/src/components-examples/cdk/tree/cdk-tree-nested/cdk-tree-nested-example.ts @@ -13,7 +13,24 @@ interface FoodNode { children?: FoodNode[]; } -const TREE_DATA: FoodNode[] = [ +/** + * @title Tree with nested nodes + */ +@Component({ + selector: 'cdk-tree-nested-example', + templateUrl: 'cdk-tree-nested-example.html', + styleUrl: 'cdk-tree-nested-example.css', + imports: [CdkTreeModule, MatButtonModule, MatIconModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class CdkTreeNestedExample { + treeControl = new NestedTreeControl(node => node.children); + dataSource = new ArrayDataSource(EXAMPLE_DATA); + + hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0; +} + +const EXAMPLE_DATA: FoodNode[] = [ { name: 'Fruit', children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], @@ -32,20 +49,3 @@ const TREE_DATA: FoodNode[] = [ ], }, ]; - -/** - * @title Tree with nested nodes - */ -@Component({ - selector: 'cdk-tree-nested-example', - templateUrl: 'cdk-tree-nested-example.html', - styleUrl: 'cdk-tree-nested-example.css', - imports: [CdkTreeModule, MatButtonModule, MatIconModule], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class CdkTreeNestedExample { - treeControl = new NestedTreeControl(node => node.children); - dataSource = new ArrayDataSource(TREE_DATA); - - hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0; -} diff --git a/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts b/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts index 5bb02d9836c9..84698afd315e 100644 --- a/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts +++ b/src/components-examples/material/tree/tree-dynamic/tree-dynamic-example.ts @@ -9,7 +9,7 @@ import {MatButtonModule} from '@angular/material/button'; import {MatTreeModule} from '@angular/material/tree'; /** Flat node with expandable and level information */ -export class DynamicFlatNode { +class DynamicFlatNode { constructor( public item: string, public level = 1, diff --git a/src/components-examples/material/tree/tree-flat-child-accessor-overview/tree-flat-child-accessor-overview-example.ts b/src/components-examples/material/tree/tree-flat-child-accessor-overview/tree-flat-child-accessor-overview-example.ts index 551f09a4a8d9..17d0c50eb649 100644 --- a/src/components-examples/material/tree/tree-flat-child-accessor-overview/tree-flat-child-accessor-overview-example.ts +++ b/src/components-examples/material/tree/tree-flat-child-accessor-overview/tree-flat-child-accessor-overview-example.ts @@ -12,7 +12,24 @@ interface FoodNode { children?: FoodNode[]; } -const TREE_DATA: FoodNode[] = [ +/** + * @title Tree with flat nodes (childrenAccessor) + */ +@Component({ + selector: 'tree-flat-child-accessor-overview-example', + templateUrl: 'tree-flat-child-accessor-overview-example.html', + imports: [MatTreeModule, MatButtonModule, MatIconModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TreeFlatChildAccessorOverviewExample { + dataSource = EXAMPLE_DATA; + + childrenAccessor = (node: FoodNode) => node.children ?? []; + + hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0; +} + +const EXAMPLE_DATA: FoodNode[] = [ { name: 'Fruit', children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], @@ -31,20 +48,3 @@ const TREE_DATA: FoodNode[] = [ ], }, ]; - -/** - * @title Tree with flat nodes (childrenAccessor) - */ -@Component({ - selector: 'tree-flat-child-accessor-overview-example', - templateUrl: 'tree-flat-child-accessor-overview-example.html', - imports: [MatTreeModule, MatButtonModule, MatIconModule], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class TreeFlatChildAccessorOverviewExample { - dataSource = TREE_DATA; - - childrenAccessor = (node: FoodNode) => node.children ?? []; - - hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0; -} diff --git a/src/components-examples/material/tree/tree-flat-overview/tree-flat-overview-example.ts b/src/components-examples/material/tree/tree-flat-overview/tree-flat-overview-example.ts index b5890ac817d9..4211f713c539 100644 --- a/src/components-examples/material/tree/tree-flat-overview/tree-flat-overview-example.ts +++ b/src/components-examples/material/tree/tree-flat-overview/tree-flat-overview-example.ts @@ -13,26 +13,6 @@ interface FoodNode { children?: FoodNode[]; } -const TREE_DATA: FoodNode[] = [ - { - name: 'Fruit', - children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], - }, - { - name: 'Vegetables', - children: [ - { - name: 'Green', - children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}], - }, - { - name: 'Orange', - children: [{name: 'Pumpkins'}, {name: 'Carrots'}], - }, - ], - }, -]; - /** Flat node with expandable and level information */ interface ExampleFlatNode { expandable: boolean; @@ -73,8 +53,28 @@ export class TreeFlatOverviewExample { dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); constructor() { - this.dataSource.data = TREE_DATA; + this.dataSource.data = EXAMPLE_DATA; } hasChild = (_: number, node: ExampleFlatNode) => node.expandable; } + +const EXAMPLE_DATA: FoodNode[] = [ + { + name: 'Fruit', + children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], + }, + { + name: 'Vegetables', + children: [ + { + name: 'Green', + children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}], + }, + { + name: 'Orange', + children: [{name: 'Pumpkins'}, {name: 'Carrots'}], + }, + ], + }, +]; diff --git a/src/components-examples/material/tree/tree-harness/tree-harness-example.ts b/src/components-examples/material/tree/tree-harness/tree-harness-example.ts index 7c6e5fddc9fb..8f3b4b4cd40f 100644 --- a/src/components-examples/material/tree/tree-harness/tree-harness-example.ts +++ b/src/components-examples/material/tree/tree-harness/tree-harness-example.ts @@ -9,22 +9,6 @@ interface Node { children?: Node[]; } -const FLAT_TREE_DATA: Node[] = [ - { - name: 'Flat Group 1', - children: [{name: 'Flat Leaf 1.1'}, {name: 'Flat Leaf 1.2'}, {name: 'Flat Leaf 1.3'}], - }, - { - name: 'Flat Group 2', - children: [ - { - name: 'Flat Group 2.1', - children: [{name: 'Flat Leaf 2.1.1'}, {name: 'Flat Leaf 2.1.2'}, {name: 'Flat Leaf 2.1.3'}], - }, - ], - }, -]; - interface ExampleFlatNode { expandable: boolean; name: string; @@ -64,8 +48,24 @@ export class TreeHarnessExample { dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); constructor() { - this.dataSource.data = FLAT_TREE_DATA; + this.dataSource.data = EXAMPLE_DATA; } hasChild = (_: number, node: ExampleFlatNode) => node.expandable; } + +const EXAMPLE_DATA: Node[] = [ + { + name: 'Flat Group 1', + children: [{name: 'Flat Leaf 1.1'}, {name: 'Flat Leaf 1.2'}, {name: 'Flat Leaf 1.3'}], + }, + { + name: 'Flat Group 2', + children: [ + { + name: 'Flat Group 2.1', + children: [{name: 'Flat Leaf 2.1.1'}, {name: 'Flat Leaf 2.1.2'}, {name: 'Flat Leaf 2.1.3'}], + }, + ], + }, +]; diff --git a/src/components-examples/material/tree/tree-legacy-keyboard-interface/tree-legacy-keyboard-interface-example.ts b/src/components-examples/material/tree/tree-legacy-keyboard-interface/tree-legacy-keyboard-interface-example.ts index 3641d3842cd7..fe0150c1bbc8 100644 --- a/src/components-examples/material/tree/tree-legacy-keyboard-interface/tree-legacy-keyboard-interface-example.ts +++ b/src/components-examples/material/tree/tree-legacy-keyboard-interface/tree-legacy-keyboard-interface-example.ts @@ -6,7 +6,48 @@ import {MatButtonModule} from '@angular/material/button'; import {NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER} from '@angular/cdk/a11y'; import {MatTreeModule} from '@angular/material/tree'; -const TREE_DATA: ExampleFlatNode[] = [ +/** Flat node with expandable and level information */ +interface ExampleFlatNode { + expandable: boolean; + name: string; + level: number; +} + +/** + * @title Tree with flat nodes + */ +@Component({ + selector: 'tree-legacy-keyboard-interface-example', + templateUrl: 'tree-legacy-keyboard-interface-example.html', + styleUrls: ['tree-legacy-keyboard-interface-example.css'], + imports: [MatTreeModule, MatButtonModule, MatIconModule], + providers: [NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TreeLegacyKeyboardInterfaceExample { + treeControl = new FlatTreeControl( + node => node.level, + node => node.expandable, + ); + + dataSource = new ArrayDataSource(EXAMPLE_DATA); + + hasChild = (_: number, node: ExampleFlatNode) => node.expandable; + + getParentNode(node: ExampleFlatNode) { + const nodeIndex = EXAMPLE_DATA.indexOf(node); + + for (let i = nodeIndex - 1; i >= 0; i--) { + if (EXAMPLE_DATA[i].level === node.level - 1) { + return EXAMPLE_DATA[i]; + } + } + + return null; + } +} + +const EXAMPLE_DATA: ExampleFlatNode[] = [ { name: 'Fruit', expandable: true, @@ -63,44 +104,3 @@ const TREE_DATA: ExampleFlatNode[] = [ level: 2, }, ]; - -/** Flat node with expandable and level information */ -interface ExampleFlatNode { - expandable: boolean; - name: string; - level: number; -} - -/** - * @title Tree with flat nodes - */ -@Component({ - selector: 'tree-legacy-keyboard-interface-example', - templateUrl: 'tree-legacy-keyboard-interface-example.html', - styleUrls: ['tree-legacy-keyboard-interface-example.css'], - imports: [MatTreeModule, MatButtonModule, MatIconModule], - providers: [NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class TreeLegacyKeyboardInterfaceExample { - treeControl = new FlatTreeControl( - node => node.level, - node => node.expandable, - ); - - dataSource = new ArrayDataSource(TREE_DATA); - - hasChild = (_: number, node: ExampleFlatNode) => node.expandable; - - getParentNode(node: ExampleFlatNode) { - const nodeIndex = TREE_DATA.indexOf(node); - - for (let i = nodeIndex - 1; i >= 0; i--) { - if (TREE_DATA[i].level === node.level - 1) { - return TREE_DATA[i]; - } - } - - return null; - } -} diff --git a/src/components-examples/material/tree/tree-loadmore/tree-loadmore-example.ts b/src/components-examples/material/tree/tree-loadmore/tree-loadmore-example.ts index 8bbec0820715..da8da8b5b15a 100644 --- a/src/components-examples/material/tree/tree-loadmore/tree-loadmore-example.ts +++ b/src/components-examples/material/tree/tree-loadmore/tree-loadmore-example.ts @@ -13,11 +13,10 @@ import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; import {ENTER, SPACE} from '@angular/cdk/keycodes'; -const LOAD_MORE = 'LOAD_MORE'; let loadMoreId = 1; /** Nested node */ -export class NestedNode { +class NestedNode { childrenChange = new BehaviorSubject([]); get children(): NestedNode[] { @@ -104,7 +103,7 @@ export class LoadmoreDatabase { .map(name => this._generateNode(name, parent.name)); if (newChildrenNumber < children.length) { // Need a new "Load More" node - nodes.push(new NestedNode(`${LOAD_MORE}-${loadMoreId++}`, false, name, true)); + nodes.push(new NestedNode(`LOAD_MORE-${loadMoreId++}`, false, name, true)); } parent.childrenChange.next(nodes); diff --git a/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.ts b/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.ts index 7281ee1a2963..6e3cc2371fa6 100644 --- a/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.ts +++ b/src/components-examples/material/tree/tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example.ts @@ -12,7 +12,25 @@ interface FoodNode { children?: FoodNode[]; } -const TREE_DATA: FoodNode[] = [ +/** + * @title Tree with nested nodes (childrenAccessor) + */ +@Component({ + selector: 'tree-nested-child-accessor-overview-example', + templateUrl: 'tree-nested-child-accessor-overview-example.html', + styleUrl: 'tree-nested-child-accessor-overview-example.css', + imports: [MatTreeModule, MatButtonModule, MatIconModule], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class TreeNestedChildAccessorOverviewExample { + childrenAccessor = (node: FoodNode) => node.children ?? []; + + dataSource = EXAMPLE_DATA; + + hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0; +} + +const EXAMPLE_DATA: FoodNode[] = [ { name: 'Fruit', children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], @@ -31,21 +49,3 @@ const TREE_DATA: FoodNode[] = [ ], }, ]; - -/** - * @title Tree with nested nodes (childrenAccessor) - */ -@Component({ - selector: 'tree-nested-child-accessor-overview-example', - templateUrl: 'tree-nested-child-accessor-overview-example.html', - styleUrl: 'tree-nested-child-accessor-overview-example.css', - imports: [MatTreeModule, MatButtonModule, MatIconModule], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class TreeNestedChildAccessorOverviewExample { - childrenAccessor = (node: FoodNode) => node.children ?? []; - - dataSource = TREE_DATA; - - hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0; -} diff --git a/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.ts b/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.ts index 48f1364142b2..3500b3a3d034 100644 --- a/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.ts +++ b/src/components-examples/material/tree/tree-nested-overview/tree-nested-overview-example.ts @@ -13,26 +13,6 @@ interface FoodNode { children?: FoodNode[]; } -const TREE_DATA: FoodNode[] = [ - { - name: 'Fruit', - children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], - }, - { - name: 'Vegetables', - children: [ - { - name: 'Green', - children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}], - }, - { - name: 'Orange', - children: [{name: 'Pumpkins'}, {name: 'Carrots'}], - }, - ], - }, -]; - /** * @title Tree with nested nodes */ @@ -48,8 +28,28 @@ export class TreeNestedOverviewExample { dataSource = new MatTreeNestedDataSource(); constructor() { - this.dataSource.data = TREE_DATA; + this.dataSource.data = EXAMPLE_DATA; } hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0; } + +const EXAMPLE_DATA: FoodNode[] = [ + { + name: 'Fruit', + children: [{name: 'Apple'}, {name: 'Banana'}, {name: 'Fruit loops'}], + }, + { + name: 'Vegetables', + children: [ + { + name: 'Green', + children: [{name: 'Broccoli'}, {name: 'Brussels sprouts'}], + }, + { + name: 'Orange', + children: [{name: 'Pumpkins'}, {name: 'Carrots'}], + }, + ], + }, +];