Compare commits

..

16 Commits

Author SHA1 Message Date
osdnk
a248c453ba chore: publish
- @react-navigation/stack@5.2.7
2020-03-26 17:07:40 +01:00
Wojciech Stanisz
e097df880a fix: add pointerEvents=box-none to overlay View (#7871) 2020-03-26 13:38:30 +01:00
Satyajit Sahoo
856449b200 chore: publish
- @react-navigation/bottom-tabs@5.2.4
 - @react-navigation/compat@5.1.6
 - @react-navigation/core@5.3.1
 - @react-navigation/drawer@5.3.4
 - @react-navigation/material-bottom-tabs@5.1.6
 - @react-navigation/material-top-tabs@5.1.6
 - @react-navigation/native@5.1.3
 - @react-navigation/stack@5.2.6
2020-03-23 17:07:43 +01:00
Steven Bell
d94e43c3c8 fix: add info about android launchMode in useLinking error 2020-03-23 16:39:18 +01:00
Satyajit Sahoo
3096de6286 fix: only call listeners for focused screen for global events 2020-03-23 13:43:43 +01:00
Satyajit Sahoo
1c001424b5 fix: don't emit events for screens that don't exist anymore 2020-03-23 13:03:33 +01:00
Satyajit Sahoo
0f2368965c chore: publish
- @react-navigation/stack@5.2.5
2020-03-23 11:42:01 +01:00
Satyajit Sahoo
61f16d3f25 fix: fix swipe gestures requiring a lot of velocity to dismiss 2020-03-23 11:40:37 +01:00
Satyajit Sahoo
853740bfaf chore: publish
- @react-navigation/bottom-tabs@5.2.3
 - @react-navigation/compat@5.1.5
 - @react-navigation/core@5.3.0
 - @react-navigation/drawer@5.3.3
 - @react-navigation/material-bottom-tabs@5.1.5
 - @react-navigation/material-top-tabs@5.1.5
 - @react-navigation/native@5.1.2
 - @react-navigation/routers@5.2.0
 - @react-navigation/stack@5.2.4
2020-03-23 00:00:55 +01:00
Satyajit Sahoo
179b6312fe chore: update prettier 2020-03-22 23:58:06 +01:00
Satyajit Sahoo
043924ca48 fix: fix swipe not dismissing card in RTL
closes #7841
2020-03-22 23:55:16 +01:00
Satyajit Sahoo
813a5903b5 feat: add keys to routes missing keys during reset 2020-03-22 23:38:40 +01:00
Satyajit Sahoo
3709e652f4 feat: support function in listeners prop 2020-03-22 23:33:25 +01:00
Satyajit Sahoo
5b15c7164f fix: return correct value for isFocused after changing screens
fixes #7843
2020-03-22 23:31:04 +01:00
Satyajit Sahoo
e030932497 chore: publish
- @react-navigation/stack@5.2.3
2020-03-19 21:56:36 +01:00
Tien Pham
adbfedcd58 fix: use the correct velocity value in closing animation (#7836)
In this commit f24d3a3461 we modified the `velocity` in inverted gesture, but since we also use this value in the closing animation, the change in that commit also introduced a new bug:
![Mar-20-2020 03-40-05](https://user-images.githubusercontent.com/57227217/77113229-006f0500-6a5d-11ea-97b5-571e8301cd87.gif)

This PR fixes the issue by keeping the original velocity value.
2020-03-19 21:55:03 +01:00
82 changed files with 708 additions and 253 deletions

View File

@@ -1,4 +1,4 @@
module.exports = function(api) {
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],

View File

@@ -15,8 +15,8 @@ const modules = ['@expo/vector-icons']
// List all packages under `packages/`
.readdirSync(packages)
// Ignore hidden files such as .DS_Store
.filter(p => !p.startsWith('.'))
.map(p => {
.filter((p) => !p.startsWith('.'))
.map((p) => {
const pak = JSON.parse(
fs.readFileSync(path.join(packages, p, 'package.json'), 'utf8')
);
@@ -50,9 +50,9 @@ module.exports = {
blacklistRE: blacklist(
fs
.readdirSync(packages)
.map(p => path.join(packages, p))
.map((p) => path.join(packages, p))
.map(
it => new RegExp(`^${escape(path.join(it, 'node_modules'))}\\/.*$`)
(it) => new RegExp(`^${escape(path.join(it, 'node_modules'))}\\/.*$`)
)
),
@@ -65,7 +65,7 @@ module.exports = {
},
server: {
enhanceMiddleware: middleware => {
enhanceMiddleware: (middleware) => {
return (req, res, next) => {
// 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

View File

@@ -28,7 +28,7 @@ export default function BottomTabsScreen() {
return (
<BottomTabs.Navigator
screenOptions={{
tabBarButton: props => <TouchableBounce {...props} />,
tabBarButton: (props) => <TouchableBounce {...props} />,
}}
>
<BottomTabs.Screen
@@ -38,7 +38,7 @@ export default function BottomTabsScreen() {
tabBarIcon: getTabBarIcon('file-document-box'),
}}
>
{props => <SimpleStackScreen {...props} headerMode="none" />}
{(props) => <SimpleStackScreen {...props} headerMode="none" />}
</BottomTabs.Screen>
<BottomTabs.Screen
name="Chat"

View File

@@ -15,7 +15,7 @@ export default function BottomTabsScreen() {
return (
<BottomTabs.Navigator>
{tabs.map(i => (
{tabs.map((i) => (
<BottomTabs.Screen
key={i}
name={`tab-${i}`}
@@ -29,12 +29,14 @@ export default function BottomTabsScreen() {
{() => (
<View style={styles.container}>
<Title>Tab {i}</Title>
<Button onPress={() => setTabs(tabs => [...tabs, tabs.length])}>
<Button onPress={() => setTabs((tabs) => [...tabs, tabs.length])}>
Add a tab
</Button>
<Button
onPress={() =>
setTabs(tabs => (tabs.length > 1 ? tabs.slice(0, -1) : tabs))
setTabs((tabs) =>
tabs.length > 1 ? tabs.slice(0, -1) : tabs
)
}
>
Remove a tab

View File

@@ -28,7 +28,7 @@ export default function MaterialBottomTabsScreen() {
tabBarColor: '#C9E7F8',
}}
>
{props => <SimpleStackScreen {...props} headerMode="none" />}
{(props) => <SimpleStackScreen {...props} headerMode="none" />}
</MaterialBottomTabs.Screen>
<MaterialBottomTabs.Screen
name="Chat"

View File

@@ -68,10 +68,7 @@ export default function Chat(props: Partial<ScrollViewProps>) {
styles.input,
{ backgroundColor: colors.card, color: colors.text },
]}
placeholderTextColor={Color(colors.text)
.alpha(0.5)
.rgb()
.string()}
placeholderTextColor={Color(colors.text).alpha(0.5).rgb().string()}
placeholder="Write a message"
underlineColorAndroid="transparent"
/>

View File

@@ -51,10 +51,7 @@ export default function NewsFeed(props: Props) {
<Card style={styles.card}>
<TextInput
placeholder="What's on your mind?"
placeholderTextColor={Color(colors.text)
.alpha(0.5)
.rgb()
.string()}
placeholderTextColor={Color(colors.text).alpha(0.5).rgb().string()}
style={styles.input}
/>
</Card>

View File

@@ -224,7 +224,7 @@ export default function App() {
<NavigationContainer
ref={containerRef}
initialState={initialState}
onStateChange={state =>
onStateChange={(state) =>
AsyncStorage.setItem(
NAVIGATION_PERSISTENCE_KEY,
JSON.stringify(state)
@@ -298,12 +298,12 @@ export default function App() {
theme.dark ? 'light' : 'dark'
);
setTheme(t => (t.dark ? DefaultTheme : DarkTheme));
setTheme((t) => (t.dark ? DefaultTheme : DarkTheme));
}}
/>
<Divider />
{(Object.keys(SCREENS) as (keyof typeof SCREENS)[]).map(
name => (
(name) => (
<List.Item
key={name}
title={SCREENS[name].title}
@@ -315,7 +315,7 @@ export default function App() {
)}
</Stack.Screen>
{(Object.keys(SCREENS) as (keyof typeof SCREENS)[]).map(
name => (
(name) => (
<Stack.Screen
key={name}
name={name}

View File

@@ -7,7 +7,7 @@ const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const node_modules = path.resolve(__dirname, '..', 'node_modules');
const packages = path.resolve(__dirname, '..', 'packages');
module.exports = async function(env, argv) {
module.exports = async function (env, argv) {
const config = await createExpoWebpackConfigAsync(env, argv);
config.context = path.resolve(__dirname, '..');
@@ -20,7 +20,7 @@ module.exports = async function(env, argv) {
});
config.resolve.plugins = config.resolve.plugins.filter(
p => !(p instanceof ModuleScopePlugin)
(p) => !(p instanceof ModuleScopePlugin)
);
Object.assign(config.resolve.alias, {
@@ -30,7 +30,7 @@ module.exports = async function(env, argv) {
'@expo/vector-icons': path.resolve(node_modules, '@expo/vector-icons'),
});
fs.readdirSync(packages).forEach(name => {
fs.readdirSync(packages).forEach((name) => {
config.resolve.alias[`@react-navigation/${name}`] = path.resolve(
packages,
name,

View File

@@ -43,7 +43,7 @@
"husky": "^4.2.3",
"jest": "^25.1.0",
"lerna": "^3.20.2",
"prettier": "^1.19.1",
"prettier": "^2.0.1",
"typescript": "^3.7.5"
},
"resolutions": {

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.2.4](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.2.3...@react-navigation/bottom-tabs@5.2.4) (2020-03-23)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.2.2...@react-navigation/bottom-tabs@5.2.3) (2020-03-22)
**Note:** Version bump only for package @react-navigation/bottom-tabs
## [5.2.2](https://github.com/react-navigation/react-navigation/tree/master/packages/bottom-tabs/compare/@react-navigation/bottom-tabs@5.2.1...@react-navigation/bottom-tabs@5.2.2) (2020-03-19)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/bottom-tabs",
"description": "Bottom tab navigator following iOS design guidelines",
"version": "5.2.2",
"version": "5.2.4",
"keywords": [
"react-native-component",
"react-component",
@@ -35,7 +35,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.10.0",
"@react-navigation/native": "^5.1.1",
"@react-navigation/native": "^5.1.3",
"@types/color": "^3.0.1",
"@types/react": "^16.9.23",
"@types/react-native": "^0.61.22",

View File

@@ -121,7 +121,7 @@ export default function BottomTabBar({
const handleLayout = (e: LayoutChangeEvent) => {
const { height, width } = e.nativeEvent.layout;
setLayout(layout => {
setLayout((layout) => {
if (height === layout.height && width === layout.width) {
return layout;
} else {

View File

@@ -133,9 +133,7 @@ export default function BottomTabBarItem({
const inactiveTintColor =
customInactiveTintColor === undefined
? Color(colors.text)
.mix(Color(colors.card), 0.5)
.hex()
? Color(colors.text).mix(Color(colors.card), 0.5).hex()
: customInactiveTintColor;
const renderLabel = ({ focused }: { focused: boolean }) => {

View File

@@ -30,7 +30,7 @@ type Props = {
export default function SafeAreaProviderCompat({ children }: Props) {
return (
<SafeAreaConsumer>
{insets => {
{(insets) => {
if (insets) {
// If we already have insets, don't wrap the stack in another safe area provider
// This avoids an issue with updates at the cost of potentially incorrect values

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.1.6](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.5...@react-navigation/compat@5.1.6) (2020-03-23)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.4...@react-navigation/compat@5.1.5) (2020-03-22)
**Note:** Version bump only for package @react-navigation/compat
## [5.1.4](https://github.com/react-navigation/react-navigation/tree/master/packages/compat/compare/@react-navigation/compat@5.1.3...@react-navigation/compat@5.1.4) (2020-03-19)
**Note:** Version bump only for package @react-navigation/compat

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/compat",
"description": "Compatibility layer to write navigator definitions in static configuration format",
"version": "5.1.4",
"version": "5.1.6",
"license": "MIT",
"repository": "https://github.com/react-navigation/react-navigation/tree/master/packages/compat",
"bugs": {
@@ -26,7 +26,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.10.0",
"@react-navigation/native": "^5.1.1",
"@react-navigation/native": "^5.1.3",
"@types/react": "^16.9.23",
"react": "~16.9.0",
"typescript": "^3.7.5"

View File

@@ -69,7 +69,7 @@ export default function createCompatNavigatorFactory<
function Navigator({ screenProps }: { screenProps?: unknown }) {
const screens = React.useMemo(
() =>
routeNames.map(name => {
routeNames.map((name) => {
let getScreenComponent: () => CompatScreenType<NavigationPropType>;
let initialParams;

View File

@@ -16,7 +16,7 @@ export default function useCompatNavigation<
const route = useRoute();
const isFirstRouteInParent = useNavigationState(
state => state.routes[0].key === route.key
(state) => state.routes[0].key === route.key
);
const context = React.useRef<Record<string, any>>({});

View File

@@ -26,8 +26,9 @@ export default function withNavigation<
return <Comp ref={onRef} navigation={navigation} {...rest} />;
};
WrappedComponent.displayName = `withNavigation(${Comp.displayName ||
Comp.name})`;
WrappedComponent.displayName = `withNavigation(${
Comp.displayName || Comp.name
})`;
return WrappedComponent;
}

View File

@@ -23,8 +23,9 @@ export default function withNavigationFocus<
return <Comp ref={onRef} isFocused={isFocused} {...rest} />;
};
WrappedComponent.displayName = `withNavigationFocus(${Comp.displayName ||
Comp.name})`;
WrappedComponent.displayName = `withNavigationFocus(${
Comp.displayName || Comp.name
})`;
return WrappedComponent;
}

View File

@@ -3,6 +3,34 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.3.1](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.3.0...@react-navigation/core@5.3.1) (2020-03-23)
### Bug Fixes
* don't emit events for screens that don't exist anymore ([1c00142](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/1c001424b595b40f9db9343096c833f75353b099))
* only call listeners for focused screen for global events ([3096de6](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/3096de62868a7ed9ed65e529c8ddfa001b9be486))
# [5.3.0](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.2.3...@react-navigation/core@5.3.0) (2020-03-22)
### Bug Fixes
* return correct value for isFocused after changing screens ([5b15c71](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/5b15c7164f5503f2f0d51006a3f23bd0c58fd9b7)), closes [#7843](https://github.com/react-navigation/react-navigation/tree/master/packages/core/issues/7843)
### Features
* support function in listeners prop ([3709e65](https://github.com/react-navigation/react-navigation/tree/master/packages/core/commit/3709e652f41a16c2c2b05d5dbbe1da2017ba2c3f))
## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/core/compare/@react-navigation/core@5.2.2...@react-navigation/core@5.2.3) (2020-03-19)
**Note:** Version bump only for package @react-navigation/core

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/core",
"description": "Core utilities for building navigators",
"version": "5.2.3",
"version": "5.3.1",
"keywords": [
"react",
"react-native",
@@ -29,7 +29,7 @@
"clean": "del lib"
},
"dependencies": {
"@react-navigation/routers": "^5.1.1",
"@react-navigation/routers": "^5.2.0",
"escape-string-regexp": "^2.0.0",
"query-string": "^6.11.1",
"react-is": "^16.13.0",

View File

@@ -73,7 +73,7 @@ const getPartialState = (
return {
...partialState,
stale: true,
routes: state.routes.map(route => {
routes: state.routes.map((route) => {
if (route.state === undefined) {
return route as Route<string> & {
state?: PartialState<NavigationState>;
@@ -156,7 +156,7 @@ const BaseNavigationContainer = React.forwardRef(
throw new Error(NOT_INITIALIZED_ERROR);
}
listeners[0](navigation => navigation.dispatch(action));
listeners[0]((navigation) => navigation.dispatch(action));
};
const canGoBack = () => {
@@ -164,7 +164,7 @@ const BaseNavigationContainer = React.forwardRef(
return false;
}
const { result, handled } = listeners[0](navigation =>
const { result, handled } = listeners[0]((navigation) =>
navigation.canGoBack()
);

View File

@@ -51,7 +51,7 @@ export default function SceneView<
const getCurrentState = React.useCallback(() => {
const state = getState();
const currentRoute = state.routes.find(r => r.key === route.key);
const currentRoute = state.routes.find((r) => r.key === route.key);
return currentRoute ? currentRoute.state : undefined;
}, [getState, route.key]);
@@ -62,7 +62,7 @@ export default function SceneView<
setState({
...state,
routes: state.routes.map(r =>
routes: state.routes.map((r) =>
r.key === route.key ? { ...r, state: child } : r
),
});

View File

@@ -122,7 +122,7 @@ it('handle dispatching with ref', () => {
return (
<React.Fragment>
{state.routes.map(route => descriptors[route.key].render())}
{state.routes.map((route) => descriptors[route.key].render())}
</React.Fragment>
);
};
@@ -220,7 +220,7 @@ it('handle resetting state with ref', () => {
return (
<React.Fragment>
{state.routes.map(route => descriptors[route.key].render())}
{state.routes.map((route) => descriptors[route.key].render())}
</React.Fragment>
);
};
@@ -371,7 +371,7 @@ it('emits state events when the state changes', () => {
return (
<React.Fragment>
{state.routes.map(route => descriptors[route.key].render())}
{state.routes.map((route) => descriptors[route.key].render())}
</React.Fragment>
);
};

View File

@@ -27,7 +27,7 @@ export default function MockRouter(options: DefaultRouterOptions) {
key: String(MockRouterKey.current++),
index,
routeNames,
routes: routeNames.map(name => ({
routes: routeNames.map((name) => ({
name,
key: name,
params: routeParamList[name],
@@ -43,9 +43,9 @@ export default function MockRouter(options: DefaultRouterOptions) {
}
const routes = state.routes
.filter(route => routeNames.includes(route.name))
.filter((route) => routeNames.includes(route.name))
.map(
route =>
(route) =>
({
...route,
key: route.key || `${route.name}-${MockRouterKey.current++}`,
@@ -73,7 +73,7 @@ export default function MockRouter(options: DefaultRouterOptions) {
},
getStateForRouteNamesChange(state, { routeNames }) {
const routes = state.routes.filter(route =>
const routes = state.routes.filter((route) =>
routeNames.includes(route.name)
);
@@ -86,7 +86,7 @@ export default function MockRouter(options: DefaultRouterOptions) {
},
getStateForRouteFocus(state, key) {
const index = state.routes.findIndex(r => r.key === key);
const index = state.routes.findIndex((r) => r.key === key);
if (index === -1 || index === state.index) {
return state;
@@ -105,7 +105,7 @@ export default function MockRouter(options: DefaultRouterOptions) {
case 'NAVIGATE': {
const index = state.routes.findIndex(
route => route.name === action.payload.name
(route) => route.name === action.payload.name
);
if (index === -1) {

View File

@@ -42,7 +42,8 @@ it('converts state to path string with config', () => {
Baz: {
path: 'baz/:author',
parse: {
author: (author: string) => author.replace(/^\w/, c => c.toUpperCase()),
author: (author: string) =>
author.replace(/^\w/, (c) => c.toUpperCase()),
id: (id: string) => Number(id.replace(/^x/, '')),
valid: Boolean,
},
@@ -128,7 +129,8 @@ it('handles state with config with nested screens', () => {
Baz: {
path: 'baz/:author',
parse: {
author: (author: string) => author.replace(/^\w/, c => c.toUpperCase()),
author: (author: string) =>
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
},
@@ -192,12 +194,14 @@ it('handles state with config with nested screens and unused configs', () => {
Baz: {
path: 'baz/:author',
parse: {
author: (author: string) => author.replace(/^\w/, c => c.toUpperCase()),
author: (author: string) =>
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
},
stringify: {
author: (author: string) => author.replace(/^\w/, c => c.toLowerCase()),
author: (author: string) =>
author.replace(/^\w/, (c) => c.toLowerCase()),
unknown: (_: unknown) => 'x',
},
},
@@ -255,11 +259,11 @@ it('handles nested object with stringify in it', () => {
path: 'bis/:author',
stringify: {
author: (author: string) =>
author.replace(/^\w/, c => c.toLowerCase()),
author.replace(/^\w/, (c) => c.toLowerCase()),
},
parse: {
author: (author: string) =>
author.replace(/^\w/, c => c.toUpperCase()),
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
},

View File

@@ -42,7 +42,8 @@ it('converts path string to initial state with config', () => {
Baz: {
path: 'baz/:author',
parse: {
author: (author: string) => author.replace(/^\w/, c => c.toUpperCase()),
author: (author: string) =>
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
},
@@ -153,7 +154,8 @@ it('converts path string to initial state with config with nested screens', () =
Baz: {
path: 'baz/:author',
parse: {
author: (author: string) => author.replace(/^\w/, c => c.toUpperCase()),
author: (author: string) =>
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
},
@@ -217,7 +219,8 @@ it('converts path string to initial state with config with nested screens and un
Baz: {
path: 'baz/:author',
parse: {
author: (author: string) => author.replace(/^\w/, c => c.toUpperCase()),
author: (author: string) =>
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
id: Boolean,
@@ -277,11 +280,11 @@ it('handles nested object with unused configs and with parse in it', () => {
path: 'bis/:author',
stringify: {
author: (author: string) =>
author.replace(/^\w/, c => c.toLowerCase()),
author.replace(/^\w/, (c) => c.toLowerCase()),
},
parse: {
author: (author: string) =>
author.replace(/^\w/, c => c.toUpperCase()),
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
},
@@ -528,11 +531,11 @@ it('handles two initialRouteNames', () => {
path: 'bis/:author',
stringify: {
author: (author: string) =>
author.replace(/^\w/, c => c.toLowerCase()),
author.replace(/^\w/, (c) => c.toLowerCase()),
},
parse: {
author: (author: string) =>
author.replace(/^\w/, c => c.toUpperCase()),
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
},
@@ -610,11 +613,11 @@ it('accepts initialRouteName without config for it', () => {
path: 'bis/:author',
stringify: {
author: (author: string) =>
author.replace(/^\w/, c => c.toLowerCase()),
author.replace(/^\w/, (c) => c.toLowerCase()),
},
parse: {
author: (author: string) =>
author.replace(/^\w/, c => c.toUpperCase()),
author.replace(/^\w/, (c) => c.toUpperCase()),
count: Number,
valid: Boolean,
},

View File

@@ -119,7 +119,7 @@ it('sets options with screenOptions prop as an object', () => {
return (
<>
{state.routes.map(route => {
{state.routes.map((route) => {
const { render, options } = descriptors[route.key];
return (
@@ -179,7 +179,7 @@ it('sets options with screenOptions prop as a fuction', () => {
return (
<>
{state.routes.map(route => {
{state.routes.map((route) => {
const { render, options } = descriptors[route.key];
return (
@@ -273,7 +273,7 @@ it('sets initial options with setOptions', () => {
<BaseNavigationContainer>
<TestNavigator>
<Screen name="foo" options={{ color: 'blue' }}>
{props => <TestScreen {...props} />}
{(props) => <TestScreen {...props} />}
</Screen>
<Screen name="bar" component={jest.fn()} />
</TestNavigator>
@@ -338,7 +338,7 @@ it('updates options with setOptions', () => {
<BaseNavigationContainer>
<TestNavigator>
<Screen name="foo" options={{ color: 'blue' }}>
{props => <TestScreen {...props} />}
{(props) => <TestScreen {...props} />}
</Screen>
<Screen name="bar" component={jest.fn()} />
</TestNavigator>

View File

@@ -15,7 +15,7 @@ it('fires focus and blur events in root navigator', () => {
React.useImperativeHandle(ref, () => navigation, [navigation]);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
});
const firstFocusCallback = jest.fn();
@@ -106,7 +106,7 @@ it('fires focus and blur events in nested navigator', () => {
React.useImperativeHandle(ref, () => navigation, [navigation]);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
});
const firstFocusCallback = jest.fn();
@@ -376,7 +376,7 @@ it('fires custom events added with addListener', () => {
state,
]);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
});
const firstCallback = jest.fn();
@@ -456,7 +456,7 @@ it("doesn't call same listener multiple times with addListener", () => {
state,
]);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
});
const callback = jest.fn();
@@ -565,12 +565,10 @@ it('fires custom events added with listeners prop', () => {
});
expect(firstCallback.mock.calls[0][0].target).toBe(undefined);
expect(secondCallback.mock.calls[0][0].target).toBe(undefined);
expect(thirdCallback.mock.calls[1][0].target).toBe(undefined);
expect(firstCallback).toBeCalledTimes(1);
expect(secondCallback).toBeCalledTimes(1);
expect(thirdCallback).toBeCalledTimes(2);
expect(secondCallback).toBeCalledTimes(0);
expect(thirdCallback).toBeCalledTimes(1);
});
it("doesn't call same listener multiple times with listeners", () => {
@@ -624,6 +622,91 @@ it("doesn't call same listener multiple times with listeners", () => {
expect(callback).toBeCalledTimes(1);
});
it('fires listeners when callback is provided for listeners prop', () => {
const eventName = 'someSuperCoolEvent';
const TestNavigator = React.forwardRef((props: any, ref: any): any => {
const { state, navigation } = useNavigationBuilder(MockRouter, props);
React.useImperativeHandle(ref, () => ({ navigation, state }), [
navigation,
state,
]);
return null;
});
const firstCallback = jest.fn();
const secondCallback = jest.fn();
const thirdCallback = jest.fn();
const ref = React.createRef<any>();
const element = (
<BaseNavigationContainer>
<TestNavigator ref={ref}>
<Screen
name="first"
listeners={({ route, navigation }) => ({
someSuperCoolEvent: (e) => firstCallback(e, route, navigation),
})}
component={jest.fn()}
/>
<Screen
name="second"
listeners={({ route, navigation }) => ({
someSuperCoolEvent: (e) => secondCallback(e, route, navigation),
})}
component={jest.fn()}
/>
<Screen
name="third"
listeners={({ route, navigation }) => ({
someSuperCoolEvent: (e) => thirdCallback(e, route, navigation),
})}
component={jest.fn()}
/>
</TestNavigator>
</BaseNavigationContainer>
);
render(element);
expect(firstCallback).toBeCalledTimes(0);
expect(secondCallback).toBeCalledTimes(0);
expect(thirdCallback).toBeCalledTimes(0);
const target =
ref.current.state.routes[ref.current.state.routes.length - 1].key;
act(() => {
ref.current.navigation.emit({
type: eventName,
target,
data: 42,
});
});
expect(firstCallback).toBeCalledTimes(0);
expect(secondCallback).toBeCalledTimes(0);
expect(thirdCallback).toBeCalledTimes(1);
expect(thirdCallback.mock.calls[0][0].type).toBe('someSuperCoolEvent');
expect(thirdCallback.mock.calls[0][0].data).toBe(42);
expect(thirdCallback.mock.calls[0][0].target).toBe(target);
expect(thirdCallback.mock.calls[0][0].defaultPrevented).toBe(undefined);
expect(thirdCallback.mock.calls[0][0].preventDefault).toBe(undefined);
act(() => {
ref.current.navigation.emit({ type: eventName });
});
expect(firstCallback.mock.calls[0][0].target).toBe(undefined);
expect(firstCallback).toBeCalledTimes(1);
expect(secondCallback).toBeCalledTimes(0);
expect(thirdCallback).toBeCalledTimes(1);
});
it('has option to prevent default', () => {
expect.assertions(5);
@@ -640,7 +723,7 @@ it('has option to prevent default', () => {
state,
]);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
});
const callback = (e: any) => {

View File

@@ -10,7 +10,7 @@ it('runs focus effect on focus change', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const focusEffect = jest.fn();
@@ -107,7 +107,7 @@ it('runs focus effect when initial state is given', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const focusEffect = jest.fn();

View File

@@ -10,7 +10,7 @@ it('renders correct focus state', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const Test = () => {

View File

@@ -12,7 +12,7 @@ it('gets navigation prop from context', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const Test = () => {
@@ -38,7 +38,7 @@ it("gets navigation's parent from context", () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const Test = () => {
@@ -70,7 +70,7 @@ it("gets navigation's parent's parent from context", () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const Test = () => {

View File

@@ -1,7 +1,10 @@
import * as React from 'react';
import { render } from 'react-native-testing-library';
import { render, act } from 'react-native-testing-library';
import useEventEmitter from '../useEventEmitter';
import useNavigationCache from '../useNavigationCache';
import useNavigationBuilder from '../useNavigationBuilder';
import BaseNavigationContainer from '../BaseNavigationContainer';
import Screen from '../Screen';
import MockRouter, { MockRouterKey } from './__fixtures__/MockRouter';
beforeEach(() => (MockRouterKey.current = 0));
@@ -40,7 +43,7 @@ it('preserves reference for navigation objects', () => {
});
if (previous.current) {
Object.keys(navigations).forEach(key => {
Object.keys(navigations).forEach((key) => {
expect(navigations[key]).toBe(previous.current[key]);
});
}
@@ -56,3 +59,136 @@ it('preserves reference for navigation objects', () => {
root.update(<Test />);
});
it('returns correct value for isFocused', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map((route) => descriptors[route.key].render());
};
let navigation: any;
const Test = (props: any) => {
navigation = props.navigation;
return null;
};
render(
<BaseNavigationContainer>
<TestNavigator>
<Screen name="first">{() => null}</Screen>
<Screen name="second" component={Test} />
<Screen name="third">{() => null}</Screen>
</TestNavigator>
</BaseNavigationContainer>
);
expect(navigation.isFocused()).toBe(false);
act(() => navigation.navigate('second'));
expect(navigation.isFocused()).toBe(true);
act(() => navigation.navigate('third'));
expect(navigation.isFocused()).toBe(false);
act(() => navigation.navigate('second'));
expect(navigation.isFocused()).toBe(true);
});
it('returns correct value for isFocused after changing screens', () => {
const TestRouter = (
options: Parameters<typeof MockRouter>[0]
): ReturnType<typeof MockRouter> => {
const router = MockRouter(options);
return {
...router,
getStateForRouteNamesChange(state, { routeNames }) {
const routes = routeNames.map(
(name) =>
state.routes.find((r) => r.name === name) || {
name,
key: name,
}
);
return {
...state,
routeNames,
routes,
index: routes.length - 1,
};
},
};
};
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(TestRouter, props);
return state.routes.map((route) => descriptors[route.key].render());
};
let navigation: any;
const Test = (props: any) => {
navigation = props.navigation;
return null;
};
const root = render(
<BaseNavigationContainer>
<TestNavigator>
<Screen name="first">{() => null}</Screen>
<Screen name="second" component={Test} />
<Screen name="third">{() => null}</Screen>
</TestNavigator>
</BaseNavigationContainer>
);
expect(navigation.isFocused()).toBe(false);
root.update(
<BaseNavigationContainer>
<TestNavigator>
<Screen name="first">{() => null}</Screen>
<Screen name="third">{() => null}</Screen>
<Screen name="second" component={Test} />
</TestNavigator>
</BaseNavigationContainer>
);
expect(navigation.isFocused()).toBe(true);
root.update(
<BaseNavigationContainer>
<TestNavigator>
<Screen name="first">{() => null}</Screen>
<Screen name="third">{() => null}</Screen>
<Screen name="fourth">{() => null}</Screen>
<Screen name="second" component={Test} />
</TestNavigator>
</BaseNavigationContainer>
);
expect(navigation.isFocused()).toBe(true);
root.update(
<BaseNavigationContainer>
<TestNavigator>
<Screen name="first">{() => null}</Screen>
<Screen name="third">{() => null}</Screen>
<Screen name="second" component={Test} />
<Screen name="fourth">{() => null}</Screen>
</TestNavigator>
</BaseNavigationContainer>
);
expect(navigation.isFocused()).toBe(false);
});

View File

@@ -11,13 +11,13 @@ it('gets the current navigation state', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const callback = jest.fn();
const Test = () => {
const state = useNavigationState(state => state);
const state = useNavigationState((state) => state);
callback(state);
@@ -62,13 +62,13 @@ it('gets the current navigation state with selector', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const callback = jest.fn();
const Test = () => {
const index = useNavigationState(state => state.index);
const index = useNavigationState((state) => state.index);
callback(index);
@@ -112,7 +112,7 @@ it('gets the correct value if selector changes', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const callback = jest.fn();
@@ -144,12 +144,12 @@ it('gets the correct value if selector changes', () => {
);
};
const root = render(<App selector={state => state.index} />);
const root = render(<App selector={(state) => state.index} />);
expect(callback).toBeCalledTimes(1);
expect(callback.mock.calls[0][0]).toBe(0);
root.update(<App selector={state => state.routes[state.index].name} />);
root.update(<App selector={(state) => state.routes[state.index].name} />);
expect(callback).toBeCalledTimes(2);
expect(callback.mock.calls[1][0]).toBe('first');

View File

@@ -137,7 +137,7 @@ it("lets children handle the action if parent didn't", () => {
return (
<React.Fragment>
{state.routes.map(route => descriptors[route.key].render())}
{state.routes.map((route) => descriptors[route.key].render())}
</React.Fragment>
);
};
@@ -270,7 +270,7 @@ it("action doesn't bubble if target is specified", () => {
return (
<React.Fragment>
{state.routes.map(route => descriptors[route.key].render())}
{state.routes.map((route) => descriptors[route.key].render())}
</React.Fragment>
);
};
@@ -317,7 +317,7 @@ it('logs error if no navigator handled the action', () => {
return (
<React.Fragment>
{state.routes.map(route => descriptors[route.key].render())}
{state.routes.map((route) => descriptors[route.key].render())}
</React.Fragment>
);
};

View File

@@ -13,7 +13,7 @@ it('gets route prop from context', () => {
const TestNavigator = (props: any): any => {
const { state, descriptors } = useNavigationBuilder(MockRouter, props);
return state.routes.map(route => descriptors[route.key].render());
return state.routes.map((route) => descriptors[route.key].render());
};
const Test = () => {

View File

@@ -16,7 +16,7 @@ export default function createNavigatorFactory<
EventMap extends EventMapBase,
NavigatorComponent extends React.ComponentType<any>
>(Navigator: NavigatorComponent) {
return function<ParamList extends ParamListBase>(): TypedNavigator<
return function <ParamList extends ParamListBase>(): TypedNavigator<
ParamList,
State,
ScreenOptions,

View File

@@ -125,7 +125,7 @@ export default function getPathFromState(
if (currentOptions[route.name] !== undefined) {
path += pattern
.split('/')
.map(p => {
.map((p) => {
const name = p.replace(/^:/, '');
// If the path has a pattern for a param, put the param in the path

View File

@@ -64,7 +64,7 @@ export default function getStateFromPath(
let initialRoutes: InitialRouteConfig[] = [];
// Create a normalized configs array which will be easier to use
const configs = ([] as RouteConfig[]).concat(
...Object.keys(options).map(key =>
...Object.keys(options).map((key) =>
createNormalizedConfigs(key, options, [], initialRoutes)
)
);
@@ -91,7 +91,7 @@ export default function getStateFromPath(
const paramPatterns = config.pattern
.split('/')
.filter(p => p.startsWith(':'));
.filter((p) => p.startsWith(':'));
if (paramPatterns.length) {
params = paramPatterns.reduce<Record<string, any>>((acc, p, i) => {
@@ -188,7 +188,7 @@ export default function getStateFromPath(
const parseFunction = findParseConfigForRoute(route.name, configs);
if (parseFunction) {
Object.keys(params).forEach(name => {
Object.keys(params).forEach((name) => {
if (parseFunction[name] && typeof params[name] === 'string') {
params[name] = parseFunction[name](params[name] as string);
}
@@ -233,7 +233,7 @@ function createNormalizedConfigs(
connectedRoutes: Object.keys(value.screens),
});
}
Object.keys(value.screens).forEach(nestedConfig => {
Object.keys(value.screens).forEach((nestedConfig) => {
const result = createNormalizedConfigs(
nestedConfig,
value.screens as Options,

View File

@@ -346,6 +346,16 @@ export type Descriptor<
>;
};
export type ScreenListeners<
State extends NavigationState,
EventMap extends EventMapBase
> = Partial<
{
[EventName in keyof (EventMap &
EventMapCore<State>)]: EventListenerCallback<EventMap, EventName>;
}
>;
export type RouteConfig<
ParamList extends ParamListBase,
RouteName extends keyof ParamList,
@@ -371,12 +381,12 @@ export type RouteConfig<
/**
* Event listeners for this screen.
*/
listeners?: Partial<
{
[EventName in keyof (EventMap &
EventMapCore<State>)]: EventListenerCallback<EventMap, EventName>;
}
>;
listeners?:
| ScreenListeners<State, EventMap>
| ((props: {
route: RouteProp<ParamList, RouteName>;
navigation: any;
}) => ScreenListeners<State, EventMap>);
/**
* Initial params object for the route.

View File

@@ -58,7 +58,7 @@ export default function useDevTools({ name, reset, state, enabled }: Options) {
React.useEffect(
() =>
devTools?.subscribe(message => {
devTools?.subscribe((message) => {
if (message.type === 'DISPATCH' && message.state) {
reset(JSON.parse(message.state));
}

View File

@@ -69,7 +69,7 @@ export default function useEventEmitter(
target !== undefined
? items[target] && items[target].slice()
: ([] as Listeners)
.concat(...Object.keys(items).map(t => items[t]))
.concat(...Object.keys(items).map((t) => items[t]))
.filter((cb, i, self) => self.lastIndexOf(cb) === i);
const event: EventArg<any, any, any> = {
@@ -117,7 +117,7 @@ export default function useEventEmitter(
listenRef.current?.(event);
callbacks?.forEach(cb => cb(event));
callbacks?.forEach((cb) => cb(event));
return event as any;
},

View File

@@ -9,6 +9,7 @@ import {
RouterFactory,
PartialState,
NavigationAction,
Route,
} from '@react-navigation/routers';
import { NavigationStateContext } from './BaseNavigationContainer';
import NavigationRouteContext from './NavigationRouteContext';
@@ -103,7 +104,7 @@ const getRouteConfigsFromChildren = <
}, []);
if (process.env.NODE_ENV !== 'production') {
configs.forEach(config => {
configs.forEach((config) => {
const { name, children, component } = config as any;
if (typeof name !== 'string' || !name) {
@@ -212,7 +213,7 @@ export default function useNavigationBuilder<
return acc;
}, {});
const routeNames = routeConfigs.map(config => config.name);
const routeNames = routeConfigs.map((config) => config.name);
const routeParamList = routeNames.reduce<Record<string, object | undefined>>(
(acc, curr) => {
const { initialParams } = screens[curr];
@@ -241,12 +242,12 @@ export default function useNavigationBuilder<
}
const isStateValid = React.useCallback(
state => state.type === undefined || state.type === router.type,
(state) => state.type === undefined || state.type === router.type,
[router.type]
);
const isStateInitialized = React.useCallback(
state =>
(state) =>
state !== undefined && state.stale === false && isStateValid(state),
[isStateValid]
);
@@ -367,34 +368,49 @@ export default function useNavigationBuilder<
: (initializedStateRef.current as State);
}, [getCurrentState, isStateInitialized]);
const emitter = useEventEmitter(e => {
const emitter = useEventEmitter((e) => {
let routeNames = [];
if (e.target) {
const name = state.routes.find(route => route.key === e.target)?.name;
let route: Route<string> | undefined;
if (name) {
routeNames.push(name);
if (e.target) {
route = state.routes.find((route) => route.key === e.target);
if (route?.name) {
routeNames.push(route.name);
}
} else {
routeNames.push(...Object.keys(screens));
route = state.routes[state.index];
routeNames.push(
...Object.keys(screens).filter((name) => route?.name === name)
);
}
if (route == null) {
return;
}
const navigation = descriptors[route.key].navigation;
const listeners = ([] as (((e: any) => void) | undefined)[])
.concat(
...routeNames.map(name => {
...routeNames.map((name) => {
const { listeners } = screens[name];
const map =
typeof listeners === 'function'
? listeners({ route: route as any, navigation })
: listeners;
return listeners
? Object.keys(listeners)
.filter(type => type === e.type)
.map(type => listeners[type])
return map
? Object.keys(map)
.filter((type) => type === e.type)
.map((type) => map?.[type])
: undefined;
})
)
.filter((cb, i, self) => cb && self.lastIndexOf(cb) === i);
listeners.forEach(listener => listener?.(e));
listeners.forEach((listener) => listener?.(e));
});
useFocusEvents({ state, emitter });

View File

@@ -63,7 +63,7 @@ export default function useNavigationCache<
};
cache.current = state.routes.reduce<NavigationCache<State, ScreenOptions>>(
(acc, route, index) => {
(acc, route) => {
const previous = cache.current[route.key];
if (previous) {
@@ -103,14 +103,14 @@ export default function useNavigationCache<
dangerouslyGetState: getState,
dispatch,
setOptions: (options: object) =>
setOptions(o => ({
setOptions((o) => ({
...o,
[route.key]: { ...o[route.key], ...options },
})),
isFocused: () => {
const state = getState();
if (index !== state.index) {
if (state.routes[state.index].key !== route.key) {
return false;
}

View File

@@ -26,7 +26,7 @@ export default function useNavigationState<T>(selector: Selector<T>): T {
});
React.useEffect(() => {
const unsubscribe = navigation.addListener('state', e => {
const unsubscribe = navigation.addListener('state', (e) => {
setResult(selectorRef.current(e.data.state));
});

View File

@@ -18,7 +18,7 @@ export default function useOnGetState({
const state = getState();
return {
...state,
routes: state.routes.map(route => ({
routes: state.routes.map((route) => ({
...route,
state: getStateForRoute(route.key),
})),

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.3.4](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.3.3...@react-navigation/drawer@5.3.4) (2020-03-23)
**Note:** Version bump only for package @react-navigation/drawer
## [5.3.3](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.3.2...@react-navigation/drawer@5.3.3) (2020-03-22)
**Note:** Version bump only for package @react-navigation/drawer
## [5.3.2](https://github.com/react-navigation/react-navigation/tree/master/packages/drawer/compare/@react-navigation/drawer@5.3.1...@react-navigation/drawer@5.3.2) (2020-03-19)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/drawer",
"description": "Drawer navigator component with animated transitions and gesturess",
"version": "5.3.2",
"version": "5.3.4",
"keywords": [
"react-native-component",
"react-component",
@@ -40,7 +40,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.10.0",
"@react-navigation/native": "^5.1.1",
"@react-navigation/native": "^5.1.3",
"@types/react": "^16.9.23",
"@types/react-native": "^0.61.22",
"del-cli": "^3.0.0",

View File

@@ -72,14 +72,8 @@ export default function DrawerItem(props: Props) {
labelStyle,
focused = false,
activeTintColor = colors.primary,
inactiveTintColor = Color(colors.text)
.alpha(0.68)
.rgb()
.string(),
activeBackgroundColor = Color(activeTintColor)
.alpha(0.12)
.rgb()
.string(),
inactiveTintColor = Color(colors.text).alpha(0.68).rgb().string(),
activeBackgroundColor = Color(activeTintColor).alpha(0.12).rgb().string(),
inactiveBackgroundColor = 'transparent',
style,
onPress,

View File

@@ -99,7 +99,7 @@ export default function DrawerView({
const { colors } = useTheme();
const isDrawerOpen = state.history.some(it => it.type === 'drawer');
const isDrawerOpen = state.history.some((it) => it.type === 'drawer');
const handleDrawerOpen = React.useCallback(() => {
navigation.dispatch({
@@ -212,7 +212,7 @@ export default function DrawerView({
gestureEnabled={gestureEnabled}
onOpen={handleDrawerOpen}
onClose={handleDrawerClose}
onGestureRef={ref => {
onGestureRef={(ref) => {
// @ts-ignore
drawerGestureRef.current = ref;
}}

View File

@@ -30,7 +30,7 @@ type Props = {
export default function SafeAreaProviderCompat({ children }: Props) {
return (
<SafeAreaConsumer>
{insets => {
{(insets) => {
if (insets) {
// If we already have insets, don't wrap the stack in another safe area provider
// This avoids an issue with updates at the cost of potentially incorrect values

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.1.6](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.5...@react-navigation/material-bottom-tabs@5.1.6) (2020-03-23)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.4...@react-navigation/material-bottom-tabs@5.1.5) (2020-03-22)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs
## [5.1.4](https://github.com/react-navigation/react-navigation/tree/master/packages/material-bottom-tabs/compare/@react-navigation/material-bottom-tabs@5.1.3...@react-navigation/material-bottom-tabs@5.1.4) (2020-03-19)
**Note:** Version bump only for package @react-navigation/material-bottom-tabs

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/material-bottom-tabs",
"description": "Integration for bottom navigation component from react-native-paper",
"version": "5.1.4",
"version": "5.1.6",
"keywords": [
"react-native-component",
"react-component",
@@ -36,7 +36,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.10.0",
"@react-navigation/native": "^5.1.1",
"@react-navigation/native": "^5.1.3",
"@types/react": "^16.9.23",
"@types/react-native": "^0.61.22",
"@types/react-native-vector-icons": "^6.4.5",

View File

@@ -3,6 +3,22 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.1.6](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.5...@react-navigation/material-top-tabs@5.1.6) (2020-03-23)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.1.5](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.4...@react-navigation/material-top-tabs@5.1.5) (2020-03-22)
**Note:** Version bump only for package @react-navigation/material-top-tabs
## [5.1.4](https://github.com/react-navigation/react-navigation/tree/master/packages/material-top-tabs/compare/@react-navigation/material-top-tabs@5.1.3...@react-navigation/material-top-tabs@5.1.4) (2020-03-19)
**Note:** Version bump only for package @react-navigation/material-top-tabs

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/material-top-tabs",
"description": "Integration for the animated tab view component from react-native-tab-view",
"version": "5.1.4",
"version": "5.1.6",
"keywords": [
"react-native-component",
"react-component",
@@ -39,7 +39,7 @@
},
"devDependencies": {
"@react-native-community/bob": "^0.10.0",
"@react-navigation/native": "^5.1.1",
"@react-navigation/native": "^5.1.3",
"@types/react": "^16.9.23",
"@types/react-native": "^0.61.22",
"del-cli": "^3.0.0",

View File

@@ -14,17 +14,11 @@ export default function TabBarTop(props: MaterialTopTabBarProps) {
navigation,
descriptors,
activeTintColor = colors.text,
inactiveTintColor = Color(activeTintColor)
.alpha(0.5)
.rgb()
.string(),
inactiveTintColor = Color(activeTintColor).alpha(0.5).rgb().string(),
allowFontScaling = true,
showIcon = false,
showLabel = true,
pressColor = Color(activeTintColor)
.alpha(0.08)
.rgb()
.string(),
pressColor = Color(activeTintColor).alpha(0.08).rgb().string(),
iconStyle,
labelStyle,
indicatorStyle,

View File

@@ -47,7 +47,7 @@ export default function MaterialTopTabView({
return (
<TabView
{...rest}
onIndexChange={index =>
onIndexChange={(index) =>
navigation.dispatch({
...TabActions.jumpTo(state.routes[index].name),
target: state.key,

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.1.3](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.1.2...@react-navigation/native@5.1.3) (2020-03-23)
### Bug Fixes
* add info about android launchMode in useLinking error ([d94e43c](https://github.com/react-navigation/react-navigation/tree/master/packages/native/commit/d94e43c3c8625b209a5c883b8cb560496d07fda7))
## [5.1.2](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.1.1...@react-navigation/native@5.1.2) (2020-03-22)
**Note:** Version bump only for package @react-navigation/native
## [5.1.1](https://github.com/react-navigation/react-navigation/tree/master/packages/native/compare/@react-navigation/native@5.1.0...@react-navigation/native@5.1.1) (2020-03-19)
**Note:** Version bump only for package @react-navigation/native

View File

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

View File

@@ -1,4 +1,4 @@
export default function() {
export default function () {
throw new Error(
"'NavigationNativeContainer' has been renamed to 'NavigationContainer"
);

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import { Linking } from 'react-native';
import { Linking, Platform } from 'react-native';
import {
getActionFromState,
getStateFromPath as getStateFromPathDefault,
@@ -20,7 +20,10 @@ export default function useLinking(
React.useEffect(() => {
if (isUsingLinking) {
throw new Error(
"Looks like you are using 'useLinking' in multiple components. This is likely an error since deep links should only be handled in one place to avoid conflicts."
"Looks like you are using 'useLinking' in multiple components. This is likely an error since deep links should only be handled in one place to avoid conflicts." +
(Platform.OS === 'android'
? "\n\nIf you're not using it in multiple components, ensure that you have set 'android:launchMode=singleTask' in the '<activity />' section of the 'AndroidManifest.xml' file to avoid launching multiple activities which run multiple instances of the root component."
: '')
);
} else {
isUsingLinking = true;

View File

@@ -40,7 +40,7 @@ export default function useLinking(
React.useEffect(() => {
if (isUsingLinking) {
throw new Error(
"Looks like you are using 'useLinking' in multiple components. This is likely an error since URL integration should only be handled in one place to avoid conflicts."
"Looks like you are using 'useLinking' in multiple components. This is likely an error since URL integration should only be handled in one place to avoid conflicts. Also ensure that you set your android activity launchMode to single task in your AndroiManifest.xml file."
);
} else {
isUsingLinking = true;

View File

@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [5.2.0](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.1.1...@react-navigation/routers@5.2.0) (2020-03-22)
### Features
* add keys to routes missing keys during reset ([813a590](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/commit/813a5903b5f44506b9097538ed85229e565b855e))
## [5.1.1](https://github.com/react-navigation/react-navigation/tree/master/packages/routers/compare/@react-navigation/routers@5.1.0...@react-navigation/routers@5.1.1) (2020-03-16)

View File

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

View File

@@ -1,3 +1,4 @@
import shortid from 'shortid';
import { CommonNavigationAction, NavigationState, PartialState } from './types';
/**
@@ -12,7 +13,7 @@ const BaseRouter = {
switch (action.type) {
case 'SET_PARAMS': {
const index = action.source
? state.routes.findIndex(r => r.key === action.source)
? state.routes.findIndex((r) => r.key === action.source)
: state.index;
if (index === -1) {
@@ -32,15 +33,6 @@ const BaseRouter = {
case 'RESET': {
const nextState = action.payload as State | PartialState<State>;
if (nextState.stale === false) {
if (
state.routeNames.length !== nextState.routeNames.length ||
nextState.routeNames.some(name => !state.routeNames.includes(name))
) {
return null;
}
}
if (
nextState.routes.length === 0 ||
nextState.routes.some(
@@ -50,6 +42,26 @@ const BaseRouter = {
return null;
}
if (nextState.stale === false) {
if (
state.routeNames.length !== nextState.routeNames.length ||
nextState.routeNames.some(
(name) => !state.routeNames.includes(name)
)
) {
return null;
}
return {
...nextState,
routes: nextState.routes.map((route) =>
route.key
? route
: { ...route, key: `${route.name}-${shortid()}` }
),
};
}
return nextState;
}

View File

@@ -71,7 +71,7 @@ export const DrawerActions = {
const isDrawerOpen = (
state: DrawerNavigationState | PartialState<DrawerNavigationState>
) => Boolean(state.history?.find(it => it.type === 'drawer'));
) => Boolean(state.history?.find((it) => it.type === 'drawer'));
const openDrawer = (state: DrawerNavigationState): DrawerNavigationState => {
if (isDrawerOpen(state)) {
@@ -91,7 +91,7 @@ const closeDrawer = (state: DrawerNavigationState): DrawerNavigationState => {
return {
...state,
history: state.history.filter(it => it.type !== 'drawer'),
history: state.history.filter((it) => it.type !== 'drawer'),
};
};

View File

@@ -134,9 +134,9 @@ export default function StackRouter(options: StackRouterOptions) {
}
const routes = state.routes
.filter(route => routeNames.includes(route.name))
.filter((route) => routeNames.includes(route.name))
.map(
route =>
(route) =>
({
...route,
key: route.key || `${route.name}-${shortid()}`,
@@ -174,7 +174,7 @@ export default function StackRouter(options: StackRouterOptions) {
},
getStateForRouteNamesChange(state, { routeNames, routeParamList }) {
const routes = state.routes.filter(route =>
const routes = state.routes.filter((route) =>
routeNames.includes(route.name)
);
@@ -201,7 +201,7 @@ export default function StackRouter(options: StackRouterOptions) {
},
getStateForRouteFocus(state, key) {
const index = state.routes.findIndex(r => r.key === key);
const index = state.routes.findIndex((r) => r.key === key);
if (index === -1 || index === state.index) {
return state;
@@ -220,7 +220,7 @@ export default function StackRouter(options: StackRouterOptions) {
switch (action.type) {
case 'REPLACE': {
const index = action.source
? state.routes.findIndex(r => r.key === action.source)
? state.routes.findIndex((r) => r.key === action.source)
: state.index;
if (index === -1) {
@@ -283,7 +283,7 @@ export default function StackRouter(options: StackRouterOptions) {
case 'POP': {
const index =
action.target === state.key && action.source
? state.routes.findIndex(r => r.key === action.source)
? state.routes.findIndex((r) => r.key === action.source)
: state.index;
if (index > 0) {

View File

@@ -93,7 +93,7 @@ const changeIndex = (
const currentKey = state.routes[index].key;
history = state.history
.filter(it => (it.type === 'route' ? it.key !== currentKey : false))
.filter((it) => (it.type === 'route' ? it.key !== currentKey : false))
.concat({ type: TYPE_ROUTE, key: currentKey });
} else {
history = getRouteHistory(state.routes, index, backBehavior);
@@ -124,7 +124,7 @@ export default function TabRouter({
? routeNames.indexOf(initialRouteName)
: 0;
const routes = routeNames.map(name => ({
const routes = routeNames.map((name) => ({
name,
key: `${name}-${shortid()}`,
params: routeParamList[name],
@@ -150,9 +150,9 @@ export default function TabRouter({
return state;
}
const routes = routeNames.map(name => {
const routes = routeNames.map((name) => {
const route = (state as PartialState<TabNavigationState>).routes.find(
r => r.name === name
(r) => r.name === name
);
return {
@@ -184,8 +184,8 @@ export default function TabRouter({
routes.length - 1
);
let history = state.history?.filter(it =>
routes.find(r => r.key === it.key)
let history = state.history?.filter((it) =>
routes.find((r) => r.key === it.key)
);
if (!history?.length) {
@@ -205,8 +205,8 @@ export default function TabRouter({
getStateForRouteNamesChange(state, { routeNames, routeParamList }) {
const routes = routeNames.map(
name =>
state.routes.find(r => r.name === name) || {
(name) =>
state.routes.find((r) => r.name === name) || {
name,
key: `${name}-${shortid()}`,
params: routeParamList[name],
@@ -218,8 +218,8 @@ export default function TabRouter({
routeNames.indexOf(state.routes[state.index].name)
);
let history = state.history.filter(it =>
routes.find(r => r.key === it.key)
let history = state.history.filter((it) =>
routes.find((r) => r.key === it.key)
);
if (!history.length) {
@@ -236,7 +236,7 @@ export default function TabRouter({
},
getStateForRouteFocus(state, key) {
const index = state.routes.findIndex(r => r.key === key);
const index = state.routes.findIndex((r) => r.key === key);
if (index === -1 || index === state.index) {
return state;
@@ -253,11 +253,11 @@ export default function TabRouter({
if (action.type === 'NAVIGATE' && action.payload.key) {
index = state.routes.findIndex(
route => route.key === action.payload.key
(route) => route.key === action.payload.key
);
} else {
index = state.routes.findIndex(
route => route.name === action.payload.name
(route) => route.name === action.payload.name
);
}
@@ -295,7 +295,7 @@ export default function TabRouter({
const previousKey = state.history[state.history.length - 2].key;
const index = state.routes.findIndex(
route => route.key === previousKey
(route) => route.key === previousKey
);
if (index === -1) {

View File

@@ -84,6 +84,22 @@ it('resets state to new state with RESET', () => {
expect(result).toEqual({ index: 0, routes });
});
it('adds keys to routes missing keys during RESET', () => {
const result = BaseRouter.getStateForAction(
STATE,
// @ts-ignore
CommonActions.reset({
...STATE,
routes: [...STATE.routes, { name: 'qux' }],
})
);
expect(result).toEqual({
...STATE,
routes: [...STATE.routes, { key: 'qux-test', name: 'qux' }],
});
});
it("doesn't handle RESET if routes don't match routeNames", () => {
const routes = [
{ key: 'bar', name: 'bar', params: { fruit: 'orange' } },

View File

@@ -3,6 +3,58 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [5.2.7](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.6...@react-navigation/stack@5.2.7) (2020-03-26)
### Bug Fixes
* add pointerEvents=box-none to overlay View ([#7871](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/7871)) ([e097df8](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/e097df880adab984aae29f847003d2548cfbdce5))
## [5.2.6](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.5...@react-navigation/stack@5.2.6) (2020-03-23)
**Note:** Version bump only for package @react-navigation/stack
## [5.2.5](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.4...@react-navigation/stack@5.2.5) (2020-03-23)
### Bug Fixes
* fix swipe gestures requiring a lot of velocity to dismiss ([61f16d3](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/61f16d3f25cbbcc00d699dd09c5f4abde9b17d5a))
## [5.2.4](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.3...@react-navigation/stack@5.2.4) (2020-03-22)
### Bug Fixes
* fix swipe not dismissing card in RTL ([043924c](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/043924ca4843b6f02626532cbf4aafc7cad9fab1)), closes [#7841](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/7841)
## [5.2.3](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.2...@react-navigation/stack@5.2.3) (2020-03-19)
### Bug Fixes
* use the correct velocity value in closing animation ([#7836](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/issues/7836)) ([adbfedc](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/commit/adbfedcd58d4e3d358c6c9691710bb8e4e0d8afb))
## [5.2.2](https://github.com/react-navigation/react-navigation/tree/master/packages/stack/compare/@react-navigation/stack@5.2.1...@react-navigation/stack@5.2.2) (2020-03-19)

View File

@@ -1,7 +1,7 @@
{
"name": "@react-navigation/stack",
"description": "Stack navigator component for iOS and Android with animated transitions and gestures",
"version": "5.2.2",
"version": "5.2.7",
"keywords": [
"react-native-component",
"react-component",
@@ -40,7 +40,7 @@
"devDependencies": {
"@react-native-community/bob": "^0.10.0",
"@react-native-community/masked-view": "^0.1.7",
"@react-navigation/native": "^5.1.1",
"@react-navigation/native": "^5.1.3",
"@types/color": "^3.0.1",
"@types/react": "^16.9.23",
"@types/react-native": "^0.61.22",

View File

@@ -40,7 +40,7 @@ function StackNavigator({
React.useEffect(
() =>
navigation.addListener &&
navigation.addListener('tabPress', e => {
navigation.addListener('tabPress', (e) => {
const isFocused = navigation.isFocused();
// Run the operation in the next frame so we're sure all listeners have been run

View File

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

View File

@@ -124,7 +124,7 @@ export default function HeaderContainer({
<View
onLayout={
onContentHeightChange
? e =>
? (e) =>
onContentHeightChange({
route: scene.route,
height: e.nativeEvent.layout.height,

View File

@@ -38,7 +38,7 @@ type State = {
};
const warnIfHeaderStylesDefined = (styles: Record<string, any>) => {
Object.keys(styles).forEach(styleProp => {
Object.keys(styles).forEach((styleProp) => {
const value = styles[styleProp];
if (styleProp === 'position' && value === 'absolute') {

View File

@@ -30,7 +30,7 @@ type Props = {
export default function SafeAreaProviderCompat({ children }: Props) {
return (
<SafeAreaConsumer>
{insets => {
{(insets) => {
if (insets) {
// If we already have insets, don't wrap the stack in another safe area provider
// This avoids an issue with updates at the cost of potentially incorrect values

View File

@@ -271,16 +271,10 @@ export default class Card extends React.Component<Props> {
velocity = nativeEvent.velocityX;
}
if (
gestureDirection === 'horizontal-inverted' ||
gestureDirection === 'vertical-inverted'
) {
translation *= -1;
velocity *= -1;
}
const closing =
translation + velocity * gestureVelocityImpact > distance / 2
(translation + velocity * gestureVelocityImpact) *
getInvertedMultiplier(gestureDirection) >
distance / 2
? velocity !== 0 || translation !== 0
: false;
@@ -486,7 +480,7 @@ export default class Card extends React.Component<Props> {
<CardAnimationContext.Provider value={animationContext}>
<View pointerEvents="box-none" {...rest}>
{overlayEnabled ? (
<View style={StyleSheet.absoluteFill}>
<View pointerEvents="box-none" style={StyleSheet.absoluteFill}>
{overlay({ style: overlayStyle })}
</View>
) : null}

View File

@@ -115,7 +115,7 @@ export default class StackView extends React.Component<Props, State> {
// We only need to animate routes if the focused route changed
// Animating previous routes won't be visible coz the focused route is on top of everything
if (!previousRoutes.find(r => r.key === nextFocusedRoute.key)) {
if (!previousRoutes.find((r) => r.key === nextFocusedRoute.key)) {
// A new route has come to the focus, we treat this as a push
// A replace can also trigger this, the animation should look like push
@@ -128,17 +128,17 @@ export default class StackView extends React.Component<Props, State> {
openingRouteKeys = [...openingRouteKeys, nextFocusedRoute.key];
closingRouteKeys = closingRouteKeys.filter(
key => key !== nextFocusedRoute.key
(key) => key !== nextFocusedRoute.key
);
replacingRouteKeys = replacingRouteKeys.filter(
key => key !== nextFocusedRoute.key
(key) => key !== nextFocusedRoute.key
);
if (!routes.find(r => r.key === previousFocusedRoute.key)) {
if (!routes.find((r) => r.key === previousFocusedRoute.key)) {
// The previous focused route isn't present in state, we treat this as a replace
openingRouteKeys = openingRouteKeys.filter(
key => key !== previousFocusedRoute.key
(key) => key !== previousFocusedRoute.key
);
if (getAnimationTypeForReplace(nextFocusedRoute.key) === 'pop') {
@@ -151,7 +151,7 @@ export default class StackView extends React.Component<Props, State> {
// But since user configured it to animate the old screen like a pop, we need to add this without animation
// So remove it from `openingRouteKeys` which will remove the animation
openingRouteKeys = openingRouteKeys.filter(
key => key !== nextFocusedRoute.key
(key) => key !== nextFocusedRoute.key
);
// Keep the route being removed at the end to animate it out
@@ -163,7 +163,7 @@ export default class StackView extends React.Component<Props, State> {
];
closingRouteKeys = closingRouteKeys.filter(
key => key !== previousFocusedRoute.key
(key) => key !== previousFocusedRoute.key
);
// Keep the old route in the state because it's visible under the new route, and removing it will feel abrupt
@@ -174,7 +174,7 @@ export default class StackView extends React.Component<Props, State> {
}
}
}
} else if (!routes.find(r => r.key === previousFocusedRoute.key)) {
} else if (!routes.find((r) => r.key === previousFocusedRoute.key)) {
// The previously focused route was removed, we treat this as a pop
if (
@@ -186,10 +186,10 @@ export default class StackView extends React.Component<Props, State> {
// Sometimes a route can be closed before the opening animation finishes
// So we also need to remove it from the opening list
openingRouteKeys = openingRouteKeys.filter(
key => key !== previousFocusedRoute.key
(key) => key !== previousFocusedRoute.key
);
replacingRouteKeys = replacingRouteKeys.filter(
key => key !== previousFocusedRoute.key
(key) => key !== previousFocusedRoute.key
);
// Keep a copy of route being removed in the state to be able to animate it
@@ -271,13 +271,13 @@ export default class StackView extends React.Component<Props, State> {
private getPreviousRoute = ({ route }: { route: Route<string> }) => {
const { closingRouteKeys, replacingRouteKeys } = this.state;
const routes = this.state.routes.filter(
r =>
(r) =>
r.key === route.key ||
(!closingRouteKeys.includes(r.key) &&
!replacingRouteKeys.includes(r.key))
);
const index = routes.findIndex(r => r.key === route.key);
const index = routes.findIndex((r) => r.key === route.key);
return routes[index - 1];
};
@@ -298,12 +298,16 @@ export default class StackView extends React.Component<Props, State> {
};
private handleOpenRoute = ({ route }: { route: Route<string> }) => {
this.setState(state => ({
this.setState((state) => ({
routes: state.replacingRouteKeys.length
? state.routes.filter(r => !state.replacingRouteKeys.includes(r.key))
? state.routes.filter((r) => !state.replacingRouteKeys.includes(r.key))
: state.routes,
openingRouteKeys: state.openingRouteKeys.filter(key => key !== route.key),
closingRouteKeys: state.closingRouteKeys.filter(key => key !== route.key),
openingRouteKeys: state.openingRouteKeys.filter(
(key) => key !== route.key
),
closingRouteKeys: state.closingRouteKeys.filter(
(key) => key !== route.key
),
replacingRouteKeys: [],
}));
};
@@ -311,7 +315,7 @@ export default class StackView extends React.Component<Props, State> {
private handleCloseRoute = ({ route }: { route: Route<string> }) => {
const { state, navigation } = this.props;
if (state.routes.find(r => r.key === route.key)) {
if (state.routes.find((r) => r.key === route.key)) {
// 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
@@ -322,13 +326,13 @@ export default class StackView extends React.Component<Props, State> {
});
} else {
// 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),
this.setState((state) => ({
routes: state.routes.filter((r) => r.key !== route.key),
openingRouteKeys: state.openingRouteKeys.filter(
key => key !== route.key
(key) => key !== route.key
),
closingRouteKeys: state.closingRouteKeys.filter(
key => key !== route.key
(key) => key !== route.key
),
}));
}
@@ -378,9 +382,9 @@ export default class StackView extends React.Component<Props, State> {
<GestureHandlerWrapper style={styles.container}>
<SafeAreaProviderCompat>
<SafeAreaConsumer>
{insets => (
{(insets) => (
<KeyboardManager enabled={keyboardHandlingEnabled !== false}>
{props => (
{(props) => (
<CardStack
mode={mode}
insets={insets as EdgeInsets}

View File

@@ -9,7 +9,7 @@ const packages = path.join(__dirname, '..', 'packages');
const invalid = [];
fs.readdirSync(packages).forEach(name => {
fs.readdirSync(packages).forEach((name) => {
const dir = path.join(packages, name);
if (fs.statSync(path.join(packages, name)).isDirectory()) {
@@ -26,6 +26,6 @@ fs.readdirSync(packages).forEach(name => {
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')
invalid.map((p) => `- ${p.name} (${p.types})`).join('\n')
);
}

View File

@@ -14637,10 +14637,10 @@ prettier-linter-helpers@^1.0.0:
dependencies:
fast-diff "^1.1.2"
prettier@^1.19.1:
version "1.19.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
prettier@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.1.tgz#3f00ac71263be34684b2b2c8d7e7f63737592dac"
integrity sha512-piXGBcY1zoFOG0MvHpNE5reAGseLmaCRifQ/fmfF49BcYkInEs/naD/unxGNAeOKFA5+JxVrPyMvMlpzcd20UA==
pretty-bytes@^4.0.2:
version "4.0.2"