UNPKG

@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
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]); }