first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,362 @@
"use strict";
import { CommonActions } from '@react-navigation/routers';
import * as React from 'react';
import useLatestCallback from 'use-latest-callback';
import { checkDuplicateRouteNames } from "./checkDuplicateRouteNames.js";
import { checkSerializable } from "./checkSerializable.js";
import { NOT_INITIALIZED_ERROR } from "./createNavigationContainerRef.js";
import { DeprecatedNavigationInChildContext } from "./DeprecatedNavigationInChildContext.js";
import { EnsureSingleNavigator } from "./EnsureSingleNavigator.js";
import { findFocusedRoute } from "./findFocusedRoute.js";
import { NavigationBuilderContext } from "./NavigationBuilderContext.js";
import { NavigationContainerRefContext } from "./NavigationContainerRefContext.js";
import { NavigationIndependentTreeContext } from "./NavigationIndependentTreeContext.js";
import { NavigationStateContext } from "./NavigationStateContext.js";
import { ThemeProvider } from "./theming/ThemeProvider.js";
import { UnhandledActionContext } from "./UnhandledActionContext.js";
import { useChildListeners } from "./useChildListeners.js";
import { useEventEmitter } from "./useEventEmitter.js";
import { useKeyedChildListeners } from "./useKeyedChildListeners.js";
import { useNavigationIndependentTree } from "./useNavigationIndependentTree.js";
import { useOptionsGetters } from "./useOptionsGetters.js";
import { useSyncState } from "./useSyncState.js";
import { jsx as _jsx } from "react/jsx-runtime";
const serializableWarnings = [];
const duplicateNameWarnings = [];
/**
* Remove `key` and `routeNames` from the state objects recursively to get partial state.
*
* @param state Initial state object.
*/
const getPartialState = state => {
if (state === undefined) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {
key,
routeNames,
...partialState
} = state;
return {
...partialState,
stale: true,
routes: state.routes.map(route => {
if (route.state === undefined) {
return route;
}
return {
...route,
state: getPartialState(route.state)
};
})
};
};
/**
* Container component which holds the navigation state.
* This should be rendered at the root wrapping the whole app.
*
* @param props.initialState Initial state object for the navigation tree.
* @param props.onReady Callback which is called after the navigation tree mounts.
* @param props.onStateChange Callback which is called with the latest navigation state when it changes.
* @param props.onUnhandledAction Callback which is called when an action is not handled.
* @param props.theme Theme object for the UI elements.
* @param props.children Child elements to render the content.
* @param props.ref Ref object which refers to the navigation object containing helper methods.
*/
export const BaseNavigationContainer = /*#__PURE__*/React.forwardRef(function BaseNavigationContainer({
initialState,
onStateChange,
onReady,
onUnhandledAction,
navigationInChildEnabled = false,
theme,
children
}, ref) {
const parent = React.useContext(NavigationStateContext);
const independent = useNavigationIndependentTree();
if (!parent.isDefault && !independent) {
throw new Error("Looks like you have nested a 'NavigationContainer' inside another. Normally you need only one container at the root of the app, so this was probably an error. If this was intentional, wrap the container in 'NavigationIndependentTree' explicitly. Note that this will make the child navigators disconnected from the parent and you won't be able to navigate between them.");
}
const {
state,
getState,
setState,
scheduleUpdate,
flushUpdates
} = useSyncState(() => getPartialState(initialState == null ? undefined : initialState));
const isFirstMountRef = React.useRef(true);
const navigatorKeyRef = React.useRef(undefined);
const getKey = React.useCallback(() => navigatorKeyRef.current, []);
const setKey = React.useCallback(key => {
navigatorKeyRef.current = key;
}, []);
const {
listeners,
addListener
} = useChildListeners();
const {
keyedListeners,
addKeyedListener
} = useKeyedChildListeners();
const dispatch = useLatestCallback(action => {
if (listeners.focus[0] == null) {
console.error(NOT_INITIALIZED_ERROR);
} else {
listeners.focus[0](navigation => navigation.dispatch(action));
}
});
const canGoBack = useLatestCallback(() => {
if (listeners.focus[0] == null) {
return false;
}
const {
result,
handled
} = listeners.focus[0](navigation => navigation.canGoBack());
if (handled) {
return result;
} else {
return false;
}
});
const resetRoot = useLatestCallback(state => {
const target = state?.key ?? keyedListeners.getState.root?.().key;
if (target == null) {
console.error(NOT_INITIALIZED_ERROR);
} else {
listeners.focus[0](navigation => navigation.dispatch({
...CommonActions.reset(state),
target
}));
}
});
const getRootState = useLatestCallback(() => {
return keyedListeners.getState.root?.();
});
const getCurrentRoute = useLatestCallback(() => {
const state = getRootState();
if (state == null) {
return undefined;
}
const route = findFocusedRoute(state);
return route;
});
const isReady = useLatestCallback(() => listeners.focus[0] != null);
const emitter = useEventEmitter();
const {
addOptionsGetter,
getCurrentOptions
} = useOptionsGetters({});
const navigation = React.useMemo(() => ({
...Object.keys(CommonActions).reduce((acc, name) => {
acc[name] = (...args) =>
// @ts-expect-error: this is ok
dispatch(CommonActions[name](...args));
return acc;
}, {}),
...emitter.create('root'),
dispatch,
resetRoot,
isFocused: () => true,
canGoBack,
getParent: () => undefined,
getState,
getRootState,
getCurrentRoute,
getCurrentOptions,
isReady,
setOptions: () => {
throw new Error('Cannot call setOptions outside a screen');
}
}), [canGoBack, dispatch, emitter, getCurrentOptions, getCurrentRoute, getRootState, getState, isReady, resetRoot]);
React.useImperativeHandle(ref, () => navigation, [navigation]);
const onDispatchAction = useLatestCallback((action, noop) => {
emitter.emit({
type: '__unsafe_action__',
data: {
action,
noop,
stack: stackRef.current
}
});
});
const lastEmittedOptionsRef = React.useRef(undefined);
const onOptionsChange = useLatestCallback(options => {
if (lastEmittedOptionsRef.current === options) {
return;
}
lastEmittedOptionsRef.current = options;
emitter.emit({
type: 'options',
data: {
options
}
});
});
const stackRef = React.useRef(undefined);
const builderContext = React.useMemo(() => ({
addListener,
addKeyedListener,
onDispatchAction,
onOptionsChange,
scheduleUpdate,
flushUpdates,
stackRef
}), [addListener, addKeyedListener, onDispatchAction, onOptionsChange, scheduleUpdate, flushUpdates]);
const isInitialRef = React.useRef(true);
const getIsInitial = React.useCallback(() => isInitialRef.current, []);
const context = React.useMemo(() => ({
state,
getState,
setState,
getKey,
setKey,
getIsInitial,
addOptionsGetter
}), [state, getState, setState, getKey, setKey, getIsInitial, addOptionsGetter]);
const onReadyRef = React.useRef(onReady);
const onStateChangeRef = React.useRef(onStateChange);
React.useEffect(() => {
isInitialRef.current = false;
onStateChangeRef.current = onStateChange;
onReadyRef.current = onReady;
});
const onReadyCalledRef = React.useRef(false);
React.useEffect(() => {
if (!onReadyCalledRef.current && isReady()) {
onReadyCalledRef.current = true;
onReadyRef.current?.();
emitter.emit({
type: 'ready'
});
}
}, [state, isReady, emitter]);
React.useEffect(() => {
const hydratedState = getRootState();
if (process.env.NODE_ENV !== 'production') {
if (hydratedState !== undefined) {
const serializableResult = checkSerializable(hydratedState);
if (!serializableResult.serializable) {
const {
location,
reason
} = serializableResult;
let path = '';
let pointer = hydratedState;
let params = false;
for (let i = 0; i < location.length; i++) {
const curr = location[i];
const prev = location[i - 1];
pointer = pointer[curr];
if (!params && curr === 'state') {
continue;
} else if (!params && curr === 'routes') {
if (path) {
path += ' > ';
}
} else if (!params && typeof curr === 'number' && prev === 'routes') {
path += pointer?.name;
} else if (!params) {
path += ` > ${curr}`;
params = true;
} else {
if (typeof curr === 'number' || /^[0-9]+$/.test(curr)) {
path += `[${curr}]`;
} else if (/^[a-z$_]+$/i.test(curr)) {
path += `.${curr}`;
} else {
path += `[${JSON.stringify(curr)}]`;
}
}
}
const message = `Non-serializable values were found in the navigation state. Check:\n\n${path} (${reason})\n\nThis can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/troubleshooting#i-get-the-warning-non-serializable-values-were-found-in-the-navigation-state for more details.`;
if (!serializableWarnings.includes(message)) {
serializableWarnings.push(message);
console.warn(message);
}
}
const duplicateRouteNamesResult = checkDuplicateRouteNames(hydratedState);
if (duplicateRouteNamesResult.length) {
const message = `Found screens with the same name nested inside one another. Check:\n${duplicateRouteNamesResult.map(locations => `\n${locations.join(', ')}`)}\n\nThis can cause confusing behavior during navigation. Consider using unique names for each screen instead.`;
if (!duplicateNameWarnings.includes(message)) {
duplicateNameWarnings.push(message);
console.warn(message);
}
}
}
}
emitter.emit({
type: 'state',
data: {
state
}
});
if (!isFirstMountRef.current && onStateChangeRef.current) {
onStateChangeRef.current(hydratedState);
}
isFirstMountRef.current = false;
}, [getRootState, emitter, state]);
const defaultOnUnhandledAction = useLatestCallback(action => {
if (process.env.NODE_ENV === 'production') {
return;
}
const payload = action.payload;
let message = `The action '${action.type}'${payload ? ` with payload ${JSON.stringify(action.payload)}` : ''} was not handled by any navigator.`;
switch (action.type) {
case 'PRELOAD':
case 'NAVIGATE':
case 'PUSH':
case 'REPLACE':
case 'POP_TO':
case 'JUMP_TO':
if (payload?.name) {
message += `\n\nDo you have a screen named '${payload.name}'?\n\nIf you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.\n\nIf you're using conditional rendering, navigation will happen automatically and you shouldn't navigate manually, see.`;
} else {
message += `\n\nYou need to pass the name of the screen to navigate to.\n\nSee https://reactnavigation.org/docs/navigation-actions for usage.`;
}
break;
case 'GO_BACK':
case 'POP':
case 'POP_TO_TOP':
message += `\n\nIs there any screen to go back to?`;
break;
case 'OPEN_DRAWER':
case 'CLOSE_DRAWER':
case 'TOGGLE_DRAWER':
message += `\n\nIs your screen inside a Drawer navigator?`;
break;
}
message += `\n\nThis is a development-only warning and won't be shown in production.`;
console.error(message);
});
return /*#__PURE__*/_jsx(NavigationIndependentTreeContext.Provider, {
value: false,
children: /*#__PURE__*/_jsx(NavigationContainerRefContext.Provider, {
value: navigation,
children: /*#__PURE__*/_jsx(NavigationBuilderContext.Provider, {
value: builderContext,
children: /*#__PURE__*/_jsx(NavigationStateContext.Provider, {
value: context,
children: /*#__PURE__*/_jsx(UnhandledActionContext.Provider, {
value: onUnhandledAction ?? defaultOnUnhandledAction,
children: /*#__PURE__*/_jsx(DeprecatedNavigationInChildContext.Provider, {
value: navigationInChildEnabled,
children: /*#__PURE__*/_jsx(EnsureSingleNavigator, {
children: /*#__PURE__*/_jsx(ThemeProvider, {
value: theme,
children: children
})
})
})
})
})
})
})
});
});
//# sourceMappingURL=BaseNavigationContainer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
"use strict";
import * as React from 'react';
/**
* Context which holds the values for the current navigation tree.
* Intended for use in SSR. This is not safe to use on the client.
*/
export const CurrentRenderContext = /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=CurrentRenderContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","CurrentRenderContext","createContext","undefined"],"sourceRoot":"../../src","sources":["CurrentRenderContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA;AACA,OAAO,MAAMC,oBAAoB,gBAAGD,KAAK,CAACE,aAAa,CAErDC,SAAS,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,9 @@
"use strict";
import * as React from 'react';
/**
* Context which enables deprecated bubbling to child navigators.
*/
export const DeprecatedNavigationInChildContext = /*#__PURE__*/React.createContext(false);
//# sourceMappingURL=DeprecatedNavigationInChildContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","DeprecatedNavigationInChildContext","createContext"],"sourceRoot":"../../src","sources":["DeprecatedNavigationInChildContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,kCAAkC,gBAAGD,KAAK,CAACE,aAAa,CAAC,KAAK,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,36 @@
"use strict";
import * as React from 'react';
import { jsx as _jsx } from "react/jsx-runtime";
const MULTIPLE_NAVIGATOR_ERROR = `Another navigator is already registered for this container. You likely have multiple navigators under a single "NavigationContainer" or "Screen". Make sure each navigator is under a separate "Screen" container. See https://reactnavigation.org/docs/nesting-navigators for a guide on nesting.`;
export const SingleNavigatorContext = /*#__PURE__*/React.createContext(undefined);
/**
* Component which ensures that there's only one navigator nested under it.
*/
export function EnsureSingleNavigator({
children
}) {
const navigatorKeyRef = React.useRef(undefined);
const value = React.useMemo(() => ({
register(key) {
const currentKey = navigatorKeyRef.current;
if (currentKey !== undefined && key !== currentKey) {
throw new Error(MULTIPLE_NAVIGATOR_ERROR);
}
navigatorKeyRef.current = key;
},
unregister(key) {
const currentKey = navigatorKeyRef.current;
if (key !== currentKey) {
return;
}
navigatorKeyRef.current = undefined;
}
}), []);
return /*#__PURE__*/_jsx(SingleNavigatorContext.Provider, {
value: value,
children: children
});
}
//# sourceMappingURL=EnsureSingleNavigator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","jsx","_jsx","MULTIPLE_NAVIGATOR_ERROR","SingleNavigatorContext","createContext","undefined","EnsureSingleNavigator","children","navigatorKeyRef","useRef","value","useMemo","register","key","currentKey","current","Error","unregister","Provider"],"sourceRoot":"../../src","sources":["EnsureSingleNavigator.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAM/B,MAAMC,wBAAwB,GAAG,oSAAoS;AAErU,OAAO,MAAMC,sBAAsB,gBAAGJ,KAAK,CAACK,aAAa,CAMvDC,SAAS,CAAC;;AAEZ;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAAC;EAAEC;AAAgB,CAAC,EAAE;EACzD,MAAMC,eAAe,GAAGT,KAAK,CAACU,MAAM,CAAqBJ,SAAS,CAAC;EAEnE,MAAMK,KAAK,GAAGX,KAAK,CAACY,OAAO,CACzB,OAAO;IACLC,QAAQA,CAACC,GAAW,EAAE;MACpB,MAAMC,UAAU,GAAGN,eAAe,CAACO,OAAO;MAE1C,IAAID,UAAU,KAAKT,SAAS,IAAIQ,GAAG,KAAKC,UAAU,EAAE;QAClD,MAAM,IAAIE,KAAK,CAACd,wBAAwB,CAAC;MAC3C;MAEAM,eAAe,CAACO,OAAO,GAAGF,GAAG;IAC/B,CAAC;IACDI,UAAUA,CAACJ,GAAW,EAAE;MACtB,MAAMC,UAAU,GAAGN,eAAe,CAACO,OAAO;MAE1C,IAAIF,GAAG,KAAKC,UAAU,EAAE;QACtB;MACF;MAEAN,eAAe,CAACO,OAAO,GAAGV,SAAS;IACrC;EACF,CAAC,CAAC,EACF,EACF,CAAC;EAED,oBACEJ,IAAA,CAACE,sBAAsB,CAACe,QAAQ;IAACR,KAAK,EAAEA,KAAM;IAAAH,QAAA,EAC3CA;EAAQ,CACsB,CAAC;AAEtC","ignoreList":[]}

View File

@@ -0,0 +1,10 @@
"use strict";
/**
* Empty component used for grouping screen configs.
*/
export function Group(_) {
/* istanbul ignore next */
return null;
}
//# sourceMappingURL=Group.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Group","_"],"sourceRoot":"../../src","sources":["Group.tsx"],"mappings":";;AAIA;AACA;AACA;AACA,OAAO,SAASA,KAAKA,CAInBC,CAAyD,EAAE;EAC3D;EACA,OAAO,IAAI;AACb","ignoreList":[]}

View File

