UNPKG

@yamada-ui/popover

Version:

Yamada UI popover component

305 lines (304 loc) • 10.4 kB
"use client" "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/popover.tsx var popover_exports = {}; __export(popover_exports, { Popover: () => Popover, popoverProperties: () => popoverProperties, usePopover: () => usePopover }); module.exports = __toCommonJS(popover_exports); var import_core = require("@yamada-ui/core"); var import_use_animation = require("@yamada-ui/use-animation"); var import_use_disclosure = require("@yamada-ui/use-disclosure"); var import_use_focus = require("@yamada-ui/use-focus"); var import_use_popper = require("@yamada-ui/use-popper"); var import_utils = require("@yamada-ui/utils"); var import_react = require("react"); var import_jsx_runtime = require("react/jsx-runtime"); var popoverProperties = [ ...import_use_popper.popperProperties, "open", "isOpen", "defaultOpen", "defaultIsOpen", "onOpen", "onClose", "initialFocusRef", "restoreFocus", "autoFocus", "closeOnBlur", "closeOnEsc", "closeOnButton", "trigger", "openDelay", "closeDelay", "lazy", "isLazy", "lazyBehavior", "animation", "duration" ]; var [PopoverProvider, usePopover] = (0, import_utils.createContext)({ name: "PopoverContext", errorMessage: `usePopoverContext returned is 'undefined'. Seems you forgot to wrap the components in "<Popover />"` }); var Popover = (props) => { const [styles, mergedProps] = (0, import_core.useComponentMultiStyle)("Popover", props); const { animation = "scale", autoFocus = true, children, closeDelay = 200, closeOnBlur = true, closeOnButton = true, closeOnEsc = true, duration, initialFocusRef, isLazy, lazy = isLazy, lazyBehavior = "unmount", openDelay = 200, relatedRef, restoreFocus = true, trigger = "click", ...rest } = (0, import_core.omitThemeProps)(mergedProps); const id = (0, import_react.useId)(); const { open, onClose, onOpen, onToggle } = (0, import_use_disclosure.useDisclosure)(mergedProps); const anchorRef = (0, import_react.useRef)(null); const triggerRef = (0, import_react.useRef)(null); const headerRef = (0, import_react.useRef)(null); const bodyRef = (0, import_react.useRef)(null); const popoverRef = (0, import_react.useRef)(null); const { present, onAnimationComplete } = (0, import_use_animation.useAnimationObserver)({ ref: popoverRef, open }); const openTimeout = (0, import_react.useRef)(void 0); const closeTimeout = (0, import_react.useRef)(void 0); const hoveringRef = (0, import_react.useRef)(false); const hasBeenOpened = (0, import_react.useRef)(false); const { forceUpdate, referenceRef, transformOrigin, getPopperProps } = (0, import_use_popper.usePopper)({ ...rest, enabled: open }); if (open) hasBeenOpened.current = true; (0, import_react.useEffect)(() => { return () => { if (openTimeout.current) clearTimeout(openTimeout.current); if (closeTimeout.current) clearTimeout(closeTimeout.current); }; }, []); (0, import_use_focus.useFocusOnPointerDown)({ ref: triggerRef, enabled: open }); (0, import_use_focus.useFocusOnHide)(popoverRef, { focusRef: triggerRef, shouldFocus: restoreFocus && (trigger === "click" || trigger === "contextmenu"), visible: open }); (0, import_use_focus.useFocusOnShow)(popoverRef, { focusRef: initialFocusRef, shouldFocus: autoFocus && (trigger === "click" || trigger === "contextmenu"), visible: open }); const shouldRenderContent = (0, import_use_disclosure.useLazyDisclosure)({ enabled: lazy, isSelected: present, mode: lazyBehavior, wasSelected: hasBeenOpened.current }); const getPopoverProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => { var _a, _b; const popoverProps = { id, "aria-describedby": (_a = bodyRef.current) == null ? void 0 : _a.id, "aria-hidden": !open, "aria-labelledby": (_b = headerRef.current) == null ? void 0 : _b.id, role: "dialog", ...props2, ref: (0, import_utils.mergeRefs)(popoverRef, ref), style: { ...props2.style, transformOrigin }, tabIndex: -1, onBlur: (0, import_utils.handlerAll)(props2.onBlur, (ev) => { const relatedTarget = (0, import_utils.getEventRelatedTarget)(ev); const targetIsPopover = (0, import_utils.isContains)(popoverRef.current, relatedTarget); const targetIsTrigger = (0, import_utils.isContains)(triggerRef.current, relatedTarget); const targetIsRelated = (relatedRef == null ? void 0 : relatedRef.current) ? (0, import_utils.isContains)(relatedRef.current, relatedTarget) : false; const validBlur = !targetIsPopover && !targetIsTrigger && !targetIsRelated; if (open && closeOnBlur && validBlur) onClose(); }), onKeyDown: (0, import_utils.handlerAll)(props2.onKeyDown, (ev) => { if (closeOnEsc && ev.key === "Escape") onClose(); }) }; if (trigger === "hover") { popoverProps.onMouseEnter = (0, import_utils.handlerAll)(props2.onMouseEnter, () => { hoveringRef.current = true; }); popoverProps.onMouseLeave = (0, import_utils.handlerAll)(props2.onMouseLeave, (ev) => { if (ev.nativeEvent.relatedTarget === null) return; hoveringRef.current = false; if (closeOnBlur) setTimeout(onClose, closeDelay); }); } return popoverProps; }, [ closeDelay, closeOnBlur, closeOnEsc, open, onClose, transformOrigin, trigger, relatedRef, id ] ); const maybeReferenceRef = (0, import_react.useCallback)( (node) => { if (anchorRef.current == null) referenceRef(node); }, [referenceRef] ); const getTriggerProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => { const triggerProps = { "aria-controls": open ? id : void 0, "aria-expanded": open, role: "button", ...props2, ref: (0, import_utils.mergeRefs)(triggerRef, ref, maybeReferenceRef) }; if (trigger === "click") { triggerProps.onClick = (0, import_utils.handlerAll)(props2.onClick, onToggle); triggerProps.onBlur = (0, import_utils.handlerAll)(props2.onBlur, (ev) => { const relatedTarget = (0, import_utils.getEventRelatedTarget)(ev); const validBlur = !(0, import_utils.isContains)(popoverRef.current, relatedTarget); if (open && closeOnBlur && validBlur) onClose(); }); } if (trigger === "contextmenu") { triggerProps.onContextMenu = (0, import_utils.handlerAll)(props2.onContextMenu, (ev) => { ev.preventDefault(); onOpen(); }); triggerProps.onBlur = (0, import_utils.handlerAll)(props2.onBlur, (ev) => { const relatedTarget = (0, import_utils.getEventRelatedTarget)(ev); const validBlur = !(0, import_utils.isContains)(popoverRef.current, relatedTarget); if (open && closeOnBlur && validBlur) onClose(); }); } if (trigger === "hover") { triggerProps.onFocus = (0, import_utils.handlerAll)(props2.onFocus, () => { if (openTimeout.current === void 0) onOpen(); }); triggerProps.onBlur = (0, import_utils.handlerAll)(props2.onBlur, (ev) => { const relatedTarget = (0, import_utils.getEventRelatedTarget)(ev); const validBlur = !(0, import_utils.isContains)(popoverRef.current, relatedTarget); if (open && closeOnBlur && validBlur) onClose(); }); triggerProps.onKeyDown = (0, import_utils.handlerAll)(props2.onKeyDown, (ev) => { if (ev.key === "Escape") onClose(); }); triggerProps.onMouseEnter = (0, import_utils.handlerAll)(props2.onMouseEnter, () => { hoveringRef.current = true; openTimeout.current = window.setTimeout(onOpen, openDelay); }); triggerProps.onMouseLeave = (0, import_utils.handlerAll)(props2.onMouseLeave, () => { hoveringRef.current = false; if (openTimeout.current) { clearTimeout(openTimeout.current); openTimeout.current = void 0; } closeTimeout.current = window.setTimeout(() => { if (!hoveringRef.current) onClose(); }, closeDelay); }); } return triggerProps; }, [ closeDelay, closeOnBlur, open, maybeReferenceRef, onClose, onOpen, onToggle, openDelay, trigger, id ] ); const getAnchorProps = (0, import_react.useCallback)( (props2 = {}, ref = null) => { return { ...props2, ref: (0, import_utils.mergeRefs)(ref, anchorRef, referenceRef) }; }, [anchorRef, referenceRef] ); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( PopoverProvider, { value: { id, animation, bodyRef, closeOnButton, duration, forceUpdate, headerRef, open, shouldRenderContent, styles, getAnchorProps, getPopoverProps, getPopperProps, getTriggerProps, onAnimationComplete, onClose }, children: (0, import_utils.runIfFunc)(children, { forceUpdate, open, onClose }) } ); }; Popover.displayName = "Popover"; Popover.__ui__ = "Popover"; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Popover, popoverProperties, usePopover }); //# sourceMappingURL=popover.js.map