Files
battlelog/project-warstone/src/lib/poppables/components/poppable.tsx

47 lines
1.3 KiB
TypeScript

import { FC, ReactNode, useCallback, useEffect, useState } from 'react'
import { PoppableContent } from './poppable-content';
import { FCC } from '../../../types';
import { useDebounce } from '../../../hooks/useDebounce';
interface IProps {
content: ReactNode;
className?: string;
preferredEdge: 'top' | 'bottom' | 'left' | 'right';
preferredAlign: 'centered' | 'top' | 'bottom' | 'left' | 'right';
spacing?: number;
}
export const Poppable: FCC<IProps> = ({ className, content, children, preferredEdge, preferredAlign, spacing }) => {
const [isHovered, setIsHovered] = useState(false);
const closing = useDebounce(!isHovered, 1000);
const closed = useDebounce(closing, 300);
const [ref, setRef] = useState<HTMLElement>();
const updateRef = useCallback((node: HTMLElement) => {
if (!node) return;
setRef(node)
}, [])
return (
<>
<span
ref={updateRef}
className={className}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
{children}
</span>
{!!ref && <PoppableContent
preferredAlign={preferredAlign}
preferredEdge={preferredEdge}
spacing={spacing}
isClosing={closing}
isClosed={closed}
relativeElement={ref}
setHover={setIsHovered}
>{content}</PoppableContent>}
</>
)
}