Reputation: 11
Cannot figure out how to get popover to close when next Link is clicked inside. Used popover from tailwindui and added next Link, tried the headlessUI closing popover using as={Link}, no luck.
<div className='max-w-7xl mx-auto grid gap-y-6 px-4 py-6 sm:grid-cols-2 sm:gap-8 sm:px-6 sm:py-8 lg:grid-cols-4 lg:px-8 lg:py-12 xl:py-16'>
{about.map((item) => (
<Popover.Button key={item.name}>
<Link href={item.href}>
<a
href={item.href}
className='-m-3 p-3 flex flex-col justify-between rounded-lg hover:bg-gray-50'>
<div className='flex md:h-full lg:flex-col'>
<div className='flex-shrink-0'>
<span className='inline-flex items-center justify-center h-10 w-10 rounded-md bg-cyan-500 text-white sm:h-12 sm:w-12'>
<item.icon
className='h-6 w-6'
aria-hidden='true'
/>
</span>
</div>
<div className='ml-4 md:flex-1 md:flex md:flex-col md:justify-between lg:ml-0 lg:mt-4'>
<div>
<p className='text-base font-medium text-gray-900'>
{item.name}
</p>
<p className='mt-1 text-sm text-gray-500'>
{item.description}
</p>
</div>
<p className='mt-2 text-sm font-medium text-cyan-600 lg:mt-4'>
Learn more
<span aria-hidden='true'>
→
</span>
</p>
</div>
</div>
</a>
</Link>
</Popover.Button>```
Help please, what am i missing?
Upvotes: 1
Views: 2654
Reputation: 1380
I just ran into this exact issue.
I got it working by doing two things referenced separately in the Headless UI docs. This involved creating a custom wrapper component for Next's Link
and exposing the close()
render prop on the Popover Panel.
A minimal example using the solution is listed first followed by an explanation with references to the docs.
import { forwardRef } from 'react'
import Link from 'next/link'
import { Popover } from '@headlessui/react'
const MyLink = forwardRef((props, ref) => {
let { href, children, ...rest } = props
return (
<Link href={href}>
<a ref={ref} {...rest}>
{children}
</a>
</Link>
)
})
function Example() {
return (
<Popover>
{({ open }) => (
<>
<Popover.Button>Open Popover</Popover.Button>
<Popover.Panel>
{({ close }) => (
<MyLink href='/profile' onClick={() => close()}>
Profile
</MyLink>
)}
</Popover.Panel>
</>
)}
</Popover>
)
}
Expose the close()
render prop inside your Popover Panel, per the alternative solution suggested in the docs.
<Popover.Panel>
{({ close }) => (
We will call this in our link to manually close the popup when the link is clicked.
Create your own custom MyLink
component (or whatever name you want) that wraps Link
and forwards props to the child a
element. As explained in the Headless UI docs, Next's Link
component doesn't forward unknown props by default and Headless needs to do this in order to work by adding the necessary event listeners.
const MyLink = forwardRef((props, ref) => {
let { href, children, ...rest } = props
return (
<Link href={href}>
<a ref={ref} {...rest}>
{children}
</a>
</Link>
)
})
Upvotes: 3