Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

@fluentui/web-components: fluent-menu-list loses its arrow keys after it is moved in the DOM (Firefox, Safari)

オープン 初心者向け
#36,869 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@asxxb がすでに取り組んでいます。

2026年10月12日 から。

  • #36871 @asxxb による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
84/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
typescript, web-dev

調査の方向性

issue では menu-list.js の動作が示されています。disconnectedCallback() はフォーカスグループを切断し、setItems() は再接続後にそれを再利用します。これらのメソッドと、issue に記載されたフォーカスグループのライフサイクルを読み、その後 Firefox または Safari で DOM の移動を再現してください。移動後も、移動しなかった場合と同じように ArrowDown でメニュー項目間をフォーカスが移動すれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Version: @fluentui/web-components 3.1.3, @microsoft/focusgroup-polyfill 1.6.0. Engines: Firefox 153 and WebKit 26.6 (Playwright's builds) fail; Chromium 153 passes, because it has native focusgroup and the polyfill stands aside.

Summary

A fluent-menu-list builds its focus group (the polyfill that gives the arrow keys in an engine without native focusgroup) on its first setItems(), disconnects it when the list leaves the document, and never builds another. Any DOM move, which disconnects and reconnects the element (for example insertBefore, or a framework reordering a list), leaves a menu whose arrow keys do nothing: focus stays on the first item, so Enter chooses the first item whatever the user wanted.

Reproduction
<!doctype html>
<div id="host">
  <fluent-menu>
    <fluent-button slot="trigger">Actions</fluent-button>
    <fluent-menu-list>
      <fluent-menu-item>One</fluent-menu-item>
      <fluent-menu-item>Two</fluent-menu-item>
      <fluent-menu-item>Three</fluent-menu-item>
    </fluent-menu-list>
  </fluent-menu>
</div>
<script type="module">
  import '@fluentui/web-components/button.js';
  import '@fluentui/web-components/menu.js';
  import '@fluentui/web-components/menu-list.js';
  import '@fluentui/web-components/menu-item.js';
  // Move the menu in place once, as a framework's reorder would.
  const menu = document.querySelector('fluent-menu');
  customElements.whenDefined('fluent-menu-list').then(() => menu.parentElement.insertBefore(menu, menu.nextSibling));
</script>
  1. Open the page in Firefox or Safari. Tab to "Actions" and press Enter: the menu opens with focus on "One".
  2. Press ArrowDown twice.
  3. Expected: focus on "Three" (as without the move, and as in Chrome). Actual: focus stays on "One".

The standalone page above reproduces it as written (bundled with esbuild, served to each engine): never moved, "One", "Two", "Three" in all three engines; moved in place once, "One", "Two", "Three" in Chromium and "One", "One", "One" in Firefox and WebKit.

Cause
  • node_modules/@fluentui/web-components/dist/esm/menu-list/menu-list.js:15-18: disconnectedCallback() calls this.fg?.disconnect(), and keeps this.fg.
  • menu-list.js:19-34: setItems() creates the FocusGroup only if (!this.fg); otherwise it calls this.fg.update().
  • node_modules/@microsoft/focusgroup-polyfill/build/focusgroup-shadowless.mjs:101-114: the constructor adds the keydown, focusin and focusout listeners, once; :127-132: disconnect() aborts them and sets the owner to null; update() returns at once when there is no owner (:146).

So after a reconnection setItems() "updates" a disconnected group, which does nothing.

Suggested fix

Drop the group when disconnecting (this.fg?.disconnect(); this.fg = undefined;), so the next setItems() builds a new one; or build the group in connectedCallback.

主要言語
TypeScript
スター
20.3k
フォーク
2.9k
平均マージ
2日 9時間
マージ済み PR(30日)
70

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

  • Dockerfile・Docker Compose ファイルなし
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/fluentui のほかの issue

microsoft/fluentui の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。