@@ -0,0 +1,17 @@
"use strict";
import * as React from 'react';
/**
* Context which holds the required helpers needed to build nested navigators.
*/
export const NavigationBuilderContext = /*#__PURE__*/React.createContext({
onDispatchAction: () => undefined,
onOptionsChange: () => undefined,
scheduleUpdate: () => {
throw new Error("Couldn't find a context for scheduling updates.");
},
flushUpdates: () => {
throw new Error("Couldn't find a context for flushing updates.");
}
});
//# sourceMappingURL=NavigationBuilderContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationBuilderContext","createContext","onDispatchAction","undefined","onOptionsChange","scheduleUpdate","Error","flushUpdates"],"sourceRoot":"../../src","sources":["NavigationBuilderContext.tsx"],"mappings":";;AAKA,OAAO,KAAKA,KAAK,MAAM,OAAO;AA6C9B;AACA;AACA;AACA,OAAO,MAAMC,wBAAwB,gBAAGD,KAAK,CAACE,aAAa,CAaxD;EACDC,gBAAgB,EAAEA,CAAA,KAAMC,SAAS;EACjCC,eAAe,EAAEA,CAAA,KAAMD,SAAS;EAChCE,cAAc,EAAEA,CAAA,KAAM;IACpB,MAAM,IAAIC,KAAK,CAAC,iDAAiD,CAAC;EACpE,CAAC;EACDC,YAAY,EAAEA,CAAA,KAAM;IAClB,MAAM,IAAID,KAAK,CAAC,+CAA+C,CAAC;EAClE;AACF,CAAC,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,8 @@
"use strict";
import * as React from 'react';
/**
* Context which holds the route prop for a screen.
*/
export const NavigationContainerRefContext = /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=NavigationContainerRefContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationContainerRefContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationContainerRefContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAI9B;AACA;AACA;AACA,OAAO,MAAMC,6BAA6B,gBAAGD,KAAK,CAACE,aAAa,CAE9DC,SAAS,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,8 @@
"use strict";
import * as React from 'react';
/**
* Context which holds the navigation prop for a screen.
*/
export const NavigationContext = /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=NavigationContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAG9B;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,gBAAGD,KAAK,CAACE,aAAa,CAElDC,SAAS,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,8 @@
"use strict";
import * as React from 'react';
/**
* Context for the parent route of a navigator.
*/
export const NavigationFocusedRouteStateContext = /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=NavigationFocusedRouteStateContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationFocusedRouteStateContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationFocusedRouteStateContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAc9B;AACA;AACA;AACA,OAAO,MAAMC,kCAAkC,gBAAGD,KAAK,CAACE,aAAa,CAEnEC,SAAS,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,9 @@
"use strict";
import * as React from 'react';
/**
* Context which holds the navigation helpers of the parent navigator.
* Navigators should use this context in their view component.
*/
export const NavigationHelpersContext = /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=NavigationHelpersContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationHelpersContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationHelpersContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAI9B;AACA;AACA;AACA;AACA,OAAO,MAAMC,wBAAwB,gBAAGD,KAAK,CAACE,aAAa,CAEzDC,SAAS,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,34 @@
"use strict";
import * as React from 'react';
import { NavigationContext } from "./NavigationContext.js";
import { NavigationIndependentTreeContext } from "./NavigationIndependentTreeContext.js";
import { NavigationRouteContext } from "./NavigationProvider.js";
import { IsFocusedContext } from "./useIsFocused.js";
/**
* Component to make the child navigation container independent of parent containers.
*/
import { jsx as _jsx } from "react/jsx-runtime";
export function NavigationIndependentTree({
children
}) {
return (
/*#__PURE__*/
// We need to clear any existing contexts for nested independent container to work correctly
_jsx(NavigationRouteContext.Provider, {
value: undefined,
children: /*#__PURE__*/_jsx(NavigationContext.Provider, {
value: undefined,
children: /*#__PURE__*/_jsx(IsFocusedContext.Provider, {
value: undefined,
children: /*#__PURE__*/_jsx(NavigationIndependentTreeContext.Provider, {
value: true,
children: children
})
})
})
})
);
}
//# sourceMappingURL=NavigationIndependentTree.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationContext","NavigationIndependentTreeContext","NavigationRouteContext","IsFocusedContext","jsx","_jsx","NavigationIndependentTree","children","Provider","value","undefined"],"sourceRoot":"../../src","sources":["NavigationIndependentTree.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,iBAAiB,QAAQ,wBAAqB;AACvD,SAASC,gCAAgC,QAAQ,uCAAoC;AACrF,SAASC,sBAAsB,QAAQ,yBAAsB;AAC7D,SAASC,gBAAgB,QAAQ,mBAAgB;;AAEjD;AACA;AACA;AAFA,SAAAC,GAAA,IAAAC,IAAA;AAGA,OAAO,SAASC,yBAAyBA,CAAC;EACxCC;AAGF,CAAC,EAAE;EACD;IAAA;IACE;IACAF,IAAA,CAACH,sBAAsB,CAACM,QAAQ;MAACC,KAAK,EAAEC,SAAU;MAAAH,QAAA,eAChDF,IAAA,CAACL,iBAAiB,CAACQ,QAAQ;QAACC,KAAK,EAAEC,SAAU;QAAAH,QAAA,eAC3CF,IAAA,CAACF,gBAAgB,CAACK,QAAQ;UAACC,KAAK,EAAEC,SAAU;UAAAH,QAAA,eAC1CF,IAAA,CAACJ,gCAAgC,CAACO,QAAQ;YAACC,KAAK;YAAAF,QAAA,EAC7CA;UAAQ,CACgC;QAAC,CACnB;MAAC,CACF;IAAC,CACE;EAAC;AAEtC","ignoreList":[]}

View File

@@ -0,0 +1,9 @@
"use strict";
import * as React from 'react';
/**
* Context which marks the navigation tree as independent.
*/
export const NavigationIndependentTreeContext = /*#__PURE__*/React.createContext(false);
//# sourceMappingURL=NavigationIndependentTreeContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationIndependentTreeContext","createContext"],"sourceRoot":"../../src","sources":["NavigationIndependentTreeContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,gCAAgC,gBAAGD,KAAK,CAACE,aAAa,CAAC,KAAK,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,15 @@
"use strict";
import * as React from 'react';
/**
* Context with additional metadata to pass to child navigator in a screen.
* For example, child native stack to know it's inside native tabs.
* So it doesn't implement features such as `popToTop` that are handled by native tabs.
*
* Consumers should not make any assumptions about the shape of the object.
* It can be different depending on the navigator and may change without notice.
* This is not intended to be used by application code.
*/
export const NavigationMetaContext = /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=NavigationMetaContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationMetaContext","createContext","undefined"],"sourceRoot":"../../src","sources":["NavigationMetaContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,qBAAqB,gBAAGD,KAAK,CAACE,aAAa,CACtDC,SACF,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,39 @@
"use strict";
import * as React from 'react';
import { NavigationContext } from "./NavigationContext.js";
import { FocusedRouteKeyContext, IsFocusedContext } from "./useIsFocused.js";
/**
* Context which holds the route prop for a screen.
*/
import { jsx as _jsx } from "react/jsx-runtime";
export const NavigationRouteContext = /*#__PURE__*/React.createContext(undefined);
/**
* Component to provide the navigation and route contexts to its children.
*/
export const NamedRouteContextListContext = /*#__PURE__*/React.createContext(undefined);
export function NavigationProvider({
route,
navigation,
children
}) {
const parentIsFocused = React.useContext(IsFocusedContext);
const focusedRouteKey = React.useContext(FocusedRouteKeyContext);
// Mark route as focused only if:
// - It doesn't have a parent navigator
// - Parent navigator is focused
const isFocused = parentIsFocused == null || parentIsFocused ? focusedRouteKey === route.key : false;
return /*#__PURE__*/_jsx(NavigationRouteContext.Provider, {
value: route,
children: /*#__PURE__*/_jsx(NavigationContext.Provider, {
value: navigation,
children: /*#__PURE__*/_jsx(IsFocusedContext.Provider, {
value: isFocused,
children: children
})
})
});
}
//# sourceMappingURL=NavigationProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationContext","FocusedRouteKeyContext","IsFocusedContext","jsx","_jsx","NavigationRouteContext","createContext","undefined","NamedRouteContextListContext","NavigationProvider","route","navigation","children","parentIsFocused","useContext","focusedRouteKey","isFocused","key","Provider","value"],"sourceRoot":"../../src","sources":["NavigationProvider.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,iBAAiB,QAAQ,wBAAqB;AAEvD,SAASC,sBAAsB,EAAEC,gBAAgB,QAAQ,mBAAgB;;AAEzE;AACA;AACA;AAFA,SAAAC,GAAA,IAAAC,IAAA;AAGA,OAAO,MAAMC,sBAAsB,gBAAGN,KAAK,CAACO,aAAa,CAEvDC,SAAS,CAAC;AAQZ;AACA;AACA;AACA,OAAO,MAAMC,4BAA4B,gBAAGT,KAAK,CAACO,aAAa,CAE7DC,SAAS,CAAC;AAEZ,OAAO,SAASE,kBAAkBA,CAAC;EAAEC,KAAK;EAAEC,UAAU;EAAEC;AAAgB,CAAC,EAAE;EACzE,MAAMC,eAAe,GAAGd,KAAK,CAACe,UAAU,CAACZ,gBAAgB,CAAC;EAC1D,MAAMa,eAAe,GAAGhB,KAAK,CAACe,UAAU,CAACb,sBAAsB,CAAC;;EAEhE;EACA;EACA;EACA,MAAMe,SAAS,GACbH,eAAe,IAAI,IAAI,IAAIA,eAAe,GACtCE,eAAe,KAAKL,KAAK,CAACO,GAAG,GAC7B,KAAK;EAEX,oBACEb,IAAA,CAACC,sBAAsB,CAACa,QAAQ;IAACC,KAAK,EAAET,KAAM;IAAAE,QAAA,eAC5CR,IAAA,CAACJ,iBAAiB,CAACkB,QAAQ;MAACC,KAAK,EAAER,UAAW;MAAAC,QAAA,eAC5CR,IAAA,CAACF,gBAAgB,CAACgB,QAAQ;QAACC,KAAK,EAAEH,SAAU;QAAAJ,QAAA,EACzCA;MAAQ,CACgB;IAAC,CACF;EAAC,CACE,CAAC;AAEtC","ignoreList":[]}

View File

@@ -0,0 +1,23 @@
"use strict";
import * as React from 'react';
const MISSING_CONTEXT_ERROR = "Couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'? See https://reactnavigation.org/docs/getting-started for setup instructions.";
export const NavigationStateContext = /*#__PURE__*/React.createContext({
isDefault: true,
get getKey() {
throw new Error(MISSING_CONTEXT_ERROR);
},
get setKey() {
throw new Error(MISSING_CONTEXT_ERROR);
},
get getState() {
throw new Error(MISSING_CONTEXT_ERROR);
},
get setState() {
throw new Error(MISSING_CONTEXT_ERROR);
},
get getIsInitial() {
throw new Error(MISSING_CONTEXT_ERROR);
}
});
//# sourceMappingURL=NavigationStateContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","MISSING_CONTEXT_ERROR","NavigationStateContext","createContext","isDefault","getKey","Error","setKey","getState","setState","getIsInitial"],"sourceRoot":"../../src","sources":["NavigationStateContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,MAAMC,qBAAqB,GACzB,wKAAwK;AAE1K,OAAO,MAAMC,sBAAsB,gBAAGF,KAAK,CAACG,aAAa,CActD;EACDC,SAAS,EAAE,IAAI;EAEf,IAAIC,MAAMA,CAAA,EAAQ;IAChB,MAAM,IAAIC,KAAK,CAACL,qBAAqB,CAAC;EACxC,CAAC;EACD,IAAIM,MAAMA,CAAA,EAAQ;IAChB,MAAM,IAAID,KAAK,CAACL,qBAAqB,CAAC;EACxC,CAAC;EACD,IAAIO,QAAQA,CAAA,EAAQ;IAClB,MAAM,IAAIF,KAAK,CAACL,qBAAqB,CAAC;EACxC,CAAC;EACD,IAAIQ,QAAQA,CAAA,EAAQ;IAClB,MAAM,IAAIH,KAAK,CAACL,qBAAqB,CAAC;EACxC,CAAC;EACD,IAAIS,YAAYA,CAAA,EAAQ;IACtB,MAAM,IAAIJ,KAAK,CAACL,qBAAqB,CAAC;EACxC;AACF,CAAC,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,11 @@
"use strict";
import * as React from 'react';
/**
* A type of an object that have a route key as an object key
* and a value whether to prevent that route.
*/
export const PreventRemoveContext = /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=PreventRemoveContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","PreventRemoveContext","createContext","undefined"],"sourceRoot":"../../src","sources":["PreventRemoveContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA;;AAGA,OAAO,MAAMC,oBAAoB,gBAAGD,KAAK,CAACE,aAAa,CAUrDC,SAAS,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,84 @@
"use strict";
import { nanoid } from 'nanoid/non-secure';
import * as React from 'react';
import useLatestCallback from 'use-latest-callback';
import { NavigationHelpersContext } from "./NavigationHelpersContext.js";
import { NavigationRouteContext } from "./NavigationProvider.js";
import { PreventRemoveContext } from "./PreventRemoveContext.js";
import { jsx as _jsx } from "react/jsx-runtime";
/**
* Util function to transform map of prevented routes to a simpler object.
*/
const transformPreventedRoutes = preventedRoutesMap => {
const preventedRoutesToTransform = [...preventedRoutesMap.values()];
const preventedRoutes = preventedRoutesToTransform.reduce((acc, {
routeKey,
preventRemove
}) => {
acc[routeKey] = {
preventRemove: acc[routeKey]?.preventRemove || preventRemove
};
return acc;
}, {});
return preventedRoutes;
};
/**
* Component used for managing which routes have to be prevented from removal in native-stack.
*/
export function PreventRemoveProvider({
children
}) {
const [parentId] = React.useState(() => nanoid());
const [preventedRoutesMap, setPreventedRoutesMap] = React.useState(() => new Map());
const navigation = React.useContext(NavigationHelpersContext);
const route = React.useContext(NavigationRouteContext);
const preventRemoveContextValue = React.useContext(PreventRemoveContext);
// take `setPreventRemove` from parent context - if exist it means we're in a nested context
const setParentPrevented = preventRemoveContextValue?.setPreventRemove;
const setPreventRemove = useLatestCallback((id, routeKey, preventRemove) => {
if (preventRemove && (navigation == null || navigation?.getState().routes.every(route => route.key !== routeKey))) {
throw new Error(`Couldn't find a route with the key ${routeKey}. Is your component inside NavigationContent?`);
}
setPreventedRoutesMap(prevPrevented => {
// values haven't changed - do nothing
if (routeKey === prevPrevented.get(id)?.routeKey && preventRemove === prevPrevented.get(id)?.preventRemove) {
return prevPrevented;
}
const nextPrevented = new Map(prevPrevented);
if (preventRemove) {
nextPrevented.set(id, {
routeKey,
preventRemove
});
} else {
nextPrevented.delete(id);
}
return nextPrevented;
});
});
const isPrevented = [...preventedRoutesMap.values()].some(({
preventRemove
}) => preventRemove);
React.useEffect(() => {
if (route?.key !== undefined && setParentPrevented !== undefined) {
// when route is defined (and setParentPrevented) it means we're in a nested stack
// route.key then will be the route key of parent
setParentPrevented(parentId, route.key, isPrevented);
return () => {
setParentPrevented(parentId, route.key, false);
};
}
return;
}, [parentId, isPrevented, route?.key, setParentPrevented]);
const value = React.useMemo(() => ({
setPreventRemove,
preventedRoutes: transformPreventedRoutes(preventedRoutesMap)
}), [setPreventRemove, preventedRoutesMap]);
return /*#__PURE__*/_jsx(PreventRemoveContext.Provider, {
value: value,
children: children
});
}
//# sourceMappingURL=PreventRemoveProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["nanoid","React","useLatestCallback","NavigationHelpersContext","NavigationRouteContext","PreventRemoveContext","jsx","_jsx","transformPreventedRoutes","preventedRoutesMap","preventedRoutesToTransform","values","preventedRoutes","reduce","acc","routeKey","preventRemove","PreventRemoveProvider","children","parentId","useState","setPreventedRoutesMap","Map","navigation","useContext","route","preventRemoveContextValue","setParentPrevented","setPreventRemove","id","getState","routes","every","key","Error","prevPrevented","get","nextPrevented","set","delete","isPrevented","some","useEffect","undefined","value","useMemo","Provider"],"sourceRoot":"../../src","sources":["PreventRemoveProvider.tsx"],"mappings":"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","ignoreList":[]}

View File

