| 1 |
import { Dialog, DialogTitle } from '@headlessui/react'; |
| 2 |
import { Icon } from '@wordpress/components'; |
| 3 |
import { useEffect, useLayoutEffect, useState } from '@wordpress/element'; |
| 4 |
import { __ } from '@wordpress/i18n'; |
| 5 |
import { close } from '@wordpress/icons'; |
| 6 |
|
| 7 |
export const ToolTip = ({ children, title, onClose, anchor }) => { |
| 8 |
const [open, setOpen] = useState(false); |
| 9 |
const [left, setLeft] = useState(0); |
| 10 |
const [top, setTop] = useState(0); |
| 11 |
const onCloseModal = () => { |
| 12 |
setOpen(false); |
| 13 |
onClose?.(); |
| 14 |
}; |
| 15 |
|
| 16 |
useLayoutEffect(() => { |
| 17 |
if (!anchor || !open) return; |
| 18 |
// set the anchor's outline to something thick |
| 19 |
const prevOutline = anchor.style.outline; |
| 20 |
anchor.style.outline = '99999px solid rgba(0, 0, 0, 0.4)'; |
| 21 |
// find the anchor's center (now only support bottom center) |
| 22 |
const rect = anchor.getBoundingClientRect(); |
| 23 |
const x = rect.left + rect.width / 2; |
| 24 |
const y = rect.top + rect.height; |
| 25 |
setLeft(x); |
| 26 |
setTop(y); |
| 27 |
return () => { |
| 28 |
anchor.style.outline = prevOutline; |
| 29 |
}; |
| 30 |
}, [anchor, open]); |
| 31 |
|
| 32 |
useEffect(() => { |
| 33 |
setOpen(true); |
| 34 |
}, [left, top]); |
| 35 |
|
| 36 |
if (!open) return; |
| 37 |
return ( |
| 38 |
<Dialog |
| 39 |
static |
| 40 |
className="extendify-shared" |
| 41 |
open={open} |
| 42 |
onClose={onCloseModal} |
| 43 |
> |
| 44 |
<div className="relative z-max"> |
| 45 |
{/* overlay to prevent click through */} |
| 46 |
<div |
| 47 |
onClick={onCloseModal} |
| 48 |
aria-hidden={true} |
| 49 |
role="presentation" |
| 50 |
className="fixed inset-0 z-10 h-screen w-screen bg-transparent" |
| 51 |
/> |
| 52 |
<div |
| 53 |
className="fixed z-20 flex min-w-80 max-w-xs flex-col bg-transparent shadow-2xl" |
| 54 |
style={{ |
| 55 |
top: `${top + 12}px`, |
| 56 |
left: `${left}px`, |
| 57 |
transform: 'translate(-50%, 0)', |
| 58 |
}} |
| 59 |
> |
| 60 |
<div className="absolute left-1/2 top-[-12px] h-0 w-0 -translate-x-1/2 transform border-b-[12px] border-l-[8px] border-r-[8px] border-transparent border-b-white" /> |
| 61 |
<button |
| 62 |
type="button" |
| 63 |
data-test="close-tooltip" |
| 64 |
className="absolute right-0 top-0 z-20 m-2 flex h-6 w-6 cursor-pointer items-center justify-center rounded-full border-0 bg-white p-0 leading-none outline-hidden ring-1 ring-gray-200 focus:shadow-none focus:ring-wp focus:ring-design-main rtl:left-0 rtl:right-auto" |
| 65 |
onClick={onCloseModal} |
| 66 |
aria-label={__('Close ToolTip', 'extendify-local')} |
| 67 |
> |
| 68 |
<Icon icon={close} className="h-4 w-4 fill-current" /> |
| 69 |
</button> |
| 70 |
<DialogTitle className="sr-only">{title}</DialogTitle> |
| 71 |
<div className="text-base relative m-0 bg-white p-6 pt-8 text-left font-sans leading-7 text-gray-900 rtl:text-right"> |
| 72 |
{children} |
| 73 |
</div> |
| 74 |
</div> |
| 75 |
</div> |
| 76 |
</Dialog> |
| 77 |
); |
| 78 |
}; |
| 79 |
|