はじめに
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のツリービューを矢印キーで操作する方法でした。