Base UI × Tailwind CSS 実践ガイド: Dialog で学ぶロジックとデザインの分離、Storybook、3 層テスト
Base UI の Dialog を Tailwind CSS で仕上げ、Storybook に載せ、jsdom と Storybook と実ブラウザの 3 層でテストするまでを通す全 9 章のガイド。状態管理や ARIA のコードを自分で書かずに済ませる分け方と、その分け方がテストの書き方をどう変えるかを扱います。
Base UI の Dialog を Tailwind CSS で仕上げ、Storybook に載せ、jsdom と Storybook と実ブラウザの 3 層でテストするまでを通す全 9 章のガイド。状態管理や ARIA のコードを自分で書かずに済ませる分け方と、その分け方がテストの書き方をどう変えるかを扱います。
Base UI の Dialog と Tailwind CSS で、お知らせ用のダイアログを実装します。パーツごとの役割、className へ直接クラスを渡す書き方、data 属性による開閉の遷移、useState と ARIA の属性を書かずに済む理由を順に見ます。
テスト 3 層の第 2 層を書きます。story に play 関数を足して開閉の操作を検証し、Vitest アドオンで実ブラウザの上で実行します。a11y の違反をテストの失敗にする設定と、Chromatic で見た目の差分を検知する流れも扱います。
Base UI と Tailwind CSS のプロジェクトに Storybook を入れ、ダイアログの閉じた状態と開いた状態を story にします。導入コマンドが足すもの、Tailwind CSS を story に効かせる設定、a11y アドオン、CSF 3 での story の書き方を扱います。
モーダルを自作すると抱える仕事を数え、そのうちどこをヘッドレス UI に渡せるかを見ます。Base UI がどういうライブラリで、Tailwind CSS と組み合わせると何が楽になり、何が手元に残るかを整理します。
Base UI、Tailwind CSS、Storybook、テストの 4 つが何を受け持ったかを振り返ります。同じ分け方を、Zod のスキーマで検証するフォームと、TanStack Query で取得したデータを props で渡す構成に広げ、通信を伴う部分をどこで差し替えるかを整理します。
Base UI が受け持つ振る舞いと、Tailwind CSS が受け持つ見た目の境界を、実際に DOM へ出る属性から確かめます。フォーカスの閉じ込め、開閉の状態を伝える data 属性、その属性を Tailwind CSS の variant で受ける書き方を扱います。
テスト 3 層の第 1 層を書きます。Vitest に jsdom の project を足し、React Testing Library と user-event で、ダイアログが開くこと、フォーカスが中へ移って外へ出ないこと、Esc キーと閉じるボタンで閉じることを確かめます。待ってから確かめる箇所と、jsdom では確かめられないことも整理します。
テスト 3 層の第 3 層を書きます。Vitest Browser Mode で本物のキー入力を送り、フォーカスの閉じ込めと閉じる遷移を確かめます。Playwright でページに組み込んだ状態を通しで確かめ、最後にどの検証をどの層に置くかを表にまとめます。
Base UI が付ける役割と名前を手がかりにすると、Tailwind CSS のクラスや要素の入れ子に触らずにテストが書けます。その理由と、表示用の計算を純粋関数へ切り出す設計、jsdom と Storybook と実ブラウザの 3 層の全体像を扱います。