@@ -0,0 +1,129 @@
"use strict";
import * as React from 'react';
import { EnsureSingleNavigator } from "./EnsureSingleNavigator.js";
import { isArrayEqual } from "./isArrayEqual.js";
import { NavigationFocusedRouteStateContext } from "./NavigationFocusedRouteStateContext.js";
import { NavigationStateContext } from "./NavigationStateContext.js";
import { StaticContainer } from "./StaticContainer.js";
import { useOptionsGetters } from "./useOptionsGetters.js";
import { jsx as _jsx } from "react/jsx-runtime";
/**
* Component which takes care of rendering the screen for a route.
* It provides all required contexts and applies optimizations when applicable.
*/
export function SceneView({
screen,
route,
navigation,
routeState,
getState,
setState,
options,
clearOptions
}) {
const navigatorKeyRef = React.useRef(undefined);
const getKey = React.useCallback(() => navigatorKeyRef.current, []);
const {
addOptionsGetter
} = useOptionsGetters({
key: route.key,
options,
navigation
});
const setKey = React.useCallback(key => {
navigatorKeyRef.current = key;
}, []);
const getCurrentState = React.useCallback(() => {
const state = getState();
const currentRoute = state.routes.find(r => r.key === route.key);
return currentRoute ? currentRoute.state : undefined;
}, [getState, route.key]);
const setCurrentState = React.useCallback(child => {
const state = getState();
const routes = state.routes.map(r => {
if (r.key === route.key && r.state !== child) {
return {
...r,
state: child
};
}
return r;
});
if (!isArrayEqual(state.routes, routes)) {
setState({
...state,
routes
});
}
}, [getState, route.key, setState]);
const isInitialRef = React.useRef(true);
React.useEffect(() => {
isInitialRef.current = false;
});
// Clear options set by this screen when it is unmounted
React.useEffect(() => {
return clearOptions;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const getIsInitial = React.useCallback(() => isInitialRef.current, []);
const parentFocusedRouteState = React.useContext(NavigationFocusedRouteStateContext);
const focusedRouteState = React.useMemo(() => {
const state = {
routes: [{
key: route.key,
name: route.name,
params: route.params,
path: route.path
}]
};
// Add our state to the innermost route of the parent state
const addState = parent => {
const parentRoute = parent?.routes[0];
if (parentRoute) {
return {
routes: [{
...parentRoute,
state: addState(parentRoute.state)
}]
};
}
return state;
};
return addState(parentFocusedRouteState);
}, [parentFocusedRouteState, route.key, route.name, route.params, route.path]);
const context = React.useMemo(() => ({
state: routeState,
getState: getCurrentState,
setState: setCurrentState,
getKey,
setKey,
getIsInitial,
addOptionsGetter
}), [routeState, getCurrentState, setCurrentState, getKey, setKey, getIsInitial, addOptionsGetter]);
const ScreenComponent = screen.getComponent ? screen.getComponent() : screen.component;
return /*#__PURE__*/_jsx(NavigationStateContext.Provider, {
value: context,
children: /*#__PURE__*/_jsx(NavigationFocusedRouteStateContext.Provider, {
value: focusedRouteState,
children: /*#__PURE__*/_jsx(EnsureSingleNavigator, {
children: /*#__PURE__*/_jsx(StaticContainer, {
name: screen.name,
render: ScreenComponent || screen.children,
navigation: navigation,
route: route,
children: ScreenComponent !== undefined ? /*#__PURE__*/_jsx(ScreenComponent, {
navigation: navigation,
route: route
}) : screen.children !== undefined ? screen.children({
navigation,
route
}) : null
})
})
})
});
}
//# sourceMappingURL=SceneView.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","EnsureSingleNavigator","isArrayEqual","NavigationFocusedRouteStateContext","NavigationStateContext","StaticContainer","useOptionsGetters","jsx","_jsx","SceneView","screen","route","navigation","routeState","getState","setState","options","clearOptions","navigatorKeyRef","useRef","undefined","getKey","useCallback","current","addOptionsGetter","key","setKey","getCurrentState","state","currentRoute","routes","find","r","setCurrentState","child","map","isInitialRef","useEffect","getIsInitial","parentFocusedRouteState","useContext","focusedRouteState","useMemo","name","params","path","addState","parent","parentRoute","context","ScreenComponent","getComponent","component","Provider","value","children","render"],"sourceRoot":"../../src","sources":["SceneView.tsx"],"mappings":";;AAMA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,qBAAqB,QAAQ,4BAAyB;AAC/D,SAASC,YAAY,QAAQ,mBAAgB;AAC7C,SAEEC,kCAAkC,QAC7B,yCAAsC;AAC7C,SAASC,sBAAsB,QAAQ,6BAA0B;AACjE,SAASC,eAAe,QAAQ,sBAAmB;AAEnD,SAASC,iBAAiB,QAAQ,wBAAqB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAmBxD;AACA;AACA;AACA;AACA,OAAO,SAASC,SAASA,CAGvB;EACAC,MAAM;EACNC,KAAK;EACLC,UAAU;EACVC,UAAU;EACVC,QAAQ;EACRC,QAAQ;EACRC,OAAO;EACPC;AAC2B,CAAC,EAAE;EAC9B,MAAMC,eAAe,GAAGlB,KAAK,CAACmB,MAAM,CAAqBC,SAAS,CAAC;EACnE,MAAMC,MAAM,GAAGrB,KAAK,CAACsB,WAAW,CAAC,MAAMJ,eAAe,CAACK,OAAO,EAAE,EAAE,CAAC;EAEnE,MAAM;IAAEC;EAAiB,CAAC,GAAGlB,iBAAiB,CAAC;IAC7CmB,GAAG,EAAEd,KAAK,CAACc,GAAG;IACdT,OAAO;IACPJ;EACF,CAAC,CAAC;EAEF,MAAMc,MAAM,GAAG1B,KAAK,CAACsB,WAAW,CAAEG,GAAW,IAAK;IAChDP,eAAe,CAACK,OAAO,GAAGE,GAAG;EAC/B,CAAC,EAAE,EAAE,CAAC;EAEN,MAAME,eAAe,GAAG3B,KAAK,CAACsB,WAAW,CAAC,MAAM;IAC9C,MAAMM,KAAK,GAAGd,QAAQ,CAAC,CAAC;IACxB,MAAMe,YAAY,GAAGD,KAAK,CAACE,MAAM,CAACC,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAACP,GAAG,KAAKd,KAAK,CAACc,GAAG,CAAC;IAElE,OAAOI,YAAY,GAAGA,YAAY,CAACD,KAAK,GAAGR,SAAS;EACtD,CAAC,EAAE,CAACN,QAAQ,EAAEH,KAAK,CAACc,GAAG,CAAC,CAAC;EAEzB,MAAMQ,eAAe,GAAGjC,KAAK,CAACsB,WAAW,CACtCY,KAAkE,IAAK;IACtE,MAAMN,KAAK,GAAGd,QAAQ,CAAC,CAAC;IAExB,MAAMgB,MAAM,GAAGF,KAAK,CAACE,MAAM,CAACK,GAAG,CAAEH,CAAC,IAAK;MACrC,IAAIA,CAAC,CAACP,GAAG,KAAKd,KAAK,CAACc,GAAG,IAAIO,CAAC,CAACJ,KAAK,KAAKM,KAAK,EAAE;QAC5C,OAAO;UACL,GAAGF,CAAC;UACJJ,KAAK,EAAEM;QACT,CAAC;MACH;MAEA,OAAOF,CAAC;IACV,CAAC,CAAC;IAEF,IAAI,CAAC9B,YAAY,CAAC0B,KAAK,CAACE,MAAM,EAAEA,MAAM,CAAC,EAAE;MACvCf,QAAQ,CAAC;QACP,GAAGa,KAAK;QACRE;MACF,CAAC,CAAC;IACJ;EACF,CAAC,EACD,CAAChB,QAAQ,EAAEH,KAAK,CAACc,GAAG,EAAEV,QAAQ,CAChC,CAAC;EAED,MAAMqB,YAAY,GAAGpC,KAAK,CAACmB,MAAM,CAAC,IAAI,CAAC;EAEvCnB,KAAK,CAACqC,SAAS,CAAC,MAAM;IACpBD,YAAY,CAACb,OAAO,GAAG,KAAK;EAC9B,CAAC,CAAC;;EAEF;EACAvB,KAAK,CAACqC,SAAS,CAAC,MAAM;IACpB,OAAOpB,YAAY;IACnB;EACF,CAAC,EAAE,EAAE,CAAC;EAEN,MAAMqB,YAAY,GAAGtC,KAAK,CAACsB,WAAW,CAAC,MAAMc,YAAY,CAACb,OAAO,EAAE,EAAE,CAAC;EAEtE,MAAMgB,uBAAuB,GAAGvC,KAAK,CAACwC,UAAU,CAC9CrC,kCACF,CAAC;EAED,MAAMsC,iBAAiB,GAAGzC,KAAK,CAAC0C,OAAO,CAAC,MAAM;IAC5C,MAAMd,KAAwB,GAAG;MAC/BE,MAAM,EAAE,CACN;QACEL,GAAG,EAAEd,KAAK,CAACc,GAAG;QACdkB,IAAI,EAAEhC,KAAK,CAACgC,IAAI;QAChBC,MAAM,EAAEjC,KAAK,CAACiC,MAAM;QACpBC,IAAI,EAAElC,KAAK,CAACkC;MACd,CAAC;IAEL,CAAC;;IAED;IACA,MAAMC,QAAQ,GACZC,MAAqC,IACf;MACtB,MAAMC,WAAW,GAAGD,MAAM,EAAEjB,MAAM,CAAC,CAAC,CAAC;MAErC,IAAIkB,WAAW,EAAE;QACf,OAAO;UACLlB,MAAM,EAAE,CACN;YACE,GAAGkB,WAAW;YACdpB,KAAK,EAAEkB,QAAQ,CAACE,WAAW,CAACpB,KAAK;UACnC,CAAC;QAEL,CAAC;MACH;MAEA,OAAOA,KAAK;IACd,CAAC;IAED,OAAOkB,QAAQ,CAACP,uBAAuB,CAAC;EAC1C,CAAC,EAAE,CACDA,uBAAuB,EACvB5B,KAAK,CAACc,GAAG,EACTd,KAAK,CAACgC,IAAI,EACVhC,KAAK,CAACiC,MAAM,EACZjC,KAAK,CAACkC,IAAI,CACX,CAAC;EAEF,MAAMI,OAAO,GAAGjD,KAAK,CAAC0C,OAAO,CAC3B,OAAO;IACLd,KAAK,EAAEf,UAAU;IACjBC,QAAQ,EAAEa,eAAe;IACzBZ,QAAQ,EAAEkB,eAAe;IACzBZ,MAAM;IACNK,MAAM;IACNY,YAAY;IACZd;EACF,CAAC,CAAC,EACF,CACEX,UAAU,EACVc,eAAe,EACfM,eAAe,EACfZ,MAAM,EACNK,MAAM,EACNY,YAAY,EACZd,gBAAgB,CAEpB,CAAC;EAED,MAAM0B,eAAe,GAAGxC,MAAM,CAACyC,YAAY,GACvCzC,MAAM,CAACyC,YAAY,CAAC,CAAC,GACrBzC,MAAM,CAAC0C,SAAS;EAEpB,oBACE5C,IAAA,CAACJ,sBAAsB,CAACiD,QAAQ;IAACC,KAAK,EAAEL,OAAQ;IAAAM,QAAA,eAC9C/C,IAAA,CAACL,kCAAkC,CAACkD,QAAQ;MAACC,KAAK,EAAEb,iBAAkB;MAAAc,QAAA,eACpE/C,IAAA,CAACP,qBAAqB;QAAAsD,QAAA,eACpB/C,IAAA,CAACH,eAAe;UACdsC,IAAI,EAAEjC,MAAM,CAACiC,IAAK;UAClBa,MAAM,EAAEN,eAAe,IAAIxC,MAAM,CAAC6C,QAAS;UAC3C3C,UAAU,EAAEA,UAAW;UACvBD,KAAK,EAAEA,KAAM;UAAA4C,QAAA,EAEZL,eAAe,KAAK9B,SAAS,gBAC5BZ,IAAA,CAAC0C,eAAe;YAACtC,UAAU,EAAEA,UAAW;YAACD,KAAK,EAAEA;UAAM,CAAE,CAAC,GACvDD,MAAM,CAAC6C,QAAQ,KAAKnC,SAAS,GAC/BV,MAAM,CAAC6C,QAAQ,CAAC;YAAE3C,UAAU;YAAED;UAAM,CAAC,CAAC,GACpC;QAAI,CACO;MAAC,CACG;IAAC,CACmB;EAAC,CACf,CAAC;AAEtC","ignoreList":[]}

View File

@@ -0,0 +1,10 @@
"use strict";
/**
* Empty component used for specifying route configuration.
*/
export function Screen(_) {
/* istanbul ignore next */
return null;
}
//# sourceMappingURL=Screen.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Screen","_"],"sourceRoot":"../../src","sources":["Screen.tsx"],"mappings":";;AAIA;AACA;AACA;AACA,OAAO,SAASA,MAAMA,CAQpBC,CAOC,EACD;EACA;EACA,OAAO,IAAI;AACb","ignoreList":[]}

View File

@@ -0,0 +1,26 @@
"use strict";
import * as React from 'react';
/**
* Component which prevents updates for children if no props changed
*/
export const StaticContainer = /*#__PURE__*/React.memo(function StaticContainer(props) {
return props.children;
}, (prevProps, nextProps) => {
const prevPropKeys = Object.keys(prevProps);
const nextPropKeys = Object.keys(nextProps);
if (prevPropKeys.length !== nextPropKeys.length) {
return false;
}
for (const key of prevPropKeys) {
if (key === 'children') {
continue;
}
if (prevProps[key] !== nextProps[key]) {
return false;
}
}
return true;
});
//# sourceMappingURL=StaticContainer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","StaticContainer","memo","props","children","prevProps","nextProps","prevPropKeys","Object","keys","nextPropKeys","length","key"],"sourceRoot":"../../src","sources":["StaticContainer.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,eAAe,gBAAGD,KAAK,CAACE,IAAI,CACvC,SAASD,eAAeA,CAACE,KAAU,EAAE;EACnC,OAAOA,KAAK,CAACC,QAAQ;AACvB,CAAC,EACD,CAACC,SAAc,EAAEC,SAAc,KAAK;EAClC,MAAMC,YAAY,GAAGC,MAAM,CAACC,IAAI,CAACJ,SAAS,CAAC;EAC3C,MAAMK,YAAY,GAAGF,MAAM,CAACC,IAAI,CAACH,SAAS,CAAC;EAE3C,IAAIC,YAAY,CAACI,MAAM,KAAKD,YAAY,CAACC,MAAM,EAAE;IAC/C,OAAO,KAAK;EACd;EAEA,KAAK,MAAMC,GAAG,IAAIL,YAAY,EAAE;IAC9B,IAAIK,GAAG,KAAK,UAAU,EAAE;MACtB;IACF;IAEA,IAAIP,SAAS,CAACO,GAAG,CAAC,KAAKN,SAAS,CAACM,GAAG,CAAC,EAAE;MACrC,OAAO,KAAK;IACd;EACF;EAEA,OAAO,IAAI;AACb,CACF,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,255 @@
"use strict";
import * as React from 'react';
import { isValidElementType } from 'react-is';
import { useRoute } from "./useRoute.js";
/**
* Flatten a type to remove all type alias names, unions etc.
* This will show a plain object when hovering over the type.
*/
/**
* keyof T doesn't work for union types. We can use distributive conditional types instead.
* https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
*/
/**
* We get a union type when using keyof, but we want an intersection instead.
* https://stackoverflow.com/a/50375286/1665026
*/
/**
* Props for a screen component which is rendered by a static navigator.
* Takes the route params as a generic argument.
*/
/**
* Infer the param list from the static navigation config.
*/
import { jsx as _jsx } from "react/jsx-runtime";
const MemoizedScreen = /*#__PURE__*/React.memo(({
component
}) => {
const route = useRoute();
const children = /*#__PURE__*/React.createElement(component, {
route
});
return children;
});
MemoizedScreen.displayName = 'Memo(Screen)';
const getItemsFromScreens = (Screen, screens) => {
return Object.entries(screens).map(([name, item]) => {
let component;
let props = {};
let useIf;
let isNavigator = false;
if ('screen' in item) {
const {
screen,
if: _if,
...rest
} = item;
useIf = _if;
props = rest;
if (isValidElementType(screen)) {
component = screen;
} else if ('config' in screen) {
isNavigator = true;
component = createComponentForStaticNavigation(screen, `${name}Navigator`);
}
} else if (isValidElementType(item)) {
component = item;
} else if ('config' in item) {
isNavigator = true;
component = createComponentForStaticNavigation(item, `${name}Navigator`);
}
if (component == null) {
throw new Error(`Couldn't find a 'screen' property for the screen '${name}'. This can happen if you passed 'undefined'. You likely forgot to export your component from the file it's defined in, or mixed up default import and named import when importing.`);
}
const element = isNavigator ? (/*#__PURE__*/React.createElement(component, {})) : /*#__PURE__*/_jsx(MemoizedScreen, {
component: component
});
return () => {
const shouldRender = useIf == null || useIf();
if (!shouldRender) {
return null;
}
return /*#__PURE__*/_jsx(Screen, {
name: name,
...props,
children: () => element
}, name);
};
});
};
/**
* Create a component that renders a navigator based on the static configuration.
*
* @param tree Static navigation config.
* @param displayName Name of the component to be displayed in React DevTools.
* @returns A component which renders the navigator.
*/
export function createComponentForStaticNavigation(tree, displayName) {
const {
Navigator,
Group,
Screen,
config
} = tree;
const {
screens,
groups,
...rest
} = config;
if (screens == null && groups == null) {
throw new Error("Couldn't find a 'screens' or 'groups' property. Make sure to define your screens under a 'screens' property in the configuration.");
}
const items = [];
// Loop through the config to find screens and groups
// So we add the screens and groups in the same order as they are defined
for (const key in config) {
if (key === 'screens' && screens) {
items.push(...getItemsFromScreens(Screen, screens));
}
if (key === 'groups' && groups) {
items.push(...Object.entries(groups).map(([key, {
if: useIf,
...group
}]) => {
const groupItems = getItemsFromScreens(Screen, group.screens);
return () => {
// Call unconditionally since screen configs may contain `useIf` hooks
const children = groupItems.map(item => item());
const shouldRender = useIf == null || useIf();
if (!shouldRender) {
return null;
}
return /*#__PURE__*/_jsx(Group, {
navigationKey: key,
...group,
children: children
}, key);
};
}));
}
}
const NavigatorComponent = () => {
const children = items.map(item => item());
return /*#__PURE__*/_jsx(Navigator, {
...rest,
children: children
});
};
NavigatorComponent.displayName = displayName;
return NavigatorComponent;
}
/**
* Create a path config object from a static navigation config for deep linking.
*
* @param tree Static navigation config.
* @param options Additional options from `linking.config`.
* @param auto Whether to automatically generate paths for leaf screens.
* @returns Path config object to use in linking config.
*
* @example
* ```js
* const config = {
* screens: {
* Home: {
* screens: createPathConfigForStaticNavigation(HomeTabs),
* },
* },
* };
* ```
*/
export function createPathConfigForStaticNavigation(tree, options, auto) {
let initialScreenHasPath = false;
let initialScreenConfig;
const createPathConfigForTree = (t, o, skipInitialDetection) => {
const createPathConfigForScreens = (screens, initialRouteName) => {
return Object.fromEntries(Object.entries(screens)
// Re-order to move the initial route to the front
// This way we can detect the initial route correctly
.sort(([a], [b]) => {
if (a === initialRouteName) {
return -1;
}
if (b === initialRouteName) {
return 1;
}
return 0;
}).map(([key, item]) => {
const screenConfig = {};
if ('linking' in item) {
if (typeof item.linking === 'string') {
screenConfig.path = item.linking;
} else {
Object.assign(screenConfig, item.linking);
}
if (typeof screenConfig.path === 'string') {
screenConfig.path = screenConfig.path.replace(/^\//, '') // Remove extra leading slash
.replace(/\/$/, ''); // Remove extra trailing slash
}
}
let screens;
const skipInitialDetectionInChild = skipInitialDetection || screenConfig.path != null && screenConfig.path !== '';
if ('config' in item) {
screens = createPathConfigForTree(item, undefined, skipInitialDetectionInChild);
} else if ('screen' in item && 'config' in item.screen && (item.screen.config.screens || item.screen.config.groups)) {
screens = createPathConfigForTree(item.screen, undefined, skipInitialDetectionInChild);
}
if (screens) {
screenConfig.screens = screens;
}
if (auto && !screenConfig.screens &&
// Skip generating path for screens that specify linking config as `undefined` or `null` explicitly
!('linking' in item && item.linking == null)) {
if (screenConfig.path != null) {
if (!skipInitialDetection) {
if (key === initialRouteName && screenConfig.path != null) {
initialScreenHasPath = true;
} else if (screenConfig.path === '') {
// We encounter a leaf screen with empty path,
// Clear the initial screen config as it's not needed anymore
initialScreenConfig = undefined;
}
}
} else {
if (!skipInitialDetection && initialScreenConfig == null) {
initialScreenConfig = screenConfig;
}
screenConfig.path = key.replace(/([A-Z]+)/g, '-$1').replace(/^-/, '').toLowerCase();
}
}
return [key, screenConfig];
}).filter(([, screen]) => Object.keys(screen).length > 0));
};
const screens = {};
// Loop through the config to find screens and groups
// So we add the screens and groups in the same order as they are defined
for (const key in t.config) {
if (key === 'screens' && t.config.screens) {
Object.assign(screens, createPathConfigForScreens(t.config.screens, o?.initialRouteName ?? t.config.initialRouteName));
}
if (key === 'groups' && t.config.groups) {
Object.entries(t.config.groups).forEach(([, group]) => {
Object.assign(screens, createPathConfigForScreens(group.screens, o?.initialRouteName ?? t.config.initialRouteName));
});
}
}
if (Object.keys(screens).length === 0) {
return undefined;
}
return screens;
};
const screens = createPathConfigForTree(tree, options, false);
if (auto && initialScreenConfig && !initialScreenHasPath) {
initialScreenConfig.path = '';
}
return screens;
}
//# sourceMappingURL=StaticNavigation.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
"use strict";
import * as React from 'react';
export const UnhandledActionContext = /*#__PURE__*/React.createContext(undefined);
//# sourceMappingURL=UnhandledActionContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","UnhandledActionContext","createContext","undefined"],"sourceRoot":"../../src","sources":["UnhandledActionContext.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,OAAO,MAAMC,sBAAsB,gBAAGD,KAAK,CAACE,aAAa,CAEvDC,SAAS,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,12 @@
"use strict";
/**
* Compare two arrays to check if the first array starts with the second array.
*/
export function arrayStartsWith(array, start) {
if (start.length > array.length) {
return false;
}
return start.every((it, index) => it === array[index]);
}
//# sourceMappingURL=arrayStartsWith.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["arrayStartsWith","array","start","length","every","it","index"],"sourceRoot":"../../src","sources":["arrayStartsWith.tsx"],"mappings":";;AAAA;AACA;AACA;AACA,OAAO,SAASA,eAAeA,CAAIC,KAAU,EAAEC,KAAU,EAAE;EACzD,IAAIA,KAAK,CAACC,MAAM,GAAGF,KAAK,CAACE,MAAM,EAAE;IAC/B,OAAO,KAAK;EACd;EAEA,OAAOD,KAAK,CAACE,KAAK,CAAC,CAACC,EAAE,EAAEC,KAAK,KAAKD,EAAE,KAAKJ,KAAK,CAACK,KAAK,CAAC,CAAC;AACxD","ignoreList":[]}

View File

@@ -0,0 +1,21 @@
"use strict";
export function checkDuplicateRouteNames(state) {
const duplicates = [];
const getRouteNames = (location, state) => {
state.routes.forEach(route => {
const currentLocation = location ? `${location} > ${route.name}` : route.name;
route.state?.routeNames?.forEach(routeName => {
if (routeName === route.name) {
duplicates.push([currentLocation, `${currentLocation} > ${route.name}`]);
}
});
if (route.state) {
getRouteNames(currentLocation, route.state);
}
});
};
getRouteNames('', state);
return duplicates;
}
//# sourceMappingURL=checkDuplicateRouteNames.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["checkDuplicateRouteNames","state","duplicates","getRouteNames","location","routes","forEach","route","currentLocation","name","routeNames","routeName","push"],"sourceRoot":"../../src","sources":["checkDuplicateRouteNames.tsx"],"mappings":";;AAEA,OAAO,SAASA,wBAAwBA,CAACC,KAAsB,EAAE;EAC/D,MAAMC,UAAsB,GAAG,EAAE;EAEjC,MAAMC,aAAa,GAAGA,CACpBC,QAAgB,EAChBH,KAAsD,KACnD;IACHA,KAAK,CAACI,MAAM,CAACC,OAAO,CAAEC,KAA+B,IAAK;MACxD,MAAMC,eAAe,GAAGJ,QAAQ,GAC5B,GAAGA,QAAQ,MAAMG,KAAK,CAACE,IAAI,EAAE,GAC7BF,KAAK,CAACE,IAAI;MAEdF,KAAK,CAACN,KAAK,EAAES,UAAU,EAAEJ,OAAO,CAAEK,SAAS,IAAK;QAC9C,IAAIA,SAAS,KAAKJ,KAAK,CAACE,IAAI,EAAE;UAC5BP,UAAU,CAACU,IAAI,CAAC,CACdJ,eAAe,EACf,GAAGA,eAAe,MAAMD,KAAK,CAACE,IAAI,EAAE,CACrC,CAAC;QACJ;MACF,CAAC,CAAC;MAEF,IAAIF,KAAK,CAACN,KAAK,EAAE;QACfE,aAAa,CAACK,eAAe,EAAED,KAAK,CAACN,KAAK,CAAC;MAC7C;IACF,CAAC,CAAC;EACJ,CAAC;EAEDE,aAAa,CAAC,EAAE,EAAEF,KAAK,CAAC;EAExB,OAAOC,UAAU;AACnB","ignoreList":[]}

View File

@@ -0,0 +1,46 @@
"use strict";
const checkSerializableWithoutCircularReference = (o, seen, location) => {
if (o === undefined || o === null || typeof o === 'boolean' || typeof o === 'number' || typeof o === 'string') {
return {
serializable: true
};
}
if (Object.prototype.toString.call(o) !== '[object Object]' && !Array.isArray(o)) {
return {
serializable: false,
location,
reason: typeof o === 'function' ? 'Function' : String(o)
};
}
if (seen.has(o)) {
return {
serializable: false,
reason: 'Circular reference',
location
};
}
seen.add(o);
if (Array.isArray(o)) {
for (let i = 0; i < o.length; i++) {
const childResult = checkSerializableWithoutCircularReference(o[i], new Set(seen), [...location, i]);
if (!childResult.serializable) {
return childResult;
}
}
} else {
for (const key in o) {
const childResult = checkSerializableWithoutCircularReference(o[key], new Set(seen), [...location, key]);
if (!childResult.serializable) {
return childResult;
}
}
}
return {
serializable: true
};
};
export function checkSerializable(o) {
return checkSerializableWithoutCircularReference(o, new Set(), []);
}
//# sourceMappingURL=checkSerializable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["checkSerializableWithoutCircularReference","o","seen","location","undefined","serializable","Object","prototype","toString","call","Array","isArray","reason","String","has","add","i","length","childResult","Set","key","checkSerializable"],"sourceRoot":"../../src","sources":["checkSerializable.tsx"],"mappings":";;AAAA,MAAMA,yCAAyC,GAAGA,CAChDC,CAAyB,EACzBC,IAAc,EACdC,QAA6B,KAOtB;EACP,IACEF,CAAC,KAAKG,SAAS,IACfH,CAAC,KAAK,IAAI,IACV,OAAOA,CAAC,KAAK,SAAS,IACtB,OAAOA,CAAC,KAAK,QAAQ,IACrB,OAAOA,CAAC,KAAK,QAAQ,EACrB;IACA,OAAO;MAAEI,YAAY,EAAE;IAAK,CAAC;EAC/B;EAEA,IACEC,MAAM,CAACC,SAAS,CAACC,QAAQ,CAACC,IAAI,CAACR,CAAC,CAAC,KAAK,iBAAiB,IACvD,CAACS,KAAK,CAACC,OAAO,CAACV,CAAC,CAAC,EACjB;IACA,OAAO;MACLI,YAAY,EAAE,KAAK;MACnBF,QAAQ;MACRS,MAAM,EAAE,OAAOX,CAAC,KAAK,UAAU,GAAG,UAAU,GAAGY,MAAM,CAACZ,CAAC;IACzD,CAAC;EACH;EAEA,IAAIC,IAAI,CAACY,GAAG,CAACb,CAAC,CAAC,EAAE;IACf,OAAO;MACLI,YAAY,EAAE,KAAK;MACnBO,MAAM,EAAE,oBAAoB;MAC5BT;IACF,CAAC;EACH;EAEAD,IAAI,CAACa,GAAG,CAACd,CAAC,CAAC;EAEX,IAAIS,KAAK,CAACC,OAAO,CAACV,CAAC,CAAC,EAAE;IACpB,KAAK,IAAIe,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGf,CAAC,CAACgB,MAAM,EAAED,CAAC,EAAE,EAAE;MACjC,MAAME,WAAW,GAAGlB,yCAAyC,CAC3DC,CAAC,CAACe,CAAC,CAAC,EACJ,IAAIG,GAAG,CAAMjB,IAAI,CAAC,EAClB,CAAC,GAAGC,QAAQ,EAAEa,CAAC,CACjB,CAAC;MAED,IAAI,CAACE,WAAW,CAACb,YAAY,EAAE;QAC7B,OAAOa,WAAW;MACpB;IACF;EACF,CAAC,MAAM;IACL,KAAK,MAAME,GAAG,IAAInB,CAAC,EAAE;MACnB,MAAMiB,WAAW,GAAGlB,yCAAyC,CAC3DC,CAAC,CAACmB,GAAG,CAAC,EACN,IAAID,GAAG,CAAMjB,IAAI,CAAC,EAClB,CAAC,GAAGC,QAAQ,EAAEiB,GAAG,CACnB,CAAC;MAED,IAAI,CAACF,WAAW,CAACb,YAAY,EAAE;QAC7B,OAAOa,WAAW;MACpB;IACF;EACF;EAEA,OAAO;IAAEb,YAAY,EAAE;EAAK,CAAC;AAC/B,CAAC;AAED,OAAO,SAASgB,iBAAiBA,CAACpB,CAAyB,EAAE;EAC3D,OAAOD,yCAAyC,CAACC,CAAC,EAAE,IAAIkB,GAAG,CAAM,CAAC,EAAE,EAAE,CAAC;AACzE","ignoreList":[]}

View File

@@ -0,0 +1,64 @@
"use strict";
import { CommonActions } from '@react-navigation/routers';
export const NOT_INITIALIZED_ERROR = "The 'navigation' object hasn't been initialized yet. This might happen if you don't have a navigator mounted, or if the navigator hasn't finished mounting. See https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization for more details.";
export function createNavigationContainerRef() {
const methods = [...Object.keys(CommonActions), 'addListener', 'removeListener', 'resetRoot', 'dispatch', 'isFocused', 'canGoBack', 'getRootState', 'getState', 'getParent', 'getCurrentRoute', 'getCurrentOptions'];
const listeners = {};
const removeListener = (event, callback) => {
if (listeners[event]) {
listeners[event] = listeners[event].filter(cb => cb !== callback);
}
};
let current = null;
const ref = {
get current() {
return current;
},
set current(value) {
current = value;
if (value != null) {
Object.entries(listeners).forEach(([event, callbacks]) => {
callbacks.forEach(callback => {
value.addListener(event, callback);
});
});
}
},
isReady: () => {
if (current == null) {
return false;
}
return current.isReady();
},
...methods.reduce((acc, name) => {
acc[name] = (...args) => {
if (current == null) {
switch (name) {
case 'addListener':
{
const [event, callback] = args;
listeners[event] = listeners[event] || [];
listeners[event].push(callback);
return () => removeListener(event, callback);
}
case 'removeListener':
{
const [event, callback] = args;
removeListener(event, callback);
break;
}
default:
console.error(NOT_INITIALIZED_ERROR);
}
} else {
// @ts-expect-error: this is ok
return current[name](...args);
}
};
return acc;
}, {})
};
return ref;
}
//# sourceMappingURL=createNavigationContainerRef.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["CommonActions","NOT_INITIALIZED_ERROR","createNavigationContainerRef","methods","Object","keys","listeners","removeListener","event","callback","filter","cb","current","ref","value","entries","forEach","callbacks","addListener","isReady","reduce","acc","name","args","push","console","error"],"sourceRoot":"../../src","sources":["createNavigationContainerRef.tsx"],"mappings":";;AAAA,SAASA,aAAa,QAAQ,2BAA2B;AAQzD,OAAO,MAAMC,qBAAqB,GAChC,+QAA+Q;AAEjR,OAAO,SAASC,4BAA4BA,CAAA,EAEM;EAChD,MAAMC,OAAO,GAAG,CACd,GAAGC,MAAM,CAACC,IAAI,CAACL,aAAa,CAAC,EAC7B,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,mBAAmB,CACX;EAEV,MAAMM,SAAuD,GAAG,CAAC,CAAC;EAElE,MAAMC,cAAc,GAAGA,CACrBC,KAAa,EACbC,QAAkC,KAC/B;IACH,IAAIH,SAAS,CAACE,KAAK,CAAC,EAAE;MACpBF,SAAS,CAACE,KAAK,CAAC,GAAGF,SAAS,CAACE,KAAK,CAAC,CAACE,MAAM,CAAEC,EAAE,IAAKA,EAAE,KAAKF,QAAQ,CAAC;IACrE;EACF,CAAC;EAED,IAAIG,OAAiD,GAAG,IAAI;EAE5D,MAAMC,GAAiD,GAAG;IACxD,IAAID,OAAOA,CAAA,EAAG;MACZ,OAAOA,OAAO;IAChB,CAAC;IACD,IAAIA,OAAOA,CAACE,KAA+C,EAAE;MAC3DF,OAAO,GAAGE,KAAK;MAEf,IAAIA,KAAK,IAAI,IAAI,EAAE;QACjBV,MAAM,CAACW,OAAO,CAACT,SAAS,CAAC,CAACU,OAAO,CAAC,CAAC,CAACR,KAAK,EAAES,SAAS,CAAC,KAAK;UACxDA,SAAS,CAACD,OAAO,CAAEP,QAAQ,IAAK;YAC9BK,KAAK,CAACI,WAAW,CACfV,KAAK,EACLC,QACF,CAAC;UACH,CAAC,CAAC;QACJ,CAAC,CAAC;MACJ;IACF,CAAC;IACDU,OAAO,EAAEA,CAAA,KAAM;MACb,IAAIP,OAAO,IAAI,IAAI,EAAE;QACnB,OAAO,KAAK;MACd;MAEA,OAAOA,OAAO,CAACO,OAAO,CAAC,CAAC;IAC1B,CAAC;IACD,GAAGhB,OAAO,CAACiB,MAAM,CAAM,CAACC,GAAG,EAAEC,IAAI,KAAK;MACpCD,GAAG,CAACC,IAAI,CAAC,GAAG,CAAC,GAAGC,IAAW,KAAK;QAC9B,IAAIX,OAAO,IAAI,IAAI,EAAE;UACnB,QAAQU,IAAI;YACV,KAAK,aAAa;cAAE;gBAClB,MAAM,CAACd,KAAK,EAAEC,QAAQ,CAAC,GAAGc,IAAI;gBAE9BjB,SAAS,CAACE,KAAK,CAAC,GAAGF,SAAS,CAACE,KAAK,CAAC,IAAI,EAAE;gBACzCF,SAAS,CAACE,KAAK,CAAC,CAACgB,IAAI,CAACf,QAAQ,CAAC;gBAE/B,OAAO,MAAMF,cAAc,CAACC,KAAK,EAAEC,QAAQ,CAAC;cAC9C;YACA,KAAK,gBAAgB;cAAE;gBACrB,MAAM,CAACD,KAAK,EAAEC,QAAQ,CAAC,GAAGc,IAAI;gBAE9BhB,cAAc,CAACC,KAAK,EAAEC,QAAQ,CAAC;gBAC/B;cACF;YACA;cACEgB,OAAO,CAACC,KAAK,CAACzB,qBAAqB,CAAC;UACxC;QACF,CAAC,MAAM;UACL;UACA,OAAOW,OAAO,CAACU,IAAI,CAAC,CAAC,GAAGC,IAAI,CAAC;QAC/B;MACF,CAAC;MACD,OAAOF,GAAG;IACZ,CAAC,EAAE,CAAC,CAAC;EACP,CAAC;EAED,OAAOR,GAAG;AACZ","ignoreList":[]}

View File

@@ -0,0 +1,31 @@
"use strict";
import { Group } from "./Group.js";
import { Screen } from "./Screen.js";
/**
* Higher order component to create a `Navigator` and `Screen` pair.
* Custom navigators should wrap the navigator component in `createNavigator` before exporting.
*
* @param Navigator The navigator component to wrap.
* @returns Factory method to create a `Navigator` and `Screen` pair.
*/
export function createNavigatorFactory(Navigator) {
function createNavigator(config) {
if (config != null) {
return {
Navigator,
Screen,
Group,
config
};
}
return {
Navigator,
Screen,
Group
};
}
return createNavigator;
}
//# sourceMappingURL=createNavigatorFactory.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["Group","Screen","createNavigatorFactory","Navigator","createNavigator","config"],"sourceRoot":"../../src","sources":["createNavigatorFactory.tsx"],"mappings":";;AAEA,SAASA,KAAK,QAAQ,YAAS;AAC/B,SAASC,MAAM,QAAQ,aAAU;;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,sBAAsBA,CAACC,SAAmC,EAAE;EAC1E,SAASC,eAAeA,CAACC,MAAY,EAAO;IAC1C,IAAIA,MAAM,IAAI,IAAI,EAAE;MAClB,OAAO;QACLF,SAAS;QACTF,MAAM;QACND,KAAK;QACLK;MACF,CAAC;IACH;IAEA,OAAO;MACLF,SAAS;MACTF,MAAM;MACND;IACF,CAAC;EACH;EAEA,OAAOI,eAAe;AACxB","ignoreList":[]}

View File

@@ -0,0 +1,34 @@
"use strict";
export const isPlainObject = value => {
if (typeof value === 'object' && value !== null) {
return Object.getPrototypeOf(value) === Object.prototype;
}
return false;
};
export const deepFreeze = object => {
// We only freeze in development to catch issues early
// Don't freeze in production to avoid unnecessary performance overhead
if (process.env.NODE_ENV === 'production') {
return object;
}
if (Object.isFrozen(object)) {
return object;
}
if (!isPlainObject(object) && !Array.isArray(object)) {
return object;
}
// Freeze properties before freezing self
for (const key in object) {
// Don't freeze objects in params since they are passed by the user
if (key !== 'params') {
if (Object.getOwnPropertyDescriptor(object, key)?.configurable) {
const value = object[key];
deepFreeze(value);
}
}
}
return Object.freeze(object);
};
//# sourceMappingURL=deepFreeze.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["isPlainObject","value","Object","getPrototypeOf","prototype","deepFreeze","object","process","env","NODE_ENV","isFrozen","Array","isArray","key","getOwnPropertyDescriptor","configurable","freeze"],"sourceRoot":"../../src","sources":["deepFreeze.tsx"],"mappings":";;AAAA,OAAO,MAAMA,aAAa,GAAIC,KAAc,IAAsB;EAChE,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,IAAI,EAAE;IAC/C,OAAOC,MAAM,CAACC,cAAc,CAACF,KAAK,CAAC,KAAKC,MAAM,CAACE,SAAS;EAC1D;EAEA,OAAO,KAAK;AACd,CAAC;AAED,OAAO,MAAMC,UAAU,GAAQC,MAAS,IAAkB;EACxD;EACA;EACA,IAAIC,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,EAAE;IACzC,OAAOH,MAAM;EACf;EAEA,IAAIJ,MAAM,CAACQ,QAAQ,CAACJ,MAAM,CAAC,EAAE;IAC3B,OAAOA,MAAM;EACf;EAEA,IAAI,CAACN,aAAa,CAACM,MAAM,CAAC,IAAI,CAACK,KAAK,CAACC,OAAO,CAACN,MAAM,CAAC,EAAE;IACpD,OAAOA,MAAM;EACf;;EAEA;EACA,KAAK,MAAMO,GAAG,IAAIP,MAAM,EAAE;IACxB;IACA,IAAIO,GAAG,KAAK,QAAQ,EAAE;MACpB,IAAIX,MAAM,CAACY,wBAAwB,CAACR,MAAM,EAAEO,GAAG,CAAC,EAAEE,YAAY,EAAE;QAC9D,MAAMd,KAAK,GAAGK,MAAM,CAACO,GAAG,CAAC;QAEzBR,UAAU,CAACJ,KAAK,CAAC;MACnB;IACF;EACF;EAEA,OAAOC,MAAM,CAACc,MAAM,CAACV,MAAM,CAAC;AAC9B,CAAC","ignoreList":[]}

View File

@@ -0,0 +1,11 @@
"use strict";
export function findFocusedRoute(state) {
let current = state;
while (current?.routes[current.index ?? 0].state != null) {
current = current.routes[current.index ?? 0].state;
}
const route = current?.routes[current?.index ?? 0];
return route;
}
//# sourceMappingURL=findFocusedRoute.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["findFocusedRoute","state","current","routes","index","route"],"sourceRoot":"../../src","sources":["findFocusedRoute.tsx"],"mappings":";;AAWA,OAAO,SAASA,gBAAgBA,CAACC,KAAmB,EAAU;EAC5D,IAAIC,OAAiC,GAAGD,KAAK;EAE7C,OAAOC,OAAO,EAAEC,MAAM,CAACD,OAAO,CAACE,KAAK,IAAI,CAAC,CAAC,CAACH,KAAK,IAAI,IAAI,EAAE;IACxDC,OAAO,GAAGA,OAAO,CAACC,MAAM,CAACD,OAAO,CAACE,KAAK,IAAI,CAAC,CAAC,CAACH,KAAK;EACpD;EAEA,MAAMI,KAAK,GAAGH,OAAO,EAAEC,MAAM,CAACD,OAAO,EAAEE,KAAK,IAAI,CAAC,CAAC;EAElD,OAAOC,KAAK;AACd","ignoreList":[]}

View File

@@ -0,0 +1,107 @@
"use strict";
export function getActionFromState(state, options) {
// Create a normalized configs object which will be easier to use
const normalizedConfig = options ? createNormalizedConfigItem(options) : {};
const routes = state.index != null ? state.routes.slice(0, state.index + 1) : state.routes;
if (routes.length === 0) {
return undefined;
}
if (!(routes.length === 1 && routes[0].key === undefined || routes.length === 2 && routes[0].key === undefined && routes[0].name === normalizedConfig?.initialRouteName && routes[1].key === undefined)) {
return {
type: 'RESET',
payload: state
};
}
const route = state.routes[state.index ?? state.routes.length - 1];
let current = route?.state;
let config = normalizedConfig?.screens?.[route?.name];
let params = {
...route.params
};
const payload = route ? {
name: route.name,
path: route.path,
params
} : undefined;
// If the screen contains a navigator, pop other screens to navigate to it
// This avoid pushing multiple instances of navigators onto a stack
//
// For example:
// - RootStack
// - BottomTabs
// - SomeScreen
//
// In this case, if deep linking to `BottomTabs`, we should pop `SomeScreen`
// Otherwise, we'll end up with 2 instances of `BottomTabs` in the stack
//
// There are 2 ways we can detect if a screen contains a navigator:
// - The route contains nested state in `route.state`
// - Nested screens are defined in the config
if (payload && config?.screens && Object.keys(config.screens).length) {
payload.pop = true;
}
while (current) {
if (current.routes.length === 0) {
return undefined;
}
const routes = current.index != null ? current.routes.slice(0, current.index + 1) : current.routes;
const route = routes[routes.length - 1];
// Explicitly set to override existing value when merging params
Object.assign(params, {
initial: undefined,
screen: undefined,
params: undefined,
state: undefined
});
if (routes.length === 1 && routes[0].key === undefined) {
params.initial = true;
params.screen = route.name;
} else if (routes.length === 2 && routes[0].key === undefined && routes[0].name === config?.initialRouteName && routes[1].key === undefined) {
params.initial = false;
params.screen = route.name;
} else {
params.state = current;
break;
}
if (route.state) {
params.params = {
...route.params
};
params.pop = true;
params = params.params;
} else {
params.path = route.path;
params.params = route.params;
}
current = route.state;
config = config?.screens?.[route.name];
if (config?.screens && Object.keys(config.screens).length) {
params.pop = true;
}
}
if (payload?.params.screen || payload?.params.state) {
payload.pop = true;
}
if (!payload) {
return;
}
// Try to construct payload for a `NAVIGATE` action from the state
// This lets us preserve the navigation state and not lose it
return {
type: 'NAVIGATE',
payload
};
}
const createNormalizedConfigItem = config => typeof config === 'object' && config != null ? {
initialRouteName: config.initialRouteName,
screens: config.screens != null ? createNormalizedConfigs(config.screens) : undefined
} : {};
const createNormalizedConfigs = options => Object.entries(options).reduce((acc, [k, v]) => {
acc[k] = createNormalizedConfigItem(v);
return acc;
}, {});
//# sourceMappingURL=getActionFromState.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["getActionFromState","state","options","normalizedConfig","createNormalizedConfigItem","routes","index","slice","length","undefined","key","name","initialRouteName","type","payload","route","current","config","screens","params","path","Object","keys","pop","assign","initial","screen","createNormalizedConfigs","entries","reduce","acc","k","v"],"sourceRoot":"../../src","sources":["getActionFromState.tsx"],"mappings":"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","ignoreList":[]}

View File

@@ -0,0 +1,18 @@
"use strict";
import { CHILD_STATE } from "./useRouteCache.js";
export function getFocusedRouteNameFromRoute(route) {
// @ts-expect-error: this isn't in type definitions coz we want this private
const state = route[CHILD_STATE] ?? route.state;
const params = route.params;
const routeName = state ?
// Get the currently active route name in the nested navigator
state.routes[
// If we have a partial state without index, for tab/drawer, first screen will be focused one, and last for stack
// The type property will only exist for rehydrated state and not for state from deep link
state.index ?? (typeof state.type === 'string' && state.type !== 'stack' ? 0 : state.routes.length - 1)].name :
// If state doesn't exist, we need to default to `screen` param if available
typeof params?.screen === 'string' ? params.screen : undefined;
return routeName;
}
//# sourceMappingURL=getFocusedRouteNameFromRoute.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["CHILD_STATE","getFocusedRouteNameFromRoute","route","state","params","routeName","routes","index","type","length","name","screen","undefined"],"sourceRoot":"../../src","sources":["getFocusedRouteNameFromRoute.tsx"],"mappings":";;AAEA,SAASA,WAAW,QAAQ,oBAAiB;AAE7C,OAAO,SAASC,4BAA4BA,CAC1CC,KAA6B,EACT;EACpB;EACA,MAAMC,KAAK,GAAGD,KAAK,CAACF,WAAW,CAAC,IAAIE,KAAK,CAACC,KAAK;EAC/C,MAAMC,MAAM,GAAGF,KAAK,CAACE,MAA0C;EAE/D,MAAMC,SAAS,GAAGF,KAAK;EACnB;EACAA,KAAK,CAACG,MAAM;EACV;EACA;EACAH,KAAK,CAACI,KAAK,KACR,OAAOJ,KAAK,CAACK,IAAI,KAAK,QAAQ,IAAIL,KAAK,CAACK,IAAI,KAAK,OAAO,GACrD,CAAC,GACDL,KAAK,CAACG,MAAM,CAACG,MAAM,GAAG,CAAC,CAAC,CAC/B,CAACC,IAAI;EACN;EACA,OAAON,MAAM,EAAEO,MAAM,KAAK,QAAQ,GAChCP,MAAM,CAACO,MAAM,GACbC,SAAS;EAEf,OAAOP,SAAS;AAClB","ignoreList":[]}

View File

@@ -0,0 +1,235 @@
"use strict";
import * as queryString from 'query-string';
import { getPatternParts } from "./getPatternParts.js";
import { validatePathConfig } from "./validatePathConfig.js";
const getActiveRoute = state => {
const route = typeof state.index === 'number' ? state.routes[state.index] : state.routes[state.routes.length - 1];
if (route.state) {
return getActiveRoute(route.state);
}
return route;
};
const cachedNormalizedConfigs = new WeakMap();
const getNormalizedConfigs = options => {
if (!options?.screens) return {};
const cached = cachedNormalizedConfigs.get(options?.screens);
if (cached) return cached;
const normalizedConfigs = createNormalizedConfigs(options.screens);
cachedNormalizedConfigs.set(options.screens, normalizedConfigs);
return normalizedConfigs;
};
/**
* Utility to serialize a navigation state object to a path string.
*
* @example
* ```js
* getPathFromState(
* {
* routes: [
* {
* name: 'Chat',
* params: { author: 'Jane', id: 42 },
* },
* ],
* },
* {
* screens: {
* Chat: {
* path: 'chat/:author/:id',
* stringify: { author: author => author.toLowerCase() }
* }
* }
* }
* )
* ```
*
* @param state Navigation state to serialize.
* @param options Extra options to fine-tune how to serialize the path.
* @returns Path representing the state, e.g. /foo/bar?count=42.
*/
export function getPathFromState(state, options) {
if (state == null) {
throw Error(`Got '${String(state)}' for the navigation state. You must pass a valid state object.`);
}
if (options) {
validatePathConfig(options);
}
const configs = getNormalizedConfigs(options);
let path = '/';
let current = state;
const allParams = {};
while (current) {
let index = typeof current.index === 'number' ? current.index : 0;
let route = current.routes[index];
let parts;
let focusedParams;
let currentOptions = configs;
const focusedRoute = getActiveRoute(state);
// Keep all the route names that appeared during going deeper in config in case the pattern is resolved to undefined
const nestedRouteNames = [];
let hasNext = true;
while (route.name in currentOptions && hasNext) {
parts = currentOptions[route.name].parts;
nestedRouteNames.push(route.name);
if (route.params) {
const options = currentOptions[route.name];
const currentParams = Object.fromEntries(Object.entries(route.params).map(([key, value]) => {
if (value === undefined) {
if (options) {
const optional = options.parts?.find(part => part.param === key)?.optional;
if (optional) {
return null;
}
} else {
return null;
}
}
const stringify = options?.stringify?.[key] ?? String;
return [key, stringify(value)];
}).filter(entry => entry != null));
if (parts?.length) {
Object.assign(allParams, currentParams);
}
if (focusedRoute === route) {
// If this is the focused route, keep the params for later use
// We save it here since it's been stringified already
focusedParams = {
...currentParams
};
parts
// eslint-disable-next-line no-loop-func
?.forEach(({
param
}) => {
if (param) {
// Remove the params present in the pattern since we'll only use the rest for query string
if (focusedParams) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete focusedParams[param];
}
}
});
}
}
// If there is no `screens` property or no nested state, we return pattern
if (!currentOptions[route.name].screens || route.state === undefined) {
hasNext = false;
} else {
index = typeof route.state.index === 'number' ? route.state.index : route.state.routes.length - 1;
const nextRoute = route.state.routes[index];
const nestedConfig = currentOptions[route.name].screens;
// if there is config for next route name, we go deeper
if (nestedConfig && nextRoute.name in nestedConfig) {
route = nextRoute;
currentOptions = nestedConfig;
} else {
// If not, there is no sense in going deeper in config
hasNext = false;
}
}
}
if (currentOptions[route.name] !== undefined) {
path += parts?.map(({
segment,
param,
optional
}) => {
// We don't know what to show for wildcard patterns
// Showing the route name seems ok, though whatever we show here will be incorrect
// Since the page doesn't actually exist
if (segment === '*') {
return route.name;
}
// If the path has a pattern for a param, put the param in the path
if (param) {
const value = allParams[param];
if (value === undefined && optional) {
// Optional params without value assigned in route.params should be ignored
return '';
}
// Valid characters according to
// https://datatracker.ietf.org/doc/html/rfc3986#section-3.3 (see pchar definition)
return Array.from(String(value)).map(char => /[^A-Za-z0-9\-._~!$&'()*+,;=:@]/g.test(char) ? encodeURIComponent(char) : char).join('');
}
return encodeURIComponent(segment);
}).join('/');
} else {
path += encodeURIComponent(route.name);
}
if (!focusedParams && focusedRoute.params) {
focusedParams = Object.fromEntries(Object.entries(focusedRoute.params).map(([key, value]) => [key, String(value)]));
}
if (route.state) {
path += '/';
} else if (focusedParams) {
for (const param in focusedParams) {
if (focusedParams[param] === 'undefined') {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete focusedParams[param];
}
}
const query = queryString.stringify(focusedParams, {
sort: false
});
if (query) {
path += `?${query}`;
}
}
current = route.state;
}
// Include the root path if specified
if (options?.path) {
path = `${options.path}/${path}`;
}
// Remove multiple as well as trailing slashes
path = path.replace(/\/+/g, '/');
path = path.length > 1 ? path.replace(/\/$/, '') : path;
// If path doesn't start with a slash, add it
// This makes sure that history.pushState will update the path correctly instead of appending
if (!path.startsWith('/')) {
path = `/${path}`;
}
return path;
}
const createConfigItem = (config, parentParts) => {
if (typeof config === 'string') {
// If a string is specified as the value of the key(e.g. Foo: '/path'), use it as the pattern
const parts = getPatternParts(config);
if (parentParts) {
return {
parts: [...parentParts, ...parts]
};
}
return {
parts
};
}
if (config.exact && config.path === undefined) {
throw new Error("A 'path' needs to be specified when specifying 'exact: true'. If you don't want this screen in the URL, specify it as empty string, e.g. `path: ''`.");
}
// If an object is specified as the value (e.g. Foo: { ... }),
// It can have `path` property and `screens` prop which has nested configs
const parts = config.exact !== true ? [...(parentParts || []), ...(config.path ? getPatternParts(config.path) : [])] : config.path ? getPatternParts(config.path) : undefined;
const screens = config.screens ? createNormalizedConfigs(config.screens, parts) : undefined;
return {
parts,
stringify: config.stringify,
screens
};
};
const createNormalizedConfigs = (options, parts) => Object.fromEntries(Object.entries(options).map(([name, c]) => {
const result = createConfigItem(c, parts);
return [name, result];
}));
//# sourceMappingURL=getPathFromState.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,101 @@
"use strict";
/**
* Parse a path into an array of parts with information about each segment.
*/
export function getPatternParts(path) {
const parts = [];
let current = {
segment: ''
};
let isRegex = false;
let isParam = false;
let regexInnerParens = 0;
// One extra iteration to add the last character
for (let i = 0; i <= path.length; i++) {
const char = path[i];
if (char != null) {
current.segment += char;
}
if (char === ':') {
// The segment must start with a colon if it's a param
if (current.segment === ':') {
isParam = true;
} else if (!isRegex) {
throw new Error(`Encountered ':' in the middle of a segment in path: ${path}`);
}
} else if (char === '(') {
if (isParam) {
if (isRegex) {
// The '(' is part of the regex if we're already inside one
regexInnerParens++;
} else {
isRegex = true;
}
} else {
throw new Error(`Encountered '(' without preceding ':' in path: ${path}`);
}
} else if (char === ')') {
if (isParam && isRegex) {
if (regexInnerParens) {
// The ')' is part of the regex if we're already inside one
regexInnerParens--;
current.regex += char;
} else {
isRegex = false;
isParam = false;
}
} else {
throw new Error(`Encountered ')' without preceding '(' in path: ${path}`);
}
} else if (char === '?') {
if (current.param) {
isParam = false;
current.optional = true;
} else {
throw new Error(`Encountered '?' without preceding ':' in path: ${path}`);
}
} else if (char == null || char === '/' && !isRegex) {
isParam = false;
// Remove trailing slash from segment
current.segment = current.segment.replace(/\/$/, '');
if (current.segment === '') {
continue;
}
if (current.param) {
current.param = current.param.replace(/^:/, '');
}
if (current.regex) {
current.regex = current.regex.replace(/^\(/, '').replace(/\)$/, '');
}
parts.push(current);
if (char == null) {
break;
}
current = {
segment: ''
};
}
if (isRegex) {
current.regex = current.regex || '';
current.regex += char;
}
if (isParam && !isRegex) {
current.param = current.param || '';
current.param += char;
}
}
if (isRegex) {
throw new Error(`Could not find closing ')' in path: ${path}`);
}
const params = parts.map(part => part.param).filter(Boolean);
for (const [index, param] of params.entries()) {
if (params.indexOf(param) !== index) {
throw new Error(`Duplicate param name '${param}' found in path: ${path}`);
}
}
return parts;
}
//# sourceMappingURL=getPatternParts.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["getPatternParts","path","parts","current","segment","isRegex","isParam","regexInnerParens","i","length","char","Error","regex","param","optional","replace","push","params","map","part","filter","Boolean","index","entries","indexOf"],"sourceRoot":"../../src","sources":["getPatternParts.tsx"],"mappings":";;AAOA;AACA;AACA;AACA,OAAO,SAASA,eAAeA,CAACC,IAAY,EAAiB;EAC3D,MAAMC,KAAoB,GAAG,EAAE;EAE/B,IAAIC,OAAoB,GAAG;IAAEC,OAAO,EAAE;EAAG,CAAC;EAE1C,IAAIC,OAAO,GAAG,KAAK;EACnB,IAAIC,OAAO,GAAG,KAAK;EACnB,IAAIC,gBAAgB,GAAG,CAAC;;EAExB;EACA,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,IAAIP,IAAI,CAACQ,MAAM,EAAED,CAAC,EAAE,EAAE;IACrC,MAAME,IAAI,GAAGT,IAAI,CAACO,CAAC,CAAC;IAEpB,IAAIE,IAAI,IAAI,IAAI,EAAE;MAChBP,OAAO,CAACC,OAAO,IAAIM,IAAI;IACzB;IAEA,IAAIA,IAAI,KAAK,GAAG,EAAE;MAChB;MACA,IAAIP,OAAO,CAACC,OAAO,KAAK,GAAG,EAAE;QAC3BE,OAAO,GAAG,IAAI;MAChB,CAAC,MAAM,IAAI,CAACD,OAAO,EAAE;QACnB,MAAM,IAAIM,KAAK,CACb,uDAAuDV,IAAI,EAC7D,CAAC;MACH;IACF,CAAC,MAAM,IAAIS,IAAI,KAAK,GAAG,EAAE;MACvB,IAAIJ,OAAO,EAAE;QACX,IAAID,OAAO,EAAE;UACX;UACAE,gBAAgB,EAAE;QACpB,CAAC,MAAM;UACLF,OAAO,GAAG,IAAI;QAChB;MACF,CAAC,MAAM;QACL,MAAM,IAAIM,KAAK,CACb,kDAAkDV,IAAI,EACxD,CAAC;MACH;IACF,CAAC,MAAM,IAAIS,IAAI,KAAK,GAAG,EAAE;MACvB,IAAIJ,OAAO,IAAID,OAAO,EAAE;QACtB,IAAIE,gBAAgB,EAAE;UACpB;UACAA,gBAAgB,EAAE;UAClBJ,OAAO,CAACS,KAAK,IAAIF,IAAI;QACvB,CAAC,MAAM;UACLL,OAAO,GAAG,KAAK;UACfC,OAAO,GAAG,KAAK;QACjB;MACF,CAAC,MAAM;QACL,MAAM,IAAIK,KAAK,CACb,kDAAkDV,IAAI,EACxD,CAAC;MACH;IACF,CAAC,MAAM,IAAIS,IAAI,KAAK,GAAG,EAAE;MACvB,IAAIP,OAAO,CAACU,KAAK,EAAE;QACjBP,OAAO,GAAG,KAAK;QAEfH,OAAO,CAACW,QAAQ,GAAG,IAAI;MACzB,CAAC,MAAM;QACL,MAAM,IAAIH,KAAK,CACb,kDAAkDV,IAAI,EACxD,CAAC;MACH;IACF,CAAC,MAAM,IAAIS,IAAI,IAAI,IAAI,IAAKA,IAAI,KAAK,GAAG,IAAI,CAACL,OAAQ,EAAE;MACrDC,OAAO,GAAG,KAAK;;MAEf;MACAH,OAAO,CAACC,OAAO,GAAGD,OAAO,CAACC,OAAO,CAACW,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;MAEpD,IAAIZ,OAAO,CAACC,OAAO,KAAK,EAAE,EAAE;QAC1B;MACF;MAEA,IAAID,OAAO,CAACU,KAAK,EAAE;QACjBV,OAAO,CAACU,KAAK,GAAGV,OAAO,CAACU,KAAK,CAACE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;MACjD;MAEA,IAAIZ,OAAO,CAACS,KAAK,EAAE;QACjBT,OAAO,CAACS,KAAK,GAAGT,OAAO,CAACS,KAAK,CAACG,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAACA,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;MACrE;MAEAb,KAAK,CAACc,IAAI,CAACb,OAAO,CAAC;MAEnB,IAAIO,IAAI,IAAI,IAAI,EAAE;QAChB;MACF;MAEAP,OAAO,GAAG;QAAEC,OAAO,EAAE;MAAG,CAAC;IAC3B;IAEA,IAAIC,OAAO,EAAE;MACXF,OAAO,CAACS,KAAK,GAAGT,OAAO,CAACS,KAAK,IAAI,EAAE;MACnCT,OAAO,CAACS,KAAK,IAAIF,IAAI;IACvB;IAEA,IAAIJ,OAAO,IAAI,CAACD,OAAO,EAAE;MACvBF,OAAO,CAACU,KAAK,GAAGV,OAAO,CAACU,KAAK,IAAI,EAAE;MACnCV,OAAO,CAACU,KAAK,IAAIH,IAAI;IACvB;EACF;EAEA,IAAIL,OAAO,EAAE;IACX,MAAM,IAAIM,KAAK,CAAC,uCAAuCV,IAAI,EAAE,CAAC;EAChE;EAEA,MAAMgB,MAAM,GAAGf,KAAK,CAACgB,GAAG,CAAEC,IAAI,IAAKA,IAAI,CAACN,KAAK,CAAC,CAACO,MAAM,CAACC,OAAO,CAAC;EAE9D,KAAK,MAAM,CAACC,KAAK,EAAET,KAAK,CAAC,IAAII,MAAM,CAACM,OAAO,CAAC,CAAC,EAAE;IAC7C,IAAIN,MAAM,CAACO,OAAO,CAACX,KAAK,CAAC,KAAKS,KAAK,EAAE;MACnC,MAAM,IAAIX,KAAK,CAAC,yBAAyBE,KAAK,oBAAoBZ,IAAI,EAAE,CAAC;IAC3E;EACF;EAEA,OAAOC,KAAK;AACd","ignoreList":[]}

View File

@@ -0,0 +1,514 @@
"use strict";
import escape from 'escape-string-regexp';
import * as queryString from 'query-string';
import { arrayStartsWith } from "./arrayStartsWith.js";
import { findFocusedRoute } from "./findFocusedRoute.js";
import { getPatternParts } from "./getPatternParts.js";
import { isArrayEqual } from "./isArrayEqual.js";
import { validatePathConfig } from "./validatePathConfig.js";
/**
* Utility to parse a path string to initial state object accepted by the container.
* This is useful for deep linking when we need to handle the incoming URL.
*
* @example
* ```js
* getStateFromPath(
* '/chat/jane/42',
* {
* screens: {
* Chat: {
* path: 'chat/:author/:id',
* parse: { id: Number }
* }
* }
* }
* )
* ```
* @param path Path string to parse and convert, e.g. /foo/bar?count=42.
* @param options Extra options to fine-tune how to parse the path.
*/
export function getStateFromPath(path, options) {
const {
initialRoutes,
configs
} = getConfigResources(options);
const screens = options?.screens;
let remaining = path.replace(/\/+/g, '/') // Replace multiple slash (//) with single ones
.replace(/^\//, '') // Remove extra leading slash
.replace(/\?.*$/, ''); // Remove query params which we will handle later
// Make sure there is a trailing slash
remaining = remaining.endsWith('/') ? remaining : `${remaining}/`;
const prefix = options?.path?.replace(/^\//, ''); // Remove extra leading slash
if (prefix) {
// Make sure there is a trailing slash
const normalizedPrefix = prefix.endsWith('/') ? prefix : `${prefix}/`;
// If the path doesn't start with the prefix, it's not a match
if (!remaining.startsWith(normalizedPrefix)) {
return undefined;
}
// Remove the prefix from the path
remaining = remaining.replace(normalizedPrefix, '');
}
if (screens === undefined) {
// When no config is specified, use the path segments as route names
const routes = remaining.split('/').filter(Boolean).map(segment => {
const name = decodeURIComponent(segment);
return {
name
};
});
if (routes.length) {
return createNestedStateObject(path, routes, initialRoutes);
}
return undefined;
}
if (remaining === '/') {
// We need to add special handling of empty path so navigation to empty path also works
// When handling empty path, we should only look at the root level config
const match = configs.find(config => config.segments.join('/') === '');
if (match) {
return createNestedStateObject(path, match.routeNames.map(name => ({
name
})), initialRoutes, configs);
}
return undefined;
}
let result;
let current;
// We match the whole path against the regex instead of segments
// This makes sure matches such as wildcard will catch any unmatched routes, even if nested
const {
routes,
remainingPath
} = matchAgainstConfigs(remaining, configs);
if (routes !== undefined) {
// This will always be empty if full path matched
current = createNestedStateObject(path, routes, initialRoutes, configs);
remaining = remainingPath;
result = current;
}
if (current == null || result == null) {
return undefined;
}
return result;
}
/**
* Reference to the last used config resources. This is used to avoid recomputing the config resources when the options are the same.
*/
const cachedConfigResources = new WeakMap();
function getConfigResources(options) {
if (!options) return prepareConfigResources();
const cached = cachedConfigResources.get(options);
if (cached) return cached;
const resources = prepareConfigResources(options);
cachedConfigResources.set(options, resources);
return resources;
}
function prepareConfigResources(options) {
if (options) {
validatePathConfig(options);
}
const initialRoutes = getInitialRoutes(options);
const configs = getSortedNormalizedConfigs(initialRoutes, options?.screens);
checkForDuplicatedConfigs(configs);
const configWithRegexes = getConfigsWithRegexes(configs);
return {
initialRoutes,
configs,
configWithRegexes
};
}
function getInitialRoutes(options) {
const initialRoutes = [];
if (options?.initialRouteName) {
initialRoutes.push({
initialRouteName: options.initialRouteName,
parentScreens: []
});
}
return initialRoutes;
}
function getSortedNormalizedConfigs(initialRoutes, screens = {}) {
// Create a normalized configs array which will be easier to use
return [].concat(...Object.keys(screens).map(key => createNormalizedConfigs(key, screens, initialRoutes, [], [], []))).sort((a, b) => {
// Sort config from most specific to least specific:
// - more segments
// - static segments
// - params with regex
// - regular params
// - wildcard
// If 2 patterns are same, move the one with less route names up
// This is an error state, so it's only useful for consistent error messages
if (isArrayEqual(a.segments, b.segments)) {
return b.routeNames.join('>').localeCompare(a.routeNames.join('>'));
}
// If one of the patterns starts with the other, it's more exhaustive
// So move it up
if (arrayStartsWith(a.segments, b.segments)) {
return -1;
}
if (arrayStartsWith(b.segments, a.segments)) {
return 1;
}
for (let i = 0; i < Math.max(a.segments.length, b.segments.length); i++) {
// if b is longer, b gets higher priority
if (a.segments[i] == null) {
return 1;
}
// if a is longer, a gets higher priority
if (b.segments[i] == null) {
return -1;
}
const aWildCard = a.segments[i] === '*';
const bWildCard = b.segments[i] === '*';
const aParam = a.segments[i].startsWith(':');
const bParam = b.segments[i].startsWith(':');
const aRegex = aParam && a.segments[i].includes('(');
const bRegex = bParam && b.segments[i].includes('(');
// if both are wildcard or regex, we compare next component
if (aWildCard && bWildCard || aRegex && bRegex) {
continue;
}
// if only a is wildcard, b gets higher priority
if (aWildCard && !bWildCard) {
return 1;
}
// if only b is wildcard, a gets higher priority
if (bWildCard && !aWildCard) {
return -1;
}
// If only a has a param, b gets higher priority
if (aParam && !bParam) {
return 1;
}
// If only b has a param, a gets higher priority
if (bParam && !aParam) {
return -1;
}
// if only a has regex, a gets higher priority
if (aRegex && !bRegex) {
return -1;
}
// if only b has regex, b gets higher priority
if (bRegex && !aRegex) {
return 1;
}
}
return a.segments.length - b.segments.length;
});
}
function checkForDuplicatedConfigs(configs) {
// Check for duplicate patterns in the config
configs.reduce((acc, config) => {
const pattern = config.segments.join('/');
if (acc[pattern]) {
const a = acc[pattern].routeNames;
const b = config.routeNames;
// It's not a problem if the path string omitted from a inner most screen
// For example, it's ok if a path resolves to `A > B > C` or `A > B`
const intersects = a.length > b.length ? b.every((it, i) => a[i] === it) : a.every((it, i) => b[i] === it);
if (!intersects) {
throw new Error(`Found conflicting screens with the same pattern. The pattern '${pattern}' resolves to both '${a.join(' > ')}' and '${b.join(' > ')}'. Patterns must be unique and cannot resolve to more than one screen.`);
}
}
return Object.assign(acc, {
[pattern]: config
});
}, {});
}
function getConfigsWithRegexes(configs) {
return configs.map(c => ({
...c,
// Add `$` to the regex to make sure it matches till end of the path and not just beginning
regex: c.regex ? new RegExp(c.regex.source + '$') : undefined
}));
}
const matchAgainstConfigs = (remaining, configs) => {
let routes;
let remainingPath = remaining;
// Go through all configs, and see if the next path segment matches our regex
for (const config of configs) {
if (!config.regex) {
continue;
}
const match = remainingPath.match(config.regex);
// If our regex matches, we need to extract params from the path
if (match) {
routes = config.routeNames.map(routeName => {
const routeConfig = configs.find(c => {
// Check matching name AND pattern in case same screen is used at different levels in config
return c.screen === routeName && arrayStartsWith(config.segments, c.segments);
});
const params = routeConfig && match.groups ? Object.fromEntries(Object.entries(match.groups).map(([key, value]) => {
const index = Number(key.replace('param_', ''));
const param = routeConfig.params.find(it => it.index === index);
if (param?.screen === routeName && param?.name) {
return [param.name, value];
}
return null;
}).filter(it => it != null).map(([key, value]) => {
if (value == null) {
return [key, undefined];
}
const decoded = decodeURIComponent(value);
const parsed = routeConfig.parse?.[key] ? routeConfig.parse[key](decoded) : decoded;
return [key, parsed];
})) : undefined;
if (params && Object.keys(params).length) {
return {
name: routeName,
params
};
}
return {
name: routeName
};
});
remainingPath = remainingPath.replace(match[0], '');
break;
}
}
return {
routes,
remainingPath
};
};
const createNormalizedConfigs = (screen, routeConfig, initials, paths, parentScreens, routeNames) => {
const configs = [];
routeNames.push(screen);
parentScreens.push(screen);
const config = routeConfig[screen];
if (typeof config === 'string') {
paths.push({
screen,
path: config
});
configs.push(createConfigItem(screen, [...routeNames], [...paths]));
} else if (typeof config === 'object') {
// if an object is specified as the value (e.g. Foo: { ... }),
// it can have `path` property and
// it could have `screens` prop which has nested configs
if (typeof config.path === 'string') {
if (config.exact && config.path == null) {
throw new Error(`Screen '${screen}' doesn't specify a 'path'. A 'path' needs to be specified when specifying 'exact: true'. If you don't want this screen in the URL, specify it as empty string, e.g. \`path: ''\`.`);
}
// We should add alias configs after the main config
// So unless they are more specific, main config will be matched first
const aliasConfigs = [];
if (config.alias) {
for (const alias of config.alias) {
if (typeof alias === 'string') {
aliasConfigs.push(createConfigItem(screen, [...routeNames], [...paths, {
screen,
path: alias
}], config.parse));
} else if (typeof alias === 'object') {
aliasConfigs.push(createConfigItem(screen, [...routeNames], alias.exact ? [{
screen,
path: alias.path
}] : [...paths, {
screen,
path: alias.path
}], alias.parse));
}
}
}
if (config.exact) {
// If it's an exact path, we don't need to keep track of the parent screens
// So we can clear it
paths.length = 0;
}
paths.push({
screen,
path: config.path
});
configs.push(createConfigItem(screen, [...routeNames], [...paths], config.parse));
configs.push(...aliasConfigs);
}
if (typeof config !== 'string' && typeof config.path !== 'string' && config.alias?.length) {
throw new Error(`Screen '${screen}' doesn't specify a 'path'. A 'path' needs to be specified in order to use 'alias'.`);
}
if (config.screens) {
// property `initialRouteName` without `screens` has no purpose
if (config.initialRouteName) {
initials.push({
initialRouteName: config.initialRouteName,
parentScreens
});
}
Object.keys(config.screens).forEach(nestedConfig => {
const result = createNormalizedConfigs(nestedConfig, config.screens, initials, [...paths], [...parentScreens], routeNames);
configs.push(...result);
});
}
}
routeNames.pop();
return configs;
};
const createConfigItem = (screen, routeNames, paths, parse) => {
const parts = [];
// Parse the path string into parts for easier matching
for (const {
screen,
path
} of paths) {
parts.push(...getPatternParts(path).map(part => ({
...part,
screen
})));
}
const regex = parts.length ? new RegExp(`^(${parts.map((it, i) => {
if (it.param) {
const reg = it.regex || '[^/]+';
return `(((?<param_${i}>${reg})\\/)${it.optional ? '?' : ''})`;
}
return `${it.segment === '*' ? '.*' : escape(it.segment)}\\/`;
}).join('')})$`) : undefined;
const segments = parts.map(it => it.segment);
const params = parts.map((it, i) => it.param ? {
index: i,
screen: it.screen,
name: it.param
} : null).filter(it => it != null);
return {
screen,
regex,
segments,
params,
routeNames,
parse
};
};
const findParseConfigForRoute = (routeName, flatConfig) => {
for (const config of flatConfig) {
if (routeName === config.routeNames[config.routeNames.length - 1]) {
return config.parse;
}
}
return undefined;
};
// Try to find an initial route connected with the one passed
const findInitialRoute = (routeName, parentScreens, initialRoutes) => {
for (const config of initialRoutes) {
if (parentScreens.length === config.parentScreens.length) {
let sameParents = true;
for (let i = 0; i < parentScreens.length; i++) {
if (parentScreens[i].localeCompare(config.parentScreens[i]) !== 0) {
sameParents = false;
break;
}
}
if (sameParents) {
return routeName !== config.initialRouteName ? config.initialRouteName : undefined;
}
}
}
return undefined;
};
// returns state object with values depending on whether
// it is the end of state and if there is initialRoute for this level
const createStateObject = (initialRoute, route, isEmpty) => {
if (isEmpty) {
if (initialRoute) {
return {
index: 1,
routes: [{
name: initialRoute
}, route]
};
} else {
return {
routes: [route]
};
}
} else {
if (initialRoute) {
return {
index: 1,
routes: [{
name: initialRoute
}, {
...route,
state: {
routes: []
}
}]
};
} else {
return {
routes: [{
...route,
state: {
routes: []
}
}]
};
}
}
};
const createNestedStateObject = (path, routes, initialRoutes, flatConfig) => {
let route = routes.shift();
const parentScreens = [];
let initialRoute = findInitialRoute(route.name, parentScreens, initialRoutes);
parentScreens.push(route.name);
const state = createStateObject(initialRoute, route, routes.length === 0);
if (routes.length > 0) {
let nestedState = state;
while (route = routes.shift()) {
initialRoute = findInitialRoute(route.name, parentScreens, initialRoutes);
const nestedStateIndex = nestedState.index || nestedState.routes.length - 1;
nestedState.routes[nestedStateIndex].state = createStateObject(initialRoute, route, routes.length === 0);
if (routes.length > 0) {
nestedState = nestedState.routes[nestedStateIndex].state;
}
parentScreens.push(route.name);
}
}
route = findFocusedRoute(state);
route.path = path.replace(/\/$/, '');
const params = parseQueryParams(path, flatConfig ? findParseConfigForRoute(route.name, flatConfig) : undefined);
if (params) {
route.params = {
...route.params,
...params
};
}
return state;
};
const parseQueryParams = (path, parseConfig) => {
const query = path.split('?')[1];
const params = queryString.parse(query);
if (parseConfig) {
Object.keys(params).forEach(name => {
if (Object.hasOwnProperty.call(parseConfig, name) && typeof params[name] === 'string') {
params[name] = parseConfig[name](params[name]);
}
});
}
return Object.keys(params).length ? params : undefined;
};
//# sourceMappingURL=getStateFromPath.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,38 @@
"use strict";
export { BaseNavigationContainer } from "./BaseNavigationContainer.js";
export { createNavigationContainerRef } from "./createNavigationContainerRef.js";
export { createNavigatorFactory } from "./createNavigatorFactory.js";
export { CurrentRenderContext } from "./CurrentRenderContext.js";
export { findFocusedRoute } from "./findFocusedRoute.js";
export { getActionFromState } from "./getActionFromState.js";
export { getFocusedRouteNameFromRoute } from "./getFocusedRouteNameFromRoute.js";
export { getPathFromState } from "./getPathFromState.js";
export { getStateFromPath } from "./getStateFromPath.js";
export { NavigationContainerRefContext } from "./NavigationContainerRefContext.js";
export { NavigationContext } from "./NavigationContext.js";
export { NavigationHelpersContext } from "./NavigationHelpersContext.js";
export { NavigationIndependentTree } from "./NavigationIndependentTree.js";
export { NavigationMetaContext } from "./NavigationMetaContext.js";
export { NavigationProvider, NavigationRouteContext } from "./NavigationProvider.js";
export { PreventRemoveContext } from "./PreventRemoveContext.js";
export { PreventRemoveProvider } from "./PreventRemoveProvider.js";
export { createComponentForStaticNavigation, createPathConfigForStaticNavigation } from "./StaticNavigation.js";
export { ThemeContext } from "./theming/ThemeContext.js";
export { ThemeProvider } from "./theming/ThemeProvider.js";
export { useTheme } from "./theming/useTheme.js";
export * from "./types.js";
export { useFocusEffect } from "./useFocusEffect.js";
export { useIsFocused } from "./useIsFocused.js";
export { useNavigation } from "./useNavigation.js";
export { useNavigationBuilder } from "./useNavigationBuilder.js";
export { useNavigationContainerRef } from "./useNavigationContainerRef.js";
export { useNavigationIndependentTree } from "./useNavigationIndependentTree.js";
export { useNavigationState } from "./useNavigationState.js";
export { usePreventRemove } from "./usePreventRemove.js";
export { usePreventRemoveContext } from "./usePreventRemoveContext.js";
export { useRoute } from "./useRoute.js";
export { useStateForPath } from "./useStateForPath.js";
export { validatePathConfig } from "./validatePathConfig.js";
export * from '@react-navigation/routers';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["BaseNavigationContainer","createNavigationContainerRef","createNavigatorFactory","CurrentRenderContext","findFocusedRoute","getActionFromState","getFocusedRouteNameFromRoute","getPathFromState","getStateFromPath","NavigationContainerRefContext","NavigationContext","NavigationHelpersContext","NavigationIndependentTree","NavigationMetaContext","NavigationProvider","NavigationRouteContext","PreventRemoveContext","PreventRemoveProvider","createComponentForStaticNavigation","createPathConfigForStaticNavigation","ThemeContext","ThemeProvider","useTheme","useFocusEffect","useIsFocused","useNavigation","useNavigationBuilder","useNavigationContainerRef","useNavigationIndependentTree","useNavigationState","usePreventRemove","usePreventRemoveContext","useRoute","useStateForPath","validatePathConfig"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,uBAAuB,QAAQ,8BAA2B;AACnE,SAASC,4BAA4B,QAAQ,mCAAgC;AAC7E,SAASC,sBAAsB,QAAQ,6BAA0B;AACjE,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,kBAAkB,QAAQ,yBAAsB;AACzD,SAASC,4BAA4B,QAAQ,mCAAgC;AAC7E,SAASC,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,6BAA6B,QAAQ,oCAAiC;AAC/E,SAASC,iBAAiB,QAAQ,wBAAqB;AACvD,SAASC,wBAAwB,QAAQ,+BAA4B;AACrE,SAASC,yBAAyB,QAAQ,gCAA6B;AACvE,SAASC,qBAAqB,QAAQ,4BAAyB;AAC/D,SACEC,kBAAkB,EAClBC,sBAAsB,QACjB,yBAAsB;AAC7B,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,qBAAqB,QAAQ,4BAAyB;AAC/D,SACEC,kCAAkC,EAClCC,mCAAmC,QAO9B,uBAAoB;AAC3B,SAASC,YAAY,QAAQ,2BAAwB;AACrD,SAASC,aAAa,QAAQ,4BAAyB;AACvD,SAASC,QAAQ,QAAQ,uBAAoB;AAC7C,cAAc,YAAS;AACvB,SAASC,cAAc,QAAQ,qBAAkB;AACjD,SAASC,YAAY,QAAQ,mBAAgB;AAC7C,SAASC,aAAa,QAAQ,oBAAiB;AAC/C,SAASC,oBAAoB,QAAQ,2BAAwB;AAC7D,SAASC,yBAAyB,QAAQ,gCAA6B;AACvE,SAASC,4BAA4B,QAAQ,mCAAgC;AAC7E,SAASC,kBAAkB,QAAQ,yBAAsB;AACzD,SAASC,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,uBAAuB,QAAQ,8BAA2B;AACnE,SAASC,QAAQ,QAAQ,eAAY;AACrC,SAASC,eAAe,QAAQ,sBAAmB;AACnD,SAASC,kBAAkB,QAAQ,yBAAsB;AACzD,cAAc,2BAA2B","ignoreList":[]}

View File

@@ -0,0 +1,16 @@
"use strict";
/**
* Compare two arrays with primitive values as the content.
* We need to make sure that both values and order match.
*/
export function isArrayEqual(a, b) {
if (a === b) {
return true;
}
if (a.length !== b.length) {
return false;
}
return a.every((it, index) => Object.is(it, b[index]));
}
//# sourceMappingURL=isArrayEqual.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["isArrayEqual","a","b","length","every","it","index","Object","is"],"sourceRoot":"../../src","sources":["isArrayEqual.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA,OAAO,SAASA,YAAYA,CAACC,CAAQ,EAAEC,CAAQ,EAAE;EAC/C,IAAID,CAAC,KAAKC,CAAC,EAAE;IACX,OAAO,IAAI;EACb;EAEA,IAAID,CAAC,CAACE,MAAM,KAAKD,CAAC,CAACC,MAAM,EAAE;IACzB,OAAO,KAAK;EACd;EAEA,OAAOF,CAAC,CAACG,KAAK,CAAC,CAACC,EAAE,EAAEC,KAAK,KAAKC,MAAM,CAACC,EAAE,CAACH,EAAE,EAAEH,CAAC,CAACI,KAAK,CAAC,CAAC,CAAC;AACxD","ignoreList":[]}

View File

@@ -0,0 +1,17 @@
"use strict";
/**
* Compare two records with primitive values as the content.
*/
export function isRecordEqual(a, b) {
if (a === b) {
return true;
}
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
if (aKeys.length !== bKeys.length) {
return false;
}
return aKeys.every(key => Object.is(a[key], b[key]));
}
//# sourceMappingURL=isRecordEqual.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["isRecordEqual","a","b","aKeys","Object","keys","bKeys","length","every","key","is"],"sourceRoot":"../../src","sources":["isRecordEqual.tsx"],"mappings":";;AAAA;AACA;AACA;AACA,OAAO,SAASA,aAAaA,CAC3BC,CAA0B,EAC1BC,CAA0B,EAC1B;EACA,IAAID,CAAC,KAAKC,CAAC,EAAE;IACX,OAAO,IAAI;EACb;EAEA,MAAMC,KAAK,GAAGC,MAAM,CAACC,IAAI,CAACJ,CAAC,CAAC;EAC5B,MAAMK,KAAK,GAAGF,MAAM,CAACC,IAAI,CAACH,CAAC,CAAC;EAE5B,IAAIC,KAAK,CAACI,MAAM,KAAKD,KAAK,CAACC,MAAM,EAAE;IACjC,OAAO,KAAK;EACd;EAEA,OAAOJ,KAAK,CAACK,KAAK,CAAEC,GAAG,IAAKL,MAAM,CAACM,EAAE,CAACT,CAAC,CAACQ,GAAG,CAAC,EAAEP,CAAC,CAACO,GAAG,CAAC,CAAC,CAAC;AACxD","ignoreList":[]}

View File

@@ -0,0 +1 @@
{"type":"module"}

View File

@@ -0,0 +1,6 @@
"use strict";
import * as React from 'react';
export const ThemeContext = /*#__PURE__*/React.createContext(undefined);
ThemeContext.displayName = 'ThemeContext';
//# sourceMappingURL=ThemeContext.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","ThemeContext","createContext","undefined","displayName"],"sourceRoot":"../../../src","sources":["theming/ThemeContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,OAAO,MAAMC,YAAY,gBAAGD,KAAK,CAACE,aAAa,CAE7CC,SAAS,CAAC;AAEZF,YAAY,CAACG,WAAW,GAAG,cAAc","ignoreList":[]}

View File

@@ -0,0 +1,15 @@
"use strict";
import * as React from 'react';
import { ThemeContext } from "./ThemeContext.js";
import { jsx as _jsx } from "react/jsx-runtime";
export function ThemeProvider({
value,
children
}) {
return /*#__PURE__*/_jsx(ThemeContext.Provider, {
value: value,
children: children
});
}
//# sourceMappingURL=ThemeProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","ThemeContext","jsx","_jsx","ThemeProvider","value","children","Provider"],"sourceRoot":"../../../src","sources":["theming/ThemeProvider.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,YAAY,QAAQ,mBAAgB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAO9C,OAAO,SAASC,aAAaA,CAAC;EAAEC,KAAK;EAAEC;AAAgB,CAAC,EAAE;EACxD,oBACEH,IAAA,CAACF,YAAY,CAACM,QAAQ;IAACF,KAAK,EAAEA,KAAM;IAAAC,QAAA,EAAEA;EAAQ,CAAwB,CAAC;AAE3E","ignoreList":[]}

View File

@@ -0,0 +1,12 @@
"use strict";
import * as React from 'react';
import { ThemeContext } from "./ThemeContext.js";
export function useTheme() {
const theme = React.useContext(ThemeContext);
if (theme == null) {
throw new Error("Couldn't find a theme. Is your component inside NavigationContainer or does it have a theme?");
}
return theme;
}
//# sourceMappingURL=useTheme.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","ThemeContext","useTheme","theme","useContext","Error"],"sourceRoot":"../../../src","sources":["theming/useTheme.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,YAAY,QAAQ,mBAAgB;AAE7C,OAAO,SAASC,QAAQA,CAAA,EAAG;EACzB,MAAMC,KAAK,GAAGH,KAAK,CAACI,UAAU,CAACH,YAAY,CAAC;EAE5C,IAAIE,KAAK,IAAI,IAAI,EAAE;IACjB,MAAM,IAAIE,KAAK,CACb,8FACF,CAAC;EACH;EAEA,OAAOF,KAAK;AACd","ignoreList":[]}

View File

@@ -0,0 +1,4 @@
"use strict";
export class PrivateValueStore {}
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["PrivateValueStore"],"sourceRoot":"../../src","sources":["types.tsx"],"mappings":";;AA0OA,OAAO,MAAMA,iBAAiB,CAA4B","ignoreList":[]}

View File

@@ -0,0 +1,30 @@
"use strict";
import * as React from 'react';
/**
* Hook which lets child navigators add action listeners.
*/
export function useChildListeners() {
const {
current: listeners
} = React.useRef({
action: [],
focus: []
});
const addListener = React.useCallback((type, listener) => {
listeners[type].push(listener);
let removed = false;
return () => {
const index = listeners[type].indexOf(listener);
if (!removed && index > -1) {
removed = true;
listeners[type].splice(index, 1);
}
};
}, [listeners]);
return {
listeners,
addListener
};
}
//# sourceMappingURL=useChildListeners.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","useChildListeners","current","listeners","useRef","action","focus","addListener","useCallback","type","listener","push","removed","index","indexOf","splice"],"sourceRoot":"../../src","sources":["useChildListeners.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAI9B;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAA,EAAG;EAClC,MAAM;IAAEC,OAAO,EAAEC;EAAU,CAAC,GAAGH,KAAK,CAACI,MAAM,CAExC;IACDC,MAAM,EAAE,EAAE;IACVC,KAAK,EAAE;EACT,CAAC,CAAC;EAEF,MAAMC,WAAW,GAAGP,KAAK,CAACQ,WAAW,CACnC,CAA8BC,IAAO,EAAEC,QAAwB,KAAK;IAClEP,SAAS,CAACM,IAAI,CAAC,CAACE,IAAI,CAACD,QAAQ,CAAC;IAE9B,IAAIE,OAAO,GAAG,KAAK;IACnB,OAAO,MAAM;MACX,MAAMC,KAAK,GAAGV,SAAS,CAACM,IAAI,CAAC,CAACK,OAAO,CAACJ,QAAQ,CAAC;MAE/C,IAAI,CAACE,OAAO,IAAIC,KAAK,GAAG,CAAC,CAAC,EAAE;QAC1BD,OAAO,GAAG,IAAI;QACdT,SAAS,CAACM,IAAI,CAAC,CAACM,MAAM,CAACF,KAAK,EAAE,CAAC,CAAC;MAClC;IACF,CAAC;EACH,CAAC,EACD,CAACV,SAAS,CACZ,CAAC;EAED,OAAO;IACLA,SAAS;IACTI;EACF,CAAC;AACH","ignoreList":[]}

View File

@@ -0,0 +1,9 @@
"use strict";
import * as React from 'react';
/**
* Use `useEffect` during SSR and `useLayoutEffect` in the Browser & React Native to avoid warnings.
*/
export const useClientLayoutEffect = typeof document !== 'undefined' || typeof navigator !== 'undefined' && navigator.product === 'ReactNative' ? React.useLayoutEffect : React.useEffect;
//# sourceMappingURL=useClientLayoutEffect.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","useClientLayoutEffect","document","navigator","product","useLayoutEffect","useEffect"],"sourceRoot":"../../src","sources":["useClientLayoutEffect.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;;AAE9B;AACA;AACA;AACA,OAAO,MAAMC,qBAAqB,GAChC,OAAOC,QAAQ,KAAK,WAAW,IAC9B,OAAOC,SAAS,KAAK,WAAW,IAAIA,SAAS,CAACC,OAAO,KAAK,aAAc,GACrEJ,KAAK,CAACK,eAAe,GACrBL,KAAK,CAACM,SAAS","ignoreList":[]}

View File

@@ -0,0 +1,34 @@
"use strict";
import * as React from 'react';
import { jsx as _jsx } from "react/jsx-runtime";
const NavigationContent = ({
render,
children
}) => {
return render(children);
};
export function useComponent(render) {
const renderRef = React.useRef(render);
// Normally refs shouldn't be mutated in render
// But we return a component which will be rendered
// So it's just for immediate consumption
renderRef.current = render;
React.useEffect(() => {
renderRef.current = null;
});
return React.useRef(({
children
}) => {
const render = renderRef.current;
if (render === null) {
throw new Error('The returned component must be rendered in the same render phase as the hook.');
}
return /*#__PURE__*/_jsx(NavigationContent, {
render: render,
children: children
});
}).current;
}
//# sourceMappingURL=useComponent.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","jsx","_jsx","NavigationContent","render","children","useComponent","renderRef","useRef","current","useEffect","Error"],"sourceRoot":"../../src","sources":["useComponent.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAS/B,MAAMC,iBAAiB,GAAGA,CAAC;EAAEC,MAAM;EAAEC;AAAgB,CAAC,KAAK;EACzD,OAAOD,MAAM,CAACC,QAAQ,CAAC;AACzB,CAAC;AAED,OAAO,SAASC,YAAYA,CAACF,MAAc,EAAE;EAC3C,MAAMG,SAAS,GAAGP,KAAK,CAACQ,MAAM,CAAgBJ,MAAM,CAAC;;EAErD;EACA;EACA;EACAG,SAAS,CAACE,OAAO,GAAGL,MAAM;EAE1BJ,KAAK,CAACU,SAAS,CAAC,MAAM;IACpBH,SAAS,CAACE,OAAO,GAAG,IAAI;EAC1B,CAAC,CAAC;EAEF,OAAOT,KAAK,CAACQ,MAAM,CAAC,CAAC;IAAEH;EAAwC,CAAC,KAAK;IACnE,MAAMD,MAAM,GAAGG,SAAS,CAACE,OAAO;IAEhC,IAAIL,MAAM,KAAK,IAAI,EAAE;MACnB,MAAM,IAAIO,KAAK,CACb,+EACF,CAAC;IACH;IAEA,oBAAOT,IAAA,CAACC,iBAAiB;MAACC,MAAM,EAAEA,MAAO;MAAAC,QAAA,EAAEA;IAAQ,CAAoB,CAAC;EAC1E,CAAC,CAAC,CAACI,OAAO;AACZ","ignoreList":[]}

View File

@@ -0,0 +1,19 @@
"use strict";
import * as React from 'react';
import { CurrentRenderContext } from "./CurrentRenderContext.js";
/**
* Write the current options, so that server renderer can get current values
* Mutating values like this is not safe in async mode, but it doesn't apply to SSR
*/
export function useCurrentRender({
state,
navigation,
descriptors
}) {
const current = React.useContext(CurrentRenderContext);
if (current && navigation.isFocused()) {
current.options = descriptors[state.routes[state.index].key].options;
}
}
//# sourceMappingURL=useCurrentRender.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","CurrentRenderContext","useCurrentRender","state","navigation","descriptors","current","useContext","isFocused","options","routes","index","key"],"sourceRoot":"../../src","sources":["useCurrentRender.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,oBAAoB,QAAQ,2BAAwB;AAiB7D;AACA;AACA;AACA;AACA,OAAO,SAASC,gBAAgBA,CAAC;EAAEC,KAAK;EAAEC,UAAU;EAAEC;AAAqB,CAAC,EAAE;EAC5E,MAAMC,OAAO,GAAGN,KAAK,CAACO,UAAU,CAACN,oBAAoB,CAAC;EAEtD,IAAIK,OAAO,IAAIF,UAAU,CAACI,SAAS,CAAC,CAAC,EAAE;IACrCF,OAAO,CAACG,OAAO,GAAGJ,WAAW,CAACF,KAAK,CAACO,MAAM,CAACP,KAAK,CAACQ,KAAK,CAAC,CAACC,GAAG,CAAC,CAACH,OAAO;EACtE;AACF","ignoreList":[]}

View File

@@ -0,0 +1,184 @@
"use strict";
import * as React from 'react';
import { NavigationBuilderContext } from "./NavigationBuilderContext.js";
import { NavigationProvider } from "./NavigationProvider.js";
import { SceneView } from "./SceneView.js";
import { ThemeContext } from "./theming/ThemeContext.js";
import { useNavigationCache } from "./useNavigationCache.js";
import { useRouteCache } from "./useRouteCache.js";
import { jsx as _jsx } from "react/jsx-runtime";
/**
* Hook to create descriptor objects for the child routes.
*
* A descriptor object provides 3 things:
* - Helper method to render a screen
* - Options specified by the screen for the navigator
* - Navigation object intended for the route
*/
export function useDescriptors({
state,
screens,
navigation,
screenOptions,
screenLayout,
onAction,
getState,
setState,
addListener,
addKeyedListener,
onRouteFocus,
router,
emitter
}) {
const theme = React.useContext(ThemeContext);
const [options, setOptions] = React.useState({});
const {
onDispatchAction,
onOptionsChange,
scheduleUpdate,
flushUpdates,
stackRef
} = React.useContext(NavigationBuilderContext);
const context = React.useMemo(() => ({
navigation,
onAction,
addListener,
addKeyedListener,
onRouteFocus,
onDispatchAction,
onOptionsChange,
scheduleUpdate,
flushUpdates,
stackRef
}), [navigation, onAction, addListener, addKeyedListener, onRouteFocus, onDispatchAction, onOptionsChange, scheduleUpdate, flushUpdates, stackRef]);
const {
base,
navigations
} = useNavigationCache({
state,
getState,
navigation,
setOptions,
router,
emitter
});
const routes = useRouteCache(state.routes);
const getOptions = (route, navigation, overrides) => {
const config = screens[route.name];
const screen = config.props;
const optionsList = [
// The default `screenOptions` passed to the navigator
screenOptions,
// The `screenOptions` props passed to `Group` elements
...(config.options ? config.options.filter(Boolean) : []),
// The `options` prop passed to `Screen` elements,
screen.options,
// The options set via `navigation.setOptions`
overrides];
return optionsList.reduce((acc, curr) => Object.assign(acc,
// @ts-expect-error: we check for function but TS still complains
typeof curr !== 'function' ? curr : curr({
route,
navigation,
theme
})), {});
};
const render = (route, navigation, customOptions, routeState) => {
const config = screens[route.name];
const screen = config.props;
const clearOptions = () => setOptions(o => {
if (route.key in o) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {
[route.key]: _,
...rest
} = o;
return rest;
}
return o;
});
const layout =
// The `layout` prop passed to `Screen` elements,
screen.layout ??
// The `screenLayout` props passed to `Group` elements
config.layout ??
// The default `screenLayout` passed to the navigator
screenLayout;
let element = /*#__PURE__*/_jsx(SceneView, {
navigation: navigation,
route: route,
screen: screen,
routeState: routeState,
getState: getState,
setState: setState,
options: customOptions,
clearOptions: clearOptions
});
if (layout != null) {
element = layout({
route,
navigation,
options: customOptions,
// @ts-expect-error: in practice `theme` will be defined
theme,
children: element
});
}
return /*#__PURE__*/_jsx(NavigationBuilderContext.Provider, {
value: context,
children: /*#__PURE__*/_jsx(NavigationProvider, {
route: route,
navigation: navigation,
children: element
})
}, route.key);
};
const descriptors = routes.reduce((acc, route, i) => {
const navigation = navigations[route.key];
const customOptions = getOptions(route, navigation, options[route.key]);
const element = render(route, navigation, customOptions, state.routes[i].state);
acc[route.key] = {
route,
// @ts-expect-error: it's missing action helpers, fix later
navigation,
render() {
return element;
},
options: customOptions
};
return acc;
}, {});
/**
* Create a descriptor object for a route.
*
* @param route Route object for which the descriptor should be created
* @param placeholder Whether the descriptor should be a placeholder, e.g. for a route not yet in the state
* @returns Descriptor object
*/
const describe = (route, placeholder) => {
if (!placeholder) {
if (!(route.key in descriptors)) {
throw new Error(`Couldn't find a route with the key ${route.key}.`);
}
return descriptors[route.key];
}
const navigation = base;
const customOptions = getOptions(route, navigation, {});
const element = render(route, navigation, customOptions, undefined);
return {
route,
navigation,
render() {
return element;
},
options: customOptions
};
};
return {
describe,
descriptors
};
}
//# sourceMappingURL=useDescriptors.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,99 @@
"use strict";
import * as React from 'react';
/**
* Hook to manage the event system used by the navigator to notify screens of various events.
*/
export function useEventEmitter(listen) {
const listenRef = React.useRef(listen);
React.useEffect(() => {
listenRef.current = listen;
});
const listeners = React.useRef(Object.create(null));
const create = React.useCallback(target => {
const removeListener = (type, callback) => {
const callbacks = listeners.current[type] ? listeners.current[type][target] : undefined;
if (!callbacks) {
return;
}
const index = callbacks.indexOf(callback);
if (index > -1) {
callbacks.splice(index, 1);
}
};
const addListener = (type, callback) => {
listeners.current[type] = listeners.current[type] || {};
listeners.current[type][target] = listeners.current[type][target] || [];
listeners.current[type][target].push(callback);
let removed = false;
return () => {
// Prevent removing other listeners when unsubscribing same listener multiple times
if (!removed) {
removed = true;
removeListener(type, callback);
}
};
};
return {
addListener,
removeListener
};
}, []);
const emit = React.useCallback(({
type,
data,
target,
canPreventDefault
}) => {
const items = listeners.current[type] || {};
// Copy the current list of callbacks in case they are mutated during execution
const callbacks = target !== undefined ? items[target]?.slice() : [].concat(...Object.keys(items).map(t => items[t])).filter((cb, i, self) => self.lastIndexOf(cb) === i);
const event = {
get type() {
return type;
}
};
if (target !== undefined) {
Object.defineProperty(event, 'target', {
enumerable: true,
get() {
return target;
}
});
}
if (data !== undefined) {
Object.defineProperty(event, 'data', {
enumerable: true,
get() {
return data;
}
});
}
if (canPreventDefault) {
let defaultPrevented = false;
Object.defineProperties(event, {
defaultPrevented: {
enumerable: true,
get() {
return defaultPrevented;
}
},
preventDefault: {
enumerable: true,
value() {
defaultPrevented = true;
}
}
});
}
listenRef.current?.(event);
callbacks?.forEach(cb => cb(event));
return event;
}, []);
return React.useMemo(() => ({
create,
emit
}), [create, emit]);
}
//# sourceMappingURL=useEventEmitter.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","useEventEmitter","listen","listenRef","useRef","useEffect","current","listeners","Object","create","useCallback","target","removeListener","type","callback","callbacks","undefined","index","indexOf","splice","addListener","push","removed","emit","data","canPreventDefault","items","slice","concat","keys","map","t","filter","cb","i","self","lastIndexOf","event","defineProperty","enumerable","get","defaultPrevented","defineProperties","preventDefault","value","forEach","useMemo"],"sourceRoot":"../../src","sources":["useEventEmitter.tsx"],"mappings":"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","ignoreList":[]}

View File

@@ -0,0 +1,74 @@
"use strict";
import * as React from 'react';
import { useNavigation } from "./useNavigation.js";
/**
* Hook to run an effect in a focused screen, similar to `React.useEffect`.
* This can be used to perform side-effects such as fetching data or subscribing to events.
* The passed callback should be wrapped in `React.useCallback` to avoid running the effect too often.
*
* @param callback Memoized callback containing the effect, should optionally return a cleanup function.
*/
export function useFocusEffect(effect) {
const navigation = useNavigation();
// eslint-disable-next-line prefer-rest-params
if (arguments[1] !== undefined) {
const message = "You passed a second argument to 'useFocusEffect', but it only accepts one argument. " + "If you want to pass a dependency array, you can use 'React.useCallback':\n\n" + 'useFocusEffect(\n' + ' React.useCallback(() => {\n' + ' // Your code here\n' + ' }, [depA, depB])\n' + ');\n\n' + 'See usage guide: https://reactnavigation.org/docs/use-focus-effect';
console.error(message);
}
React.useEffect(() => {
let isFocused = false;
let cleanup;
const callback = () => {
const destroy = effect();
if (destroy === undefined || typeof destroy === 'function') {
return destroy;
}
if (process.env.NODE_ENV !== 'production') {
let message = 'An effect function must not return anything besides a function, which is used for clean-up.';
if (destroy === null) {
message += " You returned 'null'. If your effect does not require clean-up, return 'undefined' (or nothing).";
} else if (typeof destroy.then === 'function') {
message += "\n\nIt looks like you wrote 'useFocusEffect(async () => ...)' or returned a Promise. " + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useFocusEffect(\n' + ' React.useCallback(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n\n' + ' fetchData();\n' + ' }, [someId])\n' + ');\n\n' + 'See usage guide: https://reactnavigation.org/docs/use-focus-effect';
} else {
message += ` You returned '${JSON.stringify(destroy)}'.`;
}
console.error(message);
}
};
// We need to run the effect on initial render/dep changes if the screen is focused
if (navigation.isFocused()) {
cleanup = callback();
isFocused = true;
}
const unsubscribeFocus = navigation.addListener('focus', () => {
// If callback was already called for focus, avoid calling it again
// The focus event may also fire on initial render, so we guard against running the effect twice
if (isFocused) {
return;
}
if (cleanup !== undefined) {
cleanup();
}
cleanup = callback();
isFocused = true;
});
const unsubscribeBlur = navigation.addListener('blur', () => {
if (cleanup !== undefined) {
cleanup();
}
cleanup = undefined;
isFocused = false;
});
return () => {
if (cleanup !== undefined) {
cleanup();
}
unsubscribeFocus();
unsubscribeBlur();
};
}, [effect, navigation]);
}
//# sourceMappingURL=useFocusEffect.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","useNavigation","useFocusEffect","effect","navigation","arguments","undefined","message","console","error","useEffect","isFocused","cleanup","callback","destroy","process","env","NODE_ENV","then","JSON","stringify","unsubscribeFocus","addListener","unsubscribeBlur"],"sourceRoot":"../../src","sources":["useFocusEffect.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,aAAa,QAAQ,oBAAiB;AAI/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAACC,MAAsB,EAAE;EACrD,MAAMC,UAAU,GAAGH,aAAa,CAAC,CAAC;;EAElC;EACA,IAAII,SAAS,CAAC,CAAC,CAAC,KAAKC,SAAS,EAAE;IAC9B,MAAMC,OAAO,GACX,sFAAsF,GACtF,8EAA8E,GAC9E,mBAAmB,GACnB,+BAA+B,GAC/B,yBAAyB,GACzB,sBAAsB,GACtB,QAAQ,GACR,oEAAoE;IAEtEC,OAAO,CAACC,KAAK,CAACF,OAAO,CAAC;EACxB;EAEAP,KAAK,CAACU,SAAS,CAAC,MAAM;IACpB,IAAIC,SAAS,GAAG,KAAK;IACrB,IAAIC,OAAwC;IAE5C,MAAMC,QAAQ,GAAGA,CAAA,KAAM;MACrB,MAAMC,OAAO,GAAGX,MAAM,CAAC,CAAC;MAExB,IAAIW,OAAO,KAAKR,SAAS,IAAI,OAAOQ,OAAO,KAAK,UAAU,EAAE;QAC1D,OAAOA,OAAO;MAChB;MAEA,IAAIC,OAAO,CAACC,GAAG,CAACC,QAAQ,KAAK,YAAY,EAAE;QACzC,IAAIV,OAAO,GACT,6FAA6F;QAE/F,IAAIO,OAAO,KAAK,IAAI,EAAE;UACpBP,OAAO,IACL,kGAAkG;QACtG,CAAC,MAAM,IAAI,OAAQO,OAAO,CAASI,IAAI,KAAK,UAAU,EAAE;UACtDX,OAAO,IACL,uFAAuF,GACvF,uDAAuD,GACvD,8BAA8B,GAC9B,mBAAmB,GACnB,+BAA+B,GAC/B,oCAAoC,GACpC,+BAA+B,GAC/B,uDAAuD,GACvD,gBAAgB,GAChB,WAAW,GACX,oBAAoB,GACpB,kBAAkB,GAClB,QAAQ,GACR,oEAAoE;QACxE,CAAC,MAAM;UACLA,OAAO,IAAI,kBAAkBY,IAAI,CAACC,SAAS,CAACN,OAAO,CAAC,IAAI;QAC1D;QAEAN,OAAO,CAACC,KAAK,CAACF,OAAO,CAAC;MACxB;IACF,CAAC;;IAED;IACA,IAAIH,UAAU,CAACO,SAAS,CAAC,CAAC,EAAE;MAC1BC,OAAO,GAAGC,QAAQ,CAAC,CAAC;MACpBF,SAAS,GAAG,IAAI;IAClB;IAEA,MAAMU,gBAAgB,GAAGjB,UAAU,CAACkB,WAAW,CAAC,OAAO,EAAE,MAAM;MAC7D;MACA;MACA,IAAIX,SAAS,EAAE;QACb;MACF;MAEA,IAAIC,OAAO,KAAKN,SAAS,EAAE;QACzBM,OAAO,CAAC,CAAC;MACX;MAEAA,OAAO,GAAGC,QAAQ,CAAC,CAAC;MACpBF,SAAS,GAAG,IAAI;IAClB,CAAC,CAAC;IAEF,MAAMY,eAAe,GAAGnB,UAAU,CAACkB,WAAW,CAAC,MAAM,EAAE,MAAM;MAC3D,IAAIV,OAAO,KAAKN,SAAS,EAAE;QACzBM,OAAO,CAAC,CAAC;MACX;MAEAA,OAAO,GAAGN,SAAS;MACnBK,SAAS,GAAG,KAAK;IACnB,CAAC,CAAC;IAEF,OAAO,MAAM;MACX,IAAIC,OAAO,KAAKN,SAAS,EAAE;QACzBM,OAAO,CAAC,CAAC;MACX;MAEAS,gBAAgB,CAAC,CAAC;MAClBE,eAAe,CAAC,CAAC;IACnB,CAAC;EACH,CAAC,EAAE,CAACpB,MAAM,EAAEC,UAAU,CAAC,CAAC;AAC1B","ignoreList":[]}

View File

@@ -0,0 +1,64 @@
"use strict";
import * as React from 'react';
import { NavigationContext } from "./NavigationContext.js";
/**
* Hook to take care of emitting `focus` and `blur` events.
*/
export function useFocusEvents({
state,
emitter
}) {
const navigation = React.useContext(NavigationContext);
const lastFocusedKeyRef = React.useRef(undefined);
const currentFocusedKey = state.routes[state.index].key;
// When the parent screen changes its focus state, we also need to change child's focus
// Coz the child screen can't be focused if the parent screen is out of focus
React.useEffect(() => navigation?.addListener('focus', () => {
lastFocusedKeyRef.current = currentFocusedKey;
emitter.emit({
type: 'focus',
target: currentFocusedKey
});
}), [currentFocusedKey, emitter, navigation]);
React.useEffect(() => navigation?.addListener('blur', () => {
lastFocusedKeyRef.current = undefined;
emitter.emit({
type: 'blur',
target: currentFocusedKey
});
}), [currentFocusedKey, emitter, navigation]);
React.useEffect(() => {
const lastFocusedKey = lastFocusedKeyRef.current;
lastFocusedKeyRef.current = currentFocusedKey;
// We wouldn't have `lastFocusedKey` on initial mount
// Fire focus event for the current route on mount if there's no parent navigator
if (lastFocusedKey === undefined && !navigation) {
emitter.emit({
type: 'focus',
target: currentFocusedKey
});
}
// We should only emit events when the focused key changed and navigator is focused
// When navigator is not focused, screens inside shouldn't receive focused status either
if (lastFocusedKey === currentFocusedKey || !(navigation ? navigation.isFocused() : true)) {
return;
}
if (lastFocusedKey === undefined) {
// Only fire events after initial mount
return;
}
emitter.emit({
type: 'blur',
target: lastFocusedKey
});
emitter.emit({
type: 'focus',
target: currentFocusedKey
});
}, [currentFocusedKey, emitter, navigation]);
}
//# sourceMappingURL=useFocusEvents.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["React","NavigationContext","useFocusEvents","state","emitter","navigation","useContext","lastFocusedKeyRef","useRef","undefined","currentFocusedKey","routes","index","key","useEffect","addListener","current","emit","type","target","lastFocusedKey","isFocused"],"sourceRoot":"../../src","sources":["useFocusEvents.tsx"],"mappings":";;AACA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,iBAAiB,QAAQ,wBAAqB;AASvD;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAAgC;EAC5DC,KAAK;EACLC;AACc,CAAC,EAAE;EACjB,MAAMC,UAAU,GAAGL,KAAK,CAACM,UAAU,CAACL,iBAAiB,CAAC;EACtD,MAAMM,iBAAiB,GAAGP,KAAK,CAACQ,MAAM,CAAqBC,SAAS,CAAC;EAErE,MAAMC,iBAAiB,GAAGP,KAAK,CAACQ,MAAM,CAACR,KAAK,CAACS,KAAK,CAAC,CAACC,GAAG;;EAEvD;EACA;EACAb,KAAK,CAACc,SAAS,CACb,MACET,UAAU,EAAEU,WAAW,CAAC,OAAO,EAAE,MAAM;IACrCR,iBAAiB,CAACS,OAAO,GAAGN,iBAAiB;IAC7CN,OAAO,CAACa,IAAI,CAAC;MAAEC,IAAI,EAAE,OAAO;MAAEC,MAAM,EAAET;IAAkB,CAAC,CAAC;EAC5D,CAAC,CAAC,EACJ,CAACA,iBAAiB,EAAEN,OAAO,EAAEC,UAAU,CACzC,CAAC;EAEDL,KAAK,CAACc,SAAS,CACb,MACET,UAAU,EAAEU,WAAW,CAAC,MAAM,EAAE,MAAM;IACpCR,iBAAiB,CAACS,OAAO,GAAGP,SAAS;IACrCL,OAAO,CAACa,IAAI,CAAC;MAAEC,IAAI,EAAE,MAAM;MAAEC,MAAM,EAAET;IAAkB,CAAC,CAAC;EAC3D,CAAC,CAAC,EACJ,CAACA,iBAAiB,EAAEN,OAAO,EAAEC,UAAU,CACzC,CAAC;EAEDL,KAAK,CAACc,SAAS,CAAC,MAAM;IACpB,MAAMM,cAAc,GAAGb,iBAAiB,CAACS,OAAO;IAEhDT,iBAAiB,CAACS,OAAO,GAAGN,iBAAiB;;IAE7C;IACA;IACA,IAAIU,cAAc,KAAKX,SAAS,IAAI,CAACJ,UAAU,EAAE;MAC/CD,OAAO,CAACa,IAAI,CAAC;QAAEC,IAAI,EAAE,OAAO;QAAEC,MAAM,EAAET;MAAkB,CAAC,CAAC;IAC5D;;IAEA;IACA;IACA,IACEU,cAAc,KAAKV,iBAAiB,IACpC,EAAEL,UAAU,GAAGA,UAAU,CAACgB,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,EAC7C;MACA;IACF;IAEA,IAAID,cAAc,KAAKX,SAAS,EAAE;MAChC;MACA;IACF;IAEAL,OAAO,CAACa,IAAI,CAAC;MAAEC,IAAI,EAAE,MAAM;MAAEC,MAAM,EAAEC;IAAe,CAAC,CAAC;IACtDhB,OAAO,CAACa,IAAI,CAAC;MAAEC,IAAI,EAAE,OAAO;MAAEC,MAAM,EAAET;IAAkB,CAAC,CAAC;EAC5D,CAAC,EAAE,CAACA,iBAAiB,EAAEN,OAAO,EAAEC,UAAU,CAAC,CAAC;AAC9C","ignoreList":[]}

View File

@@ -0,0 +1,42 @@
"use strict";
import * as React from 'react';
import { NavigationBuilderContext } from "./NavigationBuilderContext.js";
/**
* Hook for passing focus callback to children
*/
export function useFocusedListenersChildrenAdapter({
navigation,
focusedListeners
}) {
const {
addListener
} = React.useContext(NavigationBuilderContext);
const listener = React.useCallback(callback => {
if (navigation.isFocused()) {
for (const listener of focusedListeners) {
const {
handled,
result
} = listener(callback);
if (handled) {
return {
handled,
result
};
}
}
return {
handled: true,
result: callback(navigation)
};
} else {
return {
handled: false,
result: null
};
}
}, [focusedListeners, navigation]);
React.useEffect(() => addListener?.('focus', listener), [addListener, listener]);
}
//# sourceMappingURL=useFocusedListenersChildrenAdapter.js.map

Some files were not shown because too many files have changed in this diff Show More