UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

155 lines (154 loc) 5.84 kB
"use client"; let react = require("react"); let _mantine_hooks = require("@mantine/hooks"); let _floating_ui_react = require("@floating-ui/react"); //#region packages/@mantine/core/src/components/Popover/use-popover.ts 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, disableFlip, lockEnabled) { const middlewaresOptions = getDefaultMiddlewares(options.middlewares); const middlewares = [(0, _floating_ui_react.offset)(options.offset), (0, _floating_ui_react.hide)()]; if (middlewaresOptions.flip && !disableFlip) { const userFlip = typeof middlewaresOptions.flip === "boolean" ? {} : middlewaresOptions.flip; const flipOptions = lockEnabled ? { fallbackStrategy: "initialPlacement", ...userFlip } : userFlip; middlewares.push((0, _floating_ui_react.flip)(flipOptions)); } if (middlewaresOptions.shift) { const shiftOptions = typeof middlewaresOptions.shift === "boolean" ? {} : middlewaresOptions.shift; middlewares.push((0, _floating_ui_react.shift)((state) => { const isVerticalPlacement = state.placement.startsWith("top") || state.placement.startsWith("bottom"); return { limiter: (0, _floating_ui_react.limitShift)(), padding: 5, ...options.width === "target" && isVerticalPlacement ? { mainAxis: false } : null, ...shiftOptions }; })); } if (middlewaresOptions.inline) middlewares.push(typeof middlewaresOptions.inline === "boolean" ? (0, _floating_ui_react.inline)() : (0, _floating_ui_react.inline)(middlewaresOptions.inline)); middlewares.push((0, _floating_ui_react.arrow)({ element: options.arrowRef, padding: options.arrowOffset })); if (middlewaresOptions.size || options.width === "target") middlewares.push((0, _floating_ui_react.size)({ ...typeof middlewaresOptions.size === "boolean" ? {} : middlewaresOptions.size, apply({ rects, availableWidth, availableHeight, ...rest }) { const styles = getFloating().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] = (0, _mantine_hooks.useUncontrolled)({ value: options.opened, defaultValue: options.defaultOpened, finalValue: false, onChange: options.onChange }); const previouslyOpened = (0, react.useRef)(_opened); const [lockedPlacement, setLockedPlacement] = (0, react.useState)(null); const lockEnabled = options.preventPositionChangeWhenVisible !== false; const wasOpenedRef = (0, react.useRef)(_opened); if (_opened !== wasOpenedRef.current) { wasOpenedRef.current = _opened; if (_opened && lockedPlacement !== null) setLockedPlacement(null); } const resetLockedPlacement = (0, react.useCallback)(() => setLockedPlacement(null), []); const onClose = () => { if (_opened && !options.disabled) setOpened(false); }; const onToggle = () => { if (!options.disabled) setOpened(!_opened); }; const floating = (0, _floating_ui_react.useFloating)({ open: _opened, strategy: options.strategy, placement: lockEnabled ? lockedPlacement ?? options.position : options.position, middleware: getPopoverMiddlewares(options, () => floating, lockEnabled && lockedPlacement !== null, lockEnabled), whileElementsMounted: !options.keepMounted ? _floating_ui_react.autoUpdate : void 0 }); (0, react.useEffect)(() => { if (!options.keepMounted) return; const referenceElement = floating.refs.reference.current; const floatingElement = floating.refs.floating.current; if (_opened && referenceElement && floatingElement) return (0, _floating_ui_react.autoUpdate)(referenceElement, floatingElement, floating.update); }, [ options.keepMounted, _opened, floating.update, floating.elements.reference, floating.elements.floating ]); const measuredAfterShowRef = (0, react.useRef)(false); (0, _mantine_hooks.useIsomorphicEffect)(() => { if (!_opened) { measuredAfterShowRef.current = false; return; } if (!lockEnabled || lockedPlacement !== null) return; const flEl = floating.refs.floating.current; if (!flEl || flEl.offsetHeight === 0 || flEl.offsetWidth === 0) return; if (!measuredAfterShowRef.current) { measuredAfterShowRef.current = true; floating.update(); return; } if (floating.isPositioned) setLockedPlacement(floating.placement); }, [ lockEnabled, _opened, floating.isPositioned, floating.placement, lockedPlacement, floating.update ]); const previousPlacementRef = (0, react.useRef)(floating.placement); (0, _mantine_hooks.useIsomorphicEffect)(() => { if (previousPlacementRef.current !== floating.placement) { previousPlacementRef.current = floating.placement; options.onPositionChange?.(floating.placement); } }, [floating.placement]); (0, _mantine_hooks.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, resetLockedPlacement }; } //#endregion exports.usePopover = usePopover; //# sourceMappingURL=use-popover.cjs.map