import React, { type HTMLAttributes } from 'react' import { createPortal } from 'react-dom' import { autoUpdate, flip, offset, size, useFloating, type ReferenceType, type UseFloatingOptions, type UseFloatingReturn, } from '@floating-ui/react-dom' import classnames from 'classnames' import { FocusOn } from 'react-focus-on' import { type ReactFocusOnProps } from 'react-focus-on/dist/es5/types' import { type OverrideClassName } from '~components/types/OverrideClassName' import styles from './Popover.module.scss' export type PopoverProps = { children: React.ReactNode refs: UseFloatingReturn['refs'] /** * passes in additional options / override for https://floating-ui.com/docs/tooltip#usefloating-hook */ floatingOptions?: Omit focusOnProps?: Omit portalContainer?: Element | DocumentFragment } & OverrideClassName> export const Popover = ({ children, refs, floatingOptions, focusOnProps, portalContainer, classNameOverride, ...restProps }: PopoverProps): JSX.Element => { const { floatingStyles } = useFloating({ elements: { reference: refs.reference.current, floating: refs.floating.current, }, placement: 'bottom-start', middleware: [ offset(6), flip(), size({ apply({ availableWidth, availableHeight, elements }) { Object.assign(elements.floating.style, { maxWidth: `${Math.min(availableWidth, 400)}px`, minWidth: `${Math.min(availableWidth, 196)}px`, maxHeight: `${Math.min(availableHeight, 352)}px`, }) }, }), ], whileElementsMounted: autoUpdate, ...floatingOptions, }) return createPortal(
{children}
, portalContainer ?? document.body, ) } Popover.displayName = 'Popover'