one
Version:
One is a new React Framework that makes Vite serve both native and web.
172 lines (171 loc) • 5.47 kB
JavaScript
import { LinkingContext, useNavigationBuilder } from "@react-navigation/native";
import { Children, Fragment, isValidElement, use, useMemo, useRef } from "react";
import { StyleSheet, View } from "react-native-web";
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, ViewSlot } 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";
export * from "./TabContext.mjs";
export * from "./TabList.mjs";
export * from "./TabSlot.mjs";
export * from "./TabTrigger.mjs";
import { jsx } from "react/jsx-runtime";
function Tabs(props) {
const {
children,
asChild,
options,
...rest
} = props;
const Comp = asChild ? ViewSlot : View;
const {
NavigationContent
} = useTabsWithChildren({
// asChild adds an extra layer, so we need to process the child's children
children: asChild && isValidElement(children) && children.props && typeof children.props === "object" && "children" in children.props ? children.props.children : children,
...options
});
return /* @__PURE__ */jsx(Comp, {
style: styles.tabsRoot,
...rest,
children: /* @__PURE__ */jsx(NavigationContent, {
children
})
});
}
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 initialRouteName = routeNode.initialRouteName;
const {
children,
triggerMap
} = triggersToScreens(triggers, routeNode, linking, initialRouteName, parentTriggerMap, routeInfo, contextKey);
const navigatorContext = useNavigationBuilder(ExpoTabRouter, {
children,
...rest,
triggerMap,
id: contextKey,
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, ExpoTabRouter]);
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)) {
return screenTriggers.push({
type: "external",
name,
href: resolvedHref
});
}
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;
}
return screenTriggers.push({
type: "internal",
href: resolvedHref,
name
});
});
return screenTriggers;
}
function isFragment(child) {
return child.type === Fragment;
}
const styles = StyleSheet.create({
tabsRoot: {
flex: 1
}
});
export { Tabs, useTabsWithChildren, useTabsWithTriggers };
//# sourceMappingURL=Tabs.mjs.map