UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

157 lines (153 loc) 4.93 kB
"use client"; import { useUpdateEffect } from "../../utils/effect.js"; import { assignRef } from "../../utils/ref.js"; import { utils_exports } from "../../utils/index.js"; import { Portal } from "../portal/portal.js"; import { Background } from "./background.js"; import { Page } from "./page.js"; import { Screen } from "./screen.js"; import { createContext, createRef, use, useMemo, useRef, useState } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; import { AnimatePresence } from "motion/react"; import { RemoveScroll } from "react-remove-scroll"; //#region src/components/loading/loading-provider.tsx const LoadingContext = createContext({}); const createController = () => ({ finish: createRef(), force: createRef(), start: createRef(), update: createRef() }); const createMethods = (refs) => ({ finish: () => refs.current.finish.current?.(), force: (state) => refs.current.force.current?.(state), start: (props) => refs.current.start.current?.(props), update: (props) => refs.current.update.current?.(props) }); const incrementCount = (prev) => prev + 1; const decrementCount = (prev) => prev === 0 ? prev : prev - 1; const LoadingProvider = ({ background: backgroundConfig, children, page: pageConfig, screen: screenConfig }) => { const screen = useRef(createController()); const page = useRef(createController()); const background = useRef(createController()); return /* @__PURE__ */ jsxs(LoadingContext, { value: useMemo(() => ({ background: createMethods(background), page: createMethods(page), screen: createMethods(screen) }), []), children: [ children, /* @__PURE__ */ jsx(Controller, { ref: screen, ...screenConfig, component: Screen }), /* @__PURE__ */ jsx(Controller, { ref: page, ...pageConfig, component: Page }), /* @__PURE__ */ jsx(Controller, { ref: background, ...backgroundConfig, blockScrollOnMount: backgroundConfig?.blockScrollOnMount ?? false, component: Background }) ] }); }; const Controller = ({ ref, allowPinchZoom = false, blockScrollOnMount = true, component: Component, duration: durationProp = null, loadingCount: loadingCountProp = 0, loadingScheme: loadingSchemeProp = "oval" }) => { const loading = useRef(false); const [{ duration, loadingCount, loadingScheme, message }, setState] = useState({ duration: durationProp, loadingCount: loadingCountProp, loadingScheme: loadingSchemeProp, message: void 0 }); const { finish, force, start, update } = useMemo(() => ({ finish: () => { loading.current = false; setState(({ loadingCount: loadingCount$1 }) => ({ duration: durationProp, loadingCount: decrementCount(loadingCount$1), loadingScheme: loadingSchemeProp, message: void 0 })); }, force: ({ duration: duration$1 = durationProp, loadingCount: loadingCount$1 = 0, loadingScheme: loadingScheme$1 = loadingSchemeProp, message: message$1 }) => { loading.current = !!loadingCount$1; setState({ duration: duration$1, loadingCount: loadingCount$1, loadingScheme: loadingScheme$1, message: message$1 }); }, start: ({ duration: duration$1 = durationProp, loadingScheme: loadingScheme$1 = loadingSchemeProp, message: message$1 } = {}) => { loading.current = true; setState(({ loadingCount: loadingCount$1 }) => ({ duration: duration$1, loadingCount: incrementCount(loadingCount$1), loadingScheme: loadingScheme$1, message: message$1 })); }, update: (next) => setState((prev) => ({ ...prev, ...next })) }), [durationProp, loadingSchemeProp]); assignRef(ref.current.start, start); assignRef(ref.current.finish, finish); assignRef(ref.current.update, update); assignRef(ref.current.force, force); const props = { duration, initial: loadingCountProp > 0 ? false : "initial", loadingScheme, message, onFinish: finish }; useUpdateEffect(() => { if (loadingCountProp > 0 || (0, utils_exports.isNumber)(durationProp)) setState({ duration: durationProp, loadingCount: loadingCountProp, loadingScheme: loadingSchemeProp, message: void 0 }); }, [ loadingCountProp, durationProp, loadingSchemeProp ]); return /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: loadingCount ? /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(RemoveScroll, { allowPinchZoom, enabled: blockScrollOnMount, forwardProps: true, children: /* @__PURE__ */ jsx(Component, { ...props }) }) }) : null }); }; /** * `useLoading` is a custom hook for controlling the loading of the application. * * @see https://yamada-ui.com/docs/hooks/use-loading */ const useLoading = () => { const { background, page, screen } = use(LoadingContext); return useMemo(() => ({ background, page, screen }), [ background, page, screen ]); }; //#endregion export { LoadingProvider, useLoading }; //# sourceMappingURL=loading-provider.js.map