
Angular Materialのツリービューをキー操作できるようにカスタマイズする
はじめに
Angular Materialで用意されているツリービューは、デフォルトでキー操作ができないため、自分でカスタマイズする必要があります。今回は矢印キーでツリービューを操作するための一例をご紹介したいと思います。
環境
- Angular CLI 8.2.2
- Angular 8.2.14
- Angular Material 8.2.3
前提
- Angular CLIでプロジェクトを作成済み
- Angular Materialをプロジェクトに導入済み
ツリービューのひな型を作成する
プロジェクトフォルダに移動して、下記のコマンドを実行します。
今回はtreeViewというコンポーネント名でひな型を作成します。
ng g @angular/material:tree treeView
コマンドを実行するとsrc/appフォルダ配下に下記のファイルが生成されます。
src/app
└─tree-view
└─example-data.ts
└─tree-view.component.css
└─tree-view.component.html
└─tree-view.component.spec.ts
└─tree-view.component.ts
ツリービューを矢印キーで操作できるようにカスタマイズする
src/app/tree-view/tree-view-component.tsを開き、TreeViewComponentクラスに下記のメソッドを全て追加します。
/**
* keydownイベントハンドラ
* @param event キーボードイベント
* @param node 操作対象のツリー要素
*/
handleKeydown(event: KeyboardEvent, node: FlatTreeNode) {
const target = event.target as HTMLElement;
switch (event.key) {
case 'ArrowUp':
this.focusPreviousTreeNode(target);
break;
case 'ArrowDown':
this.focusNextTreeNode(target);
break;
case 'ArrowRight':
this.treeControl.isExpanded(node) ? this.focusNextTreeNode(target) : this.treeControl.expand(node);
break;
case 'ArrowLeft':
this.treeControl.isExpanded(node) ? this.treeControl.collapse(node) : this.focusPreviousTreeNode(target);
break;
}
}
/**
* 前の要素へフォーカス
* @param target mat-tree-nodeタグのHTMLElement
*/
focusPreviousTreeNode(target: HTMLElement) {
const previousSibling = target.previousSibling as HTMLElement;
// 最初の要素に到達したため、何もしない
if (previousSibling.nodeName !== 'MAT-TREE-NODE') {
return;
}
previousSibling.focus();
}
/**
* 次の要素へフォーカス
* @param target mat-tree-nodeタグのHTMLElement
*/
focusNextTreeNode(target: HTMLElement) {
const nextSibling = target.nextSibling as HTMLElement;
// 最後の要素に到達したため、何もしない
if (nextSibling === null) {
return;
}
nextSibling.focus();
}
src/app/tree-view/tree-view-component.htmlを開き、下記の通り修正します。
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodeToggle matTreeNodePadding tabindex="0"
(keydown)="handleKeydown($event, node)">
<mat-icon class="type-icon" [attr.aria-label]="node.type + 'icon'">
{{ node.type === 'file' ? 'description' : 'folder' }}
</mat-icon>
{{node.name}}
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding tabindex="0"
(keydown)="handleKeydown($event, node)">
<mat-icon matTreeNodeToggle class="mat-icon-rtl-mirror" style="cursor: pointer;">
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
</mat-icon>
<mat-icon class="type-icon" [attr.aria-label]="node.type + 'icon'">
{{ node.type === 'file' ? 'description' : 'folder' }}
</mat-icon>
{{node.name}}
</mat-tree-node>
</mat-tree>
src/app/app.component.htmlを開き、下記の通り修正します。
<app-tree-view></app-tree-view>
動作確認
最後に下記のコマンドを実行して、動作確認をします。
# ビルドとサーバの起動、ブラウザの表示を自動で行う ng s -o
ツリーにフォーカスを当てると矢印キーで操作できることが確認できます。

以上がAngular Materialのツリービューを矢印キーで操作する方法でした。