mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-21 03:18:18 +08:00
Compare commits
23 Commits
@react-nav
...
@react-nav
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef094d512b | ||
|
|
9f00d60bdb | ||
|
|
2b58c52f70 | ||
|
|
e5238f6084 | ||
|
|
65b6a3d864 | ||
|
|
211f1f2c0e | ||
|
|
22b7c3f6c1 | ||
|
|
6ebe0824df | ||
|
|
82900cceff | ||
|
|
dc4ffc0171 | ||
|
|
9c30c42c0b | ||
|
|
ea8ea20127 | ||
|
|
2f282f1070 | ||
|
|
5165eb76aa | ||
|
|
7c722d2028 | ||
|
|
7f015130df | ||
|
|
7580efce89 | ||
|
|
1179d56c50 | ||
|
|
a6e498170f | ||
|
|
4af9d10298 | ||
|
|
08e74af545 | ||
|
|
1e05895b24 | ||
|
|
929c3e3a3b |
@@ -10,7 +10,7 @@ executors:
|
|||||||
|
|
||||||
playwright:
|
playwright:
|
||||||
docker:
|
docker:
|
||||||
- image: mcr.microsoft.com/playwright:bionic
|
- image: mcr.microsoft.com/playwright:focal
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: development
|
NODE_ENV: development
|
||||||
|
|
||||||
|
|||||||
@@ -4,42 +4,41 @@ beforeEach(async () => {
|
|||||||
await page.click('[data-testid=LinkComponent]');
|
await page.click('[data-testid=LinkComponent]');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('loads the article page', async () => {
|
const getPageInfo = async () => ({
|
||||||
expect(await page.evaluate(() => location.pathname + location.search)).toBe(
|
url: await page.evaluate(() => location.pathname + location.search),
|
||||||
'/link-component/article/gandalf'
|
title: await page.evaluate(() => document.title),
|
||||||
);
|
heading: (await page.accessibility.snapshot())?.children?.find(
|
||||||
|
(it) => it.role === 'heading'
|
||||||
|
)?.name,
|
||||||
|
});
|
||||||
|
|
||||||
expect(
|
it('loads the article page', async () => {
|
||||||
((await page.accessibility.snapshot()) as any)?.children?.find(
|
const { url, title, heading } = await getPageInfo();
|
||||||
(it: any) => it.role === 'heading'
|
|
||||||
)?.name
|
expect(url).toBe('/link-component/article/gandalf');
|
||||||
).toBe('Article by 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 () => {
|
it('goes to the album page and goes back', async () => {
|
||||||
await page.click('[href="/link-component/music"]');
|
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(
|
expect(url).toBe('/link-component/music');
|
||||||
((await page.accessibility.snapshot()) as any)?.children?.find(
|
expect(title).toBe('Albums - React Navigation Example');
|
||||||
(it: any) => it.role === 'heading'
|
expect(heading).toBe('Albums');
|
||||||
)?.name
|
}
|
||||||
).toBe('Albums');
|
|
||||||
|
|
||||||
await page.click('[aria-label="Article by Gandalf, back"]');
|
await page.click('[aria-label="Article by Gandalf, back"]');
|
||||||
|
|
||||||
await page.waitForNavigation();
|
await page.waitForNavigation();
|
||||||
|
|
||||||
expect(await page.evaluate(() => location.pathname + location.search)).toBe(
|
{
|
||||||
'/link-component/article/gandalf'
|
const { url, title, heading } = await getPageInfo();
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
expect(url).toBe('/link-component/article/gandalf');
|
||||||
((await page.accessibility.snapshot()) as any)?.children?.find(
|
expect(title).toBe('Article by Gandalf - React Navigation Example');
|
||||||
(it: any) => it.role === 'heading'
|
expect(heading).toBe('Article by Gandalf');
|
||||||
)?.name
|
}
|
||||||
).toBe('Article by Gandalf');
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
"@types/cheerio": "^0.22.28",
|
"@types/cheerio": "^0.22.28",
|
||||||
"@types/jest-dev-server": "^4.2.0",
|
"@types/jest-dev-server": "^4.2.0",
|
||||||
"@types/koa": "^2.13.1",
|
"@types/koa": "^2.13.1",
|
||||||
|
"@types/mock-require": "^2.0.0",
|
||||||
"@types/node-fetch": "^2.5.9",
|
"@types/node-fetch": "^2.5.9",
|
||||||
"@types/react": "~16.9.35",
|
"@types/react": "~16.9.35",
|
||||||
"@types/react-dom": "~16.9.8",
|
"@types/react-dom": "~16.9.8",
|
||||||
@@ -54,10 +55,11 @@
|
|||||||
"expo-cli": "^4.4.4",
|
"expo-cli": "^4.4.4",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"jest-dev-server": "^4.4.0",
|
"jest-dev-server": "^4.4.0",
|
||||||
|
"mock-require": "^3.0.3",
|
||||||
"mock-require-assets": "^0.0.1",
|
"mock-require-assets": "^0.0.1",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.1",
|
||||||
"nodemon": "^2.0.6",
|
"nodemon": "^2.0.6",
|
||||||
"playwright": "^1.10.0",
|
"playwright": "^1.11.0",
|
||||||
"serve": "^11.3.0",
|
"serve": "^11.3.0",
|
||||||
"typescript": "~4.2.3"
|
"typescript": "~4.2.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'mock-require-assets';
|
import 'mock-require-assets';
|
||||||
|
|
||||||
|
import mock from 'mock-require';
|
||||||
import Module from 'module';
|
import Module from 'module';
|
||||||
|
|
||||||
// We need to make sure that .web.xx extensions are resolved before .xx
|
// 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;
|
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() {} }
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { ScrollView, StyleSheet } from 'react-native';
|
||||||
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
|
import { BlurView } from 'expo-blur';
|
||||||
import {
|
import {
|
||||||
getFocusedRouteNameFromRoute,
|
getFocusedRouteNameFromRoute,
|
||||||
ParamListBase,
|
ParamListBase,
|
||||||
NavigatorScreenParams,
|
NavigatorScreenParams,
|
||||||
} from '@react-navigation/native';
|
} from '@react-navigation/native';
|
||||||
import type { StackScreenProps } from '@react-navigation/stack';
|
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 { HeaderBackButton } from '@react-navigation/elements';
|
||||||
import Albums from '../Shared/Albums';
|
import Albums from '../Shared/Albums';
|
||||||
import Contacts from '../Shared/Contacts';
|
import Contacts from '../Shared/Contacts';
|
||||||
@@ -28,6 +33,16 @@ type BottomTabParams = {
|
|||||||
TabChat: undefined;
|
TabChat: undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AlbumsScreen = () => {
|
||||||
|
const tabBarHeight = useBottomTabBarHeight();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollView contentContainerStyle={{ paddingBottom: tabBarHeight }}>
|
||||||
|
<Albums scrollEnabled={false} />
|
||||||
|
</ScrollView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const BottomTabs = createBottomTabNavigator<BottomTabParams>();
|
const BottomTabs = createBottomTabNavigator<BottomTabParams>();
|
||||||
|
|
||||||
export default function BottomTabsScreen({
|
export default function BottomTabsScreen({
|
||||||
@@ -78,10 +93,18 @@ export default function BottomTabsScreen({
|
|||||||
/>
|
/>
|
||||||
<BottomTabs.Screen
|
<BottomTabs.Screen
|
||||||
name="TabAlbums"
|
name="TabAlbums"
|
||||||
component={Albums}
|
component={AlbumsScreen}
|
||||||
options={{
|
options={{
|
||||||
title: 'Albums',
|
title: 'Albums',
|
||||||
tabBarIcon: getTabBarIcon('image-album'),
|
tabBarIcon: getTabBarIcon('image-album'),
|
||||||
|
tabBarStyle: { position: 'absolute' },
|
||||||
|
tabBarBackground: () => (
|
||||||
|
<BlurView
|
||||||
|
tint="light"
|
||||||
|
intensity={100}
|
||||||
|
style={StyleSheet.absoluteFill}
|
||||||
|
/>
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</BottomTabs.Navigator>
|
</BottomTabs.Navigator>
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import type { ParamListBase } from '@react-navigation/native';
|
|||||||
import {
|
import {
|
||||||
createStackNavigator,
|
createStackNavigator,
|
||||||
StackScreenProps,
|
StackScreenProps,
|
||||||
TransitionPresets,
|
|
||||||
} from '@react-navigation/stack';
|
} from '@react-navigation/stack';
|
||||||
import Article from '../Shared/Article';
|
import Article from '../Shared/Article';
|
||||||
import Albums from '../Shared/Albums';
|
import Albums from '../Shared/Albums';
|
||||||
@@ -119,7 +118,7 @@ export default function MixedStackScreen({ navigation }: Props) {
|
|||||||
component={AlbumsScreen}
|
component={AlbumsScreen}
|
||||||
options={{
|
options={{
|
||||||
title: 'Albums',
|
title: 'Albums',
|
||||||
...TransitionPresets.ModalPresentationIOS,
|
presentation: 'modal',
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</MixedStack.Navigator>
|
</MixedStack.Navigator>
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export default function ModalStackScreen({ navigation }: Props) {
|
|||||||
}, [navigation]);
|
}, [navigation]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalStack.Navigator screenOptions={{ animationPresentation: 'modal' }}>
|
<ModalStack.Navigator screenOptions={{ presentation: 'modal' }}>
|
||||||
<ModalStack.Screen
|
<ModalStack.Screen
|
||||||
name="Article"
|
name="Article"
|
||||||
component={ArticleScreen}
|
component={ArticleScreen}
|
||||||
|
|||||||
@@ -84,9 +84,7 @@ export default function TransparentStackScreen({ navigation }: Props) {
|
|||||||
}, [navigation]);
|
}, [navigation]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TransparentStack.Navigator
|
<TransparentStack.Navigator screenOptions={{ presentation: 'modal' }}>
|
||||||
screenOptions={{ animationPresentation: 'modal' }}
|
|
||||||
>
|
|
||||||
<TransparentStack.Screen
|
<TransparentStack.Screen
|
||||||
name="Article"
|
name="Article"
|
||||||
component={ArticleScreen}
|
component={ArticleScreen}
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ export default function App() {
|
|||||||
return () => Dimensions.removeEventListener('change', onDimensionsChange);
|
return () => Dimensions.removeEventListener('change', onDimensionsChange);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const navigationRef = useNavigationContainerRef<RootStackParamList>();
|
const navigationRef = useNavigationContainerRef();
|
||||||
|
|
||||||
useReduxDevToolsExtension(navigationRef);
|
useReduxDevToolsExtension(navigationRef);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,46 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [6.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.7...@react-navigation/bottom-tabs@6.0.0-next.8) (2021-05-09)
|
# [6.0.0-next.8](https://github.com/react-navigation/react-navigation/compare/@react-navigation/bottom-tabs@6.0.0-next.7...@react-navigation/bottom-tabs@6.0.0-next.8) (2021-05-09)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
**Note:** Version bump only for package @react-navigation/bottom-tabs
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/bottom-tabs",
|
"name": "@react-navigation/bottom-tabs",
|
||||||
"description": "Bottom tab navigator following iOS design guidelines",
|
"description": "Bottom tab navigator following iOS design guidelines",
|
||||||
"version": "6.0.0-next.8",
|
"version": "6.0.0-next.11",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -36,12 +36,12 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/elements": "^1.0.0-next.7",
|
"@react-navigation/elements": "^1.0.0-next.10",
|
||||||
"color": "^3.1.3",
|
"color": "^3.1.3",
|
||||||
"warn-once": "^0.0.1"
|
"warn-once": "^0.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-navigation/native": "^6.0.0-next.5",
|
"@react-navigation/native": "^6.0.0-next.8",
|
||||||
"@testing-library/react-native": "^7.2.0",
|
"@testing-library/react-native": "^7.2.0",
|
||||||
"@types/color": "^3.0.1",
|
"@types/color": "^3.0.1",
|
||||||
"@types/react": "^16.9.53",
|
"@types/react": "^16.9.53",
|
||||||
|
|||||||
@@ -70,7 +70,12 @@ function BottomTabNavigator({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { state, descriptors, navigation } = useNavigationBuilder<
|
const {
|
||||||
|
state,
|
||||||
|
descriptors,
|
||||||
|
navigation,
|
||||||
|
NavigationContent,
|
||||||
|
} = useNavigationBuilder<
|
||||||
TabNavigationState<ParamListBase>,
|
TabNavigationState<ParamListBase>,
|
||||||
TabRouterOptions,
|
TabRouterOptions,
|
||||||
TabActionHelpers<ParamListBase>,
|
TabActionHelpers<ParamListBase>,
|
||||||
@@ -85,13 +90,15 @@ function BottomTabNavigator({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BottomTabView
|
<NavigationContent>
|
||||||
{...rest}
|
<BottomTabView
|
||||||
state={state}
|
{...rest}
|
||||||
navigation={navigation}
|
state={state}
|
||||||
descriptors={descriptors}
|
navigation={navigation}
|
||||||
sceneContainerStyle={sceneContainerStyle}
|
descriptors={descriptors}
|
||||||
/>
|
sceneContainerStyle={sceneContainerStyle}
|
||||||
|
/>
|
||||||
|
</NavigationContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -229,6 +229,15 @@ export type BottomTabNavigationOptions = HeaderOptions & {
|
|||||||
*/
|
*/
|
||||||
tabBarStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
|
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.
|
* Whether this screen should be unmounted when navigating away from it.
|
||||||
* Defaults to `false`.
|
* Defaults to `false`.
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ export default function BottomTabBar({
|
|||||||
tabBarHideOnKeyboard = false,
|
tabBarHideOnKeyboard = false,
|
||||||
tabBarVisibilityAnimationConfig,
|
tabBarVisibilityAnimationConfig,
|
||||||
tabBarStyle,
|
tabBarStyle,
|
||||||
|
tabBarBackground,
|
||||||
} = focusedOptions;
|
} = focusedOptions;
|
||||||
|
|
||||||
const dimensions = useSafeAreaFrame();
|
const dimensions = useSafeAreaFrame();
|
||||||
@@ -211,15 +212,7 @@ export default function BottomTabBar({
|
|||||||
const handleLayout = (e: LayoutChangeEvent) => {
|
const handleLayout = (e: LayoutChangeEvent) => {
|
||||||
const { height, width } = e.nativeEvent.layout;
|
const { height, width } = e.nativeEvent.layout;
|
||||||
|
|
||||||
const topBorderWidth =
|
onHeightChange?.(height);
|
||||||
// @ts-ignore
|
|
||||||
StyleSheet.flatten([styles.tabBar, tabBarStyle])?.borderTopWidth;
|
|
||||||
|
|
||||||
onHeightChange?.(
|
|
||||||
height +
|
|
||||||
paddingBottom +
|
|
||||||
(typeof topBorderWidth === 'number' ? topBorderWidth : 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
setLayout((layout) => {
|
setLayout((layout) => {
|
||||||
if (height === layout.height && width === layout.width) {
|
if (height === layout.height && width === layout.width) {
|
||||||
@@ -252,12 +245,15 @@ export default function BottomTabBar({
|
|||||||
layout,
|
layout,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const tabBarBackgroundElement = tabBarBackground?.();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animated.View
|
<Animated.View
|
||||||
style={[
|
style={[
|
||||||
styles.tabBar,
|
styles.tabBar,
|
||||||
{
|
{
|
||||||
backgroundColor: colors.card,
|
backgroundColor:
|
||||||
|
tabBarBackgroundElement != null ? 'transparent' : colors.card,
|
||||||
borderTopColor: colors.border,
|
borderTopColor: colors.border,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -286,6 +282,9 @@ export default function BottomTabBar({
|
|||||||
pointerEvents={isTabBarHidden ? 'none' : 'auto'}
|
pointerEvents={isTabBarHidden ? 'none' : 'auto'}
|
||||||
onLayout={handleLayout}
|
onLayout={handleLayout}
|
||||||
>
|
>
|
||||||
|
<View pointerEvents="none" style={StyleSheet.absoluteFill}>
|
||||||
|
{tabBarBackgroundElement}
|
||||||
|
</View>
|
||||||
<View accessibilityRole="tablist" style={styles.content}>
|
<View accessibilityRole="tablist" style={styles.content}>
|
||||||
{routes.map((route, index) => {
|
{routes.map((route, index) => {
|
||||||
const focused = index === state.index;
|
const focused = index === state.index;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { StyleSheet, Platform } from 'react-native';
|
import { StyleSheet, Platform } from 'react-native';
|
||||||
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
|
import { SafeAreaInsetsContext } from 'react-native-safe-area-context';
|
||||||
import {
|
import type {
|
||||||
NavigationHelpersContext,
|
|
||||||
ParamListBase,
|
ParamListBase,
|
||||||
TabNavigationState,
|
TabNavigationState,
|
||||||
} from '@react-navigation/native';
|
} from '@react-navigation/native';
|
||||||
@@ -89,72 +88,70 @@ export default function BottomTabView(props: Props) {
|
|||||||
const { routes } = state;
|
const { routes } = state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationHelpersContext.Provider value={navigation}>
|
<SafeAreaProviderCompat>
|
||||||
<SafeAreaProviderCompat>
|
<MaybeScreenContainer
|
||||||
<MaybeScreenContainer
|
enabled={detachInactiveScreens}
|
||||||
enabled={detachInactiveScreens}
|
style={styles.container}
|
||||||
style={styles.container}
|
>
|
||||||
>
|
{routes.map((route, index) => {
|
||||||
{routes.map((route, index) => {
|
const descriptor = descriptors[route.key];
|
||||||
const descriptor = descriptors[route.key];
|
const { lazy = true, unmountOnBlur } = descriptor.options;
|
||||||
const { lazy = true, unmountOnBlur } = descriptor.options;
|
const isFocused = state.index === index;
|
||||||
const isFocused = state.index === index;
|
|
||||||
|
|
||||||
if (unmountOnBlur && !isFocused) {
|
if (unmountOnBlur && !isFocused) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lazy && !loaded.includes(route.key) && !isFocused) {
|
if (lazy && !loaded.includes(route.key) && !isFocused) {
|
||||||
// Don't render a lazy screen if we've never navigated to it
|
// Don't render a lazy screen if we've never navigated to it
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
header = ({ layout, options }: BottomTabHeaderProps) => (
|
header = ({ layout, options }: BottomTabHeaderProps) => (
|
||||||
<Header
|
<Header
|
||||||
{...options}
|
{...options}
|
||||||
layout={layout}
|
layout={layout}
|
||||||
title={getHeaderTitle(options, route.name)}
|
title={getHeaderTitle(options, route.name)}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
} = descriptor.options;
|
} = descriptor.options;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MaybeScreen
|
<MaybeScreen
|
||||||
key={route.key}
|
key={route.key}
|
||||||
style={StyleSheet.absoluteFill}
|
style={StyleSheet.absoluteFill}
|
||||||
visible={isFocused}
|
visible={isFocused}
|
||||||
enabled={detachInactiveScreens}
|
enabled={detachInactiveScreens}
|
||||||
>
|
>
|
||||||
<BottomTabBarHeightContext.Provider value={tabBarHeight}>
|
<BottomTabBarHeightContext.Provider value={tabBarHeight}>
|
||||||
<Screen
|
<Screen
|
||||||
focused={isFocused}
|
focused={isFocused}
|
||||||
route={descriptor.route}
|
route={descriptor.route}
|
||||||
navigation={descriptor.navigation}
|
navigation={descriptor.navigation}
|
||||||
headerShown={descriptor.options.headerShown}
|
headerShown={descriptor.options.headerShown}
|
||||||
headerStatusBarHeight={
|
headerStatusBarHeight={
|
||||||
descriptor.options.headerStatusBarHeight
|
descriptor.options.headerStatusBarHeight
|
||||||
}
|
}
|
||||||
header={header({
|
header={header({
|
||||||
layout: dimensions,
|
layout: dimensions,
|
||||||
route: descriptor.route,
|
route: descriptor.route,
|
||||||
navigation: descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
|
navigation: descriptor.navigation as BottomTabNavigationProp<ParamListBase>,
|
||||||
options: descriptor.options,
|
options: descriptor.options,
|
||||||
})}
|
})}
|
||||||
style={sceneContainerStyle}
|
style={sceneContainerStyle}
|
||||||
>
|
>
|
||||||
{descriptor.render()}
|
{descriptor.render()}
|
||||||
</Screen>
|
</Screen>
|
||||||
</BottomTabBarHeightContext.Provider>
|
</BottomTabBarHeightContext.Provider>
|
||||||
</MaybeScreen>
|
</MaybeScreen>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</MaybeScreenContainer>
|
</MaybeScreenContainer>
|
||||||
<BottomTabBarHeightCallbackContext.Provider value={setTabBarHeight}>
|
<BottomTabBarHeightCallbackContext.Provider value={setTabBarHeight}>
|
||||||
{renderTabBar()}
|
{renderTabBar()}
|
||||||
</BottomTabBarHeightCallbackContext.Provider>
|
</BottomTabBarHeightCallbackContext.Provider>
|
||||||
</SafeAreaProviderCompat>
|
</SafeAreaProviderCompat>
|
||||||
</NavigationHelpersContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,39 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix type annotations for useNavigation (again) ([929c3e3](https://github.com/react-navigation/react-navigation/commit/929c3e3a3b3eb32d197ef1f887dc4cbdce48eaff))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [6.0.0-next.5](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.4...@react-navigation/core@6.0.0-next.5) (2021-05-09)
|
# [6.0.0-next.5](https://github.com/react-navigation/react-navigation/compare/@react-navigation/core@6.0.0-next.4...@react-navigation/core@6.0.0-next.5) (2021-05-09)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/core",
|
"name": "@react-navigation/core",
|
||||||
"description": "Core utilities for building navigators",
|
"description": "Core utilities for building navigators",
|
||||||
"version": "6.0.0-next.5",
|
"version": "6.0.0-next.8",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
"react-native",
|
"react-native",
|
||||||
|
|||||||
30
packages/core/src/useComponent.tsx
Normal file
30
packages/core/src/useComponent.tsx
Normal 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;
|
||||||
|
}
|
||||||
@@ -8,9 +8,7 @@ import type { NavigationProp } from './types';
|
|||||||
* @returns Navigation prop of the parent screen.
|
* @returns Navigation prop of the parent screen.
|
||||||
*/
|
*/
|
||||||
export default function useNavigation<
|
export default function useNavigation<
|
||||||
T extends
|
T = NavigationProp<ReactNavigation.RootParamList>
|
||||||
| NavigationProp<{}>
|
|
||||||
| NavigationProp<any> = NavigationProp<ReactNavigation.RootParamList>
|
|
||||||
>(): T {
|
>(): T {
|
||||||
const navigation = React.useContext(NavigationContext);
|
const navigation = React.useContext(NavigationContext);
|
||||||
|
|
||||||
@@ -20,5 +18,6 @@ export default function useNavigation<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return navigation as T;
|
// FIXME: Figure out a better way to do this
|
||||||
|
return (navigation as unknown) as T;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
} from '@react-navigation/routers';
|
} from '@react-navigation/routers';
|
||||||
import NavigationStateContext from './NavigationStateContext';
|
import NavigationStateContext from './NavigationStateContext';
|
||||||
import NavigationRouteContext from './NavigationRouteContext';
|
import NavigationRouteContext from './NavigationRouteContext';
|
||||||
|
import NavigationHelpersContext from './NavigationHelpersContext';
|
||||||
import Group from './Group';
|
import Group from './Group';
|
||||||
import Screen from './Screen';
|
import Screen from './Screen';
|
||||||
import useEventEmitter from './useEventEmitter';
|
import useEventEmitter from './useEventEmitter';
|
||||||
@@ -29,6 +30,7 @@ import useKeyedChildListeners from './useKeyedChildListeners';
|
|||||||
import useOnGetState from './useOnGetState';
|
import useOnGetState from './useOnGetState';
|
||||||
import useScheduleUpdate from './useScheduleUpdate';
|
import useScheduleUpdate from './useScheduleUpdate';
|
||||||
import useCurrentRender from './useCurrentRender';
|
import useCurrentRender from './useCurrentRender';
|
||||||
|
import useComponent from './useComponent';
|
||||||
import isArrayEqual from './isArrayEqual';
|
import isArrayEqual from './isArrayEqual';
|
||||||
import {
|
import {
|
||||||
DefaultNavigatorOptions,
|
DefaultNavigatorOptions,
|
||||||
@@ -586,9 +588,14 @@ export default function useNavigationBuilder<
|
|||||||
descriptors,
|
descriptors,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const NavigationContent = useComponent(NavigationHelpersContext.Provider, {
|
||||||
|
value: navigation,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state,
|
state,
|
||||||
navigation,
|
navigation,
|
||||||
descriptors,
|
descriptors,
|
||||||
|
NavigationContent,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import type { ParamListBase } from '@react-navigation/routers';
|
|
||||||
import createNavigationContainerRef from './createNavigationContainerRef';
|
import createNavigationContainerRef from './createNavigationContainerRef';
|
||||||
import type { NavigationContainerRefWithCurrent } from './types';
|
import type { NavigationContainerRefWithCurrent } from './types';
|
||||||
|
|
||||||
export default function useNavigationContainerRef<
|
export default function useNavigationContainerRef<
|
||||||
ParamList extends ParamListBase
|
ParamList extends {} = ReactNavigation.RootParamList
|
||||||
>(): NavigationContainerRefWithCurrent<ParamList> {
|
>(): NavigationContainerRefWithCurrent<ParamList> {
|
||||||
const navigation = React.useRef<NavigationContainerRefWithCurrent<ParamList> | null>(
|
const navigation = React.useRef<NavigationContainerRefWithCurrent<ParamList> | null>(
|
||||||
null
|
null
|
||||||
|
|||||||
@@ -3,6 +3,33 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [6.0.0-next.5](https://github.com/react-navigation/react-navigation/compare/@react-navigation/devtools@6.0.0-next.4...@react-navigation/devtools@6.0.0-next.5) (2021-05-09)
|
# [6.0.0-next.5](https://github.com/react-navigation/react-navigation/compare/@react-navigation/devtools@6.0.0-next.4...@react-navigation/devtools@6.0.0-next.5) (2021-05-09)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/devtools
|
**Note:** Version bump only for package @react-navigation/devtools
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/devtools",
|
"name": "@react-navigation/devtools",
|
||||||
"description": "Developer tools for React Navigation",
|
"description": "Developer tools for React Navigation",
|
||||||
"version": "6.0.0-next.5",
|
"version": "6.0.0-next.8",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react",
|
"react",
|
||||||
"react-native",
|
"react-native",
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/core": "^6.0.0-next.5",
|
"@react-navigation/core": "^6.0.0-next.8",
|
||||||
"deep-equal": "^2.0.5"
|
"deep-equal": "^2.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import type {
|
|||||||
NavigationContainerRef,
|
NavigationContainerRef,
|
||||||
NavigationState,
|
NavigationState,
|
||||||
NavigationAction,
|
NavigationAction,
|
||||||
ParamListBase,
|
|
||||||
} from '@react-navigation/core';
|
} from '@react-navigation/core';
|
||||||
import deepEqual from 'deep-equal';
|
import deepEqual from 'deep-equal';
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ type DevToolsExtension = {
|
|||||||
declare const __REDUX_DEVTOOLS_EXTENSION__: DevToolsExtension | undefined;
|
declare const __REDUX_DEVTOOLS_EXTENSION__: DevToolsExtension | undefined;
|
||||||
|
|
||||||
export default function useReduxDevToolsExtension(
|
export default function useReduxDevToolsExtension(
|
||||||
ref: React.RefObject<NavigationContainerRef<ParamListBase>>
|
ref: React.RefObject<NavigationContainerRef<any>>
|
||||||
) {
|
) {
|
||||||
const devToolsRef = React.useRef<DevToolsConnection>();
|
const devToolsRef = React.useRef<DevToolsConnection>();
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,41 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [6.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/drawer@6.0.0-next.6...@react-navigation/drawer@6.0.0-next.7) (2021-05-09)
|
# [6.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/drawer@6.0.0-next.6...@react-navigation/drawer@6.0.0-next.7) (2021-05-09)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/drawer
|
**Note:** Version bump only for package @react-navigation/drawer
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/drawer",
|
"name": "@react-navigation/drawer",
|
||||||
"description": "Drawer navigator component with animated transitions and gesturess",
|
"description": "Drawer navigator component with animated transitions and gesturess",
|
||||||
"version": "6.0.0-next.7",
|
"version": "6.0.0-next.10",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -41,12 +41,12 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/elements": "^1.0.0-next.7",
|
"@react-navigation/elements": "^1.0.0-next.10",
|
||||||
"color": "^3.1.3",
|
"color": "^3.1.3",
|
||||||
"warn-once": "^0.0.1"
|
"warn-once": "^0.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-navigation/native": "^6.0.0-next.5",
|
"@react-navigation/native": "^6.0.0-next.8",
|
||||||
"@testing-library/react-native": "^7.2.0",
|
"@testing-library/react-native": "^7.2.0",
|
||||||
"@types/react": "^16.9.53",
|
"@types/react": "^16.9.53",
|
||||||
"@types/react-native": "~0.64.4",
|
"@types/react-native": "~0.64.4",
|
||||||
|
|||||||
@@ -67,7 +67,12 @@ function DrawerNavigator({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { state, descriptors, navigation } = useNavigationBuilder<
|
const {
|
||||||
|
state,
|
||||||
|
descriptors,
|
||||||
|
navigation,
|
||||||
|
NavigationContent,
|
||||||
|
} = useNavigationBuilder<
|
||||||
DrawerNavigationState<ParamListBase>,
|
DrawerNavigationState<ParamListBase>,
|
||||||
DrawerRouterOptions,
|
DrawerRouterOptions,
|
||||||
DrawerActionHelpers<ParamListBase>,
|
DrawerActionHelpers<ParamListBase>,
|
||||||
@@ -83,12 +88,14 @@ function DrawerNavigator({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DrawerView
|
<NavigationContent>
|
||||||
{...rest}
|
<DrawerView
|
||||||
state={state}
|
{...rest}
|
||||||
descriptors={descriptors}
|
state={state}
|
||||||
navigation={navigation}
|
descriptors={descriptors}
|
||||||
/>
|
navigation={navigation}
|
||||||
|
/>
|
||||||
|
</NavigationContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import * as React from 'react';
|
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 { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
import DrawerPositionContext from '../utils/DrawerPositionContext';
|
import DrawerPositionContext from '../utils/DrawerPositionContext';
|
||||||
|
|
||||||
@@ -16,14 +21,18 @@ export default function DrawerContentScrollView({
|
|||||||
const drawerPosition = React.useContext(DrawerPositionContext);
|
const drawerPosition = React.useContext(DrawerPositionContext);
|
||||||
const insets = useSafeAreaInsets();
|
const insets = useSafeAreaInsets();
|
||||||
|
|
||||||
|
const isRight = I18nManager.isRTL
|
||||||
|
? drawerPosition === 'left'
|
||||||
|
: drawerPosition === 'right';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView
|
<ScrollView
|
||||||
{...rest}
|
{...rest}
|
||||||
contentContainerStyle={[
|
contentContainerStyle={[
|
||||||
{
|
{
|
||||||
paddingTop: insets.top + 4,
|
paddingTop: insets.top + 4,
|
||||||
paddingLeft: drawerPosition === 'left' ? insets.left : 0,
|
paddingStart: !isRight ? insets.left : 0,
|
||||||
paddingRight: drawerPosition === 'right' ? insets.right : 0,
|
paddingEnd: isRight ? insets.right : 0,
|
||||||
},
|
},
|
||||||
contentContainerStyle,
|
contentContainerStyle,
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import {
|
|||||||
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
||||||
import Animated from 'react-native-reanimated';
|
import Animated from 'react-native-reanimated';
|
||||||
import {
|
import {
|
||||||
NavigationHelpersContext,
|
|
||||||
DrawerNavigationState,
|
DrawerNavigationState,
|
||||||
DrawerActions,
|
DrawerActions,
|
||||||
useTheme,
|
useTheme,
|
||||||
@@ -296,13 +295,11 @@ function DrawerViewBase({
|
|||||||
|
|
||||||
export default function DrawerView({ navigation, ...rest }: Props) {
|
export default function DrawerView({ navigation, ...rest }: Props) {
|
||||||
return (
|
return (
|
||||||
<NavigationHelpersContext.Provider value={navigation}>
|
<SafeAreaProviderCompat>
|
||||||
<SafeAreaProviderCompat>
|
<GestureHandlerWrapper style={styles.content}>
|
||||||
<GestureHandlerWrapper style={styles.content}>
|
<DrawerViewBase navigation={navigation} {...rest} />
|
||||||
<DrawerViewBase navigation={navigation} {...rest} />
|
</GestureHandlerWrapper>
|
||||||
</GestureHandlerWrapper>
|
</SafeAreaProviderCompat>
|
||||||
</SafeAreaProviderCompat>
|
|
||||||
</NavigationHelpersContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,33 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [1.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/elements@1.0.0-next.6...@react-navigation/elements@1.0.0-next.7) (2021-05-09)
|
# [1.0.0-next.7](https://github.com/react-navigation/react-navigation/compare/@react-navigation/elements@1.0.0-next.6...@react-navigation/elements@1.0.0-next.7) (2021-05-09)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/elements
|
**Note:** Version bump only for package @react-navigation/elements
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/elements",
|
"name": "@react-navigation/elements",
|
||||||
"description": "UI Components for React Navigation",
|
"description": "UI Components for React Navigation",
|
||||||
"version": "1.0.0-next.7",
|
"version": "1.0.0-next.10",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native",
|
"react-native",
|
||||||
"react-navigation",
|
"react-navigation",
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-masked-view/masked-view": "^0.2.3",
|
"@react-native-masked-view/masked-view": "^0.2.3",
|
||||||
"@react-navigation/native": "^6.0.0-next.5",
|
"@react-navigation/native": "^6.0.0-next.8",
|
||||||
"@testing-library/react-native": "^7.2.0",
|
"@testing-library/react-native": "^7.2.0",
|
||||||
"@types/react": "^16.9.53",
|
"@types/react": "^16.9.53",
|
||||||
"@types/react-native": "~0.64.4",
|
"@types/react-native": "~0.64.4",
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ export default function Header(props: Props) {
|
|||||||
style={[
|
style={[
|
||||||
styles.left,
|
styles.left,
|
||||||
headerTitleAlign === 'center' && styles.expand,
|
headerTitleAlign === 'center' && styles.expand,
|
||||||
{ marginLeft: insets.left },
|
{ marginStart: insets.left },
|
||||||
leftContainerStyle,
|
leftContainerStyle,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
@@ -236,7 +236,7 @@ export default function Header(props: Props) {
|
|||||||
style={[
|
style={[
|
||||||
styles.right,
|
styles.right,
|
||||||
styles.expand,
|
styles.expand,
|
||||||
{ marginRight: insets.right },
|
{ marginEnd: insets.right },
|
||||||
rightContainerStyle,
|
rightContainerStyle,
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -3,6 +3,33 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [6.0.0-next.5](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-bottom-tabs@6.0.0-next.4...@react-navigation/material-bottom-tabs@6.0.0-next.5) (2021-05-09)
|
# [6.0.0-next.5](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-bottom-tabs@6.0.0-next.4...@react-navigation/material-bottom-tabs@6.0.0-next.5) (2021-05-09)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
|
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/material-bottom-tabs",
|
"name": "@react-navigation/material-bottom-tabs",
|
||||||
"description": "Integration for bottom navigation component from react-native-paper",
|
"description": "Integration for bottom navigation component from react-native-paper",
|
||||||
"version": "6.0.0-next.5",
|
"version": "6.0.0-next.8",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-navigation/native": "^6.0.0-next.5",
|
"@react-navigation/native": "^6.0.0-next.8",
|
||||||
"@testing-library/react-native": "^7.2.0",
|
"@testing-library/react-native": "^7.2.0",
|
||||||
"@types/react": "^16.9.53",
|
"@types/react": "^16.9.53",
|
||||||
"@types/react-native": "~0.64.4",
|
"@types/react-native": "~0.64.4",
|
||||||
|
|||||||
@@ -28,7 +28,12 @@ function MaterialBottomTabNavigator({
|
|||||||
screenOptions,
|
screenOptions,
|
||||||
...rest
|
...rest
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const { state, descriptors, navigation } = useNavigationBuilder<
|
const {
|
||||||
|
state,
|
||||||
|
descriptors,
|
||||||
|
navigation,
|
||||||
|
NavigationContent,
|
||||||
|
} = useNavigationBuilder<
|
||||||
TabNavigationState<ParamListBase>,
|
TabNavigationState<ParamListBase>,
|
||||||
TabRouterOptions,
|
TabRouterOptions,
|
||||||
TabActionHelpers<ParamListBase>,
|
TabActionHelpers<ParamListBase>,
|
||||||
@@ -42,12 +47,14 @@ function MaterialBottomTabNavigator({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MaterialBottomTabView
|
<NavigationContent>
|
||||||
{...rest}
|
<MaterialBottomTabView
|
||||||
state={state}
|
{...rest}
|
||||||
navigation={navigation}
|
state={state}
|
||||||
descriptors={descriptors}
|
navigation={navigation}
|
||||||
/>
|
descriptors={descriptors}
|
||||||
|
/>
|
||||||
|
</NavigationContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import * as React from 'react';
|
|||||||
import { Text, StyleSheet, Platform } from 'react-native';
|
import { Text, StyleSheet, Platform } from 'react-native';
|
||||||
import { BottomNavigation, DefaultTheme, DarkTheme } from 'react-native-paper';
|
import { BottomNavigation, DefaultTheme, DarkTheme } from 'react-native-paper';
|
||||||
import {
|
import {
|
||||||
NavigationHelpersContext,
|
|
||||||
Route,
|
Route,
|
||||||
TabNavigationState,
|
TabNavigationState,
|
||||||
TabActions,
|
TabActions,
|
||||||
@@ -75,7 +74,7 @@ try {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function MaterialBottomTabViewInner({
|
export default function MaterialBottomTabView({
|
||||||
state,
|
state,
|
||||||
navigation,
|
navigation,
|
||||||
descriptors,
|
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({
|
const styles = StyleSheet.create({
|
||||||
icon: {
|
icon: {
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
|
|||||||
@@ -3,6 +3,38 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [6.0.0-next.6](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-top-tabs@6.0.0-next.5...@react-navigation/material-top-tabs@6.0.0-next.6) (2021-05-09)
|
# [6.0.0-next.6](https://github.com/react-navigation/react-navigation/compare/@react-navigation/material-top-tabs@6.0.0-next.5...@react-navigation/material-top-tabs@6.0.0-next.6) (2021-05-09)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/material-top-tabs
|
**Note:** Version bump only for package @react-navigation/material-top-tabs
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/material-top-tabs",
|
"name": "@react-navigation/material-top-tabs",
|
||||||
"description": "Integration for the animated tab view component from react-native-tab-view",
|
"description": "Integration for the animated tab view component from react-native-tab-view",
|
||||||
"version": "6.0.0-next.6",
|
"version": "6.0.0-next.9",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -42,10 +42,10 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color": "^3.1.3",
|
"color": "^3.1.3",
|
||||||
"warn-once": "^0.0.1"
|
"warn-once": "^0.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-navigation/native": "^6.0.0-next.5",
|
"@react-navigation/native": "^6.0.0-next.8",
|
||||||
"@testing-library/react-native": "^7.2.0",
|
"@testing-library/react-native": "^7.2.0",
|
||||||
"@types/react": "^16.9.53",
|
"@types/react": "^16.9.53",
|
||||||
"@types/react-native": "~0.64.4",
|
"@types/react-native": "~0.64.4",
|
||||||
|
|||||||
@@ -71,7 +71,12 @@ function MaterialTopTabNavigator({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { state, descriptors, navigation } = useNavigationBuilder<
|
const {
|
||||||
|
state,
|
||||||
|
descriptors,
|
||||||
|
navigation,
|
||||||
|
NavigationContent,
|
||||||
|
} = useNavigationBuilder<
|
||||||
TabNavigationState<ParamListBase>,
|
TabNavigationState<ParamListBase>,
|
||||||
TabRouterOptions,
|
TabRouterOptions,
|
||||||
TabActionHelpers<ParamListBase>,
|
TabActionHelpers<ParamListBase>,
|
||||||
@@ -85,12 +90,14 @@ function MaterialTopTabNavigator({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MaterialTopTabView
|
<NavigationContent>
|
||||||
{...rest}
|
<MaterialTopTabView
|
||||||
state={state}
|
{...rest}
|
||||||
navigation={navigation}
|
state={state}
|
||||||
descriptors={descriptors}
|
navigation={navigation}
|
||||||
/>
|
descriptors={descriptors}
|
||||||
|
/>
|
||||||
|
</NavigationContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { TabView, SceneRendererProps } from 'react-native-tab-view';
|
import { TabView, SceneRendererProps } from 'react-native-tab-view';
|
||||||
import {
|
import {
|
||||||
NavigationHelpersContext,
|
|
||||||
TabNavigationState,
|
TabNavigationState,
|
||||||
TabActions,
|
TabActions,
|
||||||
ParamListBase,
|
ParamListBase,
|
||||||
@@ -43,29 +42,27 @@ export default function MaterialTopTabView({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationHelpersContext.Provider value={navigation}>
|
<TabView<Route<string>>
|
||||||
<TabView<Route<string>>
|
{...rest}
|
||||||
{...rest}
|
onIndexChange={(index) =>
|
||||||
onIndexChange={(index) =>
|
navigation.dispatch({
|
||||||
navigation.dispatch({
|
...TabActions.jumpTo(state.routes[index].name),
|
||||||
...TabActions.jumpTo(state.routes[index].name),
|
target: state.key,
|
||||||
target: state.key,
|
})
|
||||||
})
|
}
|
||||||
}
|
renderScene={({ route }) => descriptors[route.key].render()}
|
||||||
renderScene={({ route }) => descriptors[route.key].render()}
|
navigationState={state}
|
||||||
navigationState={state}
|
renderTabBar={renderTabBar}
|
||||||
renderTabBar={renderTabBar}
|
renderLazyPlaceholder={({ route }) =>
|
||||||
renderLazyPlaceholder={({ route }) =>
|
descriptors[route.key].options.lazyPlaceholder?.() ?? null
|
||||||
descriptors[route.key].options.lazyPlaceholder?.() ?? null
|
}
|
||||||
}
|
lazy={({ route }) => descriptors[route.key].options.lazy === true}
|
||||||
lazy={({ route }) => descriptors[route.key].options.lazy === true}
|
onSwipeStart={() => navigation.emit({ type: 'swipeStart' })}
|
||||||
onSwipeStart={() => navigation.emit({ type: 'swipeStart' })}
|
onSwipeEnd={() => navigation.emit({ type: 'swipeEnd' })}
|
||||||
onSwipeEnd={() => navigation.emit({ type: 'swipeEnd' })}
|
sceneContainerStyle={[
|
||||||
sceneContainerStyle={[
|
{ backgroundColor: colors.background },
|
||||||
{ backgroundColor: colors.background },
|
sceneContainerStyle,
|
||||||
sceneContainerStyle,
|
]}
|
||||||
]}
|
/>
|
||||||
/>
|
|
||||||
</NavigationHelpersContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,36 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [6.0.0-next.5](https://github.com/react-navigation/react-navigation/compare/@react-navigation/native@6.0.0-next.4...@react-navigation/native@6.0.0-next.5) (2021-05-09)
|
# [6.0.0-next.5](https://github.com/react-navigation/react-navigation/compare/@react-navigation/native@6.0.0-next.4...@react-navigation/native@6.0.0-next.5) (2021-05-09)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/native
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/native",
|
"name": "@react-navigation/native",
|
||||||
"description": "React Native integration for React Navigation",
|
"description": "React Native integration for React Navigation",
|
||||||
"version": "6.0.0-next.5",
|
"version": "6.0.0-next.8",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native",
|
"react-native",
|
||||||
"react-navigation",
|
"react-navigation",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/core": "^6.0.0-next.5",
|
"@react-navigation/core": "^6.0.0-next.8",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"nanoid": "^3.1.22"
|
"nanoid": "^3.1.22"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import type { NavigationAction } from '@react-navigation/core';
|
|||||||
import useLinkProps from './useLinkProps';
|
import useLinkProps from './useLinkProps';
|
||||||
import type { To } from './useLinkTo';
|
import type { To } from './useLinkTo';
|
||||||
|
|
||||||
type Props = {
|
type Props<ParamList extends ReactNavigation.RootParamList> = {
|
||||||
to: To;
|
to: To<ParamList>;
|
||||||
action?: NavigationAction;
|
action?: NavigationAction;
|
||||||
target?: string;
|
target?: string;
|
||||||
onPress?: (
|
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.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.
|
* @param props.children Child elements to render the content.
|
||||||
*/
|
*/
|
||||||
export default function Link({ to, action, ...rest }: Props) {
|
export default function Link<ParamList extends ReactNavigation.RootParamList>({
|
||||||
const props = useLinkProps({ to, action });
|
to,
|
||||||
|
action,
|
||||||
|
...rest
|
||||||
|
}: Props<ParamList>) {
|
||||||
|
const props = useLinkProps<ParamList>({ to, action });
|
||||||
|
|
||||||
const onPress = (
|
const onPress = (
|
||||||
e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
|
e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
createNavigatorFactory,
|
createNavigatorFactory,
|
||||||
StackRouter,
|
StackRouter,
|
||||||
TabRouter,
|
TabRouter,
|
||||||
NavigationHelpersContext,
|
|
||||||
createNavigationContainerRef,
|
createNavigationContainerRef,
|
||||||
ParamListBase,
|
ParamListBase,
|
||||||
} from '@react-navigation/core';
|
} from '@react-navigation/core';
|
||||||
@@ -22,36 +21,36 @@ it('integrates with the history API', () => {
|
|||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
|
|
||||||
const createStackNavigator = createNavigatorFactory((props: any) => {
|
const createStackNavigator = createNavigatorFactory((props: any) => {
|
||||||
const { navigation, state, descriptors } = useNavigationBuilder(
|
const { state, descriptors, NavigationContent } = useNavigationBuilder(
|
||||||
StackRouter,
|
StackRouter,
|
||||||
props
|
props
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationHelpersContext.Provider value={navigation}>
|
<NavigationContent>
|
||||||
{state.routes.map((route, i) => (
|
{state.routes.map((route, i) => (
|
||||||
<div key={route.key} aria-current={state.index === i || undefined}>
|
<div key={route.key} aria-current={state.index === i || undefined}>
|
||||||
{descriptors[route.key].render()}
|
{descriptors[route.key].render()}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</NavigationHelpersContext.Provider>
|
</NavigationContent>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const createTabNavigator = createNavigatorFactory((props: any) => {
|
const createTabNavigator = createNavigatorFactory((props: any) => {
|
||||||
const { navigation, state, descriptors } = useNavigationBuilder(
|
const { state, descriptors, NavigationContent } = useNavigationBuilder(
|
||||||
TabRouter,
|
TabRouter,
|
||||||
props
|
props
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationHelpersContext.Provider value={navigation}>
|
<NavigationContent>
|
||||||
{state.routes.map((route, i) => (
|
{state.routes.map((route, i) => (
|
||||||
<div key={route.key} aria-current={state.index === i || undefined}>
|
<div key={route.key} aria-current={state.index === i || undefined}>
|
||||||
{descriptors[route.key].render()}
|
{descriptors[route.key].render()}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</NavigationHelpersContext.Provider>
|
</NavigationContent>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
createNavigatorFactory,
|
createNavigatorFactory,
|
||||||
StackRouter,
|
StackRouter,
|
||||||
TabRouter,
|
TabRouter,
|
||||||
NavigationHelpersContext,
|
|
||||||
NavigatorScreenParams,
|
NavigatorScreenParams,
|
||||||
} from '@react-navigation/core';
|
} from '@react-navigation/core';
|
||||||
import { renderToString } from 'react-dom/server';
|
import { renderToString } from 'react-dom/server';
|
||||||
@@ -23,17 +22,17 @@ jest.mock('../useLinking', () => require('../useLinking.tsx').default);
|
|||||||
|
|
||||||
it('renders correct state with location', () => {
|
it('renders correct state with location', () => {
|
||||||
const createStackNavigator = createNavigatorFactory((props: any) => {
|
const createStackNavigator = createNavigatorFactory((props: any) => {
|
||||||
const { navigation, state, descriptors } = useNavigationBuilder(
|
const { state, descriptors, NavigationContent } = useNavigationBuilder(
|
||||||
StackRouter,
|
StackRouter,
|
||||||
props
|
props
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationHelpersContext.Provider value={navigation}>
|
<NavigationContent>
|
||||||
{state.routes.map((route) => (
|
{state.routes.map((route) => (
|
||||||
<div key={route.key}>{descriptors[route.key].render()}</div>
|
<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', () => {
|
it('gets the current options', () => {
|
||||||
const createTabNavigator = createNavigatorFactory((props: any) => {
|
const createTabNavigator = createNavigatorFactory((props: any) => {
|
||||||
const { navigation, state, descriptors } = useNavigationBuilder(
|
const { state, descriptors, NavigationContent } = useNavigationBuilder(
|
||||||
TabRouter,
|
TabRouter,
|
||||||
props
|
props
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationHelpersContext.Provider value={navigation}>
|
<NavigationContent>
|
||||||
{state.routes.map((route) => (
|
{state.routes.map((route) => (
|
||||||
<div key={route.key}>{descriptors[route.key].render()}</div>
|
<div key={route.key}>{descriptors[route.key].render()}</div>
|
||||||
))}
|
))}
|
||||||
</NavigationHelpersContext.Provider>
|
</NavigationContent>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ export * from '@react-navigation/core';
|
|||||||
|
|
||||||
export { default as NavigationContainer } from './NavigationContainer';
|
export { default as NavigationContainer } from './NavigationContainer';
|
||||||
|
|
||||||
export { default as useBackButton } from './useBackButton';
|
|
||||||
export { default as useScrollToTop } from './useScrollToTop';
|
export { default as useScrollToTop } from './useScrollToTop';
|
||||||
|
|
||||||
export { default as DefaultTheme } from './theming/DefaultTheme';
|
export { default as DefaultTheme } from './theming/DefaultTheme';
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import {
|
|||||||
} from '@react-navigation/core';
|
} from '@react-navigation/core';
|
||||||
import useLinkTo, { To } from './useLinkTo';
|
import useLinkTo, { To } from './useLinkTo';
|
||||||
|
|
||||||
type Props = {
|
type Props<ParamList extends ReactNavigation.RootParamList> = {
|
||||||
to: To;
|
to: To<ParamList>;
|
||||||
action?: NavigationAction;
|
action?: NavigationAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -17,9 +17,11 @@ type Props = {
|
|||||||
* @param props.to Absolute path to screen (e.g. `/feeds/hot`).
|
* @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.
|
* @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 navigation = React.useContext(NavigationHelpersContext);
|
||||||
const linkTo = useLinkTo();
|
const linkTo = useLinkTo<ParamList>();
|
||||||
|
|
||||||
const onPress = (
|
const onPress = (
|
||||||
e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
|
e?: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
|
||||||
|
|||||||
@@ -21,12 +21,14 @@ export type To<
|
|||||||
params: ParamList[RouteName];
|
params: ParamList[RouteName];
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function useLinkTo() {
|
export default function useLinkTo<
|
||||||
|
ParamList extends ReactNavigation.RootParamList
|
||||||
|
>() {
|
||||||
const navigation = React.useContext(NavigationContext);
|
const navigation = React.useContext(NavigationContext);
|
||||||
const linking = React.useContext(LinkingContext);
|
const linking = React.useContext(LinkingContext);
|
||||||
|
|
||||||
const linkTo = React.useCallback(
|
const linkTo = React.useCallback(
|
||||||
(to: To) => {
|
(to: To<ParamList>) => {
|
||||||
if (navigation === undefined) {
|
if (navigation === undefined) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Couldn't find a navigation object. Is your component inside a screen in a navigator?"
|
"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') {
|
if (typeof to !== 'string') {
|
||||||
|
// @ts-expect-error: This is fine
|
||||||
root.navigate(to.screen, to.params);
|
root.navigate(to.screen, to.params);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,66 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
# [6.0.0-next.17](https://github.com/react-navigation/react-navigation/compare/@react-navigation/stack@6.0.0-next.16...@react-navigation/stack@6.0.0-next.17) (2021-05-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* don't allow overriding gestureEnabled on first screen ([9f00d60](https://github.com/react-navigation/react-navigation/commit/9f00d60bdb7d6f02996f4fa7dfc09b890ebe22f9))
|
||||||
|
* fix broken animation on first screen ([e5238f6](https://github.com/react-navigation/react-navigation/commit/e5238f608472319165e5570f41144be5549e0df1))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [6.0.0-next.12](https://github.com/react-navigation/react-navigation/compare/@react-navigation/stack@6.0.0-next.11...@react-navigation/stack@6.0.0-next.12) (2021-05-09)
|
# [6.0.0-next.12](https://github.com/react-navigation/react-navigation/compare/@react-navigation/stack@6.0.0-next.11...@react-navigation/stack@6.0.0-next.12) (2021-05-09)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/stack
|
**Note:** Version bump only for package @react-navigation/stack
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/stack",
|
"name": "@react-navigation/stack",
|
||||||
"description": "Stack navigator component for iOS and Android with animated transitions and gestures",
|
"description": "Stack navigator component for iOS and Android with animated transitions and gestures",
|
||||||
"version": "6.0.0-next.12",
|
"version": "6.0.0-next.17",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"react-native-component",
|
"react-native-component",
|
||||||
"react-component",
|
"react-component",
|
||||||
@@ -40,13 +40,13 @@
|
|||||||
"clean": "del lib"
|
"clean": "del lib"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/elements": "^1.0.0-next.7",
|
"@react-navigation/elements": "^1.0.0-next.10",
|
||||||
"color": "^3.1.3",
|
"color": "^3.1.3",
|
||||||
"react-native-iphone-x-helper": "^1.3.0",
|
"react-native-iphone-x-helper": "^1.3.0",
|
||||||
"warn-once": "^0.0.1"
|
"warn-once": "^0.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-navigation/native": "^6.0.0-next.5",
|
"@react-navigation/native": "^6.0.0-next.8",
|
||||||
"@testing-library/react-native": "^7.2.0",
|
"@testing-library/react-native": "^7.2.0",
|
||||||
"@types/color": "^3.0.1",
|
"@types/color": "^3.0.1",
|
||||||
"@types/react": "^16.9.53",
|
"@types/react": "^16.9.53",
|
||||||
|
|||||||
@@ -30,20 +30,33 @@ function StackNavigator({
|
|||||||
screenOptions,
|
screenOptions,
|
||||||
...rest
|
...rest
|
||||||
}: Props) {
|
}: Props) {
|
||||||
|
// @ts-expect-error: mode is deprecated
|
||||||
|
const mode = rest.mode as 'card' | 'modal' | undefined;
|
||||||
|
|
||||||
// @ts-expect-error: headerMode='none' is deprecated
|
// @ts-expect-error: headerMode='none' is deprecated
|
||||||
const headerMode = rest.headerMode as StackHeaderMode | 'none' | undefined;
|
const headerMode = rest.headerMode as StackHeaderMode | 'none' | undefined;
|
||||||
|
|
||||||
|
warnOnce(
|
||||||
|
mode != null,
|
||||||
|
`Stack Navigator: 'mode="${mode}"' is deprecated. Use 'presentation: "${mode}"' in 'screenOptions' instead.`
|
||||||
|
);
|
||||||
|
|
||||||
warnOnce(
|
warnOnce(
|
||||||
headerMode === 'none',
|
headerMode === 'none',
|
||||||
`Stack Navigator: 'headerMode="none"' is deprecated. Use 'headerShown: false' in 'screenOptions' instead.`
|
`Stack Navigator: 'headerMode="none"' is deprecated. Use 'headerShown: false' in 'screenOptions' instead.`
|
||||||
);
|
);
|
||||||
|
|
||||||
warnOnce(
|
warnOnce(
|
||||||
headerMode && headerMode !== 'none',
|
headerMode != null && headerMode !== 'none',
|
||||||
`Stack Navigator: 'headerMode' is moved to 'options'. Moved it to 'screenOptions' to keep current behavior.`
|
`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>,
|
StackNavigationState<ParamListBase>,
|
||||||
StackRouterOptions,
|
StackRouterOptions,
|
||||||
StackActionHelpers<ParamListBase>,
|
StackActionHelpers<ParamListBase>,
|
||||||
@@ -54,6 +67,7 @@ function StackNavigator({
|
|||||||
children,
|
children,
|
||||||
screenOptions,
|
screenOptions,
|
||||||
defaultScreenOptions: () => ({
|
defaultScreenOptions: () => ({
|
||||||
|
presentation: mode,
|
||||||
headerShown: headerMode ? headerMode !== 'none' : true,
|
headerShown: headerMode ? headerMode !== 'none' : true,
|
||||||
headerMode: headerMode && headerMode !== 'none' ? headerMode : undefined,
|
headerMode: headerMode && headerMode !== 'none' ? headerMode : undefined,
|
||||||
}),
|
}),
|
||||||
@@ -85,12 +99,14 @@ function StackNavigator({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StackView
|
<NavigationContent>
|
||||||
{...rest}
|
<StackView
|
||||||
state={state}
|
{...rest}
|
||||||
descriptors={descriptors}
|
state={state}
|
||||||
navigation={navigation}
|
descriptors={descriptors}
|
||||||
/>
|
navigation={navigation}
|
||||||
|
/>
|
||||||
|
</NavigationContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,22 +246,25 @@ export type StackNavigationOptions = StackHeaderOptions &
|
|||||||
* so that the previous screen isn't transformed or invisible.
|
* so that the previous screen isn't transformed or invisible.
|
||||||
*/
|
*/
|
||||||
cardStyle?: StyleProp<ViewStyle>;
|
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.
|
* Whether transition animation should be enabled the screen.
|
||||||
* If you set it to `false`, the screen won't animate when pushing or popping.
|
* 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.
|
* Defaults to `true` on Android and iOS, `false` on Web.
|
||||||
*/
|
*/
|
||||||
animationEnabled?: boolean;
|
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`.
|
* 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.
|
* 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`.
|
* Defaults to `false` for the last screen for modals, otherwise `true`.
|
||||||
*/
|
*/
|
||||||
detachPreviousScreen?: boolean;
|
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 = {
|
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.
|
* 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.
|
* This will have no effect if you disable `react-native-screens`.
|
||||||
* Defaults to `true` on Android, depends on the version of `react-native-screens` on iOS.
|
*
|
||||||
|
* Defaults to `true`.
|
||||||
*/
|
*/
|
||||||
detachInactiveScreens?: boolean;
|
detachInactiveScreens?: boolean;
|
||||||
};
|
};
|
||||||
@@ -332,7 +336,7 @@ export type StackCardInterpolationProps = {
|
|||||||
progress: Animated.AnimatedInterpolation;
|
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.
|
* This can be `undefined` in case the screen animating is the last one.
|
||||||
*/
|
*/
|
||||||
next?: {
|
next?: {
|
||||||
@@ -411,7 +415,7 @@ export type StackHeaderInterpolationProps = {
|
|||||||
progress: Animated.AnimatedInterpolation;
|
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.
|
* This can be `undefined` in case the screen animating is the last one.
|
||||||
*/
|
*/
|
||||||
next?: {
|
next?: {
|
||||||
|
|||||||
105
packages/stack/src/utils/useKeyboardManager.tsx
Normal file
105
packages/stack/src/utils/useKeyboardManager.tsx
Normal 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,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,9 +11,11 @@ import type { Props as HeaderContainerProps } from '../Header/HeaderContainer';
|
|||||||
import Card from './Card';
|
import Card from './Card';
|
||||||
import { forModalPresentationIOS } from '../../TransitionConfigs/CardStyleInterpolators';
|
import { forModalPresentationIOS } from '../../TransitionConfigs/CardStyleInterpolators';
|
||||||
import ModalPresentationContext from '../../utils/ModalPresentationContext';
|
import ModalPresentationContext from '../../utils/ModalPresentationContext';
|
||||||
|
import useKeyboardManager from '../../utils/useKeyboardManager';
|
||||||
import type { Layout, Scene } from '../../types';
|
import type { Layout, Scene } from '../../types';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
index: number;
|
||||||
interpolationIndex: number;
|
interpolationIndex: number;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
focused: boolean;
|
focused: boolean;
|
||||||
@@ -37,9 +39,6 @@ type Props = {
|
|||||||
closing: boolean
|
closing: boolean
|
||||||
) => void;
|
) => void;
|
||||||
onTransitionEnd?: (props: { route: Route<string> }, 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;
|
onGestureStart?: (props: { route: Route<string> }) => void;
|
||||||
onGestureEnd?: (props: { route: Route<string> }) => void;
|
onGestureEnd?: (props: { route: Route<string> }) => void;
|
||||||
onGestureCancel?: (props: { route: Route<string> }) => void;
|
onGestureCancel?: (props: { route: Route<string> }) => void;
|
||||||
@@ -55,6 +54,7 @@ type Props = {
|
|||||||
const EPSILON = 0.1;
|
const EPSILON = 0.1;
|
||||||
|
|
||||||
function CardContainer({
|
function CardContainer({
|
||||||
|
index,
|
||||||
active,
|
active,
|
||||||
closing,
|
closing,
|
||||||
gesture,
|
gesture,
|
||||||
@@ -70,9 +70,6 @@ function CardContainer({
|
|||||||
layout,
|
layout,
|
||||||
onCloseRoute,
|
onCloseRoute,
|
||||||
onOpenRoute,
|
onOpenRoute,
|
||||||
onPageChangeCancel,
|
|
||||||
onPageChangeConfirm,
|
|
||||||
onPageChangeStart,
|
|
||||||
onGestureCancel,
|
onGestureCancel,
|
||||||
onGestureEnd,
|
onGestureEnd,
|
||||||
onGestureStart,
|
onGestureStart,
|
||||||
@@ -88,6 +85,20 @@ function CardContainer({
|
|||||||
}: Props) {
|
}: Props) {
|
||||||
const parentHeaderHeight = React.useContext(HeaderHeightContext);
|
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 handleOpen = () => {
|
||||||
const { route } = scene.descriptor;
|
const { route } = scene.descriptor;
|
||||||
|
|
||||||
@@ -170,7 +181,9 @@ function CardContainer({
|
|||||||
}, [pointerEvents, scene.progress.next]);
|
}, [pointerEvents, scene.progress.next]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
animationPresentation,
|
presentation,
|
||||||
|
detachPreviousScreen,
|
||||||
|
animationEnabled,
|
||||||
cardOverlay,
|
cardOverlay,
|
||||||
cardOverlayEnabled,
|
cardOverlayEnabled,
|
||||||
cardShadowEnabled,
|
cardShadowEnabled,
|
||||||
@@ -220,7 +233,7 @@ function CardContainer({
|
|||||||
onGestureBegin={handleGestureBegin}
|
onGestureBegin={handleGestureBegin}
|
||||||
onGestureCanceled={handleGestureCanceled}
|
onGestureCanceled={handleGestureCanceled}
|
||||||
onGestureEnd={handleGestureEnd}
|
onGestureEnd={handleGestureEnd}
|
||||||
gestureEnabled={gestureEnabled}
|
gestureEnabled={index === 0 ? false : gestureEnabled}
|
||||||
gestureResponseDistance={gestureResponseDistance}
|
gestureResponseDistance={gestureResponseDistance}
|
||||||
gestureVelocityImpact={gestureVelocityImpact}
|
gestureVelocityImpact={gestureVelocityImpact}
|
||||||
transitionSpec={transitionSpec}
|
transitionSpec={transitionSpec}
|
||||||
@@ -228,9 +241,7 @@ function CardContainer({
|
|||||||
accessibilityElementsHidden={!focused}
|
accessibilityElementsHidden={!focused}
|
||||||
importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'}
|
importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'}
|
||||||
pointerEvents={active ? 'box-none' : pointerEvents}
|
pointerEvents={active ? 'box-none' : pointerEvents}
|
||||||
pageOverflowEnabled={
|
pageOverflowEnabled={headerMode !== 'float' && presentation !== 'modal'}
|
||||||
headerMode !== 'float' && animationPresentation !== 'modal'
|
|
||||||
}
|
|
||||||
headerDarkContent={headerDarkContent}
|
headerDarkContent={headerDarkContent}
|
||||||
containerStyle={
|
containerStyle={
|
||||||
hasAbsoluteFloatHeader && headerMode !== 'screen'
|
hasAbsoluteFloatHeader && headerMode !== 'screen'
|
||||||
@@ -243,6 +254,15 @@ function CardContainer({
|
|||||||
// This is necessary to avoid unfocused larger pages increasing scroll area
|
// 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
|
// The issue can be seen on the web when a smaller screen is pushed over a larger one
|
||||||
overflow: active ? undefined : 'hidden',
|
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,
|
StyleSheet.absoluteFill,
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -63,9 +63,6 @@ type Props = {
|
|||||||
closing: boolean
|
closing: boolean
|
||||||
) => void;
|
) => void;
|
||||||
onTransitionEnd: (props: { route: Route<string> }, 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;
|
onGestureStart?: (props: { route: Route<string> }) => void;
|
||||||
onGestureEnd?: (props: { route: Route<string> }) => void;
|
onGestureEnd?: (props: { route: Route<string> }) => void;
|
||||||
onGestureCancel?: (props: { route: Route<string> }) => void;
|
onGestureCancel?: (props: { route: Route<string> }) => void;
|
||||||
@@ -122,8 +119,8 @@ const getDistanceFromOptions = (
|
|||||||
descriptor?: StackDescriptor
|
descriptor?: StackDescriptor
|
||||||
) => {
|
) => {
|
||||||
const {
|
const {
|
||||||
animationPresentation,
|
presentation,
|
||||||
gestureDirection = animationPresentation === 'modal'
|
gestureDirection = presentation === 'modal'
|
||||||
? ModalTransition.gestureDirection
|
? ModalTransition.gestureDirection
|
||||||
: DefaultTransition.gestureDirection,
|
: DefaultTransition.gestureDirection,
|
||||||
} = (descriptor?.options || {}) as StackNavigationOptions;
|
} = (descriptor?.options || {}) as StackNavigationOptions;
|
||||||
@@ -214,10 +211,19 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
props.descriptors[previousRoute?.key] ||
|
props.descriptors[previousRoute?.key] ||
|
||||||
state.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 =
|
let defaultTransitionPreset =
|
||||||
options.animationPresentation === 'modal'
|
optionsForTransitionConfig.presentation === 'modal'
|
||||||
? ModalTransition
|
? ModalTransition
|
||||||
: DefaultTransition;
|
: DefaultTransition;
|
||||||
|
|
||||||
@@ -225,9 +231,7 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
animationEnabled = Platform.OS !== 'web' &&
|
animationEnabled = Platform.OS !== 'web' &&
|
||||||
Platform.OS !== 'windows' &&
|
Platform.OS !== 'windows' &&
|
||||||
Platform.OS !== 'macos',
|
Platform.OS !== 'macos',
|
||||||
gestureEnabled = Platform.OS === 'ios' &&
|
gestureEnabled = Platform.OS === 'ios' && animationEnabled,
|
||||||
animationEnabled &&
|
|
||||||
index !== 0,
|
|
||||||
gestureDirection = defaultTransitionPreset.gestureDirection,
|
gestureDirection = defaultTransitionPreset.gestureDirection,
|
||||||
transitionSpec = defaultTransitionPreset.transitionSpec,
|
transitionSpec = defaultTransitionPreset.transitionSpec,
|
||||||
cardStyleInterpolator = animationEnabled === false
|
cardStyleInterpolator = animationEnabled === false
|
||||||
@@ -236,52 +240,16 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
|
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
|
||||||
cardOverlayEnabled = Platform.OS !== 'ios' ||
|
cardOverlayEnabled = Platform.OS !== 'ios' ||
|
||||||
cardStyleInterpolator === forModalPresentationIOS,
|
cardStyleInterpolator === forModalPresentationIOS,
|
||||||
} = options;
|
} = optionsForTransitionConfig;
|
||||||
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const headerMode: StackHeaderMode =
|
const headerMode: StackHeaderMode =
|
||||||
options.headerMode ??
|
descriptor.options.headerMode ??
|
||||||
(options.animationPresentation !== 'modal' &&
|
(!(
|
||||||
transitionConfig.cardStyleInterpolator !== forModalPresentationIOS &&
|
optionsForTransitionConfig.presentation === 'modal' ||
|
||||||
|
cardStyleInterpolator === forModalPresentationIOS
|
||||||
|
) &&
|
||||||
Platform.OS === 'ios' &&
|
Platform.OS === 'ios' &&
|
||||||
options.header === undefined
|
descriptor.options.header === undefined
|
||||||
? 'float'
|
? 'float'
|
||||||
: 'screen');
|
: 'screen');
|
||||||
|
|
||||||
@@ -290,10 +258,14 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
descriptor: {
|
descriptor: {
|
||||||
...descriptor,
|
...descriptor,
|
||||||
options: {
|
options: {
|
||||||
...options,
|
...descriptor.options,
|
||||||
...transitionConfig,
|
|
||||||
animationEnabled,
|
animationEnabled,
|
||||||
|
cardOverlayEnabled,
|
||||||
|
cardStyleInterpolator,
|
||||||
|
gestureDirection,
|
||||||
gestureEnabled,
|
gestureEnabled,
|
||||||
|
headerStyleInterpolator,
|
||||||
|
transitionSpec,
|
||||||
headerMode,
|
headerMode,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -455,9 +427,6 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
isParentHeaderShown,
|
isParentHeaderShown,
|
||||||
onTransitionStart,
|
onTransitionStart,
|
||||||
onTransitionEnd,
|
onTransitionEnd,
|
||||||
onPageChangeStart,
|
|
||||||
onPageChangeConfirm,
|
|
||||||
onPageChangeCancel,
|
|
||||||
onGestureStart,
|
onGestureStart,
|
||||||
onGestureEnd,
|
onGestureEnd,
|
||||||
onGestureCancel,
|
onGestureCancel,
|
||||||
@@ -492,7 +461,7 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
const { options } = scenes[i].descriptor;
|
const { options } = scenes[i].descriptor;
|
||||||
const {
|
const {
|
||||||
// By default, we don't want to detach the previous screen of the active one for modals
|
// 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
|
options.cardStyleInterpolator === forModalPresentationIOS
|
||||||
? i !== scenes.length - 1
|
? i !== scenes.length - 1
|
||||||
: true,
|
: true,
|
||||||
@@ -617,6 +586,7 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
pointerEvents="box-none"
|
pointerEvents="box-none"
|
||||||
>
|
>
|
||||||
<CardContainer
|
<CardContainer
|
||||||
|
index={index}
|
||||||
interpolationIndex={interpolationIndex}
|
interpolationIndex={interpolationIndex}
|
||||||
active={index === self.length - 1}
|
active={index === self.length - 1}
|
||||||
focused={focused}
|
focused={focused}
|
||||||
@@ -628,9 +598,6 @@ export default class CardStack extends React.Component<Props, State> {
|
|||||||
safeAreaInsetRight={safeAreaInsetRight}
|
safeAreaInsetRight={safeAreaInsetRight}
|
||||||
safeAreaInsetBottom={safeAreaInsetBottom}
|
safeAreaInsetBottom={safeAreaInsetBottom}
|
||||||
safeAreaInsetLeft={safeAreaInsetLeft}
|
safeAreaInsetLeft={safeAreaInsetLeft}
|
||||||
onPageChangeStart={onPageChangeStart}
|
|
||||||
onPageChangeConfirm={onPageChangeConfirm}
|
|
||||||
onPageChangeCancel={onPageChangeCancel}
|
|
||||||
onGestureStart={onGestureStart}
|
onGestureStart={onGestureStart}
|
||||||
onGestureCancel={onGestureCancel}
|
onGestureCancel={onGestureCancel}
|
||||||
onGestureEnd={onGestureEnd}
|
onGestureEnd={onGestureEnd}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import {
|
|||||||
EdgeInsets,
|
EdgeInsets,
|
||||||
} from 'react-native-safe-area-context';
|
} from 'react-native-safe-area-context';
|
||||||
import {
|
import {
|
||||||
NavigationHelpersContext,
|
|
||||||
StackActions,
|
StackActions,
|
||||||
StackNavigationState,
|
StackNavigationState,
|
||||||
Route,
|
Route,
|
||||||
@@ -18,7 +17,6 @@ import {
|
|||||||
|
|
||||||
import { GestureHandlerRootView } from '../GestureHandler';
|
import { GestureHandlerRootView } from '../GestureHandler';
|
||||||
import CardStack from './CardStack';
|
import CardStack from './CardStack';
|
||||||
import KeyboardManager from '../KeyboardManager';
|
|
||||||
import HeaderContainer, {
|
import HeaderContainer, {
|
||||||
Props as HeaderContainerProps,
|
Props as HeaderContainerProps,
|
||||||
} from '../Header/HeaderContainer';
|
} from '../Header/HeaderContainer';
|
||||||
@@ -418,8 +416,6 @@ export default class StackView extends React.Component<Props, State> {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
state,
|
state,
|
||||||
navigation,
|
|
||||||
keyboardHandlingEnabled,
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
descriptors: _,
|
descriptors: _,
|
||||||
...rest
|
...rest
|
||||||
@@ -433,45 +429,38 @@ export default class StackView extends React.Component<Props, State> {
|
|||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigationHelpersContext.Provider value={navigation}>
|
<GestureHandlerWrapper style={styles.container}>
|
||||||
<GestureHandlerWrapper style={styles.container}>
|
<SafeAreaProviderCompat>
|
||||||
<SafeAreaProviderCompat>
|
<SafeAreaInsetsContext.Consumer>
|
||||||
<SafeAreaInsetsContext.Consumer>
|
{(insets) => (
|
||||||
{(insets) => (
|
<HeaderShownContext.Consumer>
|
||||||
<KeyboardManager enabled={keyboardHandlingEnabled !== false}>
|
{(isParentHeaderShown) => (
|
||||||
{(props) => (
|
<CardStack
|
||||||
<HeaderShownContext.Consumer>
|
insets={insets as EdgeInsets}
|
||||||
{(isParentHeaderShown) => (
|
isParentHeaderShown={isParentHeaderShown}
|
||||||
<CardStack
|
getPreviousRoute={this.getPreviousRoute}
|
||||||
insets={insets as EdgeInsets}
|
routes={routes}
|
||||||
isParentHeaderShown={isParentHeaderShown}
|
openingRouteKeys={openingRouteKeys}
|
||||||
getPreviousRoute={this.getPreviousRoute}
|
closingRouteKeys={closingRouteKeys}
|
||||||
routes={routes}
|
onOpenRoute={this.handleOpenRoute}
|
||||||
openingRouteKeys={openingRouteKeys}
|
onCloseRoute={this.handleCloseRoute}
|
||||||
closingRouteKeys={closingRouteKeys}
|
onTransitionStart={this.handleTransitionStart}
|
||||||
onOpenRoute={this.handleOpenRoute}
|
onTransitionEnd={this.handleTransitionEnd}
|
||||||
onCloseRoute={this.handleCloseRoute}
|
renderHeader={this.renderHeader}
|
||||||
onTransitionStart={this.handleTransitionStart}
|
renderScene={this.renderScene}
|
||||||
onTransitionEnd={this.handleTransitionEnd}
|
state={state}
|
||||||
renderHeader={this.renderHeader}
|
descriptors={descriptors}
|
||||||
renderScene={this.renderScene}
|
onGestureStart={this.handleGestureStart}
|
||||||
state={state}
|
onGestureEnd={this.handleGestureEnd}
|
||||||
descriptors={descriptors}
|
onGestureCancel={this.handleGestureCancel}
|
||||||
onGestureStart={this.handleGestureStart}
|
{...rest}
|
||||||
onGestureEnd={this.handleGestureEnd}
|
/>
|
||||||
onGestureCancel={this.handleGestureCancel}
|
)}
|
||||||
{...rest}
|
</HeaderShownContext.Consumer>
|
||||||
{...props}
|
)}
|
||||||
/>
|
</SafeAreaInsetsContext.Consumer>
|
||||||
)}
|
</SafeAreaProviderCompat>
|
||||||
</HeaderShownContext.Consumer>
|
</GestureHandlerWrapper>
|
||||||
)}
|
|
||||||
</KeyboardManager>
|
|
||||||
)}
|
|
||||||
</SafeAreaInsetsContext.Consumer>
|
|
||||||
</SafeAreaProviderCompat>
|
|
||||||
</GestureHandlerWrapper>
|
|
||||||
</NavigationHelpersContext.Provider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
yarn.lock
44
yarn.lock
@@ -3717,6 +3717,13 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
|
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256"
|
||||||
integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==
|
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":
|
"@types/node-fetch@^2.5.9":
|
||||||
version "2.5.9"
|
version "2.5.9"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.9.tgz#c04a12115aa436f189e39579272b305e477621b4"
|
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"
|
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||||
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
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:
|
get-caller-file@^2.0.1, get-caller-file@^2.0.5:
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
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"
|
resolved "https://registry.yarnpkg.com/mock-require-assets/-/mock-require-assets-0.0.1.tgz#94136f70e5b009c52c2df3b45724d15ab4f0cb98"
|
||||||
integrity sha1-lBNvcOWwCcUsLfO0VyTRWrTwy5g=
|
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:
|
mockdate@^3.0.2:
|
||||||
version "3.0.5"
|
version "3.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
|
resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
|
||||||
@@ -14253,10 +14273,10 @@ pkg-up@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
find-up "^2.1.0"
|
find-up "^2.1.0"
|
||||||
|
|
||||||
playwright@^1.10.0:
|
playwright@^1.11.0:
|
||||||
version "1.10.0"
|
version "1.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.10.0.tgz#a14d295f1ad886caf4cc5e674afe03ac832066bc"
|
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.11.0.tgz#0796cf08f4756e8187e01c705315d8e1fb48e25f"
|
||||||
integrity sha512-b7SGBcCPq4W3pb4ImEDmNXtO0ZkJbZMuWiShsaNJd+rGfY/6fqwgllsAojmxGSgFmijYw7WxCoPiAIEDIH16Kw==
|
integrity sha512-s3FQBRpu/pW/vZ/lFYhG/Q3WBUbT2rvMgrgy1PHDA7QtPN910C2rj9Ovd6A/m8yxuLnltd/OKqvlAGevWISHKw==
|
||||||
dependencies:
|
dependencies:
|
||||||
commander "^6.1.0"
|
commander "^6.1.0"
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
@@ -14271,6 +14291,7 @@ playwright@^1.10.0:
|
|||||||
rimraf "^3.0.2"
|
rimraf "^3.0.2"
|
||||||
stack-utils "^2.0.3"
|
stack-utils "^2.0.3"
|
||||||
ws "^7.3.1"
|
ws "^7.3.1"
|
||||||
|
yazl "^2.5.1"
|
||||||
|
|
||||||
please-upgrade-node@^3.2.0:
|
please-upgrade-node@^3.2.0:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
@@ -18225,10 +18246,10 @@ walker@^1.0.7, walker@~1.0.5:
|
|||||||
dependencies:
|
dependencies:
|
||||||
makeerror "1.0.x"
|
makeerror "1.0.x"
|
||||||
|
|
||||||
warn-once@^0.0.1:
|
warn-once@^0.1.0:
|
||||||
version "0.0.1"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/warn-once/-/warn-once-0.0.1.tgz#71eda54c88f240c4461e5c7a84cac2263caf3a4e"
|
resolved "https://registry.yarnpkg.com/warn-once/-/warn-once-0.1.0.tgz#4f58d89b84f968d0389176aa99e0cf0f14ffd4c8"
|
||||||
integrity sha512-Sh/kR0dQ9Tlr70E2zuR8mZ0yxmN9kGMNfvlwWWRi7frSox2uRC7U659Le8jBIqvjykSbvo9JX9ttsqw4vZPLmA==
|
integrity sha512-recZTSvuaH/On5ZU5ywq66y99lImWqzP93+AiUo9LUwG8gXHW+LJjhOd6REJHm7qb0niYqrEQJvbHSQfuJtTqA==
|
||||||
|
|
||||||
watchpack-chokidar2@^2.0.1:
|
watchpack-chokidar2@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
@@ -19107,6 +19128,13 @@ yauzl@^2.10.0:
|
|||||||
buffer-crc32 "~0.2.3"
|
buffer-crc32 "~0.2.3"
|
||||||
fd-slicer "~1.1.0"
|
fd-slicer "~1.1.0"
|
||||||
|
|
||||||
|
yazl@^2.5.1:
|
||||||
|
version "2.5.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35"
|
||||||
|
integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==
|
||||||
|
dependencies:
|
||||||
|
buffer-crc32 "~0.2.3"
|
||||||
|
|
||||||
ylru@^1.2.0:
|
ylru@^1.2.0:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f"
|
resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f"
|
||||||
|
|||||||
Reference in New Issue
Block a user