import { useTheme } from '@wise/components-theming'; import { clsx } from 'clsx'; import { useRef, useState, cloneElement, useEffect, isValidElement, useId } from 'react'; import { Position, Typography } from '../common'; import ResponsivePanel from '../common/responsivePanel'; import Title from '../title'; import { logActionRequired } from '../utilities'; /** @deprecated Use `"top" | "bottom"` instead. */ type PopoverPreferredPlacementDeprecated = | `${Position.LEFT_TOP}` | `${Position.RIGHT_TOP}` | `${Position.BOTTOM_RIGHT}` | `${Position.BOTTOM_LEFT}`; export type PopoverPreferredPlacement = | `${Position.TOP}` | `${Position.RIGHT}` | `${Position.BOTTOM}` | `${Position.LEFT}` | PopoverPreferredPlacementDeprecated; export interface PopoverProps { children?: React.ReactNode; title?: React.ReactNode; /** Screen-reader-friendly title. Must be provided if `title` prop is not set. */ 'aria-label'?: string; /** @default 'right' */ preferredPlacement?: PopoverPreferredPlacement; content: React.ReactNode; onClose?: () => void; className?: string; } function resolvePlacement(preferredPlacement: PopoverPreferredPlacement) { switch (preferredPlacement) { case 'left-top': case 'right-top': return 'top'; case 'bottom-left': case 'bottom-right': return 'bottom'; default: return preferredPlacement; } } export default function Popover({ children, className, content, preferredPlacement = Position.RIGHT, title, onClose, 'aria-label': ariaLabel, }: PopoverProps) { const titleId = useId(); const resolvedPlacement = resolvePlacement(preferredPlacement); useEffect(() => { if (resolvedPlacement !== preferredPlacement) { logActionRequired( `Popover has deprecated ${preferredPlacement} value for the 'preferredPlacement' prop. Please use ${resolvedPlacement} instead.`, ); } }, [preferredPlacement, resolvedPlacement]); const anchorReference = useRef(null); const [open, setOpen] = useState(false); const handleOnClose = () => { setOpen(false); onClose?.(); }; return ( {isValidElement<{ onClick?: () => void }>(children) ? cloneElement(children, { onClick: () => { children.props.onClick?.(); setOpen((prevOpen) => !prevOpen); }, }) : children}
{title && ( {title} )} {content}
); }