Skip to content

Commit

Permalink
docs(material/tree): update examples on docs pages, add new childrenA…
Browse files Browse the repository at this point in the history
…ccessor examples (#29752)

* docs(mat/tree): add childrenAccessor example for mat-tree flat

* fix(mat/tree): fix imports

* docs(mat/tree): add childrenAccessor example for nested mat-tree

* fix(mat/tree): fix imports

* fix(mat/tree): formatting
  • Loading branch information
BobobUnicorn authored Sep 19, 2024
1 parent 777d1d2 commit c4ca044
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/cdk/tree/tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ are rendered as siblings in sequence.

```

<!-- example(cdk-tree-flat) -->
<!-- example(cdk-tree-flat-children-accessor) -->

Flat trees are generally easier to style and inspect. They are also more friendly to scrolling
variations, such as infinite or virtual scrolling.
Expand All @@ -40,7 +40,7 @@ contains a node outlet into which children are projected.
</cdk-tree>
```

<!-- example(cdk-tree-nested) -->
<!-- example(cdk-tree-nested-children-accessor) -->

Nested trees are easier to work with when hierarchical relationships are visually represented in
ways that would be difficult to accomplish with flat nodes.
Expand Down
2 changes: 2 additions & 0 deletions src/components-examples/material/tree/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export {TreeDynamicExample} from './tree-dynamic/tree-dynamic-example';
export {TreeFlatOverviewExample} from './tree-flat-overview/tree-flat-overview-example';
export {TreeFlatChildAccessorOverviewExample} from './tree-flat-child-accessor-overview/tree-flat-child-accessor-overview-example';
export {TreeHarnessExample} from './tree-harness/tree-harness-example';
export {TreeLoadmoreExample} from './tree-loadmore/tree-loadmore-example';
export {TreeNestedOverviewExample} from './tree-nested-overview/tree-nested-overview-example';
export {TreeNestedChildAccessorOverviewExample} from './tree-nested-child-accessor-overview/tree-nested-child-accessor-overview-example';
export {TreeLegacyKeyboardInterfaceExample} from './tree-legacy-keyboard-interface/tree-legacy-keyboard-interface-example';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<mat-tree #tree [dataSource]="dataSource" [childrenAccessor]="childrenAccessor">
<!-- This is the tree node template for leaf nodes -->
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
<!-- use a disabled button to provide padding for tree leaf -->
<button mat-icon-button disabled></button>
{{node.name}}
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding matTreeNodeToggle
[cdkTreeNodeTypeaheadLabel]="node.name">
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'Toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
{{tree.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
{{node.name}}
</mat-tree-node>
</mat-tree>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {MatTreeModule} from '@angular/material/tree';
import {MatIconModule} from '@angular/material/icon';
import {MatButtonModule} from '@angular/material/button';

/**
* Food data with nested structure.
* Each node has a name and an optional list of children.
*/
interface FoodNode {
name: string;
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 flat nodes (childrenAccessor)
*/
@Component({
selector: 'tree-flat-child-accessor-overview-example',
templateUrl: 'tree-flat-child-accessor-overview-example.html',
standalone: true,
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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.example-tree-invisible {
display: none;
}

.example-tree ul,
.example-tree li {
margin-top: 0;
margin-bottom: 0;
list-style-type: none;
}

/*
* This padding sets alignment of the nested nodes.
*/
.example-tree .mat-nested-tree-node div[role=group] {
padding-left: 40px;
}

/*
* Padding for leaf nodes.
* Leaf nodes need to have padding so as to align with other non-leaf nodes
* under the same parent.
*/
.example-tree div[role=group] > .mat-tree-node {
padding-left: 40px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<mat-tree #tree [dataSource]="dataSource" [childrenAccessor]="childrenAccessor" class="example-tree">
<!-- This is the tree node template for leaf nodes -->
<!-- There is inline padding applied to this node using styles.
This padding value depends on the mat-icon-button width. -->
<mat-tree-node *matTreeNodeDef="let node">
{{node.name}}
</mat-tree-node>
<!-- This is the tree node template for expandable nodes -->
<mat-nested-tree-node
*matTreeNodeDef="let node; when: hasChild"
matTreeNodeToggle [cdkTreeNodeTypeaheadLabel]="node.name">
<div class="mat-tree-node">
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'Toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
{{tree.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
</button>
{{node.name}}
</div>
<!-- There is inline padding applied to this div using styles.
This padding value depends on the mat-icon-button width. -->
<div [class.example-tree-invisible]="!tree.isExpanded(node)"
role="group">
<ng-container matTreeNodeOutlet></ng-container>
</div>
</mat-nested-tree-node>
</mat-tree>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {MatTreeModule} from '@angular/material/tree';
import {MatIconModule} from '@angular/material/icon';
import {MatButtonModule} from '@angular/material/button';

/**
* Food data with nested structure.
* Each node has a name and an optional list of children.
*/
interface FoodNode {
name: string;
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 (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',
standalone: true,
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;
}
8 changes: 8 additions & 0 deletions src/dev-app/tree/tree-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
<mat-expansion-panel-header>Flat tree</mat-expansion-panel-header>
<tree-flat-overview-example></tree-flat-overview-example>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>Flat tree (childrenAccessor)</mat-expansion-panel-header>
<tree-flat-child-accessor-overview-example></tree-flat-child-accessor-overview-example>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>CDK Flat tree</mat-expansion-panel-header>
<cdk-tree-flat-example></cdk-tree-flat-example>
Expand All @@ -19,6 +23,10 @@
<mat-expansion-panel-header>Nested tree</mat-expansion-panel-header>
<tree-nested-overview-example></tree-nested-overview-example>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>Nested tree (childrenAccessor)</mat-expansion-panel-header>
<tree-nested-child-accessor-overview-example></tree-nested-child-accessor-overview-example>
</mat-expansion-panel>
<mat-expansion-panel>
<mat-expansion-panel-header>CDK Nested tree</mat-expansion-panel-header>
<cdk-tree-nested-example></cdk-tree-nested-example>
Expand Down
4 changes: 4 additions & 0 deletions src/dev-app/tree/tree-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
TreeLegacyKeyboardInterfaceExample,
TreeLoadmoreExample,
TreeNestedOverviewExample,
TreeNestedChildAccessorOverviewExample,
TreeFlatChildAccessorOverviewExample,
} from '@angular/components-examples/material/tree';
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {FormsModule} from '@angular/forms';
Expand Down Expand Up @@ -53,9 +55,11 @@ import {MatTreeModule} from '@angular/material/tree';
CommonModule,
FormsModule,
TreeDynamicExample,
TreeFlatChildAccessorOverviewExample,
TreeFlatOverviewExample,
TreeLegacyKeyboardInterfaceExample,
TreeLoadmoreExample,
TreeNestedChildAccessorOverviewExample,
TreeNestedOverviewExample,
MatButtonModule,
MatExpansionModule,
Expand Down
4 changes: 2 additions & 2 deletions src/material/tree/tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ but instead are rendered as siblings in sequence.
</mat-tree>
```

<!-- example(tree-flat-overview) -->
<!-- example(tree-flat-child-accessor-overview) -->

Flat trees are generally easier to style and inspect. They are also more friendly to scrolling
variations, such as infinite or virtual scrolling.
Expand All @@ -41,7 +41,7 @@ contains a node outlet into which children are projected.
</mat-tree>
```

<!-- example(tree-nested-overview) -->
<!-- example(tree-nested-child-accessor-overview) -->

Nested trees are easier to work with when hierarchical relationships are visually represented in
ways that would be difficult to accomplish with flat nodes.
Expand Down

0 comments on commit c4ca044

Please sign in to comment.