one
Version:
One is a new React Framework that makes Vite serve both native and web.
210 lines • 7.49 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
value: true
}), mod);
var common_exports = {};
__export(common_exports, {
ViewSlot: () => ViewSlot,
stateToAction: () => stateToAction,
triggersToScreens: () => triggersToScreens
});
module.exports = __toCommonJS(common_exports);
var import_href = require("../link/href.cjs");
var import_sortRoutes = require("../router/sortRoutes.cjs");
var import_useScreens = require("../router/useScreens.cjs");
var import_Slot = require("./Slot.cjs");
var import_jsx_runtime = require("react/jsx-runtime");
const ViewSlot = import_Slot.Slot;
function resolveHrefWithSegments(href, routeInfo, segmentsWithoutGroups) {
if (href.startsWith("./") || href.startsWith("../")) {
const basePath = "/" + segmentsWithoutGroups.join("/");
const baseDir = basePath.replace(/\/[^/]*$/, "") || "/";
const parts = (baseDir + "/" + href).split("/");
const resolved = [];
for (const part of parts) {
if (part === "." || part === "") continue;
if (part === "..") {
resolved.pop();
} else {
resolved.push(part);
}
}
return "/" + resolved.join("/");
}
return href;
}
function triggersToScreens(triggers, layoutRouteNode, linking, initialRouteName, parentTriggerMap, routeInfo, contextKey) {
const configs = [];
for (const trigger of triggers) {
if (trigger.name in parentTriggerMap) {
const parentTrigger = parentTriggerMap[trigger.name];
throw new Error(`Trigger ${JSON.stringify({
name: trigger.name,
href: trigger.href
})} has the same name as parent trigger ${JSON.stringify({
name: parentTrigger.name,
href: parentTrigger.href
})}. Triggers must have unique names.`);
}
if (trigger.type === "external") {
configs.push(trigger);
continue;
}
let resolvedHref = (0, import_href.resolveHref)(trigger.href);
if (resolvedHref.startsWith("../")) {
throw new Error("Trigger href cannot link to a parent directory");
}
const segmentsWithoutGroups = contextKey.split("/").filter(segment => {
return !(segment.startsWith("(") && segment.endsWith(")"));
});
resolvedHref = resolveHrefWithSegments(resolvedHref, routeInfo, segmentsWithoutGroups);
let state = linking.getStateFromPath?.(resolvedHref, linking.config)?.routes[0];
if (!state) {
console.warn(`Unable to find screen for trigger ${JSON.stringify(trigger)}. Does this point to a valid screen?`);
continue;
}
let routeState = state;
if (routeState.name === "+not-found") {
if (process.env.NODE_ENV !== "production") {
console.warn(`Tab trigger '${trigger.name}' has the href '${trigger.href}' which points to a +not-found route.`);
}
continue;
}
const targetStateName = layoutRouteNode.route || "__root";
while (state?.state) {
if (state.name === targetStateName) break;
state = state.state.routes[state.state.index ?? state.state.routes.length - 1];
}
routeState = state.state?.routes[state.state.index ?? state.state.routes.length - 1] || state;
const routeNode = layoutRouteNode.children.find(child => child.route === routeState?.name);
if (!routeNode) {
console.warn(`Unable to find routeNode for trigger ${JSON.stringify(trigger)}. This might be a bug in One router`);
continue;
}
const duplicateTrigger = trigger.type === "internal" && configs.find(config => {
if (config.type === "external") {
return false;
}
return config.routeNode.route === routeNode.route;
});
if (duplicateTrigger) {
const duplicateTriggerText = `${JSON.stringify({
name: duplicateTrigger.name,
href: duplicateTrigger.href
})} and ${JSON.stringify({
name: trigger.name,
href: trigger.href
})}`;
throw new Error(`A navigator cannot contain multiple trigger components that map to the same sub-segment. Consider adding a shared group and assigning a group to each trigger. Conflicting triggers:
${duplicateTriggerText}.
Both triggers map to route ${routeNode.route}.`);
}
configs.push({
...trigger,
href: resolvedHref,
routeNode,
action: stateToAction(state, layoutRouteNode.route)
});
}
const sortFn = (0, import_sortRoutes.sortRoutesWithInitial)(initialRouteName);
const sortedConfigs = configs.sort((a, b) => {
if (a.type === "external" && b.type === "external") {
return 0;
} else if (a.type === "external") {
return 1;
} else if (b.type === "external") {
return -1;
}
return sortFn(a.routeNode, b.routeNode);
});
const children = [];
const triggerMap = {
...parentTriggerMap
};
for (const [index, config] of sortedConfigs.entries()) {
triggerMap[config.name] = {
...config,
index
};
if (config.type === "internal") {
const route = config.routeNode;
children.push(/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_useScreens.Screen, {
getId: (0, import_useScreens.createGetIdForRoute)(route),
name: route.route,
options: args => {
const staticOptions = route.generated ? route.loadRoute()?.getNavOptions : null;
const staticResult = typeof staticOptions === "function" ? staticOptions(args) : staticOptions;
const output = {
...staticResult
};
if (route.generated) {
output.tabBarButton = () => null;
output.drawerItemStyle = {
height: 0,
display: "none"
};
}
return output;
},
getComponent: () => (0, import_useScreens.getQualifiedRouteComponent)(route)
}, route.route));
}
}
return {
children,
triggerMap
};
}
function stateToAction(state, startAtRoute) {
const rootPayload = {};
let payload = rootPayload;
startAtRoute = startAtRoute === "" ? "__root" : startAtRoute;
let foundStartingPoint = startAtRoute === void 0 || !state?.state;
while (state) {
if (foundStartingPoint) {
if (payload === rootPayload) {
payload.name = state.name;
} else {
payload.screen = state.name;
}
payload.params = state.params ? {
...state.params
} : {};
state = state.state?.routes[state.state?.routes.length - 1];
if (state) {
payload.params ??= {};
payload = payload.params;
}
} else {
if (state.name === startAtRoute) {
foundStartingPoint = true;
}
const nextState = state.state?.routes[state.state?.routes.length - 1];
if (nextState) {
state = nextState;
}
}
}
return {
type: "JUMP_TO",
payload: rootPayload
};
}