Initial commit

This commit is contained in:
Michael Pivato
2024-06-05 21:38:06 +09:30
commit 922d74e007
44 changed files with 4433 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
import { DataSource } from "@angular/cdk/collections";
import { FlatTreeControl } from "@angular/cdk/tree";
import { CommonModule } from "@angular/common";
import {
ChangeDetectionStrategy,
Component,
Signal,
computed,
input,
output,
} from "@angular/core";
import {
MatTreeFlatDataSource,
MatTreeFlattener,
MatTreeModule,
} from "@angular/material/tree";
import { MatIconModule } from "@angular/material/icon";
export interface FileOrFolder {
isDirectory: boolean;
name: string;
children?: FileOrFolder[];
}
interface FileNode {
file: FileOrFolder;
expandable: boolean;
level: number;
}
@Component({
selector: "app-file-tree",
standalone: true,
imports: [CommonModule, MatTreeModule, MatIconModule],
template: `<mat-tree [dataSource]="dataSource()" [treeControl]="treeControl">
<mat-tree-node
*matTreeNodeDef="let node"
matTreeNodePadding
(click)="fileSelected.emit(node.file)"
>
<button mat-icon-button disabled></button>
{{ node.file.name }}
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node; when: hasChild">
<button
mat-icon-button
matTreeNodePadding
[attr.aria-label]="'Toggle ' + node.file.name"
>
<mat-icon class="mat-icon-rtl-mirror">
@if (treeControl.isExpanded(node)) { expand_more } @else {
chevron_right }
</mat-icon>
</button>
{{ node.name }}
</mat-tree-node>
</mat-tree>`,
styleUrl: "./file-tree.component.css",
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class FileTreeComponent {
files = input<FileOrFolder[]>([]);
fileSelected = output<FileOrFolder>();
protected hasChild = (_: number, node: FileNode) => node.expandable;
private _transformer = (node: FileOrFolder, level: number) => ({
expandable: !!node.children && node.children.length > 0,
file: node,
level: level,
});
protected treeControl = new FlatTreeControl<FileNode>(
(node) => node.level,
(node) => node.expandable
);
private treeFlattener = new MatTreeFlattener(
this._transformer,
(node) => node.level,
(node) => node.expandable,
(node) => node.children
);
// Use computed signals to create datasource
protected dataSource = computed(() => {
const dataSource = new MatTreeFlatDataSource(
this.treeControl,
this.treeFlattener
);
dataSource.data = this.files();
return dataSource;
});
}