@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
214 lines (210 loc) • 7.77 kB
JavaScript
"use client";
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
const require_dom = require('../../utils/dom.cjs');
const require_effect = require('../../utils/effect.cjs');
const require_ref = require('../../utils/ref.cjs');
const require_utils_index = require('../../utils/index.cjs');
const require_environment_provider = require('../../core/system/environment-provider.cjs');
const require_props = require('../../core/components/props.cjs');
const require_use_disclosure = require('../../hooks/use-disclosure/use-disclosure.cjs');
const require_hooks_use_event_listener_index = require('../../hooks/use-event-listener/index.cjs');
const require_hooks_use_focus_index = require('../../hooks/use-focus/index.cjs');
const require_hooks_use_outside_click_index = require('../../hooks/use-outside-click/index.cjs');
const require_hooks_use_popper_index = require('../../hooks/use-popper/index.cjs');
let react = require("react");
react = require_rolldown_runtime.__toESM(react);
//#region src/components/popover/use-popover.tsx
const usePopover = ({ autoFocus = true, autoUpdate, modal = false, blockScrollOnMount = modal, closeOnBlur = true, closeOnEsc = true, closeOnScroll, defaultOpen, disabled, elements, flip, gutter, initialFocusRef, matchWidth, middleware, offset, open: openProp, openOnClick = true, placement = "end", platform, preventOverflow, strategy, transferFocus = true, transform, updateRef, whileElementsMounted, onClose: onCloseProp, onOpen: onOpenProp } = {}) => {
const { getDocument } = require_environment_provider.useEnvironment();
const headerId = (0, react.useId)();
const bodyId = (0, react.useId)();
const contentId = (0, react.useId)();
const anchorRef = (0, react.useRef)(null);
const triggerRef = (0, react.useRef)(null);
const contentRef = (0, react.useRef)(null);
const openTimeout = (0, react.useRef)(void 0);
const closeTimeout = (0, react.useRef)(void 0);
const { open, onClose, onOpen } = require_use_disclosure.useDisclosure({
defaultOpen,
open: openProp,
onClose: onCloseProp,
onOpen: onOpenProp
});
const { refs, update, getPopperProps } = require_hooks_use_popper_index.usePopper({
autoUpdate,
elements,
flip,
gutter,
matchWidth,
middleware,
offset,
open,
placement,
platform,
preventOverflow,
strategy,
transform,
whileElementsMounted
});
require_ref.assignRef(updateRef, update);
const onKeyDown = (0, react.useCallback)((ev) => {
require_dom.runKeyAction(ev, { Escape: () => {
if (!closeOnEsc) return;
onClose();
triggerRef.current?.focus();
} });
}, [closeOnEsc, onClose]);
const onBlur = (0, react.useCallback)((ev) => {
const relatedTarget = require_dom.getEventRelatedTarget(ev);
const popup = relatedTarget?.hasAttribute("data-popup");
if ((0, require_utils_index.utils_exports.contains)(triggerRef.current, relatedTarget)) return;
if ((0, require_utils_index.utils_exports.contains)(contentRef.current, relatedTarget)) return;
if ((0, require_utils_index.utils_exports.contains)(contentRef.current, ev.target) && popup) return;
if (closeOnBlur) onClose();
}, [closeOnBlur, onClose]);
require_hooks_use_event_listener_index.useEventListener(getDocument(), "scroll", () => {
if (open && closeOnScroll) onClose();
});
require_hooks_use_focus_index.useFocusOnShow(contentRef, {
focusTarget: initialFocusRef,
shouldFocus: autoFocus,
visible: open
});
require_hooks_use_outside_click_index.useOutsideClick({
ref: [contentRef, triggerRef],
enabled: open && closeOnBlur,
handler: onClose
});
require_effect.useSafeLayoutEffect(() => {
const el = contentRef.current;
const hasHeader = !!getDocument()?.getElementById(headerId);
const hasBody = !!getDocument()?.getElementById(bodyId);
if (el && hasHeader) (0, require_utils_index.utils_exports.setAttribute)(el, "aria-labelledby", headerId);
if (el && hasBody) (0, require_utils_index.utils_exports.setAttribute)(el, "aria-describedby", bodyId);
}, [
open,
headerId,
bodyId
]);
(0, react.useEffect)(() => {
if (!open || !modal) return;
return (0, require_utils_index.utils_exports.focusTrap)(contentRef.current);
}, [open, modal]);
(0, react.useEffect)(() => {
if (!open || !blockScrollOnMount) return;
return (0, require_utils_index.utils_exports.scrollLock)(contentRef.current);
}, [
open,
modal,
blockScrollOnMount
]);
(0, react.useEffect)(() => {
if (!open || modal || !transferFocus) return;
return (0, require_utils_index.utils_exports.focusTransfer)(contentRef.current, triggerRef.current);
}, [
open,
modal,
transferFocus
]);
require_effect.useUnmountEffect(() => {
clearTimeout(openTimeout.current);
clearTimeout(closeTimeout.current);
});
const getTriggerProps = (0, react.useCallback)(({ ref,...props } = {}) => ({
"aria-controls": open ? contentId : void 0,
"aria-disabled": (0, require_utils_index.utils_exports.ariaAttr)(disabled),
"aria-expanded": open,
"aria-haspopup": "dialog",
role: "button",
...props,
ref: require_ref.mergeRefs(ref, triggerRef, (node) => {
if (anchorRef.current == null) refs.setReference(node);
}),
onBlur: (0, require_utils_index.utils_exports.handlerAll)(props.onBlur, (ev) => !(0, require_utils_index.utils_exports.contains)(contentRef.current, require_dom.getEventRelatedTarget(ev)) && closeOnBlur ? onClose() : void 0),
onClick: (0, require_utils_index.utils_exports.handlerAll)(props.onClick, !open ? !disabled && openOnClick ? onOpen : void 0 : onClose),
onKeyDown: (0, require_utils_index.utils_exports.handlerAll)(props.onKeyDown, onKeyDown)
}), [
closeOnBlur,
contentId,
disabled,
onClose,
onKeyDown,
onOpen,
open,
openOnClick,
refs
]);
const getAnchorProps = (0, react.useCallback)(({ ref,...props } = {}) => ({
...props,
ref: require_ref.mergeRefs(ref, anchorRef, refs.setReference)
}), [refs.setReference]);
const getPositionerProps = (0, react.useCallback)((props) => {
return getPopperProps(props);
}, [getPopperProps]);
const getContentProps = (0, react.useCallback)(({ ref,...props } = {}) => ({
id: contentId,
"aria-hidden": !open,
"aria-modal": modal ? "true" : void 0,
"data-close": (0, require_utils_index.utils_exports.dataAttr)(!open),
"data-open": (0, require_utils_index.utils_exports.dataAttr)(open),
"data-popup": (0, require_utils_index.utils_exports.dataAttr)(true),
role: "dialog",
tabIndex: -1,
...props,
ref: require_ref.mergeRefs(ref, contentRef),
onBlur: (0, require_utils_index.utils_exports.handlerAll)(props.onBlur, onBlur),
onKeyDown: (0, require_utils_index.utils_exports.handlerAll)(props.onKeyDown, onKeyDown)
}), [
contentId,
open,
modal,
onBlur,
onKeyDown
]);
const getHeaderProps = (0, react.useCallback)((props) => ({
id: headerId,
...props
}), [headerId]);
return {
open,
getAnchorProps,
getBodyProps: (0, react.useCallback)((props) => ({
id: bodyId,
...props
}), [bodyId]),
getContentProps,
getFooterProps: (0, react.useCallback)((props) => ({ ...props }), []),
getHeaderProps,
getPositionerProps,
getTriggerProps,
onClose,
onOpen
};
};
const popoverProps = [
...require_hooks_use_popper_index.popperProps,
"autoFocus",
"transferFocus",
"blockScrollOnMount",
"closeOnBlur",
"closeOnEsc",
"closeOnScroll",
"openOnClick",
"disabled",
"initialFocusRef",
"modal",
"updateRef",
"defaultOpen",
"onOpen",
"onClose",
"animationScheme",
"duration"
];
const usePopoverProps = (props, omitKeys) => {
return require_props.useSplitProps(props, popoverProps.filter((key) => !omitKeys?.includes(key)));
};
//#endregion
exports.popoverProps = popoverProps;
exports.usePopover = usePopover;
exports.usePopoverProps = usePopoverProps;
//# sourceMappingURL=use-popover.cjs.map