APG Patterns
English
English

Breadcrumb

現在のページから親ページへの階層的なリンクのリスト。

デモ

基本的なパンくずリスト

現在のページへのパスを示すシンプルなパンくずリスト。

長いパス

複数階層の深いナビゲーションパス。

デモのみ表示 →

アクセシビリティ

WAI-ARIA ロール

ロール 対象要素 説明
navigation <nav> 要素 支援技術にナビゲーションランドマークを提供します(

WAI-ARIA Breadcrumb Pattern (opens in new tab)

WAI-ARIA プロパティ

属性 対象 必須 説明
aria-label <nav> "Breadcrumb"(またはローカライズされた値) はい スクリーンリーダー向けにナビゲーションランドマークにラベルを付けます
aria-current 現在のページ要素 "page" はい(最後のアイテム) パンくずリスト内の現在のページを識別します

WAI-ARIA ステート

aria-current=""page""

パンくずリストナビゲーション内の現在のページ位置を示します。

対象 パンくずリストの最後のアイテム(現在のページ)
"page"
必須 はい
リファレンス aria-current (opens in new tab)

キーボードサポート

キー アクション
Tab パンくずリストのリンク間でフォーカスを移動します
Enter フォーカスされたリンクをアクティブ化します

Breadcrumbはネイティブの要素の動作をキーボードインタラクションに使用します。追加のキーボードハンドラーは不要です。

ソースコード

Breadcrumb.tsx
import { cn } from '@/lib/utils';

/**
 * Represents a single item in the breadcrumb trail
 */
export interface BreadcrumbItem {
  /**
   * Display text for the breadcrumb item
   */
  label: string;
  /**
   * URL for the breadcrumb link. If omitted, renders as non-interactive text.
   */
  href?: string;
}

/**
 * Props for the Breadcrumb component
 *
 * @see https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/
 *
 * @example
 * ```tsx
 * <Breadcrumb
 *   items={[
 *     { label: 'Home', href: '/' },
 *     { label: 'Products', href: '/products' },
 *     { label: 'Current Page' }
 *   ]}
 * />
 * ```
 */
export interface BreadcrumbProps {
  /**
   * Array of breadcrumb items representing the navigation path
   */
  items: BreadcrumbItem[];
  /**
   * Accessible label for the navigation landmark
   * @default "Breadcrumb"
   */
  ariaLabel?: string;
  /**
   * Additional CSS class to apply to the nav element
   */
  className?: string;
}

export function Breadcrumb({
  items,
  ariaLabel = 'Breadcrumb',
  className,
}: BreadcrumbProps): React.ReactElement | null {
  if (items.length === 0) {
    return null;
  }

  return (
    <nav aria-label={ariaLabel} className={cn('apg-breadcrumb', className)}>
      <ol className="apg-breadcrumb-list">
        {items.map((item, index) => {
          const isLast = index === items.length - 1;
          const key = `${item.href ?? 'current'}-${item.label}`;

          return (
            <li key={key} className="apg-breadcrumb-item">
              {item.href && !isLast ? (
                <a href={item.href} className="apg-breadcrumb-link">
                  {item.label}
                </a>
              ) : (
                <span aria-current={isLast ? 'page' : undefined} className="apg-breadcrumb-current">
                  {item.label}
                </span>
              )}
            </li>
          );
        })}
      </ol>
    </nav>
  );
}

export default Breadcrumb;

使い方

Example
import { Breadcrumb } from './Breadcrumb';

function App() {
  return (
    <Breadcrumb
      items={[
        { label: 'Home', href: '/' },
        { label: 'Products', href: '/products' },
        { label: 'Current Product' }
      ]}
    />
  );
}

API

BreadcrumbProps

プロパティ デフォルト 説明
items BreadcrumbItem[] 必須 パンくずリストアイテムの配列
ariaLabel string "Breadcrumb" ナビゲーションのアクセシブルラベル
className string - 追加のCSSクラス

BreadcrumbItem

プロパティ 必須 説明
label string はい アイテムの表示テキスト
href string いいえ リンクのURL(現在のページの場合は省略)

テスト

テストはARIA属性、セマンティック構造、アクセシビリティ要件全体にわたってAPG準拠を検証します。Breadcrumbコンポーネントは2層のテスト戦略を採用しています。

テスト戦略

ユニットテスト(Testing Library)

フレームワーク固有のテストライブラリを使用してコンポーネントのレンダリング出力を検証します。これらのテストは正しいHTML構造とARIA属性を確認します。

  • HTML構造(nav、ol、li要素)
  • ARIA属性(aria-label、aria-current)
  • リンクのレンダリングとhref値
  • jest-axeによるアクセシビリティ検証

E2Eテスト(Playwright)

すべてのフレームワークで実際のブラウザ環境でコンポーネントの動作を検証します。これらのテストはインタラクションとフレームワーク間の一貫性をカバーします。

  • キーボードナビゲーション(Tab、Enter)
  • ライブブラウザでのARIA構造
  • axe-coreによるアクセシビリティスキャン
  • フレームワーク間の一貫性チェック

テストカテゴリ

高優先度: APG ARIA属性(Unit + E2E)

テスト説明
nav elementセマンティックな
aria-labelナビゲーションにアクセシブルなラベルがあります(デフォルト: "Breadcrumb")
aria-current="page"最後のアイテムにaria-current="page"があります
ol/li structure適切なセマンティック構造のために順序付きリストを使用します

高優先度: キーボードインタラクション(E2E)

テスト説明
Tab navigationTabキーでパンくずリストのリンク間をフォーカス移動します
Enter activationEnterキーでフォーカスされたリンクをアクティブ化します
Current page not focusable最後のアイテム(span)はタブ順序に含まれません

中優先度: アクセシビリティ(Unit + E2E)

テスト説明
axe violationsWCAG 2.1 AAの違反がありません(jest-axe使用)
Custom aria-labelariaLabel propsでデフォルトラベルをオーバーライドできます
Separator hidden視覚的な区切り文字は支援技術から隠されています

低優先度: コンポーネントの動作(Unit)

テスト説明
Renders all items提供されたすべてのアイテムが順番にレンダリングされます
Links have href現在でないアイテムは正しいhrefを持つリンクとしてレンダリングされます
className mergeカスタムクラスがコンポーネントクラスとマージされます

低優先度: フレームワーク間の一貫性(E2E)

テスト説明
All frameworks have navReact、Vue、Svelte、Astroすべてがパンくずナビゲーションをレンダリング
Same item countすべてのフレームワークで同じ数のパンくずアイテムをレンダリング
Current page markedすべてのフレームワークで最後のアイテムにaria-current="page"をマーク

テストツール

完全なドキュメントについては testing-strategy.md (opens in new tab) を参照してください。

リソース