UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

96 lines (93 loc) 2.68 kB
'use client'; import { useFloating, offset, shift, limitShift, flip, inline, arrow, size } from '@floating-ui/react'; import { useUncontrolled, useDidUpdate } from '@mantine/hooks'; import 'react'; import { useFloatingAutoUpdate } from '../Floating/use-floating-auto-update.mjs'; import '../Floating/FloatingArrow/FloatingArrow.mjs'; function getPopoverMiddlewares(options, getFloating) { const middlewares = [offset(options.offset)]; if (options.middlewares?.shift) { middlewares.push(shift({ limiter: limitShift() })); } if (options.middlewares?.flip) { middlewares.push(flip()); } if (options.middlewares?.inline) { middlewares.push(inline()); } middlewares.push(arrow({ element: options.arrowRef, padding: options.arrowOffset })); if (options.middlewares?.size || options.width === "target") { middlewares.push( size({ apply({ rects, availableWidth, availableHeight }) { const floating = getFloating(); const styles = floating.refs.floating.current?.style ?? {}; if (options.middlewares?.size) { Object.assign(styles, { maxWidth: `${availableWidth}px`, maxHeight: `${availableHeight}px` }); } if (options.width === "target") { Object.assign(styles, { width: `${rects.reference.width}px` }); } } }) ); } return middlewares; } function usePopover(options) { const [_opened, setOpened] = useUncontrolled({ value: options.opened, defaultValue: options.defaultOpened, finalValue: false, onChange: options.onChange }); const onClose = () => { if (_opened) { options.onClose?.(); setOpened(false); } }; const onToggle = () => { if (_opened) { options.onClose?.(); setOpened(false); } else { options.onOpen?.(); setOpened(true); } }; const floating = useFloating({ placement: options.position, middleware: getPopoverMiddlewares(options, () => floating) }); useFloatingAutoUpdate({ opened: options.opened, position: options.position, positionDependencies: options.positionDependencies || [], floating }); useDidUpdate(() => { options.onPositionChange?.(floating.placement); }, [floating.placement]); useDidUpdate(() => { if (!options.opened) { options.onClose?.(); } else { options.onOpen?.(); } }, [options.opened]); return { floating, controlled: typeof options.opened === "boolean", opened: _opened, onClose, onToggle }; } export { usePopover }; //# sourceMappingURL=use-popover.mjs.map