/// <reference no-default-lib="true" /> /// <reference lib="esnext" /> /// <reference lib="dom" /> /** @jsx h */ /** @jsxFrag Fragment */ import { Fragment, h, render } from "../preact/mod.tsx"; import { useCallback, useState, useMemo, useEffect, useRef } from "../preact/hooks.ts"; const useDialog = () => { const ref = useRef<HTMLDialogElement>(null); const open = useCallback(() => ref.current?.showModal?.(), []); const close = useCallback(() => ref.current?.close?.(), []); return { ref, open, close, isOpen: ref.current?.open ?? false }; }; const App = () => { const { ref, open, close } = useDialog(); /** dialogクリックではmodalを閉じないようにする */ const stopPropagation = useCallback((e: Event) => e.stopPropagation(), []); return (<> <style>{` body:has(dialog:modal) { touch-action: none; overflow: hidden; overscroll-behavior: none; } button.open { position: fixed; z-index: 1050; top: 10%; left: 10%; } dialog { background: red; } `}</style> <button className="open" onClick={open}>open modal</button> <dialog ref={ref} onClick={close}> <div className="container" onClick={stopPropagation}> <p>dialog内のテキスト</p> <button className="close" onClick={close}>close</button> </div> </dialog> </>) }; const app = document.createElement("div"); const shadowRoot = app.attachShadow({ mode: "open" }); document.body.append(app); render(<App />, shadowRoot);