stacker.news/components/hoverable-popover.js

42 lines
1.0 KiB
JavaScript
Raw Normal View History

import { Popover } from 'react-bootstrap'
import OverlayTrigger from 'react-bootstrap/OverlayTrigger'
2024-08-13 20:30:43 +00:00
import { useRef, useState } from 'react'
2024-08-13 20:30:43 +00:00
export default function HoverablePopover ({ trigger, body, onShow }) {
const [show, setShow] = useState(false)
const popRef = useRef(null)
const timeoutId = useRef(null)
2024-08-13 20:30:43 +00:00
const onToggle = show => {
clearTimeout(timeoutId.current)
2024-08-13 20:30:43 +00:00
if (show) {
onShow?.()
timeoutId.current = setTimeout(() => setShow(true), 500)
} else {
2024-09-02 23:25:02 +00:00
timeoutId.current = setTimeout(() => setShow(!!popRef.current?.matches(':hover')), 300)
2024-08-13 20:30:43 +00:00
}
}
return (
<OverlayTrigger
placement='bottom'
2024-08-13 20:30:43 +00:00
trigger={['hover', 'focus']}
show={show}
onToggle={onToggle}
2024-09-02 23:25:02 +00:00
transition
2024-08-13 20:30:43 +00:00
rootClose
overlay={
2024-08-13 20:30:43 +00:00
<Popover style={{ position: 'fixed' }} onPointerLeave={() => onToggle(false)}>
<Popover.Body ref={popRef}>
{body}
</Popover.Body>
</Popover>
}
>
2024-08-13 20:30:43 +00:00
<span>
{trigger}
</span>
</OverlayTrigger>
)
}