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


--------------------------
システム開発のご要望・ご相談はこちらから

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です