詳細ガイド
Angular Aria

メニュー

概要

メニューは、ユーザーにアクションやオプションのリストを提供し、通常はボタンのクリックや右クリックに応じて表示されます。メニューは、矢印キーによるキーボードナビゲーション、サブメニュー、チェックボックス、ラジオボタン、無効化されたアイテムをサポートしています。

使い方

メニューは、ユーザーが選択できるアクションやコマンドのリストを提示するのに適しています。

メニューを使用する場合:

  • アプリケーションのコマンドメニュー(File、Edit、View)を構築する場合
  • コンテキストメニュー(右クリックアクション)を作成する場合
  • ドロップダウンのアクションリストを表示する場合
  • ツールバーのドロップダウンを実装する場合
  • 設定やオプションを整理する場合

メニューを避けるべき場合:

  • サイトナビゲーションを構築する場合(代わりにナビゲーションランドマークを使用してください)
  • フォームのセレクトを作成する場合(Selectコンポーネントを使用してください)
  • コンテンツパネルを切り替える場合(Tabsを使用してください)
  • 折りたたみ可能なコンテンツを表示する場合(Accordionを使用してください)

機能

  • キーボードナビゲーション - 矢印キー、Home/End、文字検索による効率的なナビゲーション
  • サブメニュー - 自動配置の機能を備えたネストされたメニューのサポート
  • メニュータイプ - スタンドアロンメニュー、トリガーメニュー、メニューバー
  • チェックボックスとラジオボタン - トグルおよび選択メニューアイテム
  • 無効化されたアイテム - フォーカス管理を備えたソフトまたはハードな無効状態
  • 自動クローズ動作 - 選択時に閉じる設定が可能
  • RTLサポート - 右から左へ記述する言語のナビゲーション

トリガーボタンとメニューを組み合わせることで、ドロップダウンメニューを作成します。トリガーはメニューを開閉します。

ユーザーがアイテムを選択するかEscapeキーを押すと、メニューは自動的に閉じます。

コンテキストメニュー

コンテキストメニューは、ユーザーが要素を右クリックしたときにカーソル位置に表示されます。

contextmenuイベントの座標を使用してメニューを配置します。

スタンドアロンメニュー

スタンドアロンメニューはトリガーを必要とせず、インターフェース上で常に表示されたままになります。

スタンドアロンメニューは、常に表示されるアクションリストやナビゲーションに適しています。

無効化されたメニューアイテム

disabled入力を使用して特定のメニューアイテムを無効にします。softDisabledでフォーカスの動作を制御します。

[softDisabled]="true"の場合、無効化されたアイテムはフォーカスを受け取ることができますが、アクティブにできません。[softDisabled]="false"の場合、無効化されたアイテムはキーボードナビゲーション中にスキップされます。

Testing

Angular Aria provides component harnesses for testing menu components. Here is an example of how to use the harnesses in a component test:

import {ComponentFixture, TestBed} from '@angular/core/testing';
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {MenuHarness, MenuItemHarness} from '@angular/aria/menu/testing';
import {MyMenuComponent} from './my-menu'; // Your component

describe('MyMenuComponent', () => {
  let fixture: ComponentFixture<MyMenuComponent>;
  let loader: HarnessLoader;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [MyMenuComponent],
    });

    fixture = TestBed.createComponent(MyMenuComponent);
    await fixture.whenStable();
    loader = TestbedHarnessEnvironment.loader(fixture);
  });

  it('should open menu and click item', async () => {
    // Load the menu harness by its trigger text
    const menu = await loader.getHarness(MenuHarness.with({triggerText: 'Open Menu'}));

    // Verify initial state
    expect(await menu.isOpen()).toBe(false);

    // Open the menu
    await menu.open();
    expect(await menu.isOpen()).toBe(true);

    // Get items
    const items = await menu.getItems();
    expect(items.length).toBe(3);
    expect(await items[0].getText()).toBe('Item 1');

    // Click first item
    await items[0].click();

    // Menu should close after selection (depending on your implementation)
    expect(await menu.isOpen()).toBe(false);
  });

  it('should interact with submenus', async () => {
    const menu = await loader.getHarness(MenuHarness.with({triggerText: 'Open Menu'}));
    await menu.open();

    // Get the item that triggers a submenu
    const subItem = await loader.getHarness(MenuItemHarness.with({text: 'Submenu'}));
    expect(await subItem.hasSubmenu()).toBe(true);

    // Open submenu
    await subItem.click();
    const submenu = await subItem.getSubmenu();
    expect(submenu).toBeTruthy();
    expect(await submenu!.isOpen()).toBe(true);

    // Interact with submenu items
    const subItems = await submenu!.getItems();
    expect(subItems.length).toBe(1);
  });
});

API reference

詳細なAPIドキュメントについては、以下のAPIリファレンスを参照してください。