webapp/src/components/_shared/Popover/Popover.tsx
2024-09-15 21:47:14 +03:00

72 lines
1.7 KiB
TypeScript

import { JSX, Show, createSignal, onMount } from 'solid-js'
import usePopper from 'solid-popper'
import styles from './Popover.module.scss'
type Props = {
children: (setTooltipEl: (el: HTMLElement | null) => void) => JSX.Element
content: string | JSX.Element
disabled?: boolean
}
export const Popover = (props: Props) => {
const [show, setShow] = createSignal(false)
const [anchor, setAnchor] = createSignal<HTMLElement>()
const [popper, setPopper] = createSignal<HTMLElement>()
usePopper(anchor, popper, {
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8]
}
},
{
name: 'flip',
options: {
fallbackPlacements: ['top', 'bottom']
}
}
]
})
const showEvents = ['mouseenter', 'focus']
const hideEvents = ['mouseleave', 'blur']
const handleMouseOver = () => setShow(true)
const handleMouseOut = () => setShow(false)
if (!props.disabled) {
onMount(() => {
if (!anchor()) return
showEvents.forEach((event) => {
anchor()?.addEventListener(event, handleMouseOver)
})
hideEvents.forEach((event) => {
anchor()?.addEventListener(event, handleMouseOut)
})
return () => {
showEvents.forEach((event) => {
anchor()?.removeEventListener(event, handleMouseOver)
})
hideEvents.forEach((event) => {
anchor()?.removeEventListener(event, handleMouseOut)
})
}
})
}
return (
<>
{props.children(setAnchor)}
<Show when={show() && !props.disabled}>
<div ref={setPopper} class={styles.tooltip}>
{props.content}
<div class={styles.arrow} data-popper-arrow={true} />
</div>
</Show>
</>
)
}