UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

152 lines (150 loc) 6.64 kB
import { jsx as _jsx } from "react/jsx-runtime"; import React from "react"; import { getContextKey, stripInvisibleSegmentsFromPath } from "../router/matchers.native.js"; import { useContextKey, useRouteNode } from "../router/Route.native.js"; import { registerProtectedRoutes, replace, resolveProtectedHref, routeInfo, unregisterProtectedRoutes } from "../router/router.native.js"; import { useSortedScreens } from "../router/useScreens.native.js"; import { sortRoutesWithInitial } from "../router/sortRoutes.native.js"; import { withStaticProperties } from "../utils/withStaticProperties.native.js"; import { isProtectedElement } from "../views/Protected.native.js"; import { Screen } from "../views/Screen.native.js"; import { StackScreen } from "./stack-utils/StackScreen.native.js"; function _type_of(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } function useFilterScreenChildren(children) { var { isCustomNavigator, contextKey } = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : (/** Used for sending developer hints */ {}); return React.useMemo(function () { var customChildren = []; var screens = []; var protectedScreens = /* @__PURE__ */new Set(); var guardedRedirects = /* @__PURE__ */new Map(); function flattenChild(child) { var exclude = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false, redirectTo = arguments.length > 2 ? arguments[2] : void 0; if (/* @__PURE__ */React.isValidElement(child) && (child.type === Screen || child.type === StackScreen)) { if (_type_of(child.props) === "object" && child.props && "name" in child.props && !child.props.name) { throw new Error(`<Screen /> component in \`default export\` at \`app${contextKey}/_layout\` must have a \`name\` prop when used as a child of a Layout Route.`); } if (process.env.NODE_ENV !== "production") { if (["children", "component", "getComponent"].some(function (key) { return child.props && _type_of(child.props) === "object" && key in child.props; })) { throw new Error(`<Screen /> component in \`default export\` at \`app${contextKey}/_layout\` must not have a \`children\`, \`component\`, or \`getComponent\` prop when used as a child of a Layout Route`); } } var screenProps = child.props; if (exclude && screenProps.name) { protectedScreens.add(screenProps.name); guardedRedirects.set(screenProps.name, redirectTo); } else { screens.push(screenProps); } return; } if (isProtectedElement(child)) { var guardFails = !child.props.guard; var excludeChildren = exclude || guardFails; var childRedirectTo = guardFails ? child.props.redirectTo : redirectTo; React.Children.forEach(child.props.children, function (nested) { flattenChild(nested, excludeChildren, childRedirectTo); }); return; } if (isCustomNavigator) { customChildren.push(child); } else if (child != null && process.env.NODE_ENV === "development") { console.warn(`[one] a non-<Screen> child of the navigator at "app${contextKey}/_layout" renders on web only. On native this navigator is drawn by react-navigation and the child is ignored.`); } } React.Children.forEach(children, function (child) { return flattenChild(child); }); if (process.env.NODE_ENV !== "production") { var names = screens.map(function (screen) { return screen.name; }); if (names && new Set(names).size !== names.length) { throw new Error("Screen names must be unique: " + names); } } return { screens, children: customChildren, protectedScreens, guardedRedirects }; }, [children, contextKey, isCustomNavigator]); } function useResolvedGuardedRedirects(guardedRedirects) { var node = useRouteNode(); return React.useMemo(function () { if (!node) { return guardedRedirects; } var defaultRoute = [...node.children].sort(sortRoutesWithInitial(node.initialRouteName)).find(function (child) { var normalized = child.route.replace(/\/index$/, ""); return !(guardedRedirects.has(child.route) || guardedRedirects.has(normalized)); }); var defaultHref = defaultRoute ? stripInvisibleSegmentsFromPath(getContextKey(defaultRoute.contextKey)) || "/" : void 0; return new Map(Array.from(guardedRedirects, function (param) { var [name, redirectTo] = param; return [name, redirectTo !== null && redirectTo !== void 0 ? redirectTo : defaultHref]; })); }, [guardedRedirects, node]); } function withLayoutContext(Nav, processor, options) { return withStaticProperties(/* @__PURE__ */React.forwardRef(function (propsIn, ref) { var { children, ...props } = propsIn; var contextKey = useContextKey(); var { screens, protectedScreens, guardedRedirects } = useFilterScreenChildren(children, { contextKey }); var resolvedGuardedRedirects = useResolvedGuardedRedirects(guardedRedirects); registerProtectedRoutes(contextKey, resolvedGuardedRedirects); var currentPathname = routeInfo === null || routeInfo === void 0 ? void 0 : routeInfo.pathname; var protectedHref = currentPathname ? resolveProtectedHref(currentPathname) : currentPathname; React.useEffect(function () { registerProtectedRoutes(contextKey, resolvedGuardedRedirects); return function () { unregisterProtectedRoutes(contextKey); }; }, [contextKey, resolvedGuardedRedirects]); React.useEffect(function () { if (currentPathname && protectedHref && protectedHref !== currentPathname) { replace(protectedHref); } }, [currentPathname, protectedHref]); var processed = processor ? processor(screens !== null && screens !== void 0 ? screens : []) : screens; var sorted = useSortedScreens(processed !== null && processed !== void 0 ? processed : [], { onlyMatching: true, protectedScreens }); if (!sorted.length) { return null; } return /* @__PURE__ */_jsx(Nav, { ...(options === null || options === void 0 ? void 0 : options.props), ...props, id: contextKey, ref, children: sorted }); }), { Screen }); } export { useFilterScreenChildren, useResolvedGuardedRedirects, withLayoutContext }; //# sourceMappingURL=withLayoutContext.native.js.map