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.

51 lines 1.96 kB
import * as React from 'react'; import { isElement } from '@floating-ui/utils/dom'; import { useEventCallback } from '@base-ui-components/utils/useEventCallback'; import { useId } from '@base-ui-components/utils/useId'; import { createEventEmitter } from "../utils/createEventEmitter.js"; import { useFloatingParentNodeId } from "../components/FloatingTree.js"; export function useFloatingRootContext(options) { const { open = false, onOpenChange: onOpenChangeProp, elements: elementsProp } = options; const floatingId = useId(); const dataRef = React.useRef({}); const [events] = React.useState(() => createEventEmitter()); const nested = useFloatingParentNodeId() != null; if (process.env.NODE_ENV !== 'production') { const optionDomReference = elementsProp.reference; if (optionDomReference && !isElement(optionDomReference)) { console.error('Cannot pass a virtual element to the `elements.reference` option,', 'as it must be a real DOM element. Use `refs.setPositionReference()`', 'instead.'); } } const [positionReference, setPositionReference] = React.useState(elementsProp.reference); const onOpenChange = useEventCallback((newOpen, event, reason) => { dataRef.current.openEvent = newOpen ? event : undefined; events.emit('openchange', { open: newOpen, event, reason, nested }); onOpenChangeProp?.(newOpen, event, reason); }); const refs = React.useMemo(() => ({ setPositionReference }), []); const elements = React.useMemo(() => ({ reference: positionReference || elementsProp.reference || null, floating: elementsProp.floating || null, domReference: elementsProp.reference }), [positionReference, elementsProp.reference, elementsProp.floating]); return React.useMemo(() => ({ dataRef, open, onOpenChange, elements, events, floatingId, refs }), [open, onOpenChange, elements, events, floatingId, refs]); }