UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

119 lines (116 loc) 3.81 kB
'use client'; import { useRef } from 'react'; import { useFloating, offset, hide, shift, limitShift, flip, inline, arrow, size } from '@floating-ui/react'; import { useUncontrolled, useDidUpdate } from '@mantine/hooks'; import { useFloatingAutoUpdate } from '../Floating/use-floating-auto-update.mjs'; import '../Floating/FloatingArrow/FloatingArrow.mjs'; function getDefaultMiddlewares(middlewares) { if (middlewares === void 0) { return { shift: true, flip: true }; } const result = { ...middlewares }; if (middlewares.shift === void 0) { result.shift = true; } if (middlewares.flip === void 0) { result.flip = true; } return result; } function getPopoverMiddlewares(options, getFloating) { const middlewaresOptions = getDefaultMiddlewares(options.middlewares); const middlewares = [offset(options.offset), hide()]; if (middlewaresOptions.shift) { middlewares.push( shift( typeof middlewaresOptions.shift === "boolean" ? { limiter: limitShift(), padding: 5 } : { limiter: limitShift(), padding: 5, ...middlewaresOptions.shift } ) ); } if (middlewaresOptions.flip) { middlewares.push( typeof middlewaresOptions.flip === "boolean" ? flip() : flip(middlewaresOptions.flip) ); } if (middlewaresOptions.inline) { middlewares.push( typeof middlewaresOptions.inline === "boolean" ? inline() : inline(middlewaresOptions.inline) ); } middlewares.push(arrow({ element: options.arrowRef, padding: options.arrowOffset })); if (middlewaresOptions.size || options.width === "target") { middlewares.push( size({ ...typeof middlewaresOptions.size === "boolean" ? {} : middlewaresOptions.size, apply({ rects, availableWidth, availableHeight, ...rest }) { const floating = getFloating(); const styles = floating.refs.floating.current?.style ?? {}; if (middlewaresOptions.size) { if (typeof middlewaresOptions.size === "object" && !!middlewaresOptions.size.apply) { middlewaresOptions.size.apply({ rects, availableWidth, availableHeight, ...rest }); } else { 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 previouslyOpened = useRef(_opened); const onClose = () => { if (_opened) { setOpened(false); } }; const onToggle = () => setOpened(!_opened); const floating = useFloating({ strategy: options.strategy, placement: options.position, middleware: getPopoverMiddlewares(options, () => floating) }); useFloatingAutoUpdate({ opened: _opened, position: options.position, positionDependencies: options.positionDependencies || [], floating }); useDidUpdate(() => { options.onPositionChange?.(floating.placement); }, [floating.placement]); useDidUpdate(() => { if (_opened !== previouslyOpened.current) { if (!_opened) { options.onClose?.(); } else { options.onOpen?.(); } } previouslyOpened.current = _opened; }, [_opened, options.onClose, options.onOpen]); return { floating, controlled: typeof options.opened === "boolean", opened: _opened, onClose, onToggle }; } export { usePopover }; //# sourceMappingURL=use-popover.mjs.map