@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
177 lines (173 loc) • 7.12 kB
JavaScript
"use client";
import { useSplitChildren, wrapOrPassProps } from "../../utils/children.js";
import { utils_exports } from "../../utils/index.js";
import { styled } from "../../core/system/factory.js";
import { createSlotComponent } from "../../core/components/create-component.js";
import { motion as motion$1 } from "../motion/factory.js";
import { Portal } from "../portal/portal.js";
import { getPopupAnimationProps } from "../popover/popover.js";
import { Button } from "../button/button.js";
import { CloseButton } from "../close-button/close-button.js";
import { modalStyle } from "./modal.style.js";
import { fadeVariants } from "../fade/fade.js";
import { FocusLock } from "../focus-lock/focus-lock.js";
import { useModal } from "./use-modal.js";
import { useMemo } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { AnimatePresence } from "motion/react";
import { RemoveScroll } from "react-remove-scroll";
//#region src/components/modal/modal.tsx
const { ComponentContext, PropsContext: ModalPropsContext, useComponentContext, usePropsContext: useModalPropsContext, withContext, withProvider } = createSlotComponent("modal", modalStyle);
/**
* `Modal` is a component that is displayed over the main content to focus the user's attention solely on the information.
*
* @see https://yamada-ui.com/docs/components/overlay/modal
*/
const ModalRoot = withProvider(({ allowPinchZoom = false, animationScheme = "scale", autoFocus, blockScrollOnMount = true, body, cancel, children, duration, finalFocusRef, footer, header, initialFocusRef, lockFocusAcrossFrames = true, middle, restoreFocus, success, title, trigger, withCloseButton = true, withOverlay = true, portalProps, onCancel, onCloseComplete, onMiddle, onSuccess,...props }) => {
const [omittedChildren, openTrigger, customOverlay] = useSplitChildren(children, ModalOpenTrigger, ModalOverlay);
const hasChildren = (0, utils_exports.isArray)(omittedChildren) && !!omittedChildren.length;
const { open, getRootProps,...rest } = useModal(props);
const customOpenTrigger = trigger ? /* @__PURE__ */ jsx(ModalOpenTrigger, { children: trigger }) : null;
return /* @__PURE__ */ jsxs(ComponentContext, {
value: useMemo(() => ({
animationScheme,
duration,
open,
withCloseButton,
...rest
}), [
animationScheme,
duration,
open,
withCloseButton,
rest
]),
children: [openTrigger ?? customOpenTrigger, /* @__PURE__ */ jsx(AnimatePresence, {
onExitComplete: onCloseComplete,
children: open ? /* @__PURE__ */ jsx(Portal, {
...portalProps,
children: /* @__PURE__ */ jsx(FocusLock, {
autoFocus,
finalFocusRef,
initialFocusRef,
lockFocusAcrossFrames,
restoreFocus,
children: /* @__PURE__ */ jsx(RemoveScroll, {
allowPinchZoom,
enabled: blockScrollOnMount,
forwardProps: true,
children: /* @__PURE__ */ jsxs(styled.div, {
...getRootProps(),
children: [customOverlay ?? (withOverlay ? /* @__PURE__ */ jsx(ModalOverlay, {}) : null), hasChildren ? omittedChildren : /* @__PURE__ */ jsx(ShorthandModalContent, {
body,
cancel,
footer,
header,
middle,
success,
title,
onCancel,
onMiddle,
onSuccess
})]
})
})
})
}) : null
})]
});
}, "root")();
const ModalOpenTrigger = withContext("button", {
name: "OpenTrigger",
slot: ["trigger", "open"]
})(void 0, (props) => {
const { getOpenTriggerProps } = useComponentContext();
return {
asChild: true,
...getOpenTriggerProps(props)
};
});
const ModalCloseTrigger = withContext("button", {
name: "CloseTrigger",
slot: ["trigger", "close"]
})(void 0, (props) => {
const { getCloseTriggerProps } = useComponentContext();
return {
asChild: true,
...getCloseTriggerProps(props)
};
});
const ModalCloseButton = withContext(CloseButton, "closeButton")(void 0, (props) => {
const { getCloseButtonProps } = useComponentContext();
return { ...getCloseButtonProps(props) };
});
const ModalOverlay = withContext((props) => {
const { animationScheme, duration, getOverlayProps } = useComponentContext();
return /* @__PURE__ */ jsx(motion$1.div, {
custom: { duration },
...animationScheme !== "none" ? {
animate: "enter",
exit: "exit",
initial: "exit",
variants: fadeVariants
} : {},
...(0, utils_exports.cast)(getOverlayProps((0, utils_exports.cast)(props)))
});
}, "overlay")();
const ModalContent = withContext(({ children,...rest }) => {
const { animationScheme, duration, withCloseButton, getContentProps } = useComponentContext();
const [omittedChildren, customCloseButton] = useSplitChildren(children, ModalCloseButton);
return /* @__PURE__ */ jsxs(motion$1.section, {
...getPopupAnimationProps(animationScheme, duration),
...(0, utils_exports.cast)(getContentProps((0, utils_exports.cast)(rest))),
children: [customCloseButton ?? (withCloseButton ? /* @__PURE__ */ jsx(ModalCloseButton, {}) : null), omittedChildren]
});
}, "content")();
const ShorthandModalContent = ({ body, cancel, footer, header, middle, success, title, onCancel, onMiddle, onSuccess }) => {
const { onClose } = useComponentContext();
const customHeader = wrapOrPassProps(ModalHeader, header);
const customTitle = wrapOrPassProps(ModalTitle, title);
const customBody = wrapOrPassProps(ModalBody, body);
const customFooter = wrapOrPassProps(ModalFooter, footer);
const customCancel = wrapOrPassProps(Button, cancel, {
colorScheme: "mono",
variant: "ghost",
onClick: () => onCancel ? onCancel(onClose) : onClose()
});
const customMiddle = wrapOrPassProps(Button, middle, {
colorScheme: "secondary",
onClick: () => onMiddle ? onMiddle(onClose) : onClose()
});
const customSuccess = wrapOrPassProps(Button, success, {
colorScheme: "primary",
onClick: () => onSuccess ? onSuccess(onClose) : onClose()
});
return /* @__PURE__ */ jsxs(ModalContent, { children: [
customHeader ?? (customTitle ? /* @__PURE__ */ jsx(ModalHeader, { children: customTitle }) : null),
customBody,
customFooter ?? (customCancel || customMiddle || customSuccess ? /* @__PURE__ */ jsxs(ModalFooter, { children: [
customCancel,
customMiddle,
customSuccess
] }) : null)
] });
};
const ModalHeader = withContext("header", "header")(void 0, (props) => {
const { getHeaderProps } = useComponentContext();
return { ...getHeaderProps(props) };
});
const ModalTitle = withContext("h2", "title")(void 0, (props) => {
const { getTitleProps } = useComponentContext();
return { ...getTitleProps(props) };
});
const ModalBody = withContext("div", "body")(void 0, (props) => {
const { getBodyProps } = useComponentContext();
return { ...getBodyProps(props) };
});
const ModalFooter = withContext("footer", "footer")(void 0, (props) => {
const { getFooterProps } = useComponentContext();
return { ...getFooterProps(props) };
});
//#endregion
export { ModalBody, ModalCloseButton, ModalCloseTrigger, ModalContent, ModalFooter, ModalHeader, ModalOpenTrigger, ModalOverlay, ModalPropsContext, ModalRoot, ModalTitle, useModalPropsContext };
//# sourceMappingURL=modal.js.map