Compare commits

..

17 Commits

Author SHA1 Message Date
Satyajit Sahoo
65b6a3d864 chore: publish
- @react-navigation/bottom-tabs@6.0.0-next.11
 - @react-navigation/core@6.0.0-next.8
 - @react-navigation/devtools@6.0.0-next.8
 - @react-navigation/drawer@6.0.0-next.10
 - @react-navigation/elements@1.0.0-next.10
 - @react-navigation/material-bottom-tabs@6.0.0-next.8
 - @react-navigation/material-top-tabs@6.0.0-next.9
 - @react-navigation/native@6.0.0-next.8
 - @react-navigation/stack@6.0.0-next.16
2021-05-16 05:06:23 +02:00
Satyajit Sahoo
211f1f2c0e fix: fix integration tests 2021-05-16 05:04:49 +02:00
Satyajit Sahoo
22b7c3f6c1 fix: make stack screens accessible on web without screens 2021-05-16 04:56:03 +02:00
Satyajit Sahoo
6ebe0824df fix: don't enable animation & gestures for first screen 2021-05-16 04:05:29 +02:00
Satyajit Sahoo
82900cceff fix: move keyboardHandlingEnabled to screen options 2021-05-16 03:58:28 +02:00
Satyajit Sahoo
dc4ffc0171 fix: fix type error when passing unannotated navigation ref 2021-05-14 09:43:18 +02:00
Satyajit Sahoo
9c30c42c0b fix: add ability to pass generic params to Link 2021-05-14 09:29:57 +02:00
Satyajit Sahoo
ea8ea20127 fix: fix drawer content padding in RTL 2021-05-14 09:07:13 +02:00
Satyajit Sahoo
2f282f1070 feat: add a tabBarBackground option to bottom tabs 2021-05-14 08:59:46 +02:00
Satyajit Sahoo
5165eb76aa refactor: remove legacy useBackButton export from /native 2021-05-14 08:31:34 +02:00
Satyajit Sahoo
7c722d2028 fix: fix tab bar height including extra bottom inset 2021-05-14 08:08:57 +02:00
Satyajit Sahoo
7f015130df chore: publish
- @react-navigation/bottom-tabs@6.0.0-next.10
 - @react-navigation/core@6.0.0-next.7
 - @react-navigation/devtools@6.0.0-next.7
 - @react-navigation/drawer@6.0.0-next.9
 - @react-navigation/elements@1.0.0-next.9
 - @react-navigation/material-bottom-tabs@6.0.0-next.7
 - @react-navigation/material-top-tabs@6.0.0-next.8
 - @react-navigation/native@6.0.0-next.7
 - @react-navigation/stack@6.0.0-next.15
2021-05-10 13:36:34 +02:00
Satyajit Sahoo
7580efce89 refactor: rename animationPresentation to presentation 2021-05-10 12:42:02 +02:00
Satyajit Sahoo
1179d56c50 feat: return a NavigationContent component from useNavigationBuilder 2021-05-10 00:17:39 +02:00
Satyajit Sahoo
a6e498170f fix: add a deprecation warning for mode prop in stack 2021-05-09 23:42:12 +02:00
Satyajit Sahoo
4af9d10298 chore: publish
- @react-navigation/stack@6.0.0-next.14
2021-05-09 08:06:56 +02:00
Satyajit Sahoo
08e74af545 fix: fix modal animation not being set properly 2021-05-09 08:06:38 +02:00
56 changed files with 833 additions and 500 deletions

View File

@@ -4,42 +4,41 @@ beforeEach(async () => {
await page.click('[data-testid=LinkComponent]');
});
it('loads the article page', async () => {
expect(await page.evaluate(() => location.pathname + location.search)).toBe(
'/link-component/article/gandalf'
);
const getPageInfo = async () => ({
url: await page.evaluate(() => location.pathname + location.search),
title: await page.evaluate(() => document.title),
heading: (await page.accessibility.snapshot())?.children?.find(
(it) => it.role === 'heading'
)?.name,
});
expect(
((await page.accessibility.snapshot()) as any)?.children?.find(
(it: any) => it.role === 'heading'
)?.name
).toBe('Article by Gandalf');
it('loads the article page', async () => {
const { url, title, heading } = await getPageInfo();
expect(url).toBe('/link-component/article/gandalf');
expect(title).toBe('Article by Gandalf - React Navigation Example');
expect(heading).toBe('Article by Gandalf');
});
it('goes to the album page and goes back', async () => {
await page.click('[href="/link-component/music"]');
expect(await page.evaluate(() => location.pathname + location.search)).toBe(
'/link-component/music'
);
{
const { url, title, heading } = await getPageInfo();
expect(
((await page.accessibility.snapshot()) as any)?.children?.find(
(it: any) => it.role === 'heading'
)?.name
).toBe('Albums');
expect(url).toBe('/link-component/music');
expect(title).toBe('Albums - React Navigation Example');
expect(heading).toBe('Albums');
}
await page.click('[aria-label="Article by Gandalf, back"]');
await page.waitForNavigation();
expect(await page.evaluate(() => location.pathname + location.search)).toBe(
'/link-component/article/gandalf'
);
{
const { url, title, heading } = await getPageInfo();
expect(
((await page.accessibility.snapshot()) as any)?.children?.find(
(it: any) => it.role === 'heading'
)?.name
).toBe('Article by Gandalf');
expect(url).toBe('/link-component/article/gandalf');
expect(title).toBe('Article by Gandalf - React Navigation Example');
expect(heading).toBe('Article by Gandalf');
}
});

View File

@@ -43,6 +43,7 @@
"@types/cheerio": "^0.22.28",
"@types/jest-dev-server": "^4.2.0",
"@types/koa": "^2.13.1",
"@types/mock-require": "^2.0.0",
"@types/node-fetch": "^2.5.9",
"@types/react": "~16.9.35",
"@types/react-dom": "~16.9.8",
@@ -54,6 +55,7 @@
"expo-cli": "^4.4.4",
"jest": "^26.6.3",
"jest-dev-server": "^4.4.0",
"mock-require": "^3.0.3",
"mock-require-assets": "^0.0.1",
"node-fetch": "^2.6.1",
"nodemon": "^2.0.6",

View File

@@ -1,5 +1,6 @@
import 'mock-require-assets';
import mock from 'mock-require';
import Module from 'module';
// We need to make sure that .web.xx extensions are resolved before .xx
@@ -10,3 +11,14 @@ Module._extensions = Object.fromEntries(
return b[0].split('.').length - a[0].split('.').length;
})
);
// Set __DEV__ that expo needs
// @ts-expect-error
global.__DEV__ = process.env.NODE_ENV !== 'production';
// Reanimated doesn't support SSR :(
mock(
'react-native-reanimated',
// eslint-disable-next-line import/no-commonjs
{ ...require('react-native-reanimated/mock').default, call() {} }
);

View File

