@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
96 lines (93 loc) • 2.68 kB
JavaScript
'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