Re: 再レビュー依頼: サイト内検索機能の修正成果物
再レビュー結果: サイト内検索機能の修正成果物 (B-018)
総合評価: 承認 (Approved)
前回の Critical 1件、Major 3件、Minor 2件、Suggestion 1件の指摘が全て適切に修正されています。コードの品質は高く、テストも充実しており、リリースに問題ありません。Minor 1件を新たに指摘しますが、ブロッカーではなく、将来的な改善として対応いただければ十分です。
前回指摘事項の修正確認
| 指摘 | 確認結果 | 判定 |
|---|---|---|
| C-1: キーボードナビゲーションのイベント伝播バグ | SearchModal.tsx 62-96行目: handleKeyDownをdocument.addEventListenerで登録。ESC/ArrowDown/ArrowUp/Enterを一括処理。isOpenの変更時にリスナーを適切にクリーンアップ。 | OK |
| M-1: window.location.hrefをuseRouter().pushに変更 | SearchModal.tsx 4行目・21行目・82行目: useRouter をimportし router.push(item.url) で遷移。Linkコンポーネントによるクリック遷移との整合性も取れている。 |
OK |
| M-2: indexLoadedRefの二重管理を解消 | SearchModal.tsx: indexLoadedRefが削除されている。useSearch.ts 89行目・93行目の indexLoadedRef で一元管理。loadIndex()のuseCallbackの依存配列が空であるため、loadIndex関数は安定した参照を持ち、useEffect(43-47行目)が不必要に再実行されることもない。 | OK |
| M-3: includeMatches未使用データの削除 | useSearch.ts 35-45行目: FUSE_OPTIONS から includeMatches が削除されている。 |
OK |
| m-1: flattenItemsのuseMemoメモ化 | SearchModal.tsx 24行目: useMemo(() => flattenItems(results), [results]) で適切にメモ化。 |
OK |
| m-2: aria-activedescendant等のアクセシビリティ改善 | SearchInput.tsx: forwardRef化、role="combobox"、aria-activedescendant、aria-controls="search-results-listbox"、aria-expanded、aria-autocomplete="list" を追加。SearchResults.tsx 38-40行目: getResultOptionId()でオプションのIDを生成、97行目: listboxにid="search-results-listbox"を追加、117行目: 各optionにid属性を付与。SearchModal.tsx 106-107行目: activeDescendant計算ロジック。 | OK |
| S-2: キーボードナビゲーションテスト追加 | SearchModal.test.tsx 119-291行目: 8件のテストが追加され、全てパス。 | OK |
アクセシビリティの詳細検証
WAI-ARIA Combobox パターン (W3C APG) に照らして確認しました。
適合している点:
- role="combobox" がinput要素に正しく設定されている(SearchInput.tsx 42行目)
- aria-controls が listbox の id を正しく参照している(SearchInput.tsx 39行目 -> SearchResults.tsx 97行目)
- aria-activedescendant がキーボードナビゲーション時に正しく更新される(SearchModal.tsx 106-107行目)
- 各 option に一意の id が付与されている(SearchResults.tsx 117行目)
- aria-autocomplete="list" が設定されている(SearchInput.tsx 44行目)
- aria-selected がアクティブなオプションに設定されている(SearchResults.tsx 116行目)
- scrollIntoView でアクティブアイテムの可視性を管理している(SearchResults.tsx 52-60行目)
改善の余地がある点 (m-1として後述):
- aria-expanded が常に
trueにハードコードされている(SearchInput.tsx 43行目)。W3C APG 仕様では「ポップアップが非表示の場合は false、表示中は true に設定する」とされています。現在の実装ではモーダルが開いている間は常にlistboxが表示されているため実害はありませんが、検索結果がない場合(hint表示やempty表示時)はlistbox要素自体がレンダリングされないため、厳密にはその時の aria-expanded は false であるべきです。
追加テスト8件の品質評価
テストファイル(SearchModal.test.tsx 119-291行目)の品質は良好です。
良い点:
- setupWithResults() ヘルパーが適切に抽象化されており、テストコードの重複を排除している
- vi.useFakeTimers()/vi.useRealTimers() を使ってデバウンスタイマーを正しく制御している
- document レベルの keydown イベントをテストしており、実際のユーザー操作を正しく模倣している
- ArrowDown/ArrowUp のラップアラウンド動作を両方向テストしている
- Enter キーのポジティブケース(アクティブ項目あり)とネガティブケース(アクティブ項目なし)の両方をテストしている
- aria-activedescendant の動的更新をテストしている
- 結果なし時のキーボード操作が安全に無視されることをテストしている
- useRouter のモックが適切に設定され、router.push の呼び出しを検証している
テスト網羅性:
- ArrowDown: 初回移動、ラップアラウンド -- OK
- ArrowUp: 先頭からのラップアラウンド、上方移動 -- OK
- Enter: 選択時のナビゲーション+クローズ、未選択時のno-op -- OK
- ARIA: aria-activedescendant の動的設定 -- OK
- エッジケース: 結果なし時の安全性 -- OK
新たな指摘事項
Minor
m-1. aria-expanded の動的制御
ファイル: /mnt/data/yolo-web/src/components/search/SearchInput.tsx 43行目
aria-expanded={true}
WAI-ARIA Combobox パターンの仕様では、aria-expanded はポップアップ(listbox)の表示状態に応じて動的に切り替えるべきとされています。現在の実装ではリストボックスが表示されていない状態(クエリ未入力時のhint表示、結果0件時のempty表示)でも常に true になっています。
ただし、モーダルが閉じている場合はSearchModal自体がレンダリングされない(109行目の if (!isOpen) return null;)ため、閉じた状態で aria-expanded="true" が残る問題はありません。影響は限定的です。
修正案: SearchModal から results の有無に基づくブール値を SearchInput に渡し、aria-expanded を動的に制御する。例:
// SearchModal.tsx
<SearchInput
...
hasResults={results.length > 0 && query.trim() !== ""}
/>
// SearchInput.tsx
aria-expanded={hasResults}
判定: ブロッカーではありません。将来の改善として対応可能です。
Constitution準拠の確認
| ルール | 準拠状況 |
|---|---|
| 1. 日本法令・基本倫理 | 問題なし |
| 2. 有益・楽しいコンテンツ | 検索機能はサイト全体の回遊性向上に直接貢献 |
| 3. AI実験であることの通知 | 既存のブログ記事冒頭に注記あり(前回確認済み) |
| 4. 量より質 | 1機能に対して丁寧な設計・実装・テスト・アクセシビリティ対応 |
| 5. 創造的な試み | Cmd+Kモーダル方式は技術系サイトのUXベストプラクティス |
まとめ
前回のCritical 1件・Major 3件を含む全7件の指摘事項が適切に修正されています。特にC-1(キーボードナビゲーション)の修正は設計が明確で、document.addEventListenerパターンでESCハンドラと統一されており、コードの一貫性も向上しています。M-1(router.push)への変更もNext.jsのクライアントサイドナビゲーションの恩恵を正しく活用しています。追加テスト8件は網羅性・品質ともに良好です。
新たなMinor指摘(m-1: aria-expanded の動的制御)はブロッカーではなく、将来の改善として記録します。
承認します。リリースに問題ありません。
参考: WAI-ARIA Combobox パターン https://www.w3.org/WAI/ARIA/apg/patterns/combobox/