The PR changes a few things about linking configuration:
- Moves the configuration for screens to a screens property so that it's possible to specify other options like `initialRouteName` for the navigator at root
- The nesting in the configuration needs to strictly match the shape of the navigation tree, it can't just rely on URL's shape anymore
- If a screen is not specified in the configuration, it won't be parsed to/from the URL (this is essential to handle unmatched screens)
- Treat `path: ''` and no specified path in the same way, unless `exact` is specified
- Disallow specifying unmatched screen with old format
- Add support for `initialRouteName` at top level
- Automatically adapt old configuration to new format
Added `collapsable={false}` to the View in order for the Android to render screens properly. This issue is most probably similar to 9c06a92d09 but fixes it on Android since the View seems to be removed from a native view hierarchy due to not drawing anything. To see the bug go to https://github.com/software-mansion/react-native-screens/issues/544.
The `devtools` package extracts the redux devtools extension integration to a separate package. In future we can add more tools such as flipper integration to this package.
Usage:
```js
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { useReduxDevToolsExtension } from '@react-navigation/devtools';
export default function App() {
const navigationRef = React.useRef();
useReduxDevToolsExtension(navigationRef);
return (
<NavigationContainer ref={navigationRef}>{/* ... */}</NavigationContainer>
);
}
```
Currently, to access the focused child screen, we need to do something like this:
```js
const routeName = route.state
? route.state.routes[route.state.index].name
: route.params?.screen || 'Feed';
```
However, it doesn't handle some cases, such as when `route.state` is partial. This helper will make it easier:
```js
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Feed';
```
## Motivation
Right now `headerMode: float` renders an absolutely-positioned header. To offset the content appropriately, it then measures the height of the header and compensates with a margin. This approach unfortunately doesn't work well for animations.
Before | After
:-------------------------:|:-------------------------:
<img src="http://ashoat.com/jerky_absolute.gif" width="300" /> | <img src="http://ashoat.com/smooth_relative.gif" width="300" />
## Approach
When rendering the header absolutely we want to render it above (after, in sibling order) the content. But when rendering it relatively we want to render it first (before, in sibling order).
The margin compensation code is no longer necessary so I removed it.
## Test plan
I used the `StackHeaderCustomization` example to make sure transitions between `headerTransparent` and `!headerTransparent` looked good. I added a custom (taller) header to test if height transitions looked good, and toggled `headerShown` to make sure that transitioned well too.
Would be open to any other suggestions of things to test!
The PR reworks history integration to better integrate with browser's history stack and supports nested navigation more reliably:
- On each navigation, save the navigation in memory and use it to reset the state when user presses back/forward
- Improve heuristic to determine if we should do a push, replace or back
This closes#8230, closes#8284 and closes#8344
Currently, if we don't have matching routes for a path, we'll reuse the path name for the route name. This doesn't produce an error, and renders the initial route in the navigator. However, the user doesn't have a way of handling this with the default configuration.
This PR adds support for a wildcard pattern ('*'). The wildcard pattern will be matched after all other patterns were matched and will always match unmatched screens. This allows the user to implement a 404 screen.
Example:
```js
{
Home: '',
Profile: 'user/:id',
404: '*',
}
```
This config will return the `404` route for paths which didn't match `Home` or `Profile`, e.g. - `/test`
Closes#8019
Co-authored-by: Evan Bacon <baconbrix@gmail.com>