UNPKG

one

Version:

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

135 lines (134 loc) 4.51 kB
import { LinkingContext, useNavigationBuilder } from "@react-navigation/native"; import { Children, Fragment, isValidElement, use, useMemo, useRef } from "react"; import { useRouteInfo } from "../hooks.mjs"; import { resolveHref } from "../link/href.mjs"; import { useContextKey, useRouteNode } from "../router/Route.mjs"; import { shouldLinkExternally } from "../utils/url.mjs"; import { NavigatorContext } from "../views/Navigator.mjs"; import { triggersToScreens } from "./common.mjs"; import { TabTriggerMapContext } from "./TabContext.mjs"; import { isTabList } from "./TabList.mjs"; import { ExpoTabRouter } from "./TabRouter.mjs"; import { isTabSlot } from "./TabSlot.mjs"; import { isTabTrigger } from "./TabTrigger.mjs"; import { useComponent } from "./useComponent.mjs"; import { jsx } from "react/jsx-runtime"; function useTabsWithChildren(options) { const { children, ...rest } = options; return useTabsWithTriggers({ triggers: parseTriggersFromChildren(children), ...rest }); } function useTabsWithTriggers(options) { const { triggers, ...rest } = options; const parentTriggerMap = use(TabTriggerMapContext); const routeNode = useRouteNode(); const contextKey = useContextKey(); const linking = use(LinkingContext).options; const routeInfo = useRouteInfo(); if (!routeNode || !linking) { throw new Error("No RouteNode. This is likely a bug in one router."); } const { children, triggerMap } = triggersToScreens(triggers, routeNode, linking, routeNode.initialRouteName, parentTriggerMap, routeInfo, contextKey); const navigatorContext = useNavigationBuilder(ExpoTabRouter, { children, ...rest, triggerMap, id: contextKey, initialRouteName: routeNode.initialRouteName }); const { state, descriptors, navigation, describe, NavigationContent: RNNavigationContent } = navigatorContext; const descriptorsRef = useRef(descriptors); descriptorsRef.current = descriptors; const navigatorContextValue = useMemo(() => ({ state, navigation, contextKey, router: ExpoTabRouter, descriptorsRef }), [state, navigation, contextKey]); const NavigationContent = useComponent(children2 => /* @__PURE__ */jsx(TabTriggerMapContext.Provider, { value: triggerMap, children: /* @__PURE__ */jsx(NavigatorContext.Provider, { value: navigatorContextValue, children: /* @__PURE__ */jsx(RNNavigationContent, { children: children2 }) }) })); return { state, descriptors, navigation, NavigationContent, describe }; } function parseTriggersFromChildren(children, screenTriggers = [], isInTabList = false) { Children.forEach(children, child => { if (!child || !isValidElement(child) || isTabSlot(child)) return; if (isFragment(child) && typeof child.props.children !== "function") { return parseTriggersFromChildren(child.props.children, screenTriggers, isInTabList || isTabList(child)); } if (isTabList(child) && typeof child.props.children !== "function") { let children2 = child.props.children; if (child.props.asChild && isValidElement(children2) && children2.props && typeof children2.props === "object" && "children" in children2.props) { children2 = children2.props.children; } return parseTriggersFromChildren(children2, screenTriggers, isInTabList || isTabList(child)); } if (!isInTabList || !isTabTrigger(child)) return; const { href, name } = child.props; if (!href) { if (process.env.NODE_ENV === "development") { console.warn(`<TabTrigger name={${name}}> does not have a 'href' prop. TabTriggers within a <TabList /> are required to have an href.`); } return; } const resolvedHref = resolveHref(href); if (shouldLinkExternally(resolvedHref)) { screenTriggers.push({ type: "external", name, href: resolvedHref }); return; } if (!name) { if (process.env.NODE_ENV === "development") { console.warn(`<TabTrigger> does not have a 'name' prop. TabTriggers within a <TabList /> are required to have a name.`); } return; } screenTriggers.push({ type: "internal", href: resolvedHref, name }); }); return screenTriggers; } function isFragment(child) { return child.type === Fragment; } export { useTabsWithChildren, useTabsWithTriggers }; //# sourceMappingURL=Tabs.shared.mjs.map