Skip to content

docs(mat/tree): update examples on docs pages, add new childrenAccessor examples #29752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading