Headless UI(Tailwind)の`Disclosure.Panel`をページ遷移で閉じる方法の覚書(Next.js)

Disclosure.Panel要素を使うと、モバイルでのドロップダウンメニューなどが簡単に作れます。 このメニューを、ページ遷移で自動的に閉じる実装を試してみました。 Disclosure.ButtonにLinkをセッ […]

広告ここから
広告ここまで

目次

    Disclosure.Panel要素を使うと、モバイルでのドロップダウンメニューなどが簡単に作れます。

    このメニューを、ページ遷移で自動的に閉じる実装を試してみました。

    Disclosure.ButtonLinkをセットすればOK・・・?

    ドキュメントを見ると、「Disclosure.Buttonasを使おう」と書かれています。

    
            <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 and Disclosure.Panel expose a close() 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>

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark