Closed4
dialog要素のあれこれ
dialog
要素を使ってモーダルの実装を考えていた時にバックドロップ ::backdrop
擬似要素が表示されないことがあり、 調べると showModal()
を実行してダイアログを開く必要があるとわかった。
その時のメモをここに記す。
Indicates that the dialog is active and can be interacted with. When the open attribute is not set, the dialog shouldn't be shown to the user. It is recommended to use the .show() or .showModal() methods to render dialogs, rather than the open attribute. If a <dialog> is opened using the open attribute, it will be non-modal.
MDNのテキストを見る限り、 open
属性の指定で開閉制御するのではなく、 .show()
または .showModal()
のメソッドを用いることが推奨されている。 open
属性で開いた場合 モーダル にはならない。
モーダル にならないとはなんなのか。🧐
モーダル、非モーダルの2パターンがある模様。それぞれ見ていこう。
非モーダル(モーダルレスなダイアログ)の例
open
属性の指定で開閉制御するケースです。
ダイアログ本体は表示はされますが、前述の通りバックドロップが表示されません。
import { useState } from 'react'
const Sample = () => {
const [open, setOpen] = useState(false)
return (
<div>
<button type='button' onClick={() => setOpen(true)}>
ダイアログを開く [open属性で開閉制御]
</button>
<dialog open={open}>
<p>open属性で開閉制御</p>
<button type='button' onClick={() => setOpen(false)}>
ダイアログを閉じる
</button>
</dialog>
</div>
)
}
ちなみに、.show()
で開いた場合も非モーダルに相当しているようだ。
import { useRef } from 'react'
import type { RefObject } from 'react'
function useDialog(dialogRef: RefObject<HTMLDialogElement>) {
return {
open: () => {
// .show() で開く
dialogRef.current?.show()
},
close: () => {
dialogRef.current?.close()
},
}
}
const Sample = () => {
const dialogRef = useRef<HTMLDialogElement | null>(null)
const { open, close } = useDialog(dialogRef)
return (
<div>
<button type='button' onClick={() => open()}>
ダイアログを開く [show()とclose()で開閉制御]
</button>
<dialog ref={dialogRef}>
<p>show()とclose()で開閉制御</p>
<button type='button' onClick={() => close()}>
ダイアログを閉じる
</button>
</dialog>
</div>
)
}
プレビュー
モーダルの例
showModal()
で開いた場合の例です。
特徴は次のとおりです。
-
Esc
キーで閉じることができる。 - モーダル背面の要素をクリックできない。
- バックドロップが表示される。また、バックドロップのスタイリングも可能。
import { useRef } from 'react'
import type { RefObject } from 'react'
function useDialog(dialogRef: RefObject<HTMLDialogElement>) {
return {
open: () => {
// .showModal() で開く
dialogRef.current?.showModal()
},
close: () => {
dialogRef.current?.close()
},
}
}
const Sample = () => {
const dialogRef = useRef<HTMLDialogElement | null>(null)
const { open, close } = useDialog(dialogRef)
return (
<div>
<button type='button' onClick={() => open()}>
ダイアログを開く [showModal()とclose()で開閉制御]
</button>
<dialog ref={dialogRef}>
<p>showModal()とclose()で開閉制御</p>
<button type='button' onClick={() => close()}>
ダイアログを閉じる
</button>
</dialog>
</div>
)
}
プレビュー
このスクラップは2024/02/29にクローズされました