UNPKG

one

Version:

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

156 lines (154 loc) 5.1 kB
"use client"; import { StackActions } from "@react-navigation/native"; import { NativeStackView } from "@react-navigation/native-stack"; import { Fragment, useCallback, useRef, useState } from "react"; import { convertStackStateToNonOverlayState, findLastNonOverlayIndex, isOverlayPresentation } from "./stackStateUtils.mjs"; import { useStackRender } from "./ScreenRenderContext.mjs"; import { jsx, jsxs } from "react/jsx-runtime"; function resolveOverlayRender(options, contextRender) { return options?.render?.web ?? contextRender?.web; } function WebStackView({ state, navigation, descriptors, describe }) { const contextRender = useStackRender(); const persistentSlotsRef = useRef(/* @__PURE__ */new Map()); for (const route of state.routes) { const desc = descriptors[route.key]; if (!desc) continue; const { options } = desc; if (!options.keepMounted) continue; if (!isOverlayPresentation(options)) continue; const Render = resolveOverlayRender(options, contextRender); if (!Render) continue; if (persistentSlotsRef.current.has(route.name)) continue; persistentSlotsRef.current.set(route.name, { routeName: route.name, Render, options, content: desc.render() }); } const isOverlayCandidate = options => isOverlayPresentation(options) && resolveOverlayRender(options ?? void 0, contextRender) !== void 0; const nonOverlay = convertStackStateToNonOverlayState(state, descriptors, isOverlayCandidate); const underlyingState = { ...state, routes: nonOverlay.routes, index: nonOverlay.index }; const lastNonOverlay = findLastNonOverlayIndex(state, descriptors, isOverlayCandidate); const trailingOverlays = state.routes.slice(lastNonOverlay + 1); const focusedOverlayNames = new Set(trailingOverlays.map(r => r.name)); const regularOverlays = trailingOverlays.filter(r => !descriptors[r.key]?.options.keepMounted); return /* @__PURE__ */jsxs(Fragment, { children: [/* @__PURE__ */jsx(NativeStackView, { state: underlyingState, descriptors, navigation, describe }), regularOverlays.map(route => /* @__PURE__ */jsx(OverlayHost, { route, descriptor: descriptors[route.key], contextRender, open: true, onDismiss: () => navigation.dispatch({ ...StackActions.pop(), source: route.key, target: state.key }) }, route.key)), Array.from(persistentSlotsRef.current.values()).map(slot => /* @__PURE__ */jsx(PersistentOverlayHost, { slot, open: focusedOverlayNames.has(slot.routeName), onDismiss: () => { const live = state.routes.find(r => r.name === slot.routeName); if (live) { navigation.dispatch({ ...StackActions.pop(), source: live.key, target: state.key }); } } }, slot.routeName))] }); } function OverlayHost({ route, descriptor, contextRender, open, onDismiss }) { const dismiss = useStableCallback(onDismiss); const options = descriptor.options; const Render = resolveOverlayRender(options, contextRender); const content = descriptor.render(); if (!Render || !isOverlayPresentation(options)) { return /* @__PURE__ */jsx(Fragment, { children: content }); } const renderProps = { routeKey: route.key, routeName: route.name, presentation: options.presentation, open, dismiss, dismissible: options.gestureEnabled ?? true, sheetAllowedDetents: options.sheetAllowedDetents, sheetGrabberVisible: options.sheetGrabberVisible, sheetCornerRadius: options.sheetCornerRadius, sheetInitialDetentIndex: options.sheetInitialDetentIndex, sheetLargestUndimmedDetentIndex: options.sheetLargestUndimmedDetentIndex, sheetExpandsWhenScrolledToEdge: options.sheetExpandsWhenScrolledToEdge, children: content }; return /* @__PURE__ */jsx(Render, { ...renderProps }); } function PersistentOverlayHost({ slot, open, onDismiss }) { const dismiss = useStableCallback(onDismiss); const { Render, options, content, routeName } = slot; const renderProps = { routeKey: `__keepMounted:${routeName}`, routeName, presentation: options.presentation, open, dismiss, dismissible: options.gestureEnabled ?? true, sheetAllowedDetents: options.sheetAllowedDetents, sheetGrabberVisible: options.sheetGrabberVisible, sheetCornerRadius: options.sheetCornerRadius, sheetInitialDetentIndex: options.sheetInitialDetentIndex, sheetLargestUndimmedDetentIndex: options.sheetLargestUndimmedDetentIndex, sheetExpandsWhenScrolledToEdge: options.sheetExpandsWhenScrolledToEdge, children: content }; return /* @__PURE__ */jsx(Render, { ...renderProps }); } function useStableCallback(fn) { const [ref] = useState(() => ({ current: fn })); ref.current = fn; return useCallback((...args) => ref.current(...args), [ref]); } export { OverlayHost, WebStackView, resolveOverlayRender }; //# sourceMappingURL=WebStackView.mjs.map