one
Version:
One is a React framework for web, iOS, and Android apps.
96 lines (93 loc) • 3.72 kB
JavaScript
import React, { Children, useMemo } from "react";
import { isChildOfType } from "../utils/children.mjs";
import { Protected } from "../views/Protected.mjs";
import { Screen } from "../views/Screen.mjs";
import { createStackNavigator, getStackNavigatorProps } from "./stack-navigator.mjs";
import { StackHeader, StackHeaderComponent, StackHeaderSearchBar, StackScreen, StackToolbarBadge, StackToolbarButton, StackToolbarComponent, StackToolbarIcon, StackToolbarLabel, StackToolbarMenu, StackToolbarMenuAction, StackToolbarSearchBarSlot, StackToolbarSpacer, appendScreenStackPropsToOptions, appendStackToolbarPropsToOptions } from "./stack-utils/index.mjs";
import { withLayoutContext } from "./withLayoutContext.mjs";
import { jsx } from "react/jsx-runtime";
const NativeStackNavigator = createStackNavigator().Navigator;
const RNStack = withLayoutContext(NativeStackNavigator, void 0, { undeclaredRoutes: true });
function mapChildren(children) {
return Children.toArray(children).map((child, index) => {
if (isChildOfType(child, StackScreen)) {
const options = appendScreenStackPropsToOptions({}, child.props);
const { children: _, ...rest } = child.props;
return /* @__PURE__ */ jsx(Screen, {
...rest,
options
}, child.props.name ?? index);
}
if (isChildOfType(child, Protected)) {
return React.cloneElement(child, { key: `protected-${index}` }, mapChildren(child.props.children));
}
if (isChildOfType(child, StackHeaderComponent)) {
return null;
}
if (isChildOfType(child, StackToolbarComponent)) {
return null;
}
if (isChildOfType(child, Screen)) {
return child;
}
return null;
}).filter(Boolean);
}
const StackWithComposition = React.forwardRef((props, ref) => {
const { children, screenOptions, ...rest } = props;
const screenOptionsWithHeader = useMemo(() => {
const stackHeader = Children.toArray(children).find((child) => isChildOfType(child, StackHeaderComponent));
const stackToolbars = Children.toArray(children).filter((child) => isChildOfType(child, StackToolbarComponent));
if (!stackHeader && !stackToolbars.length) return screenOptions;
const applyComposition = (opts) => {
let result = opts;
for (const stackToolbar of stackToolbars) {
result = appendStackToolbarPropsToOptions(result, stackToolbar.props);
}
if (stackHeader && isChildOfType(stackHeader, StackHeaderComponent)) {
const headerProps = { children: stackHeader };
result = appendScreenStackPropsToOptions(result, headerProps);
}
return result;
};
if (screenOptions) {
if (typeof screenOptions === "function") {
return (...args) => {
const opts = screenOptions(...args);
return applyComposition(opts);
};
}
return applyComposition(screenOptions);
}
return applyComposition({});
}, [children, screenOptions]);
const processedChildren = useMemo(() => mapChildren(children), [children]);
const navigatorProps = useMemo(() => getStackNavigatorProps(children), [children]);
return /* @__PURE__ */ jsx(RNStack, {
...rest,
...navigatorProps,
ref,
screenOptions: screenOptionsWithHeader,
children: processedChildren
});
});
const StackToolbar = Object.assign(StackToolbarComponent, {
Button: StackToolbarButton,
Menu: StackToolbarMenu,
MenuAction: StackToolbarMenuAction,
Spacer: StackToolbarSpacer,
SearchBarSlot: StackToolbarSearchBarSlot,
Label: StackToolbarLabel,
Icon: StackToolbarIcon,
Badge: StackToolbarBadge
});
const Stack = Object.assign(StackWithComposition, {
Screen: StackScreen,
Header: StackHeader,
Toolbar: StackToolbar,
Protected,
SearchBar: StackHeaderSearchBar
});
var Stack_default = Stack;
export { Stack, Stack_default as default };
//# sourceMappingURL=Stack.mjs.map