【React】ダイアログライブラリの調査
Reactの既存サービスにダイアログのUIライブラリを入れる可能性があったので調査。
既存サービスなので、スタイルが含まれていない「headless UIライブラリ」を中心に見ていく。[1]
WAI-ARIAのDialog (Modal) PatternとAlert and Message Dialogs Patternを理解している前提で記事を書く。
Tailwind CSS - HeadlessUI
-
https://github.com/tailwindlabs/headlessui
- 最終更新13時間前(執筆時点)
- 24.3k stars(執筆時点)
- Tailwind CSSが作っている。
- https://tailwindcss.com/blog/hiring-a-design-engineer-and-staff-engineer
- 6人のチーム。
- Tailwind CSSのチームということで、メンテナンスは問題なさそうに思える。
ダイアログに当たるコンポーネントは1つ。
問題点
ダイアログを複数開く場合、ダイアログをネストする必要がある。(ref: https://github.com/tailwindlabs/headlessui/issues/2876#issuecomment-1849866552 )
正常系のUIでダイアログが重なることが想定されている場合ならネストして組めるが、例えば複数APIのエラー表示を行いたい場合などに困る。
ちなみにネストせずにダイアログを表示すると、ダイアログは表示されるが閉じることができなかった。
Radix UI - Radix Primitive
-
https://github.com/radix-ui/primitives
- 最終更新2ヶ月前(執筆時点)
- 14.3k stars(執筆時点)
- WorkOSによるプロジェクト。
- https://workos.com/about
- 「5大陸に50名を超える従業員を抱えるリモートファーストのグローバル企業」とのことで、メンテナンスは問題なさそうに思える。
- shadcn/uiが利用しているheadless UI(ref: https://manupa.dev/blog/anatomy-of-shadcn-ui )。
- WAI-ARIA対応。
WAI-ARIAと同様に、ダイアログに当たるコンポーネントが2つある。
- Dialog https://www.radix-ui.com/primitives/docs/components/dialog
- AlertDialog https://www.radix-ui.com/primitives/docs/components/alert-dialog
問題点
ダイアログを表示するとbodyにmarginとpaddingが指定されてしまう。下記は例。
body {
overflow: hidden !important;
position: relative !important;
padding-left: 0px;
padding-top: 0px;
padding-right: 0px;
margin-left: 0;
margin-top: 0;
margin-right: 0px !important;
}
これはライブラリが依存しているreact-remove-scroll-barに因るもので、issueでも言及されている記事に拠ると、読み違えていなければWindowsのブラウザのスクロールを止めるために必要なものらしい。
- radix-ui/primitivesのissue: https://github.com/radix-ui/primitives/issues/1548
- theKashey/react-remove-scroll-barのissue:
bodyにmarginとpaddingが指定されていなければ問題ないが、弊サービスには合致しなかった。
Chakra UI - Ark UI
-
https://github.com/chakra-ui/ark
- 最終更新32分前(執筆時点)
- 3k stars(執筆時点)
- Chakra UIが作っている。
- 「Proudly made in Nigeria by Segun Adebayo」
-
https://github.com/chakra-ui
- メンバーは3人?
-
https://v2.chakra-ui.com/
- スポンサーも多いので、メンテナンスは問題なさそうに思える。
- 同じくChakra UIが作っているzagに依存している。
- アクセシビリティ対応
ダイアログに当たるコンポーネントは1つ。
注意点
- ドキュメントのAPIのデフォルト値が記載されていないものが多い。
- デフォルトでオフになっているlazyMountやunmountOnExitをtrueにしない場合、非表示時にもダイアログコンポーネントがmountされるが、非表示の制御がhidden属性のみに頼っているので、ダイアログでdisplayプロパティを使っている場合は表示されてしまう。
- → lazyMountとunmountOnExitをtrueにすれば問題ない。
- closeOnEscapeが正常に動作しない。
- onOpenChangeで開閉制御している場合、trueにしてもfalseにしても指定しなくても、Escキーでダイアログが閉じてしまう。
- おそらくバグ? issue: https://github.com/chakra-ui/ark/issues/2426
- Escキーでダイアログを閉じないようにしたい場合、onOpenChangeを指定しない必要がある。
- これをすると、「ダイアログの外側をクリックしたときに閉じる」という制御ができず、やりたい場合自前実装することになりそう。
MUI - MUI Core - Base UI
-
https://github.com/mui/base-ui
- 最終更新2時間前(執筆時点)
- 120 stars(執筆時点)
- PR見てくれていそう。
- チーム開発。
- https://mui.com/about/
- チームに載っているのは35人。
- 「MUI は世界各地から貢献する、グローバルな完全リモートのチームおよびコミュニティです。」
- バージョンがbetaとalphaしかない。
- 最適なアクセシビリティ
ダイアログに当たるコンポーネントは1つ。
注意点
- バージョンがbetaとalphaしかない。
- デフォルトのroleがなぜかpresentation。
- 上書きはできる。
- modal全体を包むroot、背景(backdrop)の宣言が宣言的じゃない。
- こんな感じ。
<Modal
open={isOpen}
onClose={onClose}
slots={{
root: 'div',
backdrop: 'div'
}}
slotProps={{
root: {
className: 'AlertDialogOverlay',
role: 'alertdialog'
},
backdrop: {
}
}}
>
その他dialog特化のライブラリ
いい感じのライブラリはあっても、メンテナンスされていなかったりで採用しづらかった。
-
Tailwind CSSが作っている「HeadlessUI」は「headless UIライブラリ」の1つ ↩︎
Discussion