Compare commits

...

34 Commits

Author SHA1 Message Date
Satyajit Sahoo
85e9376302 chore: publish
- @react-navigation/stack@5.0.8
2020-02-21 20:09:06 +01:00
Satyajit Sahoo
a67b49477e fix: fix transparent header on Android 2020-02-21 20:07:38 +01:00
Satyajit Sahoo
225cb298b6 chore: publish
- @react-navigation/bottom-tabs@5.0.7
 - @react-navigation/compat@5.0.7
 - @react-navigation/core@5.1.6
 - @react-navigation/drawer@5.0.7
 - @react-navigation/material-bottom-tabs@5.0.7
 - @react-navigation/material-top-tabs@5.0.7
 - @react-navigation/native@5.0.7
 - @react-navigation/routers@5.0.2
 - @react-navigation/stack@5.0.7
2020-02-21 19:18:56 +01:00
Satyajit Sahoo
c8ea4199f4 fix: tweak error message for navigate 2020-02-21 19:13:11 +01:00
Satyajit Sahoo
f16700812f fix: avoid emitting focus events twice
fixes #6749
2020-02-21 18:56:06 +01:00
Satyajit Sahoo
240ce01822 fix: make sure header is visibile to accessibility tools on iOS 2020-02-21 16:30:05 +01:00
Satyajit Sahoo
c7dd3a58b1 fix: debounce back button by default in stack header 2020-02-21 15:31:50 +01:00
Satyajit Sahoo
125bd70e49 fix: preserve screen order with numeric names
fixes #6900
2020-02-21 05:43:32 +01:00
Satyajit Sahoo
4578849ebf chore: publish
- @react-navigation/bottom-tabs@5.0.6
 - @react-navigation/compat@5.0.6
 - @react-navigation/core@5.1.5
 - @react-navigation/drawer@5.0.6
 - @react-navigation/material-bottom-tabs@5.0.6
 - @react-navigation/material-top-tabs@5.0.6
 - @react-navigation/native@5.0.6
 - @react-navigation/stack@5.0.6
2020-02-19 23:34:10 +01:00
Satyajit Sahoo
c084517d7b chore: add release script 2020-02-19 23:30:12 +01:00
Satyajit Sahoo
22c85ff6a9 chore: remove native-stack from the repo
it's now moved to https://github.com/kmagiera/react-native-screens
2020-02-19 23:18:11 +01:00
Satyajit Sahoo
bf76075e0f fix: add accessibilityLabel prop to back button
fixes #6895
2020-02-19 23:09:00 +01:00
Satyajit Sahoo
d69b0db604 fix: add NavigationEvents
See https://github.com/react-navigation/react-navigation/issues/6821#issuecomment-588268512
2020-02-19 23:04:14 +01:00
Satyajit Sahoo
cdb2fed43d chore: update .gitignore 2020-02-18 21:03:18 +01:00
Satyajit Sahoo
bb0226e26d chore: tweak error message 2020-02-18 18:59:39 +01:00
Satyajit Sahoo
1a28c299b5 fix: show descriptive error for invalid return for useFocusEffect 2020-02-15 20:02:39 +01:00
Satyajit Sahoo
e0c3298e64 fix: delay showing drawer by one frame after layout 2020-02-15 19:17:20 +01:00
Satyajit Sahoo
040f5dbb9d refactor: drop use of performTransaction 2020-02-15 19:05:50 +01:00
Satyajit Sahoo
5b7bbbdfd9 chore: publish
- @react-navigation/bottom-tabs@5.0.5
- @react-navigation/compat@5.0.5
- @react-navigation/core@5.1.4
- @react-navigation/drawer@5.0.5
- @react-navigation/material-bottom-tabs@5.0.5
- @react-navigation/material-top-tabs@5.0.5
- @react-navigation/native-stack@5.0.5
- @react-navigation/native@5.0.5
- @react-navigation/stack@5.0.5
2020-02-15 00:18:52 +01:00
Satyajit Sahoo
c5fefc6ee9 chore: tweak versions for peer dependencies 2020-02-15 00:15:01 +01:00
Satyajit Sahoo
aaf01e01e7 fix: return '/' for empty paths 2020-02-14 23:17:29 +01:00
Satyajit Sahoo
ac242fd281 refactor: discard all routes but last when getting action from state 2020-02-14 23:04:09 +01:00
Satyajit Sahoo
c5fcfbd427 fix: link to migration guide on invalid usage 2020-02-14 22:48:04 +01:00
Satyajit Sahoo
424c9469e4 chore: publish
- @react-navigation/bottom-tabs@5.0.4
 - @react-navigation/compat@5.0.4
 - @react-navigation/core@5.1.3
 - @react-navigation/drawer@5.0.4
 - @react-navigation/material-bottom-tabs@5.0.4
 - @react-navigation/material-top-tabs@5.0.4
 - @react-navigation/native-stack@5.0.4
 - @react-navigation/native@5.0.4
 - @react-navigation/stack@5.0.4
2020-02-14 18:50:01 +01:00
Satyajit Sahoo
8f40a98086 fix: hard code header height for animation
closes #6818
2020-02-14 18:44:54 +01:00
Satyajit Sahoo
f964200b0d fix: update links in error messages 2020-02-14 18:32:53 +01:00
Satyajit Sahoo
bd2f008a83 chore: build related changes 2020-02-14 18:32:53 +01:00
Chris
e37d6598ca docs: Update types.tsx (#6849)
Typo :)
2020-02-14 10:43:53 +01:00
Satyajit Sahoo
c8ac5fab61 fix: return false for canGoBack if navigator hasn't finished mounting 2020-02-12 21:28:03 +01:00
Satyajit Sahoo
b6accd03f6 fix: throw a descriptive error if navigation object hasn't initialized 2020-02-12 20:59:58 +01:00
Satyajit Sahoo
0cca1309ec chore: publish
- @react-navigation/bottom-tabs@5.0.3
 - @react-navigation/compat@5.0.3
 - @react-navigation/core@5.1.2
 - @react-navigation/drawer@5.0.3
 - @react-navigation/material-bottom-tabs@5.0.3
 - @react-navigation/material-top-tabs@5.0.3
 - @react-navigation/native-stack@5.0.3
 - @react-navigation/native@5.0.3
 - @react-navigation/stack@5.0.3
