Headless UI(Tailwind)の`Disclosure.Panel`をページ遷移で閉じる方法の覚書(Next.js)
Disclosure.Panel要素を使うと、モバイルでのドロップダウンメニューなどが簡単に作れます。 このメニューを、ページ遷移で自動的に閉じる実装を試してみました。 Disclosure.ButtonにLinkをセッ […]
目次
Disclosure.Panel
要素を使うと、モバイルでのドロップダウンメニューなどが簡単に作れます。
このメニューを、ページ遷移で自動的に閉じる実装を試してみました。
Disclosure.Button
にLink
をセットすればOK・・・?
ドキュメントを見ると、「Disclosure.Button
のas
を使おう」と書かれています。
<Disclosure.Button as={MyLink} href="/home">
Home
</Disclosure.Button>
This is especially useful when using disclosures for things like mobile menus that contain links where you want the disclosure to close when navigating to the next page.
https://headlessui.com/react/disclosure#closing-disclosures-manually
が、自分の実装ではうまく動きませんでした。Next.jsのLinkと相性が悪いのか、自分の設定ミスなのかはちょっと不明です。
onClick
で明示的にcloseする
結局、もう一つの方法である「Disclosure.Panel
の子要素に追加されるclose
メソッド」を採用しました。
Alternatively,
Disclosure
andDisclosure.Panel
expose aclose()
render prop which you can use to imperatively close the panel, say after running an async action:https://headlessui.com/react/disclosure#closing-disclosures-manually
<Disclosure.Panel>
{({ close }) => (
<button
onClick={async () => {
await fetch('/accept-terms', { method: 'POST' })
close()
}}
>
Read and accept
</button>
)}
</Disclosure.Panel>
サンプルコードのfetch
部分を、useRouter()
のpush
に差し替えます。
const { push } = useRouter()
...
<Disclosure.Panel>
{({ close }: { close: () => void }) => (
<button
onClick={async () => {
await push('/accept-terms')
close()
}}
>
Read and accept
</button>
)}
</Disclosure.Panel>