@base-ui-components/react
Version:
Base UI is a library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features.
62 lines • 1.94 kB
JavaScript
import * as React from 'react';
import { useAnchorPositioning } from '../../utils/useAnchorPositioning.js';
import { mergeReactProps } from '../../utils/mergeReactProps.js';
import { useSelectRootContext } from '../root/SelectRootContext.js';
import { useScrollLock } from '../../utils/useScrollLock.js';
export function useSelectPositioner(params) {
const {
open,
alignItemToTrigger,
mounted,
triggerElement,
modal
} = useSelectRootContext();
useScrollLock((alignItemToTrigger || modal) && open, triggerElement);
const {
positionerStyles: enabledPositionerStyles,
arrowStyles,
anchorHidden,
arrowRef,
arrowUncentered,
renderedSide,
renderedAlign,
positionerContext,
isPositioned
} = useAnchorPositioning({
...params,
keepMounted: true,
trackAnchor: params.trackAnchor ?? !alignItemToTrigger,
mounted
});
const positionerStyles = React.useMemo(() => alignItemToTrigger ? {
position: 'fixed'
} : enabledPositionerStyles, [alignItemToTrigger, enabledPositionerStyles]);
const getPositionerProps = React.useCallback((externalProps = {}) => {
const hiddenStyles = {};
if (!open) {
hiddenStyles.pointerEvents = 'none';
}
return mergeReactProps(externalProps, {
role: 'presentation',
hidden: !mounted,
style: {
...positionerStyles,
...hiddenStyles
}
});
}, [open, mounted, positionerStyles]);
const positioner = React.useMemo(() => ({
arrowRef,
arrowUncentered,
arrowStyles,
side: alignItemToTrigger ? 'none' : renderedSide,
align: renderedAlign,
positionerContext,
isPositioned,
anchorHidden
}), [alignItemToTrigger, arrowRef, arrowStyles, arrowUncentered, isPositioned, positionerContext, renderedAlign, renderedSide, anchorHidden]);
return React.useMemo(() => ({
getPositionerProps,
positioner
}), [getPositionerProps, positioner]);
}