one
Version:
One is a new React Framework that makes Vite serve both native and web.
124 lines (122 loc) • 3.79 kB
JavaScript
"use client";
import { StackActions } from "@react-navigation/routers";
import { Activity, Fragment, useCallback, useEffect, useState } from "react";
import useLatestCallback from "use-latest-callback";
import { devHeadlessNote } from "../../headless/devHeadlessNote.mjs";
import { useWebPresentations } from "../../headless/Presentations.mjs";
import { StackStateProvider, useStack } from "../../headless/useStack.mjs";
import { findLastNonOverlayIndex } from "./stackStateUtils.mjs";
import { jsx, jsxs } from "react/jsx-runtime";
function WebStackView({
state,
navigation,
descriptors,
customChildren
}) {
return /* @__PURE__ */jsx(StackStateProvider, {
state,
descriptors,
children: /* @__PURE__ */jsx(HeadlessStackView, {
state,
navigation,
descriptors,
customChildren
})
});
}
function HeadlessStackView({
state,
navigation,
descriptors,
customChildren
}) {
const stack = useStack();
const presentations = useWebPresentations();
if (customChildren?.length) {
return /* @__PURE__ */jsx(Fragment, {
children: customChildren
});
}
devHeadlessNote("Stack");
const lastBaseIndex = findLastNonOverlayIndex(state, descriptors, options => getPresentationType(options) !== void 0);
const baseRouteKeys = new Set(state.routes.slice(0, lastBaseIndex + 1).map(route => route.key));
const baseFocusedKey = state.routes[lastBaseIndex]?.key;
const overlayRoutes = state.routes.slice(lastBaseIndex + 1);
return /* @__PURE__ */jsxs(Fragment, {
children: [stack.screens.map(screen => {
if (!baseRouteKeys.has(screen.key)) return null;
if (screen.key === baseFocusedKey) {
return screen.keepMounted ? /* @__PURE__ */jsx(Activity, {
mode: "visible",
children: screen.element
}, screen.key) : /* @__PURE__ */jsx(Fragment, {
children: screen.element
}, screen.key);
}
if (!screen.keepMounted) return null;
return /* @__PURE__ */jsx(Activity, {
mode: "hidden",
children: screen.element
}, screen.key);
}), overlayRoutes.map(route => {
const screen = stack.screens.find(entry => entry.key === route.key);
const type = getPresentationType(descriptors[route.key]?.options);
if (!screen || !type) return null;
return /* @__PURE__ */jsx(PresentationScreen, {
screen,
type,
presentations,
onDismiss: () => navigation.dispatch({
...StackActions.pop(),
source: route.key,
target: state.key
})
}, route.key);
})]
});
}
function PresentationScreen({
screen,
type,
presentations,
onDismiss
}) {
const dismiss = useLatestCallback(onDismiss);
const onOpenChange = useCallback(nextOpen => {
if (!nextOpen) dismiss();
}, [dismiss]);
const [open, setOpen] = useState(false);
useEffect(() => setOpen(true), []);
if (type === "sheet") {
const Sheet = presentations?.sheet;
if (!Sheet) return screen.element;
return /* @__PURE__ */jsx(Sheet, {
open,
onOpenChange,
options: screen.options,
screen,
children: screen.element
});
}
const Modal = presentations?.modal;
if (!Modal) return screen.element;
return /* @__PURE__ */jsx(Modal, {
open,
onOpenChange,
options: screen.options,
screen,
children: screen.element
});
}
function getPresentationType(options) {
const presentation = options?.presentation;
if (!presentation || presentation === "card" || presentation === "push") {
return void 0;
}
if (presentation === "sheet" || presentation === "formSheet" || presentation === "pageSheet") {
return "sheet";
}
return "modal";
}
export { WebStackView };
//# sourceMappingURL=WebStackView.mjs.map