Compare commits

..

35 Commits

Author SHA1 Message Date
Satyajit Sahoo
536225c2c3 chore: publish
- @react-navigation/bottom-tabs@5.0.0-alpha.35
 - @react-navigation/compat@5.0.0-alpha.24
 - @react-navigation/core@5.0.0-alpha.33
 - @react-navigation/drawer@5.0.0-alpha.37
 - @react-navigation/material-bottom-tabs@5.0.0-alpha.32
 - @react-navigation/material-top-tabs@5.0.0-alpha.31
 - @react-navigation/native-stack@5.0.0-alpha.25
 - @react-navigation/native@5.0.0-alpha.25
 - @react-navigation/routers@5.0.0-alpha.23
 - @react-navigation/stack@5.0.0-alpha.59
2020-01-13 14:37:49 +01:00
Satyajit Sahoo
23f76189a4 refactor: rename forStatic to forSlide for header 2020-01-13 00:54:05 +01:00
Satyajit Sahoo
f1f5b7197c chore: use project references for typescript 2020-01-12 09:26:50 +01:00
Satyajit Sahoo
324fad33ef chore: add some comments to metro config 2020-01-12 02:56:22 +01:00
Satyajit Sahoo
d14c471385 docs: add instructions for forks 2020-01-12 01:23:16 +01:00
Satyajit Sahoo
7113540127 chore: remove workflow for detox for now 2020-01-11 16:58:25 +01:00
Satyajit Sahoo
a23dfd419d chore: remove nohoist from example 2020-01-10 13:12:32 +01:00
Satyajit Sahoo
e6fade010b chore: publish
- @react-navigation/material-top-tabs@5.0.0-alpha.30
2020-01-09 17:13:00 +01:00
Satyajit Sahoo
beb9a151f0 chore: add troubleshooting link 2020-01-09 17:12:01 +01:00
Satyajit Sahoo
c814636061 refactor: remove tabBarVisible from material-top-tabs 2020-01-09 17:09:41 +01:00
Satyajit Sahoo
bfb28599fb chore: publish
- @react-navigation/bottom-tabs@5.0.0-alpha.34
 - @react-navigation/compat@5.0.0-alpha.23
 - @react-navigation/core@5.0.0-alpha.32
 - @react-navigation/drawer@5.0.0-alpha.36
 - @react-navigation/material-bottom-tabs@5.0.0-alpha.31
 - @react-navigation/material-top-tabs@5.0.0-alpha.29
 - @react-navigation/native-stack@5.0.0-alpha.24
 - @react-navigation/native@5.0.0-alpha.24
 - @react-navigation/routers@5.0.0-alpha.22
 - @react-navigation/stack@5.0.0-alpha.58
2020-01-09 03:03:45 +01:00
Satyajit Sahoo
37d26ca994 fix: change default screen change animation on web 2020-01-09 02:59:36 +01:00
Satyajit Sahoo
5470aeaca2 fix: don't add header animation if mode is not float 2020-01-09 02:54:01 +01:00
Satyajit Sahoo
011dabf919 chore: upgrade depenendecies 2020-01-09 02:50:48 +01:00
Satyajit Sahoo
d077388b5f chore: add link to the docs in READMEs 2020-01-09 01:48:32 +01:00
Satyajit Sahoo
3bdbd89515 chore: update repo url for packages
npm only shows correct link if we use the link directly instead of repo metadata
2020-01-09 01:39:48 +01:00
Satyajit Sahoo
67798af869 fix: clamp interpolated styles 2020-01-09 01:27:19 +01:00
Satyajit Sahoo
32ffaac647 fix: only render last 3 headers in stack 2020-01-09 01:10:44 +01:00
Satyajit Sahoo
7a3d652e84 fix: change POP behaviour to remove elements from index only
Fixes #256
2020-01-09 01:06:55 +01:00
Satyajit Sahoo
14cd7de665 chore: update issue templates 2020-01-07 20:07:06 +01:00
osdnk
da9948bfd8 chore: publish
- @react-navigation/stack@5.0.0-alpha.56
2020-01-07 06:57:09 -05:00
Michał Osadnik
d3f5c55dbf fix: remove clamping in extrapolation of progress of stack animation 2020-01-07 06:46:29 -05:00
Satyajit Sahoo
f91d16cd5d chore: update readme 2020-01-07 05:14:04 +01:00
Satyajit Sahoo
fbadea46f1 chore: setup detox for iOS 2020-01-07 05:14:04 +01:00
Satyajit Sahoo
5614a7cd31 chore: publish
- @react-navigation/stack@5.0.0-alpha.55
2020-01-06 19:31:30 +01:00
Satyajit Sahoo
d8b88bd83f fix: memoize interpolated style to avoid extra work 2020-01-05 17:25:27 +01:00
Satyajit Sahoo
d6d06d07d9 chore: publish
- @react-navigation/stack@5.0.0-alpha.54
2020-01-05 15:31:25 +01:00
Satyajit Sahoo
65ce20ecbc fix: use memo for card container 2020-01-05 15:29:41 +01:00
Satyajit Sahoo
12d90833eb fix: expose the header height even if not floating 2020-01-05 15:10:05 +01:00
Satyajit Sahoo
edeb2e8ad9 chore: publish
- @react-navigation/stack@5.0.0-alpha.53
2020-01-05 14:29:27 +01:00
Satyajit Sahoo
133b59cd17 feat: expose header height in context 2020-01-05 14:26:16 +01:00
Satyajit Sahoo
a9e584c3b7 fix: compare with correct height when floating header height updates 2020-01-05 13:58:24 +01:00
Satyajit Sahoo
c46e0a9c14 chore: validate path to type definitions on CI 2020-01-05 13:11:08 +01:00
Satyajit Sahoo
418a858f23 chore: publish
- @react-navigation/stack@5.0.0-alpha.52
2020-01-05 02:31:09 +01:00
Satyajit Sahoo
b201fd2071 feat: add headerStatusBarHeight option to stack 2020-01-05 02:30:09 +01:00
94 changed files with 3291 additions and 2352 deletions

View File

@@ -49,6 +49,7 @@ jobs:
at: ~/project
- run: |
yarn lerna run prepare
node scripts/check-types-path.js
workflows:
version: 2

View File

