😇

react-modal × storybook で遭遇したフォーカス不具合の原因と解決方法

に公開

はじめに

React開発のモーダル実装において react-modal にお世話になる方は多いかと思います. 普段は問題なく使えていたのですが, storybook を導入した際にTabキーでのフォーカス制御が効かないという不具合に遭遇しました.
本記事では実際に遭遇した状況とその原因, そして解決方法について共有します.

事象

react-modalを使ってモーダルコンポーネントを自作し, これをstorybookに追加したところモーダル外ではフォーカス移動ができるのに, モーダルを開いたら突然効かなくなってしまう事象に遭遇しました. モーダル内にはボタンやテキストフィールドなどフォーカスが有効なコンポーネントがあり, tabindexもデフォルトのままの状態でした.
ソースコード@github

正常な状態では以下のようにtabキー押下によってフォーカスするコンポーネントを切り替えることができます.
フォーカス遷移GIF

解決方法

.stories.tsxの以下の実装で, 'centered'以外に設定するかlayout設定自体を消すことで正常に動作するようになりました.

const meta = {
    /* ... */
    parameters: {
        layout: 'centered',  
    },
}

storybook上で中央寄せで対象コンポーネントを表示したい時に使用するパラメータなのですが, どうやらこれが悪さしていたみたいです.

参照: stories.tsxの実装パターン

原因

今回のバグはbodyタグにdisplay: flex; align-items: center;の設定がされていたことが原因のようで, この設定を解消することでも同様にフォーカス移動を復活させることができました.
modal内部のコンポーネントはbodyタグ直下に配置されるため, bodyタグで継承されるstyle設定をしてしまうとその影響がモーダル内部に及び, 結果としてtabフォーカス機能が壊れてしまったのかなと思いました.

まとめ

bodyタグでのレイアウト設定がモーダル内部コンポーネントに影響することで, tabフォーカスが効かなくなるようですね. 当初はstorybookで使われるiframeタグなどが悪影響を与えているのではと思っていたのですが個人的には意外な結果でした. モーダルのフォーカス制御で沼ってしまった方の一助になれば幸いです.

Discussion