From 71992d23e2c5650fe152082d0b5be5d877663f1e Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Fri, 6 Nov 2020 19:30:16 -0800 Subject: [PATCH 01/25] screen types [nfc]: Rewrite `navigation` type for screens on AppNavigator. This is NFC because there are no changes to our effective type annotations -- we just restructure our code to be more like the new way that's documented [1] for React Navigation v5: alongside each navigator, have a "param list" type (here, `AppNavigatorParamList`) that maps a route name to that route's params and a generic helper type (here, `AppNavigationProp`) that consults it, then have each screen use that helper to type its `navigation` prop. As noted in a recent commit where we added src/nav/globalTypes, we might switch to a different structure after the upgrade is complete, but we're sticking with the docs for now. [1] https://reactnavigation.org/docs/typescript --- src/account-info/AccountDetailsScreen.js | 13 +++---- src/account/AccountPickScreen.js | 13 +++---- src/chat/ChatScreen.js | 15 ++++---- src/chat/GroupDetailsScreen.js | 16 ++++----- src/diagnostics/DiagnosticsScreen.js | 13 +++---- src/diagnostics/StorageScreen.js | 13 +++---- src/diagnostics/TimingScreen.js | 13 +++---- src/diagnostics/VariablesScreen.js | 13 +++---- src/emoji/EmojiPickerScreen.js | 13 +++---- src/lightbox/LightboxScreen.js | 17 ++++----- src/main/MainScreenWithTabs.js | 13 +++---- src/nav/AppNavigator.js | 46 ++++++++++++++++++++++++ src/nav/globalTypes.js | 4 +-- src/reactions/MessageReactionList.js | 16 ++++----- src/search/SearchMessagesScreen.js | 13 +++---- src/settings/DebugScreen.js | 13 +++---- src/settings/LanguageScreen.js | 13 +++---- src/settings/LegalScreen.js | 13 +++---- src/settings/NotificationsScreen.js | 13 +++---- src/sharing/SharingScreen.js | 18 +++++----- src/start/AuthScreen.js | 17 ++++----- src/start/DevAuthScreen.js | 13 +++---- src/start/LoadingScreen.js | 12 +++---- src/start/PasswordAuthScreen.js | 16 ++++----- src/start/RealmScreen.js | 19 ++++------ src/streams/CreateStreamScreen.js | 13 +++---- src/streams/EditStreamScreen.js | 16 ++++----- src/streams/InviteUsersScreen.js | 16 ++++----- src/streams/StreamScreen.js | 16 ++++----- src/topics/TopicListScreen.js | 16 ++++----- src/user-groups/CreateGroupScreen.js | 13 +++---- src/user-status/UserStatusScreen.js | 13 +++---- src/users/UsersScreen.js | 13 +++---- 33 files changed, 266 insertions(+), 228 deletions(-) diff --git a/src/account-info/AccountDetailsScreen.js b/src/account-info/AccountDetailsScreen.js index ca90c04f313..ebab1769bcf 100644 --- a/src/account-info/AccountDetailsScreen.js +++ b/src/account-info/AccountDetailsScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Dispatch, UserOrBot } from '../types'; import { createStyleSheet } from '../styles'; import { connect } from '../react-redux'; @@ -30,11 +30,12 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| ...NavigationStateRoute, params: {| userId: number |} |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'account-details'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/account/AccountPickScreen.js b/src/account/AccountPickScreen.js index ab16b34d04d..7b637817337 100644 --- a/src/account/AccountPickScreen.js +++ b/src/account/AccountPickScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; @@ -13,11 +13,12 @@ import AccountList from './AccountList'; import { navigateToRealmScreen, accountSwitch, removeAccount } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'account'>, accounts: $ReadOnlyArray, dispatch: Dispatch, diff --git a/src/chat/ChatScreen.js b/src/chat/ChatScreen.js index 87c1673695f..da4fcb42b72 100644 --- a/src/chat/ChatScreen.js +++ b/src/chat/ChatScreen.js @@ -1,14 +1,14 @@ /* @flow strict-local */ import React from 'react'; import { View } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; import { withNavigationFocus } from 'react-navigation'; import { ActionSheetProvider } from '@expo/react-native-action-sheet'; import { compose } from 'redux'; import { useSelector, useDispatch } from '../react-redux'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import styles, { ThemeContext, createStyleSheet } from '../styles'; -import type { Narrow, EditMessage } from '../types'; +import type { EditMessage } from '../types'; import { KeyboardAvoider, OfflineNotice, ZulipStatusBar } from '../common'; import ChatNavBar from '../nav/ChatNavBar'; import MessageList from '../webview/MessageList'; @@ -24,11 +24,12 @@ import { getFetchingForNarrow } from './fetchingSelectors'; import { getShownMessagesForNarrow, isNarrowValid as getIsNarrowValid } from './narrowsSelectors'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| ...NavigationStateRoute, params: {| narrow: Narrow |} |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'chat'>, // From React Navigation's `withNavigationFocus` HOC. Type copied // from the libdef. diff --git a/src/chat/GroupDetailsScreen.js b/src/chat/GroupDetailsScreen.js index e7f8d093a94..d4b7b61a971 100644 --- a/src/chat/GroupDetailsScreen.js +++ b/src/chat/GroupDetailsScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch, UserOrBot } from '../types'; import { connect } from '../react-redux'; @@ -11,14 +11,12 @@ import { UserItemById } from '../users/UserItem'; import { navigateToAccountDetails } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| recipients: $ReadOnlyArray |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'group-details'>, dispatch: Dispatch, |}>; diff --git a/src/diagnostics/DiagnosticsScreen.js b/src/diagnostics/DiagnosticsScreen.js index aecdedece8f..67449c5be17 100644 --- a/src/diagnostics/DiagnosticsScreen.js +++ b/src/diagnostics/DiagnosticsScreen.js @@ -1,9 +1,9 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; import { nativeApplicationVersion } from 'expo-application'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import { createStyleSheet } from '../styles'; import { OptionButton, OptionDivider, Screen, RawLabel } from '../common'; @@ -22,11 +22,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'diagnostics'>, |}>; export default class DiagnosticsScreen extends PureComponent { diff --git a/src/diagnostics/StorageScreen.js b/src/diagnostics/StorageScreen.js index eea73f5b3fc..dcb557a38bb 100644 --- a/src/diagnostics/StorageScreen.js +++ b/src/diagnostics/StorageScreen.js @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { GlobalState, Dispatch } from '../types'; import { connect } from '../react-redux'; import { Screen } from '../common'; @@ -18,11 +18,12 @@ const calculateKeyStorageSizes = obj => .sort((a, b) => b.size - a.size); type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'storage'>, dispatch: Dispatch, state: GlobalState, diff --git a/src/diagnostics/TimingScreen.js b/src/diagnostics/TimingScreen.js index c46c9089ad7..147db250a3e 100644 --- a/src/diagnostics/TimingScreen.js +++ b/src/diagnostics/TimingScreen.js @@ -1,18 +1,19 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import { Screen } from '../common'; import TimeItem from './TimeItem'; import timing from '../utils/timing'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'timing'>, |}>; export default class TimingScreen extends PureComponent { diff --git a/src/diagnostics/VariablesScreen.js b/src/diagnostics/VariablesScreen.js index 2d37696bb3c..cd3cde8aa8a 100644 --- a/src/diagnostics/VariablesScreen.js +++ b/src/diagnostics/VariablesScreen.js @@ -1,18 +1,19 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import config from '../config'; import { Screen } from '../common'; import InfoItem from './InfoItem'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'variables'>, |}>; export default class VariablesScreen extends PureComponent { diff --git a/src/emoji/EmojiPickerScreen.js b/src/emoji/EmojiPickerScreen.js index f73ee75216d..225005235c7 100644 --- a/src/emoji/EmojiPickerScreen.js +++ b/src/emoji/EmojiPickerScreen.js @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import * as api from '../api'; import { unicodeCodeByName } from './codePointMap'; @@ -17,11 +17,12 @@ import { navigateBack } from '../nav/navActions'; import zulipExtraEmojiMap from './zulipExtraEmojiMap'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| ...NavigationStateRoute, params: {| messageId: number |} |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'emoji-picker'>, activeImageEmojiByName: RealmEmojiById, auth: Auth, diff --git a/src/lightbox/LightboxScreen.js b/src/lightbox/LightboxScreen.js index 5674e890994..f3defd20332 100644 --- a/src/lightbox/LightboxScreen.js +++ b/src/lightbox/LightboxScreen.js @@ -1,13 +1,12 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; import { ActionSheetProvider } from '@expo/react-native-action-sheet'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import { ZulipStatusBar } from '../common'; import { createStyleSheet } from '../styles'; import Lightbox from './Lightbox'; -import type { Message } from '../types'; const styles = createStyleSheet({ screen: { @@ -19,14 +18,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| src: string, message: Message |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'lightbox'>, |}>; export default class LightboxScreen extends PureComponent { diff --git a/src/main/MainScreenWithTabs.js b/src/main/MainScreenWithTabs.js index a50ba3babfc..2bc0fac7af6 100644 --- a/src/main/MainScreenWithTabs.js +++ b/src/main/MainScreenWithTabs.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; import { getHaveServerData } from '../selectors'; @@ -12,11 +12,12 @@ import { OfflineNotice, ZulipStatusBar } from '../common'; import MainTabs from './MainTabs'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'main'>, dispatch: Dispatch, haveServerData: boolean, diff --git a/src/nav/AppNavigator.js b/src/nav/AppNavigator.js index 3db7157ac9b..2abcb3aca6d 100644 --- a/src/nav/AppNavigator.js +++ b/src/nav/AppNavigator.js @@ -13,8 +13,13 @@ import { // `@react-navigation/stack` libdef. // $FlowFixMe TransitionPresets, + type NavigationStackProp, + type NavigationStateRoute, } from 'react-navigation-stack'; +import type { Narrow, Message, SharedData } from '../types'; +import type { ApiResponseServerSettings } from '../api/settings/getServerSettings'; +import type { GlobalParamList } from './globalTypes'; import AccountPickScreen from '../account/AccountPickScreen'; import RealmScreen from '../start/RealmScreen'; import AuthScreen from '../start/AuthScreen'; @@ -47,6 +52,47 @@ import LegalScreen from '../settings/LegalScreen'; import UserStatusScreen from '../user-status/UserStatusScreen'; import SharingScreen from '../sharing/SharingScreen'; +export type AppNavigatorParamList = {| + account: void, + 'account-details': {| userId: number |}, + 'group-details': {| recipients: $ReadOnlyArray |}, + auth: {| serverSettings: ApiResponseServerSettings |}, + chat: {| narrow: Narrow |}, + dev: void, + 'emoji-picker': {| messageId: number |}, + loading: void, + main: void, + 'message-reactions': {| reactionName?: string, messageId: number |}, + password: {| requireEmailFormat: boolean |}, + realm: {| realm: URL | void, initial: boolean | void |}, + search: void, + users: void, + language: void, + lightbox: {| src: string, message: Message |}, + group: void, + 'invite-users': {| streamId: number |}, + diagnostics: void, + variables: void, + timing: void, + storage: void, + debug: void, + stream: {| streamId: number |}, + 'stream-edit': {| streamId: number |}, + 'stream-create': void, + topics: {| streamId: number |}, + notifications: void, + legal: void, + 'user-status': void, + sharing: {| sharedData: SharedData |}, +|}; + +export type AppNavigationProp< + RouteName: $Keys = $Keys, +> = NavigationStackProp<{| + ...NavigationStateRoute, + params: $ElementType, +|}>; + export const createAppNavigator = (args: {| initialRouteName: string, initialRouteParams?: NavigationParams, diff --git a/src/nav/globalTypes.js b/src/nav/globalTypes.js index a2b8aee893b..fecd69d5607 100644 --- a/src/nav/globalTypes.js +++ b/src/nav/globalTypes.js @@ -1,12 +1,12 @@ /* @flow strict-local */ -// import type { AppNavigatorParamList } from './AppNavigator'; +import type { AppNavigatorParamList } from './AppNavigator'; // import type { SharingNavigatorParamList } from '../sharing/SharingScreen'; // import type { StreamTabsNavigatorParamList } from '../main/StreamTabs'; // import type { MainTabsNavigatorParamList } from '../main/MainTabs'; export type GlobalParamList = {| - // ...AppNavigatorParamList, + ...AppNavigatorParamList, // ...SharingNavigatorParamList, // ...StreamTabsNavigatorParamList, // ...MainTabsNavigatorParamList, diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index fa4c2b6475f..0b0d38fdf49 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -2,9 +2,9 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; import { createAppContainer } from 'react-navigation'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import * as logging from '../utils/logging'; import ReactionUserList from './ReactionUserList'; @@ -104,14 +104,12 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| reactionName?: string, messageId: number |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'message-reactions'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/search/SearchMessagesScreen.js b/src/search/SearchMessagesScreen.js index fd45ae96a29..83300665a0a 100644 --- a/src/search/SearchMessagesScreen.js +++ b/src/search/SearchMessagesScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Auth, Dispatch, Message } from '../types'; import { Screen } from '../common'; import SearchMessagesCard from './SearchMessagesCard'; @@ -13,11 +13,12 @@ import { getAuth } from '../account/accountsSelectors'; import { fetchMessages } from '../message/fetchActions'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'search'>, auth: Auth, dispatch: Dispatch, diff --git a/src/settings/DebugScreen.js b/src/settings/DebugScreen.js index beb0f0e4176..dfb3fa554aa 100644 --- a/src/settings/DebugScreen.js +++ b/src/settings/DebugScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Debug, Dispatch } from '../types'; import { connect } from '../react-redux'; import { getSession } from '../selectors'; @@ -10,11 +10,12 @@ import { OptionRow, Screen } from '../common'; import { debugFlagToggle } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'debug'>, debug: Debug, dispatch: Dispatch, diff --git a/src/settings/LanguageScreen.js b/src/settings/LanguageScreen.js index ddb5eaa5c7d..ff4bfe3d3c2 100644 --- a/src/settings/LanguageScreen.js +++ b/src/settings/LanguageScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; import { Screen } from '../common'; @@ -11,11 +11,12 @@ import { getSettings } from '../selectors'; import { settingsChange } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'language'>, dispatch: Dispatch, locale: string, diff --git a/src/settings/LegalScreen.js b/src/settings/LegalScreen.js index 2c468c98825..b0727d025a7 100644 --- a/src/settings/LegalScreen.js +++ b/src/settings/LegalScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; import { Screen, OptionButton } from '../common'; @@ -10,11 +10,12 @@ import openLink from '../utils/openLink'; import { getCurrentRealm } from '../selectors'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'legal'>, dispatch: Dispatch, realm: URL, diff --git a/src/settings/NotificationsScreen.js b/src/settings/NotificationsScreen.js index b982654c7cd..9789d76f763 100644 --- a/src/settings/NotificationsScreen.js +++ b/src/settings/NotificationsScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Auth, Dispatch } from '../types'; import { connect } from '../react-redux'; import { getAuth, getSettings } from '../selectors'; @@ -11,11 +11,12 @@ import * as api from '../api'; import { settingsChange } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'notifications'>, auth: Auth, dispatch: Dispatch, diff --git a/src/sharing/SharingScreen.js b/src/sharing/SharingScreen.js index 2da85f5d04d..45155d98bf3 100644 --- a/src/sharing/SharingScreen.js +++ b/src/sharing/SharingScreen.js @@ -1,12 +1,12 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { Text } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; import { FormattedMessage } from 'react-intl'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; -import type { Dispatch, SharedData, Auth } from '../types'; +import type { Dispatch, Auth } from '../types'; import { createStyleSheet } from '../styles'; import { materialTopTabNavigatorConfig } from '../styles/tabs'; import { connect } from '../react-redux'; @@ -17,14 +17,12 @@ import ShareToStream from './ShareToStream'; import ShareToPm from './ShareToPm'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| sharedData: SharedData |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'sharing'>, auth: Auth | void, dispatch: Dispatch, diff --git a/src/start/AuthScreen.js b/src/start/AuthScreen.js index d982f885e31..da806667233 100644 --- a/src/start/AuthScreen.js +++ b/src/start/AuthScreen.js @@ -2,17 +2,16 @@ import React, { PureComponent } from 'react'; import { Linking, Platform } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; import type { AppleAuthenticationCredential } from 'expo-apple-authentication'; import * as AppleAuthentication from 'expo-apple-authentication'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import config from '../config'; import type { Dispatch } from '../types'; import type { AuthenticationMethods, ExternalAuthenticationMethod, - ApiResponseServerSettings, } from '../api/settings/getServerSettings'; import { IconApple, @@ -168,14 +167,12 @@ export const activeAuthentications = ( }; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| serverSettings: ApiResponseServerSettings |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'auth'>, dispatch: Dispatch, realm: URL, diff --git a/src/start/DevAuthScreen.js b/src/start/DevAuthScreen.js index 5ee27a46740..6e986ccdf4e 100644 --- a/src/start/DevAuthScreen.js +++ b/src/start/DevAuthScreen.js @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react'; import { ActivityIndicator, View, FlatList } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Auth, DevUser, Dispatch } from '../types'; import styles, { createStyleSheet } from '../styles'; import { connect } from '../react-redux'; @@ -28,11 +28,12 @@ const componentStyles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'dev'>, partialAuth: Auth, dispatch: Dispatch, diff --git a/src/start/LoadingScreen.js b/src/start/LoadingScreen.js index c952a598f8a..699cf6b7f89 100644 --- a/src/start/LoadingScreen.js +++ b/src/start/LoadingScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import { BRAND_COLOR, createStyleSheet } from '../styles'; import { LoadingIndicator, ZulipStatusBar } from '../common'; @@ -16,11 +16,11 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, but we - // do invoke it from one other place (see ZulipMobile.js), it might - // or might not get the `navigation` prop (with the stack-nav shape) - // for free. - navigation?: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, but + // we do invoke it from one other place, which is not a navigator + // (see ZulipMobile.js), it might or might not get the `navigation` + // prop (with the particular shape for this route) for free. + navigation?: AppNavigationProp<'loading'>, |}>; export default class LoadingScreen extends PureComponent { diff --git a/src/start/PasswordAuthScreen.js b/src/start/PasswordAuthScreen.js index 7c7af34dbe0..30432d0bd21 100644 --- a/src/start/PasswordAuthScreen.js +++ b/src/start/PasswordAuthScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Auth, Dispatch } from '../types'; import { createStyleSheet } from '../styles'; import { connect } from '../react-redux'; @@ -27,14 +27,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| requireEmailFormat: boolean |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'password'>, partialAuth: Auth, dispatch: Dispatch, diff --git a/src/start/RealmScreen.js b/src/start/RealmScreen.js index 96acf19ad39..b5e76cb23c1 100644 --- a/src/start/RealmScreen.js +++ b/src/start/RealmScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { ScrollView, Keyboard } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import { ZulipVersion } from '../utils/zulipVersion'; import type { Dispatch } from '../types'; @@ -18,17 +18,12 @@ type SelectorProps = {| |}; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| - realm: URL | void, - initial: boolean | void, - |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'realm'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/streams/CreateStreamScreen.js b/src/streams/CreateStreamScreen.js index c0c385884e5..a6df8576835 100644 --- a/src/streams/CreateStreamScreen.js +++ b/src/streams/CreateStreamScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; @@ -11,11 +11,12 @@ import { Screen } from '../common'; import EditStreamCard from './EditStreamCard'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'stream-create'>, dispatch: Dispatch, ownEmail: string, diff --git a/src/streams/EditStreamScreen.js b/src/streams/EditStreamScreen.js index 6635f2efc29..d4a74a180be 100644 --- a/src/streams/EditStreamScreen.js +++ b/src/streams/EditStreamScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch, Stream } from '../types'; import { connect } from '../react-redux'; @@ -15,14 +15,12 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| streamId: number |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'stream-edit'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/streams/InviteUsersScreen.js b/src/streams/InviteUsersScreen.js index e321ce546ba..64b71abd83b 100644 --- a/src/streams/InviteUsersScreen.js +++ b/src/streams/InviteUsersScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Auth, Dispatch, Stream, User } from '../types'; import { connect } from '../react-redux'; @@ -17,14 +17,12 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| streamId: number |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'invite-users'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/streams/StreamScreen.js b/src/streams/StreamScreen.js index 3a9c695180c..8c5df9cc460 100644 --- a/src/streams/StreamScreen.js +++ b/src/streams/StreamScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch, Stream, Subscription } from '../types'; import { connect } from '../react-redux'; @@ -31,14 +31,12 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| streamId: number |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'stream'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/topics/TopicListScreen.js b/src/topics/TopicListScreen.js index a126e38419d..7ed2c9c058d 100644 --- a/src/topics/TopicListScreen.js +++ b/src/topics/TopicListScreen.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { Dispatch, Stream, TopicExtended } from '../types'; import { connect } from '../react-redux'; import { Screen } from '../common'; @@ -18,14 +18,12 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| - ...NavigationStateRoute, - params: {| streamId: number |}, - |}>, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'topics'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/user-groups/CreateGroupScreen.js b/src/user-groups/CreateGroupScreen.js index 47e50784660..c2810818393 100644 --- a/src/user-groups/CreateGroupScreen.js +++ b/src/user-groups/CreateGroupScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch, User } from '../types'; import { connect } from '../react-redux'; @@ -17,11 +17,12 @@ type SelectorProps = {| |}; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'group'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/user-status/UserStatusScreen.js b/src/user-status/UserStatusScreen.js index 2f7ed80203f..dfbf0c866ce 100644 --- a/src/user-status/UserStatusScreen.js +++ b/src/user-status/UserStatusScreen.js @@ -1,10 +1,10 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { FlatList, View } from 'react-native'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; import { TranslationContext } from '../boot/TranslationProvider'; import { createStyleSheet } from '../styles'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { GetText, Dispatch } from '../types'; import { connect } from '../react-redux'; @@ -29,11 +29,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'user-status'>, dispatch: Dispatch, userStatusText: string, diff --git a/src/users/UsersScreen.js b/src/users/UsersScreen.js index 5c97f7aad84..ce387e0e7c4 100644 --- a/src/users/UsersScreen.js +++ b/src/users/UsersScreen.js @@ -1,16 +1,17 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation-stack'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import { Screen } from '../common'; import UsersCard from './UsersCard'; type Props = $ReadOnly<{| - // Since we've put this screen in a stack-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp, + // Since we've put this screen in AppNavigator's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: AppNavigationProp<'users'>, |}>; type State = {| From b09325a6699abec2f23e1afcdd7c307816693118 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 09:10:07 -0800 Subject: [PATCH 02/25] screen types [nfc]: Rewrite `navigation` type for screens on `MainTabs`. Like the previous commit, but for `MainTabs`. --- src/account-info/ProfileCard.js | 13 ++++++------ src/main/HomeTab.js | 13 ++++++------ src/main/MainTabs.js | 22 ++++++++++++++++++++- src/nav/globalTypes.js | 4 ++-- src/pm-conversations/PmConversationsCard.js | 13 ++++++------ src/settings/SettingsCard.js | 13 ++++++------ 6 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/account-info/ProfileCard.js b/src/account-info/ProfileCard.js index 584bd458e2d..022ceda3682 100644 --- a/src/account-info/ProfileCard.js +++ b/src/account-info/ProfileCard.js @@ -1,8 +1,8 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { ScrollView, View } from 'react-native'; -import type { NavigationTabProp, NavigationStateRoute } from 'react-navigation-tabs'; +import type { MainTabsNavigationProp } from '../main/MainTabs'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch, User } from '../types'; import { createStyleSheet } from '../styles'; @@ -66,11 +66,12 @@ class LogoutButton extends PureComponent<{| +dispatch: Dispatch |}> { } type Props = $ReadOnly<{| - // Since we've put this screen in a tab-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the tab-nav shape. - navigation: NavigationTabProp, + // Since we've put this screen in MainTabs's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: MainTabsNavigationProp<'profile'>, dispatch: Dispatch, selfUserDetail: User, diff --git a/src/main/HomeTab.js b/src/main/HomeTab.js index 7dda0909818..59524646bab 100644 --- a/src/main/HomeTab.js +++ b/src/main/HomeTab.js @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationTabProp, NavigationStateRoute } from 'react-navigation-tabs'; +import type { MainTabsNavigationProp } from './MainTabs'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; @@ -28,11 +28,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a tab-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the tab-nav shape. - navigation: NavigationTabProp, + // Since we've put this screen in MainTabs's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: MainTabsNavigationProp<'home'>, dispatch: Dispatch, |}>; diff --git a/src/main/MainTabs.js b/src/main/MainTabs.js index c1e501d3e18..0f59f0fe35d 100644 --- a/src/main/MainTabs.js +++ b/src/main/MainTabs.js @@ -1,8 +1,13 @@ /* @flow strict-local */ import React from 'react'; import { Platform } from 'react-native'; -import { createBottomTabNavigator } from 'react-navigation-tabs'; +import { + createBottomTabNavigator, + type NavigationTabProp, + type NavigationStateRoute, +} from 'react-navigation-tabs'; +import type { GlobalParamList } from '../nav/globalTypes'; import { bottomTabNavigatorConfig } from '../styles/tabs'; import HomeTab from './HomeTab'; import StreamTabs from './StreamTabs'; @@ -13,6 +18,21 @@ import { OwnAvatar } from '../common'; import IconUnreadConversations from '../nav/IconUnreadConversations'; import ProfileCard from '../account-info/ProfileCard'; +export type MainTabsNavigatorParamList = {| + home: void, + streams: void, + conversations: void, + settings: void, + profile: void, +|}; + +export type MainTabsNavigationProp< + RouteName: $Keys = $Keys, +> = NavigationTabProp<{| + ...NavigationStateRoute, + params: $ElementType, +|}>; + export default createBottomTabNavigator( { home: { diff --git a/src/nav/globalTypes.js b/src/nav/globalTypes.js index fecd69d5607..b6a79e0881e 100644 --- a/src/nav/globalTypes.js +++ b/src/nav/globalTypes.js @@ -3,11 +3,11 @@ import type { AppNavigatorParamList } from './AppNavigator'; // import type { SharingNavigatorParamList } from '../sharing/SharingScreen'; // import type { StreamTabsNavigatorParamList } from '../main/StreamTabs'; -// import type { MainTabsNavigatorParamList } from '../main/MainTabs'; +import type { MainTabsNavigatorParamList } from '../main/MainTabs'; export type GlobalParamList = {| ...AppNavigatorParamList, // ...SharingNavigatorParamList, // ...StreamTabsNavigatorParamList, - // ...MainTabsNavigatorParamList, + ...MainTabsNavigatorParamList, |}; diff --git a/src/pm-conversations/PmConversationsCard.js b/src/pm-conversations/PmConversationsCard.js index e61cc6e25d8..72d8edbe93d 100644 --- a/src/pm-conversations/PmConversationsCard.js +++ b/src/pm-conversations/PmConversationsCard.js @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationTabProp, NavigationStateRoute } from 'react-navigation-tabs'; +import type { MainTabsNavigationProp } from '../main/MainTabs'; import * as NavigationService from '../nav/NavigationService'; import type { ThemeData } from '../styles'; import { ThemeContext, createStyleSheet } from '../styles'; @@ -35,11 +35,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a tab-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the tab-nav shape. - navigation: NavigationTabProp, + // Since we've put this screen in MainTabs's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: MainTabsNavigationProp<'conversations'>, dispatch: Dispatch, conversations: PmConversationData[], diff --git a/src/settings/SettingsCard.js b/src/settings/SettingsCard.js index dab1031c6e7..f1687f68860 100644 --- a/src/settings/SettingsCard.js +++ b/src/settings/SettingsCard.js @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react'; import { ScrollView } from 'react-native'; -import type { NavigationTabProp, NavigationStateRoute } from 'react-navigation-tabs'; +import type { MainTabsNavigationProp } from '../main/MainTabs'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch } from '../types'; import { createStyleSheet } from '../styles'; @@ -33,11 +33,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a tab-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the tab-nav shape. - navigation: NavigationTabProp, + // Since we've put this screen in MainTabs's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: MainTabsNavigationProp<'settings'>, theme: string, dispatch: Dispatch, From 48cf5ca9f01b85c436c6e3e4ce8e854b879adda7 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 09:59:56 -0800 Subject: [PATCH 03/25] screen types [nfc]: Rewrite `navigation` type for screens on `StreamTabs`. Like the previous commits, but for `StreamTabs`. --- src/main/StreamTabs.js | 19 ++++++++++++++++++- src/nav/globalTypes.js | 4 ++-- src/streams/SubscriptionsCard.js | 9 +++++---- src/subscriptions/StreamListCard.js | 9 +++++---- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/main/StreamTabs.js b/src/main/StreamTabs.js index 12e5c1c38d6..28a6605400a 100644 --- a/src/main/StreamTabs.js +++ b/src/main/StreamTabs.js @@ -2,13 +2,30 @@ import React from 'react'; import { Text } from 'react-native'; import { FormattedMessage } from 'react-intl'; -import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; +import { + createMaterialTopTabNavigator, + type NavigationTabProp, + type NavigationStateRoute, +} from 'react-navigation-tabs'; +import type { GlobalParamList } from '../nav/globalTypes'; import { createStyleSheet } from '../styles'; import { materialTopTabNavigatorConfig } from '../styles/tabs'; import SubscriptionsCard from '../streams/SubscriptionsCard'; import StreamListCard from '../subscriptions/StreamListCard'; +export type StreamTabsNavigatorParamList = {| + subscribed: void, + allStreams: void, +|}; + +export type StreamTabsNavigationProp< + RouteName: $Keys = $Keys, +> = NavigationTabProp<{| + ...NavigationStateRoute, + params: $ElementType, +|}>; + const styles = createStyleSheet({ tab: { padding: 8, diff --git a/src/nav/globalTypes.js b/src/nav/globalTypes.js index b6a79e0881e..d87430ef34c 100644 --- a/src/nav/globalTypes.js +++ b/src/nav/globalTypes.js @@ -2,12 +2,12 @@ import type { AppNavigatorParamList } from './AppNavigator'; // import type { SharingNavigatorParamList } from '../sharing/SharingScreen'; -// import type { StreamTabsNavigatorParamList } from '../main/StreamTabs'; +import type { StreamTabsNavigatorParamList } from '../main/StreamTabs'; import type { MainTabsNavigatorParamList } from '../main/MainTabs'; export type GlobalParamList = {| ...AppNavigatorParamList, // ...SharingNavigatorParamList, - // ...StreamTabsNavigatorParamList, + ...StreamTabsNavigatorParamList, ...MainTabsNavigatorParamList, |}; diff --git a/src/streams/SubscriptionsCard.js b/src/streams/SubscriptionsCard.js index 1097a44c7bd..03a24977675 100644 --- a/src/streams/SubscriptionsCard.js +++ b/src/streams/SubscriptionsCard.js @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationTabProp, NavigationStateRoute } from 'react-navigation-tabs'; +import type { StreamTabsNavigationProp } from '../main/StreamTabs'; import type { Dispatch, Subscription } from '../types'; import { createStyleSheet } from '../styles'; import { connect } from '../react-redux'; @@ -27,11 +27,12 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in a tab-nav route config, and we + // Since we've put this screen in StreamTabs's route config, and we // don't invoke it without type-checking anywhere else (in fact, we // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the tab-nav shape. - navigation: NavigationTabProp, + // `navigation` prop for free, with the particular shape for this + // route. + navigation: StreamTabsNavigationProp<'subscribed'>, dispatch: Dispatch, ...SelectorProps, diff --git a/src/subscriptions/StreamListCard.js b/src/subscriptions/StreamListCard.js index 6a09b14c104..a9e7b07d9ca 100644 --- a/src/subscriptions/StreamListCard.js +++ b/src/subscriptions/StreamListCard.js @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { NavigationTabProp, NavigationStateRoute } from 'react-navigation-tabs'; +import type { StreamTabsNavigationProp } from '../main/StreamTabs'; import * as NavigationService from '../nav/NavigationService'; import type { Auth, Dispatch, Stream, Subscription } from '../types'; import { createStyleSheet } from '../styles'; @@ -26,11 +26,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a tab-nav route config, and we + // Since we've put this screen in StreamTabs's route config, and we // don't invoke it without type-checking anywhere else (in fact, we // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the tab-nav shape. - navigation: NavigationTabProp, + // `navigation` prop for free, with the particular shape for this + // route. + navigation: StreamTabsNavigationProp<'allStreams'>, dispatch: Dispatch, auth: Auth, From c08e8821aa3fa2de35db64570fab13694f853015 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 12:37:26 -0800 Subject: [PATCH 04/25] screen types [nfc]: Rewrite `navigation` type for screens on SharingScreen. Like the previous commits, but for `SharingScreen`. --- src/nav/globalTypes.js | 4 ++-- src/sharing/ShareToPm.js | 18 ++++++++---------- src/sharing/ShareToStream.js | 18 ++++++++---------- src/sharing/SharingScreen.js | 21 +++++++++++++++++++-- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/nav/globalTypes.js b/src/nav/globalTypes.js index d87430ef34c..e2704734ac7 100644 --- a/src/nav/globalTypes.js +++ b/src/nav/globalTypes.js @@ -1,13 +1,13 @@ /* @flow strict-local */ import type { AppNavigatorParamList } from './AppNavigator'; -// import type { SharingNavigatorParamList } from '../sharing/SharingScreen'; +import type { SharingNavigatorParamList } from '../sharing/SharingScreen'; import type { StreamTabsNavigatorParamList } from '../main/StreamTabs'; import type { MainTabsNavigatorParamList } from '../main/MainTabs'; export type GlobalParamList = {| ...AppNavigatorParamList, - // ...SharingNavigatorParamList, + ...SharingNavigatorParamList, ...StreamTabsNavigatorParamList, ...MainTabsNavigatorParamList, |}; diff --git a/src/sharing/ShareToPm.js b/src/sharing/ShareToPm.js index 9ea857ea2a0..551facc6979 100644 --- a/src/sharing/ShareToPm.js +++ b/src/sharing/ShareToPm.js @@ -1,10 +1,10 @@ /* @flow strict-local */ import React from 'react'; import { View, Image, ScrollView, Modal, BackHandler } from 'react-native'; -import type { NavigationTabProp, NavigationStateRoute } from 'react-navigation-tabs'; +import type { SharingNavigationProp } from './SharingScreen'; import * as NavigationService from '../nav/NavigationService'; -import type { Dispatch, SharedData, User, Auth, GetText } from '../types'; +import type { Dispatch, User, Auth, GetText } from '../types'; import { createStyleSheet } from '../styles'; import { TranslationContext } from '../boot/TranslationProvider'; import { connect } from '../react-redux'; @@ -55,14 +55,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a tab-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the tab-nav shape. - navigation: NavigationTabProp<{| - ...NavigationStateRoute, - params: {| sharedData: SharedData |}, - |}>, + // Since we've put this screen in SharingScreen's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: SharingNavigationProp<'share-to-pm'>, dispatch: Dispatch, auth: Auth, diff --git a/src/sharing/ShareToStream.js b/src/sharing/ShareToStream.js index c553dd5c809..9ff2abb859b 100644 --- a/src/sharing/ShareToStream.js +++ b/src/sharing/ShareToStream.js @@ -1,10 +1,10 @@ /* @flow strict-local */ import React from 'react'; import { View, Image, ScrollView, BackHandler } from 'react-native'; -import type { NavigationTabProp, NavigationStateRoute } from 'react-navigation-tabs'; +import type { SharingNavigationProp } from './SharingScreen'; import * as NavigationService from '../nav/NavigationService'; -import type { Dispatch, SharedData, Subscription, Auth, GetText } from '../types'; +import type { Dispatch, Subscription, Auth, GetText } from '../types'; import { createStyleSheet } from '../styles'; import { TranslationContext } from '../boot/TranslationProvider'; import { connect } from '../react-redux'; @@ -43,14 +43,12 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in a tab-nav route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the tab-nav shape. - navigation: NavigationTabProp<{| - ...NavigationStateRoute, - params: {| sharedData: SharedData |}, - |}>, + // Since we've put this screen in SharingScreen's route config, and + // we don't invoke it without type-checking anywhere else (in fact, + // we don't invoke it anywhere else at all), we know it gets the + // `navigation` prop for free, with the particular shape for this + // route. + navigation: SharingNavigationProp<'share-to-stream'>, dispatch: Dispatch, subscriptions: Map, diff --git a/src/sharing/SharingScreen.js b/src/sharing/SharingScreen.js index 45155d98bf3..3f37bab8ddd 100644 --- a/src/sharing/SharingScreen.js +++ b/src/sharing/SharingScreen.js @@ -1,12 +1,17 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { Text } from 'react-native'; -import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; +import { + createMaterialTopTabNavigator, + type NavigationTabProp, + type NavigationStateRoute, +} from 'react-navigation-tabs'; import { FormattedMessage } from 'react-intl'; +import type { GlobalParamList } from '../nav/globalTypes'; import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; -import type { Dispatch, Auth } from '../types'; +import type { Dispatch, Auth, SharedData } from '../types'; import { createStyleSheet } from '../styles'; import { materialTopTabNavigatorConfig } from '../styles/tabs'; import { connect } from '../react-redux'; @@ -16,6 +21,18 @@ import { navigateToAccountPicker } from '../nav/navActions'; import ShareToStream from './ShareToStream'; import ShareToPm from './ShareToPm'; +export type SharingNavigatorParamList = {| + 'share-to-stream': {| sharedData: SharedData |}, + 'share-to-pm': {| sharedData: SharedData |}, +|}; + +export type SharingNavigationProp< + RouteName: $Keys = $Keys, +> = NavigationTabProp<{| + ...NavigationStateRoute, + params: $ElementType, +|}>; + type Props = $ReadOnly<{| // Since we've put this screen in AppNavigator's route config, and // we don't invoke it without type-checking anywhere else (in fact, From e7644194d54e1557e01c279cb4148e83b6dea4e3 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 17 Nov 2020 12:57:50 -0800 Subject: [PATCH 05/25] tabs: Add `elevation: 0` to base tab-nav config's tab bar style. The issue is illustrated in a screenshot at https://github.com/react-navigation/react-navigation/issues/7299#issuecomment-661810396. That's also where I got the idea to set `elevation` to 0. --- src/styles/tabs.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/styles/tabs.js b/src/styles/tabs.js index 914da3dc9e3..855ac1abb8d 100644 --- a/src/styles/tabs.js +++ b/src/styles/tabs.js @@ -30,6 +30,13 @@ const baseTabNavigatorConfig = (args: Props) => { }, style: { backgroundColor: 'transparent', + + // Starting in React Navigation v5, if we set + // `backgroundColor` to 'transparent', the tab bar will look + // very odd on Android. It will look normal with this + // Android-only `elevation` attribute set to 0. + elevation: 0, + ...style, }, }, From 07f748e7f82bf39ecb429909004deeacdd8f5302 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 14:55:01 -0800 Subject: [PATCH 06/25] MessageReactionList: Pass `initialRouteName`, even if `undefined`. We were scrupulous about not passing `initialRouteName` at all, in some cases, but it turns out that passing `undefined` in those cases is fine. See discussion at https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20MessageReactionList/near/1058099. --- src/reactions/MessageReactionList.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index 0b0d38fdf49..6d19a1b2392 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -77,13 +77,8 @@ const getReactionsTabs = ( // The user may have originally navigated here to look at a reaction // that's since been removed. Ignore the nav hint in that case. - // - // The `Object.freeze` in the `:` case avoids an open Flow - // issue: - // https://github.com/facebook/flow/issues/2386#issuecomment-695064325 - ...(reactionName !== undefined && reactionsTabs[reactionName] - ? { initialRouteName: reactionName } - : Object.freeze({})), + initialRouteName: + reactionName !== undefined && reactionsTabs[reactionName] ? reactionName : undefined, ...materialTopTabNavigatorConfig({ showLabel: true, From ac378a7f8314fccbc28233a6fa392db04b25b494 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 15:29:56 -0800 Subject: [PATCH 07/25] MessageReactionList [nfc]: Replace `getReactionsTabs` with two functions. This will make the upcoming React Navigation v5 upgrade diff smaller. See discussion at https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20MessageReactionList/near/1058076. --- src/reactions/MessageReactionList.js | 120 +++++++++++++++------------ 1 file changed, 69 insertions(+), 51 deletions(-) diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index 6d19a1b2392..ac74baa3ba2 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -34,63 +34,70 @@ const emojiTypeFromReactionType = (reactionType: ReactionType): EmojiType => { return 'image'; }; -// Generate tabs for the reaction list. The tabs depend on the distinct -// reactions on the message. -const getReactionsTabs = ( +/** + * Get the route config for a single aggregated reaction. + */ +const getRouteConfig = ( + aggregatedReaction: AggregatedReaction, + allUsersById: Map, +) => ({ + screen: () => ( + + ), + navigationOptions: { + tabBarLabel: () => ( + + + + + ), + }, +}); + +/** + * Generate route config for the reaction-tabs navigator. + * + * There is a tab, with a user list, for each of the message's + * distinct reactions. + */ +const getReactionTabsRoutes = ( aggregatedReactions: $ReadOnlyArray, - reactionName?: string, allUsersById: Map, -) => { - // Each tab corresponds to an aggregated reaction, and has a user list. - const reactionsTabs = objectFromEntries( +) => + objectFromEntries( aggregatedReactions.map(aggregatedReaction => [ aggregatedReaction.name, - { - screen: () => ( - - ), - navigationOptions: { - tabBarLabel: () => ( - - - - - ), - }, - }, + getRouteConfig(aggregatedReaction, allUsersById), ]), ); - // It's not feasible to set up our newly created tab navigator as - // part of the entire app's navigation (see the note at - // `getReactionsTabs`'s call site). Given that, it seems we can use - // `createAppContainer` so our violation of the "only explicitly - // render one navigator" rule doesn't cause a crashing error. But - // the name `createAppContainer` is enough to suggest that we're - // definitely doing something wrong here. - return createAppContainer( - createMaterialTopTabNavigator(reactionsTabs, { - backBehavior: 'none', - - // The user may have originally navigated here to look at a reaction - // that's since been removed. Ignore the nav hint in that case. - initialRouteName: - reactionName !== undefined && reactionsTabs[reactionName] ? reactionName : undefined, - - ...materialTopTabNavigatorConfig({ - showLabel: true, - showIcon: false, - style: { - borderWidth: 0.15, - }, - }), - swipeEnabled: true, - }), - ); -}; +/** + * Generate tab-navigator config for the reaction-tabs navigator. + */ +const getReactionTabsNavConfig = ( + aggregatedReactions: $ReadOnlyArray, + reactionName?: string, +) => ({ + backBehavior: 'none', + + // The user may have originally navigated here to look at a reaction + // that's since been removed. Ignore the nav hint in that case. + initialRouteName: aggregatedReactions.some(aR => aR.name === reactionName) + ? reactionName + : undefined, + + ...materialTopTabNavigatorConfig({ + showLabel: true, + showIcon: false, + style: { + borderWidth: 0.15, + }, + }), + swipeEnabled: true, +}); type SelectorProps = $ReadOnly<{| message: Message | void, @@ -155,7 +162,18 @@ class MessageReactionList extends PureComponent { // more than one navigator in the app, and the recommended // workaround isn't feasible; see discussion at // https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/Dynamic.20routes.20in.20react-navigation/near/1008268. - const TabView = getReactionsTabs(aggregatedReactions, reactionName, allUsersById); + // Given that, it seems we can use `createAppContainer` so our + // violation of the "only explicitly render one navigator" + // rule doesn't cause a crashing error. But the name + // `createAppContainer` is enough to suggest that we're + // definitely doing something wrong here. + const TabView = createAppContainer( + createMaterialTopTabNavigator( + getReactionTabsRoutes(aggregatedReactions, allUsersById), + getReactionTabsNavConfig(aggregatedReactions, reactionName), + ), + ); + return ( From 59ed9266275e307b91f0a7debc287cc88c082d86 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 11 Nov 2020 11:56:12 -0800 Subject: [PATCH 08/25] ZulipAppContainer: Pass `theme` prop to `AppContainer`. Both React Navigation v4 and v5 have interfaces for setting the theme between light and dark, but they're quite different. One kind of unfortunate difference is that, in v5, using that interface is effectively required, even though we have a so-far quite adequate way of managing the theme. React Navigation v5 widely applies some styling overrides to its provided components (such as the background of a scene in a bottom-tab navigator) even when we don't pass a `theme` prop. I'm not sure if it applies them based on its own arbitrary default, or if it's listening to the system-wide theme setting. But we're left with a choice between papering over each of those overridden styles, or taking up their theme interface and doing something with it. We take the latter approach because it's not piecemeal. (It would be tricky to find all the forced styles we'd need to override, and it's not obvious that we'll always be able to paper over them. One such fix is to set a `backgroundColor` within `sceneContainerStyle` in `MainTabs` -- but this wouldn't have been possible even a few months ago, before @react-navigation/bottom-tabs@5.10.0.) To smoothen the change toward using the `theme` prop in v5, start doing so now, while we're still on v4. Theme support is much more rudimentary in v4 (i.e., the `theme` prop here just takes "dark" or "light"), but I don't see anything particularly disruptive by starting to use it now [1], so, might as well. [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20theme.20colors/near/1061811 --- src/nav/ZulipAppContainer.js | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/nav/ZulipAppContainer.js b/src/nav/ZulipAppContainer.js index b11f728fd85..6833332e466 100644 --- a/src/nav/ZulipAppContainer.js +++ b/src/nav/ZulipAppContainer.js @@ -8,13 +8,16 @@ import { } from 'react-navigation'; import { connect } from '../react-redux'; +import type { ThemeData } from '../styles'; +import { ThemeContext } from '../styles'; import * as NavigationService from './NavigationService'; import getInitialRouteInfo from './getInitialRouteInfo'; -import type { Dispatch, Account } from '../types'; -import { hasAuth as getHasAuth, getAccounts, getHaveServerData } from '../selectors'; +import type { Dispatch, Account, ThemeName } from '../types'; +import { hasAuth as getHasAuth, getAccounts, getHaveServerData, getSettings } from '../selectors'; import { createAppNavigator } from './AppNavigator'; type SelectorProps = $ReadOnly<{| + theme: ThemeName, hasAuth: boolean, accounts: Account[], haveServerData: boolean, @@ -36,6 +39,9 @@ type Props = $ReadOnly<{| * and `initialRouteParams` which we get from data in Redux. */ class ZulipAppContainer extends PureComponent { + static contextType = ThemeContext; + context: ThemeData; + // (odd spacing choices) // eslint-disable-next-line AppContainer: NavigationContainer< @@ -54,11 +60,23 @@ class ZulipAppContainer extends PureComponent { render() { const { AppContainer } = this; - return ; + const { theme } = this.props; + + return ( + // The `theme` prop is documented, but apparently not included + // in the type we're using: + // https://reactnavigation.org/docs/4.x/themes/ + // $FlowFixMe + + ); } } export default connect(state => ({ + theme: getSettings(state).theme, hasAuth: getHasAuth(state), accounts: getAccounts(state), haveServerData: getHaveServerData(state), From 1731f4f6202705a651e1381a89dd42b38bb68a00 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 11 Nov 2020 15:02:29 -0800 Subject: [PATCH 09/25] nav [nfc]: Remove some soon-to-be-unnecessary comments. When we're done upgrading to React Navigation 5, including the removal of @react-navigation/compat (which is completely untyped and has no existing libdef) comments like these will be unnecessary. Currently, our navigators don't check that their attached screens are annotated with the correct shape of the `navigation` prop -- so we've just been saying they are, in these comments. We'll get those checks when the upgrade is complete. We remove them now to reduce the size of the diffs in the upcoming commits. --- src/account-info/AccountDetailsScreen.js | 5 ----- src/account-info/ProfileCard.js | 5 ----- src/account/AccountPickScreen.js | 5 ----- src/chat/ChatScreen.js | 5 ----- src/chat/GroupDetailsScreen.js | 5 ----- src/diagnostics/DiagnosticsScreen.js | 5 ----- src/diagnostics/StorageScreen.js | 5 ----- src/diagnostics/TimingScreen.js | 5 ----- src/diagnostics/VariablesScreen.js | 5 ----- src/emoji/EmojiPickerScreen.js | 5 ----- src/lightbox/LightboxScreen.js | 5 ----- src/main/HomeTab.js | 5 ----- src/main/MainScreenWithTabs.js | 5 ----- src/pm-conversations/PmConversationsCard.js | 5 ----- src/reactions/MessageReactionList.js | 5 ----- src/search/SearchMessagesScreen.js | 5 ----- src/settings/DebugScreen.js | 5 ----- src/settings/LanguageScreen.js | 5 ----- src/settings/LegalScreen.js | 5 ----- src/settings/NotificationsScreen.js | 5 ----- src/settings/SettingsCard.js | 5 ----- src/sharing/ShareToPm.js | 5 ----- src/sharing/ShareToStream.js | 5 ----- src/sharing/SharingScreen.js | 5 ----- src/start/AuthScreen.js | 5 ----- src/start/DevAuthScreen.js | 5 ----- src/start/PasswordAuthScreen.js | 5 ----- src/start/RealmScreen.js | 5 ----- src/streams/CreateStreamScreen.js | 5 ----- src/streams/EditStreamScreen.js | 5 ----- src/streams/InviteUsersScreen.js | 5 ----- src/streams/StreamScreen.js | 5 ----- src/streams/SubscriptionsCard.js | 5 ----- src/subscriptions/StreamListCard.js | 5 ----- src/topics/TopicListScreen.js | 5 ----- src/user-groups/CreateGroupScreen.js | 5 ----- src/user-status/UserStatusScreen.js | 5 ----- src/users/UsersScreen.js | 5 ----- 38 files changed, 190 deletions(-) diff --git a/src/account-info/AccountDetailsScreen.js b/src/account-info/AccountDetailsScreen.js index ebab1769bcf..847c8081e5d 100644 --- a/src/account-info/AccountDetailsScreen.js +++ b/src/account-info/AccountDetailsScreen.js @@ -30,11 +30,6 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'account-details'>, dispatch: Dispatch, diff --git a/src/account-info/ProfileCard.js b/src/account-info/ProfileCard.js index 022ceda3682..562c4534ef7 100644 --- a/src/account-info/ProfileCard.js +++ b/src/account-info/ProfileCard.js @@ -66,11 +66,6 @@ class LogoutButton extends PureComponent<{| +dispatch: Dispatch |}> { } type Props = $ReadOnly<{| - // Since we've put this screen in MainTabs's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: MainTabsNavigationProp<'profile'>, dispatch: Dispatch, diff --git a/src/account/AccountPickScreen.js b/src/account/AccountPickScreen.js index 7b637817337..9c63bb1f967 100644 --- a/src/account/AccountPickScreen.js +++ b/src/account/AccountPickScreen.js @@ -13,11 +13,6 @@ import AccountList from './AccountList'; import { navigateToRealmScreen, accountSwitch, removeAccount } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'account'>, accounts: $ReadOnlyArray, diff --git a/src/chat/ChatScreen.js b/src/chat/ChatScreen.js index da4fcb42b72..d3d11d20b25 100644 --- a/src/chat/ChatScreen.js +++ b/src/chat/ChatScreen.js @@ -24,11 +24,6 @@ import { getFetchingForNarrow } from './fetchingSelectors'; import { getShownMessagesForNarrow, isNarrowValid as getIsNarrowValid } from './narrowsSelectors'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'chat'>, // From React Navigation's `withNavigationFocus` HOC. Type copied diff --git a/src/chat/GroupDetailsScreen.js b/src/chat/GroupDetailsScreen.js index d4b7b61a971..5e4587600e4 100644 --- a/src/chat/GroupDetailsScreen.js +++ b/src/chat/GroupDetailsScreen.js @@ -11,11 +11,6 @@ import { UserItemById } from '../users/UserItem'; import { navigateToAccountDetails } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'group-details'>, dispatch: Dispatch, diff --git a/src/diagnostics/DiagnosticsScreen.js b/src/diagnostics/DiagnosticsScreen.js index 67449c5be17..2b13f307e34 100644 --- a/src/diagnostics/DiagnosticsScreen.js +++ b/src/diagnostics/DiagnosticsScreen.js @@ -22,11 +22,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'diagnostics'>, |}>; diff --git a/src/diagnostics/StorageScreen.js b/src/diagnostics/StorageScreen.js index dcb557a38bb..f5605de9ea8 100644 --- a/src/diagnostics/StorageScreen.js +++ b/src/diagnostics/StorageScreen.js @@ -18,11 +18,6 @@ const calculateKeyStorageSizes = obj => .sort((a, b) => b.size - a.size); type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'storage'>, dispatch: Dispatch, diff --git a/src/diagnostics/TimingScreen.js b/src/diagnostics/TimingScreen.js index 147db250a3e..814914f9879 100644 --- a/src/diagnostics/TimingScreen.js +++ b/src/diagnostics/TimingScreen.js @@ -8,11 +8,6 @@ import TimeItem from './TimeItem'; import timing from '../utils/timing'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'timing'>, |}>; diff --git a/src/diagnostics/VariablesScreen.js b/src/diagnostics/VariablesScreen.js index cd3cde8aa8a..dd8d7c693e4 100644 --- a/src/diagnostics/VariablesScreen.js +++ b/src/diagnostics/VariablesScreen.js @@ -8,11 +8,6 @@ import { Screen } from '../common'; import InfoItem from './InfoItem'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'variables'>, |}>; diff --git a/src/emoji/EmojiPickerScreen.js b/src/emoji/EmojiPickerScreen.js index 225005235c7..f929a0d8a07 100644 --- a/src/emoji/EmojiPickerScreen.js +++ b/src/emoji/EmojiPickerScreen.js @@ -17,11 +17,6 @@ import { navigateBack } from '../nav/navActions'; import zulipExtraEmojiMap from './zulipExtraEmojiMap'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'emoji-picker'>, activeImageEmojiByName: RealmEmojiById, diff --git a/src/lightbox/LightboxScreen.js b/src/lightbox/LightboxScreen.js index f3defd20332..c462b9eab38 100644 --- a/src/lightbox/LightboxScreen.js +++ b/src/lightbox/LightboxScreen.js @@ -18,11 +18,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'lightbox'>, |}>; diff --git a/src/main/HomeTab.js b/src/main/HomeTab.js index 59524646bab..c227e9ce21f 100644 --- a/src/main/HomeTab.js +++ b/src/main/HomeTab.js @@ -28,11 +28,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in MainTabs's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: MainTabsNavigationProp<'home'>, dispatch: Dispatch, diff --git a/src/main/MainScreenWithTabs.js b/src/main/MainScreenWithTabs.js index 2bc0fac7af6..b35a1f21745 100644 --- a/src/main/MainScreenWithTabs.js +++ b/src/main/MainScreenWithTabs.js @@ -12,11 +12,6 @@ import { OfflineNotice, ZulipStatusBar } from '../common'; import MainTabs from './MainTabs'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'main'>, dispatch: Dispatch, diff --git a/src/pm-conversations/PmConversationsCard.js b/src/pm-conversations/PmConversationsCard.js index 72d8edbe93d..7bae8caaa86 100644 --- a/src/pm-conversations/PmConversationsCard.js +++ b/src/pm-conversations/PmConversationsCard.js @@ -35,11 +35,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in MainTabs's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: MainTabsNavigationProp<'conversations'>, dispatch: Dispatch, diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index ac74baa3ba2..d235b1f2289 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -106,11 +106,6 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'message-reactions'>, dispatch: Dispatch, diff --git a/src/search/SearchMessagesScreen.js b/src/search/SearchMessagesScreen.js index 83300665a0a..5c36448f063 100644 --- a/src/search/SearchMessagesScreen.js +++ b/src/search/SearchMessagesScreen.js @@ -13,11 +13,6 @@ import { getAuth } from '../account/accountsSelectors'; import { fetchMessages } from '../message/fetchActions'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'search'>, auth: Auth, diff --git a/src/settings/DebugScreen.js b/src/settings/DebugScreen.js index dfb3fa554aa..cd1c702da7a 100644 --- a/src/settings/DebugScreen.js +++ b/src/settings/DebugScreen.js @@ -10,11 +10,6 @@ import { OptionRow, Screen } from '../common'; import { debugFlagToggle } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'debug'>, debug: Debug, diff --git a/src/settings/LanguageScreen.js b/src/settings/LanguageScreen.js index ff4bfe3d3c2..1f238d6b395 100644 --- a/src/settings/LanguageScreen.js +++ b/src/settings/LanguageScreen.js @@ -11,11 +11,6 @@ import { getSettings } from '../selectors'; import { settingsChange } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'language'>, dispatch: Dispatch, diff --git a/src/settings/LegalScreen.js b/src/settings/LegalScreen.js index b0727d025a7..0b3767c03ff 100644 --- a/src/settings/LegalScreen.js +++ b/src/settings/LegalScreen.js @@ -10,11 +10,6 @@ import openLink from '../utils/openLink'; import { getCurrentRealm } from '../selectors'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'legal'>, dispatch: Dispatch, diff --git a/src/settings/NotificationsScreen.js b/src/settings/NotificationsScreen.js index 9789d76f763..79dac602b5f 100644 --- a/src/settings/NotificationsScreen.js +++ b/src/settings/NotificationsScreen.js @@ -11,11 +11,6 @@ import * as api from '../api'; import { settingsChange } from '../actions'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'notifications'>, auth: Auth, diff --git a/src/settings/SettingsCard.js b/src/settings/SettingsCard.js index f1687f68860..c90a4a025ec 100644 --- a/src/settings/SettingsCard.js +++ b/src/settings/SettingsCard.js @@ -33,11 +33,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in MainTabs's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: MainTabsNavigationProp<'settings'>, theme: string, diff --git a/src/sharing/ShareToPm.js b/src/sharing/ShareToPm.js index 551facc6979..75136cb63f8 100644 --- a/src/sharing/ShareToPm.js +++ b/src/sharing/ShareToPm.js @@ -55,11 +55,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in SharingScreen's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: SharingNavigationProp<'share-to-pm'>, dispatch: Dispatch, diff --git a/src/sharing/ShareToStream.js b/src/sharing/ShareToStream.js index 9ff2abb859b..a815e403716 100644 --- a/src/sharing/ShareToStream.js +++ b/src/sharing/ShareToStream.js @@ -43,11 +43,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in SharingScreen's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: SharingNavigationProp<'share-to-stream'>, dispatch: Dispatch, diff --git a/src/sharing/SharingScreen.js b/src/sharing/SharingScreen.js index 3f37bab8ddd..cbadfd441e0 100644 --- a/src/sharing/SharingScreen.js +++ b/src/sharing/SharingScreen.js @@ -34,11 +34,6 @@ export type SharingNavigationProp< |}>; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'sharing'>, auth: Auth | void, diff --git a/src/start/AuthScreen.js b/src/start/AuthScreen.js index da806667233..2cd156bc18b 100644 --- a/src/start/AuthScreen.js +++ b/src/start/AuthScreen.js @@ -167,11 +167,6 @@ export const activeAuthentications = ( }; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'auth'>, dispatch: Dispatch, diff --git a/src/start/DevAuthScreen.js b/src/start/DevAuthScreen.js index 6e986ccdf4e..ca4b7980e0f 100644 --- a/src/start/DevAuthScreen.js +++ b/src/start/DevAuthScreen.js @@ -28,11 +28,6 @@ const componentStyles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'dev'>, partialAuth: Auth, diff --git a/src/start/PasswordAuthScreen.js b/src/start/PasswordAuthScreen.js index 30432d0bd21..61ce62b3120 100644 --- a/src/start/PasswordAuthScreen.js +++ b/src/start/PasswordAuthScreen.js @@ -27,11 +27,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'password'>, partialAuth: Auth, diff --git a/src/start/RealmScreen.js b/src/start/RealmScreen.js index b5e76cb23c1..27179eea41e 100644 --- a/src/start/RealmScreen.js +++ b/src/start/RealmScreen.js @@ -18,11 +18,6 @@ type SelectorProps = {| |}; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'realm'>, dispatch: Dispatch, diff --git a/src/streams/CreateStreamScreen.js b/src/streams/CreateStreamScreen.js index a6df8576835..d7c33e5592b 100644 --- a/src/streams/CreateStreamScreen.js +++ b/src/streams/CreateStreamScreen.js @@ -11,11 +11,6 @@ import { Screen } from '../common'; import EditStreamCard from './EditStreamCard'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'stream-create'>, dispatch: Dispatch, diff --git a/src/streams/EditStreamScreen.js b/src/streams/EditStreamScreen.js index d4a74a180be..1f7a7fa75db 100644 --- a/src/streams/EditStreamScreen.js +++ b/src/streams/EditStreamScreen.js @@ -15,11 +15,6 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'stream-edit'>, dispatch: Dispatch, diff --git a/src/streams/InviteUsersScreen.js b/src/streams/InviteUsersScreen.js index 64b71abd83b..25ef78ec59a 100644 --- a/src/streams/InviteUsersScreen.js +++ b/src/streams/InviteUsersScreen.js @@ -17,11 +17,6 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'invite-users'>, dispatch: Dispatch, diff --git a/src/streams/StreamScreen.js b/src/streams/StreamScreen.js index 8c5df9cc460..a9be2210dd7 100644 --- a/src/streams/StreamScreen.js +++ b/src/streams/StreamScreen.js @@ -31,11 +31,6 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'stream'>, dispatch: Dispatch, diff --git a/src/streams/SubscriptionsCard.js b/src/streams/SubscriptionsCard.js index 03a24977675..aba982b185e 100644 --- a/src/streams/SubscriptionsCard.js +++ b/src/streams/SubscriptionsCard.js @@ -27,11 +27,6 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in StreamTabs's route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: StreamTabsNavigationProp<'subscribed'>, dispatch: Dispatch, diff --git a/src/subscriptions/StreamListCard.js b/src/subscriptions/StreamListCard.js index a9e7b07d9ca..a7b24e19ff8 100644 --- a/src/subscriptions/StreamListCard.js +++ b/src/subscriptions/StreamListCard.js @@ -26,11 +26,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in StreamTabs's route config, and we - // don't invoke it without type-checking anywhere else (in fact, we - // don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: StreamTabsNavigationProp<'allStreams'>, dispatch: Dispatch, diff --git a/src/topics/TopicListScreen.js b/src/topics/TopicListScreen.js index 7ed2c9c058d..a534d537b4d 100644 --- a/src/topics/TopicListScreen.js +++ b/src/topics/TopicListScreen.js @@ -18,11 +18,6 @@ type SelectorProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'topics'>, dispatch: Dispatch, diff --git a/src/user-groups/CreateGroupScreen.js b/src/user-groups/CreateGroupScreen.js index c2810818393..7c74e9f7571 100644 --- a/src/user-groups/CreateGroupScreen.js +++ b/src/user-groups/CreateGroupScreen.js @@ -17,11 +17,6 @@ type SelectorProps = {| |}; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'group'>, dispatch: Dispatch, diff --git a/src/user-status/UserStatusScreen.js b/src/user-status/UserStatusScreen.js index dfbf0c866ce..2d26132359b 100644 --- a/src/user-status/UserStatusScreen.js +++ b/src/user-status/UserStatusScreen.js @@ -29,11 +29,6 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'user-status'>, dispatch: Dispatch, diff --git a/src/users/UsersScreen.js b/src/users/UsersScreen.js index ce387e0e7c4..223a23a611a 100644 --- a/src/users/UsersScreen.js +++ b/src/users/UsersScreen.js @@ -6,11 +6,6 @@ import { Screen } from '../common'; import UsersCard from './UsersCard'; type Props = $ReadOnly<{| - // Since we've put this screen in AppNavigator's route config, and - // we don't invoke it without type-checking anywhere else (in fact, - // we don't invoke it anywhere else at all), we know it gets the - // `navigation` prop for free, with the particular shape for this - // route. navigation: AppNavigationProp<'users'>, |}>; From 64a928fa5068b0855b14dec685058649ffc38133 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 11 Nov 2020 17:05:53 -0800 Subject: [PATCH 10/25] deps: Add libdefs for new, differently named React Navigation packages. We can change out the libdefs for the React Navigation v5 upgrade outside the main upgrade commit because the packages changed names. In v5, they're all under the `@react-navigation` scope. So, add the new ones, and plan to clean out the old ones after the upcoming main upgrade commit. --- .../@react-navigation/bottom-tabs_v5.x.x.js | 2042 +++++++++++++++ .../npm/@react-navigation/compat_vx.x.x.js | 255 ++ .../npm/@react-navigation/drawer_v5.x.x.js | 2101 ++++++++++++++++ .../material-top-tabs_v5.x.x.js | 2046 +++++++++++++++ .../npm/@react-navigation/native_v5.x.x.js | 2183 +++++++++++++++++ .../npm/@react-navigation/stack_v5.x.x.js | 2137 ++++++++++++++++ 6 files changed, 10764 insertions(+) create mode 100644 flow-typed/npm/@react-navigation/bottom-tabs_v5.x.x.js create mode 100644 flow-typed/npm/@react-navigation/compat_vx.x.x.js create mode 100644 flow-typed/npm/@react-navigation/drawer_v5.x.x.js create mode 100644 flow-typed/npm/@react-navigation/material-top-tabs_v5.x.x.js create mode 100644 flow-typed/npm/@react-navigation/native_v5.x.x.js create mode 100644 flow-typed/npm/@react-navigation/stack_v5.x.x.js diff --git a/flow-typed/npm/@react-navigation/bottom-tabs_v5.x.x.js b/flow-typed/npm/@react-navigation/bottom-tabs_v5.x.x.js new file mode 100644 index 00000000000..e2f0db0af64 --- /dev/null +++ b/flow-typed/npm/@react-navigation/bottom-tabs_v5.x.x.js @@ -0,0 +1,2042 @@ +// flow-typed signature: e37ac5b72f5fe9ae743fbc011032560b +// flow-typed version: 3c17c8ecd5/@react-navigation/bottom-tabs_v5.x.x/flow_>=v0.104.x + +declare module '@react-navigation/bottom-tabs' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + // Vaguely copied from + // react-native/Libraries/Animated/src/animations/Animation.js + declare type EndResult = { finished: boolean, ... }; + declare type EndCallback = (result: EndResult) => void; + declare interface Animation { + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void; + stop(): void; + } + declare type AnimationConfig = { + isInteraction?: boolean, + useNativeDriver: boolean, + onComplete?: ?EndCallback, + iterations?: number, + ... + }; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js + declare interface AnimatedTracking { + constructor( + value: AnimatedValue, + parent: any, + animationClass: any, + animationConfig: Object, + callback?: ?EndCallback, + ): void; + update(): void; + } + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedValue.js + declare type ValueListenerCallback = (state: { value: number, ... }) => void; + declare interface AnimatedValue { + constructor(value: number): void; + setValue(value: number): void; + setOffset(offset: number): void; + flattenOffset(): void; + extractOffset(): void; + addListener(callback: ValueListenerCallback): string; + removeListener(id: string): void; + removeAllListeners(): void; + stopAnimation(callback?: ?(value: number) => void): void; + resetAnimation(callback?: ?(value: number) => void): void; + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + animate(animation: Animation, callback: ?EndCallback): void; + stopTracking(): void; + track(tracking: AnimatedTracking): void; + } + + // Copied from + // react-native/Libraries/Animated/src/animations/TimingAnimation.js + declare type TimingAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + easing?: (value: number) => number, + duration?: number, + delay?: number, + ... + }; + + // Copied from + // react-native/Libraries/Animated/src/animations/SpringAnimation.js + declare type SpringAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + overshootClamping?: boolean, + restDisplacementThreshold?: number, + restSpeedThreshold?: number, + velocity?: number, + bounciness?: number, + speed?: number, + tension?: number, + friction?: number, + stiffness?: number, + damping?: number, + mass?: number, + delay?: number, + ... + }; + + // Copied from react-native/Libraries/Types/CoreEventTypes.js + declare type SyntheticEvent = $ReadOnly<{| + bubbles: ?boolean, + cancelable: ?boolean, + currentTarget: number, + defaultPrevented: ?boolean, + dispatchConfig: $ReadOnly<{| + registrationName: string, + |}>, + eventPhase: ?number, + preventDefault: () => void, + isDefaultPrevented: () => boolean, + stopPropagation: () => void, + isPropagationStopped: () => boolean, + isTrusted: ?boolean, + nativeEvent: T, + persist: () => void, + target: ?number, + timeStamp: number, + type: ?string, + |}>; + declare type Layout = $ReadOnly<{| + x: number, + y: number, + width: number, + height: number, + |}>; + declare type LayoutEvent = SyntheticEvent< + $ReadOnly<{| + layout: Layout, + |}>, + >; + declare type BlurEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type FocusEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type ResponderSyntheticEvent = $ReadOnly<{| + ...SyntheticEvent, + touchHistory: $ReadOnly<{| + indexOfSingleActiveTouch: number, + mostRecentTimeStamp: number, + numberActiveTouches: number, + touchBank: $ReadOnlyArray< + $ReadOnly<{| + touchActive: boolean, + startPageX: number, + startPageY: number, + startTimeStamp: number, + currentPageX: number, + currentPageY: number, + currentTimeStamp: number, + previousPageX: number, + previousPageY: number, + previousTimeStamp: number, + |}>, + >, + |}>, + |}>; + declare type PressEvent = ResponderSyntheticEvent< + $ReadOnly<{| + changedTouches: $ReadOnlyArray<$PropertyType>, + force: number, + identifier: number, + locationX: number, + locationY: number, + pageX: number, + pageY: number, + target: ?number, + timestamp: number, + touches: $ReadOnlyArray<$PropertyType>, + |}>, + >; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js + declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; + declare type InterpolationConfigType = { + inputRange: Array, + outputRange: Array | Array, + easing?: (input: number) => number, + extrapolate?: ExtrapolateType, + extrapolateLeft?: ExtrapolateType, + extrapolateRight?: ExtrapolateType, + ... + }; + declare interface AnimatedInterpolation { + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + } + + // Copied from react-native/Libraries/Components/View/ViewAccessibility.js + declare type AccessibilityRole = + | 'none' + | 'button' + | 'link' + | 'search' + | 'image' + | 'keyboardkey' + | 'text' + | 'adjustable' + | 'imagebutton' + | 'header' + | 'summary' + | 'alert' + | 'checkbox' + | 'combobox' + | 'menu' + | 'menubar' + | 'menuitem' + | 'progressbar' + | 'radio' + | 'radiogroup' + | 'scrollbar' + | 'spinbutton' + | 'switch' + | 'tab' + | 'tablist' + | 'timer' + | 'toolbar'; + declare type AccessibilityActionInfo = $ReadOnly<{ + name: string, + label?: string, + ... + }>; + declare type AccessibilityActionEvent = SyntheticEvent< + $ReadOnly<{actionName: string, ...}>, + >; + declare type AccessibilityState = { + disabled?: boolean, + selected?: boolean, + checked?: ?boolean | 'mixed', + busy?: boolean, + expanded?: boolean, + ... + }; + declare type AccessibilityValue = $ReadOnly<{| + min?: number, + max?: number, + now?: number, + text?: string, + |}>; + + // Copied from + // react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js + declare type Stringish = string; + declare type EdgeInsetsProp = $ReadOnly<$Shape>; + declare type TouchableWithoutFeedbackProps = $ReadOnly<{| + accessibilityActions?: ?$ReadOnlyArray, + accessibilityElementsHidden?: ?boolean, + accessibilityHint?: ?Stringish, + accessibilityIgnoresInvertColors?: ?boolean, + accessibilityLabel?: ?Stringish, + accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), + accessibilityRole?: ?AccessibilityRole, + accessibilityState?: ?AccessibilityState, + accessibilityValue?: ?AccessibilityValue, + accessibilityViewIsModal?: ?boolean, + accessible?: ?boolean, + children?: ?React$Node, + delayLongPress?: ?number, + delayPressIn?: ?number, + delayPressOut?: ?number, + disabled?: ?boolean, + focusable?: ?boolean, + hitSlop?: ?EdgeInsetsProp, + importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), + nativeID?: ?string, + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, + onBlur?: ?(event: BlurEvent) => mixed, + onFocus?: ?(event: FocusEvent) => mixed, + onLayout?: ?(event: LayoutEvent) => mixed, + onLongPress?: ?(event: PressEvent) => mixed, + onPress?: ?(event: PressEvent) => mixed, + onPressIn?: ?(event: PressEvent) => mixed, + onPressOut?: ?(event: PressEvent) => mixed, + pressRetentionOffset?: ?EdgeInsetsProp, + rejectResponderTermination?: ?boolean, + testID?: ?string, + touchSoundDisabled?: ?boolean, + |}>; + + // Copied from react-native/Libraries/Image/ImageSource.js + declare type ImageURISource = $ReadOnly<{ + uri?: ?string, + bundle?: ?string, + method?: ?string, + headers?: ?Object, + body?: ?string, + cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached'), + width?: ?number, + height?: ?number, + scale?: ?number, + ... + }>; + + /** + * The following is copied from react-native-gesture-handler's libdef + */ + + declare type $EventHandlers = {| + onGestureEvent?: ($Event) => mixed, + onHandlerStateChange?: ($Event) => mixed, + onBegan?: ($Event) => mixed, + onFailed?: ($Event) => mixed, + onCancelled?: ($Event) => mixed, + onActivated?: ($Event) => mixed, + onEnded?: ($Event) => mixed, + |}; + + declare type HitSlop = + | number + | {| + left?: number, + top?: number, + right?: number, + bottom?: number, + vertical?: number, + horizontal?: number, + width?: number, + height?: number, + |} + | {| + width: number, + left: number, + |} + | {| + width: number, + right: number, + |} + | {| + height: number, + top: number, + |} + | {| + height: number, + bottom: number, + |}; + + declare type $GestureHandlerProps< + AdditionalProps: {...}, + ExtraEventsProps: {...} + > = $ReadOnly<{| + ...$Exact, + ...$EventHandlers, + id?: string, + enabled?: boolean, + waitFor?: React$Ref | Array>, + simultaneousHandlers?: React$Ref | Array>, + shouldCancelWhenOutside?: boolean, + minPointers?: number, + hitSlop?: HitSlop, + children?: React$Node, + |}>; + + declare type PanGestureHandlerProps = $GestureHandlerProps< + { + activeOffsetY?: number | [number, number], + activeOffsetX?: number | [number, number], + failOffsetY?: number | [number, number], + failOffsetX?: number | [number, number], + minDist?: number, + minVelocity?: number, + minVelocityX?: number, + minVelocityY?: number, + minPointers?: number, + maxPointers?: number, + avgTouches?: boolean, + ... + }, + { + x: number, + y: number, + absoluteX: number, + absoluteY: number, + translationX: number, + translationY: number, + velocityX: number, + velocityY: number, + ... + } + >; + + /** + * MAGIC + */ + + declare type $If = $Call< + ((true, Then, Else) => Then) & ((false, Then, Else) => Else), + Test, + Then, + Else, + >; + declare type $IsA = $Call< + (Y => true) & (mixed => false), + X, + >; + declare type $IsUndefined = $IsA; + + declare type $Partial = $Rest; + + /** + * Actions, state, etc. + */ + + declare export type ScreenParams = { +[key: string]: mixed, ... }; + + declare export type BackAction = {| + +type: 'GO_BACK', + +source?: string, + +target?: string, + |}; + declare export type NavigateAction = {| + +type: 'NAVIGATE', + +payload: + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type ResetAction = {| + +type: 'RESET', + +payload: StaleNavigationState, + +source?: string, + +target?: string, + |}; + declare export type SetParamsAction = {| + +type: 'SET_PARAMS', + +payload: {| +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type CommonAction = + | BackAction + | NavigateAction + | ResetAction + | SetParamsAction; + + declare type NavigateActionCreator = {| + (routeName: string, params?: ScreenParams): NavigateAction, + ( + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + ): NavigateAction, + |}; + declare export type CommonActionsType = {| + +navigate: NavigateActionCreator, + +goBack: () => BackAction, + +reset: (state: PossiblyStaleNavigationState) => ResetAction, + +setParams: (params: ScreenParams) => SetParamsAction, + |}; + + declare export type GenericNavigationAction = {| + +type: string, + +payload?: { +[key: string]: mixed, ... }, + +source?: string, + +target?: string, + |}; + + declare export type LeafRoute = {| + +key: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StateRoute = {| + ...LeafRoute, + +state: NavigationState | StaleNavigationState, + |}; + declare export type Route = + | LeafRoute + | StateRoute; + + declare export type NavigationState = {| + +key: string, + +index: number, + +routeNames: $ReadOnlyArray, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type: string, + +stale: false, + |}; + + declare export type StaleLeafRoute = {| + +key?: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StaleStateRoute = {| + ...StaleLeafRoute, + +state: StaleNavigationState, + |}; + declare export type StaleRoute = + | StaleLeafRoute + | StaleStateRoute; + declare export type StaleNavigationState = {| + // It's possible to pass React Nav a StaleNavigationState with an undefined + // index, but React Nav will always return one with the index set. This is + // the same as for the type property below, but in the case of index we tend + // to rely on it being set more... + +index: number, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type?: string, + +stale?: true, + |}; + + declare export type PossiblyStaleNavigationState = + | NavigationState + | StaleNavigationState; + declare export type PossiblyStaleRoute = + | Route + | StaleRoute; + + /** + * Routers + */ + + declare type ActionCreators< + State: NavigationState, + Action: GenericNavigationAction, + > = { + +[key: string]: (...args: any) => (Action | State => Action), + ... + }; + + declare export type DefaultRouterOptions = { + +initialRouteName?: string, + ... + }; + + declare export type RouterFactory< + State: NavigationState, + Action: GenericNavigationAction, + RouterOptions: DefaultRouterOptions, + > = (options: RouterOptions) => Router; + + declare export type ParamListBase = { +[key: string]: ?ScreenParams, ... }; + + declare export type RouterConfigOptions = {| + +routeNames: $ReadOnlyArray, + +routeParamList: ParamListBase, + |}; + + declare export type Router< + State: NavigationState, + Action: GenericNavigationAction, + > = {| + +type: $PropertyType, + +getInitialState: (options: RouterConfigOptions) => State, + +getRehydratedState: ( + partialState: PossibleStaleNavigationState, + options: RouterConfigOptions, + ) => State, + +getStateForRouteNamesChange: ( + state: State, + options: RouterConfigOptions, + ) => State, + +getStateForRouteFocus: (state: State, key: string) => State, + +getStateForAction: ( + state: State, + action: Action, + options: RouterConfigOptions, + ) => ?PossiblyStaleNavigationState; + +shouldActionChangeFocus: (action: GenericNavigationAction) => boolean, + +actionCreators?: ActionCreators, + |}; + + /** + * Stack actions and router + */ + + declare export type StackNavigationState = {| + ...NavigationState, + +type: 'stack', + |}; + + declare export type ReplaceAction = {| + +type: 'REPLACE', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PushAction = {| + +type: 'PUSH', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PopAction = {| + +type: 'POP', + +payload: {| +count: number |}, + +source?: string, + +target?: string, + |}; + declare export type PopToTopAction = {| + +type: 'POP_TO_TOP', + +source?: string, + +target?: string, + |}; + declare export type StackAction = + | CommonAction + | ReplaceAction + | PushAction + | PopAction + | PopToTopAction; + + declare export type StackActionsType = {| + +replace: (routeName: string, params?: ScreenParams) => ReplaceAction, + +push: (routeName: string, params?: ScreenParams) => PushAction, + +pop: (count?: number) => PopAction, + +popToTop: () => PopToTopAction, + |}; + + declare export type StackRouterOptions = $Exact; + + /** + * Tab actions and router + */ + + declare export type TabNavigationState = {| + ...NavigationState, + +type: 'tab', + +history: $ReadOnlyArray<{| type: 'route', key: string |}>, + |}; + + declare export type JumpToAction = {| + +type: 'JUMP_TO', + +payload: {| +name: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type TabAction = + | CommonAction + | JumpToAction; + + declare export type TabActionsType = {| + +jumpTo: string => JumpToAction, + |}; + + declare export type TabRouterOptions = {| + ...$Exact, + +backBehavior?: 'initialRoute' | 'order' | 'history' | 'none', + |}; + + /** + * Drawer actions and router + */ + + declare type DrawerHistoryEntry = + | {| +type: 'route', +key: string |} + | {| +type: 'drawer' |}; + declare export type DrawerNavigationState = {| + ...NavigationState, + +type: 'drawer', + +history: $ReadOnlyArray, + |}; + + declare export type OpenDrawerAction = {| + +type: 'OPEN_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type CloseDrawerAction = {| + +type: 'CLOSE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type ToggleDrawerAction = {| + +type: 'TOGGLE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type DrawerAction = + | TabAction + | OpenDrawerAction + | CloseDrawerAction + | ToggleDrawerAction; + + declare export type DrawerActionsType = {| + ...TabActionsType, + +openDrawer: () => OpenDrawerAction, + +closeDrawer: () => CloseDrawerAction, + +toggleDrawer: () => ToggleDrawerAction, + |}; + + declare export type DrawerRouterOptions = {| + ...TabRouterOptions, + +openByDefault?: boolean, + |}; + + /** + * Events + */ + + declare export type EventMapBase = { + +[name: string]: {| + +data?: mixed, + +canPreventDefault?: boolean, + |}, + ... + }; + declare type EventPreventDefaultProperties = $If< + Test, + {| +defaultPrevented: boolean, +preventDefault: () => void |}, + {| |}, + >; + declare type EventDataProperties = $If< + $IsUndefined, + {| |}, + {| +data: Data |}, + >; + declare type EventArg< + EventName: string, + CanPreventDefault: ?boolean = false, + Data = void, + > = {| + ...EventPreventDefaultProperties, + ...EventDataProperties, + +type: EventName, + +target?: string, + |}; + declare type GlobalEventMap = {| + +state: {| +data: {| +state: State |}, +canPreventDefault: false |}, + |}; + declare type EventMapCore = {| + ...GlobalEventMap, + +focus: {| +data: void, +canPreventDefault: false |}, + +blur: {| +data: void, +canPreventDefault: false |}, + |}; + declare type EventListenerCallback< + EventName: string, + State: PossiblyStaleNavigationState = NavigationState, + EventMap: EventMapBase = EventMapCore, + > = (e: EventArg< + EventName, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'canPreventDefault', + >, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'data', + >, + >) => mixed; + + /** + * Navigation prop + */ + + declare export type SimpleNavigate = + >( + routeName: DestinationRouteName, + params: $ElementType, + ) => void; + + declare export type Navigate = + & SimpleNavigate + & >( + route: + | {| + key: string, + params?: $ElementType, + |} + | {| + name: DestinationRouteName, + key?: string, + params?: $ElementType, + |}, + ) => void; + + declare type NavigationHelpers< + ParamList: ParamListBase, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + EventMap: EventMapBase = EventMapCore, + > = { + +navigate: Navigate, + +dispatch: ( + action: + | GenericNavigationAction + | (State => GenericNavigationAction), + ) => void, + +reset: PossiblyStaleNavigationState => void, + +goBack: () => void, + +isFocused: () => boolean, + +canGoBack: () => boolean, + +dangerouslyGetParent: >() => ?Parent, + +dangerouslyGetState: () => NavigationState, + +addListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => () => void, + +removeListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => void, + ... + }; + + declare export type NavigationProp< + ParamList: ParamListBase, + RouteName: $Keys = $Keys, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = { + ...$Exact>, + +setOptions: (options: $Shape) => void, + +setParams: ( + params: $If< + $IsUndefined<$ElementType>, + empty, + $Shape<$NonMaybeType<$ElementType>>, + >, + ) => void, + ... + }; + + /** + * CreateNavigator + */ + + declare export type RouteProp< + ParamList: ParamListBase, + RouteName: $Keys, + > = {| + ...LeafRoute, + +params: $ElementType, + |}; + + declare export type ScreenListeners< + EventMap: EventMapBase = EventMapCore, + State: NavigationState = NavigationState, + > = $ObjMapi< + {| [name: $Keys]: empty |}, + >(K, empty) => EventListenerCallback, + >; + + declare type BaseScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = {| + +name: RouteName, + +options?: + | ScreenOptions + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenOptions, + +listeners?: + | ScreenListeners + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenListeners, + +initialParams?: $Shape<$ElementType>, + |}; + + declare export type ScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +component: React$ComponentType<{| + route: RouteProp, + navigation: NavProp, + |}>, + |} + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +children: ({| + route: RouteProp, + navigation: NavProp, + |}) => React$Node, + |}; + + declare export type ScreenComponent< + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = < + RouteName: $Keys, + NavProp: NavigationProp< + GlobalParamList, + RouteName, + State, + ScreenOptions, + EventMap, + >, + >(props: ScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >) => React$Node; + + declare type ScreenOptionsProp = {| + +screenOptions?: + | ScreenOptions + | ({| route: LeafRoute<>, navigation: NavProp |}) => ScreenOptions, + |}; + declare export type ExtraNavigatorPropsBase = { + ...$Exact, + +children?: React$Node, + ... + }; + declare export type NavigatorPropsBase = { + ...$Exact, + ...ScreenOptionsProp, + ... + }; + + declare export type CreateNavigator< + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + > = < + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + NavProp: NavigationHelpers< + GlobalParamList, + State, + EventMap, + >, + >() => {| + +Screen: ScreenComponent< + GlobalParamList, + ParamList, + State, + ScreenOptions, + EventMap, + >, + +Navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + |}; + + declare export type CreateNavigatorFactory = < + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + NavProp: NavigationHelpers< + ParamListBase, + State, + EventMap, + >, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + >( + navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + ) => CreateNavigator; + + /** + * useNavigationBuilder + */ + + declare export type Descriptor< + NavProp, + ScreenOptions: {...} = {...}, + > = {| + +render: () => React$Node, + +options: $ReadOnly, + +navigation: NavProp, + |}; + + declare export type UseNavigationBuilder = < + State: NavigationState, + Action: GenericNavigationAction, + ScreenOptions: {...}, + RouterOptions: DefaultRouterOptions, + NavProp, + >( + routerFactory: RouterFactory, + options: {| + ...$Exact, + ...ScreenOptionsProp, + +children?: React$Node, + |}, + ) => {| + +state: State, + +descriptors: {| +[key: string]: Descriptor |}, + +navigation: NavProp, + |}; + + /** + * EdgeInsets + */ + + declare type EdgeInsets = {| + +top: number, + +right: number, + +bottom: number, + +left: number, + |}; + + /** + * TransitionPreset + */ + + declare export type TransitionSpec = + | {| + animation: 'spring', + config: $Diff< + SpringAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |} + | {| + animation: 'timing', + config: $Diff< + TimingAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |}; + + declare export type StackCardInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +index: number, + +closing: AnimatedInterpolation, + +swiping: AnimatedInterpolation, + +inverted: AnimatedInterpolation, + +layouts: {| + +screen: {| +width: number, +height: number |}, + |}, + +insets: EdgeInsets, + |}; + declare export type StackCardInterpolatedStyle = {| + containerStyle?: AnimatedViewStyleProp, + cardStyle?: AnimatedViewStyleProp, + overlayStyle?: AnimatedViewStyleProp, + shadowStyle?: AnimatedViewStyleProp, + |}; + declare export type StackCardStyleInterpolator = ( + props: StackCardInterpolationProps, + ) => StackCardInterpolatedStyle; + + declare export type StackHeaderInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +layouts: {| + +header: {| +width: number, +height: number |}, + +screen: {| +width: number, +height: number |}, + +title?: {| +width: number, +height: number |}, + +leftLabel?: {| +width: number, +height: number |}, + |}, + |}; + declare export type StackHeaderInterpolatedStyle = {| + leftLabelStyle?: AnimatedViewStyleProp, + leftButtonStyle?: AnimatedViewStyleProp, + rightButtonStyle?: AnimatedViewStyleProp, + titleStyle?: AnimatedViewStyleProp, + backgroundStyle?: AnimatedViewStyleProp, + |}; + declare export type StackHeaderStyleInterpolator = ( + props: StackHeaderInterpolationProps, + ) => StackHeaderInterpolatedStyle; + + declare type GestureDirection = + | 'horizontal' + | 'horizontal-inverted' + | 'vertical' + | 'vertical-inverted'; + + declare export type TransitionPreset = {| + +gestureDirection: GestureDirection, + +transitionSpec: {| + +open: TransitionSpec, + +close: TransitionSpec, + |}, + +cardStyleInterpolator: StackCardStyleInterpolator, + +headerStyleInterpolator: StackHeaderStyleInterpolator, + |}; + + /** + * Stack options + */ + + declare export type StackDescriptor = Descriptor< + StackNavigationProp<>, + StackOptions, + >; + + declare type Scene = {| + +route: T, + +descriptor: StackDescriptor, + +progress: {| + +current: AnimatedInterpolation, + +next?: AnimatedInterpolation, + +previous?: AnimatedInterpolation, + |}, + |}; + + declare export type StackHeaderProps = {| + +mode: 'float' | 'screen', + +layout: {| +width: number, +height: number |}, + +insets: EdgeInsets, + +scene: Scene>, + +previous?: Scene>, + +navigation: StackNavigationProp, + +styleInterpolator: StackHeaderStyleInterpolator, + |}; + + declare export type StackHeaderLeftButtonProps = $Shape<{| + +onPress: (() => void), + +pressColorAndroid: string; + +backImage: (props: {| tintColor: string |}) => React$Node, + +tintColor: string, + +label: string, + +truncatedLabel: string, + +labelVisible: boolean, + +labelStyle: AnimatedTextStyleProp, + +allowFontScaling: boolean, + +onLabelLayout: LayoutEvent => void, + +screenLayout: {| +width: number, +height: number |}, + +titleLayout: {| +width: number, +height: number |}, + +canGoBack: boolean, + |}>; + + declare type StackHeaderTitleInputBase = { + +onLayout: LayoutEvent => void, + +children: string, + +allowFontScaling: ?boolean, + +tintColor: ?string, + +style: ?AnimatedTextStyleProp, + ... + }; + + declare export type StackHeaderTitleInputProps = + $Exact; + + declare export type StackOptions = $Shape<{| + +title: string, + +header: StackHeaderProps => React$Node, + +headerShown: boolean, + +cardShadowEnabled: boolean, + +cardOverlayEnabled: boolean, + +cardOverlay: {| style: ViewStyleProp |} => React$Node, + +cardStyle: ViewStyleProp, + +animationEnabled: boolean, + +animationTypeForReplace: 'push' | 'pop', + +gestureEnabled: boolean, + +gestureResponseDistance: {| vertical?: number, horizontal?: number |}, + +gestureVelocityImpact: number, + +safeAreaInsets: $Shape, + // Transition + ...TransitionPreset, + // Header + +headerTitle: string | (StackHeaderTitleInputProps => React$Node), + +headerTitleAlign: 'left' | 'center', + +headerTitleStyle: AnimatedTextStyleProp, + +headerTitleContainerStyle: ViewStyleProp, + +headerTintColor: string, + +headerTitleAllowFontScaling: boolean, + +headerBackAllowFontScaling: boolean, + +headerBackTitle: string | null, + +headerBackTitleStyle: TextStyleProp, + +headerBackTitleVisible: boolean, + +headerTruncatedBackTitle: string, + +headerLeft: StackHeaderLeftButtonProps => React$Node, + +headerLeftContainerStyle: ViewStyleProp, + +headerRight: {| tintColor?: string |} => React$Node, + +headerRightContainerStyle: ViewStyleProp, + +headerBackImage: $PropertyType, + +headerPressColorAndroid: string, + +headerBackground: ({| style: ViewStyleProp |}) => React$Node, + +headerStyle: ViewStyleProp, + +headerTransparent: boolean, + +headerStatusBarHeight: number, + |}>; + + /** + * Stack navigation prop + */ + + declare export type StackNavigationEventMap = {| + ...EventMapCore, + +transitionStart: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + +transitionEnd: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + |}; + + declare type InexactStackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = { + ...$Exact>, + +replace: SimpleNavigate, + +push: SimpleNavigate, + +pop: (count?: number) => void, + +popToTop: () => void, + ... + }; + + declare export type StackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous stack exports + */ + + declare type StackNavigationConfig = {| + +mode?: 'card' | 'modal', + +headerMode?: 'float' | 'screen' | 'none', + +keyboardHandlingEnabled?: boolean, + |}; + + declare export type ExtraStackNavigatorProps = {| + ...$Exact, + ...StackRouterOptions, + ...StackNavigationConfig, + |}; + + declare export type StackNavigatorProps< + NavProp: InexactStackNavigationProp<> = StackNavigationProp<>, + > = {| + ...ExtraStackNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Bottom tab options + */ + + declare export type BottomTabBarButtonProps = {| + ...$Diff< + TouchableWithoutFeedbackProps, + {| onPress?: ?(event: PressEvent) => mixed |}, + >, + +to?: string, + +children: React$Node, + +onPress?: (MouseEvent | PressEvent) => void, + |}; + + declare export type BottomTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| focused: boolean, color: string |}) => React$Node, + +tabBarIcon: ({| + focused: boolean, + color: string, + size: number, + |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + +tabBarVisible: boolean, + +tabBarButton: BottomTabBarButtonProps => React$Node, + +unmountOnBlur: boolean, + |}>; + + /** + * Bottom tab navigation prop + */ + + declare export type BottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + |}; + + declare type InexactTabNavigationProp< + ParamList: ParamListBase, + RouteName: $Keys, + Options: {...}, + EventMap: EventMapBase, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + ... + }; + + declare export type InexactBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type BottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous bottom tab exports + */ + + declare export type BottomTabDescriptor = Descriptor< + BottomTabNavigationProp<>, + BottomTabOptions, + >; + + declare export type BottomTabBarOptions = $Shape<{| + +keyboardHidesTabBar: boolean, + +activeTintColor: string, + +inactiveTintColor: string, + +activeBackgroundColor: string, + +inactiveBackgroundColor: string, + +allowFontScaling: boolean, + +showLabel: boolean, + +showIcon: boolean, + +labelStyle: TextStyleProp, + +iconStyle: TextStyleProp, + +tabStyle: ViewStyleProp, + +labelPosition: 'beside-icon' | 'below-icon', + +adaptive: boolean, + +safeAreaInsets: $Shape, + +style: ViewStyleProp, + |}>; + + declare type BottomTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: BottomTabNavigationProp<>, + +descriptors: {| +[key: string]: BottomTabDescriptor |}, + |}; + + declare export type BottomTabBarProps = {| + ...BottomTabBarOptions, + ...BottomTabNavigationBuilderResult, + |} + + declare type BottomTabNavigationConfig = {| + +lazy?: boolean, + +tabBar?: BottomTabBarProps => React$Node, + +tabBarOptions?: BottomTabBarOptions, + |}; + + declare export type ExtraBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...BottomTabNavigationConfig, + |}; + + declare export type BottomTabNavigatorProps< + NavProp: InexactBottomTabNavigationProp<> = BottomTabNavigationProp<>, + > = {| + ...ExtraBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material bottom tab options + */ + + declare export type MaterialBottomTabOptions = $Shape<{| + +title: string, + +tabBarColor: string, + +tabBarLabel: string, + +tabBarIcon: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarBadge: boolean | number | string, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material bottom tab navigation prop + */ + + declare export type MaterialBottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + |}; + + declare export type InexactMaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material bottom tab exports + */ + + declare export type PaperFont = {| + +fontFamily: string, + +fontWeight?: + | 'normal' + | 'bold' + | '100' + | '200' + | '300' + | '400' + | '500' + | '600' + | '700' + | '800' + | '900', + |}; + + declare export type PaperFonts = {| + +regular: Font, + +medium: Font, + +light: Font, + +thin: Font, + |}; + + declare export type PaperTheme = {| + +dark: boolean, + +mode?: 'adaptive' | 'exact', + +roundness: number, + +colors: {| + +primary: string, + +background: string, + +surface: string, + +accent: string, + +error: string, + +text: string, + +onSurface: string, + +onBackground: string, + +disabled: string, + +placeholder: string, + +backdrop: string, + +notification: string, + |}, + +fonts: PaperFonts, + +animation: {| + +scale: number, + |}, + |}; + + declare export type PaperRoute = {| + +key: string, + +title?: string, + +icon?: any, + +badge?: string | number | boolean, + +color?: string, + +accessibilityLabel?: string, + +testID?: string, + |}; + + declare export type PaperTouchableProps = {| + ...TouchableWithoutFeedbackProps, + +key: string, + +route: PaperRoute, + +children: React$Node, + +borderless?: boolean, + +centered?: boolean, + +rippleColor?: string, + |}; + + declare export type MaterialBottomTabNavigationConfig = {| + +shifting?: boolean, + +labeled?: boolean, + +renderTouchable?: PaperTouchableProps => React$Node, + +activeColor?: string, + +inactiveColor?: string, + +sceneAnimationEnabled?: boolean, + +keyboardHidesNavigationBar?: boolean, + +barStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +theme?: PaperTheme, + |}; + + declare export type ExtraMaterialBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialBottomTabNavigationConfig, + |}; + + declare export type MaterialBottomTabNavigatorProps< + NavProp: InexactMaterialBottomTabNavigationProp<> = + MaterialBottomTabNavigationProp<>, + > = {| + ...ExtraMaterialBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material top tab options + */ + + declare export type MaterialTopTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarIcon: ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material top tab navigation prop + */ + + declare export type MaterialTopTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + +swipeStart: {| +data: void, +canPreventDefault: false |}, + +swipeEnd: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactMaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material top tab exports + */ + + declare type MaterialTopTabPagerCommonProps = {| + +keyboardDismissMode: 'none' | 'on-drag' | 'auto', + +swipeEnabled: boolean, + +swipeVelocityImpact?: number, + +springVelocityScale?: number, + +springConfig: $Shape<{| + +damping: number, + +mass: number, + +stiffness: number, + +restSpeedThreshold: number, + +restDisplacementThreshold: number, + |}>, + +timingConfig: $Shape<{| + +duration: number, + |}>, + |}; + + declare export type MaterialTopTabPagerProps = {| + ...MaterialTopTabPagerCommonProps, + +onSwipeStart?: () => void, + +onSwipeEnd?: () => void, + +onIndexChange: (index: number) => void, + +navigationState: TabNavigationState, + +layout: {| +width: number, +height: number |}, + +removeClippedSubviews: boolean, + +children: ({| + +addListener: (type: 'enter', listener: number => void) => void, + +removeListener: (type: 'enter', listener: number => void) => void, + +position: any, // Reanimated.Node + +render: React$Node => React$Node, + +jumpTo: string => void, + |}) => React$Node, + +gestureHandlerProps: PanGestureHandlerProps, + |}; + + declare export type MaterialTopTabBarIndicatorProps = {| + +navigationState: TabNavigationState, + +width: string, + +style?: ViewStyleProp, + +getTabWidth: number => number, + |}; + + declare export type MaterialTopTabBarOptions = $Shape<{| + +scrollEnabled: boolean, + +bounces: boolean, + +pressColor: string, + +pressOpacity: number, + +getAccessible: ({| +route: Route<> |}) => boolean, + +renderBadge: ({| +route: Route<> |}) => React$Node, + +renderIndicator: MaterialTopTabBarIndicatorProps => React$Node, + +tabStyle: ViewStyleProp, + +indicatorStyle: ViewStyleProp, + +indicatorContainerStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + +activeTintColor: string, + +inactiveTintColor: string, + +iconStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +showLabel: boolean, + +showIcon: boolean, + +allowFontScaling: boolean, + |}>; + + declare export type MaterialTopTabDescriptor = Descriptor< + MaterialBottomTabNavigationProp<>, + MaterialBottomTabOptions, + >; + + declare type MaterialTopTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: MaterialTopTabNavigationProp<>, + +descriptors: {| +[key: string]: MaterialTopTabDescriptor |}, + |}; + + declare export type MaterialTopTabBarProps = {| + ...MaterialTopTabBarOptions, + ...MaterialTopTabNavigationBuilderResult, + +layout: {| +width: number, +height: number |}, + +position: any, // Reanimated.Node + +jumpTo: string => void, + |}; + + declare export type MaterialTopTabNavigationConfig = {| + ...$Partial, + +position?: any, // Reanimated.Value + +tabBarPosition?: 'top' | 'bottom', + +initialLayout?: $Shape<{| +width: number, +height: number |}>, + +lazy?: boolean, + +lazyPreloadDistance?: number, + +removeClippedSubviews?: boolean, + +sceneContainerStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +gestureHandlerProps?: PanGestureHandlerProps, + +pager?: MaterialTopTabPagerProps => React$Node, + +lazyPlaceholder?: ({| +route: Route<> |}) => React$Node, + +tabBar?: MaterialTopTabBarProps => React$Node, + +tabBarOptions?: MaterialTopTabBarOptions, + |}; + + declare export type ExtraMaterialTopTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialTopTabNavigationConfig, + |}; + + declare export type MaterialTopTabNavigatorProps< + NavProp: InexactMaterialTopTabNavigationProp<> = + MaterialTopTabNavigationProp<>, + > = {| + ...ExtraMaterialTopTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Drawer options + */ + + declare export type DrawerOptions = $Shape<{| + title: string, + drawerLabel: + | string + | ({| +color: string, +focused: boolean |}) => React$Node, + drawerIcon: ({| + +color: string, + +size: number, + +focused: boolean, + |}) => React$Node, + gestureEnabled: boolean, + swipeEnabled: boolean, + unmountOnBlur: boolean, + |}>; + + /** + * Drawer navigation prop + */ + + declare export type DrawerNavigationEventMap = {| + ...EventMapCore, + +drawerOpen: {| +data: void, +canPreventDefault: false |}, + +drawerClose: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactDrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + +openDrawer: () => void, + +closeDrawer: () => void, + +toggleDrawer: () => void, + ... + }; + + declare export type DrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous drawer exports + */ + + declare export type DrawerDescriptor = Descriptor< + DrawerNavigationProp<>, + DrawerOptions, + >; + + declare export type DrawerItemListBaseOptions = $Shape<{| + +activeTintColor: string, + +activeBackgroundColor: string, + +inactiveTintColor: string, + +inactiveBackgroundColor: string, + +itemStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + |}>; + + declare export type DrawerContentOptions = $Shape<{| + ...DrawerItemListBaseOptions, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + |}>; + + declare type DrawerNavigationBuilderResult = {| + +state: DrawerNavigationState, + +navigation: DrawerNavigationProp<>, + +descriptors: {| +[key: string]: DrawerDescriptor |}, + |}; + + declare export type DrawerContentProps = {| + ...DrawerContentOptions, + ...DrawerNavigationBuilderResult, + +progress: any, // Reanimated.Node + |}; + + declare export type DrawerNavigationConfig = {| + +drawerPosition?: 'left' | 'right', + +drawerType?: 'front' | 'back' | 'slide' | 'permanent', + +edgeWidth?: number, + +hideStatusBar?: boolean, + +keyboardDismissMode?: 'on-drag' | 'none', + +minSwipeDistance?: number, + +overlayColor?: string, + +statusBarAnimation?: 'slide' | 'none' | 'fade', + +gestureHandlerProps?: PanGestureHandlerProps, + +lazy?: boolean, + +drawerContent?: DrawerContentProps => React$Node, + +drawerContentOptions?: DrawerContentOptions, + +sceneContainerStyle?: ViewStyleProp, + +drawerStyle?: ViewStyleProp, + |}; + + declare export type ExtraDrawerNavigatorProps = {| + ...$Exact, + ...DrawerRouterOptions, + ...DrawerNavigationConfig, + |}; + + declare export type DrawerNavigatorProps< + NavProp: InexactDrawerNavigationProp<> = DrawerNavigationProp<>, + > = {| + ...ExtraDrawerNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * BaseNavigationContainer + */ + + declare export type BaseNavigationContainerProps = {| + +children: React$Node, + +initialState?: PossiblyStaleNavigationState, + +onStateChange?: (state: ?PossiblyStaleNavigationState) => void, + +independent?: boolean, + |}; + + declare export type ContainerEventMap = {| + ...GlobalEventMap, + +options: {| + +data: {| +options: { +[key: string]: mixed, ... } |}, + +canPreventDefault: false, + |}, + +__unsafe_action__: {| + +data: {| + +action: GenericNavigationAction, + +noop: boolean, + |}, + +canPreventDefault: false, + |}, + |}; + + declare export type BaseNavigationContainerInterface = {| + ...$Exact>, + +setParams: (params: ScreenParams) => void, + +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, + +getRootState: () => PossiblyStaleNavigationState, + |}; + + /** + * State utils + */ + + declare export type GetStateFromPath = ( + path: string, + options?: LinkingConfig, + ) => PossiblyStaleNavigationState; + + declare export type GetPathFromState = ( + state?: ?PossiblyStaleNavigationState, + options?: LinkingConfig, + ) => string; + + declare export type GetFocusedRouteNameFromRoute = + PossiblyStaleRoute => ?string; + + /** + * Linking + */ + + declare export type ScreenLinkingConfig = {| + +path?: string, + +exact?: boolean, + +parse?: {| +[param: string]: string => mixed |}, + +stringify?: {| +[param: string]: mixed => string |}, + +screens?: ScreenLinkingConfigMap, + +initialRouteName?: string, + |}; + + declare export type ScreenLinkingConfigMap = {| + +[routeName: string]: string | ScreenLinkingConfig, + |}; + + declare export type LinkingConfig = {| + +initialRouteName?: string, + +screens: ScreenLinkingConfigMap, + |}; + + declare export type LinkingOptions = {| + +enabled?: boolean, + +prefixes: $ReadOnlyArray, + +config?: LinkingConfig, + +getStateFromPath?: GetStateFromPath, + +getPathFromState?: GetPathFromState, + |}; + + /** + * NavigationContainer + */ + + declare export type Theme = {| + +dark: boolean, + +colors: {| + +primary: string, + +background: string, + +card: string, + +text: string, + +border: string, + |}, + |}; + + declare export type NavigationContainerType = React$AbstractComponent< + {| + ...BaseNavigationContainerProps, + +theme?: Theme, + +linking?: LinkingOptions, + +fallback?: React$Node, + +onReady?: () => mixed, + |}, + BaseNavigationContainerInterface, + >; + + //--------------------------------------------------------------------------- + // SECTION 2: EXPORTED MODULE + // This section defines the module exports and contains exported types that + // are not present in any other React Navigation libdef. + //--------------------------------------------------------------------------- + + /** + * createBottomTabNavigator + */ + + declare export var createBottomTabNavigator: CreateNavigator< + TabNavigationState, + BottomTabOptions, + BottomTabNavigationEventMap, + ExtraBottomTabNavigatorProps, + >; + + /** + * BottomTabBar + */ + + declare export var BottomTabBar: React$ComponentType; + + /** + * BottomTabView + */ + + declare export type BottomTabViewProps = {| + ...BottomTabNavigationConfig, + ...BottomTabNavigationBuilderResult, + |}; + declare export var BottomTabView: React$ComponentType; + +} diff --git a/flow-typed/npm/@react-navigation/compat_vx.x.x.js b/flow-typed/npm/@react-navigation/compat_vx.x.x.js new file mode 100644 index 00000000000..d7eda105875 --- /dev/null +++ b/flow-typed/npm/@react-navigation/compat_vx.x.x.js @@ -0,0 +1,255 @@ +// flow-typed signature: 6a548cf77d4aa0f0ec8619987a9578e6 +// flow-typed version: <>/@react-navigation/compat_v5.3.9/flow_v0.113.0 + +/** + * This is an autogenerated libdef stub for: + * + * '@react-navigation/compat' + * + * Fill this stub out by replacing all the `any` types. + * + * Once filled out, we encourage you to share your work with the + * community by sending a pull request to: + * https://github.com/flowtype/flow-typed + */ + +declare module '@react-navigation/compat' { + declare module.exports: any; +} + +/** + * We include stubs for each file inside this npm package in case you need to + * require those files directly. Feel free to delete any files that aren't + * needed. + */ +declare module '@react-navigation/compat/lib/commonjs/CompatScreen' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/createCompatNavigationProp' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/createCompatNavigatorFactory' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/createSwitchNavigator' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/DrawerActions' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/helpers' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/NavigationActions' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/NavigationEvents' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/ScreenPropsContext' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/StackActions' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/SwitchActions' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/types' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/useCompatNavigation' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/withNavigation' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/commonjs/withNavigationFocus' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/CompatScreen' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/createCompatNavigationProp' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/createCompatNavigatorFactory' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/createSwitchNavigator' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/DrawerActions' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/helpers' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/NavigationActions' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/NavigationEvents' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/ScreenPropsContext' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/StackActions' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/SwitchActions' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/types' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/useCompatNavigation' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/withNavigation' { + declare module.exports: any; +} + +declare module '@react-navigation/compat/lib/module/withNavigationFocus' { + declare module.exports: any; +} + +// Filename aliases +declare module '@react-navigation/compat/lib/commonjs/CompatScreen.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/CompatScreen'>; +} +declare module '@react-navigation/compat/lib/commonjs/createCompatNavigationProp.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/createCompatNavigationProp'>; +} +declare module '@react-navigation/compat/lib/commonjs/createCompatNavigatorFactory.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/createCompatNavigatorFactory'>; +} +declare module '@react-navigation/compat/lib/commonjs/createSwitchNavigator.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/createSwitchNavigator'>; +} +declare module '@react-navigation/compat/lib/commonjs/DrawerActions.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/DrawerActions'>; +} +declare module '@react-navigation/compat/lib/commonjs/helpers.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/helpers'>; +} +declare module '@react-navigation/compat/lib/commonjs/index' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs'>; +} +declare module '@react-navigation/compat/lib/commonjs/index.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs'>; +} +declare module '@react-navigation/compat/lib/commonjs/NavigationActions.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/NavigationActions'>; +} +declare module '@react-navigation/compat/lib/commonjs/NavigationEvents.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/NavigationEvents'>; +} +declare module '@react-navigation/compat/lib/commonjs/ScreenPropsContext.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/ScreenPropsContext'>; +} +declare module '@react-navigation/compat/lib/commonjs/StackActions.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/StackActions'>; +} +declare module '@react-navigation/compat/lib/commonjs/SwitchActions.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/SwitchActions'>; +} +declare module '@react-navigation/compat/lib/commonjs/types.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/types'>; +} +declare module '@react-navigation/compat/lib/commonjs/useCompatNavigation.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/useCompatNavigation'>; +} +declare module '@react-navigation/compat/lib/commonjs/withNavigation.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/withNavigation'>; +} +declare module '@react-navigation/compat/lib/commonjs/withNavigationFocus.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/commonjs/withNavigationFocus'>; +} +declare module '@react-navigation/compat/lib/module/CompatScreen.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/CompatScreen'>; +} +declare module '@react-navigation/compat/lib/module/createCompatNavigationProp.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/createCompatNavigationProp'>; +} +declare module '@react-navigation/compat/lib/module/createCompatNavigatorFactory.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/createCompatNavigatorFactory'>; +} +declare module '@react-navigation/compat/lib/module/createSwitchNavigator.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/createSwitchNavigator'>; +} +declare module '@react-navigation/compat/lib/module/DrawerActions.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/DrawerActions'>; +} +declare module '@react-navigation/compat/lib/module/helpers.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/helpers'>; +} +declare module '@react-navigation/compat/lib/module/index' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module'>; +} +declare module '@react-navigation/compat/lib/module/index.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module'>; +} +declare module '@react-navigation/compat/lib/module/NavigationActions.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/NavigationActions'>; +} +declare module '@react-navigation/compat/lib/module/NavigationEvents.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/NavigationEvents'>; +} +declare module '@react-navigation/compat/lib/module/ScreenPropsContext.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/ScreenPropsContext'>; +} +declare module '@react-navigation/compat/lib/module/StackActions.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/StackActions'>; +} +declare module '@react-navigation/compat/lib/module/SwitchActions.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/SwitchActions'>; +} +declare module '@react-navigation/compat/lib/module/types.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/types'>; +} +declare module '@react-navigation/compat/lib/module/useCompatNavigation.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/useCompatNavigation'>; +} +declare module '@react-navigation/compat/lib/module/withNavigation.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/withNavigation'>; +} +declare module '@react-navigation/compat/lib/module/withNavigationFocus.js' { + declare module.exports: $Exports<'@react-navigation/compat/lib/module/withNavigationFocus'>; +} diff --git a/flow-typed/npm/@react-navigation/drawer_v5.x.x.js b/flow-typed/npm/@react-navigation/drawer_v5.x.x.js new file mode 100644 index 00000000000..5bc4dedf412 --- /dev/null +++ b/flow-typed/npm/@react-navigation/drawer_v5.x.x.js @@ -0,0 +1,2101 @@ +// flow-typed signature: 1c0795a3c7af7a1beb390a1efd331d41 +// flow-typed version: 3c17c8ecd5/@react-navigation/drawer_v5.x.x/flow_>=v0.104.x + +declare module '@react-navigation/drawer' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + // Vaguely copied from + // react-native/Libraries/Animated/src/animations/Animation.js + declare type EndResult = { finished: boolean, ... }; + declare type EndCallback = (result: EndResult) => void; + declare interface Animation { + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void; + stop(): void; + } + declare type AnimationConfig = { + isInteraction?: boolean, + useNativeDriver: boolean, + onComplete?: ?EndCallback, + iterations?: number, + ... + }; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js + declare interface AnimatedTracking { + constructor( + value: AnimatedValue, + parent: any, + animationClass: any, + animationConfig: Object, + callback?: ?EndCallback, + ): void; + update(): void; + } + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedValue.js + declare type ValueListenerCallback = (state: { value: number, ... }) => void; + declare interface AnimatedValue { + constructor(value: number): void; + setValue(value: number): void; + setOffset(offset: number): void; + flattenOffset(): void; + extractOffset(): void; + addListener(callback: ValueListenerCallback): string; + removeListener(id: string): void; + removeAllListeners(): void; + stopAnimation(callback?: ?(value: number) => void): void; + resetAnimation(callback?: ?(value: number) => void): void; + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + animate(animation: Animation, callback: ?EndCallback): void; + stopTracking(): void; + track(tracking: AnimatedTracking): void; + } + + // Copied from + // react-native/Libraries/Animated/src/animations/TimingAnimation.js + declare type TimingAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + easing?: (value: number) => number, + duration?: number, + delay?: number, + ... + }; + + // Copied from + // react-native/Libraries/Animated/src/animations/SpringAnimation.js + declare type SpringAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + overshootClamping?: boolean, + restDisplacementThreshold?: number, + restSpeedThreshold?: number, + velocity?: number, + bounciness?: number, + speed?: number, + tension?: number, + friction?: number, + stiffness?: number, + damping?: number, + mass?: number, + delay?: number, + ... + }; + + // Copied from react-native/Libraries/Types/CoreEventTypes.js + declare type SyntheticEvent = $ReadOnly<{| + bubbles: ?boolean, + cancelable: ?boolean, + currentTarget: number, + defaultPrevented: ?boolean, + dispatchConfig: $ReadOnly<{| + registrationName: string, + |}>, + eventPhase: ?number, + preventDefault: () => void, + isDefaultPrevented: () => boolean, + stopPropagation: () => void, + isPropagationStopped: () => boolean, + isTrusted: ?boolean, + nativeEvent: T, + persist: () => void, + target: ?number, + timeStamp: number, + type: ?string, + |}>; + declare type Layout = $ReadOnly<{| + x: number, + y: number, + width: number, + height: number, + |}>; + declare type LayoutEvent = SyntheticEvent< + $ReadOnly<{| + layout: Layout, + |}>, + >; + declare type BlurEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type FocusEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type ResponderSyntheticEvent = $ReadOnly<{| + ...SyntheticEvent, + touchHistory: $ReadOnly<{| + indexOfSingleActiveTouch: number, + mostRecentTimeStamp: number, + numberActiveTouches: number, + touchBank: $ReadOnlyArray< + $ReadOnly<{| + touchActive: boolean, + startPageX: number, + startPageY: number, + startTimeStamp: number, + currentPageX: number, + currentPageY: number, + currentTimeStamp: number, + previousPageX: number, + previousPageY: number, + previousTimeStamp: number, + |}>, + >, + |}>, + |}>; + declare type PressEvent = ResponderSyntheticEvent< + $ReadOnly<{| + changedTouches: $ReadOnlyArray<$PropertyType>, + force: number, + identifier: number, + locationX: number, + locationY: number, + pageX: number, + pageY: number, + target: ?number, + timestamp: number, + touches: $ReadOnlyArray<$PropertyType>, + |}>, + >; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js + declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; + declare type InterpolationConfigType = { + inputRange: Array, + outputRange: Array | Array, + easing?: (input: number) => number, + extrapolate?: ExtrapolateType, + extrapolateLeft?: ExtrapolateType, + extrapolateRight?: ExtrapolateType, + ... + }; + declare interface AnimatedInterpolation { + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + } + + // Copied from react-native/Libraries/Components/View/ViewAccessibility.js + declare type AccessibilityRole = + | 'none' + | 'button' + | 'link' + | 'search' + | 'image' + | 'keyboardkey' + | 'text' + | 'adjustable' + | 'imagebutton' + | 'header' + | 'summary' + | 'alert' + | 'checkbox' + | 'combobox' + | 'menu' + | 'menubar' + | 'menuitem' + | 'progressbar' + | 'radio' + | 'radiogroup' + | 'scrollbar' + | 'spinbutton' + | 'switch' + | 'tab' + | 'tablist' + | 'timer' + | 'toolbar'; + declare type AccessibilityActionInfo = $ReadOnly<{ + name: string, + label?: string, + ... + }>; + declare type AccessibilityActionEvent = SyntheticEvent< + $ReadOnly<{actionName: string, ...}>, + >; + declare type AccessibilityState = { + disabled?: boolean, + selected?: boolean, + checked?: ?boolean | 'mixed', + busy?: boolean, + expanded?: boolean, + ... + }; + declare type AccessibilityValue = $ReadOnly<{| + min?: number, + max?: number, + now?: number, + text?: string, + |}>; + + // Copied from + // react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js + declare type Stringish = string; + declare type EdgeInsetsProp = $ReadOnly<$Shape>; + declare type TouchableWithoutFeedbackProps = $ReadOnly<{| + accessibilityActions?: ?$ReadOnlyArray, + accessibilityElementsHidden?: ?boolean, + accessibilityHint?: ?Stringish, + accessibilityIgnoresInvertColors?: ?boolean, + accessibilityLabel?: ?Stringish, + accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), + accessibilityRole?: ?AccessibilityRole, + accessibilityState?: ?AccessibilityState, + accessibilityValue?: ?AccessibilityValue, + accessibilityViewIsModal?: ?boolean, + accessible?: ?boolean, + children?: ?React$Node, + delayLongPress?: ?number, + delayPressIn?: ?number, + delayPressOut?: ?number, + disabled?: ?boolean, + focusable?: ?boolean, + hitSlop?: ?EdgeInsetsProp, + importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), + nativeID?: ?string, + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, + onBlur?: ?(event: BlurEvent) => mixed, + onFocus?: ?(event: FocusEvent) => mixed, + onLayout?: ?(event: LayoutEvent) => mixed, + onLongPress?: ?(event: PressEvent) => mixed, + onPress?: ?(event: PressEvent) => mixed, + onPressIn?: ?(event: PressEvent) => mixed, + onPressOut?: ?(event: PressEvent) => mixed, + pressRetentionOffset?: ?EdgeInsetsProp, + rejectResponderTermination?: ?boolean, + testID?: ?string, + touchSoundDisabled?: ?boolean, + |}>; + + // Copied from react-native/Libraries/Image/ImageSource.js + declare type ImageURISource = $ReadOnly<{ + uri?: ?string, + bundle?: ?string, + method?: ?string, + headers?: ?Object, + body?: ?string, + cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached'), + width?: ?number, + height?: ?number, + scale?: ?number, + ... + }>; + + /** + * The following is copied from react-native-gesture-handler's libdef + */ + + declare type $EventHandlers = {| + onGestureEvent?: ($Event) => mixed, + onHandlerStateChange?: ($Event) => mixed, + onBegan?: ($Event) => mixed, + onFailed?: ($Event) => mixed, + onCancelled?: ($Event) => mixed, + onActivated?: ($Event) => mixed, + onEnded?: ($Event) => mixed, + |}; + + declare type HitSlop = + | number + | {| + left?: number, + top?: number, + right?: number, + bottom?: number, + vertical?: number, + horizontal?: number, + width?: number, + height?: number, + |} + | {| + width: number, + left: number, + |} + | {| + width: number, + right: number, + |} + | {| + height: number, + top: number, + |} + | {| + height: number, + bottom: number, + |}; + + declare type $GestureHandlerProps< + AdditionalProps: {...}, + ExtraEventsProps: {...} + > = $ReadOnly<{| + ...$Exact, + ...$EventHandlers, + id?: string, + enabled?: boolean, + waitFor?: React$Ref | Array>, + simultaneousHandlers?: React$Ref | Array>, + shouldCancelWhenOutside?: boolean, + minPointers?: number, + hitSlop?: HitSlop, + children?: React$Node, + |}>; + + declare type PanGestureHandlerProps = $GestureHandlerProps< + { + activeOffsetY?: number | [number, number], + activeOffsetX?: number | [number, number], + failOffsetY?: number | [number, number], + failOffsetX?: number | [number, number], + minDist?: number, + minVelocity?: number, + minVelocityX?: number, + minVelocityY?: number, + minPointers?: number, + maxPointers?: number, + avgTouches?: boolean, + ... + }, + { + x: number, + y: number, + absoluteX: number, + absoluteY: number, + translationX: number, + translationY: number, + velocityX: number, + velocityY: number, + ... + } + >; + + /** + * MAGIC + */ + + declare type $If = $Call< + ((true, Then, Else) => Then) & ((false, Then, Else) => Else), + Test, + Then, + Else, + >; + declare type $IsA = $Call< + (Y => true) & (mixed => false), + X, + >; + declare type $IsUndefined = $IsA; + + declare type $Partial = $Rest; + + /** + * Actions, state, etc. + */ + + declare export type ScreenParams = { +[key: string]: mixed, ... }; + + declare export type BackAction = {| + +type: 'GO_BACK', + +source?: string, + +target?: string, + |}; + declare export type NavigateAction = {| + +type: 'NAVIGATE', + +payload: + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type ResetAction = {| + +type: 'RESET', + +payload: StaleNavigationState, + +source?: string, + +target?: string, + |}; + declare export type SetParamsAction = {| + +type: 'SET_PARAMS', + +payload: {| +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type CommonAction = + | BackAction + | NavigateAction + | ResetAction + | SetParamsAction; + + declare type NavigateActionCreator = {| + (routeName: string, params?: ScreenParams): NavigateAction, + ( + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + ): NavigateAction, + |}; + declare export type CommonActionsType = {| + +navigate: NavigateActionCreator, + +goBack: () => BackAction, + +reset: (state: PossiblyStaleNavigationState) => ResetAction, + +setParams: (params: ScreenParams) => SetParamsAction, + |}; + + declare export type GenericNavigationAction = {| + +type: string, + +payload?: { +[key: string]: mixed, ... }, + +source?: string, + +target?: string, + |}; + + declare export type LeafRoute = {| + +key: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StateRoute = {| + ...LeafRoute, + +state: NavigationState | StaleNavigationState, + |}; + declare export type Route = + | LeafRoute + | StateRoute; + + declare export type NavigationState = {| + +key: string, + +index: number, + +routeNames: $ReadOnlyArray, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type: string, + +stale: false, + |}; + + declare export type StaleLeafRoute = {| + +key?: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StaleStateRoute = {| + ...StaleLeafRoute, + +state: StaleNavigationState, + |}; + declare export type StaleRoute = + | StaleLeafRoute + | StaleStateRoute; + declare export type StaleNavigationState = {| + // It's possible to pass React Nav a StaleNavigationState with an undefined + // index, but React Nav will always return one with the index set. This is + // the same as for the type property below, but in the case of index we tend + // to rely on it being set more... + +index: number, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type?: string, + +stale?: true, + |}; + + declare export type PossiblyStaleNavigationState = + | NavigationState + | StaleNavigationState; + declare export type PossiblyStaleRoute = + | Route + | StaleRoute; + + /** + * Routers + */ + + declare type ActionCreators< + State: NavigationState, + Action: GenericNavigationAction, + > = { + +[key: string]: (...args: any) => (Action | State => Action), + ... + }; + + declare export type DefaultRouterOptions = { + +initialRouteName?: string, + ... + }; + + declare export type RouterFactory< + State: NavigationState, + Action: GenericNavigationAction, + RouterOptions: DefaultRouterOptions, + > = (options: RouterOptions) => Router; + + declare export type ParamListBase = { +[key: string]: ?ScreenParams, ... }; + + declare export type RouterConfigOptions = {| + +routeNames: $ReadOnlyArray, + +routeParamList: ParamListBase, + |}; + + declare export type Router< + State: NavigationState, + Action: GenericNavigationAction, + > = {| + +type: $PropertyType, + +getInitialState: (options: RouterConfigOptions) => State, + +getRehydratedState: ( + partialState: PossibleStaleNavigationState, + options: RouterConfigOptions, + ) => State, + +getStateForRouteNamesChange: ( + state: State, + options: RouterConfigOptions, + ) => State, + +getStateForRouteFocus: (state: State, key: string) => State, + +getStateForAction: ( + state: State, + action: Action, + options: RouterConfigOptions, + ) => ?PossiblyStaleNavigationState; + +shouldActionChangeFocus: (action: GenericNavigationAction) => boolean, + +actionCreators?: ActionCreators, + |}; + + /** + * Stack actions and router + */ + + declare export type StackNavigationState = {| + ...NavigationState, + +type: 'stack', + |}; + + declare export type ReplaceAction = {| + +type: 'REPLACE', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PushAction = {| + +type: 'PUSH', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PopAction = {| + +type: 'POP', + +payload: {| +count: number |}, + +source?: string, + +target?: string, + |}; + declare export type PopToTopAction = {| + +type: 'POP_TO_TOP', + +source?: string, + +target?: string, + |}; + declare export type StackAction = + | CommonAction + | ReplaceAction + | PushAction + | PopAction + | PopToTopAction; + + declare export type StackActionsType = {| + +replace: (routeName: string, params?: ScreenParams) => ReplaceAction, + +push: (routeName: string, params?: ScreenParams) => PushAction, + +pop: (count?: number) => PopAction, + +popToTop: () => PopToTopAction, + |}; + + declare export type StackRouterOptions = $Exact; + + /** + * Tab actions and router + */ + + declare export type TabNavigationState = {| + ...NavigationState, + +type: 'tab', + +history: $ReadOnlyArray<{| type: 'route', key: string |}>, + |}; + + declare export type JumpToAction = {| + +type: 'JUMP_TO', + +payload: {| +name: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type TabAction = + | CommonAction + | JumpToAction; + + declare export type TabActionsType = {| + +jumpTo: string => JumpToAction, + |}; + + declare export type TabRouterOptions = {| + ...$Exact, + +backBehavior?: 'initialRoute' | 'order' | 'history' | 'none', + |}; + + /** + * Drawer actions and router + */ + + declare type DrawerHistoryEntry = + | {| +type: 'route', +key: string |} + | {| +type: 'drawer' |}; + declare export type DrawerNavigationState = {| + ...NavigationState, + +type: 'drawer', + +history: $ReadOnlyArray, + |}; + + declare export type OpenDrawerAction = {| + +type: 'OPEN_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type CloseDrawerAction = {| + +type: 'CLOSE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type ToggleDrawerAction = {| + +type: 'TOGGLE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type DrawerAction = + | TabAction + | OpenDrawerAction + | CloseDrawerAction + | ToggleDrawerAction; + + declare export type DrawerActionsType = {| + ...TabActionsType, + +openDrawer: () => OpenDrawerAction, + +closeDrawer: () => CloseDrawerAction, + +toggleDrawer: () => ToggleDrawerAction, + |}; + + declare export type DrawerRouterOptions = {| + ...TabRouterOptions, + +openByDefault?: boolean, + |}; + + /** + * Events + */ + + declare export type EventMapBase = { + +[name: string]: {| + +data?: mixed, + +canPreventDefault?: boolean, + |}, + ... + }; + declare type EventPreventDefaultProperties = $If< + Test, + {| +defaultPrevented: boolean, +preventDefault: () => void |}, + {| |}, + >; + declare type EventDataProperties = $If< + $IsUndefined, + {| |}, + {| +data: Data |}, + >; + declare type EventArg< + EventName: string, + CanPreventDefault: ?boolean = false, + Data = void, + > = {| + ...EventPreventDefaultProperties, + ...EventDataProperties, + +type: EventName, + +target?: string, + |}; + declare type GlobalEventMap = {| + +state: {| +data: {| +state: State |}, +canPreventDefault: false |}, + |}; + declare type EventMapCore = {| + ...GlobalEventMap, + +focus: {| +data: void, +canPreventDefault: false |}, + +blur: {| +data: void, +canPreventDefault: false |}, + |}; + declare type EventListenerCallback< + EventName: string, + State: PossiblyStaleNavigationState = NavigationState, + EventMap: EventMapBase = EventMapCore, + > = (e: EventArg< + EventName, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'canPreventDefault', + >, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'data', + >, + >) => mixed; + + /** + * Navigation prop + */ + + declare export type SimpleNavigate = + >( + routeName: DestinationRouteName, + params: $ElementType, + ) => void; + + declare export type Navigate = + & SimpleNavigate + & >( + route: + | {| + key: string, + params?: $ElementType, + |} + | {| + name: DestinationRouteName, + key?: string, + params?: $ElementType, + |}, + ) => void; + + declare type NavigationHelpers< + ParamList: ParamListBase, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + EventMap: EventMapBase = EventMapCore, + > = { + +navigate: Navigate, + +dispatch: ( + action: + | GenericNavigationAction + | (State => GenericNavigationAction), + ) => void, + +reset: PossiblyStaleNavigationState => void, + +goBack: () => void, + +isFocused: () => boolean, + +canGoBack: () => boolean, + +dangerouslyGetParent: >() => ?Parent, + +dangerouslyGetState: () => NavigationState, + +addListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => () => void, + +removeListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => void, + ... + }; + + declare export type NavigationProp< + ParamList: ParamListBase, + RouteName: $Keys = $Keys, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = { + ...$Exact>, + +setOptions: (options: $Shape) => void, + +setParams: ( + params: $If< + $IsUndefined<$ElementType>, + empty, + $Shape<$NonMaybeType<$ElementType>>, + >, + ) => void, + ... + }; + + /** + * CreateNavigator + */ + + declare export type RouteProp< + ParamList: ParamListBase, + RouteName: $Keys, + > = {| + ...LeafRoute, + +params: $ElementType, + |}; + + declare export type ScreenListeners< + EventMap: EventMapBase = EventMapCore, + State: NavigationState = NavigationState, + > = $ObjMapi< + {| [name: $Keys]: empty |}, + >(K, empty) => EventListenerCallback, + >; + + declare type BaseScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = {| + +name: RouteName, + +options?: + | ScreenOptions + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenOptions, + +listeners?: + | ScreenListeners + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenListeners, + +initialParams?: $Shape<$ElementType>, + |}; + + declare export type ScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +component: React$ComponentType<{| + route: RouteProp, + navigation: NavProp, + |}>, + |} + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +children: ({| + route: RouteProp, + navigation: NavProp, + |}) => React$Node, + |}; + + declare export type ScreenComponent< + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = < + RouteName: $Keys, + NavProp: NavigationProp< + GlobalParamList, + RouteName, + State, + ScreenOptions, + EventMap, + >, + >(props: ScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >) => React$Node; + + declare type ScreenOptionsProp = {| + +screenOptions?: + | ScreenOptions + | ({| route: LeafRoute<>, navigation: NavProp |}) => ScreenOptions, + |}; + declare export type ExtraNavigatorPropsBase = { + ...$Exact, + +children?: React$Node, + ... + }; + declare export type NavigatorPropsBase = { + ...$Exact, + ...ScreenOptionsProp, + ... + }; + + declare export type CreateNavigator< + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + > = < + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + NavProp: NavigationHelpers< + GlobalParamList, + State, + EventMap, + >, + >() => {| + +Screen: ScreenComponent< + GlobalParamList, + ParamList, + State, + ScreenOptions, + EventMap, + >, + +Navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + |}; + + declare export type CreateNavigatorFactory = < + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + NavProp: NavigationHelpers< + ParamListBase, + State, + EventMap, + >, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + >( + navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + ) => CreateNavigator; + + /** + * useNavigationBuilder + */ + + declare export type Descriptor< + NavProp, + ScreenOptions: {...} = {...}, + > = {| + +render: () => React$Node, + +options: $ReadOnly, + +navigation: NavProp, + |}; + + declare export type UseNavigationBuilder = < + State: NavigationState, + Action: GenericNavigationAction, + ScreenOptions: {...}, + RouterOptions: DefaultRouterOptions, + NavProp, + >( + routerFactory: RouterFactory, + options: {| + ...$Exact, + ...ScreenOptionsProp, + +children?: React$Node, + |}, + ) => {| + +state: State, + +descriptors: {| +[key: string]: Descriptor |}, + +navigation: NavProp, + |}; + + /** + * EdgeInsets + */ + + declare type EdgeInsets = {| + +top: number, + +right: number, + +bottom: number, + +left: number, + |}; + + /** + * TransitionPreset + */ + + declare export type TransitionSpec = + | {| + animation: 'spring', + config: $Diff< + SpringAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |} + | {| + animation: 'timing', + config: $Diff< + TimingAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |}; + + declare export type StackCardInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +index: number, + +closing: AnimatedInterpolation, + +swiping: AnimatedInterpolation, + +inverted: AnimatedInterpolation, + +layouts: {| + +screen: {| +width: number, +height: number |}, + |}, + +insets: EdgeInsets, + |}; + declare export type StackCardInterpolatedStyle = {| + containerStyle?: AnimatedViewStyleProp, + cardStyle?: AnimatedViewStyleProp, + overlayStyle?: AnimatedViewStyleProp, + shadowStyle?: AnimatedViewStyleProp, + |}; + declare export type StackCardStyleInterpolator = ( + props: StackCardInterpolationProps, + ) => StackCardInterpolatedStyle; + + declare export type StackHeaderInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +layouts: {| + +header: {| +width: number, +height: number |}, + +screen: {| +width: number, +height: number |}, + +title?: {| +width: number, +height: number |}, + +leftLabel?: {| +width: number, +height: number |}, + |}, + |}; + declare export type StackHeaderInterpolatedStyle = {| + leftLabelStyle?: AnimatedViewStyleProp, + leftButtonStyle?: AnimatedViewStyleProp, + rightButtonStyle?: AnimatedViewStyleProp, + titleStyle?: AnimatedViewStyleProp, + backgroundStyle?: AnimatedViewStyleProp, + |}; + declare export type StackHeaderStyleInterpolator = ( + props: StackHeaderInterpolationProps, + ) => StackHeaderInterpolatedStyle; + + declare type GestureDirection = + | 'horizontal' + | 'horizontal-inverted' + | 'vertical' + | 'vertical-inverted'; + + declare export type TransitionPreset = {| + +gestureDirection: GestureDirection, + +transitionSpec: {| + +open: TransitionSpec, + +close: TransitionSpec, + |}, + +cardStyleInterpolator: StackCardStyleInterpolator, + +headerStyleInterpolator: StackHeaderStyleInterpolator, + |}; + + /** + * Stack options + */ + + declare export type StackDescriptor = Descriptor< + StackNavigationProp<>, + StackOptions, + >; + + declare type Scene = {| + +route: T, + +descriptor: StackDescriptor, + +progress: {| + +current: AnimatedInterpolation, + +next?: AnimatedInterpolation, + +previous?: AnimatedInterpolation, + |}, + |}; + + declare export type StackHeaderProps = {| + +mode: 'float' | 'screen', + +layout: {| +width: number, +height: number |}, + +insets: EdgeInsets, + +scene: Scene>, + +previous?: Scene>, + +navigation: StackNavigationProp, + +styleInterpolator: StackHeaderStyleInterpolator, + |}; + + declare export type StackHeaderLeftButtonProps = $Shape<{| + +onPress: (() => void), + +pressColorAndroid: string; + +backImage: (props: {| tintColor: string |}) => React$Node, + +tintColor: string, + +label: string, + +truncatedLabel: string, + +labelVisible: boolean, + +labelStyle: AnimatedTextStyleProp, + +allowFontScaling: boolean, + +onLabelLayout: LayoutEvent => void, + +screenLayout: {| +width: number, +height: number |}, + +titleLayout: {| +width: number, +height: number |}, + +canGoBack: boolean, + |}>; + + declare type StackHeaderTitleInputBase = { + +onLayout: LayoutEvent => void, + +children: string, + +allowFontScaling: ?boolean, + +tintColor: ?string, + +style: ?AnimatedTextStyleProp, + ... + }; + + declare export type StackHeaderTitleInputProps = + $Exact; + + declare export type StackOptions = $Shape<{| + +title: string, + +header: StackHeaderProps => React$Node, + +headerShown: boolean, + +cardShadowEnabled: boolean, + +cardOverlayEnabled: boolean, + +cardOverlay: {| style: ViewStyleProp |} => React$Node, + +cardStyle: ViewStyleProp, + +animationEnabled: boolean, + +animationTypeForReplace: 'push' | 'pop', + +gestureEnabled: boolean, + +gestureResponseDistance: {| vertical?: number, horizontal?: number |}, + +gestureVelocityImpact: number, + +safeAreaInsets: $Shape, + // Transition + ...TransitionPreset, + // Header + +headerTitle: string | (StackHeaderTitleInputProps => React$Node), + +headerTitleAlign: 'left' | 'center', + +headerTitleStyle: AnimatedTextStyleProp, + +headerTitleContainerStyle: ViewStyleProp, + +headerTintColor: string, + +headerTitleAllowFontScaling: boolean, + +headerBackAllowFontScaling: boolean, + +headerBackTitle: string | null, + +headerBackTitleStyle: TextStyleProp, + +headerBackTitleVisible: boolean, + +headerTruncatedBackTitle: string, + +headerLeft: StackHeaderLeftButtonProps => React$Node, + +headerLeftContainerStyle: ViewStyleProp, + +headerRight: {| tintColor?: string |} => React$Node, + +headerRightContainerStyle: ViewStyleProp, + +headerBackImage: $PropertyType, + +headerPressColorAndroid: string, + +headerBackground: ({| style: ViewStyleProp |}) => React$Node, + +headerStyle: ViewStyleProp, + +headerTransparent: boolean, + +headerStatusBarHeight: number, + |}>; + + /** + * Stack navigation prop + */ + + declare export type StackNavigationEventMap = {| + ...EventMapCore, + +transitionStart: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + +transitionEnd: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + |}; + + declare type InexactStackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = { + ...$Exact>, + +replace: SimpleNavigate, + +push: SimpleNavigate, + +pop: (count?: number) => void, + +popToTop: () => void, + ... + }; + + declare export type StackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous stack exports + */ + + declare type StackNavigationConfig = {| + +mode?: 'card' | 'modal', + +headerMode?: 'float' | 'screen' | 'none', + +keyboardHandlingEnabled?: boolean, + |}; + + declare export type ExtraStackNavigatorProps = {| + ...$Exact, + ...StackRouterOptions, + ...StackNavigationConfig, + |}; + + declare export type StackNavigatorProps< + NavProp: InexactStackNavigationProp<> = StackNavigationProp<>, + > = {| + ...ExtraStackNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Bottom tab options + */ + + declare export type BottomTabBarButtonProps = {| + ...$Diff< + TouchableWithoutFeedbackProps, + {| onPress?: ?(event: PressEvent) => mixed |}, + >, + +to?: string, + +children: React$Node, + +onPress?: (MouseEvent | PressEvent) => void, + |}; + + declare export type BottomTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| focused: boolean, color: string |}) => React$Node, + +tabBarIcon: ({| + focused: boolean, + color: string, + size: number, + |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + +tabBarVisible: boolean, + +tabBarButton: BottomTabBarButtonProps => React$Node, + +unmountOnBlur: boolean, + |}>; + + /** + * Bottom tab navigation prop + */ + + declare export type BottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + |}; + + declare type InexactTabNavigationProp< + ParamList: ParamListBase, + RouteName: $Keys, + Options: {...}, + EventMap: EventMapBase, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + ... + }; + + declare export type InexactBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type BottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous bottom tab exports + */ + + declare export type BottomTabDescriptor = Descriptor< + BottomTabNavigationProp<>, + BottomTabOptions, + >; + + declare export type BottomTabBarOptions = $Shape<{| + +keyboardHidesTabBar: boolean, + +activeTintColor: string, + +inactiveTintColor: string, + +activeBackgroundColor: string, + +inactiveBackgroundColor: string, + +allowFontScaling: boolean, + +showLabel: boolean, + +showIcon: boolean, + +labelStyle: TextStyleProp, + +iconStyle: TextStyleProp, + +tabStyle: ViewStyleProp, + +labelPosition: 'beside-icon' | 'below-icon', + +adaptive: boolean, + +safeAreaInsets: $Shape, + +style: ViewStyleProp, + |}>; + + declare type BottomTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: BottomTabNavigationProp<>, + +descriptors: {| +[key: string]: BottomTabDescriptor |}, + |}; + + declare export type BottomTabBarProps = {| + ...BottomTabBarOptions, + ...BottomTabNavigationBuilderResult, + |} + + declare type BottomTabNavigationConfig = {| + +lazy?: boolean, + +tabBar?: BottomTabBarProps => React$Node, + +tabBarOptions?: BottomTabBarOptions, + |}; + + declare export type ExtraBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...BottomTabNavigationConfig, + |}; + + declare export type BottomTabNavigatorProps< + NavProp: InexactBottomTabNavigationProp<> = BottomTabNavigationProp<>, + > = {| + ...ExtraBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material bottom tab options + */ + + declare export type MaterialBottomTabOptions = $Shape<{| + +title: string, + +tabBarColor: string, + +tabBarLabel: string, + +tabBarIcon: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarBadge: boolean | number | string, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material bottom tab navigation prop + */ + + declare export type MaterialBottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + |}; + + declare export type InexactMaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material bottom tab exports + */ + + declare export type PaperFont = {| + +fontFamily: string, + +fontWeight?: + | 'normal' + | 'bold' + | '100' + | '200' + | '300' + | '400' + | '500' + | '600' + | '700' + | '800' + | '900', + |}; + + declare export type PaperFonts = {| + +regular: Font, + +medium: Font, + +light: Font, + +thin: Font, + |}; + + declare export type PaperTheme = {| + +dark: boolean, + +mode?: 'adaptive' | 'exact', + +roundness: number, + +colors: {| + +primary: string, + +background: string, + +surface: string, + +accent: string, + +error: string, + +text: string, + +onSurface: string, + +onBackground: string, + +disabled: string, + +placeholder: string, + +backdrop: string, + +notification: string, + |}, + +fonts: PaperFonts, + +animation: {| + +scale: number, + |}, + |}; + + declare export type PaperRoute = {| + +key: string, + +title?: string, + +icon?: any, + +badge?: string | number | boolean, + +color?: string, + +accessibilityLabel?: string, + +testID?: string, + |}; + + declare export type PaperTouchableProps = {| + ...TouchableWithoutFeedbackProps, + +key: string, + +route: PaperRoute, + +children: React$Node, + +borderless?: boolean, + +centered?: boolean, + +rippleColor?: string, + |}; + + declare export type MaterialBottomTabNavigationConfig = {| + +shifting?: boolean, + +labeled?: boolean, + +renderTouchable?: PaperTouchableProps => React$Node, + +activeColor?: string, + +inactiveColor?: string, + +sceneAnimationEnabled?: boolean, + +keyboardHidesNavigationBar?: boolean, + +barStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +theme?: PaperTheme, + |}; + + declare export type ExtraMaterialBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialBottomTabNavigationConfig, + |}; + + declare export type MaterialBottomTabNavigatorProps< + NavProp: InexactMaterialBottomTabNavigationProp<> = + MaterialBottomTabNavigationProp<>, + > = {| + ...ExtraMaterialBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material top tab options + */ + + declare export type MaterialTopTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarIcon: ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material top tab navigation prop + */ + + declare export type MaterialTopTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + +swipeStart: {| +data: void, +canPreventDefault: false |}, + +swipeEnd: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactMaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material top tab exports + */ + + declare type MaterialTopTabPagerCommonProps = {| + +keyboardDismissMode: 'none' | 'on-drag' | 'auto', + +swipeEnabled: boolean, + +swipeVelocityImpact?: number, + +springVelocityScale?: number, + +springConfig: $Shape<{| + +damping: number, + +mass: number, + +stiffness: number, + +restSpeedThreshold: number, + +restDisplacementThreshold: number, + |}>, + +timingConfig: $Shape<{| + +duration: number, + |}>, + |}; + + declare export type MaterialTopTabPagerProps = {| + ...MaterialTopTabPagerCommonProps, + +onSwipeStart?: () => void, + +onSwipeEnd?: () => void, + +onIndexChange: (index: number) => void, + +navigationState: TabNavigationState, + +layout: {| +width: number, +height: number |}, + +removeClippedSubviews: boolean, + +children: ({| + +addListener: (type: 'enter', listener: number => void) => void, + +removeListener: (type: 'enter', listener: number => void) => void, + +position: any, // Reanimated.Node + +render: React$Node => React$Node, + +jumpTo: string => void, + |}) => React$Node, + +gestureHandlerProps: PanGestureHandlerProps, + |}; + + declare export type MaterialTopTabBarIndicatorProps = {| + +navigationState: TabNavigationState, + +width: string, + +style?: ViewStyleProp, + +getTabWidth: number => number, + |}; + + declare export type MaterialTopTabBarOptions = $Shape<{| + +scrollEnabled: boolean, + +bounces: boolean, + +pressColor: string, + +pressOpacity: number, + +getAccessible: ({| +route: Route<> |}) => boolean, + +renderBadge: ({| +route: Route<> |}) => React$Node, + +renderIndicator: MaterialTopTabBarIndicatorProps => React$Node, + +tabStyle: ViewStyleProp, + +indicatorStyle: ViewStyleProp, + +indicatorContainerStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + +activeTintColor: string, + +inactiveTintColor: string, + +iconStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +showLabel: boolean, + +showIcon: boolean, + +allowFontScaling: boolean, + |}>; + + declare export type MaterialTopTabDescriptor = Descriptor< + MaterialBottomTabNavigationProp<>, + MaterialBottomTabOptions, + >; + + declare type MaterialTopTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: MaterialTopTabNavigationProp<>, + +descriptors: {| +[key: string]: MaterialTopTabDescriptor |}, + |}; + + declare export type MaterialTopTabBarProps = {| + ...MaterialTopTabBarOptions, + ...MaterialTopTabNavigationBuilderResult, + +layout: {| +width: number, +height: number |}, + +position: any, // Reanimated.Node + +jumpTo: string => void, + |}; + + declare export type MaterialTopTabNavigationConfig = {| + ...$Partial, + +position?: any, // Reanimated.Value + +tabBarPosition?: 'top' | 'bottom', + +initialLayout?: $Shape<{| +width: number, +height: number |}>, + +lazy?: boolean, + +lazyPreloadDistance?: number, + +removeClippedSubviews?: boolean, + +sceneContainerStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +gestureHandlerProps?: PanGestureHandlerProps, + +pager?: MaterialTopTabPagerProps => React$Node, + +lazyPlaceholder?: ({| +route: Route<> |}) => React$Node, + +tabBar?: MaterialTopTabBarProps => React$Node, + +tabBarOptions?: MaterialTopTabBarOptions, + |}; + + declare export type ExtraMaterialTopTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialTopTabNavigationConfig, + |}; + + declare export type MaterialTopTabNavigatorProps< + NavProp: InexactMaterialTopTabNavigationProp<> = + MaterialTopTabNavigationProp<>, + > = {| + ...ExtraMaterialTopTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Drawer options + */ + + declare export type DrawerOptions = $Shape<{| + title: string, + drawerLabel: + | string + | ({| +color: string, +focused: boolean |}) => React$Node, + drawerIcon: ({| + +color: string, + +size: number, + +focused: boolean, + |}) => React$Node, + gestureEnabled: boolean, + swipeEnabled: boolean, + unmountOnBlur: boolean, + |}>; + + /** + * Drawer navigation prop + */ + + declare export type DrawerNavigationEventMap = {| + ...EventMapCore, + +drawerOpen: {| +data: void, +canPreventDefault: false |}, + +drawerClose: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactDrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + +openDrawer: () => void, + +closeDrawer: () => void, + +toggleDrawer: () => void, + ... + }; + + declare export type DrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous drawer exports + */ + + declare export type DrawerDescriptor = Descriptor< + DrawerNavigationProp<>, + DrawerOptions, + >; + + declare export type DrawerItemListBaseOptions = $Shape<{| + +activeTintColor: string, + +activeBackgroundColor: string, + +inactiveTintColor: string, + +inactiveBackgroundColor: string, + +itemStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + |}>; + + declare export type DrawerContentOptions = $Shape<{| + ...DrawerItemListBaseOptions, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + |}>; + + declare type DrawerNavigationBuilderResult = {| + +state: DrawerNavigationState, + +navigation: DrawerNavigationProp<>, + +descriptors: {| +[key: string]: DrawerDescriptor |}, + |}; + + declare export type DrawerContentProps = {| + ...DrawerContentOptions, + ...DrawerNavigationBuilderResult, + +progress: any, // Reanimated.Node + |}; + + declare export type DrawerNavigationConfig = {| + +drawerPosition?: 'left' | 'right', + +drawerType?: 'front' | 'back' | 'slide' | 'permanent', + +edgeWidth?: number, + +hideStatusBar?: boolean, + +keyboardDismissMode?: 'on-drag' | 'none', + +minSwipeDistance?: number, + +overlayColor?: string, + +statusBarAnimation?: 'slide' | 'none' | 'fade', + +gestureHandlerProps?: PanGestureHandlerProps, + +lazy?: boolean, + +drawerContent?: DrawerContentProps => React$Node, + +drawerContentOptions?: DrawerContentOptions, + +sceneContainerStyle?: ViewStyleProp, + +drawerStyle?: ViewStyleProp, + |}; + + declare export type ExtraDrawerNavigatorProps = {| + ...$Exact, + ...DrawerRouterOptions, + ...DrawerNavigationConfig, + |}; + + declare export type DrawerNavigatorProps< + NavProp: InexactDrawerNavigationProp<> = DrawerNavigationProp<>, + > = {| + ...ExtraDrawerNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * BaseNavigationContainer + */ + + declare export type BaseNavigationContainerProps = {| + +children: React$Node, + +initialState?: PossiblyStaleNavigationState, + +onStateChange?: (state: ?PossiblyStaleNavigationState) => void, + +independent?: boolean, + |}; + + declare export type ContainerEventMap = {| + ...GlobalEventMap, + +options: {| + +data: {| +options: { +[key: string]: mixed, ... } |}, + +canPreventDefault: false, + |}, + +__unsafe_action__: {| + +data: {| + +action: GenericNavigationAction, + +noop: boolean, + |}, + +canPreventDefault: false, + |}, + |}; + + declare export type BaseNavigationContainerInterface = {| + ...$Exact>, + +setParams: (params: ScreenParams) => void, + +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, + +getRootState: () => PossiblyStaleNavigationState, + |}; + + /** + * State utils + */ + + declare export type GetStateFromPath = ( + path: string, + options?: LinkingConfig, + ) => PossiblyStaleNavigationState; + + declare export type GetPathFromState = ( + state?: ?PossiblyStaleNavigationState, + options?: LinkingConfig, + ) => string; + + declare export type GetFocusedRouteNameFromRoute = + PossiblyStaleRoute => ?string; + + /** + * Linking + */ + + declare export type ScreenLinkingConfig = {| + +path?: string, + +exact?: boolean, + +parse?: {| +[param: string]: string => mixed |}, + +stringify?: {| +[param: string]: mixed => string |}, + +screens?: ScreenLinkingConfigMap, + +initialRouteName?: string, + |}; + + declare export type ScreenLinkingConfigMap = {| + +[routeName: string]: string | ScreenLinkingConfig, + |}; + + declare export type LinkingConfig = {| + +initialRouteName?: string, + +screens: ScreenLinkingConfigMap, + |}; + + declare export type LinkingOptions = {| + +enabled?: boolean, + +prefixes: $ReadOnlyArray, + +config?: LinkingConfig, + +getStateFromPath?: GetStateFromPath, + +getPathFromState?: GetPathFromState, + |}; + + /** + * NavigationContainer + */ + + declare export type Theme = {| + +dark: boolean, + +colors: {| + +primary: string, + +background: string, + +card: string, + +text: string, + +border: string, + |}, + |}; + + declare export type NavigationContainerType = React$AbstractComponent< + {| + ...BaseNavigationContainerProps, + +theme?: Theme, + +linking?: LinkingOptions, + +fallback?: React$Node, + +onReady?: () => mixed, + |}, + BaseNavigationContainerInterface, + >; + + //--------------------------------------------------------------------------- + // SECTION 2: EXPORTED MODULE + // This section defines the module exports and contains exported types that + // are not present in any other React Navigation libdef. + //--------------------------------------------------------------------------- + + /** + * createDrawerNavigator + */ + + declare export var createDrawerNavigator: CreateNavigator< + DrawerNavigationState, + DrawerOptions, + DrawerNavigationEventMap, + ExtraDrawerNavigatorProps, + >; + + /** + * DrawerView + */ + + declare export type DrawerViewProps = {| + ...DrawerNavigationConfig, + ...DrawerNavigationBuilderResult, + |}; + declare export var DrawerView: React$ComponentType; + + /** + * DrawerItem + */ + + declare export type DrawerItemProps = {| + +label: + | string + | ({| +color: string, +focused: boolean |}) => React$Node, + +onPress: () => mixed, + +icon?: ({| + +color: string, + +size: number, + +focused: boolean, + |}) => React$Node, + +to?: string, + +focused?: boolean, + +activeTintColor?: string, + +inactiveTintColor?: string, + +activeBackgroundColor?: string, + +inactiveBackgroundColor?: string, + +labelStyle?: TextStyleProp, + +style?: ViewStyleProp, + |}; + declare export var DrawerItem: React$ComponentType; + + /** + * DrawerItemList + */ + + declare export type DrawerItemListProps = {| + ...DrawerItemListBaseOptions, + ...DrawerNavigationBuilderResult, + |}; + declare export var DrawerItemList: React$ComponentType; + + /** + * DrawerContent + */ + + declare export var DrawerContent: React$ComponentType; + + /** + * DrawerContentScrollView + */ + + declare export var DrawerContentScrollView: React$ComponentType<{ + +children: React$Node, + ... + }>; + + /** + * DrawerGestureContext + */ + + declare type GestureHandlerRef = React$Ref< + React$ComponentType, + >; + declare export var DrawerGestureContext: React$Context; + + /** + * useIsDrawerOpen + */ + + declare export function useIsDrawerOpen(): boolean; + +} diff --git a/flow-typed/npm/@react-navigation/material-top-tabs_v5.x.x.js b/flow-typed/npm/@react-navigation/material-top-tabs_v5.x.x.js new file mode 100644 index 00000000000..7e0fd3de3fb --- /dev/null +++ b/flow-typed/npm/@react-navigation/material-top-tabs_v5.x.x.js @@ -0,0 +1,2046 @@ +// flow-typed signature: 941c2a283a18085d92480b12a9e4c28d +// flow-typed version: 3c17c8ecd5/@react-navigation/material-top-tabs_v5.x.x/flow_>=v0.104.x + +declare module '@react-navigation/material-top-tabs' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + // Vaguely copied from + // react-native/Libraries/Animated/src/animations/Animation.js + declare type EndResult = { finished: boolean, ... }; + declare type EndCallback = (result: EndResult) => void; + declare interface Animation { + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void; + stop(): void; + } + declare type AnimationConfig = { + isInteraction?: boolean, + useNativeDriver: boolean, + onComplete?: ?EndCallback, + iterations?: number, + ... + }; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js + declare interface AnimatedTracking { + constructor( + value: AnimatedValue, + parent: any, + animationClass: any, + animationConfig: Object, + callback?: ?EndCallback, + ): void; + update(): void; + } + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedValue.js + declare type ValueListenerCallback = (state: { value: number, ... }) => void; + declare interface AnimatedValue { + constructor(value: number): void; + setValue(value: number): void; + setOffset(offset: number): void; + flattenOffset(): void; + extractOffset(): void; + addListener(callback: ValueListenerCallback): string; + removeListener(id: string): void; + removeAllListeners(): void; + stopAnimation(callback?: ?(value: number) => void): void; + resetAnimation(callback?: ?(value: number) => void): void; + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + animate(animation: Animation, callback: ?EndCallback): void; + stopTracking(): void; + track(tracking: AnimatedTracking): void; + } + + // Copied from + // react-native/Libraries/Animated/src/animations/TimingAnimation.js + declare type TimingAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + easing?: (value: number) => number, + duration?: number, + delay?: number, + ... + }; + + // Copied from + // react-native/Libraries/Animated/src/animations/SpringAnimation.js + declare type SpringAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + overshootClamping?: boolean, + restDisplacementThreshold?: number, + restSpeedThreshold?: number, + velocity?: number, + bounciness?: number, + speed?: number, + tension?: number, + friction?: number, + stiffness?: number, + damping?: number, + mass?: number, + delay?: number, + ... + }; + + // Copied from react-native/Libraries/Types/CoreEventTypes.js + declare type SyntheticEvent = $ReadOnly<{| + bubbles: ?boolean, + cancelable: ?boolean, + currentTarget: number, + defaultPrevented: ?boolean, + dispatchConfig: $ReadOnly<{| + registrationName: string, + |}>, + eventPhase: ?number, + preventDefault: () => void, + isDefaultPrevented: () => boolean, + stopPropagation: () => void, + isPropagationStopped: () => boolean, + isTrusted: ?boolean, + nativeEvent: T, + persist: () => void, + target: ?number, + timeStamp: number, + type: ?string, + |}>; + declare type Layout = $ReadOnly<{| + x: number, + y: number, + width: number, + height: number, + |}>; + declare type LayoutEvent = SyntheticEvent< + $ReadOnly<{| + layout: Layout, + |}>, + >; + declare type BlurEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type FocusEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type ResponderSyntheticEvent = $ReadOnly<{| + ...SyntheticEvent, + touchHistory: $ReadOnly<{| + indexOfSingleActiveTouch: number, + mostRecentTimeStamp: number, + numberActiveTouches: number, + touchBank: $ReadOnlyArray< + $ReadOnly<{| + touchActive: boolean, + startPageX: number, + startPageY: number, + startTimeStamp: number, + currentPageX: number, + currentPageY: number, + currentTimeStamp: number, + previousPageX: number, + previousPageY: number, + previousTimeStamp: number, + |}>, + >, + |}>, + |}>; + declare type PressEvent = ResponderSyntheticEvent< + $ReadOnly<{| + changedTouches: $ReadOnlyArray<$PropertyType>, + force: number, + identifier: number, + locationX: number, + locationY: number, + pageX: number, + pageY: number, + target: ?number, + timestamp: number, + touches: $ReadOnlyArray<$PropertyType>, + |}>, + >; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js + declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; + declare type InterpolationConfigType = { + inputRange: Array, + outputRange: Array | Array, + easing?: (input: number) => number, + extrapolate?: ExtrapolateType, + extrapolateLeft?: ExtrapolateType, + extrapolateRight?: ExtrapolateType, + ... + }; + declare interface AnimatedInterpolation { + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + } + + // Copied from react-native/Libraries/Components/View/ViewAccessibility.js + declare type AccessibilityRole = + | 'none' + | 'button' + | 'link' + | 'search' + | 'image' + | 'keyboardkey' + | 'text' + | 'adjustable' + | 'imagebutton' + | 'header' + | 'summary' + | 'alert' + | 'checkbox' + | 'combobox' + | 'menu' + | 'menubar' + | 'menuitem' + | 'progressbar' + | 'radio' + | 'radiogroup' + | 'scrollbar' + | 'spinbutton' + | 'switch' + | 'tab' + | 'tablist' + | 'timer' + | 'toolbar'; + declare type AccessibilityActionInfo = $ReadOnly<{ + name: string, + label?: string, + ... + }>; + declare type AccessibilityActionEvent = SyntheticEvent< + $ReadOnly<{actionName: string, ...}>, + >; + declare type AccessibilityState = { + disabled?: boolean, + selected?: boolean, + checked?: ?boolean | 'mixed', + busy?: boolean, + expanded?: boolean, + ... + }; + declare type AccessibilityValue = $ReadOnly<{| + min?: number, + max?: number, + now?: number, + text?: string, + |}>; + + // Copied from + // react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js + declare type Stringish = string; + declare type EdgeInsetsProp = $ReadOnly<$Shape>; + declare type TouchableWithoutFeedbackProps = $ReadOnly<{| + accessibilityActions?: ?$ReadOnlyArray, + accessibilityElementsHidden?: ?boolean, + accessibilityHint?: ?Stringish, + accessibilityIgnoresInvertColors?: ?boolean, + accessibilityLabel?: ?Stringish, + accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), + accessibilityRole?: ?AccessibilityRole, + accessibilityState?: ?AccessibilityState, + accessibilityValue?: ?AccessibilityValue, + accessibilityViewIsModal?: ?boolean, + accessible?: ?boolean, + children?: ?React$Node, + delayLongPress?: ?number, + delayPressIn?: ?number, + delayPressOut?: ?number, + disabled?: ?boolean, + focusable?: ?boolean, + hitSlop?: ?EdgeInsetsProp, + importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), + nativeID?: ?string, + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, + onBlur?: ?(event: BlurEvent) => mixed, + onFocus?: ?(event: FocusEvent) => mixed, + onLayout?: ?(event: LayoutEvent) => mixed, + onLongPress?: ?(event: PressEvent) => mixed, + onPress?: ?(event: PressEvent) => mixed, + onPressIn?: ?(event: PressEvent) => mixed, + onPressOut?: ?(event: PressEvent) => mixed, + pressRetentionOffset?: ?EdgeInsetsProp, + rejectResponderTermination?: ?boolean, + testID?: ?string, + touchSoundDisabled?: ?boolean, + |}>; + + // Copied from react-native/Libraries/Image/ImageSource.js + declare type ImageURISource = $ReadOnly<{ + uri?: ?string, + bundle?: ?string, + method?: ?string, + headers?: ?Object, + body?: ?string, + cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached'), + width?: ?number, + height?: ?number, + scale?: ?number, + ... + }>; + + /** + * The following is copied from react-native-gesture-handler's libdef + */ + + declare type $EventHandlers = {| + onGestureEvent?: ($Event) => mixed, + onHandlerStateChange?: ($Event) => mixed, + onBegan?: ($Event) => mixed, + onFailed?: ($Event) => mixed, + onCancelled?: ($Event) => mixed, + onActivated?: ($Event) => mixed, + onEnded?: ($Event) => mixed, + |}; + + declare type HitSlop = + | number + | {| + left?: number, + top?: number, + right?: number, + bottom?: number, + vertical?: number, + horizontal?: number, + width?: number, + height?: number, + |} + | {| + width: number, + left: number, + |} + | {| + width: number, + right: number, + |} + | {| + height: number, + top: number, + |} + | {| + height: number, + bottom: number, + |}; + + declare type $GestureHandlerProps< + AdditionalProps: {...}, + ExtraEventsProps: {...} + > = $ReadOnly<{| + ...$Exact, + ...$EventHandlers, + id?: string, + enabled?: boolean, + waitFor?: React$Ref | Array>, + simultaneousHandlers?: React$Ref | Array>, + shouldCancelWhenOutside?: boolean, + minPointers?: number, + hitSlop?: HitSlop, + children?: React$Node, + |}>; + + declare type PanGestureHandlerProps = $GestureHandlerProps< + { + activeOffsetY?: number | [number, number], + activeOffsetX?: number | [number, number], + failOffsetY?: number | [number, number], + failOffsetX?: number | [number, number], + minDist?: number, + minVelocity?: number, + minVelocityX?: number, + minVelocityY?: number, + minPointers?: number, + maxPointers?: number, + avgTouches?: boolean, + ... + }, + { + x: number, + y: number, + absoluteX: number, + absoluteY: number, + translationX: number, + translationY: number, + velocityX: number, + velocityY: number, + ... + } + >; + + /** + * MAGIC + */ + + declare type $If = $Call< + ((true, Then, Else) => Then) & ((false, Then, Else) => Else), + Test, + Then, + Else, + >; + declare type $IsA = $Call< + (Y => true) & (mixed => false), + X, + >; + declare type $IsUndefined = $IsA; + + declare type $Partial = $Rest; + + /** + * Actions, state, etc. + */ + + declare export type ScreenParams = { +[key: string]: mixed, ... }; + + declare export type BackAction = {| + +type: 'GO_BACK', + +source?: string, + +target?: string, + |}; + declare export type NavigateAction = {| + +type: 'NAVIGATE', + +payload: + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type ResetAction = {| + +type: 'RESET', + +payload: StaleNavigationState, + +source?: string, + +target?: string, + |}; + declare export type SetParamsAction = {| + +type: 'SET_PARAMS', + +payload: {| +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type CommonAction = + | BackAction + | NavigateAction + | ResetAction + | SetParamsAction; + + declare type NavigateActionCreator = {| + (routeName: string, params?: ScreenParams): NavigateAction, + ( + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + ): NavigateAction, + |}; + declare export type CommonActionsType = {| + +navigate: NavigateActionCreator, + +goBack: () => BackAction, + +reset: (state: PossiblyStaleNavigationState) => ResetAction, + +setParams: (params: ScreenParams) => SetParamsAction, + |}; + + declare export type GenericNavigationAction = {| + +type: string, + +payload?: { +[key: string]: mixed, ... }, + +source?: string, + +target?: string, + |}; + + declare export type LeafRoute = {| + +key: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StateRoute = {| + ...LeafRoute, + +state: NavigationState | StaleNavigationState, + |}; + declare export type Route = + | LeafRoute + | StateRoute; + + declare export type NavigationState = {| + +key: string, + +index: number, + +routeNames: $ReadOnlyArray, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type: string, + +stale: false, + |}; + + declare export type StaleLeafRoute = {| + +key?: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StaleStateRoute = {| + ...StaleLeafRoute, + +state: StaleNavigationState, + |}; + declare export type StaleRoute = + | StaleLeafRoute + | StaleStateRoute; + declare export type StaleNavigationState = {| + // It's possible to pass React Nav a StaleNavigationState with an undefined + // index, but React Nav will always return one with the index set. This is + // the same as for the type property below, but in the case of index we tend + // to rely on it being set more... + +index: number, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type?: string, + +stale?: true, + |}; + + declare export type PossiblyStaleNavigationState = + | NavigationState + | StaleNavigationState; + declare export type PossiblyStaleRoute = + | Route + | StaleRoute; + + /** + * Routers + */ + + declare type ActionCreators< + State: NavigationState, + Action: GenericNavigationAction, + > = { + +[key: string]: (...args: any) => (Action | State => Action), + ... + }; + + declare export type DefaultRouterOptions = { + +initialRouteName?: string, + ... + }; + + declare export type RouterFactory< + State: NavigationState, + Action: GenericNavigationAction, + RouterOptions: DefaultRouterOptions, + > = (options: RouterOptions) => Router; + + declare export type ParamListBase = { +[key: string]: ?ScreenParams, ... }; + + declare export type RouterConfigOptions = {| + +routeNames: $ReadOnlyArray, + +routeParamList: ParamListBase, + |}; + + declare export type Router< + State: NavigationState, + Action: GenericNavigationAction, + > = {| + +type: $PropertyType, + +getInitialState: (options: RouterConfigOptions) => State, + +getRehydratedState: ( + partialState: PossibleStaleNavigationState, + options: RouterConfigOptions, + ) => State, + +getStateForRouteNamesChange: ( + state: State, + options: RouterConfigOptions, + ) => State, + +getStateForRouteFocus: (state: State, key: string) => State, + +getStateForAction: ( + state: State, + action: Action, + options: RouterConfigOptions, + ) => ?PossiblyStaleNavigationState; + +shouldActionChangeFocus: (action: GenericNavigationAction) => boolean, + +actionCreators?: ActionCreators, + |}; + + /** + * Stack actions and router + */ + + declare export type StackNavigationState = {| + ...NavigationState, + +type: 'stack', + |}; + + declare export type ReplaceAction = {| + +type: 'REPLACE', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PushAction = {| + +type: 'PUSH', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PopAction = {| + +type: 'POP', + +payload: {| +count: number |}, + +source?: string, + +target?: string, + |}; + declare export type PopToTopAction = {| + +type: 'POP_TO_TOP', + +source?: string, + +target?: string, + |}; + declare export type StackAction = + | CommonAction + | ReplaceAction + | PushAction + | PopAction + | PopToTopAction; + + declare export type StackActionsType = {| + +replace: (routeName: string, params?: ScreenParams) => ReplaceAction, + +push: (routeName: string, params?: ScreenParams) => PushAction, + +pop: (count?: number) => PopAction, + +popToTop: () => PopToTopAction, + |}; + + declare export type StackRouterOptions = $Exact; + + /** + * Tab actions and router + */ + + declare export type TabNavigationState = {| + ...NavigationState, + +type: 'tab', + +history: $ReadOnlyArray<{| type: 'route', key: string |}>, + |}; + + declare export type JumpToAction = {| + +type: 'JUMP_TO', + +payload: {| +name: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type TabAction = + | CommonAction + | JumpToAction; + + declare export type TabActionsType = {| + +jumpTo: string => JumpToAction, + |}; + + declare export type TabRouterOptions = {| + ...$Exact, + +backBehavior?: 'initialRoute' | 'order' | 'history' | 'none', + |}; + + /** + * Drawer actions and router + */ + + declare type DrawerHistoryEntry = + | {| +type: 'route', +key: string |} + | {| +type: 'drawer' |}; + declare export type DrawerNavigationState = {| + ...NavigationState, + +type: 'drawer', + +history: $ReadOnlyArray, + |}; + + declare export type OpenDrawerAction = {| + +type: 'OPEN_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type CloseDrawerAction = {| + +type: 'CLOSE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type ToggleDrawerAction = {| + +type: 'TOGGLE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type DrawerAction = + | TabAction + | OpenDrawerAction + | CloseDrawerAction + | ToggleDrawerAction; + + declare export type DrawerActionsType = {| + ...TabActionsType, + +openDrawer: () => OpenDrawerAction, + +closeDrawer: () => CloseDrawerAction, + +toggleDrawer: () => ToggleDrawerAction, + |}; + + declare export type DrawerRouterOptions = {| + ...TabRouterOptions, + +openByDefault?: boolean, + |}; + + /** + * Events + */ + + declare export type EventMapBase = { + +[name: string]: {| + +data?: mixed, + +canPreventDefault?: boolean, + |}, + ... + }; + declare type EventPreventDefaultProperties = $If< + Test, + {| +defaultPrevented: boolean, +preventDefault: () => void |}, + {| |}, + >; + declare type EventDataProperties = $If< + $IsUndefined, + {| |}, + {| +data: Data |}, + >; + declare type EventArg< + EventName: string, + CanPreventDefault: ?boolean = false, + Data = void, + > = {| + ...EventPreventDefaultProperties, + ...EventDataProperties, + +type: EventName, + +target?: string, + |}; + declare type GlobalEventMap = {| + +state: {| +data: {| +state: State |}, +canPreventDefault: false |}, + |}; + declare type EventMapCore = {| + ...GlobalEventMap, + +focus: {| +data: void, +canPreventDefault: false |}, + +blur: {| +data: void, +canPreventDefault: false |}, + |}; + declare type EventListenerCallback< + EventName: string, + State: PossiblyStaleNavigationState = NavigationState, + EventMap: EventMapBase = EventMapCore, + > = (e: EventArg< + EventName, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'canPreventDefault', + >, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'data', + >, + >) => mixed; + + /** + * Navigation prop + */ + + declare export type SimpleNavigate = + >( + routeName: DestinationRouteName, + params: $ElementType, + ) => void; + + declare export type Navigate = + & SimpleNavigate + & >( + route: + | {| + key: string, + params?: $ElementType, + |} + | {| + name: DestinationRouteName, + key?: string, + params?: $ElementType, + |}, + ) => void; + + declare type NavigationHelpers< + ParamList: ParamListBase, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + EventMap: EventMapBase = EventMapCore, + > = { + +navigate: Navigate, + +dispatch: ( + action: + | GenericNavigationAction + | (State => GenericNavigationAction), + ) => void, + +reset: PossiblyStaleNavigationState => void, + +goBack: () => void, + +isFocused: () => boolean, + +canGoBack: () => boolean, + +dangerouslyGetParent: >() => ?Parent, + +dangerouslyGetState: () => NavigationState, + +addListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => () => void, + +removeListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => void, + ... + }; + + declare export type NavigationProp< + ParamList: ParamListBase, + RouteName: $Keys = $Keys, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = { + ...$Exact>, + +setOptions: (options: $Shape) => void, + +setParams: ( + params: $If< + $IsUndefined<$ElementType>, + empty, + $Shape<$NonMaybeType<$ElementType>>, + >, + ) => void, + ... + }; + + /** + * CreateNavigator + */ + + declare export type RouteProp< + ParamList: ParamListBase, + RouteName: $Keys, + > = {| + ...LeafRoute, + +params: $ElementType, + |}; + + declare export type ScreenListeners< + EventMap: EventMapBase = EventMapCore, + State: NavigationState = NavigationState, + > = $ObjMapi< + {| [name: $Keys]: empty |}, + >(K, empty) => EventListenerCallback, + >; + + declare type BaseScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = {| + +name: RouteName, + +options?: + | ScreenOptions + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenOptions, + +listeners?: + | ScreenListeners + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenListeners, + +initialParams?: $Shape<$ElementType>, + |}; + + declare export type ScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +component: React$ComponentType<{| + route: RouteProp, + navigation: NavProp, + |}>, + |} + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +children: ({| + route: RouteProp, + navigation: NavProp, + |}) => React$Node, + |}; + + declare export type ScreenComponent< + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = < + RouteName: $Keys, + NavProp: NavigationProp< + GlobalParamList, + RouteName, + State, + ScreenOptions, + EventMap, + >, + >(props: ScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >) => React$Node; + + declare type ScreenOptionsProp = {| + +screenOptions?: + | ScreenOptions + | ({| route: LeafRoute<>, navigation: NavProp |}) => ScreenOptions, + |}; + declare export type ExtraNavigatorPropsBase = { + ...$Exact, + +children?: React$Node, + ... + }; + declare export type NavigatorPropsBase = { + ...$Exact, + ...ScreenOptionsProp, + ... + }; + + declare export type CreateNavigator< + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + > = < + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + NavProp: NavigationHelpers< + GlobalParamList, + State, + EventMap, + >, + >() => {| + +Screen: ScreenComponent< + GlobalParamList, + ParamList, + State, + ScreenOptions, + EventMap, + >, + +Navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + |}; + + declare export type CreateNavigatorFactory = < + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + NavProp: NavigationHelpers< + ParamListBase, + State, + EventMap, + >, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + >( + navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + ) => CreateNavigator; + + /** + * useNavigationBuilder + */ + + declare export type Descriptor< + NavProp, + ScreenOptions: {...} = {...}, + > = {| + +render: () => React$Node, + +options: $ReadOnly, + +navigation: NavProp, + |}; + + declare export type UseNavigationBuilder = < + State: NavigationState, + Action: GenericNavigationAction, + ScreenOptions: {...}, + RouterOptions: DefaultRouterOptions, + NavProp, + >( + routerFactory: RouterFactory, + options: {| + ...$Exact, + ...ScreenOptionsProp, + +children?: React$Node, + |}, + ) => {| + +state: State, + +descriptors: {| +[key: string]: Descriptor |}, + +navigation: NavProp, + |}; + + /** + * EdgeInsets + */ + + declare type EdgeInsets = {| + +top: number, + +right: number, + +bottom: number, + +left: number, + |}; + + /** + * TransitionPreset + */ + + declare export type TransitionSpec = + | {| + animation: 'spring', + config: $Diff< + SpringAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |} + | {| + animation: 'timing', + config: $Diff< + TimingAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |}; + + declare export type StackCardInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +index: number, + +closing: AnimatedInterpolation, + +swiping: AnimatedInterpolation, + +inverted: AnimatedInterpolation, + +layouts: {| + +screen: {| +width: number, +height: number |}, + |}, + +insets: EdgeInsets, + |}; + declare export type StackCardInterpolatedStyle = {| + containerStyle?: AnimatedViewStyleProp, + cardStyle?: AnimatedViewStyleProp, + overlayStyle?: AnimatedViewStyleProp, + shadowStyle?: AnimatedViewStyleProp, + |}; + declare export type StackCardStyleInterpolator = ( + props: StackCardInterpolationProps, + ) => StackCardInterpolatedStyle; + + declare export type StackHeaderInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +layouts: {| + +header: {| +width: number, +height: number |}, + +screen: {| +width: number, +height: number |}, + +title?: {| +width: number, +height: number |}, + +leftLabel?: {| +width: number, +height: number |}, + |}, + |}; + declare export type StackHeaderInterpolatedStyle = {| + leftLabelStyle?: AnimatedViewStyleProp, + leftButtonStyle?: AnimatedViewStyleProp, + rightButtonStyle?: AnimatedViewStyleProp, + titleStyle?: AnimatedViewStyleProp, + backgroundStyle?: AnimatedViewStyleProp, + |}; + declare export type StackHeaderStyleInterpolator = ( + props: StackHeaderInterpolationProps, + ) => StackHeaderInterpolatedStyle; + + declare type GestureDirection = + | 'horizontal' + | 'horizontal-inverted' + | 'vertical' + | 'vertical-inverted'; + + declare export type TransitionPreset = {| + +gestureDirection: GestureDirection, + +transitionSpec: {| + +open: TransitionSpec, + +close: TransitionSpec, + |}, + +cardStyleInterpolator: StackCardStyleInterpolator, + +headerStyleInterpolator: StackHeaderStyleInterpolator, + |}; + + /** + * Stack options + */ + + declare export type StackDescriptor = Descriptor< + StackNavigationProp<>, + StackOptions, + >; + + declare type Scene = {| + +route: T, + +descriptor: StackDescriptor, + +progress: {| + +current: AnimatedInterpolation, + +next?: AnimatedInterpolation, + +previous?: AnimatedInterpolation, + |}, + |}; + + declare export type StackHeaderProps = {| + +mode: 'float' | 'screen', + +layout: {| +width: number, +height: number |}, + +insets: EdgeInsets, + +scene: Scene>, + +previous?: Scene>, + +navigation: StackNavigationProp, + +styleInterpolator: StackHeaderStyleInterpolator, + |}; + + declare export type StackHeaderLeftButtonProps = $Shape<{| + +onPress: (() => void), + +pressColorAndroid: string; + +backImage: (props: {| tintColor: string |}) => React$Node, + +tintColor: string, + +label: string, + +truncatedLabel: string, + +labelVisible: boolean, + +labelStyle: AnimatedTextStyleProp, + +allowFontScaling: boolean, + +onLabelLayout: LayoutEvent => void, + +screenLayout: {| +width: number, +height: number |}, + +titleLayout: {| +width: number, +height: number |}, + +canGoBack: boolean, + |}>; + + declare type StackHeaderTitleInputBase = { + +onLayout: LayoutEvent => void, + +children: string, + +allowFontScaling: ?boolean, + +tintColor: ?string, + +style: ?AnimatedTextStyleProp, + ... + }; + + declare export type StackHeaderTitleInputProps = + $Exact; + + declare export type StackOptions = $Shape<{| + +title: string, + +header: StackHeaderProps => React$Node, + +headerShown: boolean, + +cardShadowEnabled: boolean, + +cardOverlayEnabled: boolean, + +cardOverlay: {| style: ViewStyleProp |} => React$Node, + +cardStyle: ViewStyleProp, + +animationEnabled: boolean, + +animationTypeForReplace: 'push' | 'pop', + +gestureEnabled: boolean, + +gestureResponseDistance: {| vertical?: number, horizontal?: number |}, + +gestureVelocityImpact: number, + +safeAreaInsets: $Shape, + // Transition + ...TransitionPreset, + // Header + +headerTitle: string | (StackHeaderTitleInputProps => React$Node), + +headerTitleAlign: 'left' | 'center', + +headerTitleStyle: AnimatedTextStyleProp, + +headerTitleContainerStyle: ViewStyleProp, + +headerTintColor: string, + +headerTitleAllowFontScaling: boolean, + +headerBackAllowFontScaling: boolean, + +headerBackTitle: string | null, + +headerBackTitleStyle: TextStyleProp, + +headerBackTitleVisible: boolean, + +headerTruncatedBackTitle: string, + +headerLeft: StackHeaderLeftButtonProps => React$Node, + +headerLeftContainerStyle: ViewStyleProp, + +headerRight: {| tintColor?: string |} => React$Node, + +headerRightContainerStyle: ViewStyleProp, + +headerBackImage: $PropertyType, + +headerPressColorAndroid: string, + +headerBackground: ({| style: ViewStyleProp |}) => React$Node, + +headerStyle: ViewStyleProp, + +headerTransparent: boolean, + +headerStatusBarHeight: number, + |}>; + + /** + * Stack navigation prop + */ + + declare export type StackNavigationEventMap = {| + ...EventMapCore, + +transitionStart: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + +transitionEnd: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + |}; + + declare type InexactStackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = { + ...$Exact>, + +replace: SimpleNavigate, + +push: SimpleNavigate, + +pop: (count?: number) => void, + +popToTop: () => void, + ... + }; + + declare export type StackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous stack exports + */ + + declare type StackNavigationConfig = {| + +mode?: 'card' | 'modal', + +headerMode?: 'float' | 'screen' | 'none', + +keyboardHandlingEnabled?: boolean, + |}; + + declare export type ExtraStackNavigatorProps = {| + ...$Exact, + ...StackRouterOptions, + ...StackNavigationConfig, + |}; + + declare export type StackNavigatorProps< + NavProp: InexactStackNavigationProp<> = StackNavigationProp<>, + > = {| + ...ExtraStackNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Bottom tab options + */ + + declare export type BottomTabBarButtonProps = {| + ...$Diff< + TouchableWithoutFeedbackProps, + {| onPress?: ?(event: PressEvent) => mixed |}, + >, + +to?: string, + +children: React$Node, + +onPress?: (MouseEvent | PressEvent) => void, + |}; + + declare export type BottomTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| focused: boolean, color: string |}) => React$Node, + +tabBarIcon: ({| + focused: boolean, + color: string, + size: number, + |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + +tabBarVisible: boolean, + +tabBarButton: BottomTabBarButtonProps => React$Node, + +unmountOnBlur: boolean, + |}>; + + /** + * Bottom tab navigation prop + */ + + declare export type BottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + |}; + + declare type InexactTabNavigationProp< + ParamList: ParamListBase, + RouteName: $Keys, + Options: {...}, + EventMap: EventMapBase, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + ... + }; + + declare export type InexactBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type BottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous bottom tab exports + */ + + declare export type BottomTabDescriptor = Descriptor< + BottomTabNavigationProp<>, + BottomTabOptions, + >; + + declare export type BottomTabBarOptions = $Shape<{| + +keyboardHidesTabBar: boolean, + +activeTintColor: string, + +inactiveTintColor: string, + +activeBackgroundColor: string, + +inactiveBackgroundColor: string, + +allowFontScaling: boolean, + +showLabel: boolean, + +showIcon: boolean, + +labelStyle: TextStyleProp, + +iconStyle: TextStyleProp, + +tabStyle: ViewStyleProp, + +labelPosition: 'beside-icon' | 'below-icon', + +adaptive: boolean, + +safeAreaInsets: $Shape, + +style: ViewStyleProp, + |}>; + + declare type BottomTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: BottomTabNavigationProp<>, + +descriptors: {| +[key: string]: BottomTabDescriptor |}, + |}; + + declare export type BottomTabBarProps = {| + ...BottomTabBarOptions, + ...BottomTabNavigationBuilderResult, + |} + + declare type BottomTabNavigationConfig = {| + +lazy?: boolean, + +tabBar?: BottomTabBarProps => React$Node, + +tabBarOptions?: BottomTabBarOptions, + |}; + + declare export type ExtraBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...BottomTabNavigationConfig, + |}; + + declare export type BottomTabNavigatorProps< + NavProp: InexactBottomTabNavigationProp<> = BottomTabNavigationProp<>, + > = {| + ...ExtraBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material bottom tab options + */ + + declare export type MaterialBottomTabOptions = $Shape<{| + +title: string, + +tabBarColor: string, + +tabBarLabel: string, + +tabBarIcon: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarBadge: boolean | number | string, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material bottom tab navigation prop + */ + + declare export type MaterialBottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + |}; + + declare export type InexactMaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material bottom tab exports + */ + + declare export type PaperFont = {| + +fontFamily: string, + +fontWeight?: + | 'normal' + | 'bold' + | '100' + | '200' + | '300' + | '400' + | '500' + | '600' + | '700' + | '800' + | '900', + |}; + + declare export type PaperFonts = {| + +regular: Font, + +medium: Font, + +light: Font, + +thin: Font, + |}; + + declare export type PaperTheme = {| + +dark: boolean, + +mode?: 'adaptive' | 'exact', + +roundness: number, + +colors: {| + +primary: string, + +background: string, + +surface: string, + +accent: string, + +error: string, + +text: string, + +onSurface: string, + +onBackground: string, + +disabled: string, + +placeholder: string, + +backdrop: string, + +notification: string, + |}, + +fonts: PaperFonts, + +animation: {| + +scale: number, + |}, + |}; + + declare export type PaperRoute = {| + +key: string, + +title?: string, + +icon?: any, + +badge?: string | number | boolean, + +color?: string, + +accessibilityLabel?: string, + +testID?: string, + |}; + + declare export type PaperTouchableProps = {| + ...TouchableWithoutFeedbackProps, + +key: string, + +route: PaperRoute, + +children: React$Node, + +borderless?: boolean, + +centered?: boolean, + +rippleColor?: string, + |}; + + declare export type MaterialBottomTabNavigationConfig = {| + +shifting?: boolean, + +labeled?: boolean, + +renderTouchable?: PaperTouchableProps => React$Node, + +activeColor?: string, + +inactiveColor?: string, + +sceneAnimationEnabled?: boolean, + +keyboardHidesNavigationBar?: boolean, + +barStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +theme?: PaperTheme, + |}; + + declare export type ExtraMaterialBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialBottomTabNavigationConfig, + |}; + + declare export type MaterialBottomTabNavigatorProps< + NavProp: InexactMaterialBottomTabNavigationProp<> = + MaterialBottomTabNavigationProp<>, + > = {| + ...ExtraMaterialBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material top tab options + */ + + declare export type MaterialTopTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarIcon: ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material top tab navigation prop + */ + + declare export type MaterialTopTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + +swipeStart: {| +data: void, +canPreventDefault: false |}, + +swipeEnd: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactMaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material top tab exports + */ + + declare type MaterialTopTabPagerCommonProps = {| + +keyboardDismissMode: 'none' | 'on-drag' | 'auto', + +swipeEnabled: boolean, + +swipeVelocityImpact?: number, + +springVelocityScale?: number, + +springConfig: $Shape<{| + +damping: number, + +mass: number, + +stiffness: number, + +restSpeedThreshold: number, + +restDisplacementThreshold: number, + |}>, + +timingConfig: $Shape<{| + +duration: number, + |}>, + |}; + + declare export type MaterialTopTabPagerProps = {| + ...MaterialTopTabPagerCommonProps, + +onSwipeStart?: () => void, + +onSwipeEnd?: () => void, + +onIndexChange: (index: number) => void, + +navigationState: TabNavigationState, + +layout: {| +width: number, +height: number |}, + +removeClippedSubviews: boolean, + +children: ({| + +addListener: (type: 'enter', listener: number => void) => void, + +removeListener: (type: 'enter', listener: number => void) => void, + +position: any, // Reanimated.Node + +render: React$Node => React$Node, + +jumpTo: string => void, + |}) => React$Node, + +gestureHandlerProps: PanGestureHandlerProps, + |}; + + declare export type MaterialTopTabBarIndicatorProps = {| + +navigationState: TabNavigationState, + +width: string, + +style?: ViewStyleProp, + +getTabWidth: number => number, + |}; + + declare export type MaterialTopTabBarOptions = $Shape<{| + +scrollEnabled: boolean, + +bounces: boolean, + +pressColor: string, + +pressOpacity: number, + +getAccessible: ({| +route: Route<> |}) => boolean, + +renderBadge: ({| +route: Route<> |}) => React$Node, + +renderIndicator: MaterialTopTabBarIndicatorProps => React$Node, + +tabStyle: ViewStyleProp, + +indicatorStyle: ViewStyleProp, + +indicatorContainerStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + +activeTintColor: string, + +inactiveTintColor: string, + +iconStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +showLabel: boolean, + +showIcon: boolean, + +allowFontScaling: boolean, + |}>; + + declare export type MaterialTopTabDescriptor = Descriptor< + MaterialBottomTabNavigationProp<>, + MaterialBottomTabOptions, + >; + + declare type MaterialTopTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: MaterialTopTabNavigationProp<>, + +descriptors: {| +[key: string]: MaterialTopTabDescriptor |}, + |}; + + declare export type MaterialTopTabBarProps = {| + ...MaterialTopTabBarOptions, + ...MaterialTopTabNavigationBuilderResult, + +layout: {| +width: number, +height: number |}, + +position: any, // Reanimated.Node + +jumpTo: string => void, + |}; + + declare export type MaterialTopTabNavigationConfig = {| + ...$Partial, + +position?: any, // Reanimated.Value + +tabBarPosition?: 'top' | 'bottom', + +initialLayout?: $Shape<{| +width: number, +height: number |}>, + +lazy?: boolean, + +lazyPreloadDistance?: number, + +removeClippedSubviews?: boolean, + +sceneContainerStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +gestureHandlerProps?: PanGestureHandlerProps, + +pager?: MaterialTopTabPagerProps => React$Node, + +lazyPlaceholder?: ({| +route: Route<> |}) => React$Node, + +tabBar?: MaterialTopTabBarProps => React$Node, + +tabBarOptions?: MaterialTopTabBarOptions, + |}; + + declare export type ExtraMaterialTopTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialTopTabNavigationConfig, + |}; + + declare export type MaterialTopTabNavigatorProps< + NavProp: InexactMaterialTopTabNavigationProp<> = + MaterialTopTabNavigationProp<>, + > = {| + ...ExtraMaterialTopTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Drawer options + */ + + declare export type DrawerOptions = $Shape<{| + title: string, + drawerLabel: + | string + | ({| +color: string, +focused: boolean |}) => React$Node, + drawerIcon: ({| + +color: string, + +size: number, + +focused: boolean, + |}) => React$Node, + gestureEnabled: boolean, + swipeEnabled: boolean, + unmountOnBlur: boolean, + |}>; + + /** + * Drawer navigation prop + */ + + declare export type DrawerNavigationEventMap = {| + ...EventMapCore, + +drawerOpen: {| +data: void, +canPreventDefault: false |}, + +drawerClose: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactDrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + +openDrawer: () => void, + +closeDrawer: () => void, + +toggleDrawer: () => void, + ... + }; + + declare export type DrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous drawer exports + */ + + declare export type DrawerDescriptor = Descriptor< + DrawerNavigationProp<>, + DrawerOptions, + >; + + declare export type DrawerItemListBaseOptions = $Shape<{| + +activeTintColor: string, + +activeBackgroundColor: string, + +inactiveTintColor: string, + +inactiveBackgroundColor: string, + +itemStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + |}>; + + declare export type DrawerContentOptions = $Shape<{| + ...DrawerItemListBaseOptions, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + |}>; + + declare type DrawerNavigationBuilderResult = {| + +state: DrawerNavigationState, + +navigation: DrawerNavigationProp<>, + +descriptors: {| +[key: string]: DrawerDescriptor |}, + |}; + + declare export type DrawerContentProps = {| + ...DrawerContentOptions, + ...DrawerNavigationBuilderResult, + +progress: any, // Reanimated.Node + |}; + + declare export type DrawerNavigationConfig = {| + +drawerPosition?: 'left' | 'right', + +drawerType?: 'front' | 'back' | 'slide' | 'permanent', + +edgeWidth?: number, + +hideStatusBar?: boolean, + +keyboardDismissMode?: 'on-drag' | 'none', + +minSwipeDistance?: number, + +overlayColor?: string, + +statusBarAnimation?: 'slide' | 'none' | 'fade', + +gestureHandlerProps?: PanGestureHandlerProps, + +lazy?: boolean, + +drawerContent?: DrawerContentProps => React$Node, + +drawerContentOptions?: DrawerContentOptions, + +sceneContainerStyle?: ViewStyleProp, + +drawerStyle?: ViewStyleProp, + |}; + + declare export type ExtraDrawerNavigatorProps = {| + ...$Exact, + ...DrawerRouterOptions, + ...DrawerNavigationConfig, + |}; + + declare export type DrawerNavigatorProps< + NavProp: InexactDrawerNavigationProp<> = DrawerNavigationProp<>, + > = {| + ...ExtraDrawerNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * BaseNavigationContainer + */ + + declare export type BaseNavigationContainerProps = {| + +children: React$Node, + +initialState?: PossiblyStaleNavigationState, + +onStateChange?: (state: ?PossiblyStaleNavigationState) => void, + +independent?: boolean, + |}; + + declare export type ContainerEventMap = {| + ...GlobalEventMap, + +options: {| + +data: {| +options: { +[key: string]: mixed, ... } |}, + +canPreventDefault: false, + |}, + +__unsafe_action__: {| + +data: {| + +action: GenericNavigationAction, + +noop: boolean, + |}, + +canPreventDefault: false, + |}, + |}; + + declare export type BaseNavigationContainerInterface = {| + ...$Exact>, + +setParams: (params: ScreenParams) => void, + +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, + +getRootState: () => PossiblyStaleNavigationState, + |}; + + /** + * State utils + */ + + declare export type GetStateFromPath = ( + path: string, + options?: LinkingConfig, + ) => PossiblyStaleNavigationState; + + declare export type GetPathFromState = ( + state?: ?PossiblyStaleNavigationState, + options?: LinkingConfig, + ) => string; + + declare export type GetFocusedRouteNameFromRoute = + PossiblyStaleRoute => ?string; + + /** + * Linking + */ + + declare export type ScreenLinkingConfig = {| + +path?: string, + +exact?: boolean, + +parse?: {| +[param: string]: string => mixed |}, + +stringify?: {| +[param: string]: mixed => string |}, + +screens?: ScreenLinkingConfigMap, + +initialRouteName?: string, + |}; + + declare export type ScreenLinkingConfigMap = {| + +[routeName: string]: string | ScreenLinkingConfig, + |}; + + declare export type LinkingConfig = {| + +initialRouteName?: string, + +screens: ScreenLinkingConfigMap, + |}; + + declare export type LinkingOptions = {| + +enabled?: boolean, + +prefixes: $ReadOnlyArray, + +config?: LinkingConfig, + +getStateFromPath?: GetStateFromPath, + +getPathFromState?: GetPathFromState, + |}; + + /** + * NavigationContainer + */ + + declare export type Theme = {| + +dark: boolean, + +colors: {| + +primary: string, + +background: string, + +card: string, + +text: string, + +border: string, + |}, + |}; + + declare export type NavigationContainerType = React$AbstractComponent< + {| + ...BaseNavigationContainerProps, + +theme?: Theme, + +linking?: LinkingOptions, + +fallback?: React$Node, + +onReady?: () => mixed, + |}, + BaseNavigationContainerInterface, + >; + + //--------------------------------------------------------------------------- + // SECTION 2: EXPORTED MODULE + // This section defines the module exports and contains exported types that + // are not present in any other React Navigation libdef. + //--------------------------------------------------------------------------- + + /** + * createMaterialTopTabNavigator + */ + + declare export var createMaterialTopTabNavigator: CreateNavigator< + TabNavigationState, + MaterialTopTabOptions, + MaterialTopTabNavigationEventMap, + ExtraMaterialTopTabNavigatorProps, + >; + + /** + * MaterialTopTabView + */ + + declare export type MaterialTopTabViewProps = {| + ...MaterialTopTabNavigationConfig, + ...MaterialTopTabNavigationBuilderResult, + |}; + declare export var MaterialTopTabView: React$ComponentType< + MaterialTopTabViewProps, + >; + + /** + * MaterialTopTabBar + */ + + declare export var MaterialTopTabBar: React$ComponentType< + MaterialTopTabBarProps, + >; + +} diff --git a/flow-typed/npm/@react-navigation/native_v5.x.x.js b/flow-typed/npm/@react-navigation/native_v5.x.x.js new file mode 100644 index 00000000000..09e5b4da735 --- /dev/null +++ b/flow-typed/npm/@react-navigation/native_v5.x.x.js @@ -0,0 +1,2183 @@ +// flow-typed signature: 2c957c911a30440cb9ce08a7862e8731 +// flow-typed version: 3c17c8ecd5/@react-navigation/native_v5.x.x/flow_>=v0.104.x + +declare module '@react-navigation/native' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + // Vaguely copied from + // react-native/Libraries/Animated/src/animations/Animation.js + declare type EndResult = { finished: boolean, ... }; + declare type EndCallback = (result: EndResult) => void; + declare interface Animation { + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void; + stop(): void; + } + declare type AnimationConfig = { + isInteraction?: boolean, + useNativeDriver: boolean, + onComplete?: ?EndCallback, + iterations?: number, + ... + }; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js + declare interface AnimatedTracking { + constructor( + value: AnimatedValue, + parent: any, + animationClass: any, + animationConfig: Object, + callback?: ?EndCallback, + ): void; + update(): void; + } + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedValue.js + declare type ValueListenerCallback = (state: { value: number, ... }) => void; + declare interface AnimatedValue { + constructor(value: number): void; + setValue(value: number): void; + setOffset(offset: number): void; + flattenOffset(): void; + extractOffset(): void; + addListener(callback: ValueListenerCallback): string; + removeListener(id: string): void; + removeAllListeners(): void; + stopAnimation(callback?: ?(value: number) => void): void; + resetAnimation(callback?: ?(value: number) => void): void; + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + animate(animation: Animation, callback: ?EndCallback): void; + stopTracking(): void; + track(tracking: AnimatedTracking): void; + } + + // Copied from + // react-native/Libraries/Animated/src/animations/TimingAnimation.js + declare type TimingAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + easing?: (value: number) => number, + duration?: number, + delay?: number, + ... + }; + + // Copied from + // react-native/Libraries/Animated/src/animations/SpringAnimation.js + declare type SpringAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + overshootClamping?: boolean, + restDisplacementThreshold?: number, + restSpeedThreshold?: number, + velocity?: number, + bounciness?: number, + speed?: number, + tension?: number, + friction?: number, + stiffness?: number, + damping?: number, + mass?: number, + delay?: number, + ... + }; + + // Copied from react-native/Libraries/Types/CoreEventTypes.js + declare type SyntheticEvent = $ReadOnly<{| + bubbles: ?boolean, + cancelable: ?boolean, + currentTarget: number, + defaultPrevented: ?boolean, + dispatchConfig: $ReadOnly<{| + registrationName: string, + |}>, + eventPhase: ?number, + preventDefault: () => void, + isDefaultPrevented: () => boolean, + stopPropagation: () => void, + isPropagationStopped: () => boolean, + isTrusted: ?boolean, + nativeEvent: T, + persist: () => void, + target: ?number, + timeStamp: number, + type: ?string, + |}>; + declare type Layout = $ReadOnly<{| + x: number, + y: number, + width: number, + height: number, + |}>; + declare type LayoutEvent = SyntheticEvent< + $ReadOnly<{| + layout: Layout, + |}>, + >; + declare type BlurEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type FocusEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type ResponderSyntheticEvent = $ReadOnly<{| + ...SyntheticEvent, + touchHistory: $ReadOnly<{| + indexOfSingleActiveTouch: number, + mostRecentTimeStamp: number, + numberActiveTouches: number, + touchBank: $ReadOnlyArray< + $ReadOnly<{| + touchActive: boolean, + startPageX: number, + startPageY: number, + startTimeStamp: number, + currentPageX: number, + currentPageY: number, + currentTimeStamp: number, + previousPageX: number, + previousPageY: number, + previousTimeStamp: number, + |}>, + >, + |}>, + |}>; + declare type PressEvent = ResponderSyntheticEvent< + $ReadOnly<{| + changedTouches: $ReadOnlyArray<$PropertyType>, + force: number, + identifier: number, + locationX: number, + locationY: number, + pageX: number, + pageY: number, + target: ?number, + timestamp: number, + touches: $ReadOnlyArray<$PropertyType>, + |}>, + >; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js + declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; + declare type InterpolationConfigType = { + inputRange: Array, + outputRange: Array | Array, + easing?: (input: number) => number, + extrapolate?: ExtrapolateType, + extrapolateLeft?: ExtrapolateType, + extrapolateRight?: ExtrapolateType, + ... + }; + declare interface AnimatedInterpolation { + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + } + + // Copied from react-native/Libraries/Components/View/ViewAccessibility.js + declare type AccessibilityRole = + | 'none' + | 'button' + | 'link' + | 'search' + | 'image' + | 'keyboardkey' + | 'text' + | 'adjustable' + | 'imagebutton' + | 'header' + | 'summary' + | 'alert' + | 'checkbox' + | 'combobox' + | 'menu' + | 'menubar' + | 'menuitem' + | 'progressbar' + | 'radio' + | 'radiogroup' + | 'scrollbar' + | 'spinbutton' + | 'switch' + | 'tab' + | 'tablist' + | 'timer' + | 'toolbar'; + declare type AccessibilityActionInfo = $ReadOnly<{ + name: string, + label?: string, + ... + }>; + declare type AccessibilityActionEvent = SyntheticEvent< + $ReadOnly<{actionName: string, ...}>, + >; + declare type AccessibilityState = { + disabled?: boolean, + selected?: boolean, + checked?: ?boolean | 'mixed', + busy?: boolean, + expanded?: boolean, + ... + }; + declare type AccessibilityValue = $ReadOnly<{| + min?: number, + max?: number, + now?: number, + text?: string, + |}>; + + // Copied from + // react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js + declare type Stringish = string; + declare type EdgeInsetsProp = $ReadOnly<$Shape>; + declare type TouchableWithoutFeedbackProps = $ReadOnly<{| + accessibilityActions?: ?$ReadOnlyArray, + accessibilityElementsHidden?: ?boolean, + accessibilityHint?: ?Stringish, + accessibilityIgnoresInvertColors?: ?boolean, + accessibilityLabel?: ?Stringish, + accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), + accessibilityRole?: ?AccessibilityRole, + accessibilityState?: ?AccessibilityState, + accessibilityValue?: ?AccessibilityValue, + accessibilityViewIsModal?: ?boolean, + accessible?: ?boolean, + children?: ?React$Node, + delayLongPress?: ?number, + delayPressIn?: ?number, + delayPressOut?: ?number, + disabled?: ?boolean, + focusable?: ?boolean, + hitSlop?: ?EdgeInsetsProp, + importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), + nativeID?: ?string, + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, + onBlur?: ?(event: BlurEvent) => mixed, + onFocus?: ?(event: FocusEvent) => mixed, + onLayout?: ?(event: LayoutEvent) => mixed, + onLongPress?: ?(event: PressEvent) => mixed, + onPress?: ?(event: PressEvent) => mixed, + onPressIn?: ?(event: PressEvent) => mixed, + onPressOut?: ?(event: PressEvent) => mixed, + pressRetentionOffset?: ?EdgeInsetsProp, + rejectResponderTermination?: ?boolean, + testID?: ?string, + touchSoundDisabled?: ?boolean, + |}>; + + // Copied from react-native/Libraries/Image/ImageSource.js + declare type ImageURISource = $ReadOnly<{ + uri?: ?string, + bundle?: ?string, + method?: ?string, + headers?: ?Object, + body?: ?string, + cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached'), + width?: ?number, + height?: ?number, + scale?: ?number, + ... + }>; + + /** + * The following is copied from react-native-gesture-handler's libdef + */ + + declare type $EventHandlers = {| + onGestureEvent?: ($Event) => mixed, + onHandlerStateChange?: ($Event) => mixed, + onBegan?: ($Event) => mixed, + onFailed?: ($Event) => mixed, + onCancelled?: ($Event) => mixed, + onActivated?: ($Event) => mixed, + onEnded?: ($Event) => mixed, + |}; + + declare type HitSlop = + | number + | {| + left?: number, + top?: number, + right?: number, + bottom?: number, + vertical?: number, + horizontal?: number, + width?: number, + height?: number, + |} + | {| + width: number, + left: number, + |} + | {| + width: number, + right: number, + |} + | {| + height: number, + top: number, + |} + | {| + height: number, + bottom: number, + |}; + + declare type $GestureHandlerProps< + AdditionalProps: {...}, + ExtraEventsProps: {...} + > = $ReadOnly<{| + ...$Exact, + ...$EventHandlers, + id?: string, + enabled?: boolean, + waitFor?: React$Ref | Array>, + simultaneousHandlers?: React$Ref | Array>, + shouldCancelWhenOutside?: boolean, + minPointers?: number, + hitSlop?: HitSlop, + children?: React$Node, + |}>; + + declare type PanGestureHandlerProps = $GestureHandlerProps< + { + activeOffsetY?: number | [number, number], + activeOffsetX?: number | [number, number], + failOffsetY?: number | [number, number], + failOffsetX?: number | [number, number], + minDist?: number, + minVelocity?: number, + minVelocityX?: number, + minVelocityY?: number, + minPointers?: number, + maxPointers?: number, + avgTouches?: boolean, + ... + }, + { + x: number, + y: number, + absoluteX: number, + absoluteY: number, + translationX: number, + translationY: number, + velocityX: number, + velocityY: number, + ... + } + >; + + /** + * MAGIC + */ + + declare type $If = $Call< + ((true, Then, Else) => Then) & ((false, Then, Else) => Else), + Test, + Then, + Else, + >; + declare type $IsA = $Call< + (Y => true) & (mixed => false), + X, + >; + declare type $IsUndefined = $IsA; + + declare type $Partial = $Rest; + + /** + * Actions, state, etc. + */ + + declare export type ScreenParams = { +[key: string]: mixed, ... }; + + declare export type BackAction = {| + +type: 'GO_BACK', + +source?: string, + +target?: string, + |}; + declare export type NavigateAction = {| + +type: 'NAVIGATE', + +payload: + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type ResetAction = {| + +type: 'RESET', + +payload: StaleNavigationState, + +source?: string, + +target?: string, + |}; + declare export type SetParamsAction = {| + +type: 'SET_PARAMS', + +payload: {| +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type CommonAction = + | BackAction + | NavigateAction + | ResetAction + | SetParamsAction; + + declare type NavigateActionCreator = {| + (routeName: string, params?: ScreenParams): NavigateAction, + ( + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + ): NavigateAction, + |}; + declare export type CommonActionsType = {| + +navigate: NavigateActionCreator, + +goBack: () => BackAction, + +reset: (state: PossiblyStaleNavigationState) => ResetAction, + +setParams: (params: ScreenParams) => SetParamsAction, + |}; + + declare export type GenericNavigationAction = {| + +type: string, + +payload?: { +[key: string]: mixed, ... }, + +source?: string, + +target?: string, + |}; + + declare export type LeafRoute = {| + +key: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StateRoute = {| + ...LeafRoute, + +state: NavigationState | StaleNavigationState, + |}; + declare export type Route = + | LeafRoute + | StateRoute; + + declare export type NavigationState = {| + +key: string, + +index: number, + +routeNames: $ReadOnlyArray, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type: string, + +stale: false, + |}; + + declare export type StaleLeafRoute = {| + +key?: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StaleStateRoute = {| + ...StaleLeafRoute, + +state: StaleNavigationState, + |}; + declare export type StaleRoute = + | StaleLeafRoute + | StaleStateRoute; + declare export type StaleNavigationState = {| + // It's possible to pass React Nav a StaleNavigationState with an undefined + // index, but React Nav will always return one with the index set. This is + // the same as for the type property below, but in the case of index we tend + // to rely on it being set more... + +index: number, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type?: string, + +stale?: true, + |}; + + declare export type PossiblyStaleNavigationState = + | NavigationState + | StaleNavigationState; + declare export type PossiblyStaleRoute = + | Route + | StaleRoute; + + /** + * Routers + */ + + declare type ActionCreators< + State: NavigationState, + Action: GenericNavigationAction, + > = { + +[key: string]: (...args: any) => (Action | State => Action), + ... + }; + + declare export type DefaultRouterOptions = { + +initialRouteName?: string, + ... + }; + + declare export type RouterFactory< + State: NavigationState, + Action: GenericNavigationAction, + RouterOptions: DefaultRouterOptions, + > = (options: RouterOptions) => Router; + + declare export type ParamListBase = { +[key: string]: ?ScreenParams, ... }; + + declare export type RouterConfigOptions = {| + +routeNames: $ReadOnlyArray, + +routeParamList: ParamListBase, + |}; + + declare export type Router< + State: NavigationState, + Action: GenericNavigationAction, + > = {| + +type: $PropertyType, + +getInitialState: (options: RouterConfigOptions) => State, + +getRehydratedState: ( + partialState: PossibleStaleNavigationState, + options: RouterConfigOptions, + ) => State, + +getStateForRouteNamesChange: ( + state: State, + options: RouterConfigOptions, + ) => State, + +getStateForRouteFocus: (state: State, key: string) => State, + +getStateForAction: ( + state: State, + action: Action, + options: RouterConfigOptions, + ) => ?PossiblyStaleNavigationState; + +shouldActionChangeFocus: (action: GenericNavigationAction) => boolean, + +actionCreators?: ActionCreators, + |}; + + /** + * Stack actions and router + */ + + declare export type StackNavigationState = {| + ...NavigationState, + +type: 'stack', + |}; + + declare export type ReplaceAction = {| + +type: 'REPLACE', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PushAction = {| + +type: 'PUSH', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PopAction = {| + +type: 'POP', + +payload: {| +count: number |}, + +source?: string, + +target?: string, + |}; + declare export type PopToTopAction = {| + +type: 'POP_TO_TOP', + +source?: string, + +target?: string, + |}; + declare export type StackAction = + | CommonAction + | ReplaceAction + | PushAction + | PopAction + | PopToTopAction; + + declare export type StackActionsType = {| + +replace: (routeName: string, params?: ScreenParams) => ReplaceAction, + +push: (routeName: string, params?: ScreenParams) => PushAction, + +pop: (count?: number) => PopAction, + +popToTop: () => PopToTopAction, + |}; + + declare export type StackRouterOptions = $Exact; + + /** + * Tab actions and router + */ + + declare export type TabNavigationState = {| + ...NavigationState, + +type: 'tab', + +history: $ReadOnlyArray<{| type: 'route', key: string |}>, + |}; + + declare export type JumpToAction = {| + +type: 'JUMP_TO', + +payload: {| +name: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type TabAction = + | CommonAction + | JumpToAction; + + declare export type TabActionsType = {| + +jumpTo: string => JumpToAction, + |}; + + declare export type TabRouterOptions = {| + ...$Exact, + +backBehavior?: 'initialRoute' | 'order' | 'history' | 'none', + |}; + + /** + * Drawer actions and router + */ + + declare type DrawerHistoryEntry = + | {| +type: 'route', +key: string |} + | {| +type: 'drawer' |}; + declare export type DrawerNavigationState = {| + ...NavigationState, + +type: 'drawer', + +history: $ReadOnlyArray, + |}; + + declare export type OpenDrawerAction = {| + +type: 'OPEN_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type CloseDrawerAction = {| + +type: 'CLOSE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type ToggleDrawerAction = {| + +type: 'TOGGLE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type DrawerAction = + | TabAction + | OpenDrawerAction + | CloseDrawerAction + | ToggleDrawerAction; + + declare export type DrawerActionsType = {| + ...TabActionsType, + +openDrawer: () => OpenDrawerAction, + +closeDrawer: () => CloseDrawerAction, + +toggleDrawer: () => ToggleDrawerAction, + |}; + + declare export type DrawerRouterOptions = {| + ...TabRouterOptions, + +openByDefault?: boolean, + |}; + + /** + * Events + */ + + declare export type EventMapBase = { + +[name: string]: {| + +data?: mixed, + +canPreventDefault?: boolean, + |}, + ... + }; + declare type EventPreventDefaultProperties = $If< + Test, + {| +defaultPrevented: boolean, +preventDefault: () => void |}, + {| |}, + >; + declare type EventDataProperties = $If< + $IsUndefined, + {| |}, + {| +data: Data |}, + >; + declare type EventArg< + EventName: string, + CanPreventDefault: ?boolean = false, + Data = void, + > = {| + ...EventPreventDefaultProperties, + ...EventDataProperties, + +type: EventName, + +target?: string, + |}; + declare type GlobalEventMap = {| + +state: {| +data: {| +state: State |}, +canPreventDefault: false |}, + |}; + declare type EventMapCore = {| + ...GlobalEventMap, + +focus: {| +data: void, +canPreventDefault: false |}, + +blur: {| +data: void, +canPreventDefault: false |}, + |}; + declare type EventListenerCallback< + EventName: string, + State: PossiblyStaleNavigationState = NavigationState, + EventMap: EventMapBase = EventMapCore, + > = (e: EventArg< + EventName, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'canPreventDefault', + >, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'data', + >, + >) => mixed; + + /** + * Navigation prop + */ + + declare export type SimpleNavigate = + >( + routeName: DestinationRouteName, + params: $ElementType, + ) => void; + + declare export type Navigate = + & SimpleNavigate + & >( + route: + | {| + key: string, + params?: $ElementType, + |} + | {| + name: DestinationRouteName, + key?: string, + params?: $ElementType, + |}, + ) => void; + + declare type NavigationHelpers< + ParamList: ParamListBase, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + EventMap: EventMapBase = EventMapCore, + > = { + +navigate: Navigate, + +dispatch: ( + action: + | GenericNavigationAction + | (State => GenericNavigationAction), + ) => void, + +reset: PossiblyStaleNavigationState => void, + +goBack: () => void, + +isFocused: () => boolean, + +canGoBack: () => boolean, + +dangerouslyGetParent: >() => ?Parent, + +dangerouslyGetState: () => NavigationState, + +addListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => () => void, + +removeListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => void, + ... + }; + + declare export type NavigationProp< + ParamList: ParamListBase, + RouteName: $Keys = $Keys, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = { + ...$Exact>, + +setOptions: (options: $Shape) => void, + +setParams: ( + params: $If< + $IsUndefined<$ElementType>, + empty, + $Shape<$NonMaybeType<$ElementType>>, + >, + ) => void, + ... + }; + + /** + * CreateNavigator + */ + + declare export type RouteProp< + ParamList: ParamListBase, + RouteName: $Keys, + > = {| + ...LeafRoute, + +params: $ElementType, + |}; + + declare export type ScreenListeners< + EventMap: EventMapBase = EventMapCore, + State: NavigationState = NavigationState, + > = $ObjMapi< + {| [name: $Keys]: empty |}, + >(K, empty) => EventListenerCallback, + >; + + declare type BaseScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = {| + +name: RouteName, + +options?: + | ScreenOptions + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenOptions, + +listeners?: + | ScreenListeners + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenListeners, + +initialParams?: $Shape<$ElementType>, + |}; + + declare export type ScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +component: React$ComponentType<{| + route: RouteProp, + navigation: NavProp, + |}>, + |} + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +children: ({| + route: RouteProp, + navigation: NavProp, + |}) => React$Node, + |}; + + declare export type ScreenComponent< + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = < + RouteName: $Keys, + NavProp: NavigationProp< + GlobalParamList, + RouteName, + State, + ScreenOptions, + EventMap, + >, + >(props: ScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >) => React$Node; + + declare type ScreenOptionsProp = {| + +screenOptions?: + | ScreenOptions + | ({| route: LeafRoute<>, navigation: NavProp |}) => ScreenOptions, + |}; + declare export type ExtraNavigatorPropsBase = { + ...$Exact, + +children?: React$Node, + ... + }; + declare export type NavigatorPropsBase = { + ...$Exact, + ...ScreenOptionsProp, + ... + }; + + declare export type CreateNavigator< + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + > = < + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + NavProp: NavigationHelpers< + GlobalParamList, + State, + EventMap, + >, + >() => {| + +Screen: ScreenComponent< + GlobalParamList, + ParamList, + State, + ScreenOptions, + EventMap, + >, + +Navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + |}; + + declare export type CreateNavigatorFactory = < + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + NavProp: NavigationHelpers< + ParamListBase, + State, + EventMap, + >, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + >( + navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + ) => CreateNavigator; + + /** + * useNavigationBuilder + */ + + declare export type Descriptor< + NavProp, + ScreenOptions: {...} = {...}, + > = {| + +render: () => React$Node, + +options: $ReadOnly, + +navigation: NavProp, + |}; + + declare export type UseNavigationBuilder = < + State: NavigationState, + Action: GenericNavigationAction, + ScreenOptions: {...}, + RouterOptions: DefaultRouterOptions, + NavProp, + >( + routerFactory: RouterFactory, + options: {| + ...$Exact, + ...ScreenOptionsProp, + +children?: React$Node, + |}, + ) => {| + +state: State, + +descriptors: {| +[key: string]: Descriptor |}, + +navigation: NavProp, + |}; + + /** + * EdgeInsets + */ + + declare type EdgeInsets = {| + +top: number, + +right: number, + +bottom: number, + +left: number, + |}; + + /** + * TransitionPreset + */ + + declare export type TransitionSpec = + | {| + animation: 'spring', + config: $Diff< + SpringAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |} + | {| + animation: 'timing', + config: $Diff< + TimingAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |}; + + declare export type StackCardInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +index: number, + +closing: AnimatedInterpolation, + +swiping: AnimatedInterpolation, + +inverted: AnimatedInterpolation, + +layouts: {| + +screen: {| +width: number, +height: number |}, + |}, + +insets: EdgeInsets, + |}; + declare export type StackCardInterpolatedStyle = {| + containerStyle?: AnimatedViewStyleProp, + cardStyle?: AnimatedViewStyleProp, + overlayStyle?: AnimatedViewStyleProp, + shadowStyle?: AnimatedViewStyleProp, + |}; + declare export type StackCardStyleInterpolator = ( + props: StackCardInterpolationProps, + ) => StackCardInterpolatedStyle; + + declare export type StackHeaderInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +layouts: {| + +header: {| +width: number, +height: number |}, + +screen: {| +width: number, +height: number |}, + +title?: {| +width: number, +height: number |}, + +leftLabel?: {| +width: number, +height: number |}, + |}, + |}; + declare export type StackHeaderInterpolatedStyle = {| + leftLabelStyle?: AnimatedViewStyleProp, + leftButtonStyle?: AnimatedViewStyleProp, + rightButtonStyle?: AnimatedViewStyleProp, + titleStyle?: AnimatedViewStyleProp, + backgroundStyle?: AnimatedViewStyleProp, + |}; + declare export type StackHeaderStyleInterpolator = ( + props: StackHeaderInterpolationProps, + ) => StackHeaderInterpolatedStyle; + + declare type GestureDirection = + | 'horizontal' + | 'horizontal-inverted' + | 'vertical' + | 'vertical-inverted'; + + declare export type TransitionPreset = {| + +gestureDirection: GestureDirection, + +transitionSpec: {| + +open: TransitionSpec, + +close: TransitionSpec, + |}, + +cardStyleInterpolator: StackCardStyleInterpolator, + +headerStyleInterpolator: StackHeaderStyleInterpolator, + |}; + + /** + * Stack options + */ + + declare export type StackDescriptor = Descriptor< + StackNavigationProp<>, + StackOptions, + >; + + declare type Scene = {| + +route: T, + +descriptor: StackDescriptor, + +progress: {| + +current: AnimatedInterpolation, + +next?: AnimatedInterpolation, + +previous?: AnimatedInterpolation, + |}, + |}; + + declare export type StackHeaderProps = {| + +mode: 'float' | 'screen', + +layout: {| +width: number, +height: number |}, + +insets: EdgeInsets, + +scene: Scene>, + +previous?: Scene>, + +navigation: StackNavigationProp, + +styleInterpolator: StackHeaderStyleInterpolator, + |}; + + declare export type StackHeaderLeftButtonProps = $Shape<{| + +onPress: (() => void), + +pressColorAndroid: string; + +backImage: (props: {| tintColor: string |}) => React$Node, + +tintColor: string, + +label: string, + +truncatedLabel: string, + +labelVisible: boolean, + +labelStyle: AnimatedTextStyleProp, + +allowFontScaling: boolean, + +onLabelLayout: LayoutEvent => void, + +screenLayout: {| +width: number, +height: number |}, + +titleLayout: {| +width: number, +height: number |}, + +canGoBack: boolean, + |}>; + + declare type StackHeaderTitleInputBase = { + +onLayout: LayoutEvent => void, + +children: string, + +allowFontScaling: ?boolean, + +tintColor: ?string, + +style: ?AnimatedTextStyleProp, + ... + }; + + declare export type StackHeaderTitleInputProps = + $Exact; + + declare export type StackOptions = $Shape<{| + +title: string, + +header: StackHeaderProps => React$Node, + +headerShown: boolean, + +cardShadowEnabled: boolean, + +cardOverlayEnabled: boolean, + +cardOverlay: {| style: ViewStyleProp |} => React$Node, + +cardStyle: ViewStyleProp, + +animationEnabled: boolean, + +animationTypeForReplace: 'push' | 'pop', + +gestureEnabled: boolean, + +gestureResponseDistance: {| vertical?: number, horizontal?: number |}, + +gestureVelocityImpact: number, + +safeAreaInsets: $Shape, + // Transition + ...TransitionPreset, + // Header + +headerTitle: string | (StackHeaderTitleInputProps => React$Node), + +headerTitleAlign: 'left' | 'center', + +headerTitleStyle: AnimatedTextStyleProp, + +headerTitleContainerStyle: ViewStyleProp, + +headerTintColor: string, + +headerTitleAllowFontScaling: boolean, + +headerBackAllowFontScaling: boolean, + +headerBackTitle: string | null, + +headerBackTitleStyle: TextStyleProp, + +headerBackTitleVisible: boolean, + +headerTruncatedBackTitle: string, + +headerLeft: StackHeaderLeftButtonProps => React$Node, + +headerLeftContainerStyle: ViewStyleProp, + +headerRight: {| tintColor?: string |} => React$Node, + +headerRightContainerStyle: ViewStyleProp, + +headerBackImage: $PropertyType, + +headerPressColorAndroid: string, + +headerBackground: ({| style: ViewStyleProp |}) => React$Node, + +headerStyle: ViewStyleProp, + +headerTransparent: boolean, + +headerStatusBarHeight: number, + |}>; + + /** + * Stack navigation prop + */ + + declare export type StackNavigationEventMap = {| + ...EventMapCore, + +transitionStart: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + +transitionEnd: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + |}; + + declare type InexactStackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = { + ...$Exact>, + +replace: SimpleNavigate, + +push: SimpleNavigate, + +pop: (count?: number) => void, + +popToTop: () => void, + ... + }; + + declare export type StackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous stack exports + */ + + declare type StackNavigationConfig = {| + +mode?: 'card' | 'modal', + +headerMode?: 'float' | 'screen' | 'none', + +keyboardHandlingEnabled?: boolean, + |}; + + declare export type ExtraStackNavigatorProps = {| + ...$Exact, + ...StackRouterOptions, + ...StackNavigationConfig, + |}; + + declare export type StackNavigatorProps< + NavProp: InexactStackNavigationProp<> = StackNavigationProp<>, + > = {| + ...ExtraStackNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Bottom tab options + */ + + declare export type BottomTabBarButtonProps = {| + ...$Diff< + TouchableWithoutFeedbackProps, + {| onPress?: ?(event: PressEvent) => mixed |}, + >, + +to?: string, + +children: React$Node, + +onPress?: (MouseEvent | PressEvent) => void, + |}; + + declare export type BottomTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| focused: boolean, color: string |}) => React$Node, + +tabBarIcon: ({| + focused: boolean, + color: string, + size: number, + |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + +tabBarVisible: boolean, + +tabBarButton: BottomTabBarButtonProps => React$Node, + +unmountOnBlur: boolean, + |}>; + + /** + * Bottom tab navigation prop + */ + + declare export type BottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + |}; + + declare type InexactTabNavigationProp< + ParamList: ParamListBase, + RouteName: $Keys, + Options: {...}, + EventMap: EventMapBase, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + ... + }; + + declare export type InexactBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type BottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous bottom tab exports + */ + + declare export type BottomTabDescriptor = Descriptor< + BottomTabNavigationProp<>, + BottomTabOptions, + >; + + declare export type BottomTabBarOptions = $Shape<{| + +keyboardHidesTabBar: boolean, + +activeTintColor: string, + +inactiveTintColor: string, + +activeBackgroundColor: string, + +inactiveBackgroundColor: string, + +allowFontScaling: boolean, + +showLabel: boolean, + +showIcon: boolean, + +labelStyle: TextStyleProp, + +iconStyle: TextStyleProp, + +tabStyle: ViewStyleProp, + +labelPosition: 'beside-icon' | 'below-icon', + +adaptive: boolean, + +safeAreaInsets: $Shape, + +style: ViewStyleProp, + |}>; + + declare type BottomTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: BottomTabNavigationProp<>, + +descriptors: {| +[key: string]: BottomTabDescriptor |}, + |}; + + declare export type BottomTabBarProps = {| + ...BottomTabBarOptions, + ...BottomTabNavigationBuilderResult, + |} + + declare type BottomTabNavigationConfig = {| + +lazy?: boolean, + +tabBar?: BottomTabBarProps => React$Node, + +tabBarOptions?: BottomTabBarOptions, + |}; + + declare export type ExtraBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...BottomTabNavigationConfig, + |}; + + declare export type BottomTabNavigatorProps< + NavProp: InexactBottomTabNavigationProp<> = BottomTabNavigationProp<>, + > = {| + ...ExtraBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material bottom tab options + */ + + declare export type MaterialBottomTabOptions = $Shape<{| + +title: string, + +tabBarColor: string, + +tabBarLabel: string, + +tabBarIcon: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarBadge: boolean | number | string, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material bottom tab navigation prop + */ + + declare export type MaterialBottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + |}; + + declare export type InexactMaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material bottom tab exports + */ + + declare export type PaperFont = {| + +fontFamily: string, + +fontWeight?: + | 'normal' + | 'bold' + | '100' + | '200' + | '300' + | '400' + | '500' + | '600' + | '700' + | '800' + | '900', + |}; + + declare export type PaperFonts = {| + +regular: Font, + +medium: Font, + +light: Font, + +thin: Font, + |}; + + declare export type PaperTheme = {| + +dark: boolean, + +mode?: 'adaptive' | 'exact', + +roundness: number, + +colors: {| + +primary: string, + +background: string, + +surface: string, + +accent: string, + +error: string, + +text: string, + +onSurface: string, + +onBackground: string, + +disabled: string, + +placeholder: string, + +backdrop: string, + +notification: string, + |}, + +fonts: PaperFonts, + +animation: {| + +scale: number, + |}, + |}; + + declare export type PaperRoute = {| + +key: string, + +title?: string, + +icon?: any, + +badge?: string | number | boolean, + +color?: string, + +accessibilityLabel?: string, + +testID?: string, + |}; + + declare export type PaperTouchableProps = {| + ...TouchableWithoutFeedbackProps, + +key: string, + +route: PaperRoute, + +children: React$Node, + +borderless?: boolean, + +centered?: boolean, + +rippleColor?: string, + |}; + + declare export type MaterialBottomTabNavigationConfig = {| + +shifting?: boolean, + +labeled?: boolean, + +renderTouchable?: PaperTouchableProps => React$Node, + +activeColor?: string, + +inactiveColor?: string, + +sceneAnimationEnabled?: boolean, + +keyboardHidesNavigationBar?: boolean, + +barStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +theme?: PaperTheme, + |}; + + declare export type ExtraMaterialBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialBottomTabNavigationConfig, + |}; + + declare export type MaterialBottomTabNavigatorProps< + NavProp: InexactMaterialBottomTabNavigationProp<> = + MaterialBottomTabNavigationProp<>, + > = {| + ...ExtraMaterialBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material top tab options + */ + + declare export type MaterialTopTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarIcon: ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material top tab navigation prop + */ + + declare export type MaterialTopTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + +swipeStart: {| +data: void, +canPreventDefault: false |}, + +swipeEnd: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactMaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material top tab exports + */ + + declare type MaterialTopTabPagerCommonProps = {| + +keyboardDismissMode: 'none' | 'on-drag' | 'auto', + +swipeEnabled: boolean, + +swipeVelocityImpact?: number, + +springVelocityScale?: number, + +springConfig: $Shape<{| + +damping: number, + +mass: number, + +stiffness: number, + +restSpeedThreshold: number, + +restDisplacementThreshold: number, + |}>, + +timingConfig: $Shape<{| + +duration: number, + |}>, + |}; + + declare export type MaterialTopTabPagerProps = {| + ...MaterialTopTabPagerCommonProps, + +onSwipeStart?: () => void, + +onSwipeEnd?: () => void, + +onIndexChange: (index: number) => void, + +navigationState: TabNavigationState, + +layout: {| +width: number, +height: number |}, + +removeClippedSubviews: boolean, + +children: ({| + +addListener: (type: 'enter', listener: number => void) => void, + +removeListener: (type: 'enter', listener: number => void) => void, + +position: any, // Reanimated.Node + +render: React$Node => React$Node, + +jumpTo: string => void, + |}) => React$Node, + +gestureHandlerProps: PanGestureHandlerProps, + |}; + + declare export type MaterialTopTabBarIndicatorProps = {| + +navigationState: TabNavigationState, + +width: string, + +style?: ViewStyleProp, + +getTabWidth: number => number, + |}; + + declare export type MaterialTopTabBarOptions = $Shape<{| + +scrollEnabled: boolean, + +bounces: boolean, + +pressColor: string, + +pressOpacity: number, + +getAccessible: ({| +route: Route<> |}) => boolean, + +renderBadge: ({| +route: Route<> |}) => React$Node, + +renderIndicator: MaterialTopTabBarIndicatorProps => React$Node, + +tabStyle: ViewStyleProp, + +indicatorStyle: ViewStyleProp, + +indicatorContainerStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + +activeTintColor: string, + +inactiveTintColor: string, + +iconStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +showLabel: boolean, + +showIcon: boolean, + +allowFontScaling: boolean, + |}>; + + declare export type MaterialTopTabDescriptor = Descriptor< + MaterialBottomTabNavigationProp<>, + MaterialBottomTabOptions, + >; + + declare type MaterialTopTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: MaterialTopTabNavigationProp<>, + +descriptors: {| +[key: string]: MaterialTopTabDescriptor |}, + |}; + + declare export type MaterialTopTabBarProps = {| + ...MaterialTopTabBarOptions, + ...MaterialTopTabNavigationBuilderResult, + +layout: {| +width: number, +height: number |}, + +position: any, // Reanimated.Node + +jumpTo: string => void, + |}; + + declare export type MaterialTopTabNavigationConfig = {| + ...$Partial, + +position?: any, // Reanimated.Value + +tabBarPosition?: 'top' | 'bottom', + +initialLayout?: $Shape<{| +width: number, +height: number |}>, + +lazy?: boolean, + +lazyPreloadDistance?: number, + +removeClippedSubviews?: boolean, + +sceneContainerStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +gestureHandlerProps?: PanGestureHandlerProps, + +pager?: MaterialTopTabPagerProps => React$Node, + +lazyPlaceholder?: ({| +route: Route<> |}) => React$Node, + +tabBar?: MaterialTopTabBarProps => React$Node, + +tabBarOptions?: MaterialTopTabBarOptions, + |}; + + declare export type ExtraMaterialTopTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialTopTabNavigationConfig, + |}; + + declare export type MaterialTopTabNavigatorProps< + NavProp: InexactMaterialTopTabNavigationProp<> = + MaterialTopTabNavigationProp<>, + > = {| + ...ExtraMaterialTopTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Drawer options + */ + + declare export type DrawerOptions = $Shape<{| + title: string, + drawerLabel: + | string + | ({| +color: string, +focused: boolean |}) => React$Node, + drawerIcon: ({| + +color: string, + +size: number, + +focused: boolean, + |}) => React$Node, + gestureEnabled: boolean, + swipeEnabled: boolean, + unmountOnBlur: boolean, + |}>; + + /** + * Drawer navigation prop + */ + + declare export type DrawerNavigationEventMap = {| + ...EventMapCore, + +drawerOpen: {| +data: void, +canPreventDefault: false |}, + +drawerClose: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactDrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + +openDrawer: () => void, + +closeDrawer: () => void, + +toggleDrawer: () => void, + ... + }; + + declare export type DrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous drawer exports + */ + + declare export type DrawerDescriptor = Descriptor< + DrawerNavigationProp<>, + DrawerOptions, + >; + + declare export type DrawerItemListBaseOptions = $Shape<{| + +activeTintColor: string, + +activeBackgroundColor: string, + +inactiveTintColor: string, + +inactiveBackgroundColor: string, + +itemStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + |}>; + + declare export type DrawerContentOptions = $Shape<{| + ...DrawerItemListBaseOptions, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + |}>; + + declare type DrawerNavigationBuilderResult = {| + +state: DrawerNavigationState, + +navigation: DrawerNavigationProp<>, + +descriptors: {| +[key: string]: DrawerDescriptor |}, + |}; + + declare export type DrawerContentProps = {| + ...DrawerContentOptions, + ...DrawerNavigationBuilderResult, + +progress: any, // Reanimated.Node + |}; + + declare export type DrawerNavigationConfig = {| + +drawerPosition?: 'left' | 'right', + +drawerType?: 'front' | 'back' | 'slide' | 'permanent', + +edgeWidth?: number, + +hideStatusBar?: boolean, + +keyboardDismissMode?: 'on-drag' | 'none', + +minSwipeDistance?: number, + +overlayColor?: string, + +statusBarAnimation?: 'slide' | 'none' | 'fade', + +gestureHandlerProps?: PanGestureHandlerProps, + +lazy?: boolean, + +drawerContent?: DrawerContentProps => React$Node, + +drawerContentOptions?: DrawerContentOptions, + +sceneContainerStyle?: ViewStyleProp, + +drawerStyle?: ViewStyleProp, + |}; + + declare export type ExtraDrawerNavigatorProps = {| + ...$Exact, + ...DrawerRouterOptions, + ...DrawerNavigationConfig, + |}; + + declare export type DrawerNavigatorProps< + NavProp: InexactDrawerNavigationProp<> = DrawerNavigationProp<>, + > = {| + ...ExtraDrawerNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * BaseNavigationContainer + */ + + declare export type BaseNavigationContainerProps = {| + +children: React$Node, + +initialState?: PossiblyStaleNavigationState, + +onStateChange?: (state: ?PossiblyStaleNavigationState) => void, + +independent?: boolean, + |}; + + declare export type ContainerEventMap = {| + ...GlobalEventMap, + +options: {| + +data: {| +options: { +[key: string]: mixed, ... } |}, + +canPreventDefault: false, + |}, + +__unsafe_action__: {| + +data: {| + +action: GenericNavigationAction, + +noop: boolean, + |}, + +canPreventDefault: false, + |}, + |}; + + declare export type BaseNavigationContainerInterface = {| + ...$Exact>, + +setParams: (params: ScreenParams) => void, + +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, + +getRootState: () => PossiblyStaleNavigationState, + |}; + + /** + * State utils + */ + + declare export type GetStateFromPath = ( + path: string, + options?: LinkingConfig, + ) => PossiblyStaleNavigationState; + + declare export type GetPathFromState = ( + state?: ?PossiblyStaleNavigationState, + options?: LinkingConfig, + ) => string; + + declare export type GetFocusedRouteNameFromRoute = + PossiblyStaleRoute => ?string; + + /** + * Linking + */ + + declare export type ScreenLinkingConfig = {| + +path?: string, + +exact?: boolean, + +parse?: {| +[param: string]: string => mixed |}, + +stringify?: {| +[param: string]: mixed => string |}, + +screens?: ScreenLinkingConfigMap, + +initialRouteName?: string, + |}; + + declare export type ScreenLinkingConfigMap = {| + +[routeName: string]: string | ScreenLinkingConfig, + |}; + + declare export type LinkingConfig = {| + +initialRouteName?: string, + +screens: ScreenLinkingConfigMap, + |}; + + declare export type LinkingOptions = {| + +enabled?: boolean, + +prefixes: $ReadOnlyArray, + +config?: LinkingConfig, + +getStateFromPath?: GetStateFromPath, + +getPathFromState?: GetPathFromState, + |}; + + /** + * NavigationContainer + */ + + declare export type Theme = {| + +dark: boolean, + +colors: {| + +primary: string, + +background: string, + +card: string, + +text: string, + +border: string, + |}, + |}; + + declare export type NavigationContainerType = React$AbstractComponent< + {| + ...BaseNavigationContainerProps, + +theme?: Theme, + +linking?: LinkingOptions, + +fallback?: React$Node, + +onReady?: () => mixed, + |}, + BaseNavigationContainerInterface, + >; + + //--------------------------------------------------------------------------- + // SECTION 2: EXPORTED MODULE + // This section defines the module exports and contains exported types that + // are not present in any other React Navigation libdef. + //--------------------------------------------------------------------------- + + /** + * Actions and routers + */ + + declare export var CommonActions: CommonActionsType; + declare export var StackActions: StackActionsType; + declare export var TabActions: TabActionsType; + declare export var DrawerActions: DrawerActionsType; + + declare export var BaseRouter: RouterFactory< + NavigationState, + CommonAction, + DefaultRouterOptions, + >; + declare export var StackRouter: RouterFactory< + StackNavigationState, + StackAction, + StackRouterOptions, + >; + declare export var TabRouter: RouterFactory< + TabNavigationState, + TabAction, + TabRouterOptions, + >; + declare export var DrawerRouter: RouterFactory< + DrawerNavigationState, + DrawerAction, + DrawerRouterOptions, + >; + + /** + * Navigator utils + */ + + declare export var BaseNavigationContainer: React$AbstractComponent< + BaseNavigationContainerProps, + BaseNavigationContainerInterface, + >; + + declare export var createNavigatorFactory: CreateNavigatorFactory; + + declare export var useNavigationBuilder: UseNavigationBuilder; + + declare export var NavigationHelpersContext: React$Context< + ?NavigationHelpers, + >; + + /** + * Navigation prop / route accessors + */ + + declare export var NavigationContext: React$Context< + ?NavigationProp, + >; + declare export function useNavigation(): NavigationProp; + + declare export var NavigationRouteContext: React$Context>; + declare export function useRoute(): LeafRoute<>; + + declare export function useNavigationState( + selector: NavigationState => T, + ): T; + + /** + * Focus utils + */ + + declare export function useFocusEffect( + effect: () => ?(() => mixed), + ): void; + declare export function useIsFocused(): boolean; + + /** + * State utils + */ + + declare export var getStateFromPath: GetStateFromPath; + + declare export var getPathFromState: GetPathFromState; + + declare export function getActionFromState( + state: PossiblyStaleNavigationState, + ): ?NavigateAction; + + declare export var getFocusedRouteNameFromRoute: GetFocusedRouteNameFromRoute; + + /** + * useScrollToTop + */ + + declare type ScrollToOptions = { y?: number, animated?: boolean, ... }; + declare type ScrollToOffsetOptions = { + offset: number, + animated?: boolean, + ... + }; + declare type ScrollableView = + | { scrollToTop(): void, ... } + | { scrollTo(options: ScrollToOptions): void, ... } + | { scrollToOffset(options: ScrollToOffsetOptions): void, ... } + | { scrollResponderScrollTo(options: ScrollToOptions): void, ... }; + declare type ScrollableWrapper = + | { getScrollResponder(): React$Node, ... } + | { getNode(): ScrollableView, ... } + | ScrollableView; + declare export function useScrollToTop( + ref: { +current: ?ScrollableWrapper, ... }, + ): void; + + /** + * Themes + */ + + declare export var DefaultTheme: Theme & { +dark: false, ... }; + declare export var DarkTheme: Theme & { +dark: true, ... }; + declare export function useTheme(): Theme; + declare export var ThemeProvider: React$ComponentType<{| + +value: Theme, + +children: React$Node, + |}>; + + /** + * Linking + */ + + declare export var Link: React$ComponentType<{ + +to: string, + +action?: GenericNavigationAction, + +target?: string, + +children: React$Node, + ... + }>; + + declare export function useLinking( + container: { +current: ?React$ElementRef, ... }, + options: LinkingOptions, + ): {| +getInitialState: () => Promise |}; + + declare export function useLinkTo(): (path: string) => void; + + declare export function useLinkProps(props: {| + +to: Top, + +action?: GenericNavigationAction, + |}): {| + +href: To, + +accessibilityRole: 'link', + +onPress: (MouseEvent | PressEvent) => void, + |}; + + declare export function useLinkBuilder(): ( + name: string, + params?: ScreenParams, + ) => ?string; + + /** + * NavigationContainer + */ + + declare export var NavigationContainer: NavigationContainerType; + + /** + * useBackButton + */ + + declare export function useBackButton( + container: { +current: ?React$ElementRef, ... }, + ): void; + +} diff --git a/flow-typed/npm/@react-navigation/stack_v5.x.x.js b/flow-typed/npm/@react-navigation/stack_v5.x.x.js new file mode 100644 index 00000000000..1679a2da0a6 --- /dev/null +++ b/flow-typed/npm/@react-navigation/stack_v5.x.x.js @@ -0,0 +1,2137 @@ +// flow-typed signature: 84942f76d5ef0432db67cd351ba8ce7a +// flow-typed version: 3c17c8ecd5/@react-navigation/stack_v5.x.x/flow_>=v0.104.x + +declare module '@react-navigation/stack' { + + //--------------------------------------------------------------------------- + // SECTION 1: IDENTICAL TYPE DEFINITIONS + // This section is identical across all React Navigation libdefs and contains + // shared definitions. We wish we could make it DRY and import from a shared + // definition, but that isn't yet possible. + //--------------------------------------------------------------------------- + + /** + * We start with some definitions that we have copy-pasted from React Native + * source files. + */ + + // This is a bastardization of the true StyleObj type located in + // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't + // import that here, and it's too lengthy (and consequently too brittle) to + // copy-paste here either. + declare type StyleObj = + | null + | void + | number + | false + | '' + | $ReadOnlyArray + | { [name: string]: any, ... }; + declare type ViewStyleProp = StyleObj; + declare type TextStyleProp = StyleObj; + declare type AnimatedViewStyleProp = StyleObj; + declare type AnimatedTextStyleProp = StyleObj; + + // Vaguely copied from + // react-native/Libraries/Animated/src/animations/Animation.js + declare type EndResult = { finished: boolean, ... }; + declare type EndCallback = (result: EndResult) => void; + declare interface Animation { + start( + fromValue: number, + onUpdate: (value: number) => void, + onEnd: ?EndCallback, + previousAnimation: ?Animation, + animatedValue: AnimatedValue, + ): void; + stop(): void; + } + declare type AnimationConfig = { + isInteraction?: boolean, + useNativeDriver: boolean, + onComplete?: ?EndCallback, + iterations?: number, + ... + }; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js + declare interface AnimatedTracking { + constructor( + value: AnimatedValue, + parent: any, + animationClass: any, + animationConfig: Object, + callback?: ?EndCallback, + ): void; + update(): void; + } + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedValue.js + declare type ValueListenerCallback = (state: { value: number, ... }) => void; + declare interface AnimatedValue { + constructor(value: number): void; + setValue(value: number): void; + setOffset(offset: number): void; + flattenOffset(): void; + extractOffset(): void; + addListener(callback: ValueListenerCallback): string; + removeListener(id: string): void; + removeAllListeners(): void; + stopAnimation(callback?: ?(value: number) => void): void; + resetAnimation(callback?: ?(value: number) => void): void; + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + animate(animation: Animation, callback: ?EndCallback): void; + stopTracking(): void; + track(tracking: AnimatedTracking): void; + } + + // Copied from + // react-native/Libraries/Animated/src/animations/TimingAnimation.js + declare type TimingAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + easing?: (value: number) => number, + duration?: number, + delay?: number, + ... + }; + + // Copied from + // react-native/Libraries/Animated/src/animations/SpringAnimation.js + declare type SpringAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, + overshootClamping?: boolean, + restDisplacementThreshold?: number, + restSpeedThreshold?: number, + velocity?: number, + bounciness?: number, + speed?: number, + tension?: number, + friction?: number, + stiffness?: number, + damping?: number, + mass?: number, + delay?: number, + ... + }; + + // Copied from react-native/Libraries/Types/CoreEventTypes.js + declare type SyntheticEvent = $ReadOnly<{| + bubbles: ?boolean, + cancelable: ?boolean, + currentTarget: number, + defaultPrevented: ?boolean, + dispatchConfig: $ReadOnly<{| + registrationName: string, + |}>, + eventPhase: ?number, + preventDefault: () => void, + isDefaultPrevented: () => boolean, + stopPropagation: () => void, + isPropagationStopped: () => boolean, + isTrusted: ?boolean, + nativeEvent: T, + persist: () => void, + target: ?number, + timeStamp: number, + type: ?string, + |}>; + declare type Layout = $ReadOnly<{| + x: number, + y: number, + width: number, + height: number, + |}>; + declare type LayoutEvent = SyntheticEvent< + $ReadOnly<{| + layout: Layout, + |}>, + >; + declare type BlurEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type FocusEvent = SyntheticEvent< + $ReadOnly<{| + target: number, + |}>, + >; + declare type ResponderSyntheticEvent = $ReadOnly<{| + ...SyntheticEvent, + touchHistory: $ReadOnly<{| + indexOfSingleActiveTouch: number, + mostRecentTimeStamp: number, + numberActiveTouches: number, + touchBank: $ReadOnlyArray< + $ReadOnly<{| + touchActive: boolean, + startPageX: number, + startPageY: number, + startTimeStamp: number, + currentPageX: number, + currentPageY: number, + currentTimeStamp: number, + previousPageX: number, + previousPageY: number, + previousTimeStamp: number, + |}>, + >, + |}>, + |}>; + declare type PressEvent = ResponderSyntheticEvent< + $ReadOnly<{| + changedTouches: $ReadOnlyArray<$PropertyType>, + force: number, + identifier: number, + locationX: number, + locationY: number, + pageX: number, + pageY: number, + target: ?number, + timestamp: number, + touches: $ReadOnlyArray<$PropertyType>, + |}>, + >; + + // Vaguely copied from + // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js + declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; + declare type InterpolationConfigType = { + inputRange: Array, + outputRange: Array | Array, + easing?: (input: number) => number, + extrapolate?: ExtrapolateType, + extrapolateLeft?: ExtrapolateType, + extrapolateRight?: ExtrapolateType, + ... + }; + declare interface AnimatedInterpolation { + interpolate(config: InterpolationConfigType): AnimatedInterpolation; + } + + // Copied from react-native/Libraries/Components/View/ViewAccessibility.js + declare type AccessibilityRole = + | 'none' + | 'button' + | 'link' + | 'search' + | 'image' + | 'keyboardkey' + | 'text' + | 'adjustable' + | 'imagebutton' + | 'header' + | 'summary' + | 'alert' + | 'checkbox' + | 'combobox' + | 'menu' + | 'menubar' + | 'menuitem' + | 'progressbar' + | 'radio' + | 'radiogroup' + | 'scrollbar' + | 'spinbutton' + | 'switch' + | 'tab' + | 'tablist' + | 'timer' + | 'toolbar'; + declare type AccessibilityActionInfo = $ReadOnly<{ + name: string, + label?: string, + ... + }>; + declare type AccessibilityActionEvent = SyntheticEvent< + $ReadOnly<{actionName: string, ...}>, + >; + declare type AccessibilityState = { + disabled?: boolean, + selected?: boolean, + checked?: ?boolean | 'mixed', + busy?: boolean, + expanded?: boolean, + ... + }; + declare type AccessibilityValue = $ReadOnly<{| + min?: number, + max?: number, + now?: number, + text?: string, + |}>; + + // Copied from + // react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js + declare type Stringish = string; + declare type EdgeInsetsProp = $ReadOnly<$Shape>; + declare type TouchableWithoutFeedbackProps = $ReadOnly<{| + accessibilityActions?: ?$ReadOnlyArray, + accessibilityElementsHidden?: ?boolean, + accessibilityHint?: ?Stringish, + accessibilityIgnoresInvertColors?: ?boolean, + accessibilityLabel?: ?Stringish, + accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), + accessibilityRole?: ?AccessibilityRole, + accessibilityState?: ?AccessibilityState, + accessibilityValue?: ?AccessibilityValue, + accessibilityViewIsModal?: ?boolean, + accessible?: ?boolean, + children?: ?React$Node, + delayLongPress?: ?number, + delayPressIn?: ?number, + delayPressOut?: ?number, + disabled?: ?boolean, + focusable?: ?boolean, + hitSlop?: ?EdgeInsetsProp, + importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), + nativeID?: ?string, + onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, + onBlur?: ?(event: BlurEvent) => mixed, + onFocus?: ?(event: FocusEvent) => mixed, + onLayout?: ?(event: LayoutEvent) => mixed, + onLongPress?: ?(event: PressEvent) => mixed, + onPress?: ?(event: PressEvent) => mixed, + onPressIn?: ?(event: PressEvent) => mixed, + onPressOut?: ?(event: PressEvent) => mixed, + pressRetentionOffset?: ?EdgeInsetsProp, + rejectResponderTermination?: ?boolean, + testID?: ?string, + touchSoundDisabled?: ?boolean, + |}>; + + // Copied from react-native/Libraries/Image/ImageSource.js + declare type ImageURISource = $ReadOnly<{ + uri?: ?string, + bundle?: ?string, + method?: ?string, + headers?: ?Object, + body?: ?string, + cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached'), + width?: ?number, + height?: ?number, + scale?: ?number, + ... + }>; + + /** + * The following is copied from react-native-gesture-handler's libdef + */ + + declare type $EventHandlers = {| + onGestureEvent?: ($Event) => mixed, + onHandlerStateChange?: ($Event) => mixed, + onBegan?: ($Event) => mixed, + onFailed?: ($Event) => mixed, + onCancelled?: ($Event) => mixed, + onActivated?: ($Event) => mixed, + onEnded?: ($Event) => mixed, + |}; + + declare type HitSlop = + | number + | {| + left?: number, + top?: number, + right?: number, + bottom?: number, + vertical?: number, + horizontal?: number, + width?: number, + height?: number, + |} + | {| + width: number, + left: number, + |} + | {| + width: number, + right: number, + |} + | {| + height: number, + top: number, + |} + | {| + height: number, + bottom: number, + |}; + + declare type $GestureHandlerProps< + AdditionalProps: {...}, + ExtraEventsProps: {...} + > = $ReadOnly<{| + ...$Exact, + ...$EventHandlers, + id?: string, + enabled?: boolean, + waitFor?: React$Ref | Array>, + simultaneousHandlers?: React$Ref | Array>, + shouldCancelWhenOutside?: boolean, + minPointers?: number, + hitSlop?: HitSlop, + children?: React$Node, + |}>; + + declare type PanGestureHandlerProps = $GestureHandlerProps< + { + activeOffsetY?: number | [number, number], + activeOffsetX?: number | [number, number], + failOffsetY?: number | [number, number], + failOffsetX?: number | [number, number], + minDist?: number, + minVelocity?: number, + minVelocityX?: number, + minVelocityY?: number, + minPointers?: number, + maxPointers?: number, + avgTouches?: boolean, + ... + }, + { + x: number, + y: number, + absoluteX: number, + absoluteY: number, + translationX: number, + translationY: number, + velocityX: number, + velocityY: number, + ... + } + >; + + /** + * MAGIC + */ + + declare type $If = $Call< + ((true, Then, Else) => Then) & ((false, Then, Else) => Else), + Test, + Then, + Else, + >; + declare type $IsA = $Call< + (Y => true) & (mixed => false), + X, + >; + declare type $IsUndefined = $IsA; + + declare type $Partial = $Rest; + + /** + * Actions, state, etc. + */ + + declare export type ScreenParams = { +[key: string]: mixed, ... }; + + declare export type BackAction = {| + +type: 'GO_BACK', + +source?: string, + +target?: string, + |}; + declare export type NavigateAction = {| + +type: 'NAVIGATE', + +payload: + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type ResetAction = {| + +type: 'RESET', + +payload: StaleNavigationState, + +source?: string, + +target?: string, + |}; + declare export type SetParamsAction = {| + +type: 'SET_PARAMS', + +payload: {| +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type CommonAction = + | BackAction + | NavigateAction + | ResetAction + | SetParamsAction; + + declare type NavigateActionCreator = {| + (routeName: string, params?: ScreenParams): NavigateAction, + ( + | {| +key: string, +params?: ScreenParams |} + | {| +name: string, +key?: string, +params?: ScreenParams |}, + ): NavigateAction, + |}; + declare export type CommonActionsType = {| + +navigate: NavigateActionCreator, + +goBack: () => BackAction, + +reset: (state: PossiblyStaleNavigationState) => ResetAction, + +setParams: (params: ScreenParams) => SetParamsAction, + |}; + + declare export type GenericNavigationAction = {| + +type: string, + +payload?: { +[key: string]: mixed, ... }, + +source?: string, + +target?: string, + |}; + + declare export type LeafRoute = {| + +key: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StateRoute = {| + ...LeafRoute, + +state: NavigationState | StaleNavigationState, + |}; + declare export type Route = + | LeafRoute + | StateRoute; + + declare export type NavigationState = {| + +key: string, + +index: number, + +routeNames: $ReadOnlyArray, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type: string, + +stale: false, + |}; + + declare export type StaleLeafRoute = {| + +key?: string, + +name: RouteName, + +params?: ScreenParams, + |}; + declare export type StaleStateRoute = {| + ...StaleLeafRoute, + +state: StaleNavigationState, + |}; + declare export type StaleRoute = + | StaleLeafRoute + | StaleStateRoute; + declare export type StaleNavigationState = {| + // It's possible to pass React Nav a StaleNavigationState with an undefined + // index, but React Nav will always return one with the index set. This is + // the same as for the type property below, but in the case of index we tend + // to rely on it being set more... + +index: number, + +history?: $ReadOnlyArray, + +routes: $ReadOnlyArray>, + +type?: string, + +stale?: true, + |}; + + declare export type PossiblyStaleNavigationState = + | NavigationState + | StaleNavigationState; + declare export type PossiblyStaleRoute = + | Route + | StaleRoute; + + /** + * Routers + */ + + declare type ActionCreators< + State: NavigationState, + Action: GenericNavigationAction, + > = { + +[key: string]: (...args: any) => (Action | State => Action), + ... + }; + + declare export type DefaultRouterOptions = { + +initialRouteName?: string, + ... + }; + + declare export type RouterFactory< + State: NavigationState, + Action: GenericNavigationAction, + RouterOptions: DefaultRouterOptions, + > = (options: RouterOptions) => Router; + + declare export type ParamListBase = { +[key: string]: ?ScreenParams, ... }; + + declare export type RouterConfigOptions = {| + +routeNames: $ReadOnlyArray, + +routeParamList: ParamListBase, + |}; + + declare export type Router< + State: NavigationState, + Action: GenericNavigationAction, + > = {| + +type: $PropertyType, + +getInitialState: (options: RouterConfigOptions) => State, + +getRehydratedState: ( + partialState: PossibleStaleNavigationState, + options: RouterConfigOptions, + ) => State, + +getStateForRouteNamesChange: ( + state: State, + options: RouterConfigOptions, + ) => State, + +getStateForRouteFocus: (state: State, key: string) => State, + +getStateForAction: ( + state: State, + action: Action, + options: RouterConfigOptions, + ) => ?PossiblyStaleNavigationState; + +shouldActionChangeFocus: (action: GenericNavigationAction) => boolean, + +actionCreators?: ActionCreators, + |}; + + /** + * Stack actions and router + */ + + declare export type StackNavigationState = {| + ...NavigationState, + +type: 'stack', + |}; + + declare export type ReplaceAction = {| + +type: 'REPLACE', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PushAction = {| + +type: 'PUSH', + +payload: {| +name: string, +key?: ?string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type PopAction = {| + +type: 'POP', + +payload: {| +count: number |}, + +source?: string, + +target?: string, + |}; + declare export type PopToTopAction = {| + +type: 'POP_TO_TOP', + +source?: string, + +target?: string, + |}; + declare export type StackAction = + | CommonAction + | ReplaceAction + | PushAction + | PopAction + | PopToTopAction; + + declare export type StackActionsType = {| + +replace: (routeName: string, params?: ScreenParams) => ReplaceAction, + +push: (routeName: string, params?: ScreenParams) => PushAction, + +pop: (count?: number) => PopAction, + +popToTop: () => PopToTopAction, + |}; + + declare export type StackRouterOptions = $Exact; + + /** + * Tab actions and router + */ + + declare export type TabNavigationState = {| + ...NavigationState, + +type: 'tab', + +history: $ReadOnlyArray<{| type: 'route', key: string |}>, + |}; + + declare export type JumpToAction = {| + +type: 'JUMP_TO', + +payload: {| +name: string, +params?: ScreenParams |}, + +source?: string, + +target?: string, + |}; + declare export type TabAction = + | CommonAction + | JumpToAction; + + declare export type TabActionsType = {| + +jumpTo: string => JumpToAction, + |}; + + declare export type TabRouterOptions = {| + ...$Exact, + +backBehavior?: 'initialRoute' | 'order' | 'history' | 'none', + |}; + + /** + * Drawer actions and router + */ + + declare type DrawerHistoryEntry = + | {| +type: 'route', +key: string |} + | {| +type: 'drawer' |}; + declare export type DrawerNavigationState = {| + ...NavigationState, + +type: 'drawer', + +history: $ReadOnlyArray, + |}; + + declare export type OpenDrawerAction = {| + +type: 'OPEN_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type CloseDrawerAction = {| + +type: 'CLOSE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type ToggleDrawerAction = {| + +type: 'TOGGLE_DRAWER', + +source?: string, + +target?: string, + |}; + declare export type DrawerAction = + | TabAction + | OpenDrawerAction + | CloseDrawerAction + | ToggleDrawerAction; + + declare export type DrawerActionsType = {| + ...TabActionsType, + +openDrawer: () => OpenDrawerAction, + +closeDrawer: () => CloseDrawerAction, + +toggleDrawer: () => ToggleDrawerAction, + |}; + + declare export type DrawerRouterOptions = {| + ...TabRouterOptions, + +openByDefault?: boolean, + |}; + + /** + * Events + */ + + declare export type EventMapBase = { + +[name: string]: {| + +data?: mixed, + +canPreventDefault?: boolean, + |}, + ... + }; + declare type EventPreventDefaultProperties = $If< + Test, + {| +defaultPrevented: boolean, +preventDefault: () => void |}, + {| |}, + >; + declare type EventDataProperties = $If< + $IsUndefined, + {| |}, + {| +data: Data |}, + >; + declare type EventArg< + EventName: string, + CanPreventDefault: ?boolean = false, + Data = void, + > = {| + ...EventPreventDefaultProperties, + ...EventDataProperties, + +type: EventName, + +target?: string, + |}; + declare type GlobalEventMap = {| + +state: {| +data: {| +state: State |}, +canPreventDefault: false |}, + |}; + declare type EventMapCore = {| + ...GlobalEventMap, + +focus: {| +data: void, +canPreventDefault: false |}, + +blur: {| +data: void, +canPreventDefault: false |}, + |}; + declare type EventListenerCallback< + EventName: string, + State: PossiblyStaleNavigationState = NavigationState, + EventMap: EventMapBase = EventMapCore, + > = (e: EventArg< + EventName, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'canPreventDefault', + >, + $PropertyType< + $ElementType< + {| ...EventMap, ...EventMapCore |}, + EventName, + >, + 'data', + >, + >) => mixed; + + /** + * Navigation prop + */ + + declare export type SimpleNavigate = + >( + routeName: DestinationRouteName, + params: $ElementType, + ) => void; + + declare export type Navigate = + & SimpleNavigate + & >( + route: + | {| + key: string, + params?: $ElementType, + |} + | {| + name: DestinationRouteName, + key?: string, + params?: $ElementType, + |}, + ) => void; + + declare type NavigationHelpers< + ParamList: ParamListBase, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + EventMap: EventMapBase = EventMapCore, + > = { + +navigate: Navigate, + +dispatch: ( + action: + | GenericNavigationAction + | (State => GenericNavigationAction), + ) => void, + +reset: PossiblyStaleNavigationState => void, + +goBack: () => void, + +isFocused: () => boolean, + +canGoBack: () => boolean, + +dangerouslyGetParent: >() => ?Parent, + +dangerouslyGetState: () => NavigationState, + +addListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => () => void, + +removeListener: |}, + >>( + name: EventName, + callback: EventListenerCallback, + ) => void, + ... + }; + + declare export type NavigationProp< + ParamList: ParamListBase, + RouteName: $Keys = $Keys, + State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = { + ...$Exact>, + +setOptions: (options: $Shape) => void, + +setParams: ( + params: $If< + $IsUndefined<$ElementType>, + empty, + $Shape<$NonMaybeType<$ElementType>>, + >, + ) => void, + ... + }; + + /** + * CreateNavigator + */ + + declare export type RouteProp< + ParamList: ParamListBase, + RouteName: $Keys, + > = {| + ...LeafRoute, + +params: $ElementType, + |}; + + declare export type ScreenListeners< + EventMap: EventMapBase = EventMapCore, + State: NavigationState = NavigationState, + > = $ObjMapi< + {| [name: $Keys]: empty |}, + >(K, empty) => EventListenerCallback, + >; + + declare type BaseScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = {| + +name: RouteName, + +options?: + | ScreenOptions + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenOptions, + +listeners?: + | ScreenListeners + | ({| + route: RouteProp, + navigation: NavProp, + |}) => ScreenListeners, + +initialParams?: $Shape<$ElementType>, + |}; + + declare export type ScreenProps< + ParamList: ParamListBase, + NavProp, + RouteName: $Keys = $Keys, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +component: React$ComponentType<{| + route: RouteProp, + navigation: NavProp, + |}>, + |} + | {| + ...BaseScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >, + +children: ({| + route: RouteProp, + navigation: NavProp, + |}) => React$Node, + |}; + + declare export type ScreenComponent< + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + State: NavigationState = NavigationState, + ScreenOptions: {...} = {...}, + EventMap: EventMapBase = EventMapCore, + > = < + RouteName: $Keys, + NavProp: NavigationProp< + GlobalParamList, + RouteName, + State, + ScreenOptions, + EventMap, + >, + >(props: ScreenProps< + ParamList, + NavProp, + RouteName, + State, + ScreenOptions, + EventMap, + >) => React$Node; + + declare type ScreenOptionsProp = {| + +screenOptions?: + | ScreenOptions + | ({| route: LeafRoute<>, navigation: NavProp |}) => ScreenOptions, + |}; + declare export type ExtraNavigatorPropsBase = { + ...$Exact, + +children?: React$Node, + ... + }; + declare export type NavigatorPropsBase = { + ...$Exact, + ...ScreenOptionsProp, + ... + }; + + declare export type CreateNavigator< + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + > = < + GlobalParamList: ParamListBase, + ParamList: ParamListBase, + NavProp: NavigationHelpers< + GlobalParamList, + State, + EventMap, + >, + >() => {| + +Screen: ScreenComponent< + GlobalParamList, + ParamList, + State, + ScreenOptions, + EventMap, + >, + +Navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + |}; + + declare export type CreateNavigatorFactory = < + State: NavigationState, + ScreenOptions: {...}, + EventMap: EventMapBase, + NavProp: NavigationHelpers< + ParamListBase, + State, + EventMap, + >, + ExtraNavigatorProps: ExtraNavigatorPropsBase, + >( + navigator: React$ComponentType<{| + ...$Exact, + ...ScreenOptionsProp, + |}>, + ) => CreateNavigator; + + /** + * useNavigationBuilder + */ + + declare export type Descriptor< + NavProp, + ScreenOptions: {...} = {...}, + > = {| + +render: () => React$Node, + +options: $ReadOnly, + +navigation: NavProp, + |}; + + declare export type UseNavigationBuilder = < + State: NavigationState, + Action: GenericNavigationAction, + ScreenOptions: {...}, + RouterOptions: DefaultRouterOptions, + NavProp, + >( + routerFactory: RouterFactory, + options: {| + ...$Exact, + ...ScreenOptionsProp, + +children?: React$Node, + |}, + ) => {| + +state: State, + +descriptors: {| +[key: string]: Descriptor |}, + +navigation: NavProp, + |}; + + /** + * EdgeInsets + */ + + declare type EdgeInsets = {| + +top: number, + +right: number, + +bottom: number, + +left: number, + |}; + + /** + * TransitionPreset + */ + + declare export type TransitionSpec = + | {| + animation: 'spring', + config: $Diff< + SpringAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |} + | {| + animation: 'timing', + config: $Diff< + TimingAnimationConfigSingle, + { toValue: number | AnimatedValue, ... }, + >, + |}; + + declare export type StackCardInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +index: number, + +closing: AnimatedInterpolation, + +swiping: AnimatedInterpolation, + +inverted: AnimatedInterpolation, + +layouts: {| + +screen: {| +width: number, +height: number |}, + |}, + +insets: EdgeInsets, + |}; + declare export type StackCardInterpolatedStyle = {| + containerStyle?: AnimatedViewStyleProp, + cardStyle?: AnimatedViewStyleProp, + overlayStyle?: AnimatedViewStyleProp, + shadowStyle?: AnimatedViewStyleProp, + |}; + declare export type StackCardStyleInterpolator = ( + props: StackCardInterpolationProps, + ) => StackCardInterpolatedStyle; + + declare export type StackHeaderInterpolationProps = {| + +current: {| + +progress: AnimatedInterpolation, + |}, + +next?: {| + +progress: AnimatedInterpolation, + |}, + +layouts: {| + +header: {| +width: number, +height: number |}, + +screen: {| +width: number, +height: number |}, + +title?: {| +width: number, +height: number |}, + +leftLabel?: {| +width: number, +height: number |}, + |}, + |}; + declare export type StackHeaderInterpolatedStyle = {| + leftLabelStyle?: AnimatedViewStyleProp, + leftButtonStyle?: AnimatedViewStyleProp, + rightButtonStyle?: AnimatedViewStyleProp, + titleStyle?: AnimatedViewStyleProp, + backgroundStyle?: AnimatedViewStyleProp, + |}; + declare export type StackHeaderStyleInterpolator = ( + props: StackHeaderInterpolationProps, + ) => StackHeaderInterpolatedStyle; + + declare type GestureDirection = + | 'horizontal' + | 'horizontal-inverted' + | 'vertical' + | 'vertical-inverted'; + + declare export type TransitionPreset = {| + +gestureDirection: GestureDirection, + +transitionSpec: {| + +open: TransitionSpec, + +close: TransitionSpec, + |}, + +cardStyleInterpolator: StackCardStyleInterpolator, + +headerStyleInterpolator: StackHeaderStyleInterpolator, + |}; + + /** + * Stack options + */ + + declare export type StackDescriptor = Descriptor< + StackNavigationProp<>, + StackOptions, + >; + + declare type Scene = {| + +route: T, + +descriptor: StackDescriptor, + +progress: {| + +current: AnimatedInterpolation, + +next?: AnimatedInterpolation, + +previous?: AnimatedInterpolation, + |}, + |}; + + declare export type StackHeaderProps = {| + +mode: 'float' | 'screen', + +layout: {| +width: number, +height: number |}, + +insets: EdgeInsets, + +scene: Scene>, + +previous?: Scene>, + +navigation: StackNavigationProp, + +styleInterpolator: StackHeaderStyleInterpolator, + |}; + + declare export type StackHeaderLeftButtonProps = $Shape<{| + +onPress: (() => void), + +pressColorAndroid: string; + +backImage: (props: {| tintColor: string |}) => React$Node, + +tintColor: string, + +label: string, + +truncatedLabel: string, + +labelVisible: boolean, + +labelStyle: AnimatedTextStyleProp, + +allowFontScaling: boolean, + +onLabelLayout: LayoutEvent => void, + +screenLayout: {| +width: number, +height: number |}, + +titleLayout: {| +width: number, +height: number |}, + +canGoBack: boolean, + |}>; + + declare type StackHeaderTitleInputBase = { + +onLayout: LayoutEvent => void, + +children: string, + +allowFontScaling: ?boolean, + +tintColor: ?string, + +style: ?AnimatedTextStyleProp, + ... + }; + + declare export type StackHeaderTitleInputProps = + $Exact; + + declare export type StackOptions = $Shape<{| + +title: string, + +header: StackHeaderProps => React$Node, + +headerShown: boolean, + +cardShadowEnabled: boolean, + +cardOverlayEnabled: boolean, + +cardOverlay: {| style: ViewStyleProp |} => React$Node, + +cardStyle: ViewStyleProp, + +animationEnabled: boolean, + +animationTypeForReplace: 'push' | 'pop', + +gestureEnabled: boolean, + +gestureResponseDistance: {| vertical?: number, horizontal?: number |}, + +gestureVelocityImpact: number, + +safeAreaInsets: $Shape, + // Transition + ...TransitionPreset, + // Header + +headerTitle: string | (StackHeaderTitleInputProps => React$Node), + +headerTitleAlign: 'left' | 'center', + +headerTitleStyle: AnimatedTextStyleProp, + +headerTitleContainerStyle: ViewStyleProp, + +headerTintColor: string, + +headerTitleAllowFontScaling: boolean, + +headerBackAllowFontScaling: boolean, + +headerBackTitle: string | null, + +headerBackTitleStyle: TextStyleProp, + +headerBackTitleVisible: boolean, + +headerTruncatedBackTitle: string, + +headerLeft: StackHeaderLeftButtonProps => React$Node, + +headerLeftContainerStyle: ViewStyleProp, + +headerRight: {| tintColor?: string |} => React$Node, + +headerRightContainerStyle: ViewStyleProp, + +headerBackImage: $PropertyType, + +headerPressColorAndroid: string, + +headerBackground: ({| style: ViewStyleProp |}) => React$Node, + +headerStyle: ViewStyleProp, + +headerTransparent: boolean, + +headerStatusBarHeight: number, + |}>; + + /** + * Stack navigation prop + */ + + declare export type StackNavigationEventMap = {| + ...EventMapCore, + +transitionStart: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + +transitionEnd: {| + +data: {| +closing: boolean |}, + +canPreventDefault: false, + |}, + |}; + + declare type InexactStackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = { + ...$Exact>, + +replace: SimpleNavigate, + +push: SimpleNavigate, + +pop: (count?: number) => void, + +popToTop: () => void, + ... + }; + + declare export type StackNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = StackOptions, + EventMap: EventMapBase = StackNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous stack exports + */ + + declare type StackNavigationConfig = {| + +mode?: 'card' | 'modal', + +headerMode?: 'float' | 'screen' | 'none', + +keyboardHandlingEnabled?: boolean, + |}; + + declare export type ExtraStackNavigatorProps = {| + ...$Exact, + ...StackRouterOptions, + ...StackNavigationConfig, + |}; + + declare export type StackNavigatorProps< + NavProp: InexactStackNavigationProp<> = StackNavigationProp<>, + > = {| + ...ExtraStackNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Bottom tab options + */ + + declare export type BottomTabBarButtonProps = {| + ...$Diff< + TouchableWithoutFeedbackProps, + {| onPress?: ?(event: PressEvent) => mixed |}, + >, + +to?: string, + +children: React$Node, + +onPress?: (MouseEvent | PressEvent) => void, + |}; + + declare export type BottomTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| focused: boolean, color: string |}) => React$Node, + +tabBarIcon: ({| + focused: boolean, + color: string, + size: number, + |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + +tabBarVisible: boolean, + +tabBarButton: BottomTabBarButtonProps => React$Node, + +unmountOnBlur: boolean, + |}>; + + /** + * Bottom tab navigation prop + */ + + declare export type BottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + |}; + + declare type InexactTabNavigationProp< + ParamList: ParamListBase, + RouteName: $Keys, + Options: {...}, + EventMap: EventMapBase, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + ... + }; + + declare export type InexactBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type BottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = BottomTabOptions, + EventMap: EventMapBase = BottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous bottom tab exports + */ + + declare export type BottomTabDescriptor = Descriptor< + BottomTabNavigationProp<>, + BottomTabOptions, + >; + + declare export type BottomTabBarOptions = $Shape<{| + +keyboardHidesTabBar: boolean, + +activeTintColor: string, + +inactiveTintColor: string, + +activeBackgroundColor: string, + +inactiveBackgroundColor: string, + +allowFontScaling: boolean, + +showLabel: boolean, + +showIcon: boolean, + +labelStyle: TextStyleProp, + +iconStyle: TextStyleProp, + +tabStyle: ViewStyleProp, + +labelPosition: 'beside-icon' | 'below-icon', + +adaptive: boolean, + +safeAreaInsets: $Shape, + +style: ViewStyleProp, + |}>; + + declare type BottomTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: BottomTabNavigationProp<>, + +descriptors: {| +[key: string]: BottomTabDescriptor |}, + |}; + + declare export type BottomTabBarProps = {| + ...BottomTabBarOptions, + ...BottomTabNavigationBuilderResult, + |} + + declare type BottomTabNavigationConfig = {| + +lazy?: boolean, + +tabBar?: BottomTabBarProps => React$Node, + +tabBarOptions?: BottomTabBarOptions, + |}; + + declare export type ExtraBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...BottomTabNavigationConfig, + |}; + + declare export type BottomTabNavigatorProps< + NavProp: InexactBottomTabNavigationProp<> = BottomTabNavigationProp<>, + > = {| + ...ExtraBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material bottom tab options + */ + + declare export type MaterialBottomTabOptions = $Shape<{| + +title: string, + +tabBarColor: string, + +tabBarLabel: string, + +tabBarIcon: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarBadge: boolean | number | string, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material bottom tab navigation prop + */ + + declare export type MaterialBottomTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + |}; + + declare export type InexactMaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialBottomTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialBottomTabOptions, + EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material bottom tab exports + */ + + declare export type PaperFont = {| + +fontFamily: string, + +fontWeight?: + | 'normal' + | 'bold' + | '100' + | '200' + | '300' + | '400' + | '500' + | '600' + | '700' + | '800' + | '900', + |}; + + declare export type PaperFonts = {| + +regular: Font, + +medium: Font, + +light: Font, + +thin: Font, + |}; + + declare export type PaperTheme = {| + +dark: boolean, + +mode?: 'adaptive' | 'exact', + +roundness: number, + +colors: {| + +primary: string, + +background: string, + +surface: string, + +accent: string, + +error: string, + +text: string, + +onSurface: string, + +onBackground: string, + +disabled: string, + +placeholder: string, + +backdrop: string, + +notification: string, + |}, + +fonts: PaperFonts, + +animation: {| + +scale: number, + |}, + |}; + + declare export type PaperRoute = {| + +key: string, + +title?: string, + +icon?: any, + +badge?: string | number | boolean, + +color?: string, + +accessibilityLabel?: string, + +testID?: string, + |}; + + declare export type PaperTouchableProps = {| + ...TouchableWithoutFeedbackProps, + +key: string, + +route: PaperRoute, + +children: React$Node, + +borderless?: boolean, + +centered?: boolean, + +rippleColor?: string, + |}; + + declare export type MaterialBottomTabNavigationConfig = {| + +shifting?: boolean, + +labeled?: boolean, + +renderTouchable?: PaperTouchableProps => React$Node, + +activeColor?: string, + +inactiveColor?: string, + +sceneAnimationEnabled?: boolean, + +keyboardHidesNavigationBar?: boolean, + +barStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +theme?: PaperTheme, + |}; + + declare export type ExtraMaterialBottomTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialBottomTabNavigationConfig, + |}; + + declare export type MaterialBottomTabNavigatorProps< + NavProp: InexactMaterialBottomTabNavigationProp<> = + MaterialBottomTabNavigationProp<>, + > = {| + ...ExtraMaterialBottomTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Material top tab options + */ + + declare export type MaterialTopTabOptions = $Shape<{| + +title: string, + +tabBarLabel: + | string + | ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarIcon: ({| +focused: boolean, +color: string |}) => React$Node, + +tabBarAccessibilityLabel: string, + +tabBarTestID: string, + |}>; + + /** + * Material top tab navigation prop + */ + + declare export type MaterialTopTabNavigationEventMap = {| + ...EventMapCore, + +tabPress: {| +data: void, +canPreventDefault: true |}, + +tabLongPress: {| +data: void, +canPreventDefault: false |}, + +swipeStart: {| +data: void, +canPreventDefault: false |}, + +swipeEnd: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactMaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = InexactTabNavigationProp< + ParamList, + RouteName, + Options, + EventMap, + >; + + declare export type MaterialTopTabNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = MaterialTopTabOptions, + EventMap: EventMapBase = MaterialTopTabNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous material top tab exports + */ + + declare type MaterialTopTabPagerCommonProps = {| + +keyboardDismissMode: 'none' | 'on-drag' | 'auto', + +swipeEnabled: boolean, + +swipeVelocityImpact?: number, + +springVelocityScale?: number, + +springConfig: $Shape<{| + +damping: number, + +mass: number, + +stiffness: number, + +restSpeedThreshold: number, + +restDisplacementThreshold: number, + |}>, + +timingConfig: $Shape<{| + +duration: number, + |}>, + |}; + + declare export type MaterialTopTabPagerProps = {| + ...MaterialTopTabPagerCommonProps, + +onSwipeStart?: () => void, + +onSwipeEnd?: () => void, + +onIndexChange: (index: number) => void, + +navigationState: TabNavigationState, + +layout: {| +width: number, +height: number |}, + +removeClippedSubviews: boolean, + +children: ({| + +addListener: (type: 'enter', listener: number => void) => void, + +removeListener: (type: 'enter', listener: number => void) => void, + +position: any, // Reanimated.Node + +render: React$Node => React$Node, + +jumpTo: string => void, + |}) => React$Node, + +gestureHandlerProps: PanGestureHandlerProps, + |}; + + declare export type MaterialTopTabBarIndicatorProps = {| + +navigationState: TabNavigationState, + +width: string, + +style?: ViewStyleProp, + +getTabWidth: number => number, + |}; + + declare export type MaterialTopTabBarOptions = $Shape<{| + +scrollEnabled: boolean, + +bounces: boolean, + +pressColor: string, + +pressOpacity: number, + +getAccessible: ({| +route: Route<> |}) => boolean, + +renderBadge: ({| +route: Route<> |}) => React$Node, + +renderIndicator: MaterialTopTabBarIndicatorProps => React$Node, + +tabStyle: ViewStyleProp, + +indicatorStyle: ViewStyleProp, + +indicatorContainerStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + +activeTintColor: string, + +inactiveTintColor: string, + +iconStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + +showLabel: boolean, + +showIcon: boolean, + +allowFontScaling: boolean, + |}>; + + declare export type MaterialTopTabDescriptor = Descriptor< + MaterialBottomTabNavigationProp<>, + MaterialBottomTabOptions, + >; + + declare type MaterialTopTabNavigationBuilderResult = {| + +state: TabNavigationState, + +navigation: MaterialTopTabNavigationProp<>, + +descriptors: {| +[key: string]: MaterialTopTabDescriptor |}, + |}; + + declare export type MaterialTopTabBarProps = {| + ...MaterialTopTabBarOptions, + ...MaterialTopTabNavigationBuilderResult, + +layout: {| +width: number, +height: number |}, + +position: any, // Reanimated.Node + +jumpTo: string => void, + |}; + + declare export type MaterialTopTabNavigationConfig = {| + ...$Partial, + +position?: any, // Reanimated.Value + +tabBarPosition?: 'top' | 'bottom', + +initialLayout?: $Shape<{| +width: number, +height: number |}>, + +lazy?: boolean, + +lazyPreloadDistance?: number, + +removeClippedSubviews?: boolean, + +sceneContainerStyle?: ViewStyleProp, + +style?: ViewStyleProp, + +gestureHandlerProps?: PanGestureHandlerProps, + +pager?: MaterialTopTabPagerProps => React$Node, + +lazyPlaceholder?: ({| +route: Route<> |}) => React$Node, + +tabBar?: MaterialTopTabBarProps => React$Node, + +tabBarOptions?: MaterialTopTabBarOptions, + |}; + + declare export type ExtraMaterialTopTabNavigatorProps = {| + ...$Exact, + ...TabRouterOptions, + ...MaterialTopTabNavigationConfig, + |}; + + declare export type MaterialTopTabNavigatorProps< + NavProp: InexactMaterialTopTabNavigationProp<> = + MaterialTopTabNavigationProp<>, + > = {| + ...ExtraMaterialTopTabNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * Drawer options + */ + + declare export type DrawerOptions = $Shape<{| + title: string, + drawerLabel: + | string + | ({| +color: string, +focused: boolean |}) => React$Node, + drawerIcon: ({| + +color: string, + +size: number, + +focused: boolean, + |}) => React$Node, + gestureEnabled: boolean, + swipeEnabled: boolean, + unmountOnBlur: boolean, + |}>; + + /** + * Drawer navigation prop + */ + + declare export type DrawerNavigationEventMap = {| + ...EventMapCore, + +drawerOpen: {| +data: void, +canPreventDefault: false |}, + +drawerClose: {| +data: void, +canPreventDefault: false |}, + |}; + + declare export type InexactDrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = { + ...$Exact>, + +jumpTo: SimpleNavigate, + +openDrawer: () => void, + +closeDrawer: () => void, + +toggleDrawer: () => void, + ... + }; + + declare export type DrawerNavigationProp< + ParamList: ParamListBase = ParamListBase, + RouteName: $Keys = $Keys, + Options: {...} = DrawerOptions, + EventMap: EventMapBase = DrawerNavigationEventMap, + > = $Exact>; + + /** + * Miscellaneous drawer exports + */ + + declare export type DrawerDescriptor = Descriptor< + DrawerNavigationProp<>, + DrawerOptions, + >; + + declare export type DrawerItemListBaseOptions = $Shape<{| + +activeTintColor: string, + +activeBackgroundColor: string, + +inactiveTintColor: string, + +inactiveBackgroundColor: string, + +itemStyle: ViewStyleProp, + +labelStyle: TextStyleProp, + |}>; + + declare export type DrawerContentOptions = $Shape<{| + ...DrawerItemListBaseOptions, + +contentContainerStyle: ViewStyleProp, + +style: ViewStyleProp, + |}>; + + declare type DrawerNavigationBuilderResult = {| + +state: DrawerNavigationState, + +navigation: DrawerNavigationProp<>, + +descriptors: {| +[key: string]: DrawerDescriptor |}, + |}; + + declare export type DrawerContentProps = {| + ...DrawerContentOptions, + ...DrawerNavigationBuilderResult, + +progress: any, // Reanimated.Node + |}; + + declare export type DrawerNavigationConfig = {| + +drawerPosition?: 'left' | 'right', + +drawerType?: 'front' | 'back' | 'slide' | 'permanent', + +edgeWidth?: number, + +hideStatusBar?: boolean, + +keyboardDismissMode?: 'on-drag' | 'none', + +minSwipeDistance?: number, + +overlayColor?: string, + +statusBarAnimation?: 'slide' | 'none' | 'fade', + +gestureHandlerProps?: PanGestureHandlerProps, + +lazy?: boolean, + +drawerContent?: DrawerContentProps => React$Node, + +drawerContentOptions?: DrawerContentOptions, + +sceneContainerStyle?: ViewStyleProp, + +drawerStyle?: ViewStyleProp, + |}; + + declare export type ExtraDrawerNavigatorProps = {| + ...$Exact, + ...DrawerRouterOptions, + ...DrawerNavigationConfig, + |}; + + declare export type DrawerNavigatorProps< + NavProp: InexactDrawerNavigationProp<> = DrawerNavigationProp<>, + > = {| + ...ExtraDrawerNavigatorProps, + ...ScreenOptionsProp, + |}; + + /** + * BaseNavigationContainer + */ + + declare export type BaseNavigationContainerProps = {| + +children: React$Node, + +initialState?: PossiblyStaleNavigationState, + +onStateChange?: (state: ?PossiblyStaleNavigationState) => void, + +independent?: boolean, + |}; + + declare export type ContainerEventMap = {| + ...GlobalEventMap, + +options: {| + +data: {| +options: { +[key: string]: mixed, ... } |}, + +canPreventDefault: false, + |}, + +__unsafe_action__: {| + +data: {| + +action: GenericNavigationAction, + +noop: boolean, + |}, + +canPreventDefault: false, + |}, + |}; + + declare export type BaseNavigationContainerInterface = {| + ...$Exact>, + +setParams: (params: ScreenParams) => void, + +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, + +getRootState: () => PossiblyStaleNavigationState, + |}; + + /** + * State utils + */ + + declare export type GetStateFromPath = ( + path: string, + options?: LinkingConfig, + ) => PossiblyStaleNavigationState; + + declare export type GetPathFromState = ( + state?: ?PossiblyStaleNavigationState, + options?: LinkingConfig, + ) => string; + + declare export type GetFocusedRouteNameFromRoute = + PossiblyStaleRoute => ?string; + + /** + * Linking + */ + + declare export type ScreenLinkingConfig = {| + +path?: string, + +exact?: boolean, + +parse?: {| +[param: string]: string => mixed |}, + +stringify?: {| +[param: string]: mixed => string |}, + +screens?: ScreenLinkingConfigMap, + +initialRouteName?: string, + |}; + + declare export type ScreenLinkingConfigMap = {| + +[routeName: string]: string | ScreenLinkingConfig, + |}; + + declare export type LinkingConfig = {| + +initialRouteName?: string, + +screens: ScreenLinkingConfigMap, + |}; + + declare export type LinkingOptions = {| + +enabled?: boolean, + +prefixes: $ReadOnlyArray, + +config?: LinkingConfig, + +getStateFromPath?: GetStateFromPath, + +getPathFromState?: GetPathFromState, + |}; + + /** + * NavigationContainer + */ + + declare export type Theme = {| + +dark: boolean, + +colors: {| + +primary: string, + +background: string, + +card: string, + +text: string, + +border: string, + |}, + |}; + + declare export type NavigationContainerType = React$AbstractComponent< + {| + ...BaseNavigationContainerProps, + +theme?: Theme, + +linking?: LinkingOptions, + +fallback?: React$Node, + +onReady?: () => mixed, + |}, + BaseNavigationContainerInterface, + >; + + //--------------------------------------------------------------------------- + // SECTION 2: EXPORTED MODULE + // This section defines the module exports and contains exported types that + // are not present in any other React Navigation libdef. + //--------------------------------------------------------------------------- + + /** + * StackView + */ + + declare export var StackView: React$ComponentType<{| + ...StackNavigationConfig, + +state: StackNavigationState, + +navigation: StackNavigationProp<>, + +descriptors: {| +[key: string]: StackDescriptor |}, + |}>; + + /** + * createStackNavigator + */ + + declare export var createStackNavigator: CreateNavigator< + StackNavigationState, + StackOptions, + StackNavigationEventMap, + ExtraStackNavigatorProps, + >; + + /** + * Header components + */ + + declare export var Header: React$ComponentType; + + declare export type StackHeaderTitleProps = $Shape; + declare export var HeaderTitle: React$ComponentType; + + declare export type HeaderBackButtonProps = $Shape<{| + ...StackHeaderLeftButtonProps, + +disabled: boolean, + +accessibilityLabel: string, + |}>; + declare export var HeaderBackButton: React$ComponentType< + HeaderBackButtonProps, + >; + + declare export type HeaderBackgroundProps = $Shape<{ + +children: React$Node, + +style: AnimatedViewStyleProp, + ... + }>; + declare export var HeaderBackground: React$ComponentType< + HeaderBackgroundProps, + >; + + /** + * Style/animation options + */ + + declare export var CardStyleInterpolators: {| + +forHorizontalIOS: StackCardStyleInterpolator, + +forVerticalIOS: StackCardStyleInterpolator, + +forModalPresentationIOS: StackCardStyleInterpolator, + +forFadeFromBottomAndroid: StackCardStyleInterpolator, + +forRevealFromBottomAndroid: StackCardStyleInterpolator, + +forScaleFromCenterAndroid: StackCardStyleInterpolator, + +forNoAnimation: StackCardStyleInterpolator, + |}; + declare export var HeaderStyleInterpolators: {| + +forUIKit: StackHeaderStyleInterpolator, + +forFade: StackHeaderStyleInterpolator, + +forSlideLeft: StackHeaderStyleInterpolator, + +forSlideRight: StackHeaderStyleInterpolator, + +forSlideUp: StackHeaderStyleInterpolator, + +forNoAnimation: StackHeaderStyleInterpolator, + |}; + declare export var TransitionSpecs: {| + +TransitionIOSSpec: TransitionSpec, + +FadeInFromBottomAndroidSpec: TransitionSpec, + +FadeOutToBottomAndroidSpec: TransitionSpec, + +RevealFromBottomAndroidSpec: TransitionSpec, + +ScaleFromCenterAndroidSpec: TransitionSpec, + |}; + declare export var TransitionPresets: {| + +SlideFromRightIOS: TransitionPreset, + +ModalSlideFromBottomIOS: TransitionPreset, + +ModalPresentationIOS: TransitionPreset, + +FadeFromBottomAndroid: TransitionPreset, + +RevealFromBottomAndroid: TransitionPreset, + +ScaleFromCenterAndroid: TransitionPreset, + +DefaultTransition: TransitionPreset, + +ModalTransition: TransitionPreset, + |}; + + /** + * Image assets + */ + + declare export var Assets: $ReadOnlyArray; + + /** + * CardAnimation accessors + */ + + declare export var CardAnimationContext: React$Context< + ?StackCardInterpolationProps, + >; + declare export function useCardAnimation(): StackCardInterpolationProps + + /** + * HeaderHeight accessors + */ + + declare export var HeaderHeightContext: React$Context; + declare export function useHeaderHeight(): number; + + /** + * GestureHandler accessors + */ + + declare type GestureHandlerRef = React$Ref< + React$ComponentType, + >; + declare export var GestureHandlerRefContext: React$Context< + ?GestureHandlerRef, + >; + declare export function useGestureHandlerRef(): GestureHandlerRef; + +} From 8c51a395e9c017577f458413e12fe5698067b13f Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 12 Jan 2021 14:50:26 -0500 Subject: [PATCH 11/25] react-navigation libdef: Move out of `npm` directory, preparing for edits. --- flow-typed/{npm => }/@react-navigation/bottom-tabs_v5.x.x.js | 0 flow-typed/{npm => }/@react-navigation/compat_vx.x.x.js | 0 flow-typed/{npm => }/@react-navigation/drawer_v5.x.x.js | 0 .../{npm => }/@react-navigation/material-top-tabs_v5.x.x.js | 0 flow-typed/{npm => }/@react-navigation/native_v5.x.x.js | 0 flow-typed/{npm => }/@react-navigation/stack_v5.x.x.js | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename flow-typed/{npm => }/@react-navigation/bottom-tabs_v5.x.x.js (100%) rename flow-typed/{npm => }/@react-navigation/compat_vx.x.x.js (100%) rename flow-typed/{npm => }/@react-navigation/drawer_v5.x.x.js (100%) rename flow-typed/{npm => }/@react-navigation/material-top-tabs_v5.x.x.js (100%) rename flow-typed/{npm => }/@react-navigation/native_v5.x.x.js (100%) rename flow-typed/{npm => }/@react-navigation/stack_v5.x.x.js (100%) diff --git a/flow-typed/npm/@react-navigation/bottom-tabs_v5.x.x.js b/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js similarity index 100% rename from flow-typed/npm/@react-navigation/bottom-tabs_v5.x.x.js rename to flow-typed/@react-navigation/bottom-tabs_v5.x.x.js diff --git a/flow-typed/npm/@react-navigation/compat_vx.x.x.js b/flow-typed/@react-navigation/compat_vx.x.x.js similarity index 100% rename from flow-typed/npm/@react-navigation/compat_vx.x.x.js rename to flow-typed/@react-navigation/compat_vx.x.x.js diff --git a/flow-typed/npm/@react-navigation/drawer_v5.x.x.js b/flow-typed/@react-navigation/drawer_v5.x.x.js similarity index 100% rename from flow-typed/npm/@react-navigation/drawer_v5.x.x.js rename to flow-typed/@react-navigation/drawer_v5.x.x.js diff --git a/flow-typed/npm/@react-navigation/material-top-tabs_v5.x.x.js b/flow-typed/@react-navigation/material-top-tabs_v5.x.x.js similarity index 100% rename from flow-typed/npm/@react-navigation/material-top-tabs_v5.x.x.js rename to flow-typed/@react-navigation/material-top-tabs_v5.x.x.js diff --git a/flow-typed/npm/@react-navigation/native_v5.x.x.js b/flow-typed/@react-navigation/native_v5.x.x.js similarity index 100% rename from flow-typed/npm/@react-navigation/native_v5.x.x.js rename to flow-typed/@react-navigation/native_v5.x.x.js diff --git a/flow-typed/npm/@react-navigation/stack_v5.x.x.js b/flow-typed/@react-navigation/stack_v5.x.x.js similarity index 100% rename from flow-typed/npm/@react-navigation/stack_v5.x.x.js rename to flow-typed/@react-navigation/stack_v5.x.x.js From f92a8e288a7f618fce041e10ba0c975605ea2028 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 13 Jan 2021 17:14:15 -0500 Subject: [PATCH 12/25] prettier: Ignore flow-typed/@react-navigation. As Greg points out [1], it's best to smoothen the path to making a PR to the FlowTyped repo with the changes we're about to make to this libdef. That means not converting it to our own style, which means telling Prettier and ESLint to ignore these files. ESLint already ignores them because of the `**/flow-typed/**` line in `.eslintignore`. [1] https://github.com/zulip/zulip-mobile/pull/4393#discussion_r556853806 --- .prettierignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.prettierignore b/.prettierignore index 1bac849192e..4f67be67761 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,4 +2,9 @@ src/emoji/__tests__/data-test.js # We're not allowing Prettier to touch some of our vendored code. -src/third/redux-persist \ No newline at end of file +src/third/redux-persist + +# We'd like to keep the original formatting for some Flow libdefs from +# FlowTyped, to make it easier to eventually make a PR back to +# FlowTyped. +flow-typed/@react-navigation From f7c1629a4d31d5e5dcacef8a2817263542dcf57a Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 12 Jan 2021 14:55:04 -0500 Subject: [PATCH 13/25] react-navigation libdef: Make *NavigationProp covariant in RouteName param. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When we make our own types based on `StackNavigationProp` -- e.g., when we define `AppNavigationProp`, in an upcoming commit -- we'll want those types to be covariant in their own `RouteName` param. That's because we want, e.g., `AppNavigationProp<'realm'>` to be recognized as a subtype of `AppNavigationProp<'realm' | 'account' | …>`, i.e., `AppNavigationProp<$Keys>`. So, start by making `NavigationProp`, `StackNavigationProp`, and `InexactStackNavigationProp` covariant in their `RouteName` params, following discussion at https://github.com/zulip/zulip-mobile/pull/4393#discussion_r555412574. Also make the change for types of navigators other than stack navigators, across all the libdef files. There's a lot of repetition because libdef files can't import types from other files [1]. [1] https://github.com/zulip/zulip-mobile/issues/3458#issuecomment-639859987 --- .../@react-navigation/bottom-tabs_v5.x.x.js | 24 +++++++++---------- flow-typed/@react-navigation/drawer_v5.x.x.js | 24 +++++++++---------- .../material-top-tabs_v5.x.x.js | 24 +++++++++---------- flow-typed/@react-navigation/native_v5.x.x.js | 24 +++++++++---------- flow-typed/@react-navigation/stack_v5.x.x.js | 24 +++++++++---------- 5 files changed, 60 insertions(+), 60 deletions(-) diff --git a/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js b/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js index e2f0db0af64..8ee193b006e 100644 --- a/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js +++ b/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js @@ -830,7 +830,7 @@ declare module '@react-navigation/bottom-tabs' { declare export type NavigationProp< ParamList: ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, ScreenOptions: {...} = {...}, EventMap: EventMapBase = EventMapCore, @@ -1261,7 +1261,7 @@ declare module '@react-navigation/bottom-tabs' { declare type InexactStackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = { @@ -1281,7 +1281,7 @@ declare module '@react-navigation/bottom-tabs' { declare export type StackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = $Exact, + +RouteName: $Keys, Options: {...}, EventMap: EventMapBase, > = { @@ -1374,7 +1374,7 @@ declare module '@react-navigation/bottom-tabs' { declare export type InexactBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1386,7 +1386,7 @@ declare module '@react-navigation/bottom-tabs' { declare export type BottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1492,7 +1492,7 @@ declare module '@react-navigation/bottom-tabs' { declare export type MaterialBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1640,7 +1640,7 @@ declare module '@react-navigation/bottom-tabs' { declare export type MaterialTopTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = { @@ -1820,7 +1820,7 @@ declare module '@react-navigation/bottom-tabs' { declare export type DrawerNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, ScreenOptions: {...} = {...}, EventMap: EventMapBase = EventMapCore, @@ -1261,7 +1261,7 @@ declare module '@react-navigation/drawer' { declare type InexactStackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = { @@ -1281,7 +1281,7 @@ declare module '@react-navigation/drawer' { declare export type StackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = $Exact, + +RouteName: $Keys, Options: {...}, EventMap: EventMapBase, > = { @@ -1374,7 +1374,7 @@ declare module '@react-navigation/drawer' { declare export type InexactBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1386,7 +1386,7 @@ declare module '@react-navigation/drawer' { declare export type BottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1492,7 +1492,7 @@ declare module '@react-navigation/drawer' { declare export type MaterialBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1640,7 +1640,7 @@ declare module '@react-navigation/drawer' { declare export type MaterialTopTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = { @@ -1820,7 +1820,7 @@ declare module '@react-navigation/drawer' { declare export type DrawerNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, ScreenOptions: {...} = {...}, EventMap: EventMapBase = EventMapCore, @@ -1261,7 +1261,7 @@ declare module '@react-navigation/material-top-tabs' { declare type InexactStackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = { @@ -1281,7 +1281,7 @@ declare module '@react-navigation/material-top-tabs' { declare export type StackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = $Exact, + +RouteName: $Keys, Options: {...}, EventMap: EventMapBase, > = { @@ -1374,7 +1374,7 @@ declare module '@react-navigation/material-top-tabs' { declare export type InexactBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1386,7 +1386,7 @@ declare module '@react-navigation/material-top-tabs' { declare export type BottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1492,7 +1492,7 @@ declare module '@react-navigation/material-top-tabs' { declare export type MaterialBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1640,7 +1640,7 @@ declare module '@react-navigation/material-top-tabs' { declare export type MaterialTopTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = { @@ -1820,7 +1820,7 @@ declare module '@react-navigation/material-top-tabs' { declare export type DrawerNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, ScreenOptions: {...} = {...}, EventMap: EventMapBase = EventMapCore, @@ -1261,7 +1261,7 @@ declare module '@react-navigation/native' { declare type InexactStackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = { @@ -1281,7 +1281,7 @@ declare module '@react-navigation/native' { declare export type StackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = $Exact, + +RouteName: $Keys, Options: {...}, EventMap: EventMapBase, > = { @@ -1374,7 +1374,7 @@ declare module '@react-navigation/native' { declare export type InexactBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1386,7 +1386,7 @@ declare module '@react-navigation/native' { declare export type BottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1492,7 +1492,7 @@ declare module '@react-navigation/native' { declare export type MaterialBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1640,7 +1640,7 @@ declare module '@react-navigation/native' { declare export type MaterialTopTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = { @@ -1820,7 +1820,7 @@ declare module '@react-navigation/native' { declare export type DrawerNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, State: PossiblyStaleNavigationState = PossiblyStaleNavigationState, ScreenOptions: {...} = {...}, EventMap: EventMapBase = EventMapCore, @@ -1261,7 +1261,7 @@ declare module '@react-navigation/stack' { declare type InexactStackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = { @@ -1281,7 +1281,7 @@ declare module '@react-navigation/stack' { declare export type StackNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = StackOptions, EventMap: EventMapBase = StackNavigationEventMap, > = $Exact, + +RouteName: $Keys, Options: {...}, EventMap: EventMapBase, > = { @@ -1374,7 +1374,7 @@ declare module '@react-navigation/stack' { declare export type InexactBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1386,7 +1386,7 @@ declare module '@react-navigation/stack' { declare export type BottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = BottomTabOptions, EventMap: EventMapBase = BottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1492,7 +1492,7 @@ declare module '@react-navigation/stack' { declare export type MaterialBottomTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialBottomTabOptions, EventMap: EventMapBase = MaterialBottomTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = InexactTabNavigationProp< @@ -1640,7 +1640,7 @@ declare module '@react-navigation/stack' { declare export type MaterialTopTabNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = MaterialTopTabOptions, EventMap: EventMapBase = MaterialTopTabNavigationEventMap, > = $Exact = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = { @@ -1820,7 +1820,7 @@ declare module '@react-navigation/stack' { declare export type DrawerNavigationProp< ParamList: ParamListBase = ParamListBase, - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, Options: {...} = DrawerOptions, EventMap: EventMapBase = DrawerNavigationEventMap, > = $Exact Date: Wed, 13 Jan 2021 12:04:30 -0500 Subject: [PATCH 14/25] react-navigation libdef: Fix `getRootState`. It seems that `PossiblyStaleNavigtionState` [1] is the Flow libdef's version of what appears in the TypeScript as `PartialState` [2]. In contrast with the Flow libdef, the TypeScript has `getRootState` returning the non-"partial", non-"possibly stale" thing, i.e., `NavigationState` [3]. That suggests we should consider making the Flow libdef say the same thing, which also has the name `NavigationState`. React Navigation does have a doc on "Partial state objects" [4]. Based on that, Greg points out [5] that a "stale" nav state is accepted as input to various React Navigation options, but a non-stale state is always the output -- suggesting that that the return value of something like `getRootState` should surely not be stale. Some logging confirms that there aren't prominent cases where `stale` is `true` or missing. (Any such cases would suggest that we should keep the `PossiblyStaleNavigationState` return type.) See discussion [6]. [1] https://github.com/flow-typed/flow-typed/blob/master/definitions/npm/%40react-navigation/native_v5.x.x/flow_v0.104.x-/native_v5.x.x.js#L526 [2] https://github.com/react-navigation/react-navigation/blob/main/packages/routers/src/types.tsx#L58 [3] https://github.com/react-navigation/react-navigation/blob/main/packages/core/src/types.tsx#L471 [4] https://reactnavigation.org/docs/navigation-state/#partial-state-objects [5] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20.60PossiblyStaleNavigationState.60/near/1097141 [6] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20.60PossiblyStaleNavigationState.60/near/1096924 --- flow-typed/@react-navigation/bottom-tabs_v5.x.x.js | 2 +- flow-typed/@react-navigation/drawer_v5.x.x.js | 2 +- flow-typed/@react-navigation/material-top-tabs_v5.x.x.js | 2 +- flow-typed/@react-navigation/native_v5.x.x.js | 2 +- flow-typed/@react-navigation/stack_v5.x.x.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js b/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js index 8ee193b006e..a2804d8d8ee 100644 --- a/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js +++ b/flow-typed/@react-navigation/bottom-tabs_v5.x.x.js @@ -1930,7 +1930,7 @@ declare module '@react-navigation/bottom-tabs' { >>, +setParams: (params: ScreenParams) => void, +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, - +getRootState: () => PossiblyStaleNavigationState, + +getRootState: () => NavigationState, |}; /** diff --git a/flow-typed/@react-navigation/drawer_v5.x.x.js b/flow-typed/@react-navigation/drawer_v5.x.x.js index 91aa05764b3..b2cf468edd1 100644 --- a/flow-typed/@react-navigation/drawer_v5.x.x.js +++ b/flow-typed/@react-navigation/drawer_v5.x.x.js @@ -1930,7 +1930,7 @@ declare module '@react-navigation/drawer' { >>, +setParams: (params: ScreenParams) => void, +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, - +getRootState: () => PossiblyStaleNavigationState, + +getRootState: () => NavigationState, |}; /** diff --git a/flow-typed/@react-navigation/material-top-tabs_v5.x.x.js b/flow-typed/@react-navigation/material-top-tabs_v5.x.x.js index 11dba0baf28..300781d34e4 100644 --- a/flow-typed/@react-navigation/material-top-tabs_v5.x.x.js +++ b/flow-typed/@react-navigation/material-top-tabs_v5.x.x.js @@ -1930,7 +1930,7 @@ declare module '@react-navigation/material-top-tabs' { >>, +setParams: (params: ScreenParams) => void, +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, - +getRootState: () => PossiblyStaleNavigationState, + +getRootState: () => NavigationState, |}; /** diff --git a/flow-typed/@react-navigation/native_v5.x.x.js b/flow-typed/@react-navigation/native_v5.x.x.js index 1a0aa8ceeb1..08724e02fb3 100644 --- a/flow-typed/@react-navigation/native_v5.x.x.js +++ b/flow-typed/@react-navigation/native_v5.x.x.js @@ -1930,7 +1930,7 @@ declare module '@react-navigation/native' { >>, +setParams: (params: ScreenParams) => void, +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, - +getRootState: () => PossiblyStaleNavigationState, + +getRootState: () => NavigationState, |}; /** diff --git a/flow-typed/@react-navigation/stack_v5.x.x.js b/flow-typed/@react-navigation/stack_v5.x.x.js index de1c7e84276..9e82f8e04ec 100644 --- a/flow-typed/@react-navigation/stack_v5.x.x.js +++ b/flow-typed/@react-navigation/stack_v5.x.x.js @@ -1930,7 +1930,7 @@ declare module '@react-navigation/stack' { >>, +setParams: (params: ScreenParams) => void, +resetRoot: (state?: ?PossiblyStaleNavigationState) => void, - +getRootState: () => PossiblyStaleNavigationState, + +getRootState: () => NavigationState, |}; /** From 12284502bb68df733ed1f384bd5da5944b56e7fe Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 13 Oct 2020 17:49:12 -0700 Subject: [PATCH 15/25] deps: Upgrade to React Navigation v5. Done mostly with the upgrade guide at https://reactnavigation.org/docs/upgrading-from-4.x, but also by consulting the v4 and v5 documentation of specific areas. In this commit: - Take the packages' name changes (e.g., react-navigation -> @react-navigation/native) - Add react-native-tab-view to handle a peer-dep warning: warning " > @react-navigation/material-top-tabs@5.2.19" has unmet peer dependency "react-native-tab-view@>= 2.0.0". - Run the usual `yarn yarn-deduplicate && yarn`. - Use the newly available `NavigationContainer` instead of the removed `createAppContainer`. We leave it in its own file (src/nav/Zulip { App -> Navigation } Container.js), since it still has to handle some special logic: - setting up the NavigationService with a ref (the initialization gets slightly more complicated, with the `onReady` prop) - deciding what to pass for the `theme` prop, based on the current theme (for more discussion of our use of this prop, see the recent commit where we started passing it) - Update `NavigationService` to handle the new shape of the thing it tracks with a ref (`AppContainer` -> `NavigationContainer`), and handle some new initialization logic for `NavigationContainer` (its `onReady` prop). - Change `MessageReactionList` over to the new component-based API [1], without going through @react-navigation/compat first. (It's small and self-contained.) - Undo f4b82535a, i.e., stop threading through `navigation` prop and assigning to `static router` in MainScreenWithTabs. The "common mistakes" doc that prescribed those things has been removed in v5, and, empirically, everything works fine without it. - Use @react-navigation/compat to reduce the size of this commit (we'll incrementally move away from it in the upcoming commits). (Note that that package is completely untyped [2] -- this causes Flow to misleadingly mark some `$FlowFixMe`s unnecessary; still, we go along with Flow and remove them -- but once we've completely adopted the v5 APIs, our types should be stronger than before.) There are a few things we use the compat package for [3]: - Postpone changes to the definitions of our four navigators: `AppNavigator`, `MainTabs`, `StreamTabs`, and `SharingScreen`, with `createCompatNavigatorFactory`. - In `navActions`, postpone taking the new interfaces of various action creators (`StackActions.push`, etc.). This isn't possible with `.reset` actions, but we only use three of those, so we change them in this commit. - Keep using the `withNavigationFocus` HOC, so we can switch to the new custom Hook later. And a few minor naming / simple API tweaks: - In `SmartUrlInput`, use the 'focus' event type instead of the now-removed one, 'didFocus', and adapt to the new API for removing a listener. - What used to be called `routeName` on a route in the navigation state is now called `name`. - Even though we're using `createCompatNavigatorFactory`, we have to access `tintColor` instead of `color` on the object passed to the function we pass to `tabBarLabel` and `tabBarIcon` in a route config on a tab navigator. - Various types are renamed, like `NavigationParams` -> `ScreenParams`. - Apparently `upperCaseLabel` in a tab navigator's config...vanished in this new version. Add a TODO with findings from a GitHub discussion about this [4]. [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20MessageReactionList/near/1061924 [2] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5/near/1046571 [3] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20compat/near/1058109 [4] https://github.com/zulip/zulip-mobile/pull/4393#discussion_r555413595 --- package.json | 11 +- src/ZulipMobile.js | 4 +- src/chat/ChatScreen.js | 2 +- src/common/SmartUrlInput.js | 19 +- src/main/MainScreenWithTabs.js | 4 +- src/main/MainTabs.js | 21 +- src/main/StreamTabs.js | 15 +- src/message/fetchActions.js | 2 +- src/nav/AppNavigator.js | 25 +-- src/nav/ConfiguredNavigationContainer.js | 0 src/nav/NavigationService.js | 33 ++-- ...ntainer.js => ZulipNavigationContainer.js} | 61 +++--- src/nav/__tests__/navSelectors-test.js | 22 +-- src/nav/getInitialRouteInfo.js | 4 +- src/nav/navActions.js | 18 +- src/nav/navSelectors.js | 10 +- src/reactions/MessageReactionList.js | 41 ++-- src/sharing/SharingScreen.js | 15 +- src/styles/tabs.js | 31 +-- yarn.lock | 185 +++++++++--------- 20 files changed, 261 insertions(+), 262 deletions(-) create mode 100644 src/nav/ConfiguredNavigationContainer.js rename src/nav/{ZulipAppContainer.js => ZulipNavigationContainer.js} (57%) diff --git a/package.json b/package.json index 679236d6512..05d2f9d845a 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,12 @@ "@react-native-community/cameraroll": "^1.7.2", "@react-native-community/masked-view": "^0.1.10", "@react-native-community/netinfo": "^5.9.5", + "@react-navigation/bottom-tabs": "^5.10.6", + "@react-navigation/compat": "^5.3.9", + "@react-navigation/drawer": "^5.9.3", + "@react-navigation/material-top-tabs": "^5.2.19", + "@react-navigation/native": "^5.7.6", + "@react-navigation/stack": "^5.9.3", "@sentry/react-native": "^1.0.9", "@unimodules/core": "~5.3.0", "@zulip/shared": "^0.0.4", @@ -72,15 +78,12 @@ "react-native-screens": "^2.10.1", "react-native-simple-toast": "^1.0.0", "react-native-sound": "^0.11.0", + "react-native-tab-view": "^2.15.2", "react-native-text-input-reset": "^1.0.2", "react-native-unimodules": "^0.10.1", "react-native-url-polyfill": "1.2.0-rc.0", "react-native-vector-icons": "^7.1.0", "react-native-webview": "^10.1.0", - "react-navigation": "^4.4.0", - "react-navigation-drawer": "^2.5.0", - "react-navigation-stack": "^2.8.2", - "react-navigation-tabs": "^2.9.0", "react-redux": "^7.2.1", "redux": "^4.0.0", "redux-action-buffer": "^1.2.0", diff --git a/src/ZulipMobile.js b/src/ZulipMobile.js index 7496153f7fa..61d288a81c5 100644 --- a/src/ZulipMobile.js +++ b/src/ZulipMobile.js @@ -4,6 +4,7 @@ import 'react-native-url-polyfill/auto'; import { SafeAreaProvider } from 'react-native-safe-area-context'; import { BRAND_COLOR } from './styles'; +import ZulipNavigationContainer from './nav/ZulipNavigationContainer'; import StoreProvider from './boot/StoreProvider'; import HideIfNotHydrated from './boot/HideIfNotHydrated'; import TranslationProvider from './boot/TranslationProvider'; @@ -12,7 +13,6 @@ import CompatibilityChecker from './boot/CompatibilityChecker'; import AppEventHandlers from './boot/AppEventHandlers'; import AppDataFetcher from './boot/AppDataFetcher'; import BackNavigationHandler from './nav/BackNavigationHandler'; -import ZulipAppContainer from './nav/ZulipAppContainer'; import { initializeSentry } from './sentry'; import LoadingScreen from './start/LoadingScreen'; @@ -37,7 +37,7 @@ export default (): React$Node => ( - + diff --git a/src/chat/ChatScreen.js b/src/chat/ChatScreen.js index d3d11d20b25..5051483cc0d 100644 --- a/src/chat/ChatScreen.js +++ b/src/chat/ChatScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React from 'react'; import { View } from 'react-native'; -import { withNavigationFocus } from 'react-navigation'; +import { withNavigationFocus } from '@react-navigation/compat'; import { ActionSheetProvider } from '@expo/react-native-action-sheet'; import { compose } from 'redux'; diff --git a/src/common/SmartUrlInput.js b/src/common/SmartUrlInput.js index 1408734782a..e07adc53571 100644 --- a/src/common/SmartUrlInput.js +++ b/src/common/SmartUrlInput.js @@ -2,12 +2,8 @@ import React, { PureComponent } from 'react'; import { TextInput, TouchableWithoutFeedback, View } from 'react-native'; import type { ViewStyleProp } from 'react-native/Libraries/StyleSheet/StyleSheet'; -import type { - NavigationEventSubscription, - NavigationScreenProp, - NavigationState, -} from 'react-navigation'; +import type { AppNavigationProp } from '../nav/AppNavigator'; import type { ThemeData } from '../styles'; import { ThemeContext, createStyleSheet } from '../styles'; import { autocompleteRealmPieces, autocompleteRealm, fixRealmUrl } from '../utils/url'; @@ -49,7 +45,10 @@ type Props = $ReadOnly<{| * it appears not to contain an explicit domain. */ defaultDomain: string, - navigation: NavigationScreenProp, + // TODO: Currently this type is acceptable because the only + // `navigation` prop we pass to a `SmartUrlInput` instance is the + // one from a component on AppNavigator. + navigation: AppNavigationProp<>, style?: ViewStyleProp, onChangeText: (value: string) => void, onSubmitEditing: () => Promise, @@ -71,10 +70,10 @@ export default class SmartUrlInput extends PureComponent { value: '', }; textInputRef = React.createRef(); - focusListener: void | NavigationEventSubscription; + unsubscribeFocusListener: () => void; componentDidMount() { - this.focusListener = this.props.navigation.addListener('didFocus', () => { + this.unsubscribeFocusListener = this.props.navigation.addListener('focus', () => { if (this.textInputRef.current) { // Should be fixed in RN v0.63 (#4245); see // https://github.com/zulip/zulip-mobile/issues/4245#issuecomment-695104351. @@ -85,8 +84,8 @@ export default class SmartUrlInput extends PureComponent { } componentWillUnmount() { - if (this.focusListener) { - this.focusListener.remove(); + if (this.unsubscribeFocusListener) { + this.unsubscribeFocusListener(); } } diff --git a/src/main/MainScreenWithTabs.js b/src/main/MainScreenWithTabs.js index b35a1f21745..fb4fd2f608a 100644 --- a/src/main/MainScreenWithTabs.js +++ b/src/main/MainScreenWithTabs.js @@ -19,8 +19,6 @@ type Props = $ReadOnly<{| |}>; class MainScreenWithTabs extends PureComponent { - static router = MainTabs.router; - static contextType = ThemeContext; context: ThemeData; @@ -40,7 +38,7 @@ class MainScreenWithTabs extends PureComponent { - + ); } diff --git a/src/main/MainTabs.js b/src/main/MainTabs.js index 0f59f0fe35d..11050959748 100644 --- a/src/main/MainTabs.js +++ b/src/main/MainTabs.js @@ -1,11 +1,12 @@ /* @flow strict-local */ import React from 'react'; import { Platform } from 'react-native'; +import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { - createBottomTabNavigator, + createCompatNavigatorFactory, type NavigationTabProp, type NavigationStateRoute, -} from 'react-navigation-tabs'; +} from '@react-navigation/compat'; import type { GlobalParamList } from '../nav/globalTypes'; import { bottomTabNavigatorConfig } from '../styles/tabs'; @@ -27,47 +28,43 @@ export type MainTabsNavigatorParamList = {| |}; export type MainTabsNavigationProp< - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, > = NavigationTabProp<{| ...NavigationStateRoute, params: $ElementType, |}>; -export default createBottomTabNavigator( +export default createCompatNavigatorFactory(createBottomTabNavigator)( { home: { - // $FlowFixMe react-navigation types are twisty and seem wrong screen: HomeTab, navigationOptions: { tabBarLabel: 'Home', - tabBarIcon: props => , + tabBarIcon: props => , }, }, streams: { screen: StreamTabs, navigationOptions: { tabBarLabel: 'Streams', - tabBarIcon: props => , + tabBarIcon: props => , }, }, conversations: { - // $FlowFixMe react-navigation types are twisty and seem wrong screen: PmConversationsCard, navigationOptions: { tabBarLabel: 'Conversations', - tabBarIcon: props => , + tabBarIcon: props => , }, }, settings: { - // $FlowFixMe react-navigation types are twisty and seem wrong screen: SettingsCard, navigationOptions: { tabBarLabel: 'Settings', - tabBarIcon: props => , + tabBarIcon: props => , }, }, profile: { - // $FlowFixMe react-navigation types are twisty and seem wrong screen: ProfileCard, navigationOptions: { tabBarLabel: 'Profile', diff --git a/src/main/StreamTabs.js b/src/main/StreamTabs.js index 28a6605400a..e29e727c654 100644 --- a/src/main/StreamTabs.js +++ b/src/main/StreamTabs.js @@ -2,11 +2,12 @@ import React from 'react'; import { Text } from 'react-native'; import { FormattedMessage } from 'react-intl'; +import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'; import { - createMaterialTopTabNavigator, + createCompatNavigatorFactory, type NavigationTabProp, type NavigationStateRoute, -} from 'react-navigation-tabs'; +} from '@react-navigation/compat'; import type { GlobalParamList } from '../nav/globalTypes'; import { createStyleSheet } from '../styles'; @@ -20,7 +21,7 @@ export type StreamTabsNavigatorParamList = {| |}; export type StreamTabsNavigationProp< - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, > = NavigationTabProp<{| ...NavigationStateRoute, params: $ElementType, @@ -33,25 +34,23 @@ const styles = createStyleSheet({ }, }); -export default createMaterialTopTabNavigator( +export default createCompatNavigatorFactory(createMaterialTopTabNavigator)( { subscribed: { - // $FlowFixMe react-navigation types are twisty and seem wrong screen: SubscriptionsCard, navigationOptions: { tabBarLabel: props => ( - + ), }, }, allStreams: { - // $FlowFixMe react-navigation types are twisty and seem wrong screen: StreamListCard, navigationOptions: { tabBarLabel: props => ( - + ), diff --git a/src/message/fetchActions.js b/src/message/fetchActions.js index 43b153cc289..a7d695abc97 100644 --- a/src/message/fetchActions.js +++ b/src/message/fetchActions.js @@ -172,7 +172,7 @@ const initialFetchCompletePlain = (): Action => ({ }); export const initialFetchComplete = () => async (dispatch: Dispatch, getState: GetState) => { - if (!getNavigationRoutes().some(navigationRoute => navigationRoute.routeName === 'main')) { + if (!getNavigationRoutes().some(navigationRoute => navigationRoute.name === 'main')) { // If we're anywhere in the normal UI of the app, then remain // where we are. Only reset the nav state if we're elsewhere, // and in that case, go to the main screen. diff --git a/src/nav/AppNavigator.js b/src/nav/AppNavigator.js index 2abcb3aca6d..e0735050f58 100644 --- a/src/nav/AppNavigator.js +++ b/src/nav/AppNavigator.js @@ -1,21 +1,13 @@ /* @flow strict-local */ import { Platform } from 'react-native'; -import type { NavigationParams } from 'react-navigation'; +import type { ScreenParams } from '@react-navigation/native'; +import { createStackNavigator, TransitionPresets } from '@react-navigation/stack'; import { - createStackNavigator, + createCompatNavigatorFactory, type NavigationNavigator, - // The FlowTyped libdef skips v2; there's one for - // `react-navigation-stack` v1 (we're using that one), and there's - // one for `@react-navigation/stack` v5, which we'll use when we're - // on React Navigation v5. `TransitionPresets` is missing in the v1 - // libdef. We could go add it in ourselves, but our use of it is - // small and isolated, so we might as well wait for the - // `@react-navigation/stack` libdef. - // $FlowFixMe - TransitionPresets, type NavigationStackProp, - type NavigationStateRoute, -} from 'react-navigation-stack'; + NavigationStateRoute, +} from '@react-navigation/compat'; import type { Narrow, Message, SharedData } from '../types'; import type { ApiResponseServerSettings } from '../api/settings/getServerSettings'; @@ -87,7 +79,7 @@ export type AppNavigatorParamList = {| |}; export type AppNavigationProp< - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, > = NavigationStackProp<{| ...NavigationStateRoute, params: $ElementType, @@ -95,11 +87,10 @@ export type AppNavigationProp< export const createAppNavigator = (args: {| initialRouteName: string, - initialRouteParams?: NavigationParams, + initialRouteParams?: ScreenParams, // flowlint-next-line deprecated-type:off |}): NavigationNavigator<*, *, *> => - createStackNavigator( - // $FlowFixMe react-navigation types :-/ -- see a36814e80 + createCompatNavigatorFactory(createStackNavigator)( { account: { screen: AccountPickScreen }, 'account-details': { screen: AccountDetailsScreen }, diff --git a/src/nav/ConfiguredNavigationContainer.js b/src/nav/ConfiguredNavigationContainer.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/nav/NavigationService.js b/src/nav/NavigationService.js index 8e54006c774..4ef524b8bee 100644 --- a/src/nav/NavigationService.js +++ b/src/nav/NavigationService.js @@ -1,32 +1,25 @@ /* @flow strict-local */ import React from 'react'; import type { - NavigationAction, + GenericNavigationAction, NavigationState, - NavigationContainer, - NavigationContainerProps, -} from 'react-navigation'; + NavigationContainerType, +} from '@react-navigation/native'; -/* prettier-ignore */ -export const appContainerRef = React.createRef< - React$ElementRef< - NavigationContainer< - NavigationState, - { ... }, - NavigationContainerProps<{ ... }, NavigationState>>> ->(); +export const isReadyRef = React.createRef(); +export const navigationContainerRef = React.createRef>(); const getContainer = () => { - if (appContainerRef.current === null) { - throw new Error('Tried to use NavigationService before appContainerRef was set.'); + if (navigationContainerRef.current === null) { + throw new Error('Tried to use NavigationService before `navigationContainerRef` was set.'); } - return appContainerRef.current; + if (isReadyRef.current !== true) { + throw new Error('Tried to use NavigationService before `NavigationContainer` was ready.'); + } + return navigationContainerRef.current; }; -export const getState = (): NavigationState => - // https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/decouple.20nav.20from.20redux.20%28.23M3804%29/near/1056167 - // $FlowFixMe - getContainer().state.nav; +export const getState = (): NavigationState => getContainer().getRootState(); -export const dispatch = (navigationAction: NavigationAction): boolean => +export const dispatch = (navigationAction: GenericNavigationAction): void => getContainer().dispatch(navigationAction); diff --git a/src/nav/ZulipAppContainer.js b/src/nav/ZulipNavigationContainer.js similarity index 57% rename from src/nav/ZulipAppContainer.js rename to src/nav/ZulipNavigationContainer.js index 6833332e466..780e3d9c9ef 100644 --- a/src/nav/ZulipAppContainer.js +++ b/src/nav/ZulipNavigationContainer.js @@ -1,11 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import { - createAppContainer, - type NavigationState, - type NavigationContainerProps, - type NavigationContainer, -} from 'react-navigation'; +import { NavigationContainer, DefaultTheme, DarkTheme } from '@react-navigation/native'; +import type { NavigationNavigator } from '@react-navigation/compat'; import { connect } from '../react-redux'; import type { ThemeData } from '../styles'; @@ -42,35 +38,50 @@ class ZulipAppContainer extends PureComponent { static contextType = ThemeContext; context: ThemeData; - // (odd spacing choices) - // eslint-disable-next-line - AppContainer: NavigationContainer< - NavigationState, - { ... }, - NavigationContainerProps<{ ... }, NavigationState>, - >; + // flowlint deprecated-type:off + AppNavigator: NavigationNavigator<*, *, *>; constructor(props: Props) { super(props); const { hasAuth, accounts, haveServerData } = this.props; - this.AppContainer = createAppContainer( - createAppNavigator(getInitialRouteInfo({ hasAuth, accounts, haveServerData })), + this.AppNavigator = createAppNavigator( + getInitialRouteInfo({ hasAuth, accounts, haveServerData }), ); } + componentWillUnmount() { + NavigationService.isReadyRef.current = false; + } + render() { - const { AppContainer } = this; - const { theme } = this.props; + const { AppNavigator } = this; + + const { theme: themeName } = this.props; + + const BaseTheme = themeName === 'night' ? DarkTheme : DefaultTheme; + + const theme = { + ...BaseTheme, + dark: themeName === 'night', + colors: { + ...BaseTheme.colors, + primary: this.context.color, + background: this.context.backgroundColor, + card: this.context.cardColor, + border: this.context.dividerColor, + }, + }; return ( - // The `theme` prop is documented, but apparently not included - // in the type we're using: - // https://reactnavigation.org/docs/4.x/themes/ - // $FlowFixMe - + { + NavigationService.isReadyRef.current = true; + }} + theme={theme} + > + + ); } } diff --git a/src/nav/__tests__/navSelectors-test.js b/src/nav/__tests__/navSelectors-test.js index e06d916ccc7..b83bda48b70 100644 --- a/src/nav/__tests__/navSelectors-test.js +++ b/src/nav/__tests__/navSelectors-test.js @@ -14,8 +14,8 @@ describe('getCurrentRouteName', () => { deepFreeze({ index: 1, routes: [ - { routeName: 'first', params: { email: 'a@a.com' } }, - { routeName: 'second', params: { email: 'b@a.com' } }, + { name: 'first', params: { email: 'a@a.com' } }, + { name: 'second', params: { email: 'b@a.com' } }, ], }), ); @@ -34,8 +34,8 @@ describe('getCurrentRouteParams', () => { deepFreeze({ index: 1, routes: [ - { routeName: 'first', params: { email: 'a@a.com' } }, - { routeName: 'second', params: { email: 'b@a.com' } }, + { name: 'first', params: { email: 'a@a.com' } }, + { name: 'second', params: { email: 'b@a.com' } }, ], }), ); @@ -52,7 +52,7 @@ describe('getChatScreenParams', () => { NavigationService.getState = jest.fn().mockReturnValue( deepFreeze({ index: 0, - routes: [{ routeName: 'chat' }], + routes: [{ name: 'chat' }], }), ); @@ -78,7 +78,7 @@ describe('getSameRoutesCount', () => { test('if last route differs from routes the count of same routes is 0', () => { NavigationService.getState = jest.fn().mockReturnValue( deepFreeze({ - routes: [{ routeName: 'main' }, { routeName: 'chat' }], + routes: [{ name: 'main' }, { name: 'chat' }], }), ); @@ -91,11 +91,11 @@ describe('getSameRoutesCount', () => { NavigationService.getState = jest.fn().mockReturnValue( deepFreeze({ routes: [ - { routeName: 'login' }, - { routeName: 'main' }, - { routeName: 'chat', params: { key: 'value' } }, - { routeName: 'chat', params: { key: 'another value' } }, - { routeName: 'chat', params: { anotherKey: 'some value' } }, + { name: 'login' }, + { name: 'main' }, + { name: 'chat', params: { key: 'value' } }, + { name: 'chat', params: { key: 'another value' } }, + { name: 'chat', params: { anotherKey: 'some value' } }, ], }), ); diff --git a/src/nav/getInitialRouteInfo.js b/src/nav/getInitialRouteInfo.js index 7136928a776..45f1314768e 100644 --- a/src/nav/getInitialRouteInfo.js +++ b/src/nav/getInitialRouteInfo.js @@ -1,6 +1,6 @@ /* @flow strict-local */ -import type { NavigationParams } from 'react-navigation'; +import type { ScreenParams } from '@react-navigation/native'; import type { Account } from '../types'; @@ -8,7 +8,7 @@ export default (args: {| hasAuth: boolean, accounts: Account[], haveServerData: boolean, -|}): {| initialRouteName: string, initialRouteParams?: NavigationParams |} => { +|}): {| initialRouteName: string, initialRouteParams?: ScreenParams |} => { const { hasAuth, accounts, haveServerData } = args; // If the active account is not logged in, bring the user as close diff --git a/src/nav/navActions.js b/src/nav/navActions.js index b5f9827aa9f..6db243484a0 100644 --- a/src/nav/navActions.js +++ b/src/nav/navActions.js @@ -1,5 +1,6 @@ /* @flow strict-local */ -import { StackActions, NavigationActions, type NavigationAction } from 'react-navigation'; +import { StackActions, type NavigationAction } from '@react-navigation/compat'; +import { CommonActions, type GenericNavigationAction } from '@react-navigation/native'; import type { Message, Narrow, SharedData } from '../types'; import type { ApiResponseServerSettings } from '../api/settings/getServerSettings'; @@ -11,14 +12,17 @@ export const navigateBack = (): NavigationAction => StackActions.pop({ n: getSam * "Reset" actions, to explicitly prohibit back navigation. */ -export const resetToLoading = (): NavigationAction => - StackActions.reset({ index: 0, actions: [NavigationActions.navigate({ routeName: 'loading' })] }); +export const resetToLoading = (): GenericNavigationAction => + CommonActions.reset({ + index: 0, + routes: [{ name: 'loading' }], + }); -export const resetToAccountPicker = (): NavigationAction => - StackActions.reset({ index: 0, actions: [NavigationActions.navigate({ routeName: 'account' })] }); +export const resetToAccountPicker = (): GenericNavigationAction => + CommonActions.reset({ index: 0, routes: [{ name: 'account' }] }); -export const resetToMainTabs = (): NavigationAction => - StackActions.reset({ index: 0, actions: [NavigationActions.navigate({ routeName: 'main' })] }); +export const resetToMainTabs = (): GenericNavigationAction => + CommonActions.reset({ index: 0, routes: [{ name: 'main' }] }); /* * Ordinary "push" actions that will push to the stack. diff --git a/src/nav/navSelectors.js b/src/nav/navSelectors.js index 6b9d5541bc5..22db9a4b53a 100644 --- a/src/nav/navSelectors.js +++ b/src/nav/navSelectors.js @@ -1,17 +1,17 @@ /* @flow strict-local */ -import type { NavigationState, NavigationRoute } from 'react-navigation'; +import type { NavigationState, Route } from '@react-navigation/native'; import * as NavigationService from './NavigationService'; export const getNavState = (): NavigationState => NavigationService.getState(); -export const getNavigationRoutes = () => getNavState().routes; +export const getNavigationRoutes = (): $ReadOnlyArray> => getNavState().routes; const getNavigationIndex = () => getNavState().index; -const getCurrentRoute = (): void | NavigationRoute => getNavigationRoutes()[getNavigationIndex()]; +const getCurrentRoute = (): void | Route => getNavigationRoutes()[getNavigationIndex()]; -export const getCurrentRouteName = () => getCurrentRoute()?.routeName; +export const getCurrentRouteName = () => getCurrentRoute()?.name; export const getCurrentRouteParams = () => getCurrentRoute()?.params; @@ -21,7 +21,7 @@ export const getSameRoutesCount = () => { const routes = getNavigationRoutes(); let i = routes.length - 1; while (i >= 0) { - if (routes[i].routeName !== routes[routes.length - 1].routeName) { + if (routes[i].name !== routes[routes.length - 1].name) { break; } i--; diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index d235b1f2289..e3de07dcd09 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -1,8 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import { createAppContainer } from 'react-navigation'; -import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; +import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'; import type { AppNavigationProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; @@ -27,6 +26,8 @@ import Emoji from '../emoji/Emoji'; import { objectFromEntries } from '../jsBackport'; import { navigateBack } from '../nav/navActions'; +const Tab = createMaterialTopTabNavigator(); + const emojiTypeFromReactionType = (reactionType: ReactionType): EmojiType => { if (reactionType === 'unicode_emoji') { return 'unicode'; @@ -41,10 +42,11 @@ const getRouteConfig = ( aggregatedReaction: AggregatedReaction, allUsersById: Map, ) => ({ - screen: () => ( + name: aggregatedReaction.name, + component: () => ( ), - navigationOptions: { + options: { tabBarLabel: () => ( , allUsersById: Map, @@ -153,25 +157,22 @@ class MessageReactionList extends PureComponent { ); } else { const aggregatedReactions = aggregateReactions(message.reactions, ownUserId); - // TODO: React Navigation doesn't want us to explicitly render - // more than one navigator in the app, and the recommended - // workaround isn't feasible; see discussion at - // https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/Dynamic.20routes.20in.20react-navigation/near/1008268. - // Given that, it seems we can use `createAppContainer` so our - // violation of the "only explicitly render one navigator" - // rule doesn't cause a crashing error. But the name - // `createAppContainer` is enough to suggest that we're - // definitely doing something wrong here. - const TabView = createAppContainer( - createMaterialTopTabNavigator( - getReactionTabsRoutes(aggregatedReactions, allUsersById), - getReactionTabsNavConfig(aggregatedReactions, reactionName), - ), - ); return ( - + + { + // Generate tabs for the reaction list. The tabs depend + // on the distinct reactions on the message. + } + {aggregatedReactions.map(aggregatedReaction => ( + // Each tab corresponds to an aggregated reaction, and has a user list. + + ))} + ); } diff --git a/src/sharing/SharingScreen.js b/src/sharing/SharingScreen.js index cbadfd441e0..51993982e64 100644 --- a/src/sharing/SharingScreen.js +++ b/src/sharing/SharingScreen.js @@ -1,11 +1,12 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; import { Text } from 'react-native'; +import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs'; import { - createMaterialTopTabNavigator, + createCompatNavigatorFactory, type NavigationTabProp, type NavigationStateRoute, -} from 'react-navigation-tabs'; +} from '@react-navigation/compat'; import { FormattedMessage } from 'react-intl'; import type { GlobalParamList } from '../nav/globalTypes'; @@ -27,7 +28,7 @@ export type SharingNavigatorParamList = {| |}; export type SharingNavigationProp< - RouteName: $Keys = $Keys, + +RouteName: $Keys = $Keys, > = NavigationTabProp<{| ...NavigationStateRoute, params: $ElementType, @@ -47,25 +48,23 @@ const styles = createStyleSheet({ }, }); -const SharingTopTabNavigator = createMaterialTopTabNavigator( +const SharingTopTabNavigator = createCompatNavigatorFactory(createMaterialTopTabNavigator)( { 'share-to-stream': { - // $FlowFixMe react-navigation types are twisty and seem wrong screen: ShareToStream, navigationOptions: { tabBarLabel: props => ( - + ), }, }, 'share-to-pm': { - // $FlowFixMe react-navigation types are twisty and seem wrong screen: ShareToPm, navigationOptions: { tabBarLabel: props => ( - + ), diff --git a/src/styles/tabs.js b/src/styles/tabs.js index 855ac1abb8d..d8d02827689 100644 --- a/src/styles/tabs.js +++ b/src/styles/tabs.js @@ -1,9 +1,7 @@ /* @flow strict-local */ import type { ViewStyle } from 'react-native/Libraries/StyleSheet/StyleSheet'; -import type { - MaterialTopTabNavigatorConfig, - BottomTabNavigatorConfig, -} from 'react-navigation-tabs'; +import type { ExtraMaterialTopTabNavigatorProps } from '@react-navigation/material-top-tabs'; +import type { ExtraBottomTabNavigatorProps } from '@react-navigation/bottom-tabs'; import { BRAND_COLOR } from './constants'; @@ -31,10 +29,8 @@ const baseTabNavigatorConfig = (args: Props) => { style: { backgroundColor: 'transparent', - // Starting in React Navigation v5, if we set - // `backgroundColor` to 'transparent', the tab bar will look - // very odd on Android. It will look normal with this - // Android-only `elevation` attribute set to 0. + // Fix a bug introduced in React Navigation v5 that is exposed + // by setting `backgroundColor` to 'transparent', as we do. elevation: 0, ...style, @@ -42,10 +38,10 @@ const baseTabNavigatorConfig = (args: Props) => { }, }; }; -export const bottomTabNavigatorConfig: Props => BottomTabNavigatorConfig = (args: Props) => +export const bottomTabNavigatorConfig: Props => ExtraBottomTabNavigatorProps = (args: Props) => baseTabNavigatorConfig(args); -export const materialTopTabNavigatorConfig: Props => MaterialTopTabNavigatorConfig = ( +export const materialTopTabNavigatorConfig: Props => ExtraMaterialTopTabNavigatorProps = ( args: Props, ) => { const baseConfig = baseTabNavigatorConfig(args); @@ -57,7 +53,20 @@ export const materialTopTabNavigatorConfig: Props => MaterialTopTabNavigatorConf indicatorStyle: { backgroundColor: BRAND_COLOR, }, - upperCaseLabel: false, + // TODO: `upperCaseLabel` vanished in react-navigation v5. We + // used to use `false` for this, but it appears that the + // effective default value is `true`, at least for material top + // tab navigators: + // https://github.com/react-navigation/react-navigation/issues/7952 + // + // The coercion into uppercase only happens when the tab-bar + // label (whether that comes directly from + // `options.tabBarLabel`, or from `options.title`) is a string, + // not a more complex React node. It also doesn't seem to happen + // on bottom tab navigators, just material top ones; this + // difference seems to align with Material Design choices (see + // Greg's comment at + // https://github.com/zulip/zulip-mobile/pull/4393#discussion_r556949209f). style: { ...baseConfig.tabBarOptions.style, diff --git a/yarn.lock b/yarn.lock index 642cb9fc123..6f708bb1740 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2237,23 +2237,68 @@ resolved "https://registry.yarnpkg.com/@react-native-community/netinfo/-/netinfo-5.9.5.tgz#3bad0d855d2e813be085ec305139d4175c512ccc" integrity sha512-PbSsRmhRwYIMdeVJTf9gJtvW0TVq/hmgz1xyjsrTIsQ7QS7wbMEiv1Eb/M/y6AEEsdUped5Axm5xykq9TGISHg== -"@react-navigation/core@^3.7.6": - version "3.7.6" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.7.6.tgz#e0244fcdc22937825b252197f70308bbe5709c58" - integrity sha512-loYFIn0Boy7C+vYxwcqsBVRFRO1EizZJErdutE6/3Jw6dbzz3Bnzupbw5hckZNB16GckacMwGoepZNIK51IIcg== - dependencies: - hoist-non-react-statics "^3.3.2" - path-to-regexp "^1.8.0" - query-string "^6.11.1" +"@react-navigation/bottom-tabs@^5.10.6": + version "5.11.2" + resolved "https://registry.yarnpkg.com/@react-navigation/bottom-tabs/-/bottom-tabs-5.11.2.tgz#5b541612fcecdea2a5024a4028da35e4a727bde6" + integrity sha512-7+hH00N9Ze74VcX8uYWVyXFXZ0Fwid+lG+SSLtmnJjk1Y6oIQpQ17EPqKO0UZlKKjhsvMlAnL5fdgFtoqnSjcA== + dependencies: + color "^3.1.3" + react-native-iphone-x-helper "^1.3.0" + +"@react-navigation/compat@^5.3.9": + version "5.3.10" + resolved "https://registry.yarnpkg.com/@react-navigation/compat/-/compat-5.3.10.tgz#902154241c24cf3f8dd2e4e9be287836098014bd" + integrity sha512-SbbWtkgUZGXEaENnEb/C9+QZX9ACqnWw5OPwMexkm0Y0xwnwBdF2kc1AvdwsEXU91MLVeeuBcc1gsC7e0fiNnQ== + +"@react-navigation/core@^5.14.4": + version "5.14.4" + resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-5.14.4.tgz#f63a2cd214bddbd25e1181f9335c32dfc3b6460f" + integrity sha512-MzZU9PO1a/6f9KdN04dC/E4BNl6M1Ba0Tb4sQdl/32y0hM2ToxlrKcERnTLWGFIbQV+9ZV1GTrp3mlGS6U9Jpw== + dependencies: + "@react-navigation/routers" "^5.6.2" + escape-string-regexp "^4.0.0" + nanoid "^3.1.15" + query-string "^6.13.6" react-is "^16.13.0" -"@react-navigation/native@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.8.0.tgz#35882c3fc2f997ea1a43c12a15088cf4c818fd92" - integrity sha512-Uym5XdNOTpTR6XC4IVa/Shfn12DUF3DUIqch+cpiLNfvauQukVmWoz+Rfxd2faGOzxT12EhrWGFsMJ/8nuTfcw== +"@react-navigation/drawer@^5.9.3": + version "5.11.4" + resolved "https://registry.yarnpkg.com/@react-navigation/drawer/-/drawer-5.11.4.tgz#8cc4c6ccd2579e78ee1d84948e2eedb2aff9d891" + integrity sha512-6Wpv2Ng9+ZMcmZ8AhwAvV+QvWERPlPUr2IH9ogufGu/fc/ppURStdJcMhHZPH4oOc1OcPow87Ew4oaMmjX4Pvw== dependencies: - hoist-non-react-statics "^3.3.2" - react-native-safe-area-view "^0.14.9" + color "^3.1.3" + react-native-iphone-x-helper "^1.3.0" + +"@react-navigation/material-top-tabs@^5.2.19": + version "5.3.10" + resolved "https://registry.yarnpkg.com/@react-navigation/material-top-tabs/-/material-top-tabs-5.3.10.tgz#158b694e87bff2eb9577e8142415de8ac3547412" + integrity sha512-mmQYEBhcLp1DwvuD8+HiFtYPk5zP43272C/38iX2T8AblcwRdoJejuO/GUzQcEPrmZHjeAnA5GDaMiXQM4EXLQ== + dependencies: + color "^3.1.3" + +"@react-navigation/native@^5.7.6": + version "5.8.10" + resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-5.8.10.tgz#3fe806abff9efb085bcf595212803dd05a1347ca" + integrity sha512-OUgD1o+y7PwmhRIRqQxN0SQvVU/SHic/ek/qMvBZX8nu5/WlBNxmNRMHVxONgHlG3AQZh27NUs9ynntL7ek1zQ== + dependencies: + "@react-navigation/core" "^5.14.4" + escape-string-regexp "^4.0.0" + nanoid "^3.1.15" + +"@react-navigation/routers@^5.6.2": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@react-navigation/routers/-/routers-5.6.2.tgz#accc008c3b777f74d998e16cb2ea8e4c1fe8d9aa" + integrity sha512-XBcDKXS5s4MaHFufN44LtbXqFDH/nUHfHjbwG85fP3k772oRyPRgbnUb2mbw5MFGqORla9T7uymR6Gh6uwIwVw== + dependencies: + nanoid "^3.1.15" + +"@react-navigation/stack@^5.9.3": + version "5.12.8" + resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.12.8.tgz#31e54e05d8a3ffaaa3e39a1a9b7969f8316a35bf" + integrity sha512-wUJFbU0v606RBXOUxHToCXJNmiwxtFYhN2TFvjxCZ3PJU+OWWx8HTmn99pT3rVH4Ax2cfO5BDUy9v+r74ZrIWw== + dependencies: + color "^3.1.3" + react-native-iphone-x-helper "^1.3.0" "@rollup/plugin-babel@^5.2.0": version "5.2.0" @@ -3887,10 +3932,10 @@ color-name@^1.0.0, color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2, color-string@^1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== +color-string@^1.5.3, color-string@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6" + integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -3900,13 +3945,13 @@ color-support@^1.1.3: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== -color@^3.0.0, color@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== +color@^3.0.0, color@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" + integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== dependencies: color-convert "^1.9.1" - color-string "^1.5.2" + color-string "^1.5.4" colorette@^1.0.7: version "1.2.0" @@ -4681,6 +4726,11 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^1.11.1, escodegen@^1.14.1: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" @@ -6030,11 +6080,6 @@ hermes-engine@~0.4.0: resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.4.3.tgz#1754932f989daddd149172600f01e69cb8f27298" integrity sha512-qkk85ezG+w70C3tQ4iDs22B8talvByGeJQ1VIb2KG5+rMZWVizRq6r+NYptOC/HWAFxkdYb6F3OPca7RxvjYew== -hoist-non-react-statics@^2.3.1: - version "2.5.5" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" - integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== - hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -6630,11 +6675,6 @@ is-wsl@^2.1.1, is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -8944,6 +8984,11 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== +nanoid@^3.1.15: + version "3.1.20" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" + integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -9570,13 +9615,6 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== -path-to-regexp@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - path-type@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" @@ -9947,10 +9985,10 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -query-string@^6.11.1: - version "6.13.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.1.tgz#d913ccfce3b4b3a713989fe6d39466d92e71ccad" - integrity sha512-RfoButmcK+yCta1+FuU8REvisx1oEzhMKwhLUNcepQTPGcNMp1sIqjnfCtfnvGSQZQEhaBHvccujtWoUV3TTbA== +query-string@^6.13.6: + version "6.13.8" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.8.tgz#8cf231759c85484da3cf05a851810d8e825c1159" + integrity sha512-jxJzQI2edQPE/NPUOusNjO/ZOGqr1o2OBa/3M00fU76FsLXDVbJDv/p7ng5OdQyorKrkRz1oqfwmbe5MAMePQg== dependencies: decode-uri-component "^0.2.0" split-on-first "^1.0.0" @@ -10031,11 +10069,6 @@ react-is@^16.12.0, react-is@^16.13.0, react-is@^16.7.0, react-is@^16.8.1, react- resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - react-native-cli@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/react-native-cli/-/react-native-cli-2.0.1.tgz#f2cd3c7aa1b83828cdfba630e2dfd817df766d54" @@ -10071,10 +10104,10 @@ react-native-image-picker@^2.3.3: resolved "https://registry.yarnpkg.com/react-native-image-picker/-/react-native-image-picker-2.3.3.tgz#eaacd4a1ed9e9887613be31f0765478ca2f18a51" integrity sha512-i/7JDnxKkUGSbFY2i7YqFNn3ncJm1YlcrPKXrXmJ/YUElz8tHkuwknuqBd9QCJivMfHX41cmq4XvdBDwIOtO+A== -react-native-iphone-x-helper@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz#645e2ffbbb49e80844bb4cbbe34a126fda1e6772" - integrity sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ== +react-native-iphone-x-helper@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz#20c603e9a0e765fd6f97396638bdeb0e5a60b010" + integrity sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg== react-native-notifications@^1.2.0: version "1.5.0" @@ -10107,13 +10140,6 @@ react-native-safe-area-context@^3.1.7: resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-3.1.7.tgz#fc9e636dfb168f992a2172d363509ce0611a8403" integrity sha512-qSyg/pVMwVPgAy8yCvw349Q+uEUhtRBV33eVXHHkfoou1vCChJxI7SmNR47/6M3BLdjWcyc4lcd018Kx+jhQCw== -react-native-safe-area-view@^0.14.9: - version "0.14.9" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.9.tgz#90ee8383037010d9a5055a97cf97e4c1da1f0c3d" - integrity sha512-WII/ulhpVyL/qbYb7vydq7dJAfZRBcEhg4/UWt6F6nAKpLa3gAceMOxBxI914ppwSP/TdUsandFy6lkJQE0z4A== - dependencies: - hoist-non-react-statics "^2.3.1" - react-native-screens@^2.10.1: version "2.10.1" resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.10.1.tgz#06d22fae87ef0ce51c616c34a199726db1403b95" @@ -10129,10 +10155,10 @@ react-native-sound@^0.11.0: resolved "https://registry.yarnpkg.com/react-native-sound/-/react-native-sound-0.11.0.tgz#ad60b55ba8c6dc89917f381ad3713f2738de530f" integrity sha512-4bGAZfni6E2L695NQjOZwNLBQGXgBGYC4Sy+h99K5h0HqNZjCqR0+aLel+ezASxEJDpaH83gylNObXpiqJgdwg== -react-native-tab-view@^2.11.0: - version "2.15.1" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.15.1.tgz#cf4df4ffdec504263a2e06a6becd8831b9a19ad9" - integrity sha512-cDYl1pNWspbEHBjHrHVpIC40h4g8VhZe0CIG0CUKcouX98vHVfAojxhgWuRosq9qMhITHpLKM+7BmBLnhCJ0nw== +react-native-tab-view@^2.15.2: + version "2.15.2" + resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.15.2.tgz#4bc7832d33a119306614efee667509672a7ee64e" + integrity sha512-2hxLkBnZtEKFDyfvNO5EUywhy3f/EiLOBO8SWqKj4BMBTO0QwnybaPE5MVF00Fhz+VA4+h/iI40Dkrrtq70dGg== react-native-text-input-reset@^1.0.2: version "1.0.2" @@ -10245,37 +10271,6 @@ react-native@0.62.2: use-subscription "^1.0.0" whatwg-fetch "^3.0.0" -react-navigation-drawer@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-2.5.0.tgz#6d2940fb6f9ae557b47a717203b4058194ae9665" - integrity sha512-wSsIdLYXYdi9wOOXGzaY4Hk/NIXaP8tClEpjlAPl1rhn3kU++gyJFcQ3xLsPWg0yRYq3y8jDPEWFFf81JqfP9Q== - -react-navigation-stack@^2.8.2: - version "2.8.2" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-2.8.2.tgz#e982bbf14a28b23c323b2d4a6fce4e9754b066e6" - integrity sha512-e1VtlF6NDdzgKmnqE3ucgizrgUWUakdT+r7htQU24iG8AJUFQEw+tH4Lfyj0St6i8/RLckXm+o9VgYJT+pNiRw== - dependencies: - color "^3.1.2" - react-native-iphone-x-helper "^1.2.1" - -react-navigation-tabs@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.9.0.tgz#37407106f33367ff0ef3e5bb128d03f2721a50ef" - integrity sha512-+C9wyPtgxpEedhs1aX8pwtM7gJtpDMN3wPwq0jNkmONaurhb3hvE+mt3D7CLtX+zwxmMhcrPxSTSkynORKNn8g== - dependencies: - hoist-non-react-statics "^3.3.2" - react-lifecycles-compat "^3.0.4" - react-native-safe-area-view "^0.14.9" - react-native-tab-view "^2.11.0" - -react-navigation@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-4.4.0.tgz#c5523669df642aab23ff9e2ceb2109d3492a9374" - integrity sha512-BtxqNNlEGm/ve1mGHxCvrtvDzZ+2OF/V9OJaDPz/Cdx2VvYiFGaq6mtlFQm5/2bLxiEVXhNFcYSTCP26YGiENA== - dependencies: - "@react-navigation/core" "^3.7.6" - "@react-navigation/native" "^3.8.0" - react-redux@^7.2.1: version "7.2.1" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.1.tgz#8dedf784901014db2feca1ab633864dee68ad985" From 1db60d29443d412d2082df9713d9b119bc2ce4d7 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 11 Nov 2020 17:09:38 -0800 Subject: [PATCH 16/25] deps: Clear out old libdefs for react-navigation. We're free to do this, since the upgrade to the differently named packages for React Navigation v5 has just been completed. --- .../npm/react-navigation-drawer_v2.x.x.js | 688 ------------ .../npm/react-navigation-stack_v1.x.x.js | 951 ----------------- .../npm/react-navigation-tabs_v2.x.x.js | 781 -------------- flow-typed/npm/react-navigation_v4.x.x.js | 980 ------------------ 4 files changed, 3400 deletions(-) delete mode 100644 flow-typed/npm/react-navigation-drawer_v2.x.x.js delete mode 100644 flow-typed/npm/react-navigation-stack_v1.x.x.js delete mode 100644 flow-typed/npm/react-navigation-tabs_v2.x.x.js delete mode 100644 flow-typed/npm/react-navigation_v4.x.x.js diff --git a/flow-typed/npm/react-navigation-drawer_v2.x.x.js b/flow-typed/npm/react-navigation-drawer_v2.x.x.js deleted file mode 100644 index 2bc1edcd10b..00000000000 --- a/flow-typed/npm/react-navigation-drawer_v2.x.x.js +++ /dev/null @@ -1,688 +0,0 @@ -// flow-typed signature: 0c2890f004abea22b4179c811d8db7f3 -// flow-typed version: 536c492332/react-navigation-drawer_v2.x.x/flow_>=v0.104.x - -// @flow - -declare module 'react-navigation-drawer' { - - //--------------------------------------------------------------------------- - // SECTION 1: IDENTICAL TYPE DEFINITIONS - // This section is identical across all React Navigation libdefs and contains - // shared definitions. We wish we could make it DRY and import from a shared - // definition, but that isn't yet possible. - //--------------------------------------------------------------------------- - - /** - * SECTION 1A - * We start with some definitions that we have copy-pasted from React Native - * source files. - */ - - // This is a bastardization of the true StyleObj type located in - // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't - // import that here, and it's too lengthy (and consequently too brittle) to - // copy-paste here either. - declare type StyleObj = - | null - | void - | number - | false - | '' - | $ReadOnlyArray - | { [name: string]: any, ... }; - declare type ViewStyleProp = StyleObj; - declare type TextStyleProp = StyleObj; - declare type AnimatedViewStyleProp = StyleObj; - declare type AnimatedTextStyleProp = StyleObj; - - /** - * SECTION 1B - * The following are type declarations for core types necessary for every - * React Navigation libdef. - */ - - /** - * Navigation State + Action - */ - - declare export type NavigationParams = { [key: string]: mixed, ... }; - - declare export type NavigationBackAction = {| - type: 'Navigation/BACK', - key?: ?string, - |}; - declare export type NavigationInitAction = {| - type: 'Navigation/INIT', - params?: NavigationParams, - |}; - declare export type NavigationNavigateAction = {| - type: 'Navigation/NAVIGATE', - routeName: string, - params?: NavigationParams, - - // The action to run inside the sub-router - action?: NavigationNavigateAction, - - key?: string, - |}; - declare export type NavigationSetParamsAction = {| - type: 'Navigation/SET_PARAMS', - - // The key of the route where the params should be set - key: string, - - // The new params to merge into the existing route params - params: NavigationParams, - |}; - - declare export type NavigationPopAction = {| - +type: 'Navigation/POP', - +n?: number, - +immediate?: boolean, - |}; - declare export type NavigationPopToTopAction = {| - +type: 'Navigation/POP_TO_TOP', - +immediate?: boolean, - |}; - declare export type NavigationPushAction = {| - +type: 'Navigation/PUSH', - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - +key?: string, - |}; - declare export type NavigationResetAction = {| - type: 'Navigation/RESET', - index: number, - key?: ?string, - actions: Array, - |}; - declare export type NavigationReplaceAction = {| - +type: 'Navigation/REPLACE', - +key: string, - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - |}; - declare export type NavigationCompleteTransitionAction = {| - +type: 'Navigation/COMPLETE_TRANSITION', - +key?: string, - +toChildKey?: string, - |}; - - declare export type NavigationOpenDrawerAction = {| - +type: 'Navigation/OPEN_DRAWER', - +key?: string, - |}; - declare export type NavigationCloseDrawerAction = {| - +type: 'Navigation/CLOSE_DRAWER', - +key?: string, - |}; - declare export type NavigationToggleDrawerAction = {| - +type: 'Navigation/TOGGLE_DRAWER', - +key?: string, - |}; - declare export type NavigationDrawerOpenedAction = {| - +type: 'Navigation/DRAWER_OPENED', - +key?: string, - |}; - declare export type NavigationDrawerClosedAction = {| - +type: 'Navigation/DRAWER_CLOSED', - +key?: string, - |}; - - declare export type NavigationJumpToAction = {| - +type: 'Navigation/JUMP_TO'; - +preserveFocus: boolean, - +routeName: string, - +key?: string, - +params?: NavigationParams, - |}; - - declare export type NavigationAction = - | NavigationBackAction - | NavigationInitAction - | NavigationNavigateAction - | NavigationSetParamsAction - | NavigationPopAction - | NavigationPopToTopAction - | NavigationPushAction - | NavigationResetAction - | NavigationReplaceAction - | NavigationCompleteTransitionAction - | NavigationOpenDrawerAction - | NavigationCloseDrawerAction - | NavigationToggleDrawerAction - | NavigationDrawerOpenedAction - | NavigationDrawerClosedAction - | NavigationJumpToAction; - - /** - * NavigationState is a tree of routes for a single navigator, where each - * child route may either be a NavigationScreenRoute or a - * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, - * while the NavigationRouterRoute represents the state of a child navigator. - * - * NOTE: NavigationState is a state tree local to a single navigator and - * its child navigators (via the routes field). - * If we're in navigator nested deep inside the app, the state will only be - * the state for that navigator. - * The state for the root navigator of our app represents the whole navigation - * state for the whole app. - */ - declare export type NavigationState = { - /** - * Index refers to the active child route in the routes array. - */ - index: number, - routes: Array, - isTransitioning?: bool, - ... - }; - - declare export type NavigationRoute = - | NavigationLeafRoute - | NavigationStateRoute; - - declare export type NavigationLeafRoute = {| - /** - * React's key used by some navigators. No need to specify these manually, - * they will be defined by the router. - */ - key: string, - /** - * For example 'Home'. - * This is used as a key in a route config when creating a navigator. - */ - routeName: string, - /** - * Path is an advanced feature used for deep linking and on the web. - */ - path?: string, - /** - * Params passed to this route when navigating to it, - * e.g. `{ car_id: 123 }` in a route that displays a car. - */ - params?: NavigationParams, - |}; - - declare export type NavigationStateRoute = {| - ...NavigationLeafRoute, - ...$Exact, - |}; - - /** - * Router - */ - - declare export type NavigationScreenProps = { [key: string]: mixed, ... }; - - declare export type NavigationScreenOptionsGetter = ( - navigation: NavigationScreenProp, - screenProps: ?NavigationScreenProps, - theme: SupportedThemes, - ) => Options; - - declare export type NavigationRouter = { - /** - * The reducer that outputs the new navigation state for a given action, - * with an optional previous state. When the action is considered handled - * but the state is unchanged, the output state is null. - */ - getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, - /** - * Maps a URI-like string to an action. This can be mapped to a state - * using `getStateForAction`. - */ - getActionForPathAndParams: ( - path: string, - params?: NavigationParams - ) => ?NavigationAction, - getPathAndParamsForState: ( - state: State - ) => { - path: string, - params?: NavigationParams, - ... - }, - getComponentForRouteName: (routeName: string) => NavigationComponent, - getComponentForState: (state: State) => NavigationComponent, - /** - * Gets the screen navigation options for a given screen. - * - * For example, we could get the config for the 'Foo' screen when the - * `navigation.state` is: - * - * {routeName: 'Foo', key: '123'} - */ - getScreenOptions: NavigationScreenOptionsGetter, - ... - }; - - declare export type NavigationScreenOptions = { title?: string, ... }; - - declare export type SupportedThemes = 'light' | 'dark'; - - declare export type NavigationScreenConfigProps = $Shape<{| - navigation: NavigationScreenProp, - screenProps: NavigationScreenProps, - theme: SupportedThemes, - |}>; - - declare export type NavigationScreenConfig = - | Options - | (({| - ...NavigationScreenConfigProps, - navigationOptions: Options, - |}) => Options); - - declare export type NavigationComponent = - | NavigationScreenComponent - | NavigationNavigator<*, *, *>; - - declare interface withOptionalNavigationOptions { - navigationOptions?: NavigationScreenConfig; - } - - declare export type NavigationScreenComponent< - Route: NavigationRoute, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withOptionalNavigationOptions; - - declare interface withRouter { - router: NavigationRouter; - } - - declare export type NavigationNavigator< - State: NavigationState, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare type _NavigationRouteConfigCore = {| - navigationOptions?: NavigationScreenConfig<*>, - params?: NavigationParams, - path?: string, - |}; - declare export type NavigationRouteConfig = - | NavigationComponent - | {| ..._NavigationRouteConfigCore, screen: NavigationComponent |} - | {| ..._NavigationRouteConfigCore, getScreen: () => NavigationComponent |}; - - declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; - - /** - * Navigator Prop - */ - - declare export type NavigationDispatch = ( - action: NavigationAction - ) => boolean; - - declare export type EventType = - | 'willFocus' - | 'didFocus' - | 'willBlur' - | 'didBlur' - | 'action'; - - declare export type NavigationEventPayload = {| - type: EventType, - action: NavigationAction, - state: NavigationState, - lastState: ?NavigationState, - |}; - - declare export type NavigationEventCallback = ( - payload: NavigationEventPayload - ) => void; - - declare export type NavigationEventSubscription = {| remove: () => void |}; - - declare export type NavigationScreenProp<+S> = { - +state: S, - dispatch: NavigationDispatch, - addListener: ( - eventName: string, - callback: NavigationEventCallback - ) => NavigationEventSubscription, - getParam: ( - paramName: ParamName, - fallback?: $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - > - ) => $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - >, - dangerouslyGetParent: () => ?NavigationScreenProp, - isFocused: () => boolean, - goBack: (routeKey?: ?string) => boolean, - dismiss: () => boolean, - navigate: ( - routeName: - | string - | { - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - key?: string, - ... - }, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - setParams: (newParams: NavigationParams) => boolean, - ... - }; - - declare export type NavigationNavigatorProps = $Shape<{ - navigation: NavigationScreenProp, - screenProps?: NavigationScreenProps, - navigationOptions?: O, - theme?: SupportedThemes | 'no-preference', - detached?: boolean, - ... - }>; - - /** - * Navigation container - */ - - declare export type NavigationContainer< - State: NavigationState, - Options: {...}, - Props: NavigationContainerProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare export type NavigationContainerProps = $Shape<{ - uriPrefix?: string | RegExp, - onNavigationStateChange?: ?( - NavigationState, - NavigationState, - NavigationAction - ) => void, - navigation?: NavigationScreenProp, - persistenceKey?: ?string, - renderLoadingExperimental?: React$ComponentType<{...}>, - screenProps?: NavigationScreenProps, - navigationOptions?: O, - ... - }>; - - /** - * NavigationDescriptor - */ - - declare export type NavigationDescriptor = { - key: string, - state: NavigationRoute, - navigation: NavigationScreenProp, - getComponent: () => NavigationComponent, - ... - }; - - declare export type NavigationDescriptorMap = { - [key: string]: NavigationDescriptor, - ... - }; - - //--------------------------------------------------------------------------- - // SECTION 2: SHARED TYPE DEFINITIONS - // This section too is copy-pasted, but it's not identical across all React - // Navigation libdefs. We pick out bits and pieces that we need. - //--------------------------------------------------------------------------- - - /** - * SECTION 2A - * We start with definitions we have copy-pasted, either from in-package - * types, other Flow libdefs, or from TypeScript types somewhere. - */ - - // This is copied from react-native-renimated's Typescript libdef - // https://github.com/kmagiera/react-native-reanimated/blob/master/react-native-reanimated.d.ts - declare class AnimatedNode { - constructor( - nodeConfig: {...}, - inputNodes?: $ReadOnlyArray>, - ): void; - isNativelyInitialized(): boolean; - } - - /** - * SECTION 2B - * This section usually contains exported types that are shared by some but - * not all react-navigation libdefs. However, react-navigation-drawer has no - * such types. - */ - - //--------------------------------------------------------------------------- - // SECTION 3: UNIQUE TYPE DEFINITIONS - // This section contains exported types that are not present in any other - // React Navigation libdef. - //--------------------------------------------------------------------------- - - /** - * DrawerRouter - */ - - declare export type NavigationDrawerProp<+S> = - & NavigationScreenProp - & { - jumpTo: (routeName: string, key?: string) => void, - openDrawer: () => boolean, - closeDrawer: () => boolean, - toggleDrawer: () => boolean, - ... - }; - - declare type _Scene = {| - route: NavigationRoute, - index: number, - focused: boolean, - tintColor?: string, - |}; - declare type _ThemedColor = - | string - | {| light: string, dark: string |}; - declare type _DrawerNavigatorItemsProps = {| - items: NavigationRoute[], - activeItemKey?: ?string, - activeTintColor?: _ThemedColor, - activeBackgroundColor?: _ThemedColor, - inactiveTintColor?: _ThemedColor, - inactiveBackgroundColor?: _ThemedColor, - getLabel: (scene: _Scene) => React$Node, - renderIcon: (scene: _Scene) => React$Node, - onItemPress: (scene: {| - route: NavigationRoute, - focused: boolean, - |}) => void, - itemsContainerStyle?: ViewStyleProp, - itemStyle?: ViewStyleProp, - labelStyle?: TextStyleProp, - activeLabelStyle?: TextStyleProp, - inactiveLabelStyle?: TextStyleProp, - iconContainerStyle?: ViewStyleProp, - drawerPosition: 'left' | 'right', - |}; - - declare type _NavigationDrawerState = - & NavigationState - & { isDrawerOpen: boolean, ... }; - declare type _DrawerContentComponentProps = {| - ..._DrawerNavigatorItemsProps, - +navigation: NavigationDrawerProp<_NavigationDrawerState>, - descriptors: NavigationDescriptorMap, - drawerOpenProgress: AnimatedNode, - screenProps: NavigationScreenProps, - |}; - - declare export type NavigationDrawerRouterConfig = {| - navigationOptions?: NavigationScreenConfig<*>, - defaultNavigationOptions?: NavigationScreenConfig<*>, - unmountInactiveRoutes?: boolean, - resetOnBlur?: boolean, - initialRouteName?: string, - contentComponent?: React$ComponentType<_DrawerContentComponentProps>, - contentOptions?: {...}, - backBehavior?: 'none' | 'initialRoute' | 'history', - |}; - - declare export type NavigationDrawerScreenOptions = {| - ...$Exact, - drawerIcon?: - | React$Node - | ((options: {| tintColor: ?string, focused: boolean |}) => ?React$Node), - drawerLabel?: - | React$Node - | ((options: {| tintColor: ?string, focused: boolean |}) => ?React$Node), - drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', - |}; - - /** - * DrawerView - */ - - declare type _DrawerViewProps = {| - edgeWidth: number, - drawerWidth: number | (() => number), - drawerPosition: 'left' | 'right', - drawerType: 'front' | 'back' | 'slide', - statusBarAnimation: 'slide' | 'none' | 'fade', - |}; - declare type _DrawerViewOptionalProps = {| - minSwipeDistance?: number, - drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open', - keyboardDismissMode?: 'none' | 'on-drag', - hideStatusBar?: boolean, - drawerBackgroundColor?: _ThemedColor, - overlayColor?: _ThemedColor, - style?: ViewStyleProp, - sceneContainerStyle?: ViewStyleProp, - onDrawerClose?: () => void, - onDrawerOpen?: () => void, - gestureHandlerProps?: {...}, - |}; - declare type _DrawerViewConfig = {| - ...NavigationDrawerRouterConfig, - ..._DrawerViewProps, - ..._DrawerViewOptionalProps, - |}; - - declare type DrawerViewProps = {| - lazy: boolean, - navigation: NavigationDrawerProp<_NavigationDrawerState>, - descriptors: NavigationDescriptorMap, - navigationConfig: _DrawerViewConfig, - screenProps?: NavigationScreenProps, - |}; - - /** - * DrawerNavigator - */ - - declare type _Partial = $Rest; - declare export type DrawerNavigatorConfig = {| - ...NavigationDrawerRouterConfig, - ..._Partial<_DrawerViewProps>, - ..._DrawerViewOptionalProps, - |}; - - //--------------------------------------------------------------------------- - // SECTION 4: EXPORTED MODULE - // This is the only section that types exports. Other sections export types, - // but this section types the module's exports. - //--------------------------------------------------------------------------- - - declare export function createDrawerNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: DrawerNavigatorConfig - ): NavigationNavigator<*, *, *>; - - declare export var DrawerActions: {| - OPEN_DRAWER: 'Navigation/OPEN_DRAWER', - CLOSE_DRAWER: 'Navigation/CLOSE_DRAWER', - TOGGLE_DRAWER: 'Navigation/TOGGLE_DRAWER', - DRAWER_OPENED: 'Navigation/DRAWER_OPENED', - DRAWER_CLOSED: 'Navigation/DRAWER_CLOSED', - - openDrawer: (payload: {| key?: string |}) => NavigationOpenDrawerAction, - closeDrawer: (payload: {| key?: string |}) => NavigationCloseDrawerAction, - toggleDrawer: (payload: {| key?: string |}) => NavigationToggleDrawerAction, - |}; - - declare export function DrawerRouter( - routeConfigs: NavigationRouteConfigMap, - stackConfig?: NavigationDrawerRouterConfig - ): NavigationRouter<*, NavigationDrawerScreenOptions>; - - declare type _DrawerScene = {| - route: NavigationRoute, - focused: boolean, - index: number, - tintColor?: string, - |}; - declare type _DrawerItemsProps = {| - navigation: NavigationDrawerProp<_NavigationDrawerState>, - descriptors: NavigationDescriptorMap, - drawerOpenProgress: AnimatedNode, - screenProps?: NavigationScreenProps, - items: NavigationRoute[], - activeItemKey?: ?string, - activeTintColor?: _ThemedColor, - activeBackgroundColor?: _ThemedColor, - inactiveTintColor?: _ThemedColor, - inactiveBackgroundColor?: _ThemedColor, - getLabel: (scene: _DrawerScene) => React$Node, - renderIcon: (scene: _DrawerScene) => React$Node, - onItemPress: (info: {| - route: NavigationRoute, - focused: boolean, - |}) => void, - itemsContainerStyle?: ViewStyleProp, - itemStyle?: ViewStyleProp, - labelStyle?: TextStyleProp, - activeLabelStyle?: TextStyleProp, - inactiveLabelStyle?: TextStyleProp, - iconContainerStyle?: ViewStyleProp, - drawerPosition: 'left' | 'right', - |}; - declare export var DrawerNavigatorItems: React$ComponentType<_DrawerItemsProps>; - - declare type _DrawerSidebarProps = {| - contentComponent?: React$ComponentType<_DrawerContentComponentProps>, - contentOptions?: {...}, - screenProps?: NavigationScreenProps, - navigation: NavigationDrawerProp<_NavigationDrawerState>, - descriptors: NavigationDescriptorMap, - drawerOpenProgress: AnimatedNode, - drawerPosition: 'left' | 'right', - style?: ViewStyleProp, - |}; - declare export var DrawerSidebar: React$ComponentType<_DrawerSidebarProps>; - - declare export var DrawerView: React$ComponentType; - - declare export var DrawerGestureContext: React$Context>; - -} diff --git a/flow-typed/npm/react-navigation-stack_v1.x.x.js b/flow-typed/npm/react-navigation-stack_v1.x.x.js deleted file mode 100644 index bcc11da514b..00000000000 --- a/flow-typed/npm/react-navigation-stack_v1.x.x.js +++ /dev/null @@ -1,951 +0,0 @@ -// flow-typed signature: c160a027e33cf97235b8234433c6420e -// flow-typed version: b527cb0ea1/react-navigation-stack_v1.x.x/flow_>=v0.104.x - -// @flow - -declare module 'react-navigation-stack' { - - //--------------------------------------------------------------------------- - // SECTION 1: IDENTICAL TYPE DEFINITIONS - // This section is identical across all React Navigation libdefs and contains - // shared definitions. We wish we could make it DRY and import from a shared - // definition, but that isn't yet possible. - //--------------------------------------------------------------------------- - - /** - * SECTION 1A - * We start with some definitions that we have copy-pasted from React Native - * source files. - */ - - // This is a bastardization of the true StyleObj type located in - // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't - // import that here, and it's too lengthy (and consequently too brittle) to - // copy-paste here either. - declare type StyleObj = - | null - | void - | number - | false - | '' - | $ReadOnlyArray - | { [name: string]: any, ... }; - declare type ViewStyleProp = StyleObj; - declare type TextStyleProp = StyleObj; - declare type AnimatedViewStyleProp = StyleObj; - declare type AnimatedTextStyleProp = StyleObj; - - /** - * SECTION 1B - * The following are type declarations for core types necessary for every - * React Navigation libdef. - */ - - /** - * Navigation State + Action - */ - - declare export type NavigationParams = { [key: string]: mixed, ... }; - - declare export type NavigationBackAction = {| - type: 'Navigation/BACK', - key?: ?string, - |}; - declare export type NavigationInitAction = {| - type: 'Navigation/INIT', - params?: NavigationParams, - |}; - declare export type NavigationNavigateAction = {| - type: 'Navigation/NAVIGATE', - routeName: string, - params?: NavigationParams, - - // The action to run inside the sub-router - action?: NavigationNavigateAction, - - key?: string, - |}; - declare export type NavigationSetParamsAction = {| - type: 'Navigation/SET_PARAMS', - - // The key of the route where the params should be set - key: string, - - // The new params to merge into the existing route params - params: NavigationParams, - |}; - - declare export type NavigationPopAction = {| - +type: 'Navigation/POP', - +n?: number, - +immediate?: boolean, - |}; - declare export type NavigationPopToTopAction = {| - +type: 'Navigation/POP_TO_TOP', - +immediate?: boolean, - |}; - declare export type NavigationPushAction = {| - +type: 'Navigation/PUSH', - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - +key?: string, - |}; - declare export type NavigationResetAction = {| - type: 'Navigation/RESET', - index: number, - key?: ?string, - actions: Array, - |}; - declare export type NavigationReplaceAction = {| - +type: 'Navigation/REPLACE', - +key: string, - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - |}; - declare export type NavigationCompleteTransitionAction = {| - +type: 'Navigation/COMPLETE_TRANSITION', - +key?: string, - +toChildKey?: string, - |}; - - declare export type NavigationOpenDrawerAction = {| - +type: 'Navigation/OPEN_DRAWER', - +key?: string, - |}; - declare export type NavigationCloseDrawerAction = {| - +type: 'Navigation/CLOSE_DRAWER', - +key?: string, - |}; - declare export type NavigationToggleDrawerAction = {| - +type: 'Navigation/TOGGLE_DRAWER', - +key?: string, - |}; - declare export type NavigationDrawerOpenedAction = {| - +type: 'Navigation/DRAWER_OPENED', - +key?: string, - |}; - declare export type NavigationDrawerClosedAction = {| - +type: 'Navigation/DRAWER_CLOSED', - +key?: string, - |}; - - declare export type NavigationJumpToAction = {| - +type: 'Navigation/JUMP_TO'; - +preserveFocus: boolean, - +routeName: string, - +key?: string, - +params?: NavigationParams, - |}; - - declare export type NavigationAction = - | NavigationBackAction - | NavigationInitAction - | NavigationNavigateAction - | NavigationSetParamsAction - | NavigationPopAction - | NavigationPopToTopAction - | NavigationPushAction - | NavigationResetAction - | NavigationReplaceAction - | NavigationCompleteTransitionAction - | NavigationOpenDrawerAction - | NavigationCloseDrawerAction - | NavigationToggleDrawerAction - | NavigationDrawerOpenedAction - | NavigationDrawerClosedAction - | NavigationJumpToAction; - - /** - * NavigationState is a tree of routes for a single navigator, where each - * child route may either be a NavigationScreenRoute or a - * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, - * while the NavigationRouterRoute represents the state of a child navigator. - * - * NOTE: NavigationState is a state tree local to a single navigator and - * its child navigators (via the routes field). - * If we're in navigator nested deep inside the app, the state will only be - * the state for that navigator. - * The state for the root navigator of our app represents the whole navigation - * state for the whole app. - */ - declare export type NavigationState = { - /** - * Index refers to the active child route in the routes array. - */ - index: number, - routes: Array, - isTransitioning?: bool, - ... - }; - - declare export type NavigationRoute = - | NavigationLeafRoute - | NavigationStateRoute; - - declare export type NavigationLeafRoute = {| - /** - * React's key used by some navigators. No need to specify these manually, - * they will be defined by the router. - */ - key: string, - /** - * For example 'Home'. - * This is used as a key in a route config when creating a navigator. - */ - routeName: string, - /** - * Path is an advanced feature used for deep linking and on the web. - */ - path?: string, - /** - * Params passed to this route when navigating to it, - * e.g. `{ car_id: 123 }` in a route that displays a car. - */ - params?: NavigationParams, - |}; - - declare export type NavigationStateRoute = {| - ...NavigationLeafRoute, - ...$Exact, - |}; - - /** - * Router - */ - - declare export type NavigationScreenProps = { [key: string]: mixed, ... }; - - declare export type NavigationScreenOptionsGetter = ( - navigation: NavigationScreenProp, - screenProps: ?NavigationScreenProps, - theme: SupportedThemes, - ) => Options; - - declare export type NavigationRouter = { - /** - * The reducer that outputs the new navigation state for a given action, - * with an optional previous state. When the action is considered handled - * but the state is unchanged, the output state is null. - */ - getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, - /** - * Maps a URI-like string to an action. This can be mapped to a state - * using `getStateForAction`. - */ - getActionForPathAndParams: ( - path: string, - params?: NavigationParams - ) => ?NavigationAction, - getPathAndParamsForState: ( - state: State - ) => { - path: string, - params?: NavigationParams, - ... - }, - getComponentForRouteName: (routeName: string) => NavigationComponent, - getComponentForState: (state: State) => NavigationComponent, - /** - * Gets the screen navigation options for a given screen. - * - * For example, we could get the config for the 'Foo' screen when the - * `navigation.state` is: - * - * {routeName: 'Foo', key: '123'} - */ - getScreenOptions: NavigationScreenOptionsGetter, - ... - }; - - declare export type NavigationScreenOptions = { title?: string, ... }; - - declare export type SupportedThemes = 'light' | 'dark'; - - declare export type NavigationScreenConfigProps = $Shape<{| - navigation: NavigationScreenProp, - screenProps: NavigationScreenProps, - theme: SupportedThemes, - |}>; - - declare export type NavigationScreenConfig = - | Options - | (({| - ...NavigationScreenConfigProps, - navigationOptions: Options, - |}) => Options); - - declare export type NavigationComponent = - | NavigationScreenComponent - | NavigationNavigator<*, *, *>; - - declare interface withOptionalNavigationOptions { - navigationOptions?: NavigationScreenConfig; - } - - declare export type NavigationScreenComponent< - Route: NavigationRoute, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withOptionalNavigationOptions; - - declare interface withRouter { - router: NavigationRouter; - } - - declare export type NavigationNavigator< - State: NavigationState, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare type _NavigationRouteConfigCore = {| - navigationOptions?: NavigationScreenConfig<*>, - params?: NavigationParams, - path?: string, - |}; - declare export type NavigationRouteConfig = - | NavigationComponent - | {| ..._NavigationRouteConfigCore, screen: NavigationComponent |} - | {| ..._NavigationRouteConfigCore, getScreen: () => NavigationComponent |}; - - declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; - - /** - * Navigator Prop - */ - - declare export type NavigationDispatch = ( - action: NavigationAction - ) => boolean; - - declare export type EventType = - | 'willFocus' - | 'didFocus' - | 'willBlur' - | 'didBlur' - | 'action'; - - declare export type NavigationEventPayload = {| - type: EventType, - action: NavigationAction, - state: NavigationState, - lastState: ?NavigationState, - |}; - - declare export type NavigationEventCallback = ( - payload: NavigationEventPayload - ) => void; - - declare export type NavigationEventSubscription = {| remove: () => void |}; - - declare export type NavigationScreenProp<+S> = { - +state: S, - dispatch: NavigationDispatch, - addListener: ( - eventName: string, - callback: NavigationEventCallback - ) => NavigationEventSubscription, - getParam: ( - paramName: ParamName, - fallback?: $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - > - ) => $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - >, - dangerouslyGetParent: () => ?NavigationScreenProp, - isFocused: () => boolean, - goBack: (routeKey?: ?string) => boolean, - dismiss: () => boolean, - navigate: ( - routeName: - | string - | { - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - key?: string, - ... - }, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - setParams: (newParams: NavigationParams) => boolean, - ... - }; - - declare export type NavigationNavigatorProps = $Shape<{ - navigation: NavigationScreenProp, - screenProps?: NavigationScreenProps, - navigationOptions?: O, - theme?: SupportedThemes | 'no-preference', - detached?: boolean, - ... - }>; - - /** - * Navigation container - */ - - declare export type NavigationContainer< - State: NavigationState, - Options: {...}, - Props: NavigationContainerProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare export type NavigationContainerProps = $Shape<{ - uriPrefix?: string | RegExp, - onNavigationStateChange?: ?( - NavigationState, - NavigationState, - NavigationAction - ) => void, - navigation?: NavigationScreenProp, - persistenceKey?: ?string, - renderLoadingExperimental?: React$ComponentType<{...}>, - screenProps?: NavigationScreenProps, - navigationOptions?: O, - ... - }>; - - /** - * NavigationDescriptor - */ - - declare export type NavigationDescriptor = { - key: string, - state: NavigationRoute, - navigation: NavigationScreenProp, - getComponent: () => NavigationComponent, - ... - }; - - declare export type NavigationDescriptorMap = { - [key: string]: NavigationDescriptor, - ... - }; - - //--------------------------------------------------------------------------- - // SECTION 2: SHARED TYPE DEFINITIONS - // This section too is copy-pasted, but it's not identical across all React - // Navigation libdefs. We pick out bits and pieces that we need. - //--------------------------------------------------------------------------- - - /** - * SECTION 2A - * We start with definitions we have copy-pasted, either from in-package - * types, other Flow libdefs, or from TypeScript types somewhere. - */ - - // This is copied from - // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js - declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; - declare type InterpolationConfigType = { - inputRange: Array, - outputRange: Array | Array, - easing?: (input: number) => number, - extrapolate?: ExtrapolateType, - extrapolateLeft?: ExtrapolateType, - extrapolateRight?: ExtrapolateType, - ... - }; - declare class AnimatedInterpolation { - interpolate(config: InterpolationConfigType): AnimatedInterpolation; - } - - // This is copied from - // react-native/Libraries/Animated/src/animations/Animation.js - declare type EndResult = { finished: boolean, ... }; - declare type EndCallback = (result: EndResult) => void; - declare class Animation { - start( - fromValue: number, - onUpdate: (value: number) => void, - onEnd: ?EndCallback, - previousAnimation: ?Animation, - animatedValue: AnimatedValue, - ): void; - stop(): void; - } - - // This is vaguely copied from - // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js - declare class AnimatedTracking { - constructor( - value: AnimatedValue, - parent: any, - animationClass: any, - animationConfig: Object, - callback?: ?EndCallback, - ): void; - update(): void; - } - - // This is vaguely copied from - // react-native/Libraries/Animated/src/nodes/AnimatedValue.js - declare type ValueListenerCallback = (state: { value: number, ... }) => void; - declare class AnimatedValue { - constructor(value: number): void; - setValue(value: number): void; - setOffset(offset: number): void; - flattenOffset(): void; - extractOffset(): void; - addListener(callback: ValueListenerCallback): string; - removeListener(id: string): void; - removeAllListeners(): void; - stopAnimation(callback?: ?(value: number) => void): void; - resetAnimation(callback?: ?(value: number) => void): void; - interpolate(config: InterpolationConfigType): AnimatedInterpolation; - animate(animation: Animation, callback: ?EndCallback): void; - stopTracking(): void; - track(tracking: AnimatedTracking): void; - } - - /** - * SECTION 2B - * The following are the actually useful definitions in Section 2, that are - * used below in section 3, but also in other libdefs. - */ - - declare export type NavigationPathsConfig = { [routeName: string]: string, ... }; - - /** - * SafeAreaView - */ - - declare type _SafeAreaViewForceInsetValue = 'always' | 'never' | number; - declare type _SafeAreaViewInsets = $Shape<{| - top: _SafeAreaViewForceInsetValue, - bottom: _SafeAreaViewForceInsetValue, - left: _SafeAreaViewForceInsetValue, - right: _SafeAreaViewForceInsetValue, - vertical: _SafeAreaViewForceInsetValue, - horizontal: _SafeAreaViewForceInsetValue, - |}>; - - /** - * Interpolation - */ - - declare export type NavigationStackInterpolatorProps = $Shape<{| - layout: NavigationStackLayout, - scene: NavigationStackScene, - scenes: NavigationStackScene[], - position: AnimatedInterpolation, - navigation: NavigationStackProp, - mode?: HeaderMode, - shadowEnabled?: boolean, - cardOverlayEnabled?: boolean, - |}>; - - declare type _InterpolationResult = { [key: string]: mixed, ... }; - declare export type NavigationStackInterpolator = - (props: NavigationStackInterpolatorProps) => _InterpolationResult; - - /** - * Header - */ - - declare export type HeaderMode = 'float' | 'screen' | 'none'; - - declare export type HeaderProps = {| - layout: NavigationStackLayout, - scene: NavigationStackScene, - scenes: NavigationStackScene[], - position: AnimatedInterpolation, - navigation: NavigationStackProp, - mode: HeaderMode, - leftInterpolator?: NavigationStackInterpolator, - titleInterpolator?: NavigationStackInterpolator, - rightInterpolator?: NavigationStackInterpolator, - backgroundInterpolator?: NavigationStackInterpolator, - layoutPreset: 'left' | 'center', - transitionPreset?: 'fade-in-place' | 'uikit', - backTitleVisible?: boolean, - isLandscape: boolean, - |}; - - /** - * StackRouter - */ - - declare export type NavigationStackProp<+S> = - & NavigationScreenProp - & { - pop: (n?: number, params?: {| immediate?: boolean |}) => boolean, - popToTop: (params?: {| immediate?: boolean |}) => boolean, - push: ( - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - replace: ( - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - reset: (actions: NavigationAction[], index: number) => boolean, - ... - }; - - declare type _HeaderBackButtonProps = {| - disabled?: boolean, - onPress: () => void, - pressColorAndroid?: string, - tintColor?: ?string, - backImage?: React$ComponentType<{ - tintColor: string, - title?: ?string, - ... - }>, - title?: ?string, - truncatedTitle?: ?string, - backTitleVisible?: boolean, - allowFontScaling?: boolean, - titleStyle?: ?TextStyleProp, - width?: ?number, - |}; - - declare export type NavigationStackScreenOptions = NavigationScreenOptions & { - header?: ?(React$Node | (HeaderProps => React$Node)), - headerTransparent?: boolean, - headerTitle?: (props: { children: ?string, ... }) => React$Node | React$Node, - headerTitleStyle?: AnimatedTextStyleProp, - headerTitleAllowFontScaling?: boolean, - headerTintColor?: string, - headerLeft?: ((props: _HeaderBackButtonProps) => React$Node) | React$Node, - headerBackTitle?: ?string, - headerBackImage?: (props: {| - tintColor?: string, - title?: ?string, - |}) => React$Node, - headerTruncatedBackTitle?: string, - headerBackTitleStyle?: TextStyleProp, - headerPressColorAndroid?: string, - headerRight?: React$Node, - headerStyle?: ViewStyleProp, - headerForceInset?: _SafeAreaViewInsets, - headerBackground?: React$Node | React$ElementType, - gesturesEnabled?: boolean, - gestureResponseDistance?: {| - vertical?: number, - horizontal?: number, - |}, - gestureDirection?: 'default' | 'inverted', - ... - }; - - declare export type NavigationStackRouterConfig = {| - initialRouteName?: string, - initialRouteParams?: NavigationParams, - paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenConfig<*>, - defaultNavigationOptions?: NavigationScreenConfig<*>, - initialRouteKey?: string, - |}; - - /** - * Stack Gestures, Animations, and Interpolators - */ - - declare export type NavigationStackLayout = { - height: AnimatedValue, - initHeight: number, - initWidth: number, - isMeasured: boolean, - width: AnimatedValue, - ... - }; - - declare export type NavigationStackScene = { - index: number, - isActive: boolean, - isStale: boolean, - key: string, - route: NavigationRoute, - descriptor: ?NavigationDescriptor, - ... - }; - - //--------------------------------------------------------------------------- - // SECTION 3: UNIQUE TYPE DEFINITIONS - // This section contains exported types that are not present in any other - // React Navigation libdef. - //--------------------------------------------------------------------------- - - /** - * NavigationStackTransitionProps - */ - - declare export type NavigationStackTransitionProps = $Shape<{| - // The layout of the screen container - layout: NavigationStackLayout, - // The destination navigation state of the transition - navigation: NavigationStackProp, - // The progressive index of the transitioner's navigation state. - position: AnimatedValue, - // All the scenes of the transitioner. - scenes: Array, - // The active scene, corresponding to the route at - // `navigation.state.routes[navigation.state.index]`. When rendering - // NavigationSceneRendererPropsIndex, the scene does not refer to the active - // scene, but instead the scene that is being rendered. The index always - // is the index of the scene - scene: NavigationStackScene, - index: number, - |}>; - - - /** - * StackNavigator - */ - - declare type _NavigationTransitionConfigurer = ( - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps, - isModal: boolean - ) => TransitionConfig; - - declare export type NavigationStackViewConfig = {| - mode?: 'card' | 'modal', - headerMode?: HeaderMode, - headerLayoutPreset?: 'left' | 'center', - headerTransitionPreset?: 'fade-in-place' | 'uikit', - headerBackgroundTransitionPreset?: 'translate' | 'fade' | 'toggle', - headerBackTitleVisible?: boolean, - disableKeyboardHandling?: boolean, - cardShadowEnabled?: boolean, - cardOverlayEnabled?: boolean, - onTransitionStart?: ( - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps, - ) => void, - onTransitionEnd?: ( - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps, - ) => void, - cardStyle?: ViewStyleProp, - transitionConfig?: _NavigationTransitionConfigurer, - transparentCard?: boolean, - |}; - - declare export type StackNavigatorConfig = $Shape<{| - ...NavigationStackViewConfig, - ...NavigationStackRouterConfig, - |}>; - - /** - * Transitioner - */ - - declare export type NavigationTransitionSpec = { - // A timing function such as `Animated.timing`. - timing: (value: AnimatedValue, config: any) => any, - duration?: number, - // An easing function from `Easing`. - easing?: (t: number) => number, - ... - }; - - // Describes a visual transition from one screen to another. - declare export type TransitionConfig = {| - // The basics properties of the animation, such as duration and easing - transitionSpec: NavigationTransitionSpec, - // How to animate position and opacity of the screen - // based on the value generated by the transitionSpec - screenInterpolator: NavigationStackInterpolator, - // How to animate position and opacity of the header components - // based on the value generated by the transitionSpec - headerLeftInterpolator?: NavigationStackInterpolator, - headerLeftLabelInterpolator?: NavigationStackInterpolator, - headerLeftButtonInterpolator?: NavigationStackInterpolator, - headerTitleFromLeftInterpolator?: NavigationStackInterpolator, - headerTitleInterpolator?: NavigationStackInterpolator, - headerRightInterpolator?: NavigationStackInterpolator, - headerBackgroundInterpolator?: NavigationStackInterpolator, - headerLayoutInterpolator?: NavigationStackInterpolator, - // The style of the container. Useful when a scene doesn't have - // 100% opacity and the underlying container is visible. - containerStyle?: ViewStyleProp, - containerStyleLight?: ViewStyleProp, - containerStyleDark?: ViewStyleProp, - |}; - - //--------------------------------------------------------------------------- - // SECTION 4: EXPORTED MODULE - // This is the only section that types exports. Other sections export types, - // but this section types the module's exports. - //--------------------------------------------------------------------------- - - declare export function createStackNavigator( - routeConfigMap: NavigationRouteConfigMap, - stackConfig?: StackNavigatorConfig - ): NavigationNavigator<*, *, *>; - - declare export var Header: React$ComponentType & { HEIGHT: number, ... }; - - declare export var HeaderBackButton: React$ComponentType< - _HeaderBackButtonProps - >; - - declare type _HeaderTitleProps = {| - children: React$Node, - style?: AnimatedTextStyleProp, - |}; - declare export var HeaderTitle: React$ComponentType<_HeaderTitleProps>; - - declare export var HeaderStyleInterpolator: {| - forLayout: NavigationStackInterpolator, - forLeft: NavigationStackInterpolator, - forLeftButton: NavigationStackInterpolator, - forLeftLabel: NavigationStackInterpolator, - forCenterFromLeft: NavigationStackInterpolator, - forCenter: NavigationStackInterpolator, - forRight: NavigationStackInterpolator, - forBackground: NavigationStackInterpolator, - forBackgroundWithInactiveHidden: NavigationStackInterpolator, - forBackgroundWithFade: NavigationStackInterpolator, - forBackgroundWithTranslation: NavigationStackInterpolator, - |}; - - declare type _StackViewProps = {| - navigation: NavigationStackProp, - descriptors: NavigationDescriptorMap, - navigationConfig: NavigationStackViewConfig, - onTransitionStart?: ( - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps - ) => void, - onGestureBegin?: () => void, - onGestureCanceled?: () => void, - onGestureEnd?: () => void, - screenProps?: NavigationScreenProps, - |}; - declare export var StackView: React$ComponentType<_StackViewProps>; - - declare type _StackViewCardProps = {| - ...$Exact<_PointerEventsInputProps>, - style: ViewStyleProp, - animatedStyle: any, - position: AnimatedInterpolation, - transparent?: boolean, - children: React$Node, - |}; - declare export var StackViewCard: React$ComponentType<_StackViewCardProps>; - - declare type _StackViewLayoutProps = {| - mode?: 'card' | 'modal', - headerMode?: HeaderMode, - headerLayoutPreset?: 'left' | 'center', - headerTransitionPreset?: 'fade-in-place' | 'uikit', - headerBackgroundTransitionPreset?: 'translate' | 'fade' | 'toggle', - headerBackTitleVisible?: boolean, - shadowEnabled?: boolean, - cardStyle?: ViewStyleProp, - transitionConfig?: _NavigationTransitionConfigurer, - transparentCard?: boolean, - transitionProps: NavigationStackTransitionProps, - lastTransitionProps: ?NavigationStackTransitionProps, - onGestureBegin?: () => void, - onGestureEnd?: () => void, - onGestureCanceled?: () => void, - screenProps?: NavigationScreenProps, - |}; - declare export var StackViewLayout: React$ComponentType<_StackViewLayoutProps>; - - declare export var StackViewStyleInterpolator: {| - forHorizontal: NavigationStackInterpolator, - forVertical: NavigationStackInterpolator, - forFadeFromBottomAndroid: NavigationStackInterpolator, - forFadeToBottomAndroid: NavigationStackInterpolator, - forFade: NavigationStackInterpolator, - forNoAnimation: NavigationStackInterpolator, - |}; - - declare export var StackViewTransitionConfigs: {| - defaultTransitionConfig: _NavigationTransitionConfigurer, - getTransitionConfig: ( - transitionConfigurer: ?_NavigationTransitionConfigurer, - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps, - isModal: boolean - ) => TransitionConfig, - SlideFromRightIOS: TransitionConfig, - ModalSlideFromBottomIOS: TransitionConfig, - FadeInFromBottomAndroid: TransitionConfig, - FadeOutToBottomAndroid: TransitionConfig, - NoAnimation: TransitionConfig, - |}; - - declare type _PointerEventsInputProps = { - scene: NavigationStackScene, - navigation: NavigationStackProp, - realPosition: AnimatedValue, - ... - }; - declare type _PointerEventsInjectedProps = { - pointerEvents: 'box-only' | 'none' | 'auto', - onComponentRef: (ref: any) => void, - ... - }; - declare export function createPointerEventsContainer< - Props: _PointerEventsInputProps & _PointerEventsInjectedProps, - ComponentType: React$ComponentType, - >( - Component: ComponentType - ): React$ComponentType<$Diff, _PointerEventsInjectedProps>>; - - declare type _TransitionerProps = {| - render: ( - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps - ) => React$Node, - configureTransition?: ( - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps - ) => NavigationTransitionSpec, - onTransitionStart?: ( - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps - ) => void, - onTransitionEnd?: ( - transitionProps: NavigationStackTransitionProps, - prevTransitionProps: ?NavigationStackTransitionProps - ) => void, - navigation: NavigationStackProp, - descriptors: NavigationDescriptorMap, - screenProps?: NavigationScreenProps, - |}; - declare export var Transitioner: React$ComponentType<_TransitionerProps>; - - declare export function ScenesReducer( - scenes: $ReadOnlyArray, - nextState: NavigationState, - prevState: ?NavigationState, - descriptors: NavigationDescriptorMap - ): NavigationStackScene[]; - - declare export var StackGestureContext: React$Context>; - -} diff --git a/flow-typed/npm/react-navigation-tabs_v2.x.x.js b/flow-typed/npm/react-navigation-tabs_v2.x.x.js deleted file mode 100644 index a5d50da92f3..00000000000 --- a/flow-typed/npm/react-navigation-tabs_v2.x.x.js +++ /dev/null @@ -1,781 +0,0 @@ -// flow-typed signature: 7e33fa8e7793c0fe796908176c9f1608 -// flow-typed version: 536c492332/react-navigation-tabs_v2.x.x/flow_>=v0.104.x - -// @flow - -declare module 'react-navigation-tabs' { - - //--------------------------------------------------------------------------- - // SECTION 1: IDENTICAL TYPE DEFINITIONS - // This section is identical across all React Navigation libdefs and contains - // shared definitions. We wish we could make it DRY and import from a shared - // definition, but that isn't yet possible. - //--------------------------------------------------------------------------- - - /** - * SECTION 1A - * We start with some definitions that we have copy-pasted from React Native - * source files. - */ - - // This is a bastardization of the true StyleObj type located in - // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't - // import that here, and it's too lengthy (and consequently too brittle) to - // copy-paste here either. - declare type StyleObj = - | null - | void - | number - | false - | '' - | $ReadOnlyArray - | { [name: string]: any, ... }; - declare type ViewStyleProp = StyleObj; - declare type TextStyleProp = StyleObj; - declare type AnimatedViewStyleProp = StyleObj; - declare type AnimatedTextStyleProp = StyleObj; - - /** - * SECTION 1B - * The following are type declarations for core types necessary for every - * React Navigation libdef. - */ - - /** - * Navigation State + Action - */ - - declare export type NavigationParams = { [key: string]: mixed, ... }; - - declare export type NavigationBackAction = {| - type: 'Navigation/BACK', - key?: ?string, - |}; - declare export type NavigationInitAction = {| - type: 'Navigation/INIT', - params?: NavigationParams, - |}; - declare export type NavigationNavigateAction = {| - type: 'Navigation/NAVIGATE', - routeName: string, - params?: NavigationParams, - - // The action to run inside the sub-router - action?: NavigationNavigateAction, - - key?: string, - |}; - declare export type NavigationSetParamsAction = {| - type: 'Navigation/SET_PARAMS', - - // The key of the route where the params should be set - key: string, - - // The new params to merge into the existing route params - params: NavigationParams, - |}; - - declare export type NavigationPopAction = {| - +type: 'Navigation/POP', - +n?: number, - +immediate?: boolean, - |}; - declare export type NavigationPopToTopAction = {| - +type: 'Navigation/POP_TO_TOP', - +immediate?: boolean, - |}; - declare export type NavigationPushAction = {| - +type: 'Navigation/PUSH', - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - +key?: string, - |}; - declare export type NavigationResetAction = {| - type: 'Navigation/RESET', - index: number, - key?: ?string, - actions: Array, - |}; - declare export type NavigationReplaceAction = {| - +type: 'Navigation/REPLACE', - +key: string, - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - |}; - declare export type NavigationCompleteTransitionAction = {| - +type: 'Navigation/COMPLETE_TRANSITION', - +key?: string, - +toChildKey?: string, - |}; - - declare export type NavigationOpenDrawerAction = {| - +type: 'Navigation/OPEN_DRAWER', - +key?: string, - |}; - declare export type NavigationCloseDrawerAction = {| - +type: 'Navigation/CLOSE_DRAWER', - +key?: string, - |}; - declare export type NavigationToggleDrawerAction = {| - +type: 'Navigation/TOGGLE_DRAWER', - +key?: string, - |}; - declare export type NavigationDrawerOpenedAction = {| - +type: 'Navigation/DRAWER_OPENED', - +key?: string, - |}; - declare export type NavigationDrawerClosedAction = {| - +type: 'Navigation/DRAWER_CLOSED', - +key?: string, - |}; - - declare export type NavigationJumpToAction = {| - +type: 'Navigation/JUMP_TO'; - +preserveFocus: boolean, - +routeName: string, - +key?: string, - +params?: NavigationParams, - |}; - - declare export type NavigationAction = - | NavigationBackAction - | NavigationInitAction - | NavigationNavigateAction - | NavigationSetParamsAction - | NavigationPopAction - | NavigationPopToTopAction - | NavigationPushAction - | NavigationResetAction - | NavigationReplaceAction - | NavigationCompleteTransitionAction - | NavigationOpenDrawerAction - | NavigationCloseDrawerAction - | NavigationToggleDrawerAction - | NavigationDrawerOpenedAction - | NavigationDrawerClosedAction - | NavigationJumpToAction; - - /** - * NavigationState is a tree of routes for a single navigator, where each - * child route may either be a NavigationScreenRoute or a - * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, - * while the NavigationRouterRoute represents the state of a child navigator. - * - * NOTE: NavigationState is a state tree local to a single navigator and - * its child navigators (via the routes field). - * If we're in navigator nested deep inside the app, the state will only be - * the state for that navigator. - * The state for the root navigator of our app represents the whole navigation - * state for the whole app. - */ - declare export type NavigationState = { - /** - * Index refers to the active child route in the routes array. - */ - index: number, - routes: Array, - isTransitioning?: bool, - ... - }; - - declare export type NavigationRoute = - | NavigationLeafRoute - | NavigationStateRoute; - - declare export type NavigationLeafRoute = {| - /** - * React's key used by some navigators. No need to specify these manually, - * they will be defined by the router. - */ - key: string, - /** - * For example 'Home'. - * This is used as a key in a route config when creating a navigator. - */ - routeName: string, - /** - * Path is an advanced feature used for deep linking and on the web. - */ - path?: string, - /** - * Params passed to this route when navigating to it, - * e.g. `{ car_id: 123 }` in a route that displays a car. - */ - params?: NavigationParams, - |}; - - declare export type NavigationStateRoute = {| - ...NavigationLeafRoute, - ...$Exact, - |}; - - /** - * Router - */ - - declare export type NavigationScreenProps = { [key: string]: mixed, ... }; - - declare export type NavigationScreenOptionsGetter = ( - navigation: NavigationScreenProp, - screenProps: ?NavigationScreenProps, - theme: SupportedThemes, - ) => Options; - - declare export type NavigationRouter = { - /** - * The reducer that outputs the new navigation state for a given action, - * with an optional previous state. When the action is considered handled - * but the state is unchanged, the output state is null. - */ - getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, - /** - * Maps a URI-like string to an action. This can be mapped to a state - * using `getStateForAction`. - */ - getActionForPathAndParams: ( - path: string, - params?: NavigationParams - ) => ?NavigationAction, - getPathAndParamsForState: ( - state: State - ) => { - path: string, - params?: NavigationParams, - ... - }, - getComponentForRouteName: (routeName: string) => NavigationComponent, - getComponentForState: (state: State) => NavigationComponent, - /** - * Gets the screen navigation options for a given screen. - * - * For example, we could get the config for the 'Foo' screen when the - * `navigation.state` is: - * - * {routeName: 'Foo', key: '123'} - */ - getScreenOptions: NavigationScreenOptionsGetter, - ... - }; - - declare export type NavigationScreenOptions = { title?: string, ... }; - - declare export type SupportedThemes = 'light' | 'dark'; - - declare export type NavigationScreenConfigProps = $Shape<{| - navigation: NavigationScreenProp, - screenProps: NavigationScreenProps, - theme: SupportedThemes, - |}>; - - declare export type NavigationScreenConfig = - | Options - | (({| - ...NavigationScreenConfigProps, - navigationOptions: Options, - |}) => Options); - - declare export type NavigationComponent = - | NavigationScreenComponent - | NavigationNavigator<*, *, *>; - - declare interface withOptionalNavigationOptions { - navigationOptions?: NavigationScreenConfig; - } - - declare export type NavigationScreenComponent< - Route: NavigationRoute, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withOptionalNavigationOptions; - - declare interface withRouter { - router: NavigationRouter; - } - - declare export type NavigationNavigator< - State: NavigationState, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare type _NavigationRouteConfigCore = {| - navigationOptions?: NavigationScreenConfig<*>, - params?: NavigationParams, - path?: string, - |}; - declare export type NavigationRouteConfig = - | NavigationComponent - | {| ..._NavigationRouteConfigCore, screen: NavigationComponent |} - | {| ..._NavigationRouteConfigCore, getScreen: () => NavigationComponent |}; - - declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; - - /** - * Navigator Prop - */ - - declare export type NavigationDispatch = ( - action: NavigationAction - ) => boolean; - - declare export type EventType = - | 'willFocus' - | 'didFocus' - | 'willBlur' - | 'didBlur' - | 'action'; - - declare export type NavigationEventPayload = {| - type: EventType, - action: NavigationAction, - state: NavigationState, - lastState: ?NavigationState, - |}; - - declare export type NavigationEventCallback = ( - payload: NavigationEventPayload - ) => void; - - declare export type NavigationEventSubscription = {| remove: () => void |}; - - declare export type NavigationScreenProp<+S> = { - +state: S, - dispatch: NavigationDispatch, - addListener: ( - eventName: string, - callback: NavigationEventCallback - ) => NavigationEventSubscription, - getParam: ( - paramName: ParamName, - fallback?: $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - > - ) => $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - >, - dangerouslyGetParent: () => ?NavigationScreenProp, - isFocused: () => boolean, - goBack: (routeKey?: ?string) => boolean, - dismiss: () => boolean, - navigate: ( - routeName: - | string - | { - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - key?: string, - ... - }, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - setParams: (newParams: NavigationParams) => boolean, - ... - }; - - declare export type NavigationNavigatorProps = $Shape<{ - navigation: NavigationScreenProp, - screenProps?: NavigationScreenProps, - navigationOptions?: O, - theme?: SupportedThemes | 'no-preference', - detached?: boolean, - ... - }>; - - /** - * Navigation container - */ - - declare export type NavigationContainer< - State: NavigationState, - Options: {...}, - Props: NavigationContainerProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare export type NavigationContainerProps = $Shape<{ - uriPrefix?: string | RegExp, - onNavigationStateChange?: ?( - NavigationState, - NavigationState, - NavigationAction - ) => void, - navigation?: NavigationScreenProp, - persistenceKey?: ?string, - renderLoadingExperimental?: React$ComponentType<{...}>, - screenProps?: NavigationScreenProps, - navigationOptions?: O, - ... - }>; - - /** - * NavigationDescriptor - */ - - declare export type NavigationDescriptor = { - key: string, - state: NavigationRoute, - navigation: NavigationScreenProp, - getComponent: () => NavigationComponent, - ... - }; - - declare export type NavigationDescriptorMap = { - [key: string]: NavigationDescriptor, - ... - }; - - //--------------------------------------------------------------------------- - // SECTION 2: SHARED TYPE DEFINITIONS - // This section too is copy-pasted, but it's not identical across all React - // Navigation libdefs. We pick out bits and pieces that we need. - //--------------------------------------------------------------------------- - - /** - * SECTION 2A - * We start with definitions we have copy-pasted, either from in-package - * types, other Flow libdefs, or from TypeScript types somewhere. - */ - - // This is copied from react-native-renimated's Typescript libdef - // https://github.com/kmagiera/react-native-reanimated/blob/master/react-native-reanimated.d.ts - declare class AnimatedNode { - constructor( - nodeConfig: {...}, - inputNodes?: $ReadOnlyArray>, - ): void; - isNativelyInitialized(): boolean; - } - - // This is copied from - // react-native/Libraries/Components/View/ViewAccessibility.js - declare type AccessibilityRole = - | 'none' - | 'button' - | 'link' - | 'search' - | 'image' - | 'keyboardkey' - | 'text' - | 'adjustable' - | 'imagebutton' - | 'header' - | 'summary' - | 'alert' - | 'checkbox' - | 'combobox' - | 'menu' - | 'menubar' - | 'menuitem' - | 'progressbar' - | 'radio' - | 'radiogroup' - | 'scrollbar' - | 'spinbutton' - | 'switch' - | 'tab' - | 'tablist' - | 'timer' - | 'toolbar'; - declare type AccessibilityState = { - disabled?: boolean, - selected?: boolean, - checked?: ?boolean | 'mixed', - busy?: boolean, - expanded?: boolean, - ... - }; - - /** - * SECTION 2B - * The following are the actually useful definitions in Section 2, that are - * used below in section 3, but also in other libdefs. - */ - - declare export type NavigationPathsConfig = { [routeName: string]: string, ... }; - - /** - * SafeAreaView - */ - - declare type _SafeAreaViewForceInsetValue = 'always' | 'never' | number; - declare type _SafeAreaViewInsets = $Shape<{| - top: _SafeAreaViewForceInsetValue, - bottom: _SafeAreaViewForceInsetValue, - left: _SafeAreaViewForceInsetValue, - right: _SafeAreaViewForceInsetValue, - vertical: _SafeAreaViewForceInsetValue, - horizontal: _SafeAreaViewForceInsetValue, - |}>; - - /** - * SwitchRouter - */ - - declare export type NavigationSwitchRouterConfig = {| - initialRouteName?: string, - initialRouteParams?: NavigationParams, - paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenConfig<*>, - defaultNavigationOptions?: NavigationScreenConfig<*>, - // todo: type these as the real route names rather than 'string' - order?: string[], - // Does the back button cause the router to switch to the initial tab - backBehavior?: 'none' | 'initialRoute' | 'history' | 'order', // defaults `initialRoute` - resetOnBlur?: boolean, - |}; - - /** - * TabRouter - */ - - declare export type NavigationTabProp<+S> = - & NavigationScreenProp - & { jumpTo: (routeName: string, key?: string) => void, ... }; - - declare export type NavigationTabRouterConfig = NavigationSwitchRouterConfig; - - declare export type NavigationTabScreenOptions = { - ...$Exact, - tabBarLabel?: React$Node, - tabBarVisible?: boolean, - tabBarAccessibilityLabel?: string, - tabBarTestID?: string, - tabBarIcon?: - | React$Node - | ((props: {| - focused: boolean, - tintColor?: string, - horizontal?: boolean, - |}) => React$Node), - tabBarOnPress?: (props: {| - navigation: NavigationTabProp, - defaultHandler: () => void, - |}) => void, - tabBarOnLongPress?: (props: {| - navigation: NavigationTabProp, - defaultHandler: () => void, - |}) => void, - ... - }; - - //--------------------------------------------------------------------------- - // SECTION 3: UNIQUE TYPE DEFINITIONS - // This section contains exported types that are not present in any other - // React Navigation libdef. - //--------------------------------------------------------------------------- - - /** - * TabNavigator - */ - - declare type _TabViewLayout = $Shape<{| height: number, width: number |}>; - - declare export type TabNavigatorConfig = {| - ...NavigationTabRouterConfig, - ...$Exact, - tabBarComponent?: React$ElementType, - lazy?: boolean, - |}; - - declare type _MaterialTopTabBarOptions = {| - activeTintColor?: string, - allowFontScaling?: boolean, - bounces?: boolean, - inactiveTintColor?: string, - pressColor?: string, - pressOpacity?: number, - scrollEnabled?: boolean, - showIcon?: boolean, - showLabel?: boolean, - upperCaseLabel?: boolean, - tabStyle?: ViewStyleProp, - indicatorStyle?: ViewStyleProp, - iconStyle?: ViewStyleProp, - labelStyle?: TextStyleProp, - contentContainerStyle?: ViewStyleProp, - style?: ViewStyleProp, - |}; - declare export type MaterialTopTabNavigatorConfig = TabNavigatorConfig<{| - tabBarOptions?: _MaterialTopTabBarOptions, - keyboardDismissMode?: 'none' | 'on-drag', - swipeEnabled?: boolean, - swipeDistanceThreshold?: number, - swipeVelocityThreshold?: number, - initialLayout?: _TabViewLayout, - lazyPlaceholderComponent?: React$ComponentType<{ route: {| - key: string, - routeName: string, - |}, ... }>, - tabBarPosition?: 'top' | 'bottom', - sceneContainerStyle?: ViewStyleProp, - style?: ViewStyleProp, - |}>; - - declare type _ThemedColor = - | string - | {| light: string, dark: string |}; - declare type _LabelPosition = 'beside-icon' | 'below-icon'; - declare type _Orientation = 'horizontal' | 'vertical'; - declare type _BottomTabBarOptions = {| - keyboardHidesTabBar?: boolean, - activeTintColor?: _ThemedColor, - inactiveTintColor?: _ThemedColor, - activeBackgroundColor?: _ThemedColor, - inactiveBackgroundColor?: _ThemedColor, - allowFontScaling?: boolean, - showLabel?: boolean, - showIcon?: boolean, - labelStyle?: TextStyleProp, - tabStyle?: ViewStyleProp, - labelPosition?: - | _LabelPosition - | ((options: {| deviceOrientation: _Orientation |}) => _LabelPosition), - adaptive?: boolean, - safeAreaInset?: _SafeAreaViewInsets, - style?: ViewStyleProp, - |}; - declare export type BottomTabNavigatorConfig = TabNavigatorConfig<{| tabBarOptions?: _BottomTabBarOptions |}>; - - /** - * Tab views - */ - - declare export type TabScene = { - route: NavigationRoute, - focused: boolean, - index: number, - tintColor?: ?string, - ... - }; - - //--------------------------------------------------------------------------- - // SECTION 4: EXPORTED MODULE - // This is the only section that types exports. Other sections export types, - // but this section types the module's exports. - //--------------------------------------------------------------------------- - - declare export function createBottomTabNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: BottomTabNavigatorConfig - ): NavigationNavigator<*, *, *>; - declare export function createMaterialTopTabNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: MaterialTopTabNavigatorConfig - ): NavigationNavigator<*, *, *>; - - declare type _SharedTabBarProps = {| - getAccessibilityLabel: (props: {| route: NavigationRoute |}) => ?string, - getTestID: (props: {| route: NavigationRoute |}) => ?string, - renderIcon: (props: {| - route: NavigationRoute, - focused: boolean, - tintColor?: string, - horizontal?: boolean, - |}) => React$Node, - |}; - - declare type _BottomTabBarButtonComponentProps = { - route: NavigationRoute, - focused: boolean, - onPress: () => void, - onLongPress: () => void, - testID?: string, - accessibilityLabel?: string, - accessibilityRole?: AccessibilityRole, - accessibilityStates?: AccessibilityState[], - style?: ViewStyleProp, - ... - }; - declare type _BottomTabBarProps = {| - ..._BottomTabBarOptions, - ..._SharedTabBarProps, - navigation: NavigationTabProp, - onTabPress: (props: {| route: NavigationRoute |}) => void, - onTabLongPress: (props: {| route: NavigationRoute |}) => void, - getAccessibilityRole: (props: {| route: NavigationRoute |}) => ?AccessibilityRole, - getAccessibilityStates: (props: {| - route: NavigationRoute, - focused: boolean, - |}) => AccessibilityState[], - getButtonComponent: (props: {| route: NavigationRoute |}) => ?React$ComponentType<_BottomTabBarButtonComponentProps>, - getLabelText: (props: {| route: NavigationRoute |}) => - | ((scene: {| - focused: boolean, - tintColor?: string, - orientation?: 'horizontal' | 'vertical', - |}) => ?string) - | ?string, - isLandscape: boolean, - jumpTo: (key: string) => void, - screenProps: NavigationScreenProps, - |}; - declare export var BottomTabBar: React$ComponentType<_BottomTabBarProps>; - - declare type _MaterialTopTabBarProps = {| - ..._MaterialTopTabBarOptions, - ..._SharedTabBarProps, - layout: _TabViewLayout, - position: AnimatedNode, - jumpTo: (key: string) => void, - getLabelText: (scene: {| route: NavigationRoute |}) => - | ((scene: {| - focused: boolean, - tintColor: string, - |}) => ?string) - | ?string, - getAccessible?: (scene: {| route: NavigationRoute |}) => ?boolean, - renderBadge?: (scene: {| route: NavigationRoute |}) => React$Node, - onTabPress?: (scene: {| route: NavigationRoute |}) => void, - onTabLongPress?: (scene: {| route: NavigationRoute |}) => void, - tabBarPosition?: 'top' | 'bottom', - screenProps: NavigationScreenProps, - navigation: NavigationTabProp, - |}; - declare export var MaterialTopTabBar: React$ComponentType< - _MaterialTopTabBarProps - >; - - declare type _TabViewProps = { - ..._SharedTabBarProps, - getLabelText: (props: {| route: NavigationRoute |}) => ?string, - renderScene: (props: {| route: NavigationRoute |}) => React$Node, - onIndexChange: (index: number) => void, - onTabPress: (props: {| route: NavigationRoute |}) => void, - onTabLongPress: (props: {| route: NavigationRoute |}) => void, - navigation: NavigationTabProp, - descriptors: NavigationDescriptorMap, - screenProps?: NavigationScreenProps, - ... - }; - declare export function createTabNavigator< - CustomProps: {...}, - >( - TabView: React$ComponentType<_TabViewProps & CustomProps> - ): ( - routeConfigMap: NavigationRouteConfigMap, - tabConfig?: TabNavigatorConfig - ) => NavigationNavigator<*, *, *>; - -} diff --git a/flow-typed/npm/react-navigation_v4.x.x.js b/flow-typed/npm/react-navigation_v4.x.x.js deleted file mode 100644 index 5ab816be1b5..00000000000 --- a/flow-typed/npm/react-navigation_v4.x.x.js +++ /dev/null @@ -1,980 +0,0 @@ -// flow-typed signature: 2f68f3597d70aadb9da3fb85b4193dc0 -// flow-typed version: ab8203bb4a/react-navigation_v4.x.x/flow_>=v0.104.x - -// @flow - -declare module 'react-navigation' { - - //--------------------------------------------------------------------------- - // SECTION 1: IDENTICAL TYPE DEFINITIONS - // This section is identical across all React Navigation libdefs and contains - // shared definitions. We wish we could make it DRY and import from a shared - // definition, but that isn't yet possible. - //--------------------------------------------------------------------------- - - /** - * SECTION 1A - * We start with some definitions that we have copy-pasted from React Native - * source files. - */ - - // This is a bastardization of the true StyleObj type located in - // react-native/Libraries/StyleSheet/StyleSheetTypes. We unfortunately can't - // import that here, and it's too lengthy (and consequently too brittle) to - // copy-paste here either. - declare type StyleObj = - | null - | void - | number - | false - | '' - | $ReadOnlyArray - | { [name: string]: any, ... }; - declare type ViewStyleProp = StyleObj; - declare type TextStyleProp = StyleObj; - declare type AnimatedViewStyleProp = StyleObj; - declare type AnimatedTextStyleProp = StyleObj; - - /** - * SECTION 1B - * The following are type declarations for core types necessary for every - * React Navigation libdef. - */ - - /** - * Navigation State + Action - */ - - declare export type NavigationParams = { [key: string]: mixed, ... }; - - declare export type NavigationBackAction = {| - type: 'Navigation/BACK', - key?: ?string, - |}; - declare export type NavigationInitAction = {| - type: 'Navigation/INIT', - params?: NavigationParams, - |}; - declare export type NavigationNavigateAction = {| - type: 'Navigation/NAVIGATE', - routeName: string, - params?: NavigationParams, - - // The action to run inside the sub-router - action?: NavigationNavigateAction, - - key?: string, - |}; - declare export type NavigationSetParamsAction = {| - type: 'Navigation/SET_PARAMS', - - // The key of the route where the params should be set - key: string, - - // The new params to merge into the existing route params - params: NavigationParams, - |}; - - declare export type NavigationPopAction = {| - +type: 'Navigation/POP', - +n?: number, - +immediate?: boolean, - |}; - declare export type NavigationPopToTopAction = {| - +type: 'Navigation/POP_TO_TOP', - +immediate?: boolean, - |}; - declare export type NavigationPushAction = {| - +type: 'Navigation/PUSH', - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - +key?: string, - |}; - declare export type NavigationResetAction = {| - type: 'Navigation/RESET', - index: number, - key?: ?string, - actions: Array, - |}; - declare export type NavigationReplaceAction = {| - +type: 'Navigation/REPLACE', - +key: string, - +routeName: string, - +params?: NavigationParams, - +action?: NavigationNavigateAction, - |}; - declare export type NavigationCompleteTransitionAction = {| - +type: 'Navigation/COMPLETE_TRANSITION', - +key?: string, - +toChildKey?: string, - |}; - - declare export type NavigationOpenDrawerAction = {| - +type: 'Navigation/OPEN_DRAWER', - +key?: string, - |}; - declare export type NavigationCloseDrawerAction = {| - +type: 'Navigation/CLOSE_DRAWER', - +key?: string, - |}; - declare export type NavigationToggleDrawerAction = {| - +type: 'Navigation/TOGGLE_DRAWER', - +key?: string, - |}; - declare export type NavigationDrawerOpenedAction = {| - +type: 'Navigation/DRAWER_OPENED', - +key?: string, - |}; - declare export type NavigationDrawerClosedAction = {| - +type: 'Navigation/DRAWER_CLOSED', - +key?: string, - |}; - - declare export type NavigationJumpToAction = {| - +type: 'Navigation/JUMP_TO'; - +preserveFocus: boolean, - +routeName: string, - +key?: string, - +params?: NavigationParams, - |}; - - declare export type NavigationAction = - | NavigationBackAction - | NavigationInitAction - | NavigationNavigateAction - | NavigationSetParamsAction - | NavigationPopAction - | NavigationPopToTopAction - | NavigationPushAction - | NavigationResetAction - | NavigationReplaceAction - | NavigationCompleteTransitionAction - | NavigationOpenDrawerAction - | NavigationCloseDrawerAction - | NavigationToggleDrawerAction - | NavigationDrawerOpenedAction - | NavigationDrawerClosedAction - | NavigationJumpToAction; - - /** - * NavigationState is a tree of routes for a single navigator, where each - * child route may either be a NavigationScreenRoute or a - * NavigationRouterRoute. NavigationScreenRoute represents a leaf screen, - * while the NavigationRouterRoute represents the state of a child navigator. - * - * NOTE: NavigationState is a state tree local to a single navigator and - * its child navigators (via the routes field). - * If we're in navigator nested deep inside the app, the state will only be - * the state for that navigator. - * The state for the root navigator of our app represents the whole navigation - * state for the whole app. - */ - declare export type NavigationState = { - /** - * Index refers to the active child route in the routes array. - */ - index: number, - routes: Array, - isTransitioning?: bool, - ... - }; - - declare export type NavigationRoute = - | NavigationLeafRoute - | NavigationStateRoute; - - declare export type NavigationLeafRoute = {| - /** - * React's key used by some navigators. No need to specify these manually, - * they will be defined by the router. - */ - key: string, - /** - * For example 'Home'. - * This is used as a key in a route config when creating a navigator. - */ - routeName: string, - /** - * Path is an advanced feature used for deep linking and on the web. - */ - path?: string, - /** - * Params passed to this route when navigating to it, - * e.g. `{ car_id: 123 }` in a route that displays a car. - */ - params?: NavigationParams, - |}; - - declare export type NavigationStateRoute = {| - ...NavigationLeafRoute, - ...$Exact, - |}; - - /** - * Router - */ - - declare export type NavigationScreenProps = { [key: string]: mixed, ... }; - - declare export type NavigationScreenOptionsGetter = ( - navigation: NavigationScreenProp, - screenProps: ?NavigationScreenProps, - theme: SupportedThemes, - ) => Options; - - declare export type NavigationRouter = { - /** - * The reducer that outputs the new navigation state for a given action, - * with an optional previous state. When the action is considered handled - * but the state is unchanged, the output state is null. - */ - getStateForAction: (action: NavigationAction, lastState: ?State) => ?State, - /** - * Maps a URI-like string to an action. This can be mapped to a state - * using `getStateForAction`. - */ - getActionForPathAndParams: ( - path: string, - params?: NavigationParams - ) => ?NavigationAction, - getPathAndParamsForState: ( - state: State - ) => { - path: string, - params?: NavigationParams, - ... - }, - getComponentForRouteName: (routeName: string) => NavigationComponent, - getComponentForState: (state: State) => NavigationComponent, - /** - * Gets the screen navigation options for a given screen. - * - * For example, we could get the config for the 'Foo' screen when the - * `navigation.state` is: - * - * {routeName: 'Foo', key: '123'} - */ - getScreenOptions: NavigationScreenOptionsGetter, - ... - }; - - declare export type NavigationScreenOptions = { title?: string, ... }; - - declare export type SupportedThemes = 'light' | 'dark'; - - declare export type NavigationScreenConfigProps = $Shape<{| - navigation: NavigationScreenProp, - screenProps: NavigationScreenProps, - theme: SupportedThemes, - |}>; - - declare export type NavigationScreenConfig = - | Options - | (({| - ...NavigationScreenConfigProps, - navigationOptions: Options, - |}) => Options); - - declare export type NavigationComponent = - | NavigationScreenComponent - | NavigationNavigator<*, *, *>; - - declare interface withOptionalNavigationOptions { - navigationOptions?: NavigationScreenConfig; - } - - declare export type NavigationScreenComponent< - Route: NavigationRoute, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withOptionalNavigationOptions; - - declare interface withRouter { - router: NavigationRouter; - } - - declare export type NavigationNavigator< - State: NavigationState, - Options: {...}, - Props: NavigationNavigatorProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare type _NavigationRouteConfigCore = {| - navigationOptions?: NavigationScreenConfig<*>, - params?: NavigationParams, - path?: string, - |}; - declare export type NavigationRouteConfig = - | NavigationComponent - | {| ..._NavigationRouteConfigCore, screen: NavigationComponent |} - | {| ..._NavigationRouteConfigCore, getScreen: () => NavigationComponent |}; - - declare export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, ... }; - - /** - * Navigator Prop - */ - - declare export type NavigationDispatch = ( - action: NavigationAction - ) => boolean; - - declare export type EventType = - | 'willFocus' - | 'didFocus' - | 'willBlur' - | 'didBlur' - | 'action'; - - declare export type NavigationEventPayload = {| - type: EventType, - action: NavigationAction, - state: NavigationState, - lastState: ?NavigationState, - |}; - - declare export type NavigationEventCallback = ( - payload: NavigationEventPayload - ) => void; - - declare export type NavigationEventSubscription = {| remove: () => void |}; - - declare export type NavigationScreenProp<+S> = { - +state: S, - dispatch: NavigationDispatch, - addListener: ( - eventName: string, - callback: NavigationEventCallback - ) => NavigationEventSubscription, - getParam: ( - paramName: ParamName, - fallback?: $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - > - ) => $ElementType< - $PropertyType< - {| - ...{| params: {...} |}, - ...$Exact, - |}, - 'params' - >, - ParamName - >, - dangerouslyGetParent: () => ?NavigationScreenProp, - isFocused: () => boolean, - goBack: (routeKey?: ?string) => boolean, - dismiss: () => boolean, - navigate: ( - routeName: - | string - | { - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - key?: string, - ... - }, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - setParams: (newParams: NavigationParams) => boolean, - ... - }; - - declare export type NavigationNavigatorProps = $Shape<{ - navigation: NavigationScreenProp, - screenProps?: NavigationScreenProps, - navigationOptions?: O, - theme?: SupportedThemes | 'no-preference', - detached?: boolean, - ... - }>; - - /** - * Navigation container - */ - - declare export type NavigationContainer< - State: NavigationState, - Options: {...}, - Props: NavigationContainerProps, - > = React$ComponentType & - withRouter & - withOptionalNavigationOptions; - - declare export type NavigationContainerProps = $Shape<{ - uriPrefix?: string | RegExp, - onNavigationStateChange?: ?( - NavigationState, - NavigationState, - NavigationAction - ) => void, - navigation?: NavigationScreenProp, - persistenceKey?: ?string, - renderLoadingExperimental?: React$ComponentType<{...}>, - screenProps?: NavigationScreenProps, - navigationOptions?: O, - ... - }>; - - /** - * NavigationDescriptor - */ - - declare export type NavigationDescriptor = { - key: string, - state: NavigationRoute, - navigation: NavigationScreenProp, - getComponent: () => NavigationComponent, - ... - }; - - declare export type NavigationDescriptorMap = { - [key: string]: NavigationDescriptor, - ... - }; - - //--------------------------------------------------------------------------- - // SECTION 2: SHARED TYPE DEFINITIONS - // This section too is copy-pasted, but it's not identical across all React - // Navigation libdefs. We pick out bits and pieces that we need. - //--------------------------------------------------------------------------- - - /** - * SECTION 2A - * We start with definitions we have copy-pasted, either from in-package - * types, other Flow libdefs, or from TypeScript types somewhere. - */ - - // This is copied from - // react-native/Libraries/Animated/src/nodes/AnimatedInterpolation.js - declare type ExtrapolateType = 'extend' | 'identity' | 'clamp'; - declare type InterpolationConfigType = { - inputRange: Array, - outputRange: Array | Array, - easing?: (input: number) => number, - extrapolate?: ExtrapolateType, - extrapolateLeft?: ExtrapolateType, - extrapolateRight?: ExtrapolateType, - ... - }; - declare class AnimatedInterpolation { - interpolate(config: InterpolationConfigType): AnimatedInterpolation; - } - - // This is copied from - // react-native/Libraries/Animated/src/animations/Animation.js - declare type EndResult = { finished: boolean, ... }; - declare type EndCallback = (result: EndResult) => void; - declare class Animation { - start( - fromValue: number, - onUpdate: (value: number) => void, - onEnd: ?EndCallback, - previousAnimation: ?Animation, - animatedValue: AnimatedValue, - ): void; - stop(): void; - } - - // This is vaguely copied from - // react-native/Libraries/Animated/src/nodes/AnimatedTracking.js - declare class AnimatedTracking { - constructor( - value: AnimatedValue, - parent: any, - animationClass: any, - animationConfig: Object, - callback?: ?EndCallback, - ): void; - update(): void; - } - - // This is vaguely copied from - // react-native/Libraries/Animated/src/nodes/AnimatedValue.js - declare type ValueListenerCallback = (state: { value: number, ... }) => void; - declare class AnimatedValue { - constructor(value: number): void; - setValue(value: number): void; - setOffset(offset: number): void; - flattenOffset(): void; - extractOffset(): void; - addListener(callback: ValueListenerCallback): string; - removeListener(id: string): void; - removeAllListeners(): void; - stopAnimation(callback?: ?(value: number) => void): void; - resetAnimation(callback?: ?(value: number) => void): void; - interpolate(config: InterpolationConfigType): AnimatedInterpolation; - animate(animation: Animation, callback: ?EndCallback): void; - stopTracking(): void; - track(tracking: AnimatedTracking): void; - } - - /** - * SECTION 2B - * The following are the actually useful definitions in Section 2, that are - * used below in section 3, but also in other libdefs. - */ - - declare export type NavigationPathsConfig = { [routeName: string]: string, ... }; - - /** - * SafeAreaView - */ - - declare type _SafeAreaViewForceInsetValue = 'always' | 'never' | number; - declare type _SafeAreaViewInsets = $Shape<{| - top: _SafeAreaViewForceInsetValue, - bottom: _SafeAreaViewForceInsetValue, - left: _SafeAreaViewForceInsetValue, - right: _SafeAreaViewForceInsetValue, - vertical: _SafeAreaViewForceInsetValue, - horizontal: _SafeAreaViewForceInsetValue, - |}>; - - /** - * Interpolation - */ - - declare export type NavigationStackInterpolatorProps = $Shape<{| - layout: NavigationStackLayout, - scene: NavigationStackScene, - scenes: NavigationStackScene[], - position: AnimatedInterpolation, - navigation: NavigationStackProp, - mode?: HeaderMode, - shadowEnabled?: boolean, - cardOverlayEnabled?: boolean, - |}>; - - declare type _InterpolationResult = { [key: string]: mixed, ... }; - declare export type NavigationStackInterpolator = - (props: NavigationStackInterpolatorProps) => _InterpolationResult; - - /** - * Header - */ - - declare export type HeaderMode = 'float' | 'screen' | 'none'; - - declare export type HeaderProps = {| - layout: NavigationStackLayout, - scene: NavigationStackScene, - scenes: NavigationStackScene[], - position: AnimatedInterpolation, - navigation: NavigationStackProp, - mode: HeaderMode, - leftInterpolator?: NavigationStackInterpolator, - titleInterpolator?: NavigationStackInterpolator, - rightInterpolator?: NavigationStackInterpolator, - backgroundInterpolator?: NavigationStackInterpolator, - layoutPreset: 'left' | 'center', - transitionPreset?: 'fade-in-place' | 'uikit', - backTitleVisible?: boolean, - isLandscape: boolean, - |}; - - /** - * StackRouter - */ - - declare export type NavigationStackProp<+S> = - & NavigationScreenProp - & { - pop: (n?: number, params?: {| immediate?: boolean |}) => boolean, - popToTop: (params?: {| immediate?: boolean |}) => boolean, - push: ( - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - replace: ( - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction - ) => boolean, - reset: (actions: NavigationAction[], index: number) => boolean, - ... - }; - - declare type _HeaderBackButtonProps = {| - disabled?: boolean, - onPress: () => void, - pressColorAndroid?: string, - tintColor?: ?string, - backImage?: React$ComponentType<{ - tintColor: string, - title?: ?string, - ... - }>, - title?: ?string, - truncatedTitle?: ?string, - backTitleVisible?: boolean, - allowFontScaling?: boolean, - titleStyle?: ?TextStyleProp, - headerLayoutPreset: 'left' | 'center', - width?: ?number, - scene: NavigationStackScene, - |}; - - declare export type NavigationStackScreenOptions = NavigationScreenOptions & { - header?: ?(React$Node | (HeaderProps => React$Node)), - headerTransparent?: boolean, - headerTitle?: (props: { children: ?string, ... }) => React$Node | React$Node, - headerTitleStyle?: AnimatedTextStyleProp, - headerTitleAllowFontScaling?: boolean, - headerTintColor?: string, - headerLeft?: ((props: _HeaderBackButtonProps) => React$Node) | React$Node, - headerBackTitle?: ?string, - headerBackImage?: (props: {| - tintColor?: string, - title?: ?string, - |}) => React$Node, - headerTruncatedBackTitle?: string, - headerBackTitleStyle?: TextStyleProp, - headerPressColorAndroid?: string, - headerRight?: React$Node, - headerStyle?: ViewStyleProp, - headerForceInset?: _SafeAreaViewInsets, - headerBackground?: React$Node | React$ElementType, - gesturesEnabled?: boolean, - gestureResponseDistance?: {| - vertical?: number, - horizontal?: number, - |}, - gestureDirection?: 'default' | 'inverted', - ... - }; - - declare export type NavigationStackRouterConfig = {| - initialRouteName?: string, - initialRouteParams?: NavigationParams, - paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenConfig<*>, - defaultNavigationOptions?: NavigationScreenConfig<*>, - initialRouteKey?: string, - |}; - - /** - * Stack Gestures, Animations, and Interpolators - */ - - declare export type NavigationStackLayout = { - height: AnimatedValue, - initHeight: number, - initWidth: number, - isMeasured: boolean, - width: AnimatedValue, - ... - }; - - declare export type NavigationStackScene = { - index: number, - isActive: boolean, - isStale: boolean, - key: string, - route: NavigationRoute, - descriptor: ?NavigationDescriptor, - ... - }; - - /** - * SwitchRouter - */ - - declare export type NavigationSwitchRouterConfig = {| - initialRouteName?: string, - initialRouteParams?: NavigationParams, - paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenConfig<*>, - defaultNavigationOptions?: NavigationScreenConfig<*>, - // todo: type these as the real route names rather than 'string' - order?: string[], - // Does the back button cause the router to switch to the initial tab - backBehavior?: 'none' | 'initialRoute' | 'history' | 'order', // defaults `initialRoute` - resetOnBlur?: boolean, - |}; - - /** - * TabRouter - */ - - declare export type NavigationTabProp<+S> = - & NavigationScreenProp - & { jumpTo: (routeName: string, key?: string) => void, ... }; - - declare export type NavigationTabRouterConfig = NavigationSwitchRouterConfig; - - declare export type NavigationTabScreenOptions = { - ...$Exact, - tabBarLabel?: React$Node, - tabBarVisible?: boolean, - tabBarAccessibilityLabel?: string, - tabBarTestID?: string, - tabBarIcon?: - | React$Node - | ((props: {| - focused: boolean, - tintColor?: string, - horizontal?: boolean, - |}) => React$Node), - tabBarOnPress?: (props: {| - navigation: NavigationTabProp, - defaultHandler: () => void, - |}) => void, - tabBarOnLongPress?: (props: {| - navigation: NavigationTabProp, - defaultHandler: () => void, - |}) => void, - ... - }; - - //--------------------------------------------------------------------------- - // SECTION 3: UNIQUE TYPE DEFINITIONS - // This section normally contains exported types that are not present in any - // other React Navigation libdef. But the main react-navigation libdef doesn't - // have any, so it's empty here. - //--------------------------------------------------------------------------- - - //--------------------------------------------------------------------------- - // SECTION 4: EXPORTED MODULE - // This is the only section that types exports. Other sections export types, - // but this section types the module's exports. - //--------------------------------------------------------------------------- - - declare export var StateUtils: { - get: (state: NavigationState, key: string) => ?NavigationRoute, - indexOf: (state: NavigationState, key: string) => number, - has: (state: NavigationState, key: string) => boolean, - push: (state: NavigationState, route: NavigationRoute) => NavigationState, - pop: (state: NavigationState) => NavigationState, - jumpToIndex: (state: NavigationState, index: number) => NavigationState, - jumpTo: (state: NavigationState, key: string) => NavigationState, - back: (state: NavigationState) => NavigationState, - forward: (state: NavigationState) => NavigationState, - replaceAt: ( - state: NavigationState, - key: string, - route: NavigationRoute - ) => NavigationState, - replaceAtIndex: ( - state: NavigationState, - index: number, - route: NavigationRoute - ) => NavigationState, - reset: ( - state: NavigationState, - routes: Array, - index?: number - ) => NavigationState, - ... - }; - - declare export function getNavigation( - router: NavigationRouter, - state: State, - dispatch: NavigationDispatch, - actionSubscribers: Set, - getScreenProps: () => {...}, - getCurrentNavigation: () => ?NavigationScreenProp - ): NavigationScreenProp; - - declare type _NavigationView> = React$ComponentType<{ - descriptors: NavigationDescriptorMap, - navigation: N, - navigationConfig: *, - ... - }>; - declare export function createNavigator>( - view: _NavigationView, - router: NavigationRouter, - navigatorConfig?: NavigatorConfig - ): NavigationNavigator; - - declare export var NavigationContext: React$Context< - ?NavigationScreenProp, - >; - declare export var NavigationProvider: $PropertyType; - declare export var NavigationConsumer: $PropertyType; - - declare type _SwitchNavigatorConfig = NavigationSwitchRouterConfig; - declare export function createSwitchNavigator( - routeConfigs: NavigationRouteConfigMap, - config?: _SwitchNavigatorConfig - ): NavigationNavigator<*, *, *>; - - declare export var ThemeContext: React$Context; - declare export var ThemeProvider: $PropertyType; - declare export var ThemeConsumer: $PropertyType; - declare export var ThemeColors: { [theme: SupportedThemes]: { [key: string]: string, ... }, ... }; - declare export function useTheme(): SupportedThemes; - - declare export var NavigationActions: {| - BACK: 'Navigation/BACK', - INIT: 'Navigation/INIT', - NAVIGATE: 'Navigation/NAVIGATE', - SET_PARAMS: 'Navigation/SET_PARAMS', - back: (payload?: {| key?: ?string |}) => NavigationBackAction, - init: (payload?: {| params?: NavigationParams |}) => NavigationInitAction, - navigate: (payload: {| - routeName: string, - params?: ?NavigationParams, - action?: ?NavigationNavigateAction, - key?: string, - |}) => NavigationNavigateAction, - setParams: (payload: {| - key: string, - params: NavigationParams, - |}) => NavigationSetParamsAction, - |}; - - declare export var StackActions: {| - POP: 'Navigation/POP', - POP_TO_TOP: 'Navigation/POP_TO_TOP', - PUSH: 'Navigation/PUSH', - RESET: 'Navigation/RESET', - REPLACE: 'Navigation/REPLACE', - COMPLETE_TRANSITION: 'Navigation/COMPLETE_TRANSITION', - pop: (payload: {| - n?: number, - immediate?: boolean, - |}) => NavigationPopAction, - popToTop: (payload: {| immediate?: boolean |}) => NavigationPopToTopAction, - push: (payload: {| - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - key?: string, - |}) => NavigationPushAction, - reset: (payload: {| - index: number, - key?: ?string, - actions: Array, - |}) => NavigationResetAction, - replace: (payload: {| - key?: string, - routeName: string, - params?: NavigationParams, - action?: NavigationNavigateAction, - |}) => NavigationReplaceAction, - completeTransition: (payload: {| - key?: string, - toChildKey?: string, - |}) => NavigationCompleteTransitionAction, - |}; - - declare export var SwitchActions: {| - JUMP_TO: 'Navigation/JUMP_TO', - jumpTo: (payload: {| - routeName: string, - key?: string, - params?: NavigationParams, - |}) => NavigationJumpToAction, - |}; - - declare export function StackRouter( - routeConfigs: NavigationRouteConfigMap, - stackConfig?: NavigationStackRouterConfig - ): NavigationRouter<*, NavigationStackScreenOptions>; - - declare export function TabRouter( - routeConfigs: NavigationRouteConfigMap, - config?: NavigationTabRouterConfig - ): NavigationRouter<*, NavigationTabScreenOptions>; - - declare export function SwitchRouter( - routeConfigs: NavigationRouteConfigMap, - stackConfig?: NavigationSwitchRouterConfig - ): NavigationRouter<*, {| |}>; - - declare export function getActiveChildNavigationOptions< - State: NavigationState, - Options: {...} - >( - navigation: NavigationScreenProp, - screenProps?: NavigationScreenProps, - theme?: SupportedThemes, - ): Options; - - declare type _SceneViewProps = { - component: React$ComponentType<{ - screenProps: ?NavigationScreenProps, - navigation: NavigationScreenProp, - ... - }>, - screenProps: ?NavigationScreenProps, - navigation: NavigationScreenProp, - ... - }; - declare export var SceneView: React$ComponentType<_SceneViewProps>; - - declare type _NavigationEventsProps = { - navigation?: NavigationScreenProp, - onWillFocus?: NavigationEventCallback, - onDidFocus?: NavigationEventCallback, - onWillBlur?: NavigationEventCallback, - onDidBlur?: NavigationEventCallback, - ... - }; - declare export var NavigationEvents: React$ComponentType< - _NavigationEventsProps - >; - - declare export function withNavigation>( - Component: ComponentType - ): React$ComponentType< - $Diff< - React$ElementConfig, - {| navigation: NavigationScreenProp |} - > - >; - declare export function withNavigationFocus>( - Component: ComponentType - ): React$ComponentType<$Diff, {| isFocused: ?boolean |}>>; - - declare export function createAppContainer( - Component: NavigationNavigator - ): NavigationContainer; - - declare export function createKeyboardAwareNavigator( - Comp: React$ComponentType, - stackConfig: {...} - ): React$ComponentType; - - declare export function withOrientation>( - Component: ComponentType - ): React$ComponentType<$Diff, {| isLandscape: boolean |}>>; - - declare type _SafeAreaViewProps = { - forceInset?: _SafeAreaViewInsets, - children?: React$Node, - style?: AnimatedViewStyleProp, - ... - }; - declare export var SafeAreaView: React$ComponentType<_SafeAreaViewProps>; - - // These components take the same props that their React Native primitives do - // Typing them correctly would be extremely brittle - // We await the day we can import types from libraries in flow-typed libdefs - declare export var ScrollView: React$ComponentType<{...}>; - declare export var FlatList: React$ComponentType<{...}>; - declare export var SectionList: React$ComponentType<{...}>; - declare export var Themed: {| - StatusBar: React$ComponentType<{...}>, - Text: React$ComponentType<{...}>, - TextInput: React$ComponentType<{...}>, - |}; - -} From 0fed2a61029f734c661ef114a5c511f9649d2c32 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 17:09:43 -0800 Subject: [PATCH 17/25] MessageReactionList [nfc]: Inline some helper functions. As discussed around https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20MessageReactionList/near/1058097. Also, as planned, delete a helper function we just don't use anymore. --- src/reactions/MessageReactionList.js | 114 ++++++++------------------- 1 file changed, 35 insertions(+), 79 deletions(-) diff --git a/src/reactions/MessageReactionList.js b/src/reactions/MessageReactionList.js index e3de07dcd09..f205d1a4492 100644 --- a/src/reactions/MessageReactionList.js +++ b/src/reactions/MessageReactionList.js @@ -8,14 +8,7 @@ import * as NavigationService from '../nav/NavigationService'; import * as logging from '../utils/logging'; import ReactionUserList from './ReactionUserList'; import { connect } from '../react-redux'; -import type { - AggregatedReaction, - Dispatch, - EmojiType, - Message, - ReactionType, - UserOrBot, -} from '../types'; +import type { Dispatch, EmojiType, Message, ReactionType, UserOrBot } from '../types'; import { Screen, Label, RawLabel } from '../common'; import { getOwnUser } from '../selectors'; import aggregateReactions from './aggregateReactions'; @@ -23,7 +16,6 @@ import styles from '../styles'; import { getAllUsersById } from '../users/userSelectors'; import { materialTopTabNavigatorConfig } from '../styles/tabs'; import Emoji from '../emoji/Emoji'; -import { objectFromEntries } from '../jsBackport'; import { navigateBack } from '../nav/navActions'; const Tab = createMaterialTopTabNavigator(); @@ -35,74 +27,6 @@ const emojiTypeFromReactionType = (reactionType: ReactionType): EmojiType => { return 'image'; }; -/** - * Get the route config for a single aggregated reaction. - */ -const getRouteConfig = ( - aggregatedReaction: AggregatedReaction, - allUsersById: Map, -) => ({ - name: aggregatedReaction.name, - component: () => ( - - ), - options: { - tabBarLabel: () => ( - - - - - ), - }, -}); - -/** - * Generate route config for the reaction-tabs navigator. - * - * There is a tab, with a user list, for each of the message's - * distinct reactions. - */ -// We'll remove this unused function soon. -// eslint-disable-next-line no-unused-vars -const getReactionTabsRoutes = ( - aggregatedReactions: $ReadOnlyArray, - allUsersById: Map, -) => - objectFromEntries( - aggregatedReactions.map(aggregatedReaction => [ - aggregatedReaction.name, - getRouteConfig(aggregatedReaction, allUsersById), - ]), - ); - -/** - * Generate tab-navigator config for the reaction-tabs navigator. - */ -const getReactionTabsNavConfig = ( - aggregatedReactions: $ReadOnlyArray, - reactionName?: string, -) => ({ - backBehavior: 'none', - - // The user may have originally navigated here to look at a reaction - // that's since been removed. Ignore the nav hint in that case. - initialRouteName: aggregatedReactions.some(aR => aR.name === reactionName) - ? reactionName - : undefined, - - ...materialTopTabNavigatorConfig({ - showLabel: true, - showIcon: false, - style: { - borderWidth: 0.15, - }, - }), - swipeEnabled: true, -}); - type SelectorProps = $ReadOnly<{| message: Message | void, ownUserId: number, @@ -160,7 +84,22 @@ class MessageReactionList extends PureComponent { return ( - + aR.name === reactionName) ? reactionName : undefined + } + {...materialTopTabNavigatorConfig({ + showLabel: true, + showIcon: false, + style: { + borderWidth: 0.15, + }, + })} + swipeEnabled + > { // Generate tabs for the reaction list. The tabs depend // on the distinct reactions on the message. @@ -169,7 +108,24 @@ class MessageReactionList extends PureComponent { // Each tab corresponds to an aggregated reaction, and has a user list. ( + + )} + options={{ + tabBarLabel: () => ( + + + + + ), + }} /> ))} From 140c28cc1052d0b1c7096b93d20d77253681e343 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 17:46:12 -0800 Subject: [PATCH 18/25] navActions: Stop using @react-navigation/compat. The compatability layer [1] has eased our migration to React Navigation v5. Now, remove our use of it here by adapting to the new APIs. The ugprade guide [2] describes the changes. There are a lot of changes to the interface, but it does say the following: """ In addition, there have been some changes to the way the navigation actions work. These changes probably won't affect you if you didn't do any advanced tasks with these methods. """ I don't know where they put the threshold for "advanced", but I think we should be fine. They do note (as they do on their "navigating without the navigation prop" doc [3]) that it's best to use the `navigation` object when one can: """ It's highly recommended to use the methods on the navigation object instead of using action creators and `dispatch`. It should only be used for advanced use cases. """ But I haven't noticed any major disruptions so far. [1] https://reactnavigation.org/docs/compatibility [2] https://reactnavigation.org/docs/upgrading-from-4.x/#action-creators [3] https://reactnavigation.org/docs/navigating-without-navigation-prop --- src/nav/navActions.js | 109 ++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/src/nav/navActions.js b/src/nav/navActions.js index 6db243484a0..4e0f136c817 100644 --- a/src/nav/navActions.js +++ b/src/nav/navActions.js @@ -1,12 +1,15 @@ /* @flow strict-local */ -import { StackActions, type NavigationAction } from '@react-navigation/compat'; -import { CommonActions, type GenericNavigationAction } from '@react-navigation/native'; +import { + StackActions, + CommonActions, + type GenericNavigationAction, +} from '@react-navigation/native'; import type { Message, Narrow, SharedData } from '../types'; import type { ApiResponseServerSettings } from '../api/settings/getServerSettings'; import { getSameRoutesCount } from '../selectors'; -export const navigateBack = (): NavigationAction => StackActions.pop({ n: getSameRoutesCount() }); +export const navigateBack = (): GenericNavigationAction => StackActions.pop(getSameRoutesCount()); /* * "Reset" actions, to explicitly prohibit back navigation. @@ -29,89 +32,83 @@ export const resetToMainTabs = (): GenericNavigationAction => */ /** Only call this via `doNarrow`. See there for details. */ -export const navigateToChat = (narrow: Narrow): NavigationAction => - StackActions.push({ routeName: 'chat', params: { narrow } }); +export const navigateToChat = (narrow: Narrow): GenericNavigationAction => + StackActions.push('chat', { narrow }); -export const navigateToUsersScreen = (): NavigationAction => - StackActions.push({ routeName: 'users' }); +export const navigateToUsersScreen = (): GenericNavigationAction => StackActions.push('users'); -export const navigateToSearch = (): NavigationAction => StackActions.push({ routeName: 'search' }); +export const navigateToSearch = (): GenericNavigationAction => StackActions.push('search'); -export const navigateToEmojiPicker = (messageId: number): NavigationAction => - StackActions.push({ routeName: 'emoji-picker', params: { messageId } }); +export const navigateToEmojiPicker = (messageId: number): GenericNavigationAction => + StackActions.push('emoji-picker', { messageId }); -export const navigateToAuth = (serverSettings: ApiResponseServerSettings): NavigationAction => - StackActions.push({ routeName: 'auth', params: { serverSettings } }); +export const navigateToAuth = ( + serverSettings: ApiResponseServerSettings, +): GenericNavigationAction => StackActions.push('auth', { serverSettings }); -export const navigateToDev = (): NavigationAction => StackActions.push({ routeName: 'dev' }); +export const navigateToDev = (): GenericNavigationAction => StackActions.push('dev'); -export const navigateToPassword = (requireEmailFormat: boolean): NavigationAction => - StackActions.push({ routeName: 'password', params: { requireEmailFormat } }); +export const navigateToPassword = (requireEmailFormat: boolean): GenericNavigationAction => + StackActions.push('password', { requireEmailFormat }); -export const navigateToAccountPicker = (): NavigationAction => - StackActions.push({ routeName: 'account' }); +export const navigateToAccountPicker = (): GenericNavigationAction => StackActions.push('account'); -export const navigateToAccountDetails = (userId: number): NavigationAction => - StackActions.push({ routeName: 'account-details', params: { userId } }); +export const navigateToAccountDetails = (userId: number): GenericNavigationAction => + StackActions.push('account-details', { userId }); -export const navigateToGroupDetails = (recipients: $ReadOnlyArray): NavigationAction => - StackActions.push({ routeName: 'group-details', params: { recipients } }); +export const navigateToGroupDetails = ( + recipients: $ReadOnlyArray, +): GenericNavigationAction => StackActions.push('group-details', { recipients }); export const navigateToRealmScreen = ( args: { realm?: URL, initial?: boolean } = {}, -): NavigationAction => - StackActions.push({ routeName: 'realm', params: { realm: args.realm, initial: args.initial } }); +): GenericNavigationAction => + StackActions.push('realm', { realm: args.realm, initial: args.initial }); -export const navigateToLightbox = (src: string, message: Message): NavigationAction => - StackActions.push({ routeName: 'lightbox', params: { src, message } }); +export const navigateToLightbox = (src: string, message: Message): GenericNavigationAction => + StackActions.push('lightbox', { src, message }); -export const navigateToLanguage = (): NavigationAction => - StackActions.push({ routeName: 'language' }); +export const navigateToLanguage = (): GenericNavigationAction => StackActions.push('language'); -export const navigateToCreateGroup = (): NavigationAction => - StackActions.push({ routeName: 'group' }); +export const navigateToCreateGroup = (): GenericNavigationAction => StackActions.push('group'); -export const navigateToDiagnostics = (): NavigationAction => - StackActions.push({ routeName: 'diagnostics' }); +export const navigateToDiagnostics = (): GenericNavigationAction => + StackActions.push('diagnostics'); -export const navigateToVariables = (): NavigationAction => - StackActions.push({ routeName: 'variables' }); +export const navigateToVariables = (): GenericNavigationAction => StackActions.push('variables'); -export const navigateToTiming = (): NavigationAction => StackActions.push({ routeName: 'timing' }); +export const navigateToTiming = (): GenericNavigationAction => StackActions.push('timing'); -export const navigateToStorage = (): NavigationAction => - StackActions.push({ routeName: 'storage' }); +export const navigateToStorage = (): GenericNavigationAction => StackActions.push('storage'); -export const navigateToDebug = (): NavigationAction => StackActions.push({ routeName: 'debug' }); +export const navigateToDebug = (): GenericNavigationAction => StackActions.push('debug'); -export const navigateToStream = (streamId: number): NavigationAction => - StackActions.push({ routeName: 'stream', params: { streamId } }); +export const navigateToStream = (streamId: number): GenericNavigationAction => + StackActions.push('stream', { streamId }); -export const navigateToTopicList = (streamId: number): NavigationAction => - StackActions.push({ routeName: 'topics', params: { streamId } }); +export const navigateToTopicList = (streamId: number): GenericNavigationAction => + StackActions.push('topics', { streamId }); -export const navigateToCreateStream = (): NavigationAction => - StackActions.push({ routeName: 'stream-create' }); +export const navigateToCreateStream = (): GenericNavigationAction => + StackActions.push('stream-create'); -export const navigateToEditStream = (streamId: number): NavigationAction => - StackActions.push({ routeName: 'stream-edit', params: { streamId } }); +export const navigateToEditStream = (streamId: number): GenericNavigationAction => + StackActions.push('stream-edit', { streamId }); -export const navigateToStreamSubscribers = (streamId: number): NavigationAction => - StackActions.push({ routeName: 'invite-users', params: { streamId } }); +export const navigateToStreamSubscribers = (streamId: number): GenericNavigationAction => + StackActions.push('invite-users', { streamId }); -export const navigateToNotifications = (): NavigationAction => - StackActions.push({ routeName: 'notifications' }); +export const navigateToNotifications = (): GenericNavigationAction => + StackActions.push('notifications'); export const navigateToMessageReactionScreen = ( messageId: number, reactionName?: string, -): NavigationAction => - StackActions.push({ routeName: 'message-reactions', params: { messageId, reactionName } }); +): GenericNavigationAction => StackActions.push('message-reactions', { messageId, reactionName }); -export const navigateToLegal = (): NavigationAction => StackActions.push({ routeName: 'legal' }); +export const navigateToLegal = (): GenericNavigationAction => StackActions.push('legal'); -export const navigateToUserStatus = (): NavigationAction => - StackActions.push({ routeName: 'user-status' }); +export const navigateToUserStatus = (): GenericNavigationAction => StackActions.push('user-status'); -export const navigateToSharing = (sharedData: SharedData): NavigationAction => - StackActions.push({ routeName: 'sharing', params: { sharedData } }); +export const navigateToSharing = (sharedData: SharedData): GenericNavigationAction => + StackActions.push('sharing', { sharedData }); From 6f74614aa306300ca9ba38e2c5c2ffb2e4ad6aa6 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 17:58:54 -0800 Subject: [PATCH 19/25] ChatScreen: Stop using @react-navigation/compat. The `withNavigationFocus` HOC was dropped in v5. Also in v5, they introduced a `useIsFocused` Hook. But, as Greg points out [1], they've mitigated the disruption of this sudden change by supplying `withNavigationFocus` in the compat package, which we've been using. We made the switch to the new API easier, in a recent commit, by changing `ChatScreen` from a class component to a function component that uses React Hooks. [1] https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/React.20Navigation.20v5.3A.20compat/near/1058117 --- src/chat/ChatScreen.js | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/chat/ChatScreen.js b/src/chat/ChatScreen.js index 5051483cc0d..e9d2fffc3f1 100644 --- a/src/chat/ChatScreen.js +++ b/src/chat/ChatScreen.js @@ -1,9 +1,8 @@ /* @flow strict-local */ import React from 'react'; import { View } from 'react-native'; -import { withNavigationFocus } from '@react-navigation/compat'; +import { useIsFocused } from '@react-navigation/native'; import { ActionSheetProvider } from '@expo/react-native-action-sheet'; -import { compose } from 'redux'; import { useSelector, useDispatch } from '../react-redux'; import type { AppNavigationProp } from '../nav/AppNavigator'; @@ -25,10 +24,6 @@ import { getShownMessagesForNarrow, isNarrowValid as getIsNarrowValid } from './ type Props = $ReadOnly<{| navigation: AppNavigationProp<'chat'>, - - // From React Navigation's `withNavigationFocus` HOC. Type copied - // from the libdef. - isFocused: ?boolean, |}>; const componentStyles = createStyleSheet({ @@ -48,9 +43,10 @@ const componentStyles = createStyleSheet({ * whole process. */ const useFetchMessages = args => { - const { isFocused, narrow } = args; + const { narrow } = args; const dispatch = useDispatch(); + const isFocused = useIsFocused(); const eventQueueId = useSelector(state => getSession(state).eventQueueId); const loading = useSelector(getLoading); @@ -100,20 +96,16 @@ const useFetchMessages = args => { return { fetchError, isFetching, haveNoMessages }; }; -function ChatScreen(props: Props) { +export default function ChatScreen(props: Props) { const { backgroundColor } = React.useContext(ThemeContext); const [editMessage, setEditMessage] = React.useState(null); - const { navigation, isFocused } = props; - const { narrow } = navigation.state.params; + const { narrow } = props.navigation.state.params; const isNarrowValid = useSelector(state => getIsNarrowValid(state, narrow)); - const { fetchError, isFetching, haveNoMessages } = useFetchMessages({ - isFocused, - narrow, - }); + const { fetchError, isFetching, haveNoMessages } = useFetchMessages({ narrow }); const showMessagePlaceholders = haveNoMessages && isFetching; const sayNoMessages = haveNoMessages && !isFetching; @@ -156,8 +148,3 @@ function ChatScreen(props: Props) { ); } - -export default compose( - // https://reactnavigation.org/docs/4.x/function-after-focusing-screen/#triggering-an-action-with-the-withnavigationfocus-higher-order-component - withNavigationFocus, -)(ChatScreen); From 6bbea373a6f27c05b9d01a496972f4ed30bfe4f2 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Tue, 10 Nov 2020 18:14:55 -0800 Subject: [PATCH 20/25] MainTabs: Stop using @react-navigation/compat. And switch over to the React Navigation v5 component-based API [1] for it. For all screens on `MainTabs`, that means the `navigation` prop gets a new shape, and the `route` prop is introduced. Also, where we invoke the screens to attach them to the navigator, the screens' `navigation` and `route` prop type annotations are checked for correctness. Since we newly define the `MainTabs` component ourselves, make it a Hooks-based component, as that seems to be the way of the future. [1] https://reactnavigation.org/docs/upgrading-from-4.x/#configuring-the-navigator --- src/account-info/ProfileCard.js | 3 +- src/main/HomeTab.js | 3 +- src/main/MainTabs.js | 122 +++++++++++--------- src/pm-conversations/PmConversationsCard.js | 3 +- src/settings/SettingsCard.js | 3 +- 5 files changed, 75 insertions(+), 59 deletions(-) diff --git a/src/account-info/ProfileCard.js b/src/account-info/ProfileCard.js index 562c4534ef7..0facc99ac25 100644 --- a/src/account-info/ProfileCard.js +++ b/src/account-info/ProfileCard.js @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { ScrollView, View } from 'react-native'; -import type { MainTabsNavigationProp } from '../main/MainTabs'; +import type { MainTabsNavigationProp, MainTabsRouteProp } from '../main/MainTabs'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch, User } from '../types'; import { createStyleSheet } from '../styles'; @@ -67,6 +67,7 @@ class LogoutButton extends PureComponent<{| +dispatch: Dispatch |}> { type Props = $ReadOnly<{| navigation: MainTabsNavigationProp<'profile'>, + route: MainTabsRouteProp<'profile'>, dispatch: Dispatch, selfUserDetail: User, diff --git a/src/main/HomeTab.js b/src/main/HomeTab.js index c227e9ce21f..416ef1a9f13 100644 --- a/src/main/HomeTab.js +++ b/src/main/HomeTab.js @@ -3,7 +3,7 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { MainTabsNavigationProp } from './MainTabs'; +import type { MainTabsNavigationProp, MainTabsRouteProp } from './MainTabs'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; @@ -29,6 +29,7 @@ const styles = createStyleSheet({ type Props = $ReadOnly<{| navigation: MainTabsNavigationProp<'home'>, + route: MainTabsRouteProp<'home'>, dispatch: Dispatch, |}>; diff --git a/src/main/MainTabs.js b/src/main/MainTabs.js index 11050959748..d4c2ff60412 100644 --- a/src/main/MainTabs.js +++ b/src/main/MainTabs.js @@ -1,12 +1,11 @@ /* @flow strict-local */ import React from 'react'; import { Platform } from 'react-native'; -import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import { - createCompatNavigatorFactory, - type NavigationTabProp, - type NavigationStateRoute, -} from '@react-navigation/compat'; + createBottomTabNavigator, + type BottomTabNavigationProp, +} from '@react-navigation/bottom-tabs'; +import type { RouteProp } from '@react-navigation/native'; import type { GlobalParamList } from '../nav/globalTypes'; import { bottomTabNavigatorConfig } from '../styles/tabs'; @@ -29,54 +28,67 @@ export type MainTabsNavigatorParamList = {| export type MainTabsNavigationProp< +RouteName: $Keys = $Keys, -> = NavigationTabProp<{| - ...NavigationStateRoute, - params: $ElementType, -|}>; +> = BottomTabNavigationProp; -export default createCompatNavigatorFactory(createBottomTabNavigator)( - { - home: { - screen: HomeTab, - navigationOptions: { - tabBarLabel: 'Home', - tabBarIcon: props => , - }, - }, - streams: { - screen: StreamTabs, - navigationOptions: { - tabBarLabel: 'Streams', - tabBarIcon: props => , - }, - }, - conversations: { - screen: PmConversationsCard, - navigationOptions: { - tabBarLabel: 'Conversations', - tabBarIcon: props => , - }, - }, - settings: { - screen: SettingsCard, - navigationOptions: { - tabBarLabel: 'Settings', - tabBarIcon: props => , - }, - }, - profile: { - screen: ProfileCard, - navigationOptions: { - tabBarLabel: 'Profile', - tabBarIcon: props => , - }, - }, - }, - { - backBehavior: 'none', - ...bottomTabNavigatorConfig({ - showLabel: !!Platform.isPad, - showIcon: true, - }), - }, -); +export type MainTabsRouteProp< + RouteName: $Keys = $Keys, +> = RouteProp; + +const Tab = createBottomTabNavigator< + GlobalParamList, + MainTabsNavigatorParamList, + MainTabsNavigationProp<>, +>(); + +export default function MainTabs() { + return ( + + , + }} + /> + , + }} + /> + , + }} + /> + , + }} + /> + , + }} + /> + + ); +} diff --git a/src/pm-conversations/PmConversationsCard.js b/src/pm-conversations/PmConversationsCard.js index 7bae8caaa86..141865b07c8 100644 --- a/src/pm-conversations/PmConversationsCard.js +++ b/src/pm-conversations/PmConversationsCard.js @@ -3,7 +3,7 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import type { MainTabsNavigationProp } from '../main/MainTabs'; +import type { MainTabsNavigationProp, MainTabsRouteProp } from '../main/MainTabs'; import * as NavigationService from '../nav/NavigationService'; import type { ThemeData } from '../styles'; import { ThemeContext, createStyleSheet } from '../styles'; @@ -36,6 +36,7 @@ const styles = createStyleSheet({ type Props = $ReadOnly<{| navigation: MainTabsNavigationProp<'conversations'>, + route: MainTabsRouteProp<'conversations'>, dispatch: Dispatch, conversations: PmConversationData[], diff --git a/src/settings/SettingsCard.js b/src/settings/SettingsCard.js index c90a4a025ec..71fa466c4bf 100644 --- a/src/settings/SettingsCard.js +++ b/src/settings/SettingsCard.js @@ -3,7 +3,7 @@ import React, { PureComponent } from 'react'; import { ScrollView } from 'react-native'; -import type { MainTabsNavigationProp } from '../main/MainTabs'; +import type { MainTabsNavigationProp, MainTabsRouteProp } from '../main/MainTabs'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch } from '../types'; import { createStyleSheet } from '../styles'; @@ -34,6 +34,7 @@ const styles = createStyleSheet({ type Props = $ReadOnly<{| navigation: MainTabsNavigationProp<'settings'>, + route: MainTabsRouteProp<'settings'>, theme: string, dispatch: Dispatch, From ce7bf0c530040223fad856d1a374221cc40b188b Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 11 Nov 2020 14:41:29 -0800 Subject: [PATCH 21/25] AppNavigator: Stop using @react-navigation/compat. Like the previous commit, but for `AppNavigator`. --- src/account-info/AccountDetailsScreen.js | 7 +- src/account/AccountPickScreen.js | 3 +- src/chat/ChatScreen.js | 5 +- src/chat/GroupDetailsScreen.js | 5 +- src/diagnostics/DiagnosticsScreen.js | 3 +- src/diagnostics/StorageScreen.js | 3 +- src/diagnostics/TimingScreen.js | 3 +- src/diagnostics/VariablesScreen.js | 3 +- src/emoji/EmojiPickerScreen.js | 7 +- src/lightbox/LightboxScreen.js | 5 +- src/main/MainScreenWithTabs.js | 3 +- src/nav/AppNavigator.js | 146 +++++++++++++---------- src/nav/ZulipNavigationContainer.js | 21 +--- src/reactions/MessageReactionList.js | 11 +- src/search/SearchMessagesScreen.js | 3 +- src/settings/DebugScreen.js | 3 +- src/settings/LanguageScreen.js | 3 +- src/settings/LegalScreen.js | 3 +- src/settings/NotificationsScreen.js | 3 +- src/sharing/SharingScreen.js | 3 +- src/start/AuthScreen.js | 9 +- src/start/DevAuthScreen.js | 3 +- src/start/LoadingScreen.js | 6 +- src/start/PasswordAuthScreen.js | 11 +- src/start/RealmScreen.js | 7 +- src/streams/CreateStreamScreen.js | 3 +- src/streams/EditStreamScreen.js | 5 +- src/streams/InviteUsersScreen.js | 5 +- src/streams/StreamScreen.js | 8 +- src/topics/TopicListScreen.js | 7 +- src/user-groups/CreateGroupScreen.js | 3 +- src/user-status/UserStatusScreen.js | 3 +- src/users/UsersScreen.js | 3 +- 33 files changed, 174 insertions(+), 142 deletions(-) diff --git a/src/account-info/AccountDetailsScreen.js b/src/account-info/AccountDetailsScreen.js index 847c8081e5d..56a5d47550d 100644 --- a/src/account-info/AccountDetailsScreen.js +++ b/src/account-info/AccountDetailsScreen.js @@ -1,7 +1,7 @@ /* @flow strict-local */ import React, { PureComponent } from 'react'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import type { Dispatch, UserOrBot } from '../types'; import { createStyleSheet } from '../styles'; import { connect } from '../react-redux'; @@ -31,6 +31,7 @@ type SelectorProps = $ReadOnly<{| type Props = $ReadOnly<{| navigation: AppNavigationProp<'account-details'>, + route: AppNavigationRouteProp<'account-details'>, dispatch: Dispatch, ...SelectorProps, @@ -70,6 +71,6 @@ class AccountDetailsScreen extends PureComponent { } export default connect((state, props) => ({ - user: getUserForId(state, props.navigation.state.params.userId), - isActive: getUserIsActive(state, props.navigation.state.params.userId), + user: getUserForId(state, props.route.params.userId), + isActive: getUserIsActive(state, props.route.params.userId), }))(AccountDetailsScreen); diff --git a/src/account/AccountPickScreen.js b/src/account/AccountPickScreen.js index 9c63bb1f967..8e606030e78 100644 --- a/src/account/AccountPickScreen.js +++ b/src/account/AccountPickScreen.js @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; @@ -14,6 +14,7 @@ import { navigateToRealmScreen, accountSwitch, removeAccount } from '../actions' type Props = $ReadOnly<{| navigation: AppNavigationProp<'account'>, + route: AppNavigationRouteProp<'account'>, accounts: $ReadOnlyArray, dispatch: Dispatch, diff --git a/src/chat/ChatScreen.js b/src/chat/ChatScreen.js index e9d2fffc3f1..3e54fcfb692 100644 --- a/src/chat/ChatScreen.js +++ b/src/chat/ChatScreen.js @@ -5,7 +5,7 @@ import { useIsFocused } from '@react-navigation/native'; import { ActionSheetProvider } from '@expo/react-native-action-sheet'; import { useSelector, useDispatch } from '../react-redux'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import styles, { ThemeContext, createStyleSheet } from '../styles'; import type { EditMessage } from '../types'; import { KeyboardAvoider, OfflineNotice, ZulipStatusBar } from '../common'; @@ -24,6 +24,7 @@ import { getShownMessagesForNarrow, isNarrowValid as getIsNarrowValid } from './ type Props = $ReadOnly<{| navigation: AppNavigationProp<'chat'>, + route: AppNavigationRouteProp<'chat'>, |}>; const componentStyles = createStyleSheet({ @@ -101,7 +102,7 @@ export default function ChatScreen(props: Props) { const [editMessage, setEditMessage] = React.useState(null); - const { narrow } = props.navigation.state.params; + const { narrow } = props.route.params; const isNarrowValid = useSelector(state => getIsNarrowValid(state, narrow)); diff --git a/src/chat/GroupDetailsScreen.js b/src/chat/GroupDetailsScreen.js index 5e4587600e4..a6b3cc45bea 100644 --- a/src/chat/GroupDetailsScreen.js +++ b/src/chat/GroupDetailsScreen.js @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import type { Dispatch, UserOrBot } from '../types'; import { connect } from '../react-redux'; @@ -12,6 +12,7 @@ import { navigateToAccountDetails } from '../actions'; type Props = $ReadOnly<{| navigation: AppNavigationProp<'group-details'>, + route: AppNavigationRouteProp<'group-details'>, dispatch: Dispatch, |}>; @@ -22,7 +23,7 @@ class GroupDetailsScreen extends PureComponent { }; render() { - const { recipients } = this.props.navigation.state.params; + const { recipients } = this.props.route.params; return ( , + route: AppNavigationRouteProp<'diagnostics'>, |}>; export default class DiagnosticsScreen extends PureComponent { diff --git a/src/diagnostics/StorageScreen.js b/src/diagnostics/StorageScreen.js index f5605de9ea8..8656073645e 100644 --- a/src/diagnostics/StorageScreen.js +++ b/src/diagnostics/StorageScreen.js @@ -3,7 +3,7 @@ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import type { GlobalState, Dispatch } from '../types'; import { connect } from '../react-redux'; import { Screen } from '../common'; @@ -19,6 +19,7 @@ const calculateKeyStorageSizes = obj => type Props = $ReadOnly<{| navigation: AppNavigationProp<'storage'>, + route: AppNavigationRouteProp<'storage'>, dispatch: Dispatch, state: GlobalState, diff --git a/src/diagnostics/TimingScreen.js b/src/diagnostics/TimingScreen.js index 814914f9879..0139ede7066 100644 --- a/src/diagnostics/TimingScreen.js +++ b/src/diagnostics/TimingScreen.js @@ -2,13 +2,14 @@ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import { Screen } from '../common'; import TimeItem from './TimeItem'; import timing from '../utils/timing'; type Props = $ReadOnly<{| navigation: AppNavigationProp<'timing'>, + route: AppNavigationRouteProp<'timing'>, |}>; export default class TimingScreen extends PureComponent { diff --git a/src/diagnostics/VariablesScreen.js b/src/diagnostics/VariablesScreen.js index dd8d7c693e4..b513d01bbd4 100644 --- a/src/diagnostics/VariablesScreen.js +++ b/src/diagnostics/VariablesScreen.js @@ -2,13 +2,14 @@ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import config from '../config'; import { Screen } from '../common'; import InfoItem from './InfoItem'; type Props = $ReadOnly<{| navigation: AppNavigationProp<'variables'>, + route: AppNavigationRouteProp<'variables'>, |}>; export default class VariablesScreen extends PureComponent { diff --git a/src/emoji/EmojiPickerScreen.js b/src/emoji/EmojiPickerScreen.js index f929a0d8a07..69a142c1987 100644 --- a/src/emoji/EmojiPickerScreen.js +++ b/src/emoji/EmojiPickerScreen.js @@ -3,7 +3,7 @@ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import * as NavigationService from '../nav/NavigationService'; import * as api from '../api'; import { unicodeCodeByName } from './codePointMap'; @@ -18,6 +18,7 @@ import zulipExtraEmojiMap from './zulipExtraEmojiMap'; type Props = $ReadOnly<{| navigation: AppNavigationProp<'emoji-picker'>, + route: AppNavigationRouteProp<'emoji-picker'>, activeImageEmojiByName: RealmEmojiById, auth: Auth, @@ -54,8 +55,8 @@ class EmojiPickerScreen extends PureComponent { }; addReaction = (emojiName: string) => { - const { auth, navigation } = this.props; - const { messageId } = navigation.state.params; + const { auth, route } = this.props; + const { messageId } = route.params; const { reactionType, emojiCode } = this.getReactionTypeAndCode(emojiName); api.emojiReactionAdd(auth, messageId, reactionType, emojiCode, emojiName); diff --git a/src/lightbox/LightboxScreen.js b/src/lightbox/LightboxScreen.js index c462b9eab38..b82e5951c2d 100644 --- a/src/lightbox/LightboxScreen.js +++ b/src/lightbox/LightboxScreen.js @@ -3,7 +3,7 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; import { ActionSheetProvider } from '@expo/react-native-action-sheet'; -import type { AppNavigationProp } from '../nav/AppNavigator'; +import type { AppNavigationProp, AppNavigationRouteProp } from '../nav/AppNavigator'; import { ZulipStatusBar } from '../common'; import { createStyleSheet } from '../styles'; import Lightbox from './Lightbox'; @@ -19,11 +19,12 @@ const styles = createStyleSheet({ type Props = $ReadOnly<{| navigation: AppNavigationProp<'lightbox'>, + route: AppNavigationRouteProp<'lightbox'>, |}>; export default class LightboxScreen extends PureComponent { render() { - const { src, message } = this.props.navigation.state.params; + const { src, message } = this.props.route.params; return (