@@ -1,40 +0,0 @@
## The issue tracker is reserved for bug reports only.
If you have a question, feature request, or an idea for improving the library or its related tools, please try one of the following resources:
- [Read the documentation](https://reactnavigation.org/)
- [Post an issue to the website repository if you'd like to see a documentation change](http://github.com/react-navigation/website)
- [Post a feature request to Canny](https://react-navigation.canny.io/feature-requests)
- [Write a RFC if you have ideas for how to implement a feature request](https://github.com/react-navigation/rfcs)
- [Get help on Discord chat (#react-navigation on Reactiflux)](https://discord.gg/4xEK3nD) or [on StackOverflow](https://stackoverflow.com/questions/tagged/react-navigation)
- Search for your issue - it may have already been answered or even fixed in the development branch. However, if you find that an old, closed issue still persists in the latest version, you should open a new issue.
Bugs with react-navigation must be reproducible *without any external libraries that operate on it*. This means that if you are attempting to use Redux or MobX with it and you think you have found a bug, you must be able to reproduce it without Redux or MobX in this report.
---
### Current Behavior
- What code are you running and what is happening?
- Include a screenshot if it makes sense.
### Expected Behavior
- What do you expect should be happening?
- Include a screenshot 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.
### Your Environment
| software | version
| ---------------- | -------
| react-navigation |
| react-native |
| expo |
| node |
| npm or yarn |

View File

@@ -0,0 +1,38 @@
---
name: Bottom Tab Navigator
about: Report an issue with Bottom Tab Navigator (@react-navigation/bottom-tabs)
title: ''
labels: bug, package:bottom-tabs
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/bottom-tabs |
| react-native-screens |
| react-native |
| expo |
| node |
| npm or yarn |

View File

@@ -0,0 +1,41 @@
---
name: Drawer Navigator
about: Report an issue with Drawer Navigator (@react-navigation/drawer)
title: ''
labels: bug, package:drawer
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/drawer |
| react-native-reanimated |
| react-native-gesture-handler |
| react-native-safe-area-context |
| react-native-screens |
| react-native |
| expo |
| node |
| npm or yarn |

View File

@@ -0,0 +1,38 @@
---
name: Material Bottom Tab Navigator
about: Report an issue with Material Bottom Tab Navigator (@react-navigation/material-bottom-tabs)
title: ''
labels: bug, package:material-bottom-tabs
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/material-bottom-tabs |
| react-native-paper |
| react-native |
| expo |
| node |
| npm or yarn |

View File

@@ -0,0 +1,38 @@
---
name: Material Top Tab Navigator
about: Report an issue with Material Top Tab Navigator (@react-navigation/material-top-tabs)
title: ''
labels: bug, package:material-top-tabs
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/material-top-tabs |
| react-native-tab-view |
| react-native |
| expo |
| node |
| npm or yarn |

View File

@@ -0,0 +1,38 @@
---
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 |

View File

@@ -0,0 +1,40 @@
---
name: Stack Navigator
about: Report an issue with Stack Navigator (@react-navigation/stack)
title: ''
labels: bug, package: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/stack |
| react-native-gesture-handler |
| react-native-safe-area-context |
| react-native-screens |
| react-native |
| expo |
| node |
| npm or yarn |

36
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@@ -0,0 +1,36 @@
---
name: Other bugs
about: Report an issue which is not about a specific navigator.
title: ''
labels: bug
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-native |
| expo |
| node |
| npm or yarn |

20
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
blank_issues_enabled: false
contact_links:
- name: Troubleshooting
url: https://reactnavigation.org/docs/en/next/troubleshooting.html
about: Read how to troubleshoot and fix common issues and mistakes.
- name: Documentation
url: https://next.reactnavigation.org
about: Read the official documentation.
- name: Feature requests
url: https://react-navigation.canny.io/feature-requests
about: Post a feature request on Canny.
- name: StackOverflow
url: https://stackoverflow.com/questions/tagged/react-navigation
about: Ask and answer questions using the react-navigation label.
- name: Reactiflux
url: https://www.reactiflux.com/
about: Chat with other community members in the react-navigation channel.
- name: Write an RFC
url: https://github.com/react-navigation/rfcs
about: Write a RFC if you have ideas for how to implement a feature request.

View File

@@ -1,10 +1,10 @@
Please provide enough information so that others can review your pull request:
## Motivation
**Motivation**
Explain the **motivation** for making this change. What existing problem does the pull request solve?
## Test plan
**Test plan**
Demonstrate the code is solid. Example: the exact commands you ran and their output, screenshots / videos if the pull request changes UI.
@@ -12,6 +12,6 @@ Make sure you test on both platforms if your change affects both platforms.
The code must pass tests.
## Code formatting
**Code formatting**
Look around. Match the style of the rest of the codebase. Run `yarn lint --fix` before committing.

545
README.md
View File

@@ -1,496 +1,12 @@
# Rethinking Navigation
# React Navigation 5
[![Build Status][build-badge]][build]
[![Code Coverage][coverage-badge]][coverage]
[![MIT License][license-badge]][license]
An exploration of a component-first API for React Navigation for building more dynamic navigation solutions.
Routing and navigation for your React Native apps with a component-first API.
## Considerations
- Should play well with static type system
- Navigation state should be contained in root component (helpful for stuff such as deep linking)
- Component-first API
## Building blocks
### `NavigationContainer`
Component which wraps the whole app. It stores the state for the whole navigation tree.
### `useNavigationBuilder`
Hook which can access the navigation state from the context. Along with the state, it also provides some helpers to modify the navigation state provided by the router. All state changes are notified to the parent `NavigationContainer`.
### Router
The router object provides various helper methods to deal with the state and actions, a reducer to update the state as well as some action creators.
The router is responsible for handling actions dispatched by calling methods on the `navigation` object. If the router cannot handle an action, it can return `null`, which would propagate the action to other routers until it's handled.
### Navigator
Navigators bundle a router and a view which takes the navigation state and decides how to render it.
A simple navigator could look like this:
```js
import { createNavigatorFactory } from '@react-navigation/native';
function StackNavigator({ initialRouteName, children, ...rest }) {
// The `navigation` object contains the navigation state and some helpers (e.g. push, pop)
// The `descriptors` object contains the screen options and a helper for rendering a screen
const { state, navigation, descriptors } = useNavigationBuilder(StackRouter, {
initialRouteName,
children,
});
return (
// The view determines how to animate any state changes
<StackView
state={state}
navigation={navigation}
descriptors={descriptors}
{...rest}
/>
);
}
export default createNavigatorFactory(StackNavigator);
```
The navigator can render a screen by calling `descriptors[route.key].render()`. Internally, the descriptor adds appropriate wrappers to handle nested state.
## Architectural differences
### Shape of the navigation state
The shape of the navigation state looks very similar to the current implementation. There are few important differences:
- The name of the route is in the `route.name` property instead of `route.routeName`.
- The state of the child navigator exists on a separate property `route.state`.
- The state object contains a `routeNames` property which contains the list of defined route names in an array of strings,
Example:
```js
{
index: 0,
key: 'stack-ytwk65',
routeNames: ['home', 'profile', 'settings'],
routes: [
{
key: 'home-hjds3b',
name: 'home',
state: {
index: 1,
key: 'tab-jhsf6g',
routeNames: ['feed', 'recommended'],
routes: [
{
key: 'feed-jv2iud',
name: 'feed',
},
{
key: 'recommended-njdh63',
name: 'recommended',
},
],
},
},
],
}
```
### Deriving initial state
In the current implementation of React Navigation, the initial state is extracted from the navigator definitions. This is possible because they are defined statically. In our case, it's not possible because the screens are rendered dynamically.
Turns out we don't really need the initial state in the `NavigationContainer`. This state is the default state, so we can store `undefined` instead, and let the navigators initialize their initial state themselves. Next time an action modifies the state, we update the value in the container.
If an initial state is specified, e.g. as a result of `Linking.getInitialURL()`, the child navigators will use that state, instead of having to initialize it themselves.
### Passing state to child navigator
Navigation state is exposed to children navigators via React context instead of having to pass it down manually. This lets the user nest navigators freely without having to worry about properly passing the state down.
### Accessing state of other navigators
Navigators should not access the state of other navigators. It might be tempting to access the state of a child route to perform some checks, but it's not going to work correctly, as the state object may not exist yet.
Instead of direct state access, navigators should communicate via events. Each navigator should access and modify its own state only.
### Bubbling of actions
In the current implementation of React Navigation, routers manually call the child routers to apply any actions. Since we have a component based architecture, this is not really possible.
Instead, we use an event based system. Child navigators can add listeners to handle actions. If the parent couldn't handle the action, it'll call the listeners. The event system is built into the core and the routers don't need to worry about it.
When an action can be bubble, the `getStateForAction` method from a router should return `null`, otherwise it should return the state object.
It's also possible to disable bubbling of actions when dispatching them by adding a `target` key in the action. The `target` key should refer to the key of the navigator that should handle the action.
## Basic usage
```js
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="home">
<Stack.Screen name="settings" component={Settings} />
<Stack.Screen
name="profile"
component={Profile}
options={{ title: 'John Doe' }}
/>
<Stack.Screen name="home">
{() => (
<Tab.Navigator initialRouteName="feed">
<Tab.Screen name="feed" component={Feed} />
<Tab.Screen name="article" component={Article} />
<Tab.Screen name="notifications">
{props => <Notifications {...props} />}
</Tab.Screen>
</Tab.Navigator>
)}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
);
}
```
Navigators need to have `Screen` components as their direct children. These components don't do anything by themselves, but the navigator can extract information from these and determine what to render. Implementation-wise, we use `React.Children` API for this purpose.
The content to render can be specified in 2 ways:
1. React component in `component` prop (recommended)
2. Render callback as children
When a React component is specified, the navigator takes care of adding a `React.memo` to prevent unnecessary re-renders. However, it's not possible to pass extra props to the component this way. It's preferable to use the context API for such cases instead of props.
A render callback which doesn't have such limitation and is easier to use for this purpose. However, performance optimization for the component is left to the user in such case.
The rendered component will receives a `navigation` prop with various helpers and a `route` prop which represents the route being rendered.
## Setting screen options
In React Navigation, screen options can be specified in a static property on the component (`navigationOptions`). This poses few issues:
- It's not possible to configure options based on props, state or context
- To update the props based on an action in the component (such as button press), we need to do it in a hacky way by changing params
- It breaks when used with HOCs which don't hoist static props, which is a common source of confusion
Instead of a static property, we expose a method to configure screen options:
```js
function Selection({ navigation }) {
const [selectedIds, setSelectedIds] = React.useState([]);
navigation.setOptions({
title: `${selectedIds.length} items selected`,
});
return <SelectionList onSelect={id => setSelectedIds(ids => [...ids, id])} />;
}
```
This allows options to be changed based on props, state or context, and doesn't have the disadvantages of static configuration.
## Navigation events
Screens can add listeners on the `navigation` prop like in React Navigation. By default, `focus` and `blur` events are fired when focused screen changes:
```js
function Profile({ navigation }) {
React.useEffect(() =>
navigation.addListener('focus', () => {
// do something
})
);
return <ProfileContent />;
}
```
The `navigation.addListener` method returns a function to remove the listener which can be returned as the cleanup function in an effect.
Navigators can also emit custom events using the `emit` method in the `navigation` object passed:
```js
navigation.emit({
type: 'transitionStart',
data: { blurring: false },
target: route.key,
});
```
The `data` is available under the `data` property in the `event` object, i.e. `event.data`.
The `target` property determines the screen that will receive the event. If the `target` property is omitted, the event is dispatched to all screens in the navigator.
Screens cannot emit events as there is no `emit` method on a screen's `navigation` prop.
If you don't need to get notified of focus change, but just need to check if the screen is currently focused in a callback, you can use the `navigation.isFocused()` method which returns a boolean. Note that it's not safe to use this in `render`. Only use it in callbacks, event listeners etc.
## Additional utilities
### Access navigation anywhere
Passing the `navigation` prop down can be tedious. The library exports a `useNavigation` hook which can access the `navigation` prop from the parent screen:
```js
const navigation = useNavigation();
```
### Side-effects in focused screen
Sometimes we want to run side-effects when a screen is focused. A side effect may involve things like adding an event listener, fetching data, updating document title, etc. While this can be achieved using `focus` and `blur` events, it's not very ergonomic.
To make this easier, the library exports a `useFocusEffect` hook:
```js
import { useFocusEffect } from '@react-navigation/native';
function Profile({ userId }) {
const [user, setUser] = React.useState(null);
const fetchUser = React.useCallback(() => {
const request = API.fetchUser(userId).then(
data => setUser(data),
error => alert(error.message)
);
return () => request.abort();
}, [userId]);
useFocusEffect(fetchUser);
return <ProfileContent user={user} />;
}
```
The `useFocusEffect` is analogous to React's `useEffect` hook. The only difference is that it runs on focus instead of render.
**NOTE:** To avoid the running the effect too often, it's important to wrap the callback in `useCallback` before passing it to `useFocusEffect` as shown in the example.
### Render based on focus state
We might want to render different content based on the current focus state of the screen. The library exports a `useIsFocused` hook to make this easier:
```js
import { useIsFocused } from '@react-navigation/native';
// ...
const isFocused = useIsFocused();
```
## React Native
For proper UX in React Native, we need to respect platform behavior such as the device back button on Android, deep linking etc. The library exports few hooks to make it easier.
### Back button integration
When the back button on the device is pressed, we also want to navigate back in the focused navigator. The library exports a `useBackButton` hook to handle this:
```js
import { useBackButton } from '@react-navigation/native';
// ...
const ref = React.useRef();
useBackButton(ref);
return <NavigationContainer ref={ref}>{/* content */}</NavigationContainer>;
```
### Scroll to top on tab button press
When there's a scroll view in a tab and the user taps on the already focused tab bar again, we might want to scroll to top in our scroll view. The library exports a `useScrollToTop` hook to handle this:
```js
import { useScrollToTop } from '@react-navigation/native';
// ...
const ref = React.useRef();
useScrollToTop(ref);
return <ScrollView ref={ref}>{/* content */}</ScrollView>;
```
The hook can accept a ref object to any view that has a `scrollTo` method.
### Deep-link integration
To handle incoming links, we need to handle 2 scenarios:
1. If the app wasn't previously open, we need to set the initial state based on the link
2. If the app was already open, we need to update the state to reflect the incoming link
The current implementation of React Navigation has an advantage in handling deep links and is able to automatically set the state based on the path definitions for each screen. It's possible because it can get the configuration for all screens statically.
With our dynamic architecture, we can't determine the state automatically. So it's necessary to manually translate a deep link to a navigation state. The library exports a `getStateFromPath` utility to convert a URL to a state object if the path segments translate directly to route names.
For example, the path `/rooms/chat?user=jane` will be translated to a state object like this:
```js
{
routes: [
{
name: 'rooms',
state: {
routes: [
{
name: 'chat',
params: { user: 'jane' },
},
],
},
},
],
}
```
The `useLinking` hooks makes it easier to handle incoming links:
```js
import { useLinking } from '@react-navigation/native';
// ...
const ref = React.useRef();
const { getInitialState } = useLinking(ref, {
prefixes: ['https://myapp.com', 'myapp://'],
});
const [isReady, setIsReady] = React.useState(false);
const [initialState, setInitialState] = React.useState();
React.useEffect(() => {
getInitialState()
.catch(() => {})
.then(state => {
if (state !== undefined) {
setInitialState(state);
}
setIsReady(true);
});
}, [getInitialState]);
if (!isReady) {
return null;
}
return (
<NavigationContainer initialState={initialState} ref={ref}>
{/* content */}
</NavigationContainer>
);
```
The hook also accepts a `getStateFromPath` option where you can provide a custom function to convert the URL to a valid state object for more advanced use cases.
## Type-checking
The library is written with TypeScript and provides type definitions for TypeScript projects.
When building custom navigators, each navigator also need to export a custom type for the `navigation` prop which should contain the actions they provide, .e.g. `push` for stack, `jumpTo` for tab etc. and pass correct type parameters to the helper functions to ensure that it works well with type-checking.
Currently type checking and intelliSense works for route name and params. The user has to define a type alias with a list of routes along with the type of params they use.
For our example above, we need 2 separate types for stack and tabs:
```ts
type StackParamList = {
settings: undefined;
profile: { userId: string };
home: undefined;
};
type TabParamList = {
feed: undefined;
article: undefined;
notifications: undefined;
};
```
In a component, it's possible to annotate the `navigation` and `route` props using these types:
```ts
type Props = {
navigation: StackNavigationProp<StackParamList, 'profile'>;
route: RouteProp<StackParamList, 'profile'>;
};
function Profile(props: Props) {
// Content
}
```
Annotating the `navigation` prop will be enough for provide type-checking for actions such as `navigate` etc. Annotating `route` will provide type-checking for accessing `params` for the current route.
For nested navigators, the `navigation` prop is a combination of multiple `navigation` props, so we need to combine multiple types to type them. We export a type called `CompositeNavigationProp` to make it easier:
```ts
type FeedScreenNavigationProp = CompositeNavigationProp<
TabNavigationProp<TabParamList, 'feed'>,
StackNavigationProp<StackParamList>
>;
```
The `CompositeNavigationProp` type takes 2 parameters, first parameter is the primary navigation type (type for the navigator that owns this screen) and second parameter is the secondary navigation type (type for a parent navigator). The primary navigation type should always have the screen's route name as it's second parameter.
For multiple parent navigators, this secondary type should be nested:
```ts
type FeedScreenNavigationProp = CompositeNavigationProp<
TabNavigationProp<TabParamList, 'feed'>,
CompositeNavigationProp<
StackNavigationProp<StackParamList>,
DrawerNavigationProp<DrawerParamList>
>
>;
```
To annotate the `navigation` prop from `useNavigation`, we can use a type parameter:
```ts
const navigation = useNavigation<FeedScreenNavigationProp>();
```
It's also possible to type-check the navigator to some extent. To do this, we need to pass a generic when creating the navigator object:
```ts
const Stack = createStackNavigator<StackParamList>();
```
And then we can use it:
```js
<Stack.Navigator initialRouteName="profile">
<Stack.Screen name="settings" component={Settings} />
<Stack.Screen
name="profile"
component={Profile}
options={{ title: 'My profile' }}
/>
<Stack.Screen name="home" component={Home} />
</Stack.Navigator>
```
Unfortunately it's not possible to verify that the type of children elements are correct since [TypeScript doesn't support type-checking JSX elements](https://github.com/microsoft/TypeScript/issues/21699).
Documentation can be found at [next.reactnavigation.org](https://next.reactnavigation.org/).
## Contributing
@@ -519,12 +35,32 @@ To fix formatting errors, run the following:
yarn lint --fix
```
Remember to add tests for your change if possible. Run the tests by:
Remember to add tests for your change if possible. Run the unit tests by:
```sh
yarn test
```
Running the e2e tests with Detox (on iOS) requires the following:
- Mac with macOS (at least macOS High Sierra 10.13.6)
- Xcode 10.1+ with Xcode command line tools
First you need to install `applesimutils` and `detox-cli`:
```sh
brew tap wix/brew
brew install applesimutils
yarn global add detox-cli
```
Then you can build and run the tests:
```sh
detox build -c ios.sim.debug
detox test -c ios.sim.debug
```
## Publishing
To publish a new version, first we 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:
@@ -535,6 +71,39 @@ yarn lerna publish
This will automatically bump the version and publish the packages. It'll also publish the changelogs on GitHub for each package.
## Installing from a fork on GitHub
Since we use a monorepo, it's not possible to install a package from the repository URL. If you need to install a forked version from Git, you can use [`gitpkg`](https://github.com/ramasilveyra/gitpkg).
First install `gitpkg`:
```sh
yarn global add gitpkg
```
Then follow these steps to publish and install a forked package:
1. Fork this repo to your account and clone the forked repo to your local machine
1. Open a Terminal and `cd` to the location of the cloned repo
1. Run `yarn` to install any dependencies
1. If you want to make any changes, make them and commit
1. Now `cd` to the package directory that you want to use (e.g. `cd packages/stack` for `@react-navigation/stack`)
1. Run `gitpkg publish` to publish the package to your repo
After publishing, you should see something like this:
```sh
Package uploaded to git@github.com:<user>/<repo>.git with the name <name>
```
You can now install the dependency in your project:
```sh
yarn add <user>/<repo>.git#<name>
```
Remember to replace `<user>`, `<repo>` and `<name>` with right values.
<!-- badges -->
[build-badge]: https://img.shields.io/circleci/project/github/react-navigation/navigation-ex/master.svg?style=flat-square

View File

@@ -1,3 +1,6 @@
import 'react-native-gesture-handler';
import { registerRootComponent } from 'expo';
export { default } from './src/index';
import App from './src/index';
registerRootComponent(App);

View File

@@ -80,8 +80,8 @@ project.ext.react = [
enableHermes: false, // clean and rebuild if changing
]
apply from: '../../node_modules/react-native-unimodules/gradle.groovy'
apply from: "../../node_modules/react-native/react.gradle"
apply from: '../../../node_modules/react-native-unimodules/gradle.groovy'
apply from: "../../../node_modules/react-native/react.gradle"
/**
* Set this to true to create two separate APKs instead of one:
@@ -179,10 +179,10 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.facebook.react:react-native:+" // From node_modules
addUnimodulesDependencies()
addUnimodulesDependencies([ modulesPaths : ['../../../node_modules'] ])
if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
def hermesPath = "../../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
@@ -197,4 +197,4 @@ task copyDownloadableDepsToLibs(type: Copy) {
into 'libs'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply from: file("../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

View File

@@ -24,11 +24,11 @@ allprojects {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
url("$rootDir/../../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
url("$rootDir/../../node_modules/jsc-android/dist")
}
google()

View File

@@ -1,7 +1,7 @@
apply from: '../node_modules/react-native-unimodules/gradle.groovy'
includeUnimodulesProjects()
apply from: '../../node_modules/react-native-unimodules/gradle.groovy'
includeUnimodulesProjects([ modulesPaths : ['../../../node_modules'] ])
rootProject.name = 'ReactNavigationExample'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'

View File

@@ -1,7 +1,10 @@
{
"name": "ReactNavigationExample",
"displayName": "React Navigation Example",
"expo": {
"name": "@react-navigation/example",
"slug": "react-navigation-example",
"description": "Demo app to showcase various functionality of React Navigation",
"privacy": "public",
"sdkVersion": "36.0.0",
"platforms": [
@@ -25,9 +28,6 @@
"ios": {
"supportsTablet": true
},
"entryPoint": "node_modules/expo/AppEntry.js",
"description": "Demo app to showcase various functionality of React Navigation"
},
"displayName": "React Navigation Example",
"name": "ReactNavigationExample"
"entryPoint": "App.tsx"
}
}

View File

@@ -0,0 +1,10 @@
{
"settings": {
"import/core-modules": [
"detox",
"detox/runners/jest/adapter",
"detox/runners/jest/specReporter"
]
},
"env": { "jest": true, "jasmine": true }
}

View File

@@ -0,0 +1,9 @@
import { by, element, expect, device } from 'detox';
beforeEach(async () => {
await device.reloadReactNative();
});
it('has dark theme toggle', async () => {
await expect(element(by.text('Dark theme'))).toBeVisible();
});

6
example/e2e/config.json Normal file
View File

@@ -0,0 +1,6 @@
{
"setupFilesAfterEnv": ["./init.js"],
"testEnvironment": "node",
"reporters": ["detox/runners/jest/streamlineReporter"],
"verbose": true
}

28
example/e2e/init.js Normal file
View File

@@ -0,0 +1,28 @@
/* eslint-disable jest/no-jasmine-globals, import/no-commonjs */
const detox = require('detox');
const config = require('../../package.json').detox;
const adapter = require('detox/runners/jest/adapter');
const specReporter = require('detox/runners/jest/specReporter');
// Set the default timeout
jest.setTimeout(120000);
jasmine.getEnv().addReporter(adapter);
// This takes care of generating status logs on a per-spec basis. By default, jest only reports at file-level.
// This is strictly optional.
jasmine.getEnv().addReporter(specReporter);
beforeAll(async () => {
await detox.init(config);
}, 300000);
beforeEach(async () => {
await adapter.beforeEach();
});
afterAll(async () => {
await adapter.afterAll();
await detox.cleanup();
});

View File

@@ -1,6 +1,4 @@
import { AppRegistry } from 'react-native';
// Need to add extension or eslint confuses it with app.json
import App from './App.tsx';
import App from './src/index.tsx';
AppRegistry.registerComponent('ReactNavigationExample', () => App);

View File

@@ -1,40 +1,40 @@
platform :ios, '10.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
require_relative '../node_modules/react-native-unimodules/cocoapods.rb'
require_relative '../../node_modules/@react-native-community/cli-platform-ios/native_modules'
require_relative '../../node_modules/react-native-unimodules/cocoapods.rb'
target 'ReactNavigationExample' do
# Pods for ReactNavigationExample
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
pod 'React', :path => '../node_modules/react-native/'
pod 'React-Core', :path => '../node_modules/react-native/'
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
pod 'FBLazyVector', :path => '../../node_modules/react-native/Libraries/FBLazyVector'
pod 'FBReactNativeSpec', :path => '../../node_modules/react-native/Libraries/FBReactNativeSpec'
pod 'RCTRequired', :path => '../../node_modules/react-native/Libraries/RCTRequired'
pod 'RCTTypeSafety', :path => '../../node_modules/react-native/Libraries/TypeSafety'
pod 'React', :path => '../../node_modules/react-native/'
pod 'React-Core', :path => '../../node_modules/react-native/'
pod 'React-CoreModules', :path => '../../node_modules/react-native/React/CoreModules'
pod 'React-Core/DevSupport', :path => '../../node_modules/react-native/'
pod 'React-RCTActionSheet', :path => '../../node_modules/react-native/Libraries/ActionSheetIOS'
pod 'React-RCTAnimation', :path => '../../node_modules/react-native/Libraries/NativeAnimation'
pod 'React-RCTBlob', :path => '../../node_modules/react-native/Libraries/Blob'
pod 'React-RCTImage', :path => '../../node_modules/react-native/Libraries/Image'
pod 'React-RCTLinking', :path => '../../node_modules/react-native/Libraries/LinkingIOS'
pod 'React-RCTNetwork', :path => '../../node_modules/react-native/Libraries/Network'
pod 'React-RCTSettings', :path => '../../node_modules/react-native/Libraries/Settings'
pod 'React-RCTText', :path => '../../node_modules/react-native/Libraries/Text'
pod 'React-RCTVibration', :path => '../../node_modules/react-native/Libraries/Vibration'
pod 'React-Core/RCTWebSocket', :path => '../../node_modules/react-native/'
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
pod 'React-cxxreact', :path => '../../node_modules/react-native/ReactCommon/cxxreact'
pod 'React-jsi', :path => '../../node_modules/react-native/ReactCommon/jsi'
pod 'React-jsiexecutor', :path => '../../node_modules/react-native/ReactCommon/jsiexecutor'
pod 'React-jsinspector', :path => '../../node_modules/react-native/ReactCommon/jsinspector'
pod 'ReactCommon/jscallinvoker', :path => '../../node_modules/react-native/ReactCommon'
pod 'ReactCommon/turbomodule/core', :path => '../../node_modules/react-native/ReactCommon'
pod 'Yoga', :path => '../../node_modules/react-native/ReactCommon/yoga'
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
pod 'DoubleConversion', :podspec => '../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../../node_modules/react-native/third-party-podspecs/Folly.podspec'
use_native_modules!
use_unimodules!
use_unimodules!({ modules_paths: ['../../node_modules'] })
end

View File

@@ -210,7 +210,7 @@ PODS:
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsinspector (0.61.5)
- react-native-safe-area-context (0.6.1):
- react-native-safe-area-context (0.6.2):
- React
- React-RCTActionSheet (0.61.5):
- React-Core/RCTActionSheetHeaders (= 0.61.5)
@@ -249,11 +249,11 @@ PODS:
- ReactCommon/jscallinvoker (= 0.61.5)
- RNCMaskedView (0.1.5):
- React
- RNGestureHandler (1.5.2):
- RNGestureHandler (1.5.3):
- React
- RNReanimated (1.4.0):
- React
- RNScreens (2.0.0-alpha.17):
- RNScreens (2.0.0-alpha.22):
- React
- UMBarCodeScannerInterface (5.0.0)
- UMCameraInterface (5.0.0)
@@ -273,62 +273,62 @@ PODS:
- Yoga (1.14.0)
DEPENDENCIES:
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- EXAppLoaderProvider (from `../node_modules/expo/node_modules/expo-app-loader-provider/ios`)
- EXConstants (from `../node_modules/expo/node_modules/expo-constants/ios`)
- EXErrorRecovery (from `../node_modules/expo-error-recovery/ios`)
- EXFileSystem (from `../node_modules/expo/node_modules/expo-file-system/ios`)
- EXFont (from `../node_modules/expo-font/ios`)
- EXKeepAwake (from `../node_modules/expo-keep-awake/ios`)
- EXLinearGradient (from `../node_modules/expo-linear-gradient/ios`)
- EXLocation (from `../node_modules/expo-location/ios`)
- EXPermissions (from `../node_modules/expo/node_modules/expo-permissions/ios`)
- EXSQLite (from `../node_modules/expo-sqlite/ios`)
- EXWebBrowser (from `../node_modules/expo-web-browser/ios`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
- React-Core (from `../node_modules/react-native/`)
- React-Core/DevSupport (from `../node_modules/react-native/`)
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
- React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
- React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
- React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
- UMBarCodeScannerInterface (from `../node_modules/expo/node_modules/unimodules-barcode-scanner-interface/ios`)
- UMCameraInterface (from `../node_modules/expo/node_modules/unimodules-camera-interface/ios`)
- UMConstantsInterface (from `../node_modules/expo/node_modules/unimodules-constants-interface/ios`)
- "UMCore (from `../node_modules/expo/node_modules/@unimodules/core/ios`)"
- UMFaceDetectorInterface (from `../node_modules/expo/node_modules/unimodules-face-detector-interface/ios`)
- UMFileSystemInterface (from `../node_modules/expo/node_modules/unimodules-file-system-interface/ios`)
- UMFontInterface (from `../node_modules/expo/node_modules/unimodules-font-interface/ios`)
- UMImageLoaderInterface (from `../node_modules/expo/node_modules/unimodules-image-loader-interface/ios`)
- UMPermissionsInterface (from `../node_modules/expo/node_modules/unimodules-permissions-interface/ios`)
- "UMReactNativeAdapter (from `../node_modules/expo/node_modules/@unimodules/react-native-adapter/ios`)"
- UMSensorsInterface (from `../node_modules/expo/node_modules/unimodules-sensors-interface/ios`)
- UMTaskManagerInterface (from `../node_modules/expo/node_modules/unimodules-task-manager-interface/ios`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
- DoubleConversion (from `../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- EXAppLoaderProvider (from `../../node_modules/expo-app-loader-provider/ios`)
- EXConstants (from `../../node_modules/expo-constants/ios`)
- EXErrorRecovery (from `../../node_modules/expo-error-recovery/ios`)
- EXFileSystem (from `../../node_modules/expo-file-system/ios`)
- EXFont (from `../../node_modules/expo-font/ios`)
- EXKeepAwake (from `../../node_modules/expo-keep-awake/ios`)
- EXLinearGradient (from `../../node_modules/expo-linear-gradient/ios`)
- EXLocation (from `../../node_modules/expo-location/ios`)
- EXPermissions (from `../../node_modules/expo-permissions/ios`)
- EXSQLite (from `../../node_modules/expo-sqlite/ios`)
- EXWebBrowser (from `../../node_modules/expo-web-browser/ios`)
- FBLazyVector (from `../../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../../node_modules/react-native/Libraries/FBReactNativeSpec`)
- Folly (from `../../node_modules/react-native/third-party-podspecs/Folly.podspec`)
- glog (from `../../node_modules/react-native/third-party-podspecs/glog.podspec`)
- RCTRequired (from `../../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../../node_modules/react-native/`)
- React-Core (from `../../node_modules/react-native/`)
- React-Core/DevSupport (from `../../node_modules/react-native/`)
- React-Core/RCTWebSocket (from `../../node_modules/react-native/`)
- React-CoreModules (from `../../node_modules/react-native/React/CoreModules`)
- React-cxxreact (from `../../node_modules/react-native/ReactCommon/cxxreact`)
- React-jsi (from `../../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../../node_modules/react-native/ReactCommon/jsinspector`)
- react-native-safe-area-context (from `../../node_modules/react-native-safe-area-context`)
- React-RCTActionSheet (from `../../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../../node_modules/react-native/Libraries/NativeAnimation`)
- React-RCTBlob (from `../../node_modules/react-native/Libraries/Blob`)
- React-RCTImage (from `../../node_modules/react-native/Libraries/Image`)
- React-RCTLinking (from `../../node_modules/react-native/Libraries/LinkingIOS`)
- React-RCTNetwork (from `../../node_modules/react-native/Libraries/Network`)
- React-RCTSettings (from `../../node_modules/react-native/Libraries/Settings`)
- React-RCTText (from `../../node_modules/react-native/Libraries/Text`)
- React-RCTVibration (from `../../node_modules/react-native/Libraries/Vibration`)
- ReactCommon/jscallinvoker (from `../../node_modules/react-native/ReactCommon`)
- ReactCommon/turbomodule/core (from `../../node_modules/react-native/ReactCommon`)
- "RNCMaskedView (from `../../node_modules/@react-native-community/masked-view`)"
- RNGestureHandler (from `../../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../../node_modules/react-native-reanimated`)
- RNScreens (from `../../node_modules/react-native-screens`)
- UMBarCodeScannerInterface (from `../../node_modules/unimodules-barcode-scanner-interface/ios`)
- UMCameraInterface (from `../../node_modules/unimodules-camera-interface/ios`)
- UMConstantsInterface (from `../../node_modules/unimodules-constants-interface/ios`)
- "UMCore (from `../../node_modules/@unimodules/core/ios`)"
- UMFaceDetectorInterface (from `../../node_modules/unimodules-face-detector-interface/ios`)
- UMFileSystemInterface (from `../../node_modules/unimodules-file-system-interface/ios`)
- UMFontInterface (from `../../node_modules/unimodules-font-interface/ios`)
- UMImageLoaderInterface (from `../../node_modules/unimodules-image-loader-interface/ios`)
- UMPermissionsInterface (from `../../node_modules/unimodules-permissions-interface/ios`)
- "UMReactNativeAdapter (from `../../node_modules/@unimodules/react-native-adapter/ios`)"
- UMSensorsInterface (from `../../node_modules/unimodules-sensors-interface/ios`)
- UMTaskManagerInterface (from `../../node_modules/unimodules-task-manager-interface/ios`)
- Yoga (from `../../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS:
trunk:
@@ -336,134 +336,134 @@ SPEC REPOS:
EXTERNAL SOURCES:
DoubleConversion:
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
:podspec: "../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
EXAppLoaderProvider:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/expo-app-loader-provider/ios"
path: "../../node_modules/expo-app-loader-provider/ios"
EXConstants:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/expo-constants/ios"
path: "../../node_modules/expo-constants/ios"
EXErrorRecovery:
:path: !ruby/object:Pathname
path: "../node_modules/expo-error-recovery/ios"
path: "../../node_modules/expo-error-recovery/ios"
EXFileSystem:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/expo-file-system/ios"
path: "../../node_modules/expo-file-system/ios"
EXFont:
:path: !ruby/object:Pathname
path: "../node_modules/expo-font/ios"
path: "../../node_modules/expo-font/ios"
EXKeepAwake:
:path: !ruby/object:Pathname
path: "../node_modules/expo-keep-awake/ios"
path: "../../node_modules/expo-keep-awake/ios"
EXLinearGradient:
:path: !ruby/object:Pathname
path: "../node_modules/expo-linear-gradient/ios"
path: "../../node_modules/expo-linear-gradient/ios"
EXLocation:
:path: !ruby/object:Pathname
path: "../node_modules/expo-location/ios"
path: "../../node_modules/expo-location/ios"
EXPermissions:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/expo-permissions/ios"
path: "../../node_modules/expo-permissions/ios"
EXSQLite:
:path: !ruby/object:Pathname
path: "../node_modules/expo-sqlite/ios"
path: "../../node_modules/expo-sqlite/ios"
EXWebBrowser:
:path: !ruby/object:Pathname
path: "../node_modules/expo-web-browser/ios"
path: "../../node_modules/expo-web-browser/ios"
FBLazyVector:
:path: "../node_modules/react-native/Libraries/FBLazyVector"
:path: "../../node_modules/react-native/Libraries/FBLazyVector"
FBReactNativeSpec:
:path: "../node_modules/react-native/Libraries/FBReactNativeSpec"
:path: "../../node_modules/react-native/Libraries/FBReactNativeSpec"
Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
:podspec: "../../node_modules/react-native/third-party-podspecs/Folly.podspec"
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
:podspec: "../../node_modules/react-native/third-party-podspecs/glog.podspec"
RCTRequired:
:path: "../node_modules/react-native/Libraries/RCTRequired"
:path: "../../node_modules/react-native/Libraries/RCTRequired"
RCTTypeSafety:
:path: "../node_modules/react-native/Libraries/TypeSafety"
:path: "../../node_modules/react-native/Libraries/TypeSafety"
React:
:path: "../node_modules/react-native/"
:path: "../../node_modules/react-native/"
React-Core:
:path: "../node_modules/react-native/"
:path: "../../node_modules/react-native/"
React-CoreModules:
:path: "../node_modules/react-native/React/CoreModules"
:path: "../../node_modules/react-native/React/CoreModules"
React-cxxreact:
:path: "../node_modules/react-native/ReactCommon/cxxreact"
:path: "../../node_modules/react-native/ReactCommon/cxxreact"
React-jsi:
:path: "../node_modules/react-native/ReactCommon/jsi"
:path: "../../node_modules/react-native/ReactCommon/jsi"
React-jsiexecutor:
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
:path: "../../node_modules/react-native/ReactCommon/jsiexecutor"
React-jsinspector:
:path: "../node_modules/react-native/ReactCommon/jsinspector"
:path: "../../node_modules/react-native/ReactCommon/jsinspector"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
:path: "../../node_modules/react-native-safe-area-context"
React-RCTActionSheet:
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
:path: "../../node_modules/react-native/Libraries/ActionSheetIOS"
React-RCTAnimation:
:path: "../node_modules/react-native/Libraries/NativeAnimation"
:path: "../../node_modules/react-native/Libraries/NativeAnimation"
React-RCTBlob:
:path: "../node_modules/react-native/Libraries/Blob"
:path: "../../node_modules/react-native/Libraries/Blob"
React-RCTImage:
:path: "../node_modules/react-native/Libraries/Image"
:path: "../../node_modules/react-native/Libraries/Image"
React-RCTLinking:
:path: "../node_modules/react-native/Libraries/LinkingIOS"
:path: "../../node_modules/react-native/Libraries/LinkingIOS"
React-RCTNetwork:
:path: "../node_modules/react-native/Libraries/Network"
:path: "../../node_modules/react-native/Libraries/Network"
React-RCTSettings:
:path: "../node_modules/react-native/Libraries/Settings"
:path: "../../node_modules/react-native/Libraries/Settings"
React-RCTText:
:path: "../node_modules/react-native/Libraries/Text"
:path: "../../node_modules/react-native/Libraries/Text"
React-RCTVibration:
:path: "../node_modules/react-native/Libraries/Vibration"
:path: "../../node_modules/react-native/Libraries/Vibration"
ReactCommon:
:path: "../node_modules/react-native/ReactCommon"
:path: "../../node_modules/react-native/ReactCommon"
RNCMaskedView:
:path: "../node_modules/@react-native-community/masked-view"
:path: "../../node_modules/@react-native-community/masked-view"
RNGestureHandler:
:path: "../node_modules/react-native-gesture-handler"
:path: "../../node_modules/react-native-gesture-handler"
RNReanimated:
:path: "../node_modules/react-native-reanimated"
:path: "../../node_modules/react-native-reanimated"
RNScreens:
:path: "../node_modules/react-native-screens"
:path: "../../node_modules/react-native-screens"
UMBarCodeScannerInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-barcode-scanner-interface/ios"
path: "../../node_modules/unimodules-barcode-scanner-interface/ios"
UMCameraInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-camera-interface/ios"
path: "../../node_modules/unimodules-camera-interface/ios"
UMConstantsInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-constants-interface/ios"
path: "../../node_modules/unimodules-constants-interface/ios"
UMCore:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/@unimodules/core/ios"
path: "../../node_modules/@unimodules/core/ios"
UMFaceDetectorInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-face-detector-interface/ios"
path: "../../node_modules/unimodules-face-detector-interface/ios"
UMFileSystemInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-file-system-interface/ios"
path: "../../node_modules/unimodules-file-system-interface/ios"
UMFontInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-font-interface/ios"
path: "../../node_modules/unimodules-font-interface/ios"
UMImageLoaderInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-image-loader-interface/ios"
path: "../../node_modules/unimodules-image-loader-interface/ios"
UMPermissionsInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-permissions-interface/ios"
path: "../../node_modules/unimodules-permissions-interface/ios"
UMReactNativeAdapter:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/@unimodules/react-native-adapter/ios"
path: "../../node_modules/@unimodules/react-native-adapter/ios"
UMSensorsInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-sensors-interface/ios"
path: "../../node_modules/unimodules-sensors-interface/ios"
UMTaskManagerInterface:
:path: !ruby/object:Pathname
path: "../node_modules/expo/node_modules/unimodules-task-manager-interface/ios"
path: "../../node_modules/unimodules-task-manager-interface/ios"
Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga"
:path: "../../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
@@ -492,7 +492,7 @@ SPEC CHECKSUMS:
React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
react-native-safe-area-context: 1f8a52fb0ab1321eef9a7099bd2c360d4e38264b
react-native-safe-area-context: 25260c5d0b9c53fd7aa88e569e2edae72af1f6a3
React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
@@ -504,9 +504,9 @@ SPEC CHECKSUMS:
React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad
ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd
RNCMaskedView: dd13f9f7b146a9ad82f9b7eb6c9b5548fcf6e990
RNGestureHandler: 946a7691e41df61e2c4b1884deab41a4cdc3afff
RNGestureHandler: 02905abe54e1f6e59c081a10b4bd689721e17aa6
RNReanimated: b2ab0b693dddd2339bd2f300e770f6302d2e960c
RNScreens: f5e2ff7ccde2a1bfcf2a48c6fd07fdcf1fd95223
RNScreens: 6adf01eb4080f44af6cca551207c6b0505066857
UMBarCodeScannerInterface: 3802c8574ef119c150701d679ab386e2266d6a54
UMCameraInterface: 985d301f688ed392f815728f0dd906ca34b7ccb1
UMConstantsInterface: bda5f8bd3403ad99e663eb3c4da685d063c5653c
@@ -521,6 +521,6 @@ SPEC CHECKSUMS:
UMTaskManagerInterface: a98e37a576a5220bf43b8faf33cfdc129d2f441d
Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b
PODFILE CHECKSUM: 18b58708b4bb9901516029103ee63c94d63edd9e
PODFILE CHECKSUM: c48a21ff513d3eadafa50f8797207ef2be75e234
COCOAPODS: 1.8.4

View File

@@ -188,7 +188,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
shellScript = "export NODE_BINARY=node\n../../node_modules/react-native/scripts/react-native-xcode.sh";
};
FC67D3D0567CD942E3DA69B7 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;

View File

@@ -8,48 +8,58 @@ const blacklist = require('metro-config/src/defaults/blacklist');
const root = path.resolve(__dirname, '..');
const packages = path.resolve(__dirname, '..', 'packages');
const modules = ['@babel/runtime', '@expo/vector-icons']
// Get the list of dependencies for all packages in the monorepo
const modules = ['@expo/vector-icons']
.concat(
...fs
// List all packages under `packages/`
.readdirSync(packages)
// Ignore hidden files such as .DS_Store
.filter(p => !p.startsWith('.'))
.map(p => {
const pak = JSON.parse(
fs.readFileSync(path.join(packages, p, 'package.json'), 'utf8')
);
const deps = [];
if (pak.dependencies) {
deps.push(...Object.keys(pak.dependencies));
}
if (pak.peerDependencies) {
deps.push(...Object.keys(pak.peerDependencies));
}
return deps;
// We need to collect list of deps that this package imports
// Collecting both dependencies are peerDependencies sould do it
return Object.keys({
...pak.dependencies,
...pak.peerDependencies,
});
})
)
.sort()
.filter(
(m, i, self) =>
// Remove duplicates and package names of the packages in the monorepo
self.lastIndexOf(m) === i && !m.startsWith('@react-navigation/')
);
module.exports = {
projectRoot: __dirname,
// We need to watch the root of the monorepo
// This lets Metro find the monorepo packages automatically using haste
// This also lets us import modules from monorepo root
watchFolders: [root],
resolver: {
// We need to blacklist `node_modules` of all our packages
// This will avoid Metro throwing duplicate module errors
blacklistRE: blacklist(
[root, ...fs.readdirSync(packages).map(p => path.join(packages, p))].map(
it => new RegExp(`^${escape(path.join(it, 'node_modules'))}\\/.*$`)
)
fs
.readdirSync(packages)
.map(p => path.join(packages, p))
.map(
it => new RegExp(`^${escape(path.join(it, 'node_modules'))}\\/.*$`)
)
),
// When we import a package from the monorepo, metro won't be able to find their deps
// We need to specify them in `extraNodeModules` to tell metro where to find them
extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, 'node_modules', name);
acc[name] = path.join(__dirname, '..', 'node_modules', name);
return acc;
}, {}),
},
@@ -60,6 +70,8 @@ module.exports = {
const assets = '/packages/stack/src/views/assets';
if (req.url.startsWith(assets)) {
// When an asset is imported outside the project root, it has wrong path on Android
// This happens for the back button in stack, so we fix the path to correct one
req.url = req.url.replace(
assets,
'/assets/../packages/stack/src/views/assets'
@@ -72,7 +84,7 @@ module.exports = {
},
transformer: {
getTransformOptions: async () => ({
getTransformOptions: () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,

View File

@@ -3,50 +3,38 @@
"description": "Demo app to showcase various functionality of React Navigation",
"version": "5.0.0-alpha.23",
"private": true,
"workspaces": {
"nohoist": [
"*",
"*/**"
]
},
"scripts": {
"start": "expo start",
"web": "expo start --web",
"react-native": "./node_modules/.bin/react-native",
"native": "./node_modules/.bin/react-native start",
"android": "./node_modules/.bin/react-native run-android",
"ios": "./node_modules/.bin/react-native run-ios"
"native": "react-native start",
"android": "react-native run-android",
"ios": "react-native run-ios"
},
"dependencies": {
"@expo/vector-icons": "^10.0.0",
"@react-native-community/masked-view": "0.1.5",
"color": "^3.1.2",
"expo": "^36.0.0",
"expo": "^36.0.2",
"expo-asset": "~8.0.0",
"query-string": "^6.9.0",
"react": "~16.9.0",
"react-dom": "~16.9.0",
"react-native": "~0.61.5",
"react-native-gesture-handler": "~1.5.0",
"react-native-iphone-x-helper": "^1.2.1",
"react-native-paper": "^3.3.0",
"react-native-gesture-handler": "~1.5.3",
"react-native-paper": "^3.4.0",
"react-native-reanimated": "^1.4.0",
"react-native-safe-area-context": "^0.6.0",
"react-native-screens": "^2.0.0-alpha.19",
"react-native-safe-area-context": "^0.6.2",
"react-native-screens": "^2.0.0-alpha.22",
"react-native-tab-view": "2.11.0",
"react-native-unimodules": "^0.7.0",
"react-native-web": "^0.11.7",
"scheduler": "^0.18.0",
"shortid": "^2.2.15",
"use-subscription": "^1.3.0"
"react-native-web": "^0.11.7"
},
"devDependencies": {
"@babel/core": "^7.7.5",
"@expo/webpack-config": "^0.10.6",
"@types/react": "^16.9.16",
"@types/react-native": "^0.60.25",
"@babel/core": "^7.7.7",
"@expo/webpack-config": "^0.10.9",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.30",
"babel-preset-expo": "^8.0.0",
"expo-cli": "^3.11.1",
"typescript": "^3.7.3"
"expo-cli": "^3.11.5",
"typescript": "^3.7.4"
}
}

View File

@@ -1,7 +1,6 @@
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Button } from 'react-native-paper';
import { useSafeArea } from 'react-native-safe-area-context';
import { RouteProp, ParamListBase } from '@react-navigation/native';
import {
createStackNavigator,
@@ -25,11 +24,9 @@ const ArticleScreen = ({
navigation: ModalStackNavigation;
route: RouteProp<ModalStackParams, 'Article'>;
}) => {
const insets = useSafeArea();
return (
<React.Fragment>
<View style={[styles.buttons, { marginTop: insets.top }]}>
<View style={styles.buttons}>
<Button
mode="contained"
onPress={() => navigation.push('Album')}
@@ -51,11 +48,9 @@ const ArticleScreen = ({
};
const AlbumsScreen = ({ navigation }: { navigation: ModalStackNavigation }) => {
const insets = useSafeArea();
return (
<React.Fragment>
<View style={[styles.buttons, { marginTop: insets.top }]}>
<View style={styles.buttons}>
<Button
mode="contained"
onPress={() => navigation.push('Article', { author: 'Babel fish' })}
@@ -91,12 +86,16 @@ export default function SimpleStackScreen({ navigation, options }: Props) {
return (
<ModalPresentationStack.Navigator
mode="modal"
headerMode="none"
screenOptions={{
headerMode="screen"
screenOptions={({ route, navigation }) => ({
...TransitionPresets.ModalPresentationIOS,
cardOverlayEnabled: true,
gestureEnabled: true,
}}
headerStatusBarHeight:
navigation.dangerouslyGetState().routes.indexOf(route) > 0
? 0
: undefined,
})}
{...options}
>
<ModalPresentationStack.Screen

View File

@@ -35,6 +35,7 @@ import {
createStackNavigator,
Assets as StackAssets,
StackNavigationProp,
HeaderStyleInterpolators,
} from '@react-navigation/stack';
import LinkingPrefixes from './LinkingPrefixes';
@@ -206,7 +207,11 @@ export default function App() {
}: {
navigation: DrawerNavigationProp<RootDrawerParamList>;
}) => (
<Stack.Navigator>
<Stack.Navigator
screenOptions={{
headerStyleInterpolator: HeaderStyleInterpolators.forUIKit,
}}
>
<Stack.Screen
name="Home"
options={{

View File

@@ -4,7 +4,7 @@ const createExpoWebpackConfigAsync = require('@expo/webpack-config');
// eslint-disable-next-line import/no-extraneous-dependencies
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const node_modules = path.resolve(__dirname, 'node_modules');
const node_modules = path.resolve(__dirname, '..', 'node_modules');
const packages = path.resolve(__dirname, '..', 'packages');
module.exports = async function(env, argv) {

View File

@@ -25,22 +25,23 @@
"devDependencies": {
"@babel/plugin-proposal-class-properties": "^7.7.0",
"@babel/plugin-proposal-optional-chaining": "^7.7.5",
"@babel/preset-env": "^7.7.6",
"@babel/preset-env": "^7.7.7",
"@babel/preset-react": "^7.7.0",
"@babel/preset-typescript": "^7.7.2",
"@babel/runtime": "^7.7.6",
"@commitlint/config-conventional": "^8.2.0",
"@types/jest": "^24.0.23",
"@babel/preset-typescript": "^7.7.7",
"@babel/runtime": "^7.7.7",
"@commitlint/config-conventional": "^8.3.4",
"@types/jest": "^24.0.25",
"codecov": "^3.6.1",
"commitlint": "^8.2.0",
"core-js": "^3.5.0",
"eslint": "^6.7.2",
"commitlint": "^8.3.4",
"core-js": "^3.6.2",
"detox": "^15.0.0",
"eslint": "^6.8.0",
"eslint-config-satya164": "^3.1.5",
"husky": "^3.0.9",
"jest": "^24.8.0",
"lerna": "^3.18.4",
"husky": "^4.0.1",
"jest": "^24.9.0",
"lerna": "^3.20.2",
"prettier": "^1.19.1",
"typescript": "^3.7.3"
"typescript": "^3.7.4"
},
"resolutions": {
"react": "~16.9.0",
@@ -70,5 +71,27 @@
"useTabs": false,
"singleQuote": true,
"trailingComma": "es5"
},
"detox": {
"test-runner": "jest",
"runner-config": "example/e2e/config.json",
"configurations": {
"ios.sim.debug": {
"binaryPath": "example/ios/build/Build/Products/Debug-iphonesimulator/ReactNavigationExample.app",
"build": "set -o pipefail; xcodebuild -workspace example/ios/ReactNavigationExample.xcworkspace -scheme ReactNavigationExample -configuration Debug -sdk iphonesimulator -derivedDataPath example/ios/build",
"type": "ios.simulator",
"device": {
"type": "iPhone 11 Pro"
}
},
"ios.sim.release": {
"binaryPath": "example/ios/build/Build/Products/Release-iphonesimulator/ReactNavigationExample.app",
"build": "export RCT_NO_LAUNCH_PACKAGER=true; set -o pipefail; xcodebuild -workspace example/ios/ReactNavigationExample.xcworkspace -scheme ReactNavigationExample -configuration Release -sdk iphonesimulator -derivedDataPath example/ios/build",
"type": "ios.simulator",
"device": {
"type": "iPhone 11 Pro"
}
}
}
}
}

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.35](https://github.com/react-navigation/navigation-ex/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.0-alpha.34...@react-navigation/bottom-tabs@5.0.0-alpha.35) (2020-01-13)
**Note:** Version bump only for package @react-navigation/bottom-tabs
# [5.0.0-alpha.34](https://github.com/react-navigation/navigation-ex/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.0-alpha.32...@react-navigation/bottom-tabs@5.0.0-alpha.34) (2020-01-09)
**Note:** Version bump only for package @react-navigation/bottom-tabs
# [5.0.0-alpha.33](https://github.com/react-navigation/navigation-ex/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.0.0-alpha.32...@react-navigation/bottom-tabs@5.0.0-alpha.33) (2020-01-09)
**Note:** Version bump only for package @react-navigation/bottom-tabs
# [5.0.0-alpha.32](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/bottom-tabs@5.0.0-alpha.31...@react-navigation/bottom-tabs@5.0.0-alpha.32) (2020-01-05)
**Note:** Version bump only for package @react-navigation/bottom-tabs

View File

@@ -2,6 +2,8 @@
Bottom tab navigator for React Navigation following iOS design guidelines.
Documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/en/next/bottom-tab-navigator.html).
## Installation
Open a Terminal in your project's folder and run,

View File

@@ -10,17 +10,13 @@
"android",
"tab"
],
"version": "5.0.0-alpha.32",
"version": "5.0.0-alpha.35",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/bottom-tabs"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/bottom-tabs",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/bottom-tabs/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -33,20 +29,20 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0-alpha.20",
"@react-navigation/routers": "^5.0.0-alpha.23",
"color": "^3.1.2",
"react-native-iphone-x-helper": "^1.2.1"
},
"devDependencies": {
"@react-native-community/bob": "^0.7.0",
"@types/color": "^3.0.0",
"@types/react": "^16.9.16",
"@types/react-native": "^0.60.25",
"@react-native-community/bob": "^0.7.1",
"@types/color": "^3.0.1",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",
"react": "~16.9.0",
"react-native": "~0.61.5",
"react-native-safe-area-context": "^0.6.0",
"typescript": "^3.7.3"
"react-native-safe-area-context": "^0.6.2",
"typescript": "^3.7.4"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0-alpha.0",

View File

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

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.24](https://github.com/react-navigation/navigation-ex/tree/master/packages/compat/compare/@react-navigation/compat@5.0.0-alpha.23...@react-navigation/compat@5.0.0-alpha.24) (2020-01-13)
**Note:** Version bump only for package @react-navigation/compat
# [5.0.0-alpha.23](https://github.com/react-navigation/navigation-ex/tree/master/packages/compat/compare/@react-navigation/compat@5.0.0-alpha.21...@react-navigation/compat@5.0.0-alpha.23) (2020-01-09)
**Note:** Version bump only for package @react-navigation/compat
# [5.0.0-alpha.22](https://github.com/react-navigation/navigation-ex/tree/master/packages/compat/compare/@react-navigation/compat@5.0.0-alpha.21...@react-navigation/compat@5.0.0-alpha.22) (2020-01-09)
**Note:** Version bump only for package @react-navigation/compat
# [5.0.0-alpha.21](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/compat@5.0.0-alpha.20...@react-navigation/compat@5.0.0-alpha.21) (2020-01-05)
**Note:** Version bump only for package @react-navigation/compat

View File

@@ -2,6 +2,8 @@
Compatibility layer to write navigator definitions in static configuration format.
Documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/en/next/compatibility.html).
## Installation
Open a Terminal in your project's folder and run,

View File

@@ -1,17 +1,13 @@
{
"name": "@react-navigation/compat",
"description": "Compatibility layer to write navigator definitions in static configuration format",
"version": "5.0.0-alpha.21",
"version": "5.0.0-alpha.24",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/compat"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/compat",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/compat/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -24,12 +20,12 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0-alpha.20"
"@react-navigation/routers": "^5.0.0-alpha.23"
},
"devDependencies": {
"@types/react": "^16.9.16",
"@types/react": "^16.9.17",
"react": "~16.9.0",
"typescript": "^3.7.3"
"typescript": "^3.7.4"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0-alpha.0",

View File

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

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.33](https://github.com/react-navigation/navigation-ex/tree/master/packages/core/compare/@react-navigation/core@5.0.0-alpha.32...@react-navigation/core@5.0.0-alpha.33) (2020-01-13)
**Note:** Version bump only for package @react-navigation/core
# [5.0.0-alpha.32](https://github.com/react-navigation/navigation-ex/tree/master/packages/core/compare/@react-navigation/core@5.0.0-alpha.30...@react-navigation/core@5.0.0-alpha.32) (2020-01-09)
**Note:** Version bump only for package @react-navigation/core
# [5.0.0-alpha.31](https://github.com/react-navigation/navigation-ex/tree/master/packages/core/compare/@react-navigation/core@5.0.0-alpha.30...@react-navigation/core@5.0.0-alpha.31) (2020-01-09)
**Note:** Version bump only for package @react-navigation/core
# [5.0.0-alpha.30](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/core@5.0.0-alpha.29...@react-navigation/core@5.0.0-alpha.30) (2020-01-01)

View File

@@ -6,17 +6,13 @@
"react-native",
"react-navigation"
],
"version": "5.0.0-alpha.30",
"version": "5.0.0-alpha.33",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/core"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/core",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -35,15 +31,15 @@
"use-subscription": "^1.3.0"
},
"devDependencies": {
"@babel/core": "^7.7.5",
"@react-native-community/bob": "^0.7.0",
"@types/react": "^16.9.16",
"@babel/core": "^7.7.7",
"@react-native-community/bob": "^0.7.1",
"@types/react": "^16.9.17",
"@types/shortid": "^0.0.29",
"del-cli": "^3.0.0",
"react": "~16.9.0",
"react-native-testing-library": "^1.12.0",
"react-test-renderer": "~16.9.0",
"typescript": "^3.7.3"
"react-test-renderer": "~16.12.0",
"typescript": "^3.7.4"
},
"peerDependencies": {
"react": "~16.9.0"

View File

@@ -273,7 +273,7 @@ it('fires blur event when a route is removed with a delay', async () => {
React.useImperativeHandle(ref, () => navigation, [navigation]);
const [previous, dispatch] = React.useReducer(
(state, action) => {
(state: any, action: any) => {
if (state.routes !== action.routes) {
return { ...state, ...action };
}

View File

@@ -1,3 +1,6 @@
{
"extends": "../../tsconfig"
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "./lib/typescript"
}
}

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.37](https://github.com/react-navigation/navigation-ex/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.0-alpha.36...@react-navigation/drawer@5.0.0-alpha.37) (2020-01-13)
**Note:** Version bump only for package @react-navigation/drawer
# [5.0.0-alpha.36](https://github.com/react-navigation/navigation-ex/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.0-alpha.34...@react-navigation/drawer@5.0.0-alpha.36) (2020-01-09)
**Note:** Version bump only for package @react-navigation/drawer
# [5.0.0-alpha.35](https://github.com/react-navigation/navigation-ex/tree/master/packages/drawer/compare/@react-navigation/drawer@5.0.0-alpha.34...@react-navigation/drawer@5.0.0-alpha.35) (2020-01-09)
**Note:** Version bump only for package @react-navigation/drawer
# [5.0.0-alpha.34](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/drawer@5.0.0-alpha.33...@react-navigation/drawer@5.0.0-alpha.34) (2020-01-05)
**Note:** Version bump only for package @react-navigation/drawer

View File

@@ -2,6 +2,8 @@
Bottom tab navigator for React Navigation following iOS design guidelines.
Documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/en/next/drawer-navigator.html).
## Installation
Open a Terminal in your project's folder and run,

View File

@@ -11,17 +11,13 @@
"material",
"drawer"
],
"version": "5.0.0-alpha.34",
"version": "5.0.0-alpha.37",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/drawer"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/drawer",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/drawer/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -34,22 +30,22 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0-alpha.20",
"@react-navigation/routers": "^5.0.0-alpha.23",
"color": "^3.1.2",
"react-native-iphone-x-helper": "^1.2.1"
},
"devDependencies": {
"@react-native-community/bob": "^0.7.0",
"@types/react": "^16.9.16",
"@types/react-native": "^0.60.25",
"@react-native-community/bob": "^0.7.1",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",
"react": "~16.9.0",
"react-native": "~0.61.5",
"react-native-gesture-handler": "^1.5.0",
"react-native-gesture-handler": "^1.5.3",
"react-native-reanimated": "^1.4.0",
"react-native-safe-area-context": "^0.6.0",
"react-native-screens": "^2.0.0-alpha.19",
"typescript": "^3.7.3"
"react-native-safe-area-context": "^0.6.2",
"react-native-screens": "^2.0.0-alpha.22",
"typescript": "^3.7.4"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0-alpha.0",

View File

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

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.32](https://github.com/react-navigation/navigation-ex/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.0-alpha.31...@react-navigation/material-bottom-tabs@5.0.0-alpha.32) (2020-01-13)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
# [5.0.0-alpha.31](https://github.com/react-navigation/navigation-ex/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.0-alpha.29...@react-navigation/material-bottom-tabs@5.0.0-alpha.31) (2020-01-09)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
# [5.0.0-alpha.30](https://github.com/react-navigation/navigation-ex/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.0.0-alpha.29...@react-navigation/material-bottom-tabs@5.0.0-alpha.30) (2020-01-09)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
# [5.0.0-alpha.29](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/material-bottom-tabs@5.0.0-alpha.28...@react-navigation/material-bottom-tabs@5.0.0-alpha.29) (2020-01-05)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs

View File

@@ -2,6 +2,8 @@
React Navigation integration for [bottom navigation](https://material.io/design/components/bottom-navigation.html) component from [`react-native-paper`](https://callstack.github.io/react-native-paper/bottom-navigation.html).
Documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/en/next/material-bottom-tab-navigator.html).
## Installation
Open a Terminal in your project's folder and run,

View File

@@ -11,17 +11,13 @@
"material",
"tab"
],
"version": "5.0.0-alpha.29",
"version": "5.0.0-alpha.32",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/material-bottom-tabs"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/material-bottom-tabs",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/material-bottom-tabs/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -34,19 +30,19 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0-alpha.20"
"@react-navigation/routers": "^5.0.0-alpha.23"
},
"devDependencies": {
"@react-native-community/bob": "^0.7.0",
"@types/react": "^16.9.16",
"@types/react-native": "^0.60.25",
"@types/react-native-vector-icons": "^6.4.4",
"@react-native-community/bob": "^0.7.1",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.30",
"@types/react-native-vector-icons": "^6.4.5",
"del-cli": "^3.0.0",
"react": "~16.9.0",
"react-native": "~0.61.5",
"react-native-paper": "^3.3.0",
"react-native-paper": "^3.4.0",
"react-native-vector-icons": "^6.6.0",
"typescript": "^3.7.3"
"typescript": "^3.7.4"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0-alpha.0",

View File

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

View File

@@ -3,6 +3,38 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.31](https://github.com/react-navigation/navigation-ex/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.0-alpha.30...@react-navigation/material-top-tabs@5.0.0-alpha.31) (2020-01-13)
**Note:** Version bump only for package @react-navigation/material-top-tabs
# [5.0.0-alpha.30](https://github.com/react-navigation/navigation-ex/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.0-alpha.29...@react-navigation/material-top-tabs@5.0.0-alpha.30) (2020-01-09)
**Note:** Version bump only for package @react-navigation/material-top-tabs
# [5.0.0-alpha.29](https://github.com/react-navigation/navigation-ex/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.0-alpha.27...@react-navigation/material-top-tabs@5.0.0-alpha.29) (2020-01-09)
**Note:** Version bump only for package @react-navigation/material-top-tabs
# [5.0.0-alpha.28](https://github.com/react-navigation/navigation-ex/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.0.0-alpha.27...@react-navigation/material-top-tabs@5.0.0-alpha.28) (2020-01-09)
**Note:** Version bump only for package @react-navigation/material-top-tabs
# [5.0.0-alpha.27](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/material-top-tabs@5.0.0-alpha.26...@react-navigation/material-top-tabs@5.0.0-alpha.27) (2020-01-05)

View File

@@ -2,6 +2,8 @@
React Navigation integration for animated tab view component from [`react-native-tab-view`](https://github.com/react-native-community/react-native-tab-view).
Documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/en/next/material-top-tab-navigator.html).
## Installation
Open a Terminal in your project's folder and run,

View File

@@ -11,17 +11,13 @@
"material",
"tab"
],
"version": "5.0.0-alpha.27",
"version": "5.0.0-alpha.31",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/material-top-tabs"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/material-top-tabs",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/material-top-tabs/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -34,20 +30,20 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0-alpha.20",
"@react-navigation/routers": "^5.0.0-alpha.23",
"color": "^3.1.2"
},
"devDependencies": {
"@react-native-community/bob": "^0.7.0",
"@types/react": "^16.9.16",
"@types/react-native": "^0.60.25",
"@react-native-community/bob": "^0.7.1",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",
"react": "~16.9.0",
"react-native": "~0.61.5",
"react-native-gesture-handler": "^1.5.0",
"react-native-gesture-handler": "^1.5.3",
"react-native-reanimated": "^1.4.0",
"react-native-tab-view": "^2.11.0",
"typescript": "^3.7.3"
"typescript": "^3.7.4"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0-alpha.0",

View File

@@ -86,11 +86,6 @@ export type MaterialTopTabNavigationOptions = {
* ID to locate this tab button in tests.
*/
tabBarTestID?: string;
/**
* Boolean indicating whether the tab bar is visible when this screen is active.
*/
tabBarVisible?: boolean;
};
export type MaterialTopTabDescriptor = Descriptor<

View File

@@ -32,15 +32,6 @@ export default function MaterialTopTabView({
const { colors } = useTheme();
const renderTabBar = (props: SceneRendererProps) => {
const route = state.routes[state.index];
const options = descriptors[route.key].options;
const tabBarVisible = options.tabBarVisible !== false;
if (tabBarVisible === false) {
return null;
}
return tabBar({
...tabBarOptions,
...props,

View File

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

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [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

View File

@@ -2,6 +2,8 @@
Stack navigator for React Native using native primitives for navigation. Uses [`react-native-screens`](https://github.com/kmagiera/react-native-screens) under the hood.
Documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/en/next/native-stack-navigator.html).
Expo SDK 35 and lower is not supported as it includes an older version of `react-native-screens`.
## Installation

View File

@@ -6,17 +6,13 @@
"react-native",
"react-navigation"
],
"version": "5.0.0-alpha.22",
"version": "5.0.0-alpha.25",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/native-stack"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/native-stack",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/native-stack/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -29,13 +25,13 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0-alpha.20"
"@react-navigation/routers": "^5.0.0-alpha.23"
},
"devDependencies": {
"@react-native-community/bob": "^0.7.0",
"@react-native-community/bob": "^0.7.1",
"del-cli": "^3.0.0",
"react-native-screens": "^2.0.0-alpha.19",
"typescript": "^3.7.3"
"react-native-screens": "^2.0.0-alpha.22",
"typescript": "^3.7.4"
},
"peerDependencies": {
"@react-navigation/native": "^5.0.0-alpha.0",

View File

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

View File

@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.25](https://github.com/react-navigation/navigation-ex/tree/master/packages/native/compare/@react-navigation/native@5.0.0-alpha.24...@react-navigation/native@5.0.0-alpha.25) (2020-01-13)
**Note:** Version bump only for package @react-navigation/native
# [5.0.0-alpha.24](https://github.com/react-navigation/navigation-ex/tree/master/packages/native/compare/@react-navigation/native@5.0.0-alpha.22...@react-navigation/native@5.0.0-alpha.24) (2020-01-09)
**Note:** Version bump only for package @react-navigation/native
# [5.0.0-alpha.23](https://github.com/react-navigation/navigation-ex/tree/master/packages/native/compare/@react-navigation/native@5.0.0-alpha.22...@react-navigation/native@5.0.0-alpha.23) (2020-01-09)
**Note:** Version bump only for package @react-navigation/native
# [5.0.0-alpha.22](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/native@5.0.0-alpha.21...@react-navigation/native@5.0.0-alpha.22) (2020-01-01)
**Note:** Version bump only for package @react-navigation/native

View File

@@ -1,6 +1,8 @@
# `@react-navigation/native`
React Native integration for React Navigation
React Native integration for React Navigation.
Documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/en/next/getting-started.html).
## Installation

View File

@@ -7,17 +7,13 @@
"ios",
"android"
],
"version": "5.0.0-alpha.22",
"version": "5.0.0-alpha.25",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/native"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/native",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/native/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -30,16 +26,16 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/core": "^5.0.0-alpha.30"
"@react-navigation/core": "^5.0.0-alpha.33"
},
"devDependencies": {
"@react-native-community/bob": "^0.7.0",
"@types/react": "^16.9.16",
"@types/react-native": "^0.60.25",
"@react-native-community/bob": "^0.7.1",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",
"react": "~16.9.0",
"react-native": "~0.61.5",
"typescript": "^3.7.3"
"typescript": "^3.7.4"
},
"peerDependencies": {
"react": "*",

View File

@@ -1,3 +1,9 @@
{
"extends": "../../tsconfig"
"extends": "../../tsconfig",
"references": [
{ "path": "../core" }
],
"compilerOptions": {
"outDir": "./lib/typescript"
}
}

View File

@@ -3,6 +3,36 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.23](https://github.com/react-navigation/navigation-ex/tree/master/packages/routers/compare/@react-navigation/routers@5.0.0-alpha.22...@react-navigation/routers@5.0.0-alpha.23) (2020-01-13)
**Note:** Version bump only for package @react-navigation/routers
# [5.0.0-alpha.22](https://github.com/react-navigation/navigation-ex/tree/master/packages/routers/compare/@react-navigation/routers@5.0.0-alpha.20...@react-navigation/routers@5.0.0-alpha.22) (2020-01-09)
### Bug Fixes
* change POP behaviour to remove elements from index only ([7a3d652](https://github.com/react-navigation/navigation-ex/tree/master/packages/routers/commit/7a3d652e847e173964a06cc9d859129ca0317861)), closes [#256](https://github.com/react-navigation/navigation-ex/tree/master/packages/routers/issues/256)
# [5.0.0-alpha.21](https://github.com/react-navigation/navigation-ex/tree/master/packages/routers/compare/@react-navigation/routers@5.0.0-alpha.20...@react-navigation/routers@5.0.0-alpha.21) (2020-01-09)
### Bug Fixes
* change POP behaviour to remove elements from index only ([7a3d652](https://github.com/react-navigation/navigation-ex/tree/master/packages/routers/commit/7a3d652e847e173964a06cc9d859129ca0317861)), closes [#256](https://github.com/react-navigation/navigation-ex/tree/master/packages/routers/issues/256)
# [5.0.0-alpha.20](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/routers@5.0.0-alpha.19...@react-navigation/routers@5.0.0-alpha.20) (2020-01-05)

View File

@@ -563,9 +563,48 @@ it('handles pop action', () => {
stale: false,
type: 'stack',
key: 'root',
index: 0,
index: 1,
routeNames: ['baz', 'bar', 'qux'],
routes: [{ key: 'baz-0', name: 'baz' }],
routes: [
{ key: 'baz-0', name: 'baz' },
{ key: 'qux-0', name: 'qux' },
],
});
expect(
router.getStateForAction(
{
stale: false,
type: 'stack',
key: 'root',
index: 4,
routeNames: ['baz', 'bar', 'qux'],
routes: [
{ key: 'baz-0', name: 'baz' },
{ key: 'bar-0', name: 'bar' },
{ key: 'qux-0', name: 'qux' },
{ key: 'quy-0', name: 'quy' },
{ key: 'quz-0', name: 'quz' },
],
},
{
...StackActions.pop(2),
target: 'root',
source: 'qux-0',
},
options
)
).toEqual({
stale: false,
type: 'stack',
key: 'root',
index: 2,
routeNames: ['baz', 'bar', 'qux'],
routes: [
{ key: 'baz-0', name: 'baz' },
{ key: 'quy-0', name: 'quy' },
{ key: 'quz-0', name: 'quz' },
],
});
expect(

View File

@@ -6,17 +6,13 @@
"react-native",
"react-navigation"
],
"version": "5.0.0-alpha.20",
"version": "5.0.0-alpha.23",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/routers"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/routers",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/routers/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -29,13 +25,13 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/core": "^5.0.0-alpha.30",
"@react-navigation/core": "^5.0.0-alpha.33",
"shortid": "^2.2.15"
},
"devDependencies": {
"@react-native-community/bob": "^0.7.0",
"@react-native-community/bob": "^0.7.1",
"del-cli": "^3.0.0",
"typescript": "^3.7.3"
"typescript": "^3.7.4"
},
"@react-native-community/bob": {
"source": "src",

View File

@@ -203,10 +203,10 @@ export default function StackRouter(options: StackRouterOptions) {
: state.index;
if (index > 0) {
const routes = state.routes.slice(
0,
Math.max(index - action.payload.count + 1, 1)
);
const count = Math.max(index - action.payload.count + 1, 0);
const routes = state.routes
.slice(0, count)
.concat(state.routes.slice(index + 1));
return {
...state,

View File

@@ -1,3 +1,9 @@
{
"extends": "../../tsconfig"
"extends": "../../tsconfig",
"references": [
{ "path": "../core" }
],
"compilerOptions": {
"outDir": "./lib/typescript"
}
}

View File

@@ -3,6 +3,103 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.0.0-alpha.59](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/compare/@react-navigation/stack@5.0.0-alpha.58...@react-navigation/stack@5.0.0-alpha.59) (2020-01-13)
**Note:** Version bump only for package @react-navigation/stack
# [5.0.0-alpha.58](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/compare/@react-navigation/stack@5.0.0-alpha.56...@react-navigation/stack@5.0.0-alpha.58) (2020-01-09)
### Bug Fixes
* change default screen change animation on web ([37d26ca](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/commit/37d26ca994f13dd78db234309b78122a52d4550c))
* change POP behaviour to remove elements from index only ([7a3d652](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/commit/7a3d652e847e173964a06cc9d859129ca0317861)), closes [#256](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/issues/256)
* clamp interpolated styles ([67798af](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/commit/67798af869dcbbf323629fc7e7cc9062d1e12c29))
* don't add header animation if mode is not float ([5470aea](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/commit/5470aeaca2f82c0cc320f773ed0cd1672a1e338a))
* only render last 3 headers in stack ([32ffaac](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/commit/32ffaac647fa711edf188a7929b762f5beb1df15))
# [5.0.0-alpha.57](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/compare/@react-navigation/stack@5.0.0-alpha.56...@react-navigation/stack@5.0.0-alpha.57) (2020-01-09)
### Bug Fixes
* change POP behaviour to remove elements from index only ([7a3d652](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/commit/7a3d652e847e173964a06cc9d859129ca0317861)), closes [#256](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/issues/256)
* clamp interpolated styles ([67798af](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/commit/67798af869dcbbf323629fc7e7cc9062d1e12c29))
* only render last 3 headers in stack ([32ffaac](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack/commit/32ffaac647fa711edf188a7929b762f5beb1df15))
# [5.0.0-alpha.56](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.55...@react-navigation/stack@5.0.0-alpha.56) (2020-01-07)
### Bug Fixes
* remove clamping in extrapolation of progress of stack animation ([d3f5c55](https://github.com/react-navigation/navigation-ex/commit/d3f5c55dbfbbff604c3289a40f3eccd91a60ee2e))
# [5.0.0-alpha.55](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.54...@react-navigation/stack@5.0.0-alpha.55) (2020-01-06)
### Bug Fixes
* memoize interpolated style to avoid extra work ([d8b88bd](https://github.com/react-navigation/navigation-ex/commit/d8b88bd83f57f2626d5b66bb157fd8e21a937c28))
# [5.0.0-alpha.54](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.53...@react-navigation/stack@5.0.0-alpha.54) (2020-01-05)
### Bug Fixes
* expose the header height even if not floating ([12d9083](https://github.com/react-navigation/navigation-ex/commit/12d90833eb36e9e7f229384ec8a05823b0a564d1))
* use memo for card container ([65ce20e](https://github.com/react-navigation/navigation-ex/commit/65ce20ecbc1e5f2dba9f1004cb29de03a6e5504a))
# [5.0.0-alpha.53](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.52...@react-navigation/stack@5.0.0-alpha.53) (2020-01-05)
### Bug Fixes
* compare with correct height when floating header height updates ([a9e584c](https://github.com/react-navigation/navigation-ex/commit/a9e584c3b765ae1e166a3a82b3fa0a40e8e2172a))
### Features
* expose header height in context ([133b59c](https://github.com/react-navigation/navigation-ex/commit/133b59cd175ddc899dff3b56bf3a0514c0c91ae6))
# [5.0.0-alpha.52](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.51...@react-navigation/stack@5.0.0-alpha.52) (2020-01-05)
### Features
* add headerStatusBarHeight option to stack ([b201fd2](https://github.com/react-navigation/navigation-ex/commit/b201fd20716a2f03cb9373c72281f5d396a9356d))
# [5.0.0-alpha.51](https://github.com/react-navigation/navigation-ex/compare/@react-navigation/stack@5.0.0-alpha.50...@react-navigation/stack@5.0.0-alpha.51) (2020-01-05)
**Note:** Version bump only for package @react-navigation/stack

View File

@@ -2,6 +2,8 @@
Stack navigator for React Navigation.
Documentation can be found on the [React Navigation website](https://reactnavigation.org/docs/en/next/stack-navigator.html).
## Installation
Open a Terminal in your project's folder and run,

View File

@@ -10,17 +10,13 @@
"android",
"stack"
],
"version": "5.0.0-alpha.51",
"version": "5.0.0-alpha.59",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/react-navigation/navigation-ex.git",
"directory": "packages/stack"
},
"repository": "https://github.com/react-navigation/navigation-ex/tree/master/packages/stack",
"main": "lib/commonjs/index.js",
"react-native": "src/index.tsx",
"module": "lib/module/index.js",
"types": "lib/typescript/stack/src/index.d.ts",
"types": "lib/typescript/src/index.d.ts",
"files": [
"src",
"lib"
@@ -33,23 +29,23 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.0.0-alpha.20",
"@react-navigation/routers": "^5.0.0-alpha.23",
"color": "^3.1.2",
"react-native-iphone-x-helper": "^1.2.1"
},
"devDependencies": {
"@react-native-community/bob": "^0.7.0",
"@react-native-community/bob": "^0.7.1",
"@react-native-community/masked-view": "^0.1.5",
"@types/color": "^3.0.0",
"@types/react": "^16.9.16",
"@types/react-native": "^0.60.25",
"@types/color": "^3.0.1",
"@types/react": "^16.9.17",
"@types/react-native": "^0.60.30",
"del-cli": "^3.0.0",
"react": "~16.9.0",
"react-native": "~0.61.5",
"react-native-gesture-handler": "^1.5.0",
"react-native-safe-area-context": "^0.6.0",
"react-native-screens": "^2.0.0-alpha.19",
"typescript": "^3.7.3"
"react-native-gesture-handler": "^1.5.3",
"react-native-safe-area-context": "^0.6.2",
"react-native-screens": "^2.0.0-alpha.22",
"typescript": "^3.7.4"
},
"peerDependencies": {
"@react-native-community/masked-view": "^0.1.1",

View File

@@ -20,6 +20,7 @@ export function forHorizontalIOS({
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.width, 0],
extrapolate: 'clamp',
}),
inverted
);
@@ -29,6 +30,7 @@ export function forHorizontalIOS({
next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, screen.width * -0.3],
extrapolate: 'clamp',
}),
inverted
)
@@ -37,11 +39,13 @@ export function forHorizontalIOS({
const overlayOpacity = current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.07],
extrapolate: 'clamp',
});
const shadowOpacity = current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 0.3],
extrapolate: 'clamp',
});
return {
@@ -70,6 +74,7 @@ export function forVerticalIOS({
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height, 0],
extrapolate: 'clamp',
}),
inverted
);
@@ -100,7 +105,20 @@ export function forModalPresentationIOS({
const statusBarHeight = insets.top;
const aspectRatio = screen.height / screen.width;
const progress = add(current.progress, next ? next.progress : 0);
const progress = add(
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
}),
next
? next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
})
: 0
);
const translateY = multiply(
progress.interpolate({
@@ -164,6 +182,7 @@ export function forFadeFromBottomAndroid({
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height * 0.08, 0],
extrapolate: 'clamp',
}),
inverted
);
@@ -198,6 +217,7 @@ export function forRevealFromBottomAndroid({
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height, 0],
extrapolate: 'clamp',
}),
inverted
);
@@ -206,6 +226,7 @@ export function forRevealFromBottomAndroid({
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [screen.height * (95.9 / 100) * -1, 0],
extrapolate: 'clamp',
}),
inverted
);
@@ -215,6 +236,7 @@ export function forRevealFromBottomAndroid({
next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, screen.height * (2 / 100) * -1],
extrapolate: 'clamp',
}),
inverted
)
@@ -223,6 +245,7 @@ export function forRevealFromBottomAndroid({
const overlayOpacity = current.progress.interpolate({
inputRange: [0, 0.36, 1],
outputRange: [0, 0.1, 0.1],
extrapolate: 'clamp',
});
return {
@@ -248,7 +271,20 @@ export function forScaleFromCenterAndroid({
next,
closing,
}: StackCardInterpolationProps): StackCardInterpolatedStyle {
const progress = add(current.progress, next ? next.progress : 0);
const progress = add(
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
}),
next
? next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
})
: 0
);
const opacity = progress.interpolate({
inputRange: [0, 0.8, 1, 1.2, 2],
@@ -260,6 +296,7 @@ export function forScaleFromCenterAndroid({
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0.9, 1],
extrapolate: 'clamp',
}),
progress.interpolate({
inputRange: [0, 1, 2],

View File

@@ -33,7 +33,20 @@ export function forUIKit({
// The back title also animates in from this position
const rightOffset = layouts.screen.width / 4;
const progress = add(current.progress, next ? next.progress : 0);
const progress = add(
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
}),
next
? next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
})
: 0
);
return {
leftButtonStyle: {
@@ -98,7 +111,21 @@ export function forFade({
current,
next,
}: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
const progress = add(current.progress, next ? next.progress : 0);
const progress = add(
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
}),
next
? next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
})
: 0
);
const opacity = progress.interpolate({
inputRange: [0, 1, 2],
outputRange: [0, 1, 0],
@@ -120,12 +147,26 @@ export function forFade({
/**
* Simple translate animation to translate the header along with the sliding screen.
*/
export function forStatic({
export function forSlide({
current,
next,
layouts: { screen },
}: StackHeaderInterpolationProps): StackHeaderInterpolatedStyle {
const progress = add(current.progress, next ? next.progress : 0);
const progress = add(
current.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
}),
next
? next.progress.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
})
: 0
);
const translateX = progress.interpolate({
inputRange: [0, 1, 2],
outputRange: I18nManager.isRTL

View File

@@ -103,9 +103,9 @@ export const ScaleFromCenterAndroid: TransitionPreset = {
export const DefaultTransition = Platform.select({
ios: SlideFromRightIOS,
default:
Platform.OS === 'android' && Platform.Version < ANDROID_VERSION_PIE
? FadeFromBottomAndroid
: RevealFromBottomAndroid,
Platform.OS === 'android' && Platform.Version >= ANDROID_VERSION_PIE
? RevealFromBottomAndroid
: FadeFromBottomAndroid,
});
/**

View File

@@ -36,8 +36,13 @@ export {
/**
* Utilities
*/
export { default as StackGestureContext } from './utils/StackGestureContext';
export { default as StackCardAnimationContext } from './utils/StackCardAnimationContext';
export { default as CardAnimationContext } from './utils/CardAnimationContext';
export { default as HeaderHeightContext } from './utils/HeaderHeightContext';
export { default as GestureHandlerRefContext } from './utils/GestureHandlerRefContext';
export { default as useCardAnimation } from './utils/useCardAnimation';
export { default as useHeaderHeight } from './utils/useHeaderHeight';
export { default as useGestureHandlerRef } from './utils/useGestureHandlerRef';
/**
* Types

View File

@@ -205,6 +205,12 @@ export type StackHeaderOptions = {
* This is useful if you want to render a semi-transparent header or a blurred background.
*/
headerTransparent?: boolean;
/**
* Extra padding to add at the top of header to account for translucent status bar.
* By default, it uses the top value from the safe area insets of the device.
* Pass 0 or a custom value to disable the default behaviour, and customize the height.
*/
headerStatusBarHeight?: number;
};
export type StackHeaderProps = {

View File

@@ -0,0 +1,3 @@
import * as React from 'react';
export default React.createContext<number | undefined>(undefined);

View File

@@ -0,0 +1,14 @@
import * as React from 'react';
import CardAnimationContext from './CardAnimationContext';
export default function useCardAnimation() {
const animation = React.useContext(CardAnimationContext);
if (animation === undefined) {
throw new Error(
"Couldn't find values for card animation. Are you inside a screen in Stack?"
);
}
return animation;
}

View File

@@ -0,0 +1,14 @@
import * as React from 'react';
import StackGestureRefContext from './GestureHandlerRefContext';
export default function useGestureHandlerRef() {
const ref = React.useContext(StackGestureRefContext);
if (ref === undefined) {
throw new Error(
"Couldn't find a ref for gesture handler. Are you inside a screen in Stack?"
);
}
return ref;
}

View File

@@ -0,0 +1,14 @@
import * as React from 'react';
import HeaderHeightContext from './HeaderHeightContext';
export default function useFloatingHeaderHeight() {
const height = React.useContext(HeaderHeightContext);
if (height === undefined) {
throw new Error(
"Couldn't find the header height. Are you inside a screen in Stack?"
);
}
return height;
}

View File

@@ -9,7 +9,10 @@ import { StackNavigationState } from '@react-navigation/routers';
import { EdgeInsets } from 'react-native-safe-area-context';
import Header from './Header';
import { forStatic } from '../../TransitionConfigs/HeaderStyleInterpolators';
import {
forSlide,
forNoAnimation,
} from '../../TransitionConfigs/HeaderStyleInterpolators';
import {
Layout,
Scene,
@@ -49,7 +52,7 @@ export default function HeaderContainer({
return (
<View pointerEvents="box-none" style={style}>
{scenes.map((scene, i, self) => {
{scenes.slice(-3).map((scene, i, self) => {
if ((mode === 'screen' && i !== self.length - 1) || !scene) {
return null;
}
@@ -78,14 +81,12 @@ export default function HeaderContainer({
const previousScene = self[i - 1];
const nextScene = self[i + 1];
const isHeaderStatic =
mode === 'float'
? (previousScene &&
previousScene.descriptor.options.headerShown === false &&
// We still need to animate when coming back from next scene
// A hacky way to check this is if the next scene exists
!nextScene) ||
(nextScene && nextScene.descriptor.options.headerShown === false)
: false;
(previousScene &&
previousScene.descriptor.options.headerShown === false &&
// We still need to animate when coming back from next scene
// A hacky way to check this is if the next scene exists
!nextScene) ||
(nextScene && nextScene.descriptor.options.headerShown === false);
const props = {
mode,
@@ -96,7 +97,12 @@ export default function HeaderContainer({
navigation: scene.descriptor.navigation as StackNavigationProp<
ParamListBase
>,
styleInterpolator: isHeaderStatic ? forStatic : styleInterpolator,
styleInterpolator:
mode === 'float'
? isHeaderStatic
? forSlide
: styleInterpolator
: forNoAnimation,
};
return (

View File

@@ -53,7 +53,10 @@ const warnIfHeaderStylesDefined = (styles: Record<string, any>) => {
});
};
export const getDefaultHeaderHeight = (layout: Layout, insets: EdgeInsets) => {
export const getDefaultHeaderHeight = (
layout: Layout,
statusBarHeight: number
) => {
const isLandscape = layout.width > layout.height;
let headerHeight;
@@ -71,7 +74,7 @@ export const getDefaultHeaderHeight = (layout: Layout, insets: EdgeInsets) => {
headerHeight = 64;
}
return headerHeight + insets.top;
return headerHeight + statusBarHeight;
};
export default class HeaderSegment extends React.Component<Props, State> {
@@ -163,6 +166,7 @@ export default class HeaderSegment extends React.Component<Props, State> {
headerRightContainerStyle: rightContainerStyle,
headerTitleContainerStyle: titleContainerStyle,
headerStyle: customHeaderStyle,
headerStatusBarHeight = insets.top,
styleInterpolator,
} = this.props;
@@ -184,7 +188,7 @@ export default class HeaderSegment extends React.Component<Props, State> {
);
const {
height = getDefaultHeaderHeight(layout, insets),
height = getDefaultHeaderHeight(layout, headerStatusBarHeight),
minHeight,
maxHeight,
backgroundColor,
@@ -311,7 +315,10 @@ export default class HeaderSegment extends React.Component<Props, State> {
pointerEvents="box-none"
style={[{ height, minHeight, maxHeight, opacity, transform }]}
>
<View pointerEvents="none" style={{ height: insets.top }} />
<View
pointerEvents="none"
style={{ height: headerStatusBarHeight }}
/>
<View pointerEvents="box-none" style={styles.content}>
{leftButton ? (
<Animated.View

View File

@@ -16,8 +16,8 @@ import {
} from 'react-native-gesture-handler';
import { EdgeInsets } from 'react-native-safe-area-context';
import Color from 'color';
import StackGestureContext from '../../utils/StackGestureContext';
import StackCardAnimationContext from '../../utils/StackCardAnimationContext';
import StackGestureRefContext from '../../utils/GestureHandlerRefContext';
import CardAnimationContext from '../../utils/CardAnimationContext';
import getDistanceForDirection from '../../utils/getDistanceForDirection';
import getInvertedMultiplier from '../../utils/getInvertedMultiplier';
import memoize from '../../utils/memoize';
@@ -30,7 +30,7 @@ import {
type Props = ViewProps & {
index: number;
closing?: boolean;
closing: boolean;
next?: Animated.AnimatedInterpolation;
current: Animated.AnimatedInterpolation;
gesture: Animated.Value;
@@ -135,7 +135,7 @@ export default class Card extends React.Component<Props> {
closing,
velocity,
}: {
closing?: boolean;
closing: boolean;
velocity?: number;
}) => {
const {
@@ -159,7 +159,7 @@ export default class Card extends React.Component<Props> {
this.setPointerEventsEnabled(!closing);
this.handleStartInteraction();
onTransitionStart?.({ closing: Boolean(closing) });
onTransitionStart?.({ closing });
animation(gesture, {
...spec.config,
velocity,
@@ -273,6 +273,38 @@ export default class Card extends React.Component<Props> {
}
};
// Memoize this to avoid extra work on re-render
private getInterpolatedStyle = memoize(
(
styleInterpolator: StackCardStyleInterpolator,
index: number,
current: Animated.AnimatedInterpolation,
next: Animated.AnimatedInterpolation | undefined,
layout: Layout,
insetTop: number,
insetRight: number,
insetBottom: number,
insetLeft: number
) =>
styleInterpolator({
index,
current: { progress: current },
next: next && { progress: next },
closing: this.isClosing,
swiping: this.isSwiping,
inverted: this.inverted,
layouts: {
screen: layout,
},
insets: {
top: insetTop,
right: insetRight,
bottom: insetBottom,
left: insetLeft,
},
})
);
// Keep track of the animation context when deps changes.
private getCardAnimationContext = memoize(
(
@@ -369,18 +401,17 @@ export default class Card extends React.Component<Props> {
...rest
} = this.props;
const interpolatedStyle = styleInterpolator({
const interpolatedStyle = this.getInterpolatedStyle(
styleInterpolator,
index,
current: { progress: current },
next: next && { progress: next },
closing: this.isClosing,
swiping: this.isSwiping,
inverted: this.inverted,
layouts: {
screen: layout,
},
insets,
});
current,
next,
layout,
insets.top,
insets.right,
insets.bottom,
insets.left
);
const animationContext = this.getCardAnimationContext(
index,
@@ -421,48 +452,48 @@ export default class Card extends React.Component<Props> {
: false;
return (
<StackGestureContext.Provider value={this.gestureRef}>
<View pointerEvents="box-none" {...rest}>
{overlayEnabled && overlayStyle ? (
<Animated.View
pointerEvents="none"
style={[styles.overlay, overlayStyle]}
/>
) : null}
<View pointerEvents="box-none" {...rest}>
{overlayEnabled && overlayStyle ? (
<Animated.View
style={[styles.container, containerStyle, customContainerStyle]}
pointerEvents="box-none"
pointerEvents="none"
style={[styles.overlay, overlayStyle]}
/>
) : null}
<Animated.View
style={[styles.container, containerStyle, customContainerStyle]}
pointerEvents="box-none"
>
<PanGestureHandler
ref={this.gestureRef}
enabled={layout.width !== 0 && gestureEnabled}
onGestureEvent={handleGestureEvent}
onHandlerStateChange={this.handleGestureStateChange}
{...this.gestureActivationCriteria()}
>
<PanGestureHandler
ref={this.gestureRef}
enabled={layout.width !== 0 && gestureEnabled}
onGestureEvent={handleGestureEvent}
onHandlerStateChange={this.handleGestureStateChange}
{...this.gestureActivationCriteria()}
>
<Animated.View style={[styles.container, cardStyle]}>
{shadowEnabled && shadowStyle && !isTransparent ? (
<Animated.View
style={[
styles.shadow,
gestureDirection === 'horizontal'
? styles.shadowHorizontal
: styles.shadowVertical,
shadowStyle,
]}
pointerEvents="none"
/>
) : null}
<View ref={this.content} style={[styles.content, contentStyle]}>
<StackCardAnimationContext.Provider value={animationContext}>
<Animated.View style={[styles.container, cardStyle]}>
{shadowEnabled && shadowStyle && !isTransparent ? (
<Animated.View
style={[
styles.shadow,
gestureDirection === 'horizontal'
? styles.shadowHorizontal
: styles.shadowVertical,
shadowStyle,
]}
pointerEvents="none"
/>
) : null}
<View ref={this.content} style={[styles.content, contentStyle]}>
<StackGestureRefContext.Provider value={this.gestureRef}>
<CardAnimationContext.Provider value={animationContext}>
{children}
</StackCardAnimationContext.Provider>
</View>
</Animated.View>
</PanGestureHandler>
</Animated.View>
</View>
</StackGestureContext.Provider>
</CardAnimationContext.Provider>
</StackGestureRefContext.Provider>
</View>
</Animated.View>
</PanGestureHandler>
</Animated.View>
</View>
);
}
}

View File

@@ -4,6 +4,7 @@ import { StackNavigationState } from '@react-navigation/routers';
import { Route, useTheme } from '@react-navigation/native';
import { Props as HeaderContainerProps } from '../Header/HeaderContainer';
import Card from './Card';
import HeaderHeightContext from '../../utils/HeaderHeightContext';
import { Scene, Layout, StackHeaderMode, TransitionPreset } from '../../types';
type Props = TransitionPreset & {
@@ -47,10 +48,14 @@ type Props = TransitionPreset & {
headerMode: StackHeaderMode;
headerShown?: boolean;
headerTransparent?: boolean;
floatingHeaderHeight: number;
headerHeight: number;
onHeaderHeightChange: (props: {
route: Route<string>;
height: number;
}) => void;
};
export default function CardContainer({
function CardContainer({
active,
cardOverlayEnabled,
cardShadowEnabled,
@@ -58,7 +63,6 @@ export default function CardContainer({
cardStyleInterpolator,
closing,
gesture,
floatingHeaderHeight,
focused,
gestureDirection,
gestureEnabled,
@@ -69,6 +73,8 @@ export default function CardContainer({
headerShown,
headerStyleInterpolator,
headerTransparent,
headerHeight,
onHeaderHeightChange,
index,
layout,
onCloseRoute,
@@ -149,14 +155,18 @@ export default function CardContainer({
pointerEvents="box-none"
containerStyle={
headerMode === 'float' && !headerTransparent && headerShown !== false
? { marginTop: floatingHeaderHeight }
? { marginTop: headerHeight }
: null
}
contentStyle={[{ backgroundColor: colors.background }, cardStyle]}
style={StyleSheet.absoluteFill}
>
<View style={styles.container}>
<View style={styles.scene}>{renderScene({ route: scene.route })}</View>
<View style={styles.scene}>
<HeaderHeightContext.Provider value={headerHeight}>
{renderScene({ route: scene.route })}
</HeaderHeightContext.Provider>
</View>
{headerMode === 'screen'
? renderHeader({
mode: 'screen',
@@ -166,6 +176,7 @@ export default function CardContainer({
state,
getPreviousRoute,
styleInterpolator: headerStyleInterpolator,
onContentHeightChange: onHeaderHeightChange,
})
: null}
</View>
@@ -173,6 +184,8 @@ export default function CardContainer({
);
}
export default React.memo(CardContainer);
const styles = StyleSheet.create({
container: {
flex: 1,

View File

@@ -71,7 +71,7 @@ type State = {
scenes: Scene<Route<string>>[];
gestures: GestureValues;
layout: Layout;
floatingHeaderHeights: Record<string, number>;
headerHeights: Record<string, number>;
};
const EPSILON = 1e-5;
@@ -112,7 +112,7 @@ const MaybeScreen = ({
const FALLBACK_DESCRIPTOR = Object.freeze({ options: {} });
const getFloatingHeaderHeights = (
const getHeaderHeights = (
routes: Route<string>[],
insets: EdgeInsets,
descriptors: StackDescriptorMap,
@@ -125,13 +125,17 @@ const getFloatingHeaderHeights = (
options.headerStyle || {}
);
const safeAreaInsets = {
...insets,
...options.safeAreaInsets,
};
const { headerStatusBarHeight = safeAreaInsets.top } = options;
acc[curr.key] =
typeof height === 'number'
? height
: getDefaultHeaderHeight(layout, {
...insets,
...options.safeAreaInsets,
});
: getDefaultHeaderHeight(layout, headerStatusBarHeight);
return acc;
}, {});
@@ -163,14 +167,12 @@ const getProgressFromGesture = (
return gesture.interpolate({
inputRange: [0, distance],
outputRange: [1, 0],
extrapolate: 'clamp',
});
}
return gesture.interpolate({
inputRange: [distance, 0],
outputRange: [0, 1],
extrapolate: 'clamp',
});
};
@@ -279,12 +281,12 @@ export default class CardStack extends React.Component<Props, State> {
}),
gestures,
descriptors: props.descriptors,
floatingHeaderHeights: getFloatingHeaderHeights(
headerHeights: getHeaderHeights(
props.routes,
props.insets,
state.descriptors,
state.layout,
state.floatingHeaderHeights
state.headerHeights
),
};
}
@@ -300,7 +302,7 @@ export default class CardStack extends React.Component<Props, State> {
// This is not a great heuristic here. We don't know synchronously
// on mount what the header height is so we have just used the most
// common cases here.
floatingHeaderHeights: {},
headerHeights: {},
};
private handleLayout = (e: LayoutChangeEvent) => {
@@ -315,7 +317,7 @@ export default class CardStack extends React.Component<Props, State> {
return {
layout,
floatingHeaderHeights: getFloatingHeaderHeights(
headerHeights: getHeaderHeights(
props.routes,
props.insets,
state.descriptors,
@@ -326,23 +328,23 @@ export default class CardStack extends React.Component<Props, State> {
});
};
private handleFloatingHeaderLayout = ({
private handleHeaderLayout = ({
route,
height,
}: {
route: Route<string>;
height: number;
}) => {
this.setState(({ floatingHeaderHeights }) => {
const previousHeight = this.state.floatingHeaderHeights[route.key];
this.setState(({ headerHeights }) => {
const previousHeight = headerHeights[route.key];
if (previousHeight && previousHeight === height) {
if (previousHeight === height) {
return null;
}
return {
floatingHeaderHeights: {
...floatingHeaderHeights,
headerHeights: {
...headerHeights,
[route.key]: height,
},
};
@@ -371,7 +373,7 @@ export default class CardStack extends React.Component<Props, State> {
onPageChangeCancel,
} = this.props;
const { scenes, layout, gestures, floatingHeaderHeights } = this.state;
const { scenes, layout, gestures, headerHeights } = this.state;
const focusedRoute = state.routes[state.index];
const focusedDescriptor = descriptors[focusedRoute.key];
@@ -517,7 +519,8 @@ export default class CardStack extends React.Component<Props, State> {
onPageChangeConfirm={onPageChangeConfirm}
onPageChangeCancel={onPageChangeCancel}
gestureResponseDistance={gestureResponseDistance}
floatingHeaderHeight={floatingHeaderHeights[route.key]}
headerHeight={headerHeights[route.key]}
onHeaderHeightChange={this.handleHeaderLayout}
getPreviousRoute={getPreviousRoute}
headerMode={headerMode}
headerShown={headerShown}
@@ -544,7 +547,7 @@ export default class CardStack extends React.Component<Props, State> {
scenes,
state,
getPreviousRoute,
onContentHeightChange: this.handleFloatingHeaderLayout,
onContentHeightChange: this.handleHeaderLayout,
styleInterpolator:
focusedOptions.headerStyleInterpolator !== undefined
? focusedOptions.headerStyleInterpolator

View File

@@ -282,27 +282,19 @@ class StackView extends React.Component<Props, State> {
// If a route exists in state, trigger a pop
// This will happen in when the route was closed from the card component
// e.g. When the close animation triggered from a gesture ends
// For the cleanup, the card needs to call this function again from its componentDidUpdate
navigation.dispatch({
...StackActions.pop(),
source: route.key,
target: state.key,
});
} else {
// Otherwise, the animation was triggered due to a route removal
// In this case, we need to clean up any state tracking the route and pop it immediately
// @ts-ignore
this.setState(state => ({
routes: state.routes.filter(r => r.key !== route.key),
openingRouteKeys: state.openingRouteKeys.filter(
key => key !== route.key
),
closingRouteKeys: state.closingRouteKeys.filter(
key => key !== route.key
),
}));
}
// We need to clean up any state tracking the route and pop it immediately
this.setState(state => ({
routes: state.routes.filter(r => r.key !== route.key),
openingRouteKeys: state.openingRouteKeys.filter(key => key !== route.key),
closingRouteKeys: state.closingRouteKeys.filter(key => key !== route.key),
}));
};
private handleTransitionStart = (

View File

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

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env node
/* eslint-disable import/no-commonjs */
const fs = require('fs');
const path = require('path');
const packages = path.join(__dirname, '..', 'packages');
const invalid = [];
fs.readdirSync(packages).forEach(name => {
const dir = path.join(packages, name);
if (fs.statSync(path.join(packages, name)).isDirectory()) {
const pak = JSON.parse(
fs.readFileSync(path.join(dir, 'package.json'), 'utf8')
);
if (pak.types && !fs.existsSync(path.join(dir, pak.types))) {
invalid.push(pak);
}
}
});
if (invalid.length) {
console.log(
'Found invalid path to type definitions in the following packages:\n',
invalid.map(p => `- ${p.name} (${p.types})`).join('\n')
);
}

View File

@@ -3,11 +3,11 @@
"baseUrl": ".",
"paths": {
"@react-navigation/*": [
"./packages/*/src",
"./packages/*/lib/typescript"
"./packages/*/src"
],
"use-subscription": ["./typings/use-subscription.d"]
},
"composite": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"esModuleInterop": true,

3029
yarn.lock

File diff suppressed because it is too large Load Diff