Modal
Modalは、主要なコンテンツに重ねて表示され、ユーザーの注意を情報のみに集中させるコンポーネントです。
<Modal.Root>
<Modal.OpenTrigger>
<Button>Open Modal</Button>
</Modal.OpenTrigger>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
使い方
import { Modal } from "@yamada-ui/react"
import { Modal } from "@/components/ui"
import { Modal } from "@workspaces/ui"
<Modal.Root>
<Modal.OpenTrigger />
<Modal.Overlay />
<Modal.Content>
<Modal.CloseButton />
<Modal.Header>
<Modal.Title />
</Modal.Header>
<Modal.Body />
<Modal.Footer>
<Modal.CloseTrigger />
</Modal.Footer>
</Modal.Content>
</Modal.Root>
propsを使う
<Modal.Root
body="青春とは嘘であり、悪である。青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。すべては彼らのご都合主義でしかない。結論を言おう。青春を楽しむ愚か者ども、砕け散れ。"
cancel="とじる"
success="砕け散る"
title="作品冒頭"
trigger={<Button>Open Modal</Button>}
onCancel={(onClose) => onClose()}
onSuccess={noop}
/>
サイズを変更する
const [size, setSize] = useState<Modal.RootProps["size"]>("md")
const { open, onClose, onOpen } = useDisclosure()
return (
<>
<Wrap gap="md">
<For each={["xs", "sm", "md", "lg", "xl", "cover", "full"] as const}>
{(size) => (
<Button
key={size}
onClick={() => {
setSize(size)
onOpen()
}}
>
Open "{size}" Modal
</Button>
)}
</For>
</Wrap>
<Modal.Root size={size} open={open} onClose={onClose}>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Button variant="ghost" onClick={onClose}>
とじる
</Button>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
)
位置を変更する
配置を変更する場合は、placementに"start-center"や"center-start"などを設定します。デフォルトでは、"center-center"が設定されています。
const [placement, setPlacement] =
useState<Modal.RootProps["placement"]>("center")
const { open, onClose, onOpen } = useDisclosure()
return (
<>
<Wrap gap="md">
<For
each={
[
"start-start",
"start-center",
"start-end",
"center-start",
"center-center",
"center-end",
"end-start",
"end-center",
"end-end",
] as const
}
>
{(placement) => (
<Button
key={placement}
onClick={() => {
setPlacement(placement)
onOpen()
}}
>
Open "{placement}" Modal
</Button>
)}
</For>
</Wrap>
<Modal.Root open={open} placement={placement} onClose={onClose}>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Button variant="ghost" onClick={onClose}>
とじる
</Button>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
)
アニメーションを変更する
表示または非表示のアニメーションを変更する場合は、animationに"block-start"や"inline-end"などを設定します。デフォルトでは、"scale"が設定されています。
const [animationScheme, setAnimationScheme] =
useState<Modal.RootProps["animationScheme"]>("scale")
const { open, onClose, onOpen } = useDisclosure()
return (
<>
<Wrap gap="md">
<For
each={
[
"scale",
"block-start",
"inline-start",
"inline-end",
"block-end",
] as const
}
>
{(animationScheme) => (
<Button
key={animationScheme}
onClick={() => {
setAnimationScheme(animationScheme)
onOpen()
}}
>
Open "{animationScheme}" Modal
</Button>
)}
</For>
</Wrap>
<Modal.Root animationScheme={animationScheme} open={open} onClose={onClose}>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Button variant="ghost" onClick={onClose}>
とじる
</Button>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
)
所要時間を変更する
所要時間を変更する場合は、durationに数値(秒)を設定します。
<Modal.Root duration={0.4}>
<Modal.OpenTrigger>
<Button>Open Modal</Button>
</Modal.OpenTrigger>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
オーバーフローの動作を変更する
デフォルトでは、"inside"が設定されており、スクロールはModal.Body内でのみ発生します。"outside"を設定すると、Modal.Content内でスクロールが発生します。
const [scrollBehavior, setScrollBehavior] =
useState<Modal.RootProps["scrollBehavior"]>("inside")
const { open, onClose, onOpen } = useDisclosure()
return (
<>
<Wrap gap="md">
<For each={["inside", "outside"] as const}>
{(scrollBehavior) => (
<Button
key={scrollBehavior}
onClick={() => {
setScrollBehavior(scrollBehavior)
onOpen()
}}
>
Open "{scrollBehavior}" Modal
</Button>
)}
</For>
</Wrap>
<Modal.Root open={open} scrollBehavior={scrollBehavior} onClose={onClose}>
<Modal.Content h="xl">
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
<Text>青春とは嘘であり、悪である。</Text>
<Text>
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。
</Text>
<Text>
彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。
</Text>
<Text>
彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。
</Text>
<Text>
仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
</Text>
<Text>すべては彼らのご都合主義でしかない。結論を言おう。</Text>
<Text>青春を楽しむ愚か者ども、砕け散れ。</Text>
</Modal.Body>
<Modal.Footer>
<Button variant="ghost" onClick={onClose}>
とじる
</Button>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
)
モーダルを開いたときにスクロールをブロックしない
デフォルトでは、モーダルを開いた際に主要なコンテンツのスクロールをブロックしています。これは、アクセシビリティを確保するためです。もし、主要なコンテンツのスクロールをブロックしたくない場合は、blockScrollOnMountをfalseに設定します。
<Modal.Root blockScrollOnMount={false}>
<Modal.OpenTrigger>
<Button>Open Modal</Button>
</Modal.OpenTrigger>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
オーバーレイをカスタマイズする
オーバーレイをカスタマイズする場合は、Modal.Overlayを使用します。
<Modal.Root>
<Modal.OpenTrigger>
<Button>Open Modal</Button>
</Modal.OpenTrigger>
<Modal.Overlay backdropFilter="blur(4px)" />
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
オーバーレイを無効にする
モーダルのオーバーレイを無効(非表示)にする場合は、withOverlayをfalseにします。
<Modal.Root withOverlay={false}>
<Modal.OpenTrigger>
<Button>Open Modal</Button>
</Modal.OpenTrigger>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
閉じるボタンをカスタマイズする
閉じるボタンをカスタマイズする場合は、Modal.CloseButtonを使用します。
<Modal.Root>
<Modal.OpenTrigger>
<Button>Open Modal</Button>
</Modal.OpenTrigger>
<Modal.Content>
<Modal.CloseButton colorScheme="warning" />
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
閉じるボタンを無効にする
モーダルの閉じるボタンを無効(非表示)にする場合は、withCloseButtonをfalseにします。
<Modal.Root withCloseButton={false}>
<Modal.OpenTrigger>
<Button>Open Modal</Button>
</Modal.OpenTrigger>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
<Button>砕け散る</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
ネストしたモーダル
<Modal.Root>
<Modal.OpenTrigger>
<Button>Open Modal</Button>
</Modal.OpenTrigger>
<Modal.Content>
<Modal.Header>
<Modal.Title>作品冒頭</Modal.Title>
</Modal.Header>
<Modal.Body>
青春とは嘘であり、悪である。
青春をおう歌せし者達は常に自己と周囲を欺き自らを取り巻く環境のすべてを肯定的にとらえる。彼らは青春の2文字の前ならばどんな一般的な解釈も社会通念もねじ曲げてみせる。彼らにかかれば嘘も秘密も罪科も失敗さえも青春のスパイスでしかないのだ。仮に失敗することが青春の証しであるのなら友達作りに失敗した人間もまた青春のど真ん中でなければおかしいではないか。しかし彼らはそれを認めないだろう。
すべては彼らのご都合主義でしかない。結論を言おう。
青春を楽しむ愚か者ども、砕け散れ。
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
<Modal.Root size="xl">
<Modal.OpenTrigger>
<Button>作品詳細</Button>
</Modal.OpenTrigger>
<Modal.Content>
<Modal.Header>
<Modal.Title>やはり俺の青春ラブコメはまちがっている。</Modal.Title>
</Modal.Header>
<Modal.Body>
<Text>青春は残酷だ!?ひねくれ男の妄言ラブコメ</Text>
<Text>
――青春は嘘で欺瞞だ。リア充爆発しろ!
ひねくれ者故に友達も彼女もいない高校生・八幡が生活指導の先生に連れてこられたのは、学園一の美少女・雪乃が所属する「奉仕部」だった――。
さえない僕がひょんなことから美少女と出会ったはずなのに、どうしてもラブコメにならない残念どころか間違いだらけの青春模様が繰り広げられる。
俺の青春、どうしてこうなった?
</Text>
</Modal.Body>
<Modal.Footer>
<Modal.CloseTrigger>
<Button variant="ghost">とじる</Button>
</Modal.CloseTrigger>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
Props
アクセシビリティ
Modalは、アクセシビリティに関してWAI-ARIA - Dialog (Modal) Patternに従います。
キーボード操作
| キー | 説明 | 状態 |
|---|---|---|
Tab | モーダル内の無効ではない次の要素にフォーカスします。最後の要素の場合は最初の無効ではない要素をフォーカスします。 | open={true} |
Shift + Tab | モーダル内の前の無効ではない要素をフォーカスします。最初の要素の場合は最後の無効ではない要素をフォーカスします。 | open={true} |
Escape | モーダルを閉じます。 | open={true} + closeOnEsc={true} |
ARIAロールと属性
| コンポーネント | ロールと属性 | 使い方 |
|---|---|---|
Modal.Content | role="dialog" | ダイアログであることを示します。 |
aria-modal="true" | 表示されているウィジェットがモーダルであることを示します。 | |
aria-labelledby | Modal.Titleのidを設定します。 | |
aria-describedby | Modal.Bodyのidを設定します。 | |
Modal.OpenTrigger | aria-haspopup="dialog" | ダイアログが存在することを示します。 |
aria-expanded | モーダルが開いている場合は"true"を設定し、閉じている場合は"false"を設定します。 | |
aria-controls | モーダルが開いている場合は、Modal.Contentのidを設定します。 | |
aria-label | "モーダルを開く"を設定します。 | |
Modal.CloseButton | aria-label | "モーダルを閉じる"を設定します。 |
Modal.CloseTrigger | aria-label | "モーダルを閉じる"を設定します。 |
Modal.Overlay | aria-hidden | 要素をアクセシビリティツリーから除外します。 |
類似のコンポーネント
Drawer
Drawerは、画面の端から表示されるパネルのコンポーネントです。
Tooltip
Tooltipは、要素の補足など短い情報を表示するコンポーネントです。
Popover
Popoverは、要素の周りにフローティングして情報を表示するコンポーネントです。
SlideFade
SlideFadeは、要素を指定位置から移動しながら次第に表示または非表示にするコンポーネントです。
Slide
Slideは、要素をページの隅から表示または非表示にするコンポーネントです。
Fade
Fadeは、要素を次第に表示または非表示にするコンポーネントです。
Collapse
Collapseは、要素を展開または折りたたんで表示するコンポーネントです。
FadeScale
FadeScaleは、要素を次第に拡大して表示または縮小して非表示にするコンポーネントです。
使用しているコンポーネント・フック
Button
Buttonは、フォームの送信、モーダルの開閉など、ユーザーが操作できるインタラクティブなコンポーネントです。
CloseButton
CloseButtonは、基本的にコンポーネントの閉じる機能をトリガーするために使用するコンポーネントです。
FocusLock
FocusLockは、モーダルやダイアログなどの要素でフォーカスを制限し、フォーカスをその範囲内にロックすることで、アクセシビリティを向上させるコンポーネントです。
Motion
Motionは、MotionにYamada UIのStyle Propsを拡張した便利なコンポーネントです。
Popover
Popoverは、要素の周りにフローティングして情報を表示するコンポーネントです。
Portal
Portalは、現在のDOM階層の外側に要素をレンダリングするコンポーネントです。
Fade
Fadeは、要素を次第に表示または非表示にするコンポーネントです。