UNPKG

@yamada-ui/loading

Version:

Yamada UI loading components

393 lines (391 loc) • 12 kB
"use client" import { Loading } from "./chunk-FS4WFG6W.mjs"; // src/loading-provider.tsx import { forwardRef, memo, ui } from "@yamada-ui/core"; import { AnimatePresence, motion } from "@yamada-ui/motion"; import { Portal } from "@yamada-ui/portal"; import { useTimeout } from "@yamada-ui/use-timeout"; import { assignRef, isNumber, isValidElement, useUpdateEffect } from "@yamada-ui/utils"; import { createContext, createRef, useContext, useMemo, useRef, useState } from "react"; import { RemoveScroll } from "react-remove-scroll"; import { jsx, jsxs } from "react/jsx-runtime"; var LoadingContext = createContext({}); var createLoadingRefs = () => ({ finish: createRef(), force: createRef(), isLoading: createRef(), start: createRef(), update: createRef() }); var createLoadingFunc = (refs) => ({ finish: () => { var _a, _b; return (_b = (_a = refs.current.finish).current) == null ? void 0 : _b.call(_a); }, force: (state) => { var _a, _b; return (_b = (_a = refs.current.force).current) == null ? void 0 : _b.call(_a, state); }, isLoading: () => { var _a, _b, _c; return (_c = (_b = (_a = refs.current.isLoading).current) == null ? void 0 : _b.call(_a)) != null ? _c : false; }, start: (props) => { var _a, _b; return (_b = (_a = refs.current.start).current) == null ? void 0 : _b.call(_a, props); }, update: (props) => { var _a, _b; return (_b = (_a = refs.current.update).current) == null ? void 0 : _b.call(_a, props); } }); var incrementCount = (prev) => prev + 1; var decrementCount = (prev) => prev === 0 ? prev : prev - 1; var LoadingProvider = ({ background, children, custom, page, screen }) => { var _a, _b, _c, _d, _e; const screenRefs = useRef(createLoadingRefs()); const pageRefs = useRef(createLoadingRefs()); const backgroundRefs = useRef(createLoadingRefs()); const customRefs = useRef(createLoadingRefs()); const screenLoadingFunc = createLoadingFunc(screenRefs); const pageLoadingFunc = createLoadingFunc(pageRefs); const backgroundLoadingFunc = createLoadingFunc(backgroundRefs); const customLoadingFunc = createLoadingFunc(customRefs); const value = { background: backgroundLoadingFunc, custom: customLoadingFunc, page: pageLoadingFunc, screen: screenLoadingFunc }; return /* @__PURE__ */ jsxs(LoadingContext.Provider, { value, children: [ children, /* @__PURE__ */ jsx( Controller, { controlRefs: screenRefs, ...screen, component: (_a = screen == null ? void 0 : screen.component) != null ? _a : (props, ref) => /* @__PURE__ */ jsx(ScreenComponent, { ref, ...props }) } ), /* @__PURE__ */ jsx( Controller, { controlRefs: pageRefs, ...page, component: (_b = page == null ? void 0 : page.component) != null ? _b : (props, ref) => /* @__PURE__ */ jsx(PageComponent, { ref, ...props }) } ), /* @__PURE__ */ jsx( Controller, { controlRefs: backgroundRefs, ...background, blockScrollOnMount: (_c = background == null ? void 0 : background.blockScrollOnMount) != null ? _c : false, component: (_d = background == null ? void 0 : background.component) != null ? _d : (props, ref) => /* @__PURE__ */ jsx(BackgroundComponent, { ref, ...props }) } ), /* @__PURE__ */ jsx( Controller, { blockScrollOnMount: (_e = background == null ? void 0 : background.blockScrollOnMount) != null ? _e : false, controlRefs: customRefs, ...custom, component: custom == null ? void 0 : custom.component } ) ] }); }; LoadingProvider.__ui__ = "LoadingProvider"; var Controller = ({ allowPinchZoom = false, appendToParentPortal, blockScrollOnMount = true, component, containerRef, controlRefs, duration: durationProps = null, icon, initialState, text }) => { const isLoadingRef = useRef(false); const [{ duration, loadingCount, message }, setState] = useState({ duration: durationProps, loadingCount: initialState ? 1 : 0, message: void 0 }); const { finish, force, isLoading, start, update } = useMemo( () => ({ finish: () => { isLoadingRef.current = false; setState(({ loadingCount: loadingCount2 }) => ({ duration: durationProps, loadingCount: decrementCount(loadingCount2), message: void 0 })); }, force: ({ duration: duration2 = durationProps, loadingCount: loadingCount2 = 0, message: message2 }) => { isLoadingRef.current = !!loadingCount2; setState({ duration: duration2, loadingCount: loadingCount2, message: message2 }); }, isLoading: () => isLoadingRef.current, start: ({ duration: duration2 = durationProps, message: message2 } = {}) => { isLoadingRef.current = true; setState(({ loadingCount: loadingCount2 }) => ({ duration: duration2, loadingCount: incrementCount(loadingCount2), message: message2 })); }, update: (next) => setState((prev) => ({ ...prev, ...next })) }), [durationProps] ); assignRef(controlRefs.current.isLoading, isLoading); assignRef(controlRefs.current.start, start); assignRef(controlRefs.current.finish, finish); assignRef(controlRefs.current.update, update); assignRef(controlRefs.current.force, force); const props = { duration, icon, initialState, message, text, onFinish: finish }; useUpdateEffect(() => { if (initialState || isNumber(durationProps)) setState({ duration: durationProps, loadingCount: initialState ? 1 : 0, message: void 0 }); }, [initialState, durationProps]); return /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: loadingCount ? /* @__PURE__ */ jsx( Portal, { appendToParentPortal, containerRef, children: /* @__PURE__ */ jsx( RemoveScroll, { allowPinchZoom, enabled: blockScrollOnMount, forwardProps: true, children: /* @__PURE__ */ jsx(Render, { component, ...props }) } ) } ) : null }); }; Controller.__ui__ = "Controller"; var Render = forwardRef( ({ component, ...props }, ref) => { if (typeof component === "function") { return component(props, ref); } else { return null; } } ); Render.displayName = "Render"; Render.__ui__ = "Render"; var Message = ({ message, ...rest }) => { return message ? isValidElement(message) ? message : /* @__PURE__ */ jsx(ui.p, { ...rest, children: message }) : null; }; var getVariants = (type = "fade") => ({ animate: { opacity: 1, scale: type === "scaleFade" ? 1 : void 0, transition: { duration: 0.4, ease: [0.4, 0, 0.2, 1] } }, exit: { opacity: 0, scale: type === "scaleFade" ? 0.95 : void 0, transition: { duration: 0.4, ease: [0.4, 0, 1, 1] } }, initial: { opacity: 0, scale: type === "scaleFade" ? 0.95 : void 0 } }); var getOverlayStyle = (type = "fill") => ({ alignItems: "center", bg: type === "fill" ? ["fallback(white, #fbfbfb)", "fallback(black, #141414)"] : "fallback(blackAlpha.600, rgba(0, 0, 0, 0.48))", bottom: 0, display: "flex", h: "100dvh", justifyContent: "center", left: 0, p: "fallback(4, 1rem)", position: "fixed", right: 0, top: 0, w: "100vw", zIndex: "fallback(beerus, 9999)" }); var getMotionProps = (initialState, type = "fade") => ({ animate: "animate", exit: "exit", initial: initialState ? false : "initial", variants: getVariants(type) }); var ScreenComponent = memo( forwardRef( ({ duration, icon, initialState, message, text, onFinish }, ref) => { const css = { alignItems: "center", display: "flex", flexDirection: "column", gap: "fallback(2, 0.5rem)", justifyContent: "center", maxW: "24rem" }; useTimeout(onFinish, duration); return /* @__PURE__ */ jsx( motion.div, { ref, className: "ui-loading-screen", ...getMotionProps(initialState), __css: getOverlayStyle(), children: /* @__PURE__ */ jsxs(ui.div, { __css: css, children: [ /* @__PURE__ */ jsx(Loading, { fontSize: "6xl", ...icon }), /* @__PURE__ */ jsx(Message, { lineClamp: 3, message, ...text }) ] }) } ); } ) ); ScreenComponent.displayName = "ScreenComponent"; ScreenComponent.__ui__ = "ScreenComponent"; var PageComponent = memo( forwardRef( ({ duration, icon, initialState, message, text, onFinish }, ref) => { const css = { alignItems: "center", bg: ["fallback(white, #fbfbfb)", "fallback(black, #141414)"], boxShadow: [ "fallback(lg, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05))", "fallback(dark-lg, 0px 0px 0px 1px rgba(0, 0, 0, 0.1), 0px 5px 10px rgba(0, 0, 0, 0.2), 0px 15px 40px rgba(0, 0, 0, 0.4))" ], display: "flex", flexDirection: "column", gap: "fallback(2, 0.5rem)", justifyContent: "center", maxW: "24rem", p: "fallback(4, 1rem)", rounded: "fallback(md, 0.375rem)" }; useTimeout(onFinish, duration); return /* @__PURE__ */ jsx( motion.div, { ref, className: "ui-loading-page", ...getMotionProps(initialState), __css: getOverlayStyle("transparent"), children: /* @__PURE__ */ jsxs( motion.div, { className: "ui-loading-page__inner", ...getMotionProps(initialState, "scaleFade"), __css: css, children: [ /* @__PURE__ */ jsx(Loading, { fontSize: "6xl", ...icon }), /* @__PURE__ */ jsx(Message, { lineClamp: 3, message, ...text }) ] } ) } ); } ) ); PageComponent.displayName = "PageComponent"; PageComponent.__ui__ = "PageComponent"; var BackgroundComponent = memo( forwardRef( ({ duration, icon, initialState, message, text, onFinish }, ref) => { const css = { alignItems: "center", bg: ["fallback(white, #fbfbfb)", "fallback(black, #141414)"], bottom: "fallback(4, 1rem)", boxShadow: [ "fallback(3xl, 0 25px 50px -12px rgba(0, 0, 0, 0.25), 0 -25px 50px -12px rgba(0, 0, 0, 0.25))", "fallback(dark-lg, 0px 0px 0px 1px rgba(0, 0, 0, 0.1), 0px 5px 10px rgba(0, 0, 0, 0.2), 0px 15px 40px rgba(0, 0, 0, 0.4))" ], display: "flex", gap: "fallback(2, 0.5rem)", justifyContent: "center", maxW: "20rem", p: "fallback(2, 0.5rem)", position: "fixed", right: "fallback(4, 1rem)", rounded: "fallback(md, 0.375rem)", zIndex: "fallback(beerus, 9999)" }; useTimeout(onFinish, duration); return /* @__PURE__ */ jsxs( motion.div, { ref, className: "ui-loading-background", ...getMotionProps(initialState, "scaleFade"), __css: css, children: [ /* @__PURE__ */ jsx(Loading, { fontSize: "xl", ...icon }), /* @__PURE__ */ jsx(Message, { fontSize: "sm", lineClamp: 1, message, ...text }) ] } ); } ) ); BackgroundComponent.displayName = "BackgroundComponent"; BackgroundComponent.__ui__ = "BackgroundComponent"; var useLoading = () => { const { background, custom, page, screen } = useContext(LoadingContext); const context = useMemo( () => ({ background, custom, page, screen }), [background, custom, page, screen] ); return context; }; export { LoadingProvider, useLoading }; //# sourceMappingURL=chunk-W3VLBPVB.mjs.map