@@ -1,12 +1,17 @@
import * as React from 'react';
import { ScrollView, StyleSheet } from 'react-native';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { BlurView } from 'expo-blur';
import {
getFocusedRouteNameFromRoute,
ParamListBase,
NavigatorScreenParams,
} from '@react-navigation/native';
import type { StackScreenProps } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import {
createBottomTabNavigator,
useBottomTabBarHeight,
} from '@react-navigation/bottom-tabs';
import { HeaderBackButton } from '@react-navigation/elements';
import Albums from '../Shared/Albums';
import Contacts from '../Shared/Contacts';
@@ -28,6 +33,16 @@ type BottomTabParams = {
TabChat: undefined;
};
const AlbumsScreen = () => {
const tabBarHeight = useBottomTabBarHeight();
return (
<ScrollView contentContainerStyle={{ paddingBottom: tabBarHeight }}>
<Albums scrollEnabled={false} />
</ScrollView>
);
};
const BottomTabs = createBottomTabNavigator<BottomTabParams>();
export default function BottomTabsScreen({
@@ -78,10 +93,18 @@ export default function BottomTabsScreen({
/>
<BottomTabs.Screen
name="TabAlbums"
component={Albums}
component={AlbumsScreen}
options={{
title: 'Albums',
tabBarIcon: getTabBarIcon('image-album'),
tabBarStyle: { position: 'absolute' },
tabBarBackground: () => (
<BlurView
tint="light"
intensity={100}
style={StyleSheet.absoluteFill}
/>
),
}}
/>
</BottomTabs.Navigator>

View File

@@ -5,7 +5,6 @@ import type { ParamListBase } from '@react-navigation/native';
import {
createStackNavigator,
StackScreenProps,
TransitionPresets,
} from '@react-navigation/stack';
import Article from '../Shared/Article';
import Albums from '../Shared/Albums';
@@ -119,7 +118,7 @@ export default function MixedStackScreen({ navigation }: Props) {
component={AlbumsScreen}
options={{
title: 'Albums',
...TransitionPresets.ModalPresentationIOS,
presentation: 'modal',
}}
/>
</MixedStack.Navigator>

View File

@@ -82,7 +82,7 @@ export default function ModalStackScreen({ navigation }: Props) {
}, [navigation]);
return (
<ModalStack.Navigator screenOptions={{ animationPresentation: 'modal' }}>
<ModalStack.Navigator screenOptions={{ presentation: 'modal' }}>
<ModalStack.Screen
name="Article"
component={ArticleScreen}

View File

@@ -84,9 +84,7 @@ export default function TransparentStackScreen({ navigation }: Props) {
}, [navigation]);
return (
<TransparentStack.Navigator
screenOptions={{ animationPresentation: 'modal' }}
>
<TransparentStack.Navigator screenOptions={{ presentation: 'modal' }}>
<TransparentStack.Screen
name="Article"
component={ArticleScreen}

View File

@@ -206,7 +206,7 @@ export default function App() {
return () => Dimensions.removeEventListener('change', onDimensionsChange);
}, []);
const navigationRef = useNavigationContainerRef<RootStackParamList>();
const navigationRef = useNavigationContainerRef();
useReduxDevToolsExtension(navigationRef);

View File

@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.0.0-next.11](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.10...@react-navigation/bottom-tabs@6.0.0-next.11) (2021-05-16)
### Bug Fixes
* fix tab bar height including extra bottom inset ([7c722d2](https://github.com/react-navigation/react-navigation/commit/7c722d2028e914e8f143b9385ebf5e1c00131a01))
### Features
* add a tabBarBackground option to bottom tabs ([2f282f1](https://github.com/react-navigation/react-navigation/commit/2f282f107053a65b69f80edb5d9c858cfa569aa2))
# [6.0.0-next.10](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.9...@react-navigation/bottom-tabs@6.0.0-next.10) (2021-05-10)
### Bug Fixes
* add a deprecation warning for mode prop in stack ([a6e4981](https://github.com/react-navigation/react-navigation/commit/a6e498170f59648190fa5513e273ca523e56c5d5))
### Features
* return a NavigationContent component from useNavigationBuilder ([1179d56](https://github.com/react-navigation/react-navigation/commit/1179d56c5008270753feef41acdc1dbd2191efcf))
# [6.0.0-next.9](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.8...@react-navigation/bottom-tabs@6.0.0-next.9) (2021-05-09)
**Note:** Version bump only for package @react-navigation/bottom-tabs

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/bottom-tabs",
"description": "Bottom tab navigator following iOS design guidelines",
"version": "6.0.0-next.9",
"version": "6.0.0-next.11",
"keywords": [
"react-native-component",
"react-component",
@@ -36,12 +36,12 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/elements": "^1.0.0-next.8",
"@react-navigation/elements": "^1.0.0-next.10",
"color": "^3.1.3",
"warn-once": "^0.0.1"
"warn-once": "^0.1.0"
},
"devDependencies": {
"@react-navigation/native": "^6.0.0-next.6",
"@react-navigation/native": "^6.0.0-next.8",
"@testing-library/react-native": "^7.2.0",
"@types/color": "^3.0.1",
"@types/react": "^16.9.53",

View File

@@ -70,7 +70,12 @@ function BottomTabNavigator({
);
}
const { state, descriptors, navigation } = useNavigationBuilder<
const {
state,
descriptors,
navigation,
NavigationContent,
} = useNavigationBuilder<
TabNavigationState<ParamListBase>,
TabRouterOptions,
TabActionHelpers<ParamListBase>,
@@ -85,13 +90,15 @@ function BottomTabNavigator({
});
return (
<BottomTabView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
sceneContainerStyle={sceneContainerStyle}
/>
<NavigationContent>
<BottomTabView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
sceneContainerStyle={sceneContainerStyle}
/>
</NavigationContent>
);
}

View File

@@ -229,6 +229,15 @@ export type BottomTabNavigationOptions = HeaderOptions & {
*/
tabBarStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/**
* Component to use as background for the tab bar.
* You could render an image, a gradient, blur view etc.
*
* When using `BlurView`, make sure to set `position: 'absolute'` in `tabBarStyle` as well.
* You'd also need to use `useBottomTabBarHeight()` to add a bottom padding to your content.
*/
tabBarBackground?: () => React.ReactNode;
/**
* Whether this screen should be unmounted when navigating away from it.
* Defaults to `false`.

View File

@@ -144,6 +144,7 @@ export default function BottomTabBar({
tabBarHideOnKeyboard = false,
tabBarVisibilityAnimationConfig,
tabBarStyle,
tabBarBackground,
} = focusedOptions;
const dimensions = useSafeAreaFrame();
@@ -211,15 +212,7 @@ export default function BottomTabBar({
const handleLayout = (e: LayoutChangeEvent) => {
const { height, width } = e.nativeEvent.layout;
const topBorderWidth =
// @ts-ignore
StyleSheet.flatten([styles.tabBar, tabBarStyle])?.borderTopWidth;
onHeightChange?.(
height +
paddingBottom +
(typeof topBorderWidth === 'number' ? topBorderWidth : 0)
);
onHeightChange?.(height);
setLayout((layout) => {
if (height === layout.height && width === layout.width) {
@@ -252,12 +245,15 @@ export default function BottomTabBar({
layout,
});
const tabBarBackgroundElement = tabBarBackground?.();
return (
<Animated.View
style={[
styles.tabBar,
{
backgroundColor: colors.card,
backgroundColor:
tabBarBackgroundElement != null ? 'transparent' : colors.card,
borderTopColor: colors.border,
},
{
@@ -286,6 +282,9 @@ export default function BottomTabBar({
pointerEvents={isTabBarHidden ? 'none' : 'auto'}
onLayout={handleLayout}
>
<View pointerEvents="none" style={StyleSheet.absoluteFill}>
{tabBarBackgroundElement}
</View>
<View accessibilityRole="tablist" style={styles.content}>
{routes.map((route, index) => {
const focused = index === state.index;

View File

@@ -1,8 +1,7 @@
import * as React from 'react';
import { StyleSheet, Platform } from 'react-native';
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
import {
NavigationHelpersContext,
import type {
ParamListBase,
TabNavigationState,
} from '@react-navigation/native';
@@ -89,72 +88,70 @@ export default function BottomTabView(props: Props) {
const { routes } = state;
return (
<NavigationHelpersContext.Provider value={navigation}>
<SafeAreaProviderCompat>
<MaybeScreenContainer
enabled={detachInactiveScreens}
style={styles.container}
>
{routes.map((route, index) => {
const descriptor = descriptors[route.key];
const { lazy = true, unmountOnBlur } = descriptor.options;
const isFocused = state.index === index;
<SafeAreaProviderCompat>
<MaybeScreenContainer
enabled={detachInactiveScreens}
style={styles.container}
>
{routes.map((route, index) => {
const descriptor = descriptors[route.key];
const { lazy = true, unmountOnBlur } = descriptor.options;
const isFocused = state.index === index;
if (unmountOnBlur && !isFocused) {
return null;
}
if (unmountOnBlur && !isFocused) {
return null;
}
if (lazy && !loaded.includes(route.key) && !isFocused) {
// Don't render a lazy screen if we've never navigated to it
return null;
}
if (lazy && !loaded.includes(route.key) && !isFocused) {
// Don't render a lazy screen if we've never navigated to it
return null;
}
const {
header = ({ layout, options }: BottomTabHeaderProps) => (
<Header
{...options}
layout={layout}
title={getHeaderTitle(options, route.name)}
/>
),
} = descriptor.options;
const {
header = ({ layout, options }: BottomTabHeaderProps) => (
<Header
{...options}
layout={layout}
title={getHeaderTitle(options, route.name)}
/>
),
} = descriptor.options;
return (
<MaybeScreen
key={route.key}
style={StyleSheet.absoluteFill}
visible={isFocused}
enabled={detachInactiveScreens}
>
<BottomTabBarHeightContext.Provider value={tabBarHeight}>
<Screen
focused={isFocused}
route={descriptor.route}
navigation={descriptor.navigation}
headerShown={descriptor.options.headerShown}
headerStatusBarHeight={
descriptor.options.headerStatusBarHeight
}
header={header({
layout: dimensions,
route: descriptor.route,
navigation: descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
options: descriptor.options,
})}
style={sceneContainerStyle}
>
{descriptor.render()}
</Screen>
</BottomTabBarHeightContext.Provider>
</MaybeScreen>
);
})}
</MaybeScreenContainer>
<BottomTabBarHeightCallbackContext.Provider value={setTabBarHeight}>
{renderTabBar()}
</BottomTabBarHeightCallbackContext.Provider>
</SafeAreaProviderCompat>
</NavigationHelpersContext.Provider>
return (
<MaybeScreen
key={route.key}
style={StyleSheet.absoluteFill}
visible={isFocused}
enabled={detachInactiveScreens}
>
<BottomTabBarHeightContext.Provider value={tabBarHeight}>
<Screen
focused={isFocused}
route={descriptor.route}
navigation={descriptor.navigation}
headerShown={descriptor.options.headerShown}
headerStatusBarHeight={
descriptor.options.headerStatusBarHeight
}
header={header({
layout: dimensions,
route: descriptor.route,
navigation: descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
options: descriptor.options,
})}
style={sceneContainerStyle}
>
{descriptor.render()}
</Screen>
</BottomTabBarHeightContext.Provider>
</MaybeScreen>
);
})}
</MaybeScreenContainer>
<BottomTabBarHeightCallbackContext.Provider value={setTabBarHeight}>
{renderTabBar()}
</BottomTabBarHeightCallbackContext.Provider>
</SafeAreaProviderCompat>
);
}

View File

@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.7...@react-navigation/core@6.0.0-next.8) (2021-05-16)
### Bug Fixes
* fix type error when passing unannotated navigation ref ([dc4ffc0](https://github.com/react-navigation/react-navigation/commit/dc4ffc0171b4535fe1b6e839b9d54350121bcf55))
# [6.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.6...@react-navigation/core@6.0.0-next.7) (2021-05-10)
### Features
* return a NavigationContent component from useNavigationBuilder ([1179d56](https://github.com/react-navigation/react-navigation/commit/1179d56c5008270753feef41acdc1dbd2191efcf))
# [6.0.0-next.6](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.5...@react-navigation/core@6.0.0-next.6) (2021-05-09)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/core",
"description": "Core utilities for building navigators",
"version": "6.0.0-next.6",
"version": "6.0.0-next.8",
"keywords": [
"react",
"react-native",

View File

@@ -0,0 +1,30 @@
import * as React from 'react';
export default function useComponent<
T extends React.ComponentType<any>,
P extends {}
>(Component: T, props: P) {
const propsRef = React.useRef<P | null>(props);
// Normally refs shouldn't be mutated in render
// But we return a component which will be rendered
// So it's just for immediate consumption
propsRef.current = props;
React.useEffect(() => {
propsRef.current = null;
});
return React.useRef((rest: Omit<React.ComponentProps<T>, keyof P>) => {
const props = propsRef.current;
if (props === null) {
throw new Error(
'The returned component must be rendered in the same render phase as the hook.'
);
}
// @ts-expect-error: the props should be fine here
return <Component {...props} {...rest} />;
}).current;
}

View File

@@ -14,6 +14,7 @@ import {
} from '@react-navigation/routers';
import NavigationStateContext from './NavigationStateContext';
import NavigationRouteContext from './NavigationRouteContext';
import NavigationHelpersContext from './NavigationHelpersContext';
import Group from './Group';
import Screen from './Screen';
import useEventEmitter from './useEventEmitter';
@@ -29,6 +30,7 @@ import useKeyedChildListeners from './useKeyedChildListeners';
import useOnGetState from './useOnGetState';
import useScheduleUpdate from './useScheduleUpdate';
import useCurrentRender from './useCurrentRender';
import useComponent from './useComponent';
import isArrayEqual from './isArrayEqual';
import {
DefaultNavigatorOptions,
@@ -586,9 +588,14 @@ export default function useNavigationBuilder<
descriptors,
});
const NavigationContent = useComponent(NavigationHelpersContext.Provider, {
value: navigation,
});
return {
state,
navigation,
descriptors,
NavigationContent,
};
}

View File

@@ -1,10 +1,9 @@
import * as React from 'react';
import type { ParamListBase } from '@react-navigation/routers';
import createNavigationContainerRef from './createNavigationContainerRef';
import type { NavigationContainerRefWithCurrent } from './types';
export default function useNavigationContainerRef<
ParamList extends ParamListBase
ParamList extends {} = ReactNavigation.RootParamList
>(): NavigationContainerRefWithCurrent<ParamList> {
const navigation = React.useRef<NavigationContainerRefWithCurrent<ParamList> | null>(
null

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/devtools@6.0.0-next.7...@react-navigation/devtools@6.0.0-next.8) (2021-05-16)
### Bug Fixes
* fix type error when passing unannotated navigation ref ([dc4ffc0](https://github.com/react-navigation/react-navigation/commit/dc4ffc0171b4535fe1b6e839b9d54350121bcf55))
# [6.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/devtools@6.0.0-next.6...@react-navigation/devtools@6.0.0-next.7) (2021-05-10)
**Note:** Version bump only for package @react-navigation/devtools
# [6.0.0-next.6](https://github.com/react-navigation/react-navigation/compare/@react-navigation/devtools@6.0.0-next.5...@react-navigation/devtools@6.0.0-next.6) (2021-05-09)
**Note:** Version bump only for package @react-navigation/devtools

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/devtools",
"description": "Developer tools for React Navigation",
"version": "6.0.0-next.6",
"version": "6.0.0-next.8",
"keywords": [
"react",
"react-native",
@@ -36,7 +36,7 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/core": "^6.0.0-next.6",
"@react-navigation/core": "^6.0.0-next.8",
"deep-equal": "^2.0.5"
},
"devDependencies": {

View File

@@ -3,7 +3,6 @@ import type {
NavigationContainerRef,
NavigationState,
NavigationAction,
ParamListBase,
} from '@react-navigation/core';
import deepEqual from 'deep-equal';
@@ -23,7 +22,7 @@ type DevToolsExtension = {
declare const __REDUX_DEVTOOLS_EXTENSION__: DevToolsExtension | undefined;
export default function useReduxDevToolsExtension(
ref: React.RefObject<NavigationContainerRef<ParamListBase>>
ref: React.RefObject<NavigationContainerRef<any>>
) {
const devToolsRef = React.useRef<DevToolsConnection>();

View File

@@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.0.0-next.10](https://github.com/react-navigation/react-navigation/compare/@react-navigation/drawer@6.0.0-next.9...@react-navigation/drawer@6.0.0-next.10) (2021-05-16)
### Bug Fixes
* fix drawer content padding in RTL ([ea8ea20](https://github.com/react-navigation/react-navigation/commit/ea8ea20127d979d8c8ddbddf56de1bdfdf0243f9))
# [6.0.0-next.9](https://github.com/react-navigation/react-navigation/compare/@react-navigation/drawer@6.0.0-next.8...@react-navigation/drawer@6.0.0-next.9) (2021-05-10)
### Bug Fixes
* add a deprecation warning for mode prop in stack ([a6e4981](https://github.com/react-navigation/react-navigation/commit/a6e498170f59648190fa5513e273ca523e56c5d5))
### Features
* return a NavigationContent component from useNavigationBuilder ([1179d56](https://github.com/react-navigation/react-navigation/commit/1179d56c5008270753feef41acdc1dbd2191efcf))
# [6.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/drawer@6.0.0-next.7...@react-navigation/drawer@6.0.0-next.8) (2021-05-09)
**Note:** Version bump only for package @react-navigation/drawer

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/drawer",
"description": "Drawer navigator component with animated transitions and gesturess",
"version": "6.0.0-next.8",
"version": "6.0.0-next.10",
"keywords": [
"react-native-component",
"react-component",
@@ -41,12 +41,12 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/elements": "^1.0.0-next.8",
"@react-navigation/elements": "^1.0.0-next.10",
"color": "^3.1.3",
"warn-once": "^0.0.1"
"warn-once": "^0.1.0"
},
"devDependencies": {
"@react-navigation/native": "^6.0.0-next.6",
"@react-navigation/native": "^6.0.0-next.8",
"@testing-library/react-native": "^7.2.0",
"@types/react": "^16.9.53",
"@types/react-native": "~0.64.4",

View File

@@ -67,7 +67,12 @@ function DrawerNavigator({
);
}
const { state, descriptors, navigation } = useNavigationBuilder<
const {
state,
descriptors,
navigation,
NavigationContent,
} = useNavigationBuilder<
DrawerNavigationState<ParamListBase>,
DrawerRouterOptions,
DrawerActionHelpers<ParamListBase>,
@@ -83,12 +88,14 @@ function DrawerNavigator({
});
return (
<DrawerView
{...rest}
state={state}
descriptors={descriptors}
navigation={navigation}
/>
<NavigationContent>
<DrawerView
{...rest}
state={state}
descriptors={descriptors}
navigation={navigation}
/>
</NavigationContent>
);
}

View File

@@ -1,5 +1,10 @@
import * as React from 'react';
import { ScrollView, StyleSheet, ScrollViewProps } from 'react-native';
import {
ScrollView,
StyleSheet,
ScrollViewProps,
I18nManager,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import DrawerPositionContext from '../utils/DrawerPositionContext';
@@ -16,14 +21,18 @@ export default function DrawerContentScrollView({
const drawerPosition = React.useContext(DrawerPositionContext);
const insets = useSafeAreaInsets();
const isRight = I18nManager.isRTL
? drawerPosition === 'left'
: drawerPosition === 'right';
return (
<ScrollView
{...rest}
contentContainerStyle={[
{
paddingTop: insets.top + 4,
paddingLeft: drawerPosition === 'left' ? insets.left : 0,
paddingRight: drawerPosition === 'right' ? insets.right : 0,
paddingStart: !isRight ? insets.left : 0,
paddingEnd: isRight ? insets.right : 0,
},
contentContainerStyle,
]}

View File

@@ -9,7 +9,6 @@ import {
import { useSafeAreaFrame } from 'react-native-safe-area-context';
import Animated from 'react-native-reanimated';
import {
NavigationHelpersContext,
DrawerNavigationState,
DrawerActions,
useTheme,
@@ -296,13 +295,11 @@ function DrawerViewBase({
export default function DrawerView({ navigation, ...rest }: Props) {
return (
<NavigationHelpersContext.Provider value={navigation}>
<SafeAreaProviderCompat>
<GestureHandlerWrapper style={styles.content}>
<DrawerViewBase navigation={navigation} {...rest} />
</GestureHandlerWrapper>
</SafeAreaProviderCompat>
</NavigationHelpersContext.Provider>
<SafeAreaProviderCompat>
<GestureHandlerWrapper style={styles.content}>
<DrawerViewBase navigation={navigation} {...rest} />
</GestureHandlerWrapper>
</SafeAreaProviderCompat>
);
}

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [1.0.0-next.10](https://github.com/react-navigation/react-navigation/compare/@react-navigation/elements@1.0.0-next.9...@react-navigation/elements@1.0.0-next.10) (2021-05-16)
### Bug Fixes
* fix drawer content padding in RTL ([ea8ea20](https://github.com/react-navigation/react-navigation/commit/ea8ea20127d979d8c8ddbddf56de1bdfdf0243f9))
# [1.0.0-next.9](https://github.com/react-navigation/react-navigation/compare/@react-navigation/elements@1.0.0-next.8...@react-navigation/elements@1.0.0-next.9) (2021-05-10)
**Note:** Version bump only for package @react-navigation/elements
# [1.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/elements@1.0.0-next.7...@react-navigation/elements@1.0.0-next.8) (2021-05-09)
**Note:** Version bump only for package @react-navigation/elements

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/elements",
"description": "UI Components for React Navigation",
"version": "1.0.0-next.8",
"version": "1.0.0-next.10",
"keywords": [
"react-native",
"react-navigation",
@@ -38,7 +38,7 @@
},
"devDependencies": {
"@react-native-masked-view/masked-view": "^0.2.3",
"@react-navigation/native": "^6.0.0-next.6",
"@react-navigation/native": "^6.0.0-next.8",
"@testing-library/react-native": "^7.2.0",
"@types/react": "^16.9.53",
"@types/react-native": "~0.64.4",

View File

@@ -214,7 +214,7 @@ export default function Header(props: Props) {
style={[
styles.left,
headerTitleAlign === 'center' && styles.expand,
{ marginLeft: insets.left },
{ marginStart: insets.left },
leftContainerStyle,
]}
>
@@ -236,7 +236,7 @@ export default function Header(props: Props) {
style={[
styles.right,
styles.expand,
{ marginRight: insets.right },
{ marginEnd: insets.right },
rightContainerStyle,
]}
>

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-bottom-tabs@6.0.0-next.7...@react-navigation/material-bottom-tabs@6.0.0-next.8) (2021-05-16)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
# [6.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-bottom-tabs@6.0.0-next.6...@react-navigation/material-bottom-tabs@6.0.0-next.7) (2021-05-10)
### Features
* return a NavigationContent component from useNavigationBuilder ([1179d56](https://github.com/react-navigation/react-navigation/commit/1179d56c5008270753feef41acdc1dbd2191efcf))
# [6.0.0-next.6](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-bottom-tabs@6.0.0-next.5...@react-navigation/material-bottom-tabs@6.0.0-next.6) (2021-05-09)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/material-bottom-tabs",
"description": "Integration for bottom navigation component from react-native-paper",
"version": "6.0.0-next.6",
"version": "6.0.0-next.8",
"keywords": [
"react-native-component",
"react-component",
@@ -41,7 +41,7 @@
"clean": "del lib"
},
"devDependencies": {
"@react-navigation/native": "^6.0.0-next.6",
"@react-navigation/native": "^6.0.0-next.8",
"@testing-library/react-native": "^7.2.0",
"@types/react": "^16.9.53",
"@types/react-native": "~0.64.4",

View File

@@ -28,7 +28,12 @@ function MaterialBottomTabNavigator({
screenOptions,
...rest
}: Props) {
const { state, descriptors, navigation } = useNavigationBuilder<
const {
state,
descriptors,
navigation,
NavigationContent,
} = useNavigationBuilder<
TabNavigationState<ParamListBase>,
TabRouterOptions,
TabActionHelpers<ParamListBase>,
@@ -42,12 +47,14 @@ function MaterialBottomTabNavigator({
});
return (
<MaterialBottomTabView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
/>
<NavigationContent>
<MaterialBottomTabView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
/>
</NavigationContent>
);
}

View File

@@ -2,7 +2,6 @@ import * as React from 'react';
import { Text, StyleSheet, Platform } from 'react-native';
import { BottomNavigation, DefaultTheme, DarkTheme } from 'react-native-paper';
import {
NavigationHelpersContext,
Route,
TabNavigationState,
TabActions,
@@ -75,7 +74,7 @@ try {
};
}
function MaterialBottomTabViewInner({
export default function MaterialBottomTabView({
state,
navigation,
descriptors,
@@ -192,14 +191,6 @@ function MaterialBottomTabViewInner({
);
}
export default function MaterialBottomTabView(props: Props) {
return (
<NavigationHelpersContext.Provider value={props.navigation}>
<MaterialBottomTabViewInner {...props} />
</NavigationHelpersContext.Provider>
);
}
const styles = StyleSheet.create({
icon: {
backgroundColor: 'transparent',

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.0.0-next.9](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-top-tabs@6.0.0-next.8...@react-navigation/material-top-tabs@6.0.0-next.9) (2021-05-16)
**Note:** Version bump only for package @react-navigation/material-top-tabs
# [6.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-top-tabs@6.0.0-next.7...@react-navigation/material-top-tabs@6.0.0-next.8) (2021-05-10)
### Bug Fixes
* add a deprecation warning for mode prop in stack ([a6e4981](https://github.com/react-navigation/react-navigation/commit/a6e498170f59648190fa5513e273ca523e56c5d5))
### Features
* return a NavigationContent component from useNavigationBuilder ([1179d56](https://github.com/react-navigation/react-navigation/commit/1179d56c5008270753feef41acdc1dbd2191efcf))
# [6.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-top-tabs@6.0.0-next.6...@react-navigation/material-top-tabs@6.0.0-next.7) (2021-05-09)
**Note:** Version bump only for package @react-navigation/material-top-tabs

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/material-top-tabs",
"description": "Integration for the animated tab view component from react-native-tab-view",
"version": "6.0.0-next.7",
"version": "6.0.0-next.9",
"keywords": [
"react-native-component",
"react-component",
@@ -42,10 +42,10 @@
},
"dependencies": {
"color": "^3.1.3",
"warn-once": "^0.0.1"
"warn-once": "^0.1.0"
},
"devDependencies": {
"@react-navigation/native": "^6.0.0-next.6",
"@react-navigation/native": "^6.0.0-next.8",
"@testing-library/react-native": "^7.2.0",
"@types/react": "^16.9.53",
"@types/react-native": "~0.64.4",

View File

@@ -71,7 +71,12 @@ function MaterialTopTabNavigator({
);
}
const { state, descriptors, navigation } = useNavigationBuilder<
const {
state,
descriptors,
navigation,
NavigationContent,
} = useNavigationBuilder<
TabNavigationState<ParamListBase>,
TabRouterOptions,
TabActionHelpers<ParamListBase>,
@@ -85,12 +90,14 @@ function MaterialTopTabNavigator({
});
return (
<MaterialTopTabView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
/>
<NavigationContent>
<MaterialTopTabView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
/>
</NavigationContent>
);
}

View File

@@ -1,7 +1,6 @@
import * as React from 'react';
import { TabView, SceneRendererProps } from 'react-native-tab-view';
import {
NavigationHelpersContext,
TabNavigationState,
TabActions,
ParamListBase,
@@ -43,29 +42,27 @@ export default function MaterialTopTabView({
};
return (
<NavigationHelpersContext.Provider value={navigation}>
<TabView<Route<string>>
{...rest}
onIndexChange={(index) =>
navigation.dispatch({
...TabActions.jumpTo(state.routes[index].name),
target: state.key,
})
}
renderScene={({ route }) => descriptors[route.key].render()}
navigationState={state}
renderTabBar={renderTabBar}
renderLazyPlaceholder={({ route }) =>
descriptors[route.key].options.lazyPlaceholder?.() ?? null
}
lazy={({ route }) => descriptors[route.key].options.lazy === true}
onSwipeStart={() => navigation.emit({ type: 'swipeStart' })}
onSwipeEnd={() => navigation.emit({ type: 'swipeEnd' })}
sceneContainerStyle={[
{ backgroundColor: colors.background },
sceneContainerStyle,
]}
/>
</NavigationHelpersContext.Provider>
<TabView<Route<string>>
{...rest}
onIndexChange={(index) =>
navigation.dispatch({
...TabActions.jumpTo(state.routes[index].name),
target: state.key,
})
}
renderScene={({ route }) => descriptors[route.key].render()}
navigationState={state}
renderTabBar={renderTabBar}
renderLazyPlaceholder={({ route }) =>
descriptors[route.key].options.lazyPlaceholder?.() ?? null
}
lazy={({ route }) => descriptors[route.key].options.lazy === true}
onSwipeStart={() => navigation.emit({ type: 'swipeStart' })}
onSwipeEnd={() => navigation.emit({ type: 'swipeEnd' })}
sceneContainerStyle={[
{ backgroundColor: colors.background },
sceneContainerStyle,
]}
/>
);
}

View File

@@ -3,6 +3,28 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/native@6.0.0-next.7...@react-navigation/native@6.0.0-next.8) (2021-05-16)
### Bug Fixes
* add ability to pass generic params to Link ([9c30c42](https://github.com/react-navigation/react-navigation/commit/9c30c42c0bddbc90c58b79a8be6d57e57a131e77))
# [6.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/native@6.0.0-next.6...@react-navigation/native@6.0.0-next.7) (2021-05-10)
### Features
* return a NavigationContent component from useNavigationBuilder ([1179d56](https://github.com/react-navigation/react-navigation/commit/1179d56c5008270753feef41acdc1dbd2191efcf))
# [6.0.0-next.6](https://github.com/react-navigation/react-navigation/compare/@react-navigation/native@6.0.0-next.5...@react-navigation/native@6.0.0-next.6) (2021-05-09)
**Note:** Version bump only for package @react-navigation/native

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/native",
"description": "React Native integration for React Navigation",
"version": "6.0.0-next.6",
"version": "6.0.0-next.8",
"keywords": [
"react-native",
"react-navigation",
@@ -37,7 +37,7 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/core": "^6.0.0-next.6",
"@react-navigation/core": "^6.0.0-next.8",
"escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.22"
},

View File

@@ -4,8 +4,8 @@ import type { NavigationAction } from '@react-navigation/core';
import useLinkProps from './useLinkProps';
import type { To } from './useLinkTo';
type Props = {
to: To;
type Props<ParamList extends ReactNavigation.RootParamList> = {
to: To<ParamList>;
action?: NavigationAction;
target?: string;
onPress?: (
@@ -21,8 +21,12 @@ type Props = {
* @param props.action Optional action to use for in-page navigation. By default, the path is parsed to an action based on linking config.
* @param props.children Child elements to render the content.
*/
export default function Link({ to, action, ...rest }: Props) {
const props = useLinkProps({ to, action });
export default function Link<ParamList extends ReactNavigation.RootParamList>({
to,
action,
...rest
}: Props<ParamList>) {
const props = useLinkProps<ParamList>({ to, action });
const onPress = (
e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent

View File

@@ -4,7 +4,6 @@ import {
createNavigatorFactory,
StackRouter,
TabRouter,
NavigationHelpersContext,
createNavigationContainerRef,
ParamListBase,
} from '@react-navigation/core';
@@ -22,36 +21,36 @@ it('integrates with the history API', () => {
jest.useFakeTimers();
const createStackNavigator = createNavigatorFactory((props: any) => {
const { navigation, state, descriptors } = useNavigationBuilder(
const { state, descriptors, NavigationContent } = useNavigationBuilder(
StackRouter,
props
);
return (
<NavigationHelpersContext.Provider value={navigation}>
<NavigationContent>
{state.routes.map((route, i) => (
<div key={route.key} aria-current={state.index === i || undefined}>
{descriptors[route.key].render()}
</div>
))}
</NavigationHelpersContext.Provider>
</NavigationContent>
);
});
const createTabNavigator = createNavigatorFactory((props: any) => {
const { navigation, state, descriptors } = useNavigationBuilder(
const { state, descriptors, NavigationContent } = useNavigationBuilder(
TabRouter,
props
);
return (
<NavigationHelpersContext.Provider value={navigation}>
<NavigationContent>
{state.routes.map((route, i) => (
<div key={route.key} aria-current={state.index === i || undefined}>
{descriptors[route.key].render()}
</div>
))}
</NavigationHelpersContext.Provider>
</NavigationContent>
);
});

View File

@@ -4,7 +4,6 @@ import {
createNavigatorFactory,
StackRouter,
TabRouter,
NavigationHelpersContext,
NavigatorScreenParams,
} from '@react-navigation/core';
import { renderToString } from 'react-dom/server';
@@ -23,17 +22,17 @@ jest.mock('../useLinking', () => require('../useLinking.tsx').default);
it('renders correct state with location', () => {
const createStackNavigator = createNavigatorFactory((props: any) => {
const { navigation, state, descriptors } = useNavigationBuilder(
const { state, descriptors, NavigationContent } = useNavigationBuilder(
StackRouter,
props
);
return (
<NavigationHelpersContext.Provider value={navigation}>
<NavigationContent>
{state.routes.map((route) => (
<div key={route.key}>{descriptors[route.key].render()}</div>
))}
</NavigationHelpersContext.Provider>
</NavigationContent>
);
});
@@ -116,17 +115,17 @@ it('renders correct state with location', () => {
it('gets the current options', () => {
const createTabNavigator = createNavigatorFactory((props: any) => {
const { navigation, state, descriptors } = useNavigationBuilder(
const { state, descriptors, NavigationContent } = useNavigationBuilder(
TabRouter,
props
);
return (
<NavigationHelpersContext.Provider value={navigation}>
<NavigationContent>
{state.routes.map((route) => (
<div key={route.key}>{descriptors[route.key].render()}</div>
))}
</NavigationHelpersContext.Provider>
</NavigationContent>
);
});

View File

@@ -2,7 +2,6 @@ export * from '@react-navigation/core';
export { default as NavigationContainer } from './NavigationContainer';
export { default as useBackButton } from './useBackButton';
export { default as useScrollToTop } from './useScrollToTop';
export { default as DefaultTheme } from './theming/DefaultTheme';

View File

@@ -6,8 +6,8 @@ import {
} from '@react-navigation/core';
import useLinkTo, { To } from './useLinkTo';
type Props = {
to: To;
type Props<ParamList extends ReactNavigation.RootParamList> = {
to: To<ParamList>;
action?: NavigationAction;
};
@@ -17,9 +17,11 @@ type Props = {
* @param props.to Absolute path to screen (e.g. `/feeds/hot`).
* @param props.action Optional action to use for in-page navigation. By default, the path is parsed to an action based on linking config.
*/
export default function useLinkProps({ to, action }: Props) {
export default function useLinkProps<
ParamList extends ReactNavigation.RootParamList
>({ to, action }: Props<ParamList>) {
const navigation = React.useContext(NavigationHelpersContext);
const linkTo = useLinkTo();
const linkTo = useLinkTo<ParamList>();
const onPress = (
e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent

View File

@@ -21,12 +21,14 @@ export type To<
params: ParamList[RouteName];
});
export default function useLinkTo() {
export default function useLinkTo<
ParamList extends ReactNavigation.RootParamList
>() {
const navigation = React.useContext(NavigationContext);
const linking = React.useContext(LinkingContext);
const linkTo = React.useCallback(
(to: To) => {
(to: To<ParamList>) => {
if (navigation === undefined) {
throw new Error(
"Couldn't find a navigation object. Is your component inside a screen in a navigator?"
@@ -42,6 +44,7 @@ export default function useLinkTo() {
}
if (typeof to !== 'string') {
// @ts-expect-error: This is fine
root.navigate(to.screen, to.params);
return;
}

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [6.0.0-next.16](https://github.com/react-navigation/react-navigation/compare/@react-navigation/stack@6.0.0-next.15...@react-navigation/stack@6.0.0-next.16) (2021-05-16)
### Bug Fixes
* don't enable animation & gestures for first screen ([6ebe082](https://github.com/react-navigation/react-navigation/commit/6ebe0824df3df4973190428a14286aab0d14d3c1))
* make stack screens accessible on web without screens ([22b7c3f](https://github.com/react-navigation/react-navigation/commit/22b7c3f6c18a73fc55b0289b91b8d3a96f5be29c))
* move keyboardHandlingEnabled to screen options ([82900cc](https://github.com/react-navigation/react-navigation/commit/82900cceffa3e338b7b93e831f9ba6cbb3784815))
# [6.0.0-next.15](https://github.com/react-navigation/react-navigation/compare/@react-navigation/stack@6.0.0-next.14...@react-navigation/stack@6.0.0-next.15) (2021-05-10)
### Bug Fixes
* add a deprecation warning for mode prop in stack ([a6e4981](https://github.com/react-navigation/react-navigation/commit/a6e498170f59648190fa5513e273ca523e56c5d5))
### Features
* return a NavigationContent component from useNavigationBuilder ([1179d56](https://github.com/react-navigation/react-navigation/commit/1179d56c5008270753feef41acdc1dbd2191efcf))
# [6.0.0-next.14](https://github.com/react-navigation/react-navigation/compare/@react-navigation/stack@6.0.0-next.13...@react-navigation/stack@6.0.0-next.14) (2021-05-09)
### Bug Fixes
* fix modal animation not being set properly ([08e74af](https://github.com/react-navigation/react-navigation/commit/08e74af54529582dcbc8d91e77bfed70f006f00d))
# [6.0.0-next.13](https://github.com/react-navigation/react-navigation/compare/@react-navigation/stack@6.0.0-next.12...@react-navigation/stack@6.0.0-next.13) (2021-05-09)
**Note:** Version bump only for package @react-navigation/stack

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/stack",
"description": "Stack navigator component for iOS and Android with animated transitions and gestures",
"version": "6.0.0-next.13",
"version": "6.0.0-next.16",
"keywords": [
"react-native-component",
"react-component",
@@ -40,13 +40,13 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/elements": "^1.0.0-next.8",
"@react-navigation/elements": "^1.0.0-next.10",
"color": "^3.1.3",
"react-native-iphone-x-helper": "^1.3.0",
"warn-once": "^0.0.1"
"warn-once": "^0.1.0"
},
"devDependencies": {
"@react-navigation/native": "^6.0.0-next.6",
"@react-navigation/native": "^6.0.0-next.8",
"@testing-library/react-native": "^7.2.0",
"@types/color": "^3.0.1",
"@types/react": "^16.9.53",

View File

@@ -30,20 +30,33 @@ function StackNavigator({
screenOptions,
...rest
}: Props) {
// @ts-expect-error: mode is deprecated
const mode = rest.mode as 'card' | 'modal' | undefined;
// @ts-expect-error: headerMode='none' is deprecated
const headerMode = rest.headerMode as StackHeaderMode | 'none' | undefined;
warnOnce(
mode != null,
`Stack Navigator: 'mode="${mode}"' is deprecated. Use 'presentation: "${mode}"' in 'screenOptions' instead.`
);
warnOnce(
headerMode === 'none',
`Stack Navigator: 'headerMode="none"' is deprecated. Use 'headerShown: false' in 'screenOptions' instead.`
);
warnOnce(
headerMode && headerMode !== 'none',
headerMode != null && headerMode !== 'none',
`Stack Navigator: 'headerMode' is moved to 'options'. Moved it to 'screenOptions' to keep current behavior.`
);
const { state, descriptors, navigation } = useNavigationBuilder<
const {
state,
descriptors,
navigation,
NavigationContent,
} = useNavigationBuilder<
StackNavigationState<ParamListBase>,
StackRouterOptions,
StackActionHelpers<ParamListBase>,
@@ -54,6 +67,7 @@ function StackNavigator({
children,
screenOptions,
defaultScreenOptions: () => ({
presentation: mode,
headerShown: headerMode ? headerMode !== 'none' : true,
headerMode: headerMode && headerMode !== 'none' ? headerMode : undefined,
}),
@@ -85,12 +99,14 @@ function StackNavigator({
);
return (
<StackView
{...rest}
state={state}
descriptors={descriptors}
navigation={navigation}
/>
<NavigationContent>
<StackView
{...rest}
state={state}
descriptors={descriptors}
navigation={navigation}
/>
</NavigationContent>
);
}

View File

@@ -246,22 +246,25 @@ export type StackNavigationOptions = StackHeaderOptions &
* so that the previous screen isn't transformed or invisible.
*/
cardStyle?: StyleProp<ViewStyle>;
/**
* Whether this screen should be presented as a modal or a regular card.
*
* Specifying this will configure several options:
* - `card`: Use the default OS animations for iOS and Android screen transitions.
* - `modal`: Use Modal animations. This changes a few things:
* - Sets `headerMode` to `screen` for the screen unless specified otherwise.
* - Changes the screen animation to match the platform behavior for modals.
* - Adjusts the `detachPreviousScreen` option so that the previous screen stays rendered.
*
* Defaults to 'card'.
*/
presentation?: 'card' | 'modal';
/**
* Whether transition animation should be enabled the screen.
* If you set it to `false`, the screen won't animate when pushing or popping.
* Defaults to `true` on Android and iOS, `false` on Web.
*/
animationEnabled?: boolean;
/**
* Whether this screen should be presented as a modal or a regular card.
*
* If you haven't customized the animations separately, the animation will change based on the value:
* - 'modal' - modal animation on iOS and Android. It'll also default `headerMode` to `screen`.
* - 'card' - horizontal slide animation on iOS, OS-default animation on Android.
*
* Defaults to 'card'.
*/
animationPresentation?: 'card' | 'modal';
/**
* The type of animation to use when this screen replaces another screen. Defaults to `push`.
* When `pop` is used, the `pop` animation is applied to the screen being replaced.
@@ -289,18 +292,19 @@ export type StackNavigationOptions = StackHeaderOptions &
* Defaults to `false` for the last screen for modals, otherwise `true`.
*/
detachPreviousScreen?: boolean;
/**
* If `false`, the keyboard will NOT automatically dismiss when navigating to a new screen from this screen.
* Defaults to `true`.
*/
keyboardHandlingEnabled?: boolean;
};
export type StackNavigationConfig = {
/**
* If `false`, the keyboard will NOT automatically dismiss when navigating to a new screen.
* Defaults to `true`.
*/
keyboardHandlingEnabled?: boolean;
/**
* Whether inactive screens should be detached from the view hierarchy to save memory.
* Make sure to call `enableScreens` from `react-native-screens` to make it work.
* Defaults to `true` on Android, depends on the version of `react-native-screens` on iOS.
* This will have no effect if you disable `react-native-screens`.
*
* Defaults to `true`.
*/
detachInactiveScreens?: boolean;
};
@@ -332,7 +336,7 @@ export type StackCardInterpolationProps = {
progress: Animated.AnimatedInterpolation;
};
/**
* Values for the current screen the screen after this one in the stack.
* Values for the screen after this one in the stack.
* This can be `undefined` in case the screen animating is the last one.
*/
next?: {
@@ -411,7 +415,7 @@ export type StackHeaderInterpolationProps = {
progress: Animated.AnimatedInterpolation;
};
/**
* Values for the current screen the screen after this one in the stack.
* Values for the screen after this one in the stack.
* This can be `undefined` in case the screen animating is the last one.
*/
next?: {

View File

@@ -0,0 +1,105 @@
import * as React from 'react';
import { TextInput, Keyboard, HostComponent } from 'react-native';
type InputRef = React.ElementRef<HostComponent<unknown>> | undefined;
export default function useKeyboardManager(isEnabled: () => boolean) {
// Numeric id of the previously focused text input
// When a gesture didn't change the tab, we can restore the focused input with this
const previouslyFocusedTextInputRef = React.useRef<InputRef>(undefined);
const startTimestampRef = React.useRef<number>(0);
const keyboardTimeoutRef = React.useRef<any>();
const clearKeyboardTimeout = React.useCallback(() => {
if (keyboardTimeoutRef.current !== undefined) {
clearTimeout(keyboardTimeoutRef.current);
keyboardTimeoutRef.current = undefined;
}
}, []);
const onPageChangeStart = React.useCallback(() => {
if (!isEnabled()) {
return;
}
clearKeyboardTimeout();
const input: InputRef = TextInput.State.currentlyFocusedInput();
// When a page change begins, blur the currently focused input
input?.blur();
// Store the id of this input so we can refocus it if change was cancelled
previouslyFocusedTextInputRef.current = input;
// Store timestamp for touch start
startTimestampRef.current = Date.now();
}, [clearKeyboardTimeout, isEnabled]);
const onPageChangeConfirm = React.useCallback(
(force: boolean) => {
if (!isEnabled()) {
return;
}
clearKeyboardTimeout();
if (force) {
// Always dismiss input, even if we don't have a ref to it
// We might not have the ref if onPageChangeStart was never called
// This can happen if page change was not from a gesture
Keyboard.dismiss();
} else {
const input = previouslyFocusedTextInputRef.current;
// Dismiss the keyboard only if an input was a focused before
// This makes sure we don't dismiss input on going back and focusing an input
input?.blur();
}
// Cleanup the ID on successful page change
previouslyFocusedTextInputRef.current = undefined;
},
[clearKeyboardTimeout, isEnabled]
);
const onPageChangeCancel = React.useCallback(() => {
if (!isEnabled()) {
return;
}
clearKeyboardTimeout();
// The page didn't change, we should restore the focus of text input
const input = previouslyFocusedTextInputRef.current;
if (input) {
// If the interaction was super short we should make sure keyboard won't hide again.
// Too fast input refocus will result only in keyboard flashing on screen and hiding right away.
// During first ~100ms keyboard will be dismissed no matter what,
// so we have to make sure it won't interrupt input refocus logic.
// That's why when the interaction is shorter than 100ms we add delay so it won't hide once again.
// Subtracting timestamps makes us sure the delay is executed only when needed.
if (Date.now() - startTimestampRef.current < 100) {
keyboardTimeoutRef.current = setTimeout(() => {
input?.focus();
previouslyFocusedTextInputRef.current = undefined;
}, 100);
} else {
input?.focus();
previouslyFocusedTextInputRef.current = undefined;
}
}
}, [clearKeyboardTimeout, isEnabled]);
React.useEffect(() => {
return () => clearKeyboardTimeout();
}, [clearKeyboardTimeout]);
return {
onPageChangeStart,
onPageChangeConfirm,
onPageChangeCancel,
};
}

View File

@@ -1,113 +0,0 @@
import * as React from 'react';
import { TextInput, Keyboard, HostComponent } from 'react-native';
type Props = {
enabled: boolean;
children: (props: {
onPageChangeStart: () => void;
onPageChangeConfirm: (force: boolean) => void;
onPageChangeCancel: () => void;
}) => React.ReactNode;
};
type InputRef = React.ElementRef<HostComponent<unknown>> | undefined;
export default class KeyboardManager extends React.Component<Props> {
componentWillUnmount() {
this.clearKeyboardTimeout();
}
// Numeric id of the previously focused text input
// When a gesture didn't change the tab, we can restore the focused input with this
private previouslyFocusedTextInput: InputRef = undefined;
private startTimestamp: number = 0;
private keyboardTimeout: any;
private clearKeyboardTimeout = () => {
if (this.keyboardTimeout !== undefined) {
clearTimeout(this.keyboardTimeout);
this.keyboardTimeout = undefined;
}
};
private handlePageChangeStart = () => {
if (!this.props.enabled) {
return;
}
this.clearKeyboardTimeout();
const input: InputRef = TextInput.State.currentlyFocusedInput();
// When a page change begins, blur the currently focused input
input?.blur();
// Store the id of this input so we can refocus it if change was cancelled
this.previouslyFocusedTextInput = input;
// Store timestamp for touch start
this.startTimestamp = Date.now();
};
private handlePageChangeConfirm = (force: boolean) => {
if (!this.props.enabled) {
return;
}
this.clearKeyboardTimeout();
if (force) {
// Always dismiss input, even if we don't have a ref to it
// We might not have the ref if onPageChangeStart was never called
// This can happen if page change was not from a gesture
Keyboard.dismiss();
} else {
const input = this.previouslyFocusedTextInput;
// Dismiss the keyboard only if an input was a focused before
// This makes sure we don't dismiss input on going back and focusing an input
input?.blur();
}
// Cleanup the ID on successful page change
this.previouslyFocusedTextInput = undefined;
};
private handlePageChangeCancel = () => {
if (!this.props.enabled) {
return;
}
this.clearKeyboardTimeout();
// The page didn't change, we should restore the focus of text input
const input = this.previouslyFocusedTextInput;
if (input) {
// If the interaction was super short we should make sure keyboard won't hide again.
// Too fast input refocus will result only in keyboard flashing on screen and hiding right away.
// During first ~100ms keyboard will be dismissed no matter what,
// so we have to make sure it won't interrupt input refocus logic.
// That's why when the interaction is shorter than 100ms we add delay so it won't hide once again.
// Subtracting timestamps makes us sure the delay is executed only when needed.
if (Date.now() - this.startTimestamp < 100) {
this.keyboardTimeout = setTimeout(() => {
input?.focus();
this.previouslyFocusedTextInput = undefined;
}, 100);
} else {
input?.focus();
this.previouslyFocusedTextInput = undefined;
}
}
};
render() {
return this.props.children({
onPageChangeStart: this.handlePageChangeStart,
onPageChangeConfirm: this.handlePageChangeConfirm,
onPageChangeCancel: this.handlePageChangeCancel,
});
}
}

View File

@@ -11,6 +11,7 @@ import type { Props as HeaderContainerProps } from '../Header/HeaderContainer';
import Card from './Card';
import { forModalPresentationIOS } from '../../TransitionConfigs/CardStyleInterpolators';
import ModalPresentationContext from '../../utils/ModalPresentationContext';
import useKeyboardManager from '../../utils/useKeyboardManager';
import type { Layout, Scene } from '../../types';
type Props = {
@@ -37,9 +38,6 @@ type Props = {
closing: boolean
) => void;
onTransitionEnd?: (props: { route: Route<string> }, closing: boolean) => void;
onPageChangeStart?: () => void;
onPageChangeConfirm?: (force: boolean) => void;
onPageChangeCancel?: () => void;
onGestureStart?: (props: { route: Route<string> }) => void;
onGestureEnd?: (props: { route: Route<string> }) => void;
onGestureCancel?: (props: { route: Route<string> }) => void;
@@ -70,9 +68,6 @@ function CardContainer({
layout,
onCloseRoute,
onOpenRoute,
onPageChangeCancel,
onPageChangeConfirm,
onPageChangeStart,
onGestureCancel,
onGestureEnd,
onGestureStart,
@@ -88,6 +83,20 @@ function CardContainer({
}: Props) {
const parentHeaderHeight = React.useContext(HeaderHeightContext);
const {
onPageChangeStart,
onPageChangeCancel,
onPageChangeConfirm,
} = useKeyboardManager(
React.useCallback(() => {
const { options, navigation } = scene.descriptor;
return (
navigation.isFocused() && options.keyboardHandlingEnabled !== false
);
}, [scene.descriptor])
);
const handleOpen = () => {
const { route } = scene.descriptor;
@@ -170,7 +179,9 @@ function CardContainer({
}, [pointerEvents, scene.progress.next]);
const {
animationPresentation,
presentation,
detachPreviousScreen,
animationEnabled,
cardOverlay,
cardOverlayEnabled,
cardShadowEnabled,
@@ -228,9 +239,7 @@ function CardContainer({
accessibilityElementsHidden={!focused}
importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'}
pointerEvents={active ? 'box-none' : pointerEvents}
pageOverflowEnabled={
headerMode !== 'float' && animationPresentation !== 'modal'
}
pageOverflowEnabled={headerMode !== 'float' && presentation !== 'modal'}
headerDarkContent={headerDarkContent}
containerStyle={
hasAbsoluteFloatHeader && headerMode !== 'screen'
@@ -243,6 +252,15 @@ function CardContainer({
// This is necessary to avoid unfocused larger pages increasing scroll area
// The issue can be seen on the web when a smaller screen is pushed over a larger one
overflow: active ? undefined : 'hidden',
display:
// Hide unfocused screens when animation isn't enabled
// This is also necessary for a11y on web
animationEnabled === false &&
detachPreviousScreen !== false &&
presentation !== 'modal' &&
!focused
? 'none'
: 'flex',
},
StyleSheet.absoluteFill,
]}

View File

@@ -63,9 +63,6 @@ type Props = {
closing: boolean
) => void;
onTransitionEnd: (props: { route: Route<string> }, closing: boolean) => void;
onPageChangeStart?: () => void;
onPageChangeConfirm?: (force: boolean) => void;
onPageChangeCancel?: () => void;
onGestureStart?: (props: { route: Route<string> }) => void;
onGestureEnd?: (props: { route: Route<string> }) => void;
onGestureCancel?: (props: { route: Route<string> }) => void;
@@ -122,8 +119,8 @@ const getDistanceFromOptions = (
descriptor?: StackDescriptor
) => {
const {
animationPresentation,
gestureDirection = animationPresentation === 'modal'
presentation,
gestureDirection = presentation === 'modal'
? ModalTransition.gestureDirection
: DefaultTransition.gestureDirection,
} = (descriptor?.options || {}) as StackNavigationOptions;
@@ -214,20 +211,30 @@ export default class CardStack extends React.Component<Props, State> {
props.descriptors[previousRoute?.key] ||
state.descriptors[previousRoute?.key];
const { options } = descriptor;
// When a screen is not the last, it should use next screen's transition config
// Many transitions also animate the previous screen, so using 2 different transitions doesn't look right
// For example combining a slide and a modal transition would look wrong otherwise
// With this approach, combining different transition styles in the same navigator mostly looks right
// This will still be broken when 2 transitions have different idle state (e.g. modal presentation),
// but majority of the transitions look alright
const optionsForTransitionConfig =
index !== self.length - 1 && nextDescriptor
? nextDescriptor.options
: descriptor.options;
let defaultTransitionPreset =
options.animationPresentation === 'modal'
optionsForTransitionConfig.presentation === 'modal'
? ModalTransition
: DefaultTransition;
const {
animationEnabled = Platform.OS !== 'web' &&
animationEnabled = index !== 0 &&
Platform.OS !== 'web' &&
Platform.OS !== 'windows' &&
Platform.OS !== 'macos',
gestureEnabled = Platform.OS === 'ios' &&
animationEnabled &&
index !== 0,
gestureEnabled = index !== 0 &&
Platform.OS === 'ios' &&
animationEnabled,
gestureDirection = defaultTransitionPreset.gestureDirection,
transitionSpec = defaultTransitionPreset.transitionSpec,
cardStyleInterpolator = animationEnabled === false
@@ -236,52 +243,16 @@ export default class CardStack extends React.Component<Props, State> {
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
cardOverlayEnabled = Platform.OS !== 'ios' ||
cardStyleInterpolator === forModalPresentationIOS,
} = options;
let transitionConfig = {
gestureDirection,
transitionSpec,
cardStyleInterpolator,
headerStyleInterpolator,
cardOverlayEnabled,
};
// When a screen is not the last, it should use next screen's transition config
// Many transitions also animate the previous screen, so using 2 different transitions doesn't look right
// For example combining a slide and a modal transition would look wrong otherwise
// With this approach, combining different transition styles in the same navigator mostly looks right
// This will still be broken when 2 transitions have different idle state (e.g. modal presentation),
// but majority of the transitions look alright
if (index !== self.length - 1) {
if (nextDescriptor) {
const {
animationEnabled,
gestureDirection = defaultTransitionPreset.gestureDirection,
transitionSpec = defaultTransitionPreset.transitionSpec,
cardStyleInterpolator = animationEnabled === false
? forNoAnimationCard
: defaultTransitionPreset.cardStyleInterpolator,
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
cardOverlayEnabled = descriptor.options.cardOverlayEnabled ??
cardStyleInterpolator === forModalPresentationIOS,
} = nextDescriptor.options;
transitionConfig = {
gestureDirection,
transitionSpec,
cardStyleInterpolator,
headerStyleInterpolator,
cardOverlayEnabled,
};
}
}
} = optionsForTransitionConfig;
const headerMode: StackHeaderMode =
options.headerMode ??
(options.animationPresentation !== 'modal' &&
transitionConfig.cardStyleInterpolator !== forModalPresentationIOS &&
descriptor.options.headerMode ??
(!(
optionsForTransitionConfig.presentation === 'modal' ||
cardStyleInterpolator === forModalPresentationIOS
) &&
Platform.OS === 'ios' &&
options.header === undefined
descriptor.options.header === undefined
? 'float'
: 'screen');
@@ -290,10 +261,14 @@ export default class CardStack extends React.Component<Props, State> {
descriptor: {
...descriptor,
options: {
...options,
...transitionConfig,
...descriptor.options,
animationEnabled,
cardOverlayEnabled,
cardStyleInterpolator,
gestureDirection,
gestureEnabled,
headerStyleInterpolator,
transitionSpec,
headerMode,
},
},
@@ -455,9 +430,6 @@ export default class CardStack extends React.Component<Props, State> {
isParentHeaderShown,
onTransitionStart,
onTransitionEnd,
onPageChangeStart,
onPageChangeConfirm,
onPageChangeCancel,
onGestureStart,
onGestureEnd,
onGestureCancel,
@@ -492,7 +464,7 @@ export default class CardStack extends React.Component<Props, State> {
const { options } = scenes[i].descriptor;
const {
// By default, we don't want to detach the previous screen of the active one for modals
detachPreviousScreen = options.animationPresentation === 'modal' ||
detachPreviousScreen = options.presentation === 'modal' ||
options.cardStyleInterpolator === forModalPresentationIOS
? i !== scenes.length - 1
: true,
@@ -628,9 +600,6 @@ export default class CardStack extends React.Component<Props, State> {
safeAreaInsetRight={safeAreaInsetRight}
safeAreaInsetBottom={safeAreaInsetBottom}
safeAreaInsetLeft={safeAreaInsetLeft}
onPageChangeStart={onPageChangeStart}
onPageChangeConfirm={onPageChangeConfirm}
onPageChangeCancel={onPageChangeCancel}
onGestureStart={onGestureStart}
onGestureCancel={onGestureCancel}
onGestureEnd={onGestureEnd}

View File

@@ -5,7 +5,6 @@ import {
EdgeInsets,
} from 'react-native-safe-area-context';
import {
NavigationHelpersContext,
StackActions,
StackNavigationState,
Route,
@@ -18,7 +17,6 @@ import {
import { GestureHandlerRootView } from '../GestureHandler';
import CardStack from './CardStack';
import KeyboardManager from '../KeyboardManager';
import HeaderContainer, {
Props as HeaderContainerProps,
} from '../Header/HeaderContainer';
@@ -418,8 +416,6 @@ export default class StackView extends React.Component<Props, State> {
render() {
const {
state,
navigation,
keyboardHandlingEnabled,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
descriptors: _,
...rest
@@ -433,45 +429,38 @@ export default class StackView extends React.Component<Props, State> {
} = this.state;
return (
<NavigationHelpersContext.Provider value={navigation}>
<GestureHandlerWrapper style={styles.container}>
<SafeAreaProviderCompat>
<SafeAreaInsetsContext.Consumer>
{(insets) => (
<KeyboardManager enabled={keyboardHandlingEnabled !== false}>
{(props) => (
<HeaderShownContext.Consumer>
{(isParentHeaderShown) => (
<CardStack
insets={insets as EdgeInsets}
isParentHeaderShown={isParentHeaderShown}
getPreviousRoute={this.getPreviousRoute}
routes={routes}
openingRouteKeys={openingRouteKeys}
closingRouteKeys={closingRouteKeys}
onOpenRoute={this.handleOpenRoute}
onCloseRoute={this.handleCloseRoute}
onTransitionStart={this.handleTransitionStart}
onTransitionEnd={this.handleTransitionEnd}
renderHeader={this.renderHeader}
renderScene={this.renderScene}
state={state}
descriptors={descriptors}
onGestureStart={this.handleGestureStart}
onGestureEnd={this.handleGestureEnd}
onGestureCancel={this.handleGestureCancel}
{...rest}
{...props}
/>
)}
</HeaderShownContext.Consumer>
)}
</KeyboardManager>
)}
</SafeAreaInsetsContext.Consumer>
</SafeAreaProviderCompat>
</GestureHandlerWrapper>
</NavigationHelpersContext.Provider>
<GestureHandlerWrapper style={styles.container}>
<SafeAreaProviderCompat>
<SafeAreaInsetsContext.Consumer>
{(insets) => (
<HeaderShownContext.Consumer>
{(isParentHeaderShown) => (
<CardStack
insets={insets as EdgeInsets}
isParentHeaderShown={isParentHeaderShown}
getPreviousRoute={this.getPreviousRoute}
routes={routes}
openingRouteKeys={openingRouteKeys}
closingRouteKeys={closingRouteKeys}
onOpenRoute={this.handleOpenRoute}
onCloseRoute={this.handleCloseRoute}
onTransitionStart={this.handleTransitionStart}
onTransitionEnd={this.handleTransitionEnd}
renderHeader={this.renderHeader}
renderScene={this.renderScene}
state={state}
descriptors={descriptors}
onGestureStart={this.handleGestureStart}
onGestureEnd={this.handleGestureEnd}
onGestureCancel={this.handleGestureCancel}
{...rest}
/>
)}
</HeaderShownContext.Consumer>
)}
</SafeAreaInsetsContext.Consumer>
</SafeAreaProviderCompat>
</GestureHandlerWrapper>
);
}
}

View File

@@ -3717,6 +3717,13 @@
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
"@types/mock-require@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/mock-require/-/mock-require-2.0.0.tgz#57a4f0db0b4b6274f610a2d2c20beb3c842181e1"
integrity sha512-nOgjoE5bBiDeiA+z41i95makyHUSMWQMOPocP+J67Pqx/68HAXaeWN1NFtrAYYV6LrISIZZ8vKHm/a50k0f6Sg==
dependencies:
"@types/node" "*"
"@types/node-fetch@^2.5.9":
version "2.5.9"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.9.tgz#c04a12115aa436f189e39579272b305e477621b4"
@@ -9069,6 +9076,11 @@ gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
get-caller-file@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
get-caller-file@^2.0.1, get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
@@ -12847,6 +12859,14 @@ mock-require-assets@^0.0.1:
resolved "https://registry.yarnpkg.com/mock-require-assets/-/mock-require-assets-0.0.1.tgz#94136f70e5b009c52c2df3b45724d15ab4f0cb98"
integrity sha1-lBNvcOWwCcUsLfO0VyTRWrTwy5g=
mock-require@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/mock-require/-/mock-require-3.0.3.tgz#ccd544d9eae81dd576b3f219f69ec867318a1946"
integrity sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==
dependencies:
get-caller-file "^1.0.2"
normalize-path "^2.1.1"
mockdate@^3.0.2:
version "3.0.5"
resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
@@ -15280,7 +15300,7 @@ react-native-web@~0.15.0:
prop-types "^15.6.0"
react-timer-mixin "^0.13.4"
"react-native@https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz", react-native@~0.63.2, react-native@~0.63.4:
"react-native@https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz", react-native@~0.63.4:
version "0.63.4"
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.63.4.tgz#2210fdd404c94a5fa6b423c6de86f8e48810ec36"
integrity sha512-I4kM8kYO2mWEYUFITMcpRulcy4/jd+j9T6PbIzR0FuMcz/xwd+JwHoLPa1HmCesvR1RDOw9o4D+OFLwuXXfmGw==
@@ -18225,10 +18245,10 @@ walker@^1.0.7, walker@~1.0.5:
dependencies:
makeerror "1.0.x"
warn-once@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/warn-once/-/warn-once-0.0.1.tgz#71eda54c88f240c4461e5c7a84cac2263caf3a4e"
integrity sha512-Sh/kR0dQ9Tlr70E2zuR8mZ0yxmN9kGMNfvlwWWRi7frSox2uRC7U659Le8jBIqvjykSbvo9JX9ttsqw4vZPLmA==
warn-once@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/warn-once/-/warn-once-0.1.0.tgz#4f58d89b84f968d0389176aa99e0cf0f14ffd4c8"
integrity sha512-recZTSvuaH/On5ZU5ywq66y99lImWqzP93+AiUo9LUwG8gXHW+LJjhOd6REJHm7qb0niYqrEQJvbHSQfuJtTqA==
watchpack-chokidar2@^2.0.1:
version "2.0.1"