import { Portal } from "solid-js/web";
import usePortal from "../utils/usePortal";
import useAlignPostion from "../utils/useAlignPostion";
import { createSignal, createUniqueId, onCleanup, onMount } from "solid-js";
import { useClassList } from "../utils/useProps";
import { useClickOutside } from "../utils/useClickOutside";
import createModel from "../utils/createModel";
import usezIndex from "../utils/usezIndex";
import { useTransition } from "../utils/useTransition";
import { createComputed } from "solid-js";
import { Button } from "../Button";
import { Space } from "../Layout";
export interface PopoverProps {
classList?: any
class?: string
align?: 'top'|'bottom'|'left'|'right'|'topLeft'|'topRight'|'bottomLeft'|'bottomRight'|'leftTop'|'leftBottom'|'rightTop'|'rightBottom'
trigger?: 'hover'|'click'
disabled?: boolean
arrow?: boolean
theme?: string
hideDelay?: number
onOpen?: Function
children?: any
content?: any
visible?: any
ref?: any
confirm?: boolean
okText?: any
cancleText?: any
style?: any
onOk?: Function,
onCancel?: Function,
}
export function Popover (props: PopoverProps) {
const [visible, setVisible] = createModel(props, 'visible', false);
const [opened, setOpened] = createSignal(visible());
const [_, update] = createSignal(createUniqueId());
const [buttonLoading, setButtonLoading] = createSignal(false);
let inner: any;
let removeClickOutside: Function;
let wrap: any;
const align = () => props.align || 'right';
const trigger = () => props.confirm ? 'click' : props.trigger || 'hover';
const zindex = usezIndex();
let timer: any = null;
const hideDelay = props.hideDelay || 200;
const clearDelayTimer = () => {
if (timer) {
clearTimeout(timer);
timer = null;
}
}
const onMouseEnter = () => {
if (props.disabled) {
return;
}
if (trigger() === 'hover') {
clearDelayTimer();
setVisible(true);
props.onOpen && props.onOpen(true);
}
}
const onMouseLeave = () => {
if (props.disabled) {
return;
}
if (trigger() === 'hover') {
timer = setTimeout( () => {
setVisible(false);
props.onOpen && props.onOpen(false);
}, hideDelay);
}
}
const onClick = (e: any) => {
if (props.disabled) {
return;
}
e.preventDefault();
e.stopPropagation();
if (trigger() === 'click') {
const show = visible();
setVisible(!show);
props.onOpen && props.onOpen(!show);
}
}
const classList = () => useClassList(props, 'cm-popover-inner', {
// 'cm-popover-inner-show': visible(),
'cm-popover-with-arrow': props.arrow,
'cm-popover-confirm': props.confirm,
[`cm-popover-${props.theme}`]: props.theme
});
const transition = useTransition({
el: ()=> wrap,
startClass: 'cm-popover-inner-visible',
activeClass: 'cm-popover-inner-show',
onLeave: () => {
setOpened(false);
},
onEnter: () => {
setOpened(true);
}
})
createComputed(() => {
const v = visible();
if (v) {
transition.enter();
} else {
transition.leave();
}
})
const posStyle = () => {
opened()
_();
if (inner && inner.nextElementSibling) {
const pos: any = useAlignPostion(align(), inner.nextElementSibling);
pos.top = pos.top + document.documentElement.scrollTop + 'px';
pos.left = pos.left + document.documentElement.scrollLeft + 'px';
pos['z-index'] = zindex;
Object.assign(pos, props.style || {});
return pos;
}
};
const onOk = async () => {
if (props.onOk) {
setButtonLoading(true);
const ret = await props.onOk();
setButtonLoading(false);
if (ret === undefined || ret === true) {
setVisible(false);
props.onOpen && props.onOpen(false);
}
}
}
const onCancel = () => {
props.onCancel && props.onCancel();
setVisible(false);
props.onOpen && props.onOpen(false);
}
onMount (() => {
if (inner.nextElementSibling) {
if (trigger() === 'hover') {
inner.nextElementSibling.addEventListener('mouseenter', onMouseEnter, false);
inner.nextElementSibling.addEventListener('mouseleave', onMouseLeave, false);
}
if (trigger() === 'click') {
inner.nextElementSibling.addEventListener('click', onClick, false);
removeClickOutside = useClickOutside([wrap, inner.nextElementSibling], () => {
setVisible(false);
});
}
}
})
onCleanup (() => {
if (inner.nextElementSibling) {
if (trigger() === 'hover') {
inner.nextElementSibling.removeEventListener('mouseenter', onMouseEnter);
inner.nextElementSibling.removeEventListener('mouseleave', onMouseLeave);
}
if (trigger() === 'click') {
inner.nextElementSibling.removeEventListener('click', onClick);
}
}
removeClickOutside && removeClickOutside();
});
const id = 'cm-popover-portal';
props.ref && props.ref({
updatePosition () {
update(createUniqueId());
}
});
const okText = props.okText ?? '确 定';
const cancleText = props.cancleText ?? '取 消';
return <>
{props.children}
{props.content}
{
props.confirm ?
: null
}
{
props.arrow ?
: null
}
>
}