UNPKG

@nex-ui/react

Version:

🎉 A beautiful, modern, and reliable React component library.

76 lines (73 loc) • 2.13 kB
"use client"; import { jsx } from 'react/jsx-runtime'; import { useControlledState, useDebounce, useUnmount } from '@nex-ui/hooks'; import { useRef, useId, useCallback, useMemo, useEffect } from 'react'; import { PopperProvider } from './PopperContext.mjs'; import { PopperManager } from './PopperManager.mjs'; const popperManager = new PopperManager(); const Popper = (props)=>{ const { children, onOpenChange, open: openProp, openDelay = 100, closeDelay = 100, defaultOpen = false } = props; const referenceRef = useRef(null); const popperRootRef = useRef(null); const id = useId(); const [open, setOpen] = useControlledState(openProp, defaultOpen, onOpenChange); const debouncedOpenPopper = useDebounce(()=>{ if (!open) setOpen(true); }, { wait: openDelay }); const debouncedClosePopper = useDebounce(()=>{ if (open) setOpen(false); }, { wait: closeDelay }); const handleOpen = useCallback(()=>{ debouncedClosePopper.cancel(); debouncedOpenPopper(); popperManager.flush(id); }, [ debouncedClosePopper, debouncedOpenPopper, id ]); const handleClose = useCallback(()=>{ debouncedOpenPopper.cancel(); debouncedClosePopper(); }, [ debouncedClosePopper, debouncedOpenPopper ]); useUnmount(()=>{ debouncedClosePopper.cancel(); debouncedOpenPopper.cancel(); }); const ctx = useMemo(()=>({ open, setOpen, referenceRef, popperRootRef, handleOpen, handleClose }), [ handleClose, handleOpen, open, setOpen ]); useEffect(()=>{ if (open) { popperManager.register(id, debouncedClosePopper.flush); return ()=>popperManager.unregister(id); } }, [ debouncedClosePopper.flush, id, open ]); return /*#__PURE__*/ jsx(PopperProvider, { value: ctx, children: children }); }; Popper.displayName = 'Popper'; export { Popper };