2020-02-12 16:58:48 +01:00
Satyajit Sahoo
6c9447a38c fix: check if we can go baack before dispatching pop 2020-02-12 13:17:08 +01:00
Satyajit Sahoo
030c63c89f fix: fix false positives for circular object check
fixes #6827
2020-02-12 11:42:36 +01:00
Abhinandan Ramaprasath
2bf0958502 fix: static container memo check (#6825)
Memo check compared elements of prevProps to nextProps but failed
to take new props into account. Fixed the logic and added a new
test.
2020-02-12 10:56:23 +01:00
73 changed files with 1039 additions and 1623 deletions

View File

@@ -8,7 +8,6 @@
"@react-navigation/routers",
"@react-navigation/compat",
"@react-navigation/stack",
"@react-navigation/native-stack",
"@react-navigation/drawer",
"@react-navigation/bottom-tabs",
"@react-navigation/material-top-tabs",

View File

@@ -1,38 +0,0 @@
---
name: Native Stack Navigator
about: Report an issue with Native Stack Navigator (@react-navigation/native-stack)
title: ''
labels: bug, package:native-stack
assignees: ''
---
**Current Behavior**
- What code are you running and what is happening?
- Include a screenshot or video if it makes sense.
**Expected Behavior**
- What do you expect should be happening?
- Include a screenshot or video if it makes sense.
**How to reproduce**
- You must provide a way to reproduce the problem. If you are having an issue with your machine or build tools, the issue belongs on another repository as that is outside of the scope of React Navigation.
- Either re-create the bug on [Snack](https://snack.expo.io) or link to a GitHub repository with code that reproduces the bug.
- Explain how to run the example app and any steps that we need to take to reproduce the issue from the example app.
- Keep the repro code as simple as possible, with the minimum amount of code required to repro the issue.
- Before reporting an issue, make sure you are on latest version of the package.
**Your Environment**
| software | version |
| ------------------------------ | ------- |
| iOS or Android |
| @react-navigation/native |
| @react-navigation/native-stack |
| react-native-screens |
| react-native |
| expo |
| node |
| npm or yarn |

2
.gitignore vendored
View File

@@ -4,6 +4,8 @@
.idea
.expo
.gradle
.project
.settings
local.properties

View File

@@ -113,7 +113,7 @@ When you're sending a pull request:
Maintainers with write access to the GitHub repo and the npm organization can publish new versions. To publish a new version, first, you need to export a `GH_TOKEN` environment variable as mentioned [here](https://github.com/lerna/lerna/tree/master/commands/version#--create-release-type). Then run:
```sh
yarn lerna publish
yarn release
```
This will automatically bump the version and publish the packages. It'll also publish the changelogs on GitHub for each package.

View File

@@ -13,7 +13,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -161,32 +161,33 @@
<orderEntry type="library" name="Gradle: com.facebook.fresco:imagepipeline-okhttp3:2.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: io.nlopez.smartlocation:library:3.2.11@aar" level="project" />
<orderEntry type="library" name="Gradle: org.webkit:android-jsc:r245459@aar" level="project" />
<orderEntry type="module" module-name="android-expo-permissions" />
<orderEntry type="module" module-name="android-expo-constants" />
<orderEntry type="module" module-name="android-unimodules-image-loader-interface" />
<orderEntry type="module" module-name="android-expo-web-browser" />
<orderEntry type="module" module-name="android-unimodules-react-native-adapter" />
<orderEntry type="module" module-name="android-expo-file-system" />
<orderEntry type="module" module-name="android-expo-location" />
<orderEntry type="module" module-name="android-expo-error-recovery" />
<orderEntry type="module" module-name="android-unimodules-permissions-interface" />
<orderEntry type="module" module-name="android-unimodules-core" />
<orderEntry type="module" module-name="android-expo-app-loader-provider" />
<orderEntry type="module" module-name="android-expo-font" />
<orderEntry type="module" module-name="android-expo-keep-awake" />
<orderEntry type="module" module-name="android-expo-linear-gradient" />
<orderEntry type="module" module-name="android-expo-sqlite" />
<orderEntry type="module" module-name="android-unimodules-barcode-scanner-interface" />
<orderEntry type="module" module-name="android-unimodules-camera-interface" />
<orderEntry type="module" module-name="android-unimodules-constants-interface" />
<orderEntry type="module" module-name="android-unimodules-face-detector-interface" />
<orderEntry type="module" module-name="android-unimodules-file-system-interface" />
<orderEntry type="module" module-name="android-unimodules-font-interface" />
<orderEntry type="module" module-name="android-unimodules-sensors-interface" />
<orderEntry type="module" module-name="android-unimodules-task-manager-interface" />
<orderEntry type="module" module-name="android-@react-native-community_masked-view" />
<orderEntry type="module" module-name="android-react-native-gesture-handler" />
<orderEntry type="module" module-name="android-react-native-reanimated" />
<orderEntry type="module" module-name="expo-permissions" />
<orderEntry type="module" module-name="expo-constants" />
<orderEntry type="module" module-name="unimodules-image-loader-interface" />
<orderEntry type="module" module-name="expo-web-browser" />
<orderEntry type="module" module-name="unimodules-react-native-adapter" />
<orderEntry type="module" module-name="expo-file-system" />
<orderEntry type="module" module-name="expo-location" />
<orderEntry type="module" module-name="expo-error-recovery" />
<orderEntry type="module" module-name="unimodules-permissions-interface" />
<orderEntry type="module" module-name="unimodules-core" />
<orderEntry type="module" module-name="expo-app-loader-provider" />
<orderEntry type="module" module-name="expo-font" />
<orderEntry type="module" module-name="expo-keep-awake" />
<orderEntry type="module" module-name="expo-linear-gradient" />
<orderEntry type="module" module-name="expo-sqlite" />
<orderEntry type="module" module-name="unimodules-barcode-scanner-interface" />
<orderEntry type="module" module-name="unimodules-camera-interface" />
<orderEntry type="module" module-name="unimodules-constants-interface" />
<orderEntry type="module" module-name="unimodules-face-detector-interface" />
<orderEntry type="module" module-name="unimodules-file-system-interface" />
<orderEntry type="module" module-name="unimodules-font-interface" />
<orderEntry type="module" module-name="unimodules-sensors-interface" />
<orderEntry type="module" module-name="unimodules-task-manager-interface" />
<orderEntry type="module" module-name="@react-native-community_masked-view" />
<orderEntry type="module" module-name="react-native-gesture-handler" />
<orderEntry type="module" module-name="react-native-reanimated" />
<orderEntry type="module" module-name="react-native-restart" />
<orderEntry type="module" module-name="react-native-safe-area-context" />
<orderEntry type="module" module-name="react-native-screens" />
</component>

View File

@@ -1,233 +0,0 @@
import * as React from 'react';
import { View, Text, ScrollView, StyleSheet } from 'react-native';
import { Button } from 'react-native-paper';
// eslint-disable-next-line import/no-unresolved
import { enableScreens } from 'react-native-screens';
import {
RouteProp,
ParamListBase,
useFocusEffect,
useTheme,
} from '@react-navigation/native';
import { DrawerNavigationProp } from '@react-navigation/drawer';
import { StackNavigationProp } from '@react-navigation/stack';
import {
createNativeStackNavigator,
NativeStackNavigationProp,
} from '@react-navigation/native-stack';
import Albums from '../Shared/Albums';
type NativeStackParams = {
Article: { author: string };
Album: undefined;
};
type NativeStackNavigation = NativeStackNavigationProp<NativeStackParams>;
const Title = ({ children }: { children: React.ReactNode }) => {
const { colors } = useTheme();
return <Text style={[styles.title, { color: colors.text }]}>{children}</Text>;
};
const Paragraph = ({ children }: { children: React.ReactNode }) => {
const { colors } = useTheme();
return (
<Text style={[styles.paragraph, { color: colors.text }]}>{children}</Text>
);
};
const ArticleScreen = ({
navigation,
}: {
navigation: NativeStackNavigation;
route: RouteProp<NativeStackParams, 'Article'>;
}) => {
const { colors } = useTheme();
return (
<ScrollView
style={{ backgroundColor: colors.card }}
contentContainerStyle={styles.content}
>
<View style={styles.buttons}>
<Button
mode="contained"
onPress={() => navigation.push('Album')}
style={styles.button}
>
Push album
</Button>
<Button
mode="outlined"
onPress={() => navigation.goBack()}
style={styles.button}
>
Go back
</Button>
</View>
<Title>What is Lorem Ipsum?</Title>
<Paragraph>
Lorem Ipsum is simply dummy text of the printing and typesetting
industry. Lorem Ipsum has been the industry&apos;s standard dummy text
ever since the 1500s, when an unknown printer took a galley of type and
scrambled it to make a type specimen book. It has survived not only five
centuries, but also the leap into electronic typesetting, remaining
essentially unchanged. It was popularised in the 1960s with the release
of Letraset sheets containing Lorem Ipsum passages, and more recently
with desktop publishing software like Aldus PageMaker including versions
of Lorem Ipsum.
</Paragraph>
<Title>Where does it come from?</Title>
<Paragraph>
Contrary to popular belief, Lorem Ipsum is not simply random text. It
has roots in a piece of classical Latin literature from 45 BC, making it
over 2000 years old. Richard McClintock, a Latin professor at
Hampden-Sydney College in Virginia, looked up one of the more obscure
Latin words, consectetur, from a Lorem Ipsum passage, and going through
the cites of the word in classical literature, discovered the
undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33
of &quot;de Finibus Bonorum et Malorum&quot; (The Extremes of Good and
Evil) by Cicero, written in 45 BC. This book is a treatise on the theory
of ethics, very popular during the Renaissance. The first line of Lorem
Ipsum, &quot;Lorem ipsum dolor sit amet..&quot;, comes from a line in
section 1.10.32.
</Paragraph>
<Paragraph>
The standard chunk of Lorem Ipsum used since the 1500s is reproduced
below for those interested. Sections 1.10.32 and 1.10.33 from &quot;de
Finibus Bonorum et Malorum&quot; by Cicero are also reproduced in their
exact original form, accompanied by English versions from the 1914
translation by H. Rackham.
</Paragraph>
<Title>Why do we use it?</Title>
<Paragraph>
It is a long established fact that a reader will be distracted by the
readable content of a page when looking at its layout. The point of
using Lorem Ipsum is that it has a more-or-less normal distribution of
letters, as opposed to using &quot;Content here, content here&quot;,
making it look like readable English. Many desktop publishing packages
and web page editors now use Lorem Ipsum as their default model text,
and a search for &quot;lorem ipsum&quot; will uncover many web sites
still in their infancy. Various versions have evolved over the years,
sometimes by accident, sometimes on purpose (injected humour and the
like).
</Paragraph>
<Title>Where can I get some?</Title>
<Paragraph>
There are many variations of passages of Lorem Ipsum available, but the
majority have suffered alteration in some form, by injected humour, or
randomised words which don&apos;t look even slightly believable. If you
are going to use a passage of Lorem Ipsum, you need to be sure there
isn&apos;t anything embarrassing hidden in the middle of text. All the
Lorem Ipsum generators on the Internet tend to repeat predefined chunks
as necessary, making this the first true generator on the Internet. It
uses a dictionary of over 200 Latin words, combined with a handful of
model sentence structures, to generate Lorem Ipsum which looks
reasonable. The generated Lorem Ipsum is therefore always free from
repetition, injected humour, or non-characteristic words etc.
</Paragraph>
</ScrollView>
);
};
const AlbumsScreen = ({
navigation,
}: {
navigation: NativeStackNavigation;
}) => (
<ScrollView>
<View style={styles.buttons}>
<Button
mode="contained"
onPress={() => navigation.push('Article', { author: 'Babel fish' })}
style={styles.button}
>
Push article
</Button>
<Button
mode="outlined"
onPress={() => navigation.goBack()}
style={styles.button}
>
Go back
</Button>
</View>
<Albums scrollEnabled={false} />
</ScrollView>
);
const NativeStack = createNativeStackNavigator<NativeStackParams>();
type Props = {
navigation: StackNavigationProp<ParamListBase>;
};
export default function NativeStackScreen({ navigation }: Props) {
navigation.setOptions({
headerShown: false,
});
useFocusEffect(
React.useCallback(() => {
const drawer = navigation.dangerouslyGetParent() as DrawerNavigationProp<
ParamListBase
>;
navigation.setOptions({ gestureEnabled: false });
drawer.setOptions({ gestureEnabled: false });
return () => {
navigation.setOptions({ gestureEnabled: true });
drawer.setOptions({ gestureEnabled: true });
};
}, [navigation])
);
return (
<NativeStack.Navigator>
<NativeStack.Screen
name="Article"
component={ArticleScreen}
options={{
title: 'Lorem Ipsum',
headerLargeTitle: true,
headerHideShadow: true,
}}
/>
<NativeStack.Screen
name="Album"
component={AlbumsScreen}
options={{ title: 'Album' }}
/>
</NativeStack.Navigator>
);
}
enableScreens(true);
const styles = StyleSheet.create({
buttons: {
flexDirection: 'row',
padding: 8,
},
button: {
margin: 8,
},
content: {
paddingVertical: 16,
},
title: {
fontWeight: 'bold',
fontSize: 24,
marginVertical: 8,
marginHorizontal: 16,
},
paragraph: {
fontSize: 16,
lineHeight: 24,
marginVertical: 8,
marginHorizontal: 16,
},
});

View File

@@ -1,23 +0,0 @@
import * as React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function NativeStack() {
return (
<View style={styles.container}>
<Text style={styles.text}>Not supported on Web :(</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#eceff1',
},
text: {
fontSize: 16,
color: '#999',
},
});

View File

@@ -39,7 +39,6 @@ import {
import LinkingPrefixes from './LinkingPrefixes';
import SimpleStack from './Screens/SimpleStack';
import NativeStack from './Screens/NativeStack';
import ModalPresentationStack from './Screens/ModalPresentationStack';
import StackTransparent from './Screens/StackTransparent';
import StackHeaderCustomization from './Screens/StackHeaderCustomization';
@@ -67,7 +66,6 @@ type RootStackParamList = {
const SCREENS = {
SimpleStack: { title: 'Simple Stack', component: SimpleStack },
NativeStack: { title: 'Native Stack', component: NativeStack },
ModalPresentationStack: {
title: 'Modal Presentation Stack',
component: ModalPresentationStack,
@@ -124,7 +122,8 @@ export default function App() {
prefixes: LinkingPrefixes,
config: {
Root: {
path: 'root',
path: '',
initialRouteName: 'Home',
screens: Object.keys(SCREENS).reduce<{ [key: string]: string }>(
(acc, name) => {
// Convert screen names such as SimpleStack to kebab case (simple-stack)
@@ -135,7 +134,7 @@ export default function App() {
return acc;
},
{}
{ Home: '' }
),
},
},

View File

@@ -20,6 +20,7 @@
"lint": "eslint --ext '.js,.ts,.tsx' .",
"typescript": "tsc --noEmit",
"test": "jest",
"release": "lerna publish",
"example": "yarn --cwd example"
},
"devDependencies": {

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.7](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.6...@react-navigation/bottom-tabs@5.0.7) (2020-02-21)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.0.6](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.5...@react-navigation/bottom-tabs@5.0.6) (2020-02-19)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.0.5](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.4...@react-navigation/bottom-tabs@5.0.5) (2020-02-14)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.0.4](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.3...@react-navigation/bottom-tabs@5.0.4) (2020-02-14)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.0.3](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.2...@react-navigation/bottom-tabs@5.0.3) (2020-02-12)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.1...@react-navigation/bottom-tabs@5.0.2) (2020-02-11)

View File

@@ -1,6 +1,7 @@
{
"name": "@react-navigation/bottom-tabs",
"description": "Bottom tab navigator following iOS design guidelines",
"version": "5.0.7",
"keywords": [
"react-native-component",
"react-component",
@@ -10,7 +11,6 @@
"android",
"tab"
],
"version": "5.0.2",
"license": "MIT",
"repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs",
"main": "lib/commonjs/index.js",
@@ -35,7 +35,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.2",
"@react-navigation/native": "^5.0.7",
"@types/color": "^3.0.1",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",
@@ -46,10 +46,10 @@
"typescript": "^3.7.5"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0",
"@react-navigation/native": "^5.0.5",
"react": "*",
"react-native": "*",
"react-native-safe-area-context": "^0.6.0"
"react-native-safe-area-context": ">= 0.6.0"
},
"@react-native-community/bob": {
"source": "src",

View File

@@ -176,8 +176,8 @@ export type BottomTabBarOptions = {
*/
tabStyle?: StyleProp<ViewStyle>;
/**
* Whether the label is renderd below the icon or beside the icon.
* By default, in `vertical` orinetation, label is rendered below and in `horizontal` orientation, it's renderd beside.
* Whether the label is rendered below the icon or beside the icon.
* By default, in `vertical` orinetation, label is rendered below and in `horizontal` orientation, it's rendered beside.
*/
labelPosition?: LabelPosition;
/**

View File

@@ -3,6 +3,49 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.7](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.0.6...@react-navigation/compat@5.0.7) (2020-02-21)
**Note:** Version bump only for package @react-navigation/compat
## [5.0.6](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.0.5...@react-navigation/compat@5.0.6) (2020-02-19)
### Bug Fixes
* add NavigationEvents ([d69b0db](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/commit/d69b0db60455b8789276822ba73f5349db8842d7)), closes [/github.com/react-navigation/react-navigation/issues/6821#issuecomment-588268512](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/issues/issuecomment-588268512)
## [5.0.5](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.0.4...@react-navigation/compat@5.0.5) (2020-02-14)
**Note:** Version bump only for package @react-navigation/compat
## [5.0.4](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.0.3...@react-navigation/compat@5.0.4) (2020-02-14)
**Note:** Version bump only for package @react-navigation/compat
## [5.0.3](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.0.2...@react-navigation/compat@5.0.3) (2020-02-12)
**Note:** Version bump only for package @react-navigation/compat
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.0.1...@react-navigation/compat@5.0.2) (2020-02-11)
**Note:** Version bump only for package @react-navigation/compat

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/compat",
"description": "Compatibility layer to write navigator definitions in static configuration format",
"version": "5.0.2",
"version": "5.0.7",
"license": "MIT",
"repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/compat",
"bugs": {
@@ -26,14 +26,14 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.2",
"@react-navigation/native": "^5.0.7",
"@types/react": "^16.9.19",
"react": "~16.9.0",
"typescript": "^3.7.5"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0",
"react": "~16.9.0"
"@react-navigation/native": "^5.0.5",
"react": "*"
},
"@react-native-community/bob": {
"source": "src",

View File

@@ -0,0 +1,45 @@
import * as React from 'react';
import { useNavigation } from '@react-navigation/native';
type Props = {
onWillFocus?: () => void;
onDidFocus?: () => void;
onWillBlur?: () => void;
onDidBlur?: () => void;
};
export default function NavigationEvents(props: Props) {
const navigation = useNavigation();
const propsRef = React.useRef(props);
React.useEffect(() => {
propsRef.current = props;
});
React.useEffect(() => {
const unsubFocus = navigation.addListener('focus', () => {
propsRef.current.onWillFocus?.();
});
const unsubBlur = navigation.addListener('blur', () => {
propsRef.current.onWillBlur?.();
});
// @ts-ignore
const unsubTransitionEnd = navigation.addListener('transitionEnd', () => {
if (navigation.isFocused()) {
propsRef.current.onDidFocus?.();
} else {
propsRef.current.onDidBlur?.();
}
});
return () => {
unsubFocus();
unsubBlur();
unsubTransitionEnd();
};
}, [navigation]);
return null;
}

View File

@@ -14,4 +14,6 @@ export { default as createSwitchNavigator } from './createSwitchNavigator';
export { default as withNavigation } from './withNavigation';
export { default as withNavigationFocus } from './withNavigationFocus';
export { default as NavigationEvents } from './NavigationEvents';
export * from './types';

View File

@@ -3,6 +3,66 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.1.6](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.1.5...@react-navigation/core@5.1.6) (2020-02-21)
### Bug Fixes
* avoid emitting focus events twice ([f167008](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/f16700812f3757713b04ca3a860209795b4a6c44)), closes [#6749](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/6749)
* preserve screen order with numeric names ([125bd70](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/125bd70e49b708d936a2eee72ba5cb92eacf26a9)), closes [#6900](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/6900)
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.1.4...@react-navigation/core@5.1.5) (2020-02-19)
### Bug Fixes
* show descriptive error for invalid return for useFocusEffect ([1a28c29](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/1a28c299b5e3f0805eb6e9ea3cf5e9cc90c7a280))
## [5.1.4](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.1.3...@react-navigation/core@5.1.4) (2020-02-14)
### Bug Fixes
* link to migration guide on invalid usage ([c5fcfbd](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/c5fcfbd4277541e131acbaa7602a5d7e636afebb))
* return '/' for empty paths ([aaf01e0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/aaf01e01e7b47b375f68aebe6d0effe82878d060))
## [5.1.3](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.1.2...@react-navigation/core@5.1.3) (2020-02-14)
### Bug Fixes
* return false for canGoBack if navigator hasn't finished mounting ([c8ac5fa](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/c8ac5fab61cf127985431075a3c59c1f3dfa42da))
* throw a descriptive error if navigation object hasn't initialized ([b6accd0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/b6accd03f69dd438e595094d8bf8599cc12e71ac))
* update links in error messages ([f964200](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/f964200b0dcbc19d5f88ad2dd1eb8e5576973497))
## [5.1.2](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.1.1...@react-navigation/core@5.1.2) (2020-02-12)
### Bug Fixes
* fix false positives for circular object check ([030c63c](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/030c63c89fe447aa484b767831c8f8e26e90431c)), closes [#6827](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/6827)
* static container memo check ([#6825](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/6825)) ([2bf0958](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/2bf09585021470f500d967e9242836840efe970f))
## [5.1.1](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.1.0...@react-navigation/core@5.1.1) (2020-02-11)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/core",
"description": "Core utilities for building navigators",
"version": "5.1.1",
"version": "5.1.6",
"keywords": [
"react",
"react-native",
@@ -29,7 +29,7 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.1",
"@react-navigation/routers": "^5.0.2",
"escape-string-regexp": "^2.0.0",
"query-string": "^6.10.1",
"react-is": "^16.12.0",
@@ -49,7 +49,7 @@
"typescript": "^3.7.5"
},
"peerDependencies": {
"react": "~16.9.0"
"react": "*"
},
"@react-native-community/bob": {
"source": "src",

View File

@@ -16,12 +16,16 @@ import isSerializable from './isSerializable';
import { NavigationContainerRef, NavigationContainerProps } from './types';
import useEventEmitter from './useEventEmitter';
import useSyncState from './useSyncState';
type State = NavigationState | PartialState<NavigationState> | undefined;
const MISSING_CONTEXT_ERROR =
"We couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'? See https://reactnavigation.org/docs/en/getting-started.html for setup instructions.";
const NOT_INITIALIZED_ERROR =
"The 'navigation' object hasn't been initialized yet. This might happen if you don't have a navigator mounted, or if the navigator hasn't finished mounting. See https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html#handling-initialization for more details.";
export const NavigationStateContext = React.createContext<{
isDefault?: true;
state?: NavigationState | PartialState<NavigationState>;
@@ -31,7 +35,6 @@ export const NavigationStateContext = React.createContext<{
setState: (
state: NavigationState | PartialState<NavigationState> | undefined
) => void;
performTransaction: (action: () => void) => void;
}>({
isDefault: true,
@@ -47,9 +50,6 @@ export const NavigationStateContext = React.createContext<{
get setState(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
get performTransaction(): any {
throw new Error(MISSING_CONTEXT_ERROR);
},
});
let hasWarnedForSerialization = false;
@@ -112,13 +112,10 @@ const BaseNavigationContainer = React.forwardRef(
);
}
const [state, setNavigationState] = React.useState<State>(() =>
const [state, getState, setState] = useSyncState<State>(() =>
getPartialState(initialState == null ? undefined : initialState)
);
const navigationStateRef = React.useRef<State>();
const transactionStateRef = React.useRef<State | null>(null);
const isTransactionActiveRef = React.useRef<boolean>(false);
const isFirstMountRef = React.useRef<boolean>(true);
const skipTrackingRef = React.useRef<boolean>(false);
@@ -130,53 +127,12 @@ const BaseNavigationContainer = React.forwardRef(
navigatorKeyRef.current = key;
}, []);
const performTransaction = React.useCallback((callback: () => void) => {
if (isTransactionActiveRef.current) {
throw new Error(
"Only one transaction can be active at a time. Did you accidentally nest 'performTransaction'?"
);
}
setNavigationState((navigationState: State) => {
isTransactionActiveRef.current = true;
transactionStateRef.current = navigationState;
try {
callback();
} finally {
isTransactionActiveRef.current = false;
}
return transactionStateRef.current;
});
}, []);
const getState = React.useCallback(
() =>
transactionStateRef.current !== null
? transactionStateRef.current
: navigationStateRef.current,
[]
);
const setState = React.useCallback((navigationState: State) => {
if (transactionStateRef.current === null) {
throw new Error(
"Any 'setState' calls need to be done inside 'performTransaction'"
);
}
transactionStateRef.current = navigationState;
}, []);
const reset = React.useCallback(
(state: NavigationState) => {
performTransaction(() => {
skipTrackingRef.current = true;
setState(state);
});
skipTrackingRef.current = true;
setState(state);
},
[performTransaction, setState]
[setState]
);
const { trackState, trackAction } = useDevTools({
@@ -195,10 +151,18 @@ const BaseNavigationContainer = React.forwardRef(
const dispatch = (
action: NavigationAction | ((state: NavigationState) => NavigationAction)
) => {
if (listeners[0] == null) {
throw new Error(NOT_INITIALIZED_ERROR);
}
listeners[0](navigation => navigation.dispatch(action));
};
const canGoBack = () => {
if (listeners[0] == null) {
return false;
}
const { result, handled } = listeners[0](navigation =>
navigation.canGoBack()
);
@@ -212,12 +176,10 @@ const BaseNavigationContainer = React.forwardRef(
const resetRoot = React.useCallback(
(state?: PartialState<NavigationState> | NavigationState) => {
performTransaction(() => {
trackAction('@@RESET_ROOT');
setState(state);
});
trackAction('@@RESET_ROOT');
setState(state);
},
[performTransaction, setState, trackAction]
[setState, trackAction]
);
const getRootState = React.useCallback(() => {
@@ -258,13 +220,12 @@ const BaseNavigationContainer = React.forwardRef(
const context = React.useMemo(
() => ({
state,
performTransaction,
getState,
setState,
getKey,
setKey,
}),
[getKey, getState, performTransaction, setKey, setState, state]
[getKey, getState, setKey, setState, state]
);
React.useEffect(() => {
@@ -277,7 +238,7 @@ const BaseNavigationContainer = React.forwardRef(
hasWarnedForSerialization = true;
console.warn(
"We found non-serializable values in the navigation state, which can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/en/header-buttons.html#header-interaction-with-its-screen-component for docs."
"We found non-serializable values in the navigation state, which can break usage such as persisting and restoring state. This might happen if you passed non-serializable values such as function, class instances etc. in params. If you need to use components with callbacks in your options, you can use 'navigation.setOptions' instead. See https://reactnavigation.org/docs/en/troubleshooting.html#i-get-the-warning-we-found-non-serializable-values-in-the-navigation-state for more details."
);
}
}
@@ -293,15 +254,12 @@ const BaseNavigationContainer = React.forwardRef(
trackState(getRootState);
}
navigationStateRef.current = state;
transactionStateRef.current = null;
if (!isFirstMountRef.current && onStateChange) {
onStateChange(getRootState());
}
isFirstMountRef.current = false;
}, [state, onStateChange, trackState, getRootState, emitter]);
}, [onStateChange, trackState, getRootState, emitter, state]);
return (
<NavigationBuilderContext.Provider value={builderContext}>

View File

@@ -36,8 +36,6 @@ export default function SceneView<
getState,
setState,
}: Props<State, ScreenOptions>) {
const { performTransaction } = React.useContext(NavigationStateContext);
const navigatorKeyRef = React.useRef<string | undefined>();
const getKey = React.useCallback(() => navigatorKeyRef.current, []);
@@ -72,18 +70,10 @@ export default function SceneView<
state: route.state,
getState: getCurrentState,
setState: setCurrentState,
performTransaction,
getKey,
setKey,
}),
[
getCurrentState,
getKey,
performTransaction,
route.state,
setCurrentState,
setKey,
]
[getCurrentState, getKey, route.state, setCurrentState, setKey]
);
return (

View File

@@ -8,12 +8,19 @@ function StaticContainer(props: any) {
}
export default React.memo(StaticContainer, (prevProps: any, nextProps: any) => {
for (const prop in prevProps) {
if (prop === 'children') {
const prevPropKeys = Object.keys(prevProps);
const nextPropKeys = Object.keys(nextProps);
if (prevPropKeys.length !== nextPropKeys.length) {
return false;
}
for (const key of prevPropKeys) {
if (key === 'children') {
continue;
}
if (prevProps[prop] !== nextProps[prop]) {
if (prevProps[key] !== nextProps[key]) {
return false;
}
}

View File

@@ -51,77 +51,6 @@ it('throws when setState is accessed without a container', () => {
);
});
it('throws when performTransaction is accessed without a container', () => {
expect.assertions(1);
const Test = () => {
const { performTransaction } = React.useContext(NavigationStateContext);
// eslint-disable-next-line babel/no-unused-expressions
performTransaction;
return null;
};
const element = <Test />;
expect(() => render(element).update(element)).toThrowError(
"We couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'?"
);
});
it('throws when setState is called outside performTransaction', () => {
expect.assertions(1);
const Test = () => {
const { setState } = React.useContext(NavigationStateContext);
React.useEffect(() => {
setState(undefined);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return null;
};
const element = (
<BaseNavigationContainer>
<Test />
</BaseNavigationContainer>
);
expect(() => render(element).update(element)).toThrowError(
"Any 'setState' calls need to be done inside 'performTransaction'"
);
});
it('throws when nesting performTransaction', () => {
expect.assertions(1);
const Test = () => {
const { performTransaction } = React.useContext(NavigationStateContext);
React.useEffect(() => {
performTransaction(() => {
performTransaction(() => {});
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return null;
};
const element = (
<BaseNavigationContainer>
<Test />
</BaseNavigationContainer>
);
expect(() => render(element).update(element)).toThrowError(
"Only one transaction can be active at a time. Did you accidentally nest 'performTransaction'?"
);
});
it('throws when nesting containers', () => {
expect(() =>
render(
@@ -501,3 +430,51 @@ it('emits state events when the state changes', () => {
],
});
});
it('throws if there is no navigator rendered', () => {
expect.assertions(1);
const ref = React.createRef<NavigationContainerRef>();
const element = <BaseNavigationContainer ref={ref} children={null} />;
render(element);
act(() => {
expect(() => ref.current?.dispatch({ type: 'WHATEVER' })).toThrow(
"The 'navigation' object hasn't been initialized yet."
);
});
});
it("throws if the ref hasn't finished initializing", () => {
expect.assertions(1);
const ref = React.createRef<NavigationContainerRef>();
const TestNavigator = (props: any) => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return descriptors[state.routes[state.index].key].render();
};
const TestScreen = () => {
React.useEffect(() => {
expect(() => ref.current?.dispatch({ type: 'WHATEVER' })).toThrow(
"The 'navigation' object hasn't been initialized yet."
);
}, []);
return null;
};
const element = (
<BaseNavigationContainer ref={ref}>
<TestNavigator>
<Screen name="foo" component={TestScreen} />
</TestNavigator>
</BaseNavigationContainer>
);
render(element);
});

View File

@@ -49,3 +49,27 @@ it('updates element if any props changed', () => {
expect(root).toMatchInlineSnapshot(`"second"`);
});
it('updates element if any props are added', () => {
expect.assertions(2);
const Test = ({ label }: any) => {
return label;
};
const root = render(
<StaticContainer count={42}>
<Test label="first" />
</StaticContainer>
);
expect(root).toMatchInlineSnapshot(`"first"`);
root.update(
<StaticContainer count={42} moreCounts={12}>
<Test label="second" />
</StaticContainer>
);
expect(root).toMatchInlineSnapshot(`"second"`);
});

View File

@@ -41,6 +41,43 @@ it('gets navigate action from state', () => {
},
type: 'NAVIGATE',
});
expect(
getActionFromState({
routes: [
{
name: 'foo',
state: {
routes: [
{
name: 'bar',
state: {
routes: [
{
name: 'qux',
params: { author: 'jane' },
},
{ name: 'quz' },
],
},
},
],
},
},
],
})
).toEqual({
payload: {
name: 'foo',
params: {
screen: 'bar',
params: {
screen: 'quz',
},
},
},
type: 'NAVIGATE',
});
});
it('gets reset action from state', () => {
@@ -53,13 +90,7 @@ it('gets reset action from state', () => {
{
name: 'bar',
state: {
routes: [
{
name: 'qux',
params: { author: 'jane' },
},
{ name: 'quz' },
],
routes: [],
},
},
],
@@ -68,8 +99,6 @@ it('gets reset action from state', () => {
],
};
expect(getActionFromState(state)).toEqual({
payload: state,
type: 'RESET_ROOT',
});
expect(getActionFromState(state)).toBe(undefined);
expect(getActionFromState({ routes: [] })).toBe(undefined);
});

View File

@@ -489,3 +489,31 @@ it('handles empty path at the end', () => {
expect(getPathFromState(state, config)).toBe(path);
expect(getPathFromState(getStateFromPath(path, config), config)).toBe(path);
});
it('returns "/" for empty path', () => {
const config = {
Foo: {
path: '',
screens: {
Bar: '',
},
},
};
const state = {
routes: [
{
name: 'Foo',
state: {
routes: [
{
name: 'Bar',
},
],
},
},
],
};
expect(getPathFromState(state, config)).toBe('/');
});

View File

@@ -772,6 +772,60 @@ it('gives access to internal state', () => {
});
});
it('preserves order of screens in state with non-numeric names', () => {
const TestNavigator = (props: any): any => {
useNavigationBuilder(MockRouter, props);
return null;
};
const navigation = React.createRef<NavigationContainerRef>();
const root = (
<BaseNavigationContainer ref={navigation}>
<TestNavigator>
<Screen name="foo" component={jest.fn()} />
<Screen name="bar" component={jest.fn()} />
<Screen name="baz" component={jest.fn()} />
</TestNavigator>
</BaseNavigationContainer>
);
render(root);
expect(navigation.current?.getRootState().routeNames).toEqual([
'foo',
'bar',
'baz',
]);
});
it('preserves order of screens in state with numeric names', () => {
const TestNavigator = (props: any): any => {
useNavigationBuilder(MockRouter, props);
return null;
};
const navigation = React.createRef<NavigationContainerRef>();
const root = (
<BaseNavigationContainer ref={navigation}>
<TestNavigator>
<Screen name="4" component={jest.fn()} />
<Screen name="7" component={jest.fn()} />
<Screen name="1" component={jest.fn()} />
</TestNavigator>
</BaseNavigationContainer>
);
render(root);
expect(navigation.current?.getRootState().routeNames).toEqual([
'4',
'7',
'1',
]);
});
it("throws if navigator doesn't have any screens", () => {
const TestNavigator = (props: any) => {
useNavigationBuilder(MockRouter, props);

View File

@@ -51,20 +51,55 @@ it('returns false for non-serializable object', () => {
});
it('returns false for circular references', () => {
const o = {
index: 0,
key: '7',
routeNames: ['foo', 'bar'],
routes: [
{
key: 'foo',
name: 'foo',
},
],
const x = {
a: 1,
b: { b1: 1 },
};
// @ts-ignore
o.routes[0].state = o;
x.b.b2 = x;
// @ts-ignore
x.c = x.b;
expect(isSerializable(o)).toBe(false);
expect(isSerializable(x)).toBe(false);
const y = [
{
label: 'home',
children: [{ label: 'product' }],
},
{ label: 'about', extend: {} },
];
// @ts-ignore
y[0].children[0].parent = y[0];
// @ts-ignore
y[1].extend.home = y[0].children[0];
expect(isSerializable(y)).toBe(false);
const z = {
name: 'sun',
child: [{ name: 'flower' }],
};
// @ts-ignore
z.child[0].parent = z;
expect(isSerializable(z)).toBe(false);
});
it("doesn't fail if same object used multiple times", () => {
const o = { foo: 'bar' };
expect(
isSerializable({
baz: 'bax',
first: o,
second: o,
stuff: {
b: o,
},
})
).toBe(true);
});

View File

@@ -188,10 +188,12 @@ it('fires focus and blur events in nested navigator', () => {
expect(thirdFocusCallback).toBeCalledTimes(0);
expect(secondFocusCallback).toBeCalledTimes(1);
expect(fourthBlurCallback).toBeCalledTimes(0);
act(() => parent.current.navigate('nested'));
expect(firstBlurCallback).toBeCalledTimes(1);
expect(secondBlurCallback).toBeCalledTimes(1);
expect(thirdFocusCallback).toBeCalledTimes(0);
expect(fourthFocusCallback).toBeCalledTimes(1);
@@ -199,6 +201,35 @@ it('fires focus and blur events in nested navigator', () => {
expect(fourthBlurCallback).toBeCalledTimes(1);
expect(thirdFocusCallback).toBeCalledTimes(1);
act(() => parent.current.navigate('first'));
expect(firstFocusCallback).toBeCalledTimes(2);
expect(thirdBlurCallback).toBeCalledTimes(1);
act(() => parent.current.navigate('nested', { screen: 'fourth' }));
expect(fourthFocusCallback).toBeCalledTimes(2);
expect(thirdBlurCallback).toBeCalledTimes(1);
expect(firstBlurCallback).toBeCalledTimes(2);
act(() => parent.current.navigate('nested', { screen: 'third' }));
expect(thirdFocusCallback).toBeCalledTimes(2);
expect(fourthBlurCallback).toBeCalledTimes(2);
// Make sure nothing else has changed
expect(firstFocusCallback).toBeCalledTimes(2);
expect(firstBlurCallback).toBeCalledTimes(2);
expect(secondFocusCallback).toBeCalledTimes(1);
expect(secondBlurCallback).toBeCalledTimes(1);
expect(thirdFocusCallback).toBeCalledTimes(2);
expect(thirdBlurCallback).toBeCalledTimes(1);
expect(fourthFocusCallback).toBeCalledTimes(2);
expect(fourthBlurCallback).toBeCalledTimes(2);
});
it('fires blur event when a route is removed with a delay', async () => {

View File

@@ -21,7 +21,7 @@ export default function createNavigatorFactory<
> {
if (arguments[0] !== undefined) {
throw new Error(
"Creating a navigator doesn't take an argument. Maybe you are trying to use React Navigation 4 API with React Navigation 5? See https://reactnavigation.org/docs/en/hello-react-navigation.html for usage guide."
"Creating a navigator doesn't take an argument. Maybe you are trying to use React Navigation 4 API with React Navigation 5? See https://reactnavigation.org/docs/en/upgrading-from-4.x.html for migration guide."
);
}

View File

@@ -5,63 +5,50 @@ type NavigateParams = {
params?: NavigateParams;
};
type Action =
| {
type: 'NAVIGATE';
payload: { name: string; params: NavigateParams };
}
| {
type: 'RESET_ROOT';
payload: PartialState<NavigationState>;
};
type NavigateAction = {
type: 'NAVIGATE';
payload: { name: string; params: NavigateParams };
};
export default function getActionFromState(
state: PartialState<NavigationState>
): Action {
let payload: { name: string; params: NavigateParams } | undefined;
if (state.routes.length === 1) {
// Try to construct payload for a `NAVIGATE` action from the state
// This lets us preserve the navigation state and not lose it
let route = state.routes[0];
payload = {
name: route.name,
params: { ...route.params },
};
let current = state.routes[0].state;
let params = payload.params;
while (current) {
if (current.routes.length === 1) {
route = current.routes[0];
params.screen = route.name;
if (route.state) {
params.params = { ...route.params };
params = params.params;
} else {
params.params = route.params;
}
current = route.state;
} else {
payload = undefined;
break;
}
}
): NavigateAction | undefined {
if (state.routes.length === 0) {
return undefined;
}
if (payload) {
return {
type: 'NAVIGATE',
payload,
};
// Try to construct payload for a `NAVIGATE` action from the state
// This lets us preserve the navigation state and not lose it
let route = state.routes[state.routes.length - 1];
let payload: { name: string; params: NavigateParams } = {
name: route.name,
params: { ...route.params },
};
let current = route.state;
let params = payload.params;
while (current) {
if (current.routes.length === 0) {
return undefined;
}
route = current.routes[current.routes.length - 1];
params.screen = route.name;
if (route.state) {
params.params = { ...route.params };
params = params.params;
} else {
params.params = route.params;
}
current = route.state;
}
return {
type: 'RESET_ROOT',
payload: state,
type: 'NAVIGATE',
payload,
};
}

View File

@@ -158,6 +158,10 @@ export default function getPathFromState(
current = route.state;
}
path = path.slice(path.length - 1) === '/' ? path.slice(0, -1) : path;
path =
path !== '/' && path.slice(path.length - 1) === '/'
? path.slice(0, -1)
: path;
return path;
}

View File

@@ -1,6 +1,6 @@
const isSerializableWithoutCircularReference = (
o: { [key: string]: any },
seen = new Set<any>()
seen: Set<any>
): boolean => {
if (
o === undefined ||
@@ -27,13 +27,13 @@ const isSerializableWithoutCircularReference = (
if (Array.isArray(o)) {
for (const it of o) {
if (!isSerializableWithoutCircularReference(it, seen)) {
if (!isSerializableWithoutCircularReference(it, new Set<any>(seen))) {
return false;
}
}
} else {
for (const key in o) {
if (!isSerializableWithoutCircularReference(o[key], seen)) {
if (!isSerializableWithoutCircularReference(o[key], new Set<any>(seen))) {
return false;
}
}
@@ -43,5 +43,5 @@ const isSerializableWithoutCircularReference = (
};
export default function isSerializable(o: { [key: string]: any }) {
return isSerializableWithoutCircularReference(o);
return isSerializableWithoutCircularReference(o, new Set<any>());
}

View File

@@ -10,13 +10,51 @@ type EffectCallback = () => undefined | void | (() => void);
*
* @param callback Memoized callback containing the effect, should optionally return a cleanup function.
*/
export default function useFocusEffect(callback: EffectCallback) {
export default function useFocusEffect(effect: EffectCallback) {
const navigation = useNavigation();
React.useEffect(() => {
let isFocused = false;
let cleanup: undefined | void | (() => void);
const callback = () => {
const destroy = effect();
if (destroy === undefined || typeof destroy === 'function') {
return destroy;
}
if (process.env.NODE_ENV !== 'production') {
let message =
'An effect function must not return anything besides a function, which is used for clean-up.';
if (destroy === null) {
message +=
" You returned 'null'. If your effect does not require clean-up, return 'undefined' (or nothing).";
} else if (typeof (destroy as any).then === 'function') {
message +=
"\n\nIt looks like you wrote 'useFocusEffect(async () => ...)' or returned a Promise. " +
'Instead, write the async function inside your effect ' +
'and call it immediately:\n\n' +
'useFocusEffect(\n' +
' React.useCallback() => {\n' +
' async function fetchData() {\n' +
' // You can await here\n' +
' const response = await MyAPI.getData(someId);\n' +
' // ...\n' +
' }\n\n' +
' fetchData();\n' +
' }, [someId])\n' +
'};\n\n' +
'See usage guide: https://reactnavigation.org/docs/en/use-focus-effect.html';
} else {
message += ` You returned: '${JSON.stringify(destroy)}'`;
}
console.error(message);
}
};
// We need to run the effect on intial render/dep changes if the screen is focused
if (navigation.isFocused()) {
cleanup = callback();
@@ -55,5 +93,5 @@ export default function useFocusEffect(callback: EffectCallback) {
unsubscribeFocus();
unsubscribeBlur();
};
}, [callback, navigation]);
}, [effect, navigation]);
}

View File

@@ -21,17 +21,19 @@ export default function useFocusEvents({ state, emitter }: Options) {
// Coz the child screen can't be focused if the parent screen is out of focus
React.useEffect(
() =>
navigation?.addListener('focus', () =>
emitter.emit({ type: 'focus', target: currentFocusedKey })
),
navigation?.addListener('focus', () => {
lastFocusedKeyRef.current = currentFocusedKey;
emitter.emit({ type: 'focus', target: currentFocusedKey });
}),
[currentFocusedKey, emitter, navigation]
);
React.useEffect(
() =>
navigation?.addListener('blur', () =>
emitter.emit({ type: 'blur', target: currentFocusedKey })
),
navigation?.addListener('blur', () => {
lastFocusedKeyRef.current = undefined;
emitter.emit({ type: 'blur', target: currentFocusedKey });
}),
[currentFocusedKey, emitter, navigation]
);
@@ -60,14 +62,7 @@ export default function useFocusEvents({ state, emitter }: Options) {
return;
}
emitter.emit({
type: 'focus',
target: currentFocusedKey,
});
emitter.emit({
type: 'blur',
target: lastFocusedKey,
});
emitter.emit({ type: 'focus', target: currentFocusedKey });
emitter.emit({ type: 'blur', target: lastFocusedKey });
}, [currentFocusedKey, emitter, navigation]);
}

View File

@@ -177,20 +177,21 @@ export default function useNavigationBuilder<
})
);
const screens = getRouteConfigsFromChildren<ScreenOptions>(children).reduce<
const routeConfigs = getRouteConfigsFromChildren<ScreenOptions>(children);
const screens = routeConfigs.reduce<
Record<string, RouteConfig<ParamListBase, string, ScreenOptions>>
>((acc, curr) => {
if (curr.name in acc) {
>((acc, config) => {
if (config.name in acc) {
throw new Error(
`A navigator cannot contain multiple 'Screen' components with the same name (found duplicate screen named '${curr.name}')`
`A navigator cannot contain multiple 'Screen' components with the same name (found duplicate screen named '${config.name}')`
);
}
acc[curr.name] = curr;
acc[config.name] = config;
return acc;
}, {});
const routeNames = Object.keys(screens);
const routeNames = routeConfigs.map(config => config.name);
const routeParamList = routeNames.reduce<Record<string, object | undefined>>(
(acc, curr) => {
const { initialParams } = screens[curr];
@@ -235,7 +236,6 @@ export default function useNavigationBuilder<
setState,
setKey,
getKey,
performTransaction,
} = React.useContext(NavigationStateContext);
const previousStateRef = React.useRef<
@@ -316,9 +316,7 @@ export default function useNavigationBuilder<
// If the state needs to be updated, we'll schedule an update with React
// setState in render seems hacky, but that's how React docs implement getDerivedPropsFromState
// https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-getderivedstatefromprops
performTransaction(() => {
setState(nextState);
});
setState(nextState);
}
// The up-to-date state will come in next render, but we don't need to wait for it
@@ -331,11 +329,9 @@ export default function useNavigationBuilder<
return () => {
// We need to clean up state for this navigator on unmount
performTransaction(() => {
if (getCurrentState() !== undefined && getKey() === navigatorKey) {
setState(undefined);
}
});
if (getCurrentState() !== undefined && getKey() === navigatorKey) {
setState(undefined);
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

View File

@@ -7,7 +7,6 @@ import {
Router,
} from '@react-navigation/routers';
import NavigationContext from './NavigationContext';
import { NavigationStateContext } from './BaseNavigationContainer';
import { NavigationEventEmitter } from './useEventEmitter';
import { NavigationHelpers, NavigationProp, PrivateValueStore } from './types';
@@ -35,24 +34,21 @@ export default function useNavigationHelpers<
EventMap extends Record<string, any>
>({ onAction, getState, emitter, router }: Options<State, Action>) {
const parentNavigationHelpers = React.useContext(NavigationContext);
const { performTransaction } = React.useContext(NavigationStateContext);
return React.useMemo(() => {
const dispatch = (action: Action | ((state: State) => Action)) => {
performTransaction(() => {
const payload =
typeof action === 'function' ? action(getState()) : action;
const payload =
typeof action === 'function' ? action(getState()) : action;
const handled = onAction(payload);
const handled = onAction(payload);
if (!handled && process.env.NODE_ENV !== 'production') {
console.error(
`The action '${payload.type}' with payload '${JSON.stringify(
payload.payload
)}' was not handled by any navigator. If you are trying to navigate to a screen, check if the screen exists in your navigator. If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/en/nesting-navigators.html#navigating-to-a-screen-in-a-nested-navigator.`
);
}
});
if (!handled && process.env.NODE_ENV !== 'production') {
console.error(
`The action '${payload.type}' with payload '${JSON.stringify(
payload.payload
)}' was not handled by any navigator. If you are trying to navigate to a screen, check if the screen exists in your navigator. If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/en/nesting-navigators.html#navigating-to-a-screen-in-a-nested-navigator.`
);
}
};
const actions = {
@@ -91,12 +87,5 @@ export default function useNavigationHelpers<
},
} as NavigationHelpers<ParamListBase, EventMap> &
(NavigationProp<ParamListBase, string, any, any, any> | undefined);
}, [
router,
getState,
parentNavigationHelpers,
emitter.emit,
performTransaction,
onAction,
]);
}, [router, getState, parentNavigationHelpers, emitter.emit, onAction]);
}

View File

@@ -0,0 +1,28 @@
import * as React from 'react';
const UNINTIALIZED_STATE = {};
export default function useSyncState<T>(initialState?: (() => T) | T) {
const stateRef = React.useRef<T>(UNINTIALIZED_STATE as any);
if (stateRef.current === UNINTIALIZED_STATE) {
stateRef.current =
// @ts-ignore
typeof initialState === 'function' ? initialState() : initialState;
}
const [state, setTrackingState] = React.useState(stateRef.current);
const getState = React.useCallback(() => stateRef.current, []);
const setState = React.useCallback((state: T) => {
if (state === stateRef.current) {
return;
}
stateRef.current = state;
setTrackingState(state);
}, []);
return [state, getState, setState] as const;
}

View File

@@ -3,6 +3,49 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.7](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.6...@react-navigation/drawer@5.0.7) (2020-02-21)
**Note:** Version bump only for package @react-navigation/drawer
## [5.0.6](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.5...@react-navigation/drawer@5.0.6) (2020-02-19)
### Bug Fixes
* delay showing drawer by one frame after layout ([e0c3298](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/commit/e0c3298e64970dc01a61401cfbd7a623eb0fd735))
## [5.0.5](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.4...@react-navigation/drawer@5.0.5) (2020-02-14)
**Note:** Version bump only for package @react-navigation/drawer
## [5.0.4](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.3...@react-navigation/drawer@5.0.4) (2020-02-14)
**Note:** Version bump only for package @react-navigation/drawer
## [5.0.3](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.2...@react-navigation/drawer@5.0.3) (2020-02-12)
**Note:** Version bump only for package @react-navigation/drawer
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.1...@react-navigation/drawer@5.0.2) (2020-02-11)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/drawer",
"description": "Drawer navigator component with animated transitions and gesturess",
"version": "5.0.2",
"version": "5.0.7",
"keywords": [
"react-native-component",
"react-component",
@@ -40,7 +40,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.2",
"@react-navigation/native": "^5.0.7",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",
@@ -53,13 +53,13 @@
"typescript": "^3.7.5"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0",
"@react-navigation/native": "^5.0.5",
"react": "*",
"react-native": "*",
"react-native-gesture-handler": "^1.0.0",
"react-native-reanimated": "^1.0.0",
"react-native-safe-area-context": "^0.6.0",
"react-native-screens": "^2.0.0-alpha.33"
"react-native-gesture-handler": ">= 1.0.0",
"react-native-reanimated": ">= 1.0.0",
"react-native-safe-area-context": ">= 0.6.0",
"react-native-screens": ">= 2.0.0-alpha.0 || >= 2.0.0-beta.0"
},
"@react-native-community/bob": {
"source": "src",

View File

@@ -504,7 +504,9 @@ export default class DrawerView extends React.PureComponent<Props> {
// Until layout is available, drawer is hidden with opacity: 0 by default
// Show it in the next frame when layout is available
// If we don't delay it until the next frame, there's a visible flicker
requestAnimationFrame(() => this.drawerOpacity.setValue(1));
requestAnimationFrame(() =>
requestAnimationFrame(() => this.drawerOpacity.setValue(1))
);
};
private toggleDrawer = (open: boolean) => {

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.7](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.6...@react-navigation/material-bottom-tabs@5.0.7) (2020-02-21)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.0.6](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.5...@react-navigation/material-bottom-tabs@5.0.6) (2020-02-19)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.0.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.4...@react-navigation/material-bottom-tabs@5.0.5) (2020-02-14)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.0.4](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.3...@react-navigation/material-bottom-tabs@5.0.4) (2020-02-14)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.0.3](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.2...@react-navigation/material-bottom-tabs@5.0.3) (2020-02-12)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.1...@react-navigation/material-bottom-tabs@5.0.2) (2020-02-11)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/material-bottom-tabs",
"description": "Integration for bottom navigation component from react-native-paper",
"version": "5.0.2",
"version": "5.0.7",
"keywords": [
"react-native-component",
"react-component",
@@ -36,7 +36,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.2",
"@react-navigation/native": "^5.0.7",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",
"@types/react-native-vector-icons": "^6.4.5",
@@ -48,11 +48,11 @@
"typescript": "^3.7.5"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0",
"@react-navigation/native": "^5.0.5",
"react": "*",
"react-native": "*",
"react-native-paper": "^3.5.0",
"react-native-vector-icons": "^6.0.0"
"react-native-paper": ">= 3.0.0",
"react-native-vector-icons": ">= 6.0.0"
},
"@react-native-community/bob": {
"source": "src",

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.7](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.6...@react-navigation/material-top-tabs@5.0.7) (2020-02-21)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.0.6](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.5...@react-navigation/material-top-tabs@5.0.6) (2020-02-19)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.0.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.4...@react-navigation/material-top-tabs@5.0.5) (2020-02-14)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.0.4](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.3...@react-navigation/material-top-tabs@5.0.4) (2020-02-14)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.0.3](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.2...@react-navigation/material-top-tabs@5.0.3) (2020-02-12)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.1...@react-navigation/material-top-tabs@5.0.2) (2020-02-11)
**Note:** Version bump only for package @react-navigation/material-top-tabs

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/material-top-tabs",
"description": "Integration for the animated tab view component from react-native-tab-view",
"version": "5.0.2",
"version": "5.0.7",
"keywords": [
"react-native-component",
"react-component",
@@ -39,7 +39,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.2",
"@react-navigation/native": "^5.0.7",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",
@@ -51,12 +51,12 @@
"typescript": "^3.7.5"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0",
"@react-navigation/native": "^5.0.5",
"react": "*",
"react-native": "*",
"react-native-gesture-handler": "^1.0.0",
"react-native-reanimated": "^1.0.0",
"react-native-tab-view": "^2.13.0"
"react-native-gesture-handler": ">= 1.0.0",
"react-native-reanimated": ">= 1.0.0",
"react-native-tab-view": ">= 2.0.0"
},
"@react-native-community/bob": {
"source": "src",

View File

@@ -1,343 +0,0 @@
# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.1...@react-navigation/native-stack@5.0.2) (2020-02-11)
**Note:** Version bump only for package @react-navigation/native-stack
## [5.0.1](https://github.com/react-navigation/react-navigation/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.35...@react-navigation/native-stack@5.0.1) (2020-02-10)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.35](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.34...@react-navigation/native-stack@5.0.0-alpha.35) (2020-02-04)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.34](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.33...@react-navigation/native-stack@5.0.0-alpha.34) (2020-02-04)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.33](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.32...@react-navigation/native-stack@5.0.0-alpha.33) (2020-02-03)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.32](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.29...@react-navigation/native-stack@5.0.0-alpha.32) (2020-02-02)
### Bug Fixes
* add licenses ([0c159db](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/0c159db4c9bc85e83b5cfe6819ab2562669a4d8f))
* screens integration on Android ([#294](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/issues/294)) ([9bfb295](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/9bfb29562020c61b4d5c9bee278bcb1c7bdb8b67))
* update screens for native stack ([5411816](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/54118161885738a6d20b062c7e6679f3bace8424))
# [5.0.0-alpha.30](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.29...@react-navigation/native-stack@5.0.0-alpha.30) (2020-02-02)
### Bug Fixes
* add licenses ([0c159db](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/0c159db4c9bc85e83b5cfe6819ab2562669a4d8f))
* screens integration on Android ([#294](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/issues/294)) ([9bfb295](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/9bfb29562020c61b4d5c9bee278bcb1c7bdb8b67))
* update screens for native stack ([5411816](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/54118161885738a6d20b062c7e6679f3bace8424))
# [5.0.0-alpha.29](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.28...@react-navigation/native-stack@5.0.0-alpha.29) (2020-01-24)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.28](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.27...@react-navigation/native-stack@5.0.0-alpha.28) (2020-01-23)
### Bug Fixes
* fix types for native stack ([1da4a64](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/1da4a6437f4607c1d4547d26dd5068615631982e))
### Features
* emit appear and dismiss events for native stack ([f1df4a0](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/f1df4a080877b3642e748a41a5ffc2da8c449a8c))
* let the navigator specify if default can be prevented ([da67e13](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/da67e134d2157201360427d3c10da24f24cae7aa))
# [5.0.0-alpha.27](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.26...@react-navigation/native-stack@5.0.0-alpha.27) (2020-01-14)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.26](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.25...@react-navigation/native-stack@5.0.0-alpha.26) (2020-01-13)
### Bug Fixes
* make sure paths aren't aliased when building definitions ([65a5dac](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/commit/65a5dac2bf887f4ba081ab15bd4c9870bb15697f)), closes [#265](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/issues/265)
# [5.0.0-alpha.25](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.24...@react-navigation/native-stack@5.0.0-alpha.25) (2020-01-13)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.24](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.22...@react-navigation/native-stack@5.0.0-alpha.24) (2020-01-09)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.23](https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack/compare/@react-navigation/native-stack@5.0.0-alpha.22...@react-navigation/native-stack@5.0.0-alpha.23) (2020-01-09)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.22](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.21...@react-navigation/native-stack@5.0.0-alpha.22) (2020-01-05)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.21](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.20...@react-navigation/native-stack@5.0.0-alpha.21) (2020-01-03)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.20](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.19...@react-navigation/native-stack@5.0.0-alpha.20) (2020-01-01)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.19](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.18...@react-navigation/native-stack@5.0.0-alpha.19) (2019-12-19)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.18](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.17...@react-navigation/native-stack@5.0.0-alpha.18) (2019-12-16)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.17](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.16...@react-navigation/native-stack@5.0.0-alpha.17) (2019-12-14)
### Features
* add custom theme support ([#211](https://github.com/react-navigation/navigation-ex/issues/211)) ([00fc616](https://github.com/react-navigation/navigation-ex/commit/00fc616de0572bade8aa85052cdc8290360b1d7f))
# [5.0.0-alpha.16](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.15...@react-navigation/native-stack@5.0.0-alpha.16) (2019-12-11)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.15](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.14...@react-navigation/native-stack@5.0.0-alpha.15) (2019-12-07)
### Features
* export underlying views used to build navigators ([#191](https://github.com/react-navigation/navigation-ex/issues/191)) ([d618ab3](https://github.com/react-navigation/navigation-ex/commit/d618ab382ecc5eccbcd5faa89e76f9ed2d75f405))
# [5.0.0-alpha.14](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.13...@react-navigation/native-stack@5.0.0-alpha.14) (2019-11-20)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.13](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.12...@react-navigation/native-stack@5.0.0-alpha.13) (2019-11-17)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.12](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.11...@react-navigation/native-stack@5.0.0-alpha.12) (2019-11-10)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.11](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.10...@react-navigation/native-stack@5.0.0-alpha.11) (2019-11-08)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.10](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.9...@react-navigation/native-stack@5.0.0-alpha.10) (2019-11-04)
### Bug Fixes
* popToTop on tab press in native stack ([301c35e](https://github.com/react-navigation/navigation-ex/commit/301c35e))
# [5.0.0-alpha.9](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.8...@react-navigation/native-stack@5.0.0-alpha.9) (2019-11-04)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.8](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.7...@react-navigation/native-stack@5.0.0-alpha.8) (2019-11-02)
### Features
* add headerBackTitleVisible to navigation options in native stack ([77f29d3](https://github.com/react-navigation/navigation-ex/commit/77f29d3))
# [5.0.0-alpha.7](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.6...@react-navigation/native-stack@5.0.0-alpha.7) (2019-11-02)
### Bug Fixes
* remove top margin from screen in native stack on Android ([5cd6940](https://github.com/react-navigation/navigation-ex/commit/5cd6940))
# [5.0.0-alpha.6](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.5...@react-navigation/native-stack@5.0.0-alpha.6) (2019-10-30)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.5](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.4...@react-navigation/native-stack@5.0.0-alpha.5) (2019-10-29)
**Note:** Version bump only for package @react-navigation/native-stack
# [5.0.0-alpha.4](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.3...@react-navigation/native-stack@5.0.0-alpha.4) (2019-10-22)
### Features
* **native-stack:** add support for large title attributes ([#135](https://github.com/react-navigation/navigation-ex/issues/135)) ([6cf1a04](https://github.com/react-navigation/navigation-ex/commit/6cf1a04))
# [5.0.0-alpha.3](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.2...@react-navigation/native-stack@5.0.0-alpha.3) (2019-10-18)
### Bug Fixes
* remove top margin when header is hidden in native stack. fixes [#131](https://github.com/react-navigation/navigation-ex/issues/131) ([fb726ee](https://github.com/react-navigation/navigation-ex/commit/fb726ee))
# [5.0.0-alpha.2](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native-stack@5.0.0-alpha.1...@react-navigation/native-stack@5.0.0-alpha.2) (2019-10-18)
### Bug Fixes
* fix header font size config in native stack ([#128](https://github.com/react-navigation/navigation-ex/issues/128)) ([477c088](https://github.com/react-navigation/navigation-ex/commit/477c088))
# 5.0.0-alpha.1 (2019-10-15)
### Bug Fixes
* increase hitSlop of back button on Android ([c7da1e4](https://github.com/react-navigation/navigation-ex/commit/c7da1e4))
* update supported options for native stack ([b71f4e5](https://github.com/react-navigation/navigation-ex/commit/b71f4e5))
### Features
* initial version of native stack ([#102](https://github.com/react-navigation/navigation-ex/issues/102)) ([ba3f718](https://github.com/react-navigation/navigation-ex/commit/ba3f718))

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017 React Navigation Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,5 +0,0 @@
# `@react-navigation/native-stack`
Stack navigator for React Native using native primitives for navigation. Uses [`react-native-screens`](https://github.com/kmagiera/react-native-screens) under the hood.
Installation instructions and documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/native-stack-navigator.html).

View File

@@ -1,59 +0,0 @@
{
"name": "@react-navigation/native-stack",
"description": "Native stack navigator component for iOS and Android",
"version": "5.0.2",
"keywords": [
"react",
"react-native",
"react-navigation"
],
"license": "MIT",
"repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/native-stack",
"bugs": {
"url": "https://github.com/react-navigation/react-navigation/issues"
},
"homepage": "https://reactnavigation.org/docs/native-stack-navigator.html",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
],
"sideEffects": false,
"publishConfig": {
"access": "public"
},
"scripts": {
"prepare": "bob build",
"clean": "del lib"
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-navigation/native": "^5.0.2",
"del-cli": "^3.0.0",
"react-native-screens": "^2.0.0-beta.2",
"typescript": "^3.7.5"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0",
"react": "*",
"react-native": "*",
"react-native-screens": "^2.0.0-alpha.33"
},
"@react-native-community/bob": {
"source": "src",
"output": "lib",
"targets": [
"commonjs",
"module",
[
"typescript",
{
"project": "tsconfig.build.json"
}
]
]
}
}

View File

@@ -1,17 +0,0 @@
/**
* Navigators
*/
export { default as createNativeStackNavigator } from './navigators/createNativeStackNavigator';
/**
* Views
*/
export { default as NativeStackView } from './views/NativeStackView';
/**
* Types
*/
export {
NativeStackNavigationOptions,
NativeStackNavigationProp,
} from './types';

View File

@@ -1,81 +0,0 @@
import React from 'react';
import {
createNavigatorFactory,
useNavigationBuilder,
EventArg,
StackRouter,
StackNavigationState,
StackRouterOptions,
StackActions,
} from '@react-navigation/native';
import {
screensEnabled,
// eslint-disable-next-line import/no-unresolved
} from 'react-native-screens';
import NativeStackView from '../views/NativeStackView';
import {
NativeStackNavigatorProps,
NativeStackNavigationOptions,
NativeStackNavigationEventMap,
} from '../types';
function NativeStackNavigator(props: NativeStackNavigatorProps) {
if (!screensEnabled()) {
throw new Error(
'Native stack is only available if React Native Screens is enabled.'
);
}
const { initialRouteName, children, screenOptions, ...rest } = props;
const { state, descriptors, navigation } = useNavigationBuilder<
StackNavigationState,
StackRouterOptions,
NativeStackNavigationOptions,
NativeStackNavigationEventMap
>(StackRouter, {
initialRouteName,
children,
screenOptions,
});
React.useEffect(
() =>
navigation.addListener &&
navigation.addListener('tabPress', e => {
const isFocused = navigation.isFocused();
// Run the operation in the next frame so we're sure all listeners have been run
// This is necessary to know if preventDefault() has been called
requestAnimationFrame(() => {
if (
state.index > 0 &&
isFocused &&
!(e as EventArg<'tabPress', true>).defaultPrevented
) {
// When user taps on already focused tab and we're inside the tab,
// reset the stack to replicate native behaviour
navigation.dispatch({
...StackActions.popToTop(),
target: state.key,
});
}
});
}),
[navigation, state.index, state.key]
);
return (
<NativeStackView
{...rest}
state={state}
navigation={navigation}
descriptors={descriptors}
/>
);
}
export default createNavigatorFactory<
NativeStackNavigationOptions,
typeof NativeStackNavigator
>(NativeStackNavigator);

View File

@@ -1,217 +0,0 @@
import * as React from 'react';
import { StyleProp, ViewStyle } from 'react-native';
// eslint-disable-next-line import/no-unresolved
import { ScreenProps } from 'react-native-screens';
import {
DefaultNavigatorOptions,
Descriptor,
NavigationHelpers,
NavigationProp,
ParamListBase,
StackNavigationState,
StackRouterOptions,
} from '@react-navigation/native';
export type NativeStackNavigationEventMap = {
/**
* Event which fires when the screen appears.
*/
appear: { data: undefined };
/**
* Event which fires when the current screen is dismissed by hardware back (on Android) or dismiss gesture (swipe back or down).
*/
dismiss: { data: undefined };
};
export type NativeStackNavigationProp<
ParamList extends ParamListBase,
RouteName extends keyof ParamList = string
> = NavigationProp<
ParamList,
RouteName,
StackNavigationState,
NativeStackNavigationOptions,
NativeStackNavigationEventMap
> & {
/**
* Push a new screen onto the stack.
*
* @param name Name of the route for the tab.
* @param [params] Params object for the route.
*/
push<RouteName extends keyof ParamList>(
...args: ParamList[RouteName] extends undefined | any
? [RouteName] | [RouteName, ParamList[RouteName]]
: [RouteName, ParamList[RouteName]]
): void;
/**
* Pop a screen from the stack.
*/
pop(count?: number): void;
/**
* Pop to the first route in the stack, dismissing all other screens.
*/
popToTop(): void;
};
export type NativeStackNavigationHelpers = NavigationHelpers<
ParamListBase,
NativeStackNavigationEventMap
>;
export type NativeStackNavigationConfig = {};
export type NativeStackNavigationOptions = {
/**
* String that can be displayed in the header as a fallback for `headerTitle`.
*/
title?: string;
/**
* String to display in the header as title. Defaults to scene `title`.
*/
headerTitle?: string;
/**
* Title to display in the back button.
* Only supported on iOS.
*
* @platform ios
*/
headerBackTitle?: string;
/**
* Whether the back button title should be visible or not. Defaults to `true`.
* Only supported on iOS.
*
* @platform ios
*/
headerBackTitleVisible?: boolean;
/**
* Whether to show the header.
*/
headerShown?: boolean;
/**
* Boolean indicating whether the navigation bar is translucent.
* Only supported on iOS.
*
* @platform ios
*/
headerTranslucent?: boolean;
/**
* Boolean to set native property to prefer large title header (like in iOS setting).
* For large title to collapse on scroll, the content of the screen should be wrapped in a scrollable view such as `ScrollView` or `FlatList`.
* If the scrollable area doesn't fill the screen, the large title won't collapse on scroll.
* Only supported on iOS.
*
* @platform ios
*/
headerLargeTitle?: boolean;
/**
* Function which returns a React Element to display on the right side of the header.
*/
headerRight?: () => React.ReactNode;
/**
* Tint color for the header. Changes the color of back button and title.
*/
headerTintColor?: string;
/**
* Boolean indicating whether to hide the back button in header.
* Only supported on Android.
*
* @platform android
*/
headerHideBackButton?: boolean;
/**
* Boolean indicating whether to hide the elevation shadow or the bottom border on the header.
*/
headerHideShadow?: boolean;
/**
* Style object for header title. Supported properties:
* - backgroundColor
*/
headerStyle?: {
backgroundColor?: string;
};
/**
* Style object for header title. Supported properties:
* - fontFamily
* - fontSize
* - color
*/
headerTitleStyle?: {
fontFamily?: string;
fontSize?: number;
color?: string;
};
/**
* Style object for header large title. Supported properties:
* - fontFamily
* - fontSize
*
* Only supported on iOS.
*
* @platform ios
*/
headerLargeTitleStyle?: {
fontFamily?: string;
fontSize?: number;
};
/**
* Style object for header back title. Supported properties:
* - fontFamily
* - fontSize
*
* Only supported on iOS.
*
* @platform ios
*/
headerBackTitleStyle?: {
fontFamily?: string;
fontSize?: number;
};
/**
* Style object for the scene content.
*/
contentStyle?: StyleProp<ViewStyle>;
/**
* Whether you can use gestures to dismiss this screen. Defaults to `true`.
* Only supported on iOS.
*
* @platform ios
*/
gestureEnabled?: boolean;
/**
* How should the screen be presented.
* The following values are currently supported:
* - "push" the new screen will be pushed onto a stack which on iOS means that the default animation will be slide from the side, the animation on Android may vary depending on the OS version and theme.
* - "modal" the new screen will be presented modally. In addition this allow for a nested stack to be rendered inside such screens
* - "transparentModal" the new screen will be presented modally but in addition the second to last screen will remain attached to the stack container such that if the top screen is non opaque the content below can still be seen. If "modal" is used instead the below screen will get unmounted as soon as the transition ends.
*/
stackPresentation?: ScreenProps['stackPresentation'];
/**
* How the screen should appear/disappear when pushed or popped at the top of the stack.
* The following values are currently supported:
* - "default" uses a platform default animation
* - "fade" fades screen in or out
* - "flip" flips the screen, requires stackPresentation: "modal" (iOS only)
* - "none" the screen appears/dissapears without an animation
*/
stackAnimation?: ScreenProps['stackAnimation'];
};
export type NativeStackNavigatorProps = DefaultNavigatorOptions<
NativeStackNavigationOptions
> &
StackRouterOptions &
NativeStackNavigationConfig;
export type NativeStackDescriptor = Descriptor<
ParamListBase,
string,
StackNavigationState,
NativeStackNavigationOptions
>;
export type NativeStackDescriptorMap = {
[key: string]: NativeStackDescriptor;
};

View File

@@ -1,79 +0,0 @@
import * as React from 'react';
import {
ScreenStackHeaderConfig,
ScreenStackHeaderRightView,
// eslint-disable-next-line import/no-unresolved
} from 'react-native-screens';
import { Route, useTheme } from '@react-navigation/native';
import { NativeStackNavigationOptions } from '../types';
type Props = NativeStackNavigationOptions & {
route: Route<string>;
};
export default function HeaderConfig(props: Props) {
const { colors } = useTheme();
const {
route,
title,
headerRight,
headerTitle,
headerBackTitle,
headerBackTitleVisible = true,
headerHideBackButton,
headerHideShadow,
headerTintColor,
headerLargeTitle,
headerTranslucent,
headerStyle = {},
headerTitleStyle = {},
headerLargeTitleStyle = {},
headerBackTitleStyle = {},
headerShown,
gestureEnabled,
} = props;
return (
<ScreenStackHeaderConfig
hidden={headerShown === false}
translucent={headerTranslucent === true}
hideShadow={headerHideShadow}
hideBackButton={headerHideBackButton}
title={
headerTitle !== undefined
? headerTitle
: title !== undefined
? title
: route.name
}
titleFontFamily={headerTitleStyle.fontFamily}
titleFontSize={headerTitleStyle.fontSize}
titleColor={
headerTitleStyle.color !== undefined
? headerTitleStyle.color
: headerTintColor !== undefined
? headerTintColor
: colors.text
}
backTitle={headerBackTitleVisible ? headerBackTitle : ' '}
backTitleFontFamily={headerBackTitleStyle.fontFamily}
backTitleFontSize={headerBackTitleStyle.fontSize}
color={headerTintColor !== undefined ? headerTintColor : colors.primary}
// Keep this temporarily for compatibility with old versions of screens
// @ts-ignore
gestureEnabled={gestureEnabled}
largeTitle={headerLargeTitle}
largeTitleFontFamily={headerLargeTitleStyle.fontFamily}
largeTitleFontSize={headerLargeTitleStyle.fontSize}
backgroundColor={
headerStyle.backgroundColor !== undefined
? headerStyle.backgroundColor
: colors.card
}
>
{headerRight !== undefined ? (
<ScreenStackHeaderRightView>{headerRight()}</ScreenStackHeaderRightView>
) : null}
</ScreenStackHeaderConfig>
);
}

View File

@@ -1,93 +0,0 @@
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import {
ScreenStack,
Screen as ScreenComponent,
ScreenProps,
// eslint-disable-next-line import/no-unresolved
} from 'react-native-screens';
import {
StackNavigationState,
StackActions,
useTheme,
} from '@react-navigation/native';
import HeaderConfig from './HeaderConfig';
import {
NativeStackNavigationHelpers,
NativeStackDescriptorMap,
} from '../types';
const Screen = (ScreenComponent as unknown) as React.ComponentType<ScreenProps>;
type Props = {
state: StackNavigationState;
navigation: NativeStackNavigationHelpers;
descriptors: NativeStackDescriptorMap;
};
export default function NativeStackView({
state,
navigation,
descriptors,
}: Props) {
const { colors } = useTheme();
return (
<ScreenStack style={styles.container}>
{state.routes.map(route => {
const { options, render: renderScene } = descriptors[route.key];
const {
gestureEnabled,
stackPresentation = 'push',
stackAnimation,
contentStyle,
} = options;
return (
<Screen
key={route.key}
style={StyleSheet.absoluteFill}
gestureEnabled={gestureEnabled}
stackPresentation={stackPresentation}
stackAnimation={stackAnimation}
onAppear={() => {
navigation.emit({
type: 'appear',
target: route.key,
});
}}
onDismissed={() => {
navigation.emit({
type: 'dismiss',
target: route.key,
});
navigation.dispatch({
...StackActions.pop(),
source: route.key,
target: state.key,
});
}}
>
<HeaderConfig {...options} route={route} />
<View
style={[
styles.container,
{ backgroundColor: colors.background },
contentStyle,
]}
>
{renderScene()}
</View>
</Screen>
);
})}
</ScreenStack>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});

View File

@@ -1,6 +0,0 @@
{
"extends": "./tsconfig",
"compilerOptions": {
"paths": {}
}
}

View File

@@ -1,11 +0,0 @@
{
"extends": "../../tsconfig",
"references": [
{ "path": "../core" },
{ "path": "../routers" },
{ "path": "../native" }
],
"compilerOptions": {
"outDir": "./lib/typescript"
}
}

View File

@@ -3,6 +3,46 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.7](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.0.6...@react-navigation/native@5.0.7) (2020-02-21)
**Note:** Version bump only for package @react-navigation/native
## [5.0.6](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.0.5...@react-navigation/native@5.0.6) (2020-02-19)
**Note:** Version bump only for package @react-navigation/native
## [5.0.5](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.0.4...@react-navigation/native@5.0.5) (2020-02-14)
**Note:** Version bump only for package @react-navigation/native
## [5.0.4](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.0.3...@react-navigation/native@5.0.4) (2020-02-14)
**Note:** Version bump only for package @react-navigation/native
## [5.0.3](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.0.2...@react-navigation/native@5.0.3) (2020-02-12)
**Note:** Version bump only for package @react-navigation/native
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.0.1...@react-navigation/native@5.0.2) (2020-02-11)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/native",
"description": "React Native integration for React Navigation",
"version": "5.0.2",
"version": "5.0.7",
"keywords": [
"react-native",
"react-navigation",
@@ -31,7 +31,7 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/core": "^5.1.1"
"@react-navigation/core": "^5.1.6"
},
"devDependencies": {
"@react-native-community/bob": "^0.9.3",

View File

@@ -76,10 +76,10 @@ export default function useLinking(
if (state) {
const action = getActionFromState(state);
if (action.type === 'RESET_ROOT') {
navigation.resetRoot(action.payload);
} else {
if (action !== undefined) {
navigation.dispatch(action);
} else {
navigation.resetRoot(state);
}
}
}

View File

@@ -162,10 +162,10 @@ export default function useLinking(
pendingStateUpdateRef.current = true;
if (action.type === 'RESET_ROOT') {
navigation.resetRoot(action.payload);
} else {
if (action !== undefined) {
navigation.dispatch(action);
} else {
navigation.resetRoot(state);
}
}
}

View File

@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.0.1...@react-navigation/routers@5.0.2) (2020-02-21)
### Bug Fixes
* tweak error message for navigate ([c8ea419](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/commit/c8ea4199f4b19a58d5e409cfcc96e587fe354a9a))
## [5.0.1](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.0.0-alpha.33...@react-navigation/routers@5.0.1) (2020-02-10)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/routers",
"description": "Routers to help build custom navigators",
"version": "5.0.1",
"version": "5.0.2",
"keywords": [
"react",
"react-native",

View File

@@ -45,7 +45,7 @@ export function navigate(...args: any): Action {
if (!payload.hasOwnProperty('key') && !payload.hasOwnProperty('name')) {
throw new Error(
'While calling navigate with an object as the argument, you need to specify name or key'
'You need to specify name or key when calling navigate with an object as the argument. See https://reactnavigation.org/docs/navigation-actions.html#navigate for usage.'
);
}

View File

@@ -3,6 +3,6 @@ import * as CommonActions from '../CommonActions';
it('throws if NAVIGATE is called without key or name', () => {
// @ts-ignore
expect(() => CommonActions.navigate({})).toThrowError(
'While calling navigate with an object as the argument, you need to specify name or key'
'You need to specify name or key when calling navigate with an object as the argument.'
);
});

View File

@@ -3,6 +3,70 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.0.8](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.0.7...@react-navigation/stack@5.0.8) (2020-02-21)
### Bug Fixes
* fix transparent header on Android ([a67b494](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/a67b49477eb500c81fedcd73bbd8102901a95170))
## [5.0.7](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.0.6...@react-navigation/stack@5.0.7) (2020-02-21)
### Bug Fixes
* debounce back button by default in stack header ([c7dd3a5](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/c7dd3a58b18d7a267d94009d459944c251ea74c1))
* make sure header is visibile to accessibility tools on iOS ([240ce01](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/240ce01822febac2c1aa324c01e43fdc88a235a0))
## [5.0.6](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.0.5...@react-navigation/stack@5.0.6) (2020-02-19)
### Bug Fixes
* add accessibilityLabel prop to back button ([bf76075](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/bf76075e0fbf51961e81e9337ef194e43cc6b986)), closes [#6895](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/6895)
## [5.0.5](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.0.4...@react-navigation/stack@5.0.5) (2020-02-14)
**Note:** Version bump only for package @react-navigation/stack
## [5.0.4](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.0.3...@react-navigation/stack@5.0.4) (2020-02-14)
### Bug Fixes
* hard code header height for animation ([8f40a98](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/8f40a980862a182a9e86dbb1e4764a39d824cd70)), closes [#6818](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/6818)
## [5.0.3](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.0.2...@react-navigation/stack@5.0.3) (2020-02-12)
### Bug Fixes
* check if we can go baack before dispatching pop ([6c9447a](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/6c9447a38c74ca029fc9def8aca0a2d2cca9639c))
## [5.0.2](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.0.1...@react-navigation/stack@5.0.2) (2020-02-11)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/stack",
"description": "Stack navigator component for iOS and Android with animated transitions and gestures",
"version": "5.0.2",
"version": "5.0.8",
"keywords": [
"react-native-component",
"react-component",
@@ -40,7 +40,7 @@
"devDependencies": {
"@react-native-community/bob": "^0.9.3",
"@react-native-community/masked-view": "^0.1.6",
"@react-navigation/native": "^5.0.2",
"@react-navigation/native": "^5.0.7",
"@types/color": "^3.0.1",
"@types/react": "^16.9.19",
"@types/react-native": "^0.60.30",
@@ -53,13 +53,13 @@
"typescript": "^3.7.5"
},
"peerDependencies": {
"@react-native-community/masked-view": "^0.1.1",
"@react-navigation/native": "^5.0.0",
"@react-native-community/masked-view": ">= 0.1.0",
"@react-navigation/native": "^5.0.5",
"react": "*",
"react-native": "*",
"react-native-gesture-handler": "^1.0.0",
"react-native-safe-area-context": "^0.6.0",
"react-native-screens": "^2.0.0-alpha.33"
"react-native-gesture-handler": ">= 1.0.0",
"react-native-safe-area-context": ">= 0.6.0",
"react-native-screens": ">= 2.0.0-alpha.0 || >= 2.0.0-beta.0"
},
"@react-native-community/bob": {
"source": "src",

View File

@@ -230,6 +230,7 @@ export function forSlideRight({
export function forSlideUp({
current,
next,
layouts: { header },
}: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
const progress = add(
current.progress.interpolate({
@@ -248,7 +249,7 @@ export function forSlideUp({
const translateY = progress.interpolate({
inputRange: [0, 1, 2],
outputRange: ['-100%', '0%', '-100%'],
outputRange: [-header.height, 0, -header.height],
});
const transform = [{ translateY }];

View File

@@ -404,6 +404,10 @@ export type StackHeaderLeftButtonProps = {
* Whether it's possible to navigate back in stack.
*/
canGoBack?: boolean;
/**
* Accessibility label for the button for screen readers.
*/
accessibilityLabel?: string;
};
export type StackHeaderTitleProps = {
@@ -548,6 +552,10 @@ export type StackHeaderInterpolationProps = {
* Layout measurements for various items we use for animation.
*/
layouts: {
/**
* Layout of the header
*/
header: Layout;
/**
* Layout of the whole screen.
*/

View File

@@ -0,0 +1,17 @@
export default function debounce<T extends (...args: any[]) => void>(
func: T,
duration: number
): T {
let timeout: NodeJS.Timeout | number | undefined;
return function(this: any, ...args) {
if (!timeout) {
// eslint-disable-next-line babel/no-invalid-this
func.apply(this, args);
timeout = setTimeout(() => {
timeout = undefined;
}, duration);
}
} as T;
}

View File

@@ -2,8 +2,9 @@ import * as React from 'react';
import { StackActions } from '@react-navigation/native';
import HeaderSegment from './HeaderSegment';
import { StackHeaderProps, StackHeaderTitleProps } from '../../types';
import HeaderTitle from './HeaderTitle';
import debounce from '../../utils/debounce';
import { StackHeaderProps, StackHeaderTitleProps } from '../../types';
export default React.memo(function Header(props: StackHeaderProps) {
const {
@@ -40,6 +41,18 @@ export default React.memo(function Header(props: StackHeaderProps) {
: previous.route.name;
}
const goBack = React.useCallback(
debounce(() => {
if (navigation.canGoBack()) {
navigation.dispatch({
...StackActions.pop(),
source: scene.route.key,
});
}
}, 50),
[navigation, scene.route.key]
);
return (
<HeaderSegment
{...options}
@@ -53,15 +66,7 @@ export default React.memo(function Header(props: StackHeaderProps) {
? (props: StackHeaderTitleProps) => <HeaderTitle {...props} />
: options.headerTitle
}
onGoBack={
previous
? () =>
navigation.dispatch({
...StackActions.pop(),
source: scene.route.key,
})
: undefined
}
onGoBack={previous ? goBack : undefined}
styleInterpolator={styleInterpolator}
/>
);

View File

@@ -29,6 +29,7 @@ export default function HeaderBackButton({
tintColor: customTintColor,
titleLayout,
truncatedLabel = 'Back',
accessibilityLabel = label && label !== 'Back' ? `${label}, back` : 'Go back',
}: Props) {
const { dark, colors } = useTheme();
@@ -153,9 +154,7 @@ export default function HeaderBackButton({
accessible
accessibilityRole="button"
accessibilityComponentType="button"
accessibilityLabel={
label && label !== 'Back' ? `${label}, back` : 'Go back'
}
accessibilityLabel={accessibilityLabel}
accessibilityTraits="button"
testID="header-back"
delayPressIn={0}

View File

@@ -137,7 +137,9 @@ export default function HeaderContainer({
isFocused ? 'auto' : 'no-hide-descendants'
}
style={
mode === 'float' || options.headerTransparent
// Avoid positioning the focused header absolutely
// Otherwise accessibility tools don't seem to be able to find it
(mode === 'float' && !isFocused) || options.headerTransparent
? styles.header
: null
}

View File

@@ -56,7 +56,7 @@ const warnIfHeaderStylesDefined = (styles: Record<string, any>) => {
export const getDefaultHeaderHeight = (
layout: Layout,
statusBarHeight: number
) => {
): number => {
const isLandscape = layout.width > layout.height;
let headerHeight;
@@ -120,12 +120,17 @@ export default class HeaderSegment extends React.Component<Props, State> {
current: Animated.AnimatedInterpolation,
next: Animated.AnimatedInterpolation | undefined,
titleLayout: Layout | undefined,
leftLabelLayout: Layout | undefined
leftLabelLayout: Layout | undefined,
headerHeight: number
) =>
styleInterpolator({
current: { progress: current },
next: next && { progress: next },
layouts: {
header: {
height: headerHeight,
width: layout.width,
},
screen: layout,
title: titleLayout,
leftLabel: leftLabelLayout,
@@ -172,23 +177,10 @@ export default class HeaderSegment extends React.Component<Props, State> {
const { leftLabelLayout, titleLayout } = this.state;
const {
titleStyle,
leftButtonStyle,
leftLabelStyle,
rightButtonStyle,
backgroundStyle,
} = this.getInterpolatedStyle(
styleInterpolator,
layout,
scene.progress.current,
scene.progress.next,
titleLayout,
previousTitle ? leftLabelLayout : undefined
);
const defaultHeight = getDefaultHeaderHeight(layout, headerStatusBarHeight);
const {
height = getDefaultHeaderHeight(layout, headerStatusBarHeight),
height = defaultHeight,
minHeight,
maxHeight,
backgroundColor,
@@ -281,6 +273,22 @@ export default class HeaderSegment extends React.Component<Props, State> {
}
}
const {
titleStyle,
leftButtonStyle,
leftLabelStyle,
rightButtonStyle,
backgroundStyle,
} = this.getInterpolatedStyle(
styleInterpolator,
layout,
scene.progress.current,
scene.progress.next,
titleLayout,
previousTitle ? leftLabelLayout : undefined,
typeof height === 'number' ? height : defaultHeight
);
const leftButton = left
? left({
backImage,