2022-10-25 15:36:32 +00:00
|
|
|
import { createEffect, createSignal, JSX, onCleanup, onMount, Show } from 'solid-js'
|
|
|
|
import styles from './Popup.module.scss'
|
|
|
|
import { clsx } from 'clsx'
|
|
|
|
|
|
|
|
export type PopupProps = {
|
|
|
|
containerCssClass?: string
|
|
|
|
trigger: JSX.Element
|
|
|
|
children: JSX.Element
|
|
|
|
onVisibilityChange?: (isVisible) => void
|
2022-10-17 20:53:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export const Popup = (props: PopupProps) => {
|
2022-10-25 15:36:32 +00:00
|
|
|
const [isVisible, setIsVisible] = createSignal(false)
|
2022-10-17 20:53:04 +00:00
|
|
|
|
2022-10-25 15:36:32 +00:00
|
|
|
createEffect(() => {
|
|
|
|
if (props.onVisibilityChange) {
|
|
|
|
props.onVisibilityChange(isVisible())
|
|
|
|
}
|
2022-10-17 20:53:04 +00:00
|
|
|
})
|
|
|
|
|
2022-10-25 15:36:32 +00:00
|
|
|
let container: HTMLDivElement | undefined
|
|
|
|
|
|
|
|
const handleClickOutside = (event: MouseEvent & { target: Element }) => {
|
|
|
|
if (!isVisible()) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.target === container || container?.contains(event.target)) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
setIsVisible(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
onMount(() => {
|
|
|
|
document.addEventListener('click', handleClickOutside, { capture: true })
|
|
|
|
onCleanup(() => document.removeEventListener('click', handleClickOutside, { capture: true }))
|
2022-10-17 20:53:04 +00:00
|
|
|
})
|
|
|
|
|
2022-10-25 15:36:32 +00:00
|
|
|
const toggle = () => setIsVisible((oldVisible) => !oldVisible)
|
|
|
|
// class={clsx(styles.popupShare, stylesPopup.popupShare)}
|
2022-10-17 20:53:04 +00:00
|
|
|
return (
|
2022-10-25 15:36:32 +00:00
|
|
|
<span class={clsx(styles.container, props.containerCssClass)} ref={container}>
|
|
|
|
<span onClick={toggle}>{props.trigger}</span>
|
|
|
|
<Show when={isVisible()}>
|
|
|
|
<div class={clsx(styles.popup)}>{props.children}</div>
|
|
|
|
</Show>
|
|
|
|
</span>
|
2022-10-17 20:53:04 +00:00
|
|
|
)
|
|
|
|
}
|