From 257ab02c7d05f98493f179336a74bd3f492790fd Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Tue, 20 Oct 2020 10:45:44 +0200 Subject: [PATCH] feat: bring alphabetical order (#664) Added README.md for old implementation of native-stack and made all props follow alphabetical order. --- README.md | 10 +- createNativeStackNavigator/README.md | 200 ++++++++++++++++++++++++ native-stack/README.md | 97 ++++++------ src/createNativeStackNavigator.js | 44 +++--- src/index.d.ts | 155 +++++++++--------- src/native-stack/types.tsx | 170 ++++++++++---------- src/native-stack/views/HeaderConfig.tsx | 32 ++-- 7 files changed, 455 insertions(+), 253 deletions(-) create mode 100644 createNativeStackNavigator/README.md diff --git a/README.md b/README.md index 4c21c048c0..04514f3939 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ For most people using an app built from the react-native template, that means ed You should add this code, which specifically discards any Activity state persisted during the Activity restart process, to avoid inconsistencies that lead to crashes. ```java - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(null); - } +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(null); +} ``` For people that must handle cases like this, there is [a more detailed discussion of the difficulties in a series of related comments](https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704633). @@ -66,7 +66,7 @@ Note that the above code needs to execute before the first render of a navigatio ### Using createNativeStackNavigator with React Navigation -To take advantage of the native stack navigator primitive for React Navigation that leverages `UINavigationController` on iOS and `Fragment` on Android, please refer to the [README in react-native-screens/native-stack](https://github.com/software-mansion/react-native-screens/tree/master/native-stack). Note that this depends on React Navigation v5. +To take advantage of the native stack navigator primitive for React Navigation that leverages `UINavigationController` on iOS and `Fragment` on Android, please refer to the [README in react-native-screens/native-stack](https://github.com/software-mansion/react-native-screens/tree/master/native-stack) for React Navigation v5 and [README in react-native-screens/createNativeStackNavigator](https://github.com/software-mansion/react-native-screens/tree/master/createNativeStackNavigator) for older versions. ## Interop with [react-native-navigation](https://github.com/wix/react-native-navigation) diff --git a/createNativeStackNavigator/README.md b/createNativeStackNavigator/README.md new file mode 100644 index 0000000000..b562e9fab7 --- /dev/null +++ b/createNativeStackNavigator/README.md @@ -0,0 +1,200 @@ +# Native Stack Navigator + +Provides a way for your app to transition between screens where each new screen is placed on top of a stack. + +By default the stack navigator is configured to have the familiar iOS and Android look & feel: new screens slide in from the right on iOS, fade in from the bottom on Android. On iOS, the stack navigator can also be configured to a modal style where screens slide in from the bottom. + +This navigator uses native navigation primitives (`UINavigationController` on iOS and `Fragment` on Android) for navigation under the hood. The main difference from React Navigation's JS-based [stack navigator](https://reactnavigation.org/docs/stack-navigator.html) is that the JS-based navigator re-implements animations and gestures while the native stack navigator relies on the platform primitives for animations and gestures. You should use this navigator if you want native feeling and performance for navigation and don't need much customization, as the customization options of this navigator are limited. + +```sh +npm install react-native-screens @react-navigation/native +``` + +Make sure to enable `react-native-screens`. This needs to be done before our app renders. To do it, add the following code in your entry file (e.g. `App.js`): + +```js +import { enableScreens } from 'react-native-screens'; + +enableScreens(); +``` + +## API Definition + +To use this navigator, import it from `react-native-screens/createNativeStackNavigator`: + +```js +import createNativeStackNavigator from 'react-native-screens/createNativeStackNavigator'; + +const RootStack = createNativeStackNavigator( + { + Home: HomeScreen, + Details: DetailsScreen, + }, + { + initialRouteName: 'Home', + } +); +``` + +### `navigationOptions` for screens inside of the navigator + +#### `backButtonInCustomView` + +Boolean indicating whether to hide the back button while using `headerLeft` function. + +#### `direction` + +String that applies `rtl` or `ltr` form to the stack. On Android, you have to add `android:supportsRtl="true"` in the manifest of your app to enable `rtl`. On Android, if you set the above flag in the manifest, the orientation changes without the need to do it programmatically if the phone has `rtl` direction enabled. On iOS, the direction defaults to `ltr`, and only way to change it is via this prop. + +#### `gestureEnabled` + +Whether you can use gestures to dismiss this screen. Defaults to `true`, + +Gestures are only supported on iOS. They can be disabled only when `stackPresentation` is `push`. + +#### `headerBackTitle` + +Title string used by the back button on iOS. Defaults to the previous scene's `headerTitle`. + +#### `headerBackTitleStyle` + +Style object for header back title. Supported properties: + +- `fontFamily` +- `fontSize` + +#### `headerBackTitleVisible` + +Whether the back button title should be visible or not. Defaults to `true`. Only supported on iOS. + +#### `headerLeft` + +Function which returns a React Element to display on the left side of the header. For now, on Android, using it will cause the title to also disappear. + +#### `headerRight` + +Function which returns a React Element to display on the right side of the header. + +#### `headerHideBackButton` + +Boolean indicating whether to hide the back button in the header. Only supported on Android. + +#### `headerStyle` + +Style object for the header. Supported properties: + +- `backgroundColor` +- `blurEffect` (iOS only). Possible values can be checked in `index.d.ts` file. + +#### `headerTintColor` + +Tint color for the header. Changes the color of the back button and title. + +#### `headerTitle` + +String to be used by the header as title string. Defaults to scene `title`. + +#### `headerTitleStyle` + +Style object for header title. Supported properties: + +- `fontFamily` +- `fontSize` +- `color` + +#### `headerTopInsetEnabled` + +A Boolean to that lets you opt out of insetting the header. You may want to * set this to `false` if you use an opaque status bar. Defaults to `true`. Insets are always applied on iOS because the header cannot be opaque. Only supported on Android. + +#### `hideShadow` + +Boolean indicating whether to hide the elevation shadow on the header. + +#### `largeTitle` + +Boolean used to set a native property to prefer a large title header (like in iOS setting). + +For the large title to collapse on scroll, the content of the screen should be wrapped in a scrollable view such as `ScrollView` or `FlatList`. If the scrollable area doesn't fill the screen, the large title won't collapse on scroll. + +Only supported on iOS. + +#### `stackAnimation` + +How the given screen should appear/disappear when pushed or popped at the top of the stack. Possible values: + +- `default` - Uses a platform default animation. +- `fade` - Fades screen in or out. +- `flip` – Flips the screen, requires stackPresentation: `modal` (iOS only). +- `none` - The screen appears/disappears without an animation. + +Defaults to `default`. + +#### `stackPresentation` + +How the screen should be presented. Possible values: + +- `push` - The new screen will be pushed onto a stack. The default animation on iOS is to slide from the side. The animation on Android may vary depending on the OS version and theme. +- `modal` - The new screen will be presented modally. In addition, this allows for a nested stack to be rendered inside such screens. +- `transparentModal` - The new screen will be presented modally. In addition, the second to last screen will remain attached to the stack container such that if the top screen is translucent, the content below can still be seen. If `"modal"` is used instead, the below screen gets removed as soon as the transition ends. +- `containedModal` – will use "UIModalPresentationCurrentContext" modal style on iOS and will fallback to `"modal"` on Android. +- `containedTransparentModal` – will use "UIModalPresentationOverCurrentContext" modal style on iOS and will fallback to `"transparentModal"` on Android. +- `fullScreenModal` – will use "UIModalPresentationFullScreen" modal style on iOS and will fallback to `"modal"` on Android. +- `formSheet` – will use "UIModalPresentationFormSheet" modal style on iOS and will fallback to `"modal"` on Android. + +Defaults to `push`. + +#### `title` + +A string that can be used as a fallback for `headerTitle`. + +#### `translucent` + +Boolean indicating whether the navigation bar is translucent. + +### Helpers + +The stack navigator adds the following methods to the navigation prop: + +#### `push` + +Pushes a new screen to the top of the stack and navigate to it. The method accepts the following arguments: + +- `name` - _string_ - Name of the route to push onto the stack. +- `params` - _object_ - Screen params to merge into the destination route (found in the pushed screen through `route.params`). + +```js +navigation.push('Profile', { name: 'Wojtek' }); +``` + +#### `pop` + +Pops the current screen from the stack and navigates back to the previous screen. It takes one optional argument (`count`), which allows you to specify how many screens to pop back by. + +```js +navigation.pop(); +``` + +#### `popToTop` + +Pops all of the screens in the stack except the first one and navigates to it. + +```js +navigation.popToTop(); +``` + +## Additional options + +### Measuring header's height on iOS + +Using translucent header on iOS can result in the need of measuring your header's height. In order to do it, you can use `react-native-safe-area-context`. It can be measured like this: +```js +import { useSafeAreaInsets } from 'react-native-safe-area-context'; + +... + +const statusBarInset = useSafeAreaInsets().top; // inset of the status bar +const smallHeaderInset = statusBarInset + 44; // inset to use for a small header since it's frame is equal to 44 + the frame of status bar +const largeHeaderInset = statusBarInset + 96; // inset to use for a large header since it's frame is equal to 96 + the frame of status bar +``` + +You can also see an example of using these values with a `ScrollView` here: https://snack.expo.io/@wolewicki/ios-header-height. diff --git a/native-stack/README.md b/native-stack/README.md index c31ad758ef..396cc0e8ca 100644 --- a/native-stack/README.md +++ b/native-stack/README.md @@ -55,57 +55,50 @@ Default options to use for the screens in the navigator. The `options` prop can be used to configure individual screens inside the navigator. Supported options are: -#### `title` - -A string that can be used as a fallback for `headerTitle`. - -#### `headerShown` - -Whether to show or hide the header for the screen. The header is shown by default. Setting this to `false` hides the header. +#### `backButtonInCustomView` -#### `headerHideBackButton` +Boolean indicating whether to hide the back button while using `headerLeft` function. -Boolean indicating whether to hide the back button in the header. Only supported on Android. +#### `contentStyle` -#### `backButtonInCustomView` +Style object for the scene content. -Boolean indicating whether to hide the back button while using `headerLeft` function. +#### `direction` -#### `headerHideShadow` +String that applies `rtl` or `ltr` form to the stack. On Android, you have to add `android:supportsRtl="true"` in the manifest of your app to enable `rtl`. On Android, if you set the above flag in the manifest, the orientation changes without the need to do it programmatically if the phone has `rtl` direction enabled. On iOS, the direction defaults to `ltr`, and only way to change it is via this prop. -Boolean indicating whether to hide the elevation shadow on the header. +#### `gestureEnabled` -#### `headerTitle` +Whether you can use gestures to dismiss this screen. Defaults to `true`, -String to be used by the header as title string. Defaults to scene `title`. +Gestures are only supported on iOS. They can be disabled only when `stackPresentation` is `push`. #### `headerBackTitle` Title string used by the back button on iOS. Defaults to the previous scene's `headerTitle`. -#### `headerBackTitleVisible` - -Whether the back button title should be visible or not. Defaults to `true`. Only supported on iOS. +#### `headerBackTitleStyle` -#### `headerRight` +Style object for header back title. Supported properties: -Function which returns a React Element to display on the right side of the header. +- `fontFamily` +- `fontSize` -#### `headerLeft` +#### `headerBackTitleVisible` -Function which returns a React Element to display on the left side of the header. For now, on Android, using it will cause the title to also disappear. +Whether the back button title should be visible or not. Defaults to `true`. Only supported on iOS. #### `headerCenter` Function which returns a React Element to display in the center of the header. -#### `headerTranslucent` +#### `headerHideBackButton` -Boolean indicating whether the navigation bar is translucent. +Boolean indicating whether to hide the back button in the header. Only supported on Android. -#### `headerTopInsetEnabled` +#### `headerHideShadow` -A Boolean to that lets you opt out of insetting the header. You may want to * set this to `false` if you use an opaque status bar. Defaults to `true`. Insets are always applied on iOS because the header cannot be opaque. Only supported on Android. +Boolean indicating whether to hide the elevation shadow on the header. #### `headerLargeTitle` @@ -115,19 +108,32 @@ For the large title to collapse on scroll, the content of the screen should be w Only supported on iOS. -#### `direction` +#### `headerLeft` -String that applies `rtl` or `ltr` form to the stack. On Android, you have to add `android:supportsRtl="true"` in the manifest of your app to enable `rtl`. On Android, if you set the above flag in the manifest, the orientation changes without the need to do it programmatically if the phone has `rtl` direction enabled. On iOS, the direction defaults to `ltr`, and only way to change it is via this prop. +Function which returns a React Element to display on the left side of the header. For now, on Android, using it will cause the title to also disappear. -#### `headerTintColor` +#### `headerRight` -Tint color for the header. Changes the color of the back button and title. +Function which returns a React Element to display on the right side of the header. + +#### `headerShown` + +Whether to show or hide the header for the screen. The header is shown by default. Setting this to `false` hides the header. #### `headerStyle` Style object for the header. Supported properties: - `backgroundColor` +- `blurEffect` (iOS only). Possible values can be checked in `index.d.ts` file. + +#### `headerTintColor` + +Tint color for the header. Changes the color of the back button and title. + +#### `headerTitle` + +String to be used by the header as title string. Defaults to scene `title`. #### `headerTitleStyle` @@ -137,22 +143,24 @@ Style object for header title. Supported properties: - `fontSize` - `color` -#### `headerBackTitleStyle` +#### `headerTopInsetEnabled` -Style object for header back title. Supported properties: +A Boolean to that lets you opt out of insetting the header. You may want to * set this to `false` if you use an opaque status bar. Defaults to `true`. Insets are always applied on iOS because the header cannot be opaque. Only supported on Android. -- `fontFamily` -- `fontSize` +#### `headerTranslucent` -#### `contentStyle` +Boolean indicating whether the navigation bar is translucent. -Style object for the scene content. +#### `stackAnimation` -#### `gestureEnabled` +How the given screen should appear/disappear when pushed or popped at the top of the stack. Possible values: -Whether you can use gestures to dismiss this screen. Defaults to `true`, +- `default` - Uses a platform default animation. +- `fade` - Fades screen in or out. +- `flip` – Flips the screen, requires stackPresentation: `modal` (iOS only). +- `none` - The screen appears/disappears without an animation. -Gestures are only supported on iOS. They can be disabled only when `stackPresentation` is `push`. +Defaults to `default`. #### `stackPresentation` @@ -168,16 +176,9 @@ How the screen should be presented. Possible values: Defaults to `push`. -#### `stackAnimation` - -How the given screen should appear/disappear when pushed or popped at the top of the stack. Possible values: - -- `default` - Uses a platform default animation. -- `fade` - Fades screen in or out. -- `flip` – Flips the screen, requires stackPresentation: `modal` (iOS only). -- `none` - The screen appears/disappears without an animation. +#### `title` -Defaults to `default`. +A string that can be used as a fallback for `headerTitle`. ### Events diff --git a/src/createNativeStackNavigator.js b/src/createNativeStackNavigator.js index 4243bf53a8..9dbd302d5e 100644 --- a/src/createNativeStackNavigator.js +++ b/src/createNativeStackNavigator.js @@ -67,19 +67,21 @@ class StackView extends React.Component { const { headerMode } = navigationConfig; const { - title, - headerStyle, - headerTitleStyle, - headerBackTitleStyle, + backButtonInCustomView, + direction, headerBackTitle, + headerBackTitleStyle, headerBackTitleVisible, + headerHideBackButton, + headerLargeTitleStyle, + headerStyle, headerTintColor, + headerTitleStyle, + headerTopInsetEnabled = true, + hideShadow, largeTitle, - headerLargeTitleStyle, + title, translucent, - hideShadow, - headerTopInsetEnabled = true, - direction, } = options; const scene = { @@ -90,28 +92,30 @@ class StackView extends React.Component { }; const headerOptions = { - translucent: translucent === undefined ? false : translucent, - title, - titleFontFamily: headerTitleStyle && headerTitleStyle.fontFamily, - titleColor: - (headerTitleStyle && headerTitleStyle.color) || headerTintColor, - titleFontSize: headerTitleStyle && headerTitleStyle.fontSize, + backButtonInCustomView, backTitle: headerBackTitleVisible === false ? '' : headerBackTitle, backTitleFontFamily: headerBackTitleStyle && headerBackTitleStyle.fontFamily, backTitleFontSize: headerBackTitleStyle && headerBackTitleStyle.fontSize, color: headerTintColor, + direction, + topInsetEnabled: headerTopInsetEnabled, + hideBackButton: headerHideBackButton, + hideShadow, largeTitle, + largeTitleBackgroundColor: + headerLargeTitleStyle && headerLargeTitleStyle.backgroundColor, + largeTitleColor: headerLargeTitleStyle && headerLargeTitleStyle.color, largeTitleFontFamily: headerLargeTitleStyle && headerLargeTitleStyle.fontFamily, largeTitleFontSize: headerLargeTitleStyle && headerLargeTitleStyle.fontSize, - largeTitleColor: headerLargeTitleStyle && headerLargeTitleStyle.color, - largeTitleBackgroundColor: - headerLargeTitleStyle && headerLargeTitleStyle.backgroundColor, - hideShadow, - headerTopInsetEnabled, - direction, + title, + titleColor: + (headerTitleStyle && headerTitleStyle.color) || headerTintColor, + titleFontFamily: headerTitleStyle && headerTitleStyle.fontFamily, + titleFontSize: headerTitleStyle && headerTitleStyle.fontSize, + translucent: translucent === undefined ? false : translucent, }; const hasHeader = headerMode !== 'none' && options.header !== null; diff --git a/src/index.d.ts b/src/index.d.ts index 3db953b495..523206e57f 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -49,25 +49,20 @@ declare module 'react-native-screens' { export interface ScreenProps extends ViewProps { active?: 0 | 1 | Animated.AnimatedInterpolation; - onComponentRef?: (view: any) => void; children?: React.ReactNode; - /** * @description All children screens should have the same value of their "enabled" prop as their container. */ enabled?: boolean; /** - * @description A callback that gets called when the current screen will appear. This is called as soon as the transition begins. - */ - onWillAppear?: (e: NativeSyntheticEvent) => void; - /** - * @description A callback that gets called when the current screen will disappear. This is called as soon as the transition begins. + * @description When set to false the back swipe gesture will be disabled when the parent Screen is on top of the stack. The default value is true. */ - onWillDisappear?: (e: NativeSyntheticEvent) => void; + gestureEnabled?: boolean; /** * @description A callback that gets called when the current screen appears. */ onAppear?: (e: NativeSyntheticEvent) => void; + onComponentRef?: (view: any) => void; /** * @description A callback that gets called when the current screen disappears. */ @@ -77,23 +72,13 @@ declare module 'react-native-screens' { */ onDismissed?: (e: NativeSyntheticEvent) => void; /** - * @type "push" – the new screen will be pushed onto a stack which on iOS means that the default animation will be slide from the side, the animation on Android may vary depending on the OS version and theme. - * @type "modal" – the new screen will be presented modally. In addition this allow for a nested stack to be rendered inside such screens. - * @type "transparentModal" – the new screen will be presented modally but in addition the second to last screen will remain attached to the stack container such that if the top screen is non opaque the content below can still be seen. If "modal" is used instead the below screen will get unmounted as soon as the transition ends. - * @type "containedModal" – will use "UIModalPresentationCurrentContext" modal style on iOS and will fallback to "modal" on Android. - * @type "containedTransparentModal" – will use "UIModalPresentationOverCurrentContext" modal style on iOS and will fallback to "transparentModal" on Android. - * @type "fullScreenModal" – will use "UIModalPresentationFullScreen" modal style on iOS and will fallback to "modal" on Android. - * @type "formSheet" – will use "UIModalPresentationFormSheet" modal style on iOS and will fallback to "modal" on Android. + * @description A callback that gets called when the current screen will appear. This is called as soon as the transition begins. */ - stackPresentation?: StackPresentationTypes; + onWillAppear?: (e: NativeSyntheticEvent) => void; /** - * @description Allows for the customization of how the given screen should appear/dissapear when pushed or popped at the top of the stack. The following values are currently supported: - * @type "default" – uses a platform default animation - * @type "fade" – fades screen in or out - * @type "flip" – flips the screen, requires stackPresentation: "modal" (iOS only) - * @type "none" – the screen appears/dissapears without an animation + * @description A callback that gets called when the current screen will disappear. This is called as soon as the transition begins. */ - stackAnimation?: StackAnimationTypes; + onWillDisappear?: (e: NativeSyntheticEvent) => void; /** * @description Allows for the customization of the type of animation to use when this screen replaces another screen at the top of the stack. The following values are currently supported: * @type "push" – performs push animation @@ -101,9 +86,23 @@ declare module 'react-native-screens' { */ replaceAnimation?: ScreenReplaceTypes; /** - * @description When set to false the back swipe gesture will be disabled when the parent Screen is on top of the stack. The default value is true. + * @description Allows for the customization of how the given screen should appear/dissapear when pushed or popped at the top of the stack. The following values are currently supported: + * @type "default" – uses a platform default animation + * @type "fade" – fades screen in or out + * @type "flip" – flips the screen, requires stackPresentation: "modal" (iOS only) + * @type "none" – the screen appears/dissapears without an animation */ - gestureEnabled?: boolean; + stackAnimation?: StackAnimationTypes; + /** + * @type "push" – the new screen will be pushed onto a stack which on iOS means that the default animation will be slide from the side, the animation on Android may vary depending on the OS version and theme. + * @type "modal" – the new screen will be presented modally. In addition this allow for a nested stack to be rendered inside such screens. + * @type "transparentModal" – the new screen will be presented modally but in addition the second to last screen will remain attached to the stack container such that if the top screen is non opaque the content below can still be seen. If "modal" is used instead the below screen will get unmounted as soon as the transition ends. + * @type "containedModal" – will use "UIModalPresentationCurrentContext" modal style on iOS and will fallback to "modal" on Android. + * @type "containedTransparentModal" – will use "UIModalPresentationOverCurrentContext" modal style on iOS and will fallback to "transparentModal" on Android. + * @type "fullScreenModal" – will use "UIModalPresentationFullScreen" modal style on iOS and will fallback to "modal" on Android. + * @type "formSheet" – will use "UIModalPresentationFormSheet" modal style on iOS and will fallback to "modal" on Android. + */ + stackPresentation?: StackPresentationTypes; } export interface ScreenContainerProps extends ViewProps { @@ -114,8 +113,6 @@ declare module 'react-native-screens' { } export interface ScreenStackProps extends ViewProps { - transitioning?: number; - progress?: number; /** * @description A callback that gets called when the current screen finishes its transition. */ @@ -124,78 +121,71 @@ declare module 'react-native-screens' { export interface ScreenStackHeaderConfigProps extends ViewProps { /** - * @description String that representing screen title that will get rendered in the middle section of the header. On iOS the title is centered on the header while on Android it is aligned to the left and placed next to back button (if one is present). - */ - title?: string; - /** - * @description When set to true the header will be hidden while the parent Screen is on the top of the stack. The default value is false. + * @description Whether to show the back button with a custom left side of the header. */ - hidden?: boolean; + backButtonInCustomView?: boolean; /** - * @description Controls the color of items rendered on the header. This includes back icon, back text (iOS only) and title text. If you want the title to have different color use titleColor property. + * @description Controls the color of the navigation header. */ - color?: string; + backgroundColor?: string; /** - * @description Customize font family to be used for the title. + * @host (iOS only) + * @description Allows for controlling the string to be rendered next to back button. By default iOS uses the title of the previous screen. */ - titleFontFamily?: string; + backTitle?: string; /** - * @description Customize the size of the font to be used for the title. + * @host (iOS only) + * @description Allows for customizing font family to be used for back button title on iOS. */ - titleFontSize?: number; + backTitleFontFamily?: string; /** - * @description Allows for setting text color of the title. + * @host (iOS only) + * @description Allows for customizing font size to be used for back button title on iOS. */ - titleColor?: string; + backTitleFontSize?: number; /** - * @description Controls the color of the navigation header. + * @host (iOS only) + * @description Blur effect to be applied to the header. Works with backgroundColor's alpha < 1. */ - backgroundColor?: string; + blurEffect?: BlurEffectTypes; /** - * @description Boolean that allows for disabling drop shadow under navigation header. The default value is true. + * Pass HeaderLeft, HeaderRight and HeaderTitle */ - hideShadow?: boolean; + children?: React.ReactNode; /** - * @description If set to true the back button will not be rendered as a part of navigation header. + *@description Controls whether the stack should be in rtl or ltr form. */ - hideBackButton?: boolean; + direction?: 'rtl' | 'ltr'; /** - * @description Whether to show the back button with a custom left side of the header. + * @description When set to true the header will be hidden while the parent Screen is on the top of the stack. The default value is false. */ - backButtonInCustomView?: boolean; + hidden?: boolean; /** - * @description When set to true, it makes native navigation bar on iOS semi transparent with blur effect. It is a common way of presenting navigation bar introduced in iOS 11. The default value is false + * @description Controls the color of items rendered on the header. This includes back icon, back text (iOS only) and title text. If you want the title to have different color use titleColor property. */ - translucent?: boolean; + color?: string; /** - * @description A flag to that lets you opt out of insetting the header. You may want to set this to `false` if you use an opaque status bar. Defaults to `true`. - * @host (Android only) + * @description If set to true the back button will not be rendered as a part of navigation header. */ - topInsetEnabled?: boolean; + hideBackButton?: boolean; /** - * @host (iOS only) - * @description Allows for controlling the string to be rendered next to back button. By default iOS uses the title of the previous screen. + * @description Boolean that allows for disabling drop shadow under navigation header. The default value is true. */ - backTitle?: string; + hideShadow?: boolean; /** * @host (iOS only) - * @description Allows for customizing font family to be used for back button title on iOS. + * @description When set to true it makes the title display using the large title effect. */ - backTitleFontFamily?: string; + largeTitle?: boolean; /** - * @host (iOS only) - * @description Allows for customizing font size to be used for back button title on iOS. + *@description Controls the color of the navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar. */ - backTitleFontSize?: number; + largeTitleBackgroundColor?: string; /** * @host (iOS only) - * @description When set to true it makes the title display using the large title effect. - */ - largeTitle?: boolean; - /** - *@description Controls whether the stack should be in rtl or ltr form. + * @description Customize the color to be used for the large title. By default uses the titleColor property. */ - direction?: 'rtl' | 'ltr'; + largeTitleColor?: string; /** * @host (iOS only) * @description Customize font family to be used for the large title. @@ -206,28 +196,35 @@ declare module 'react-native-screens' { * @description Customize the size of the font to be used for the large title. */ largeTitleFontSize?: number; - /** - *@description Controls the color of the navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar. - */ - largeTitleBackgroundColor?: string; /** * @description Boolean that allows for disabling drop shadow under navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar. */ largeTitleHideShadow?: boolean; /** - * @host (iOS only) - * @description Customize the color to be used for the large title. By default uses the titleColor property. + * @description String that representing screen title that will get rendered in the middle section of the header. On iOS the title is centered on the header while on Android it is aligned to the left and placed next to back button (if one is present). */ - largeTitleColor?: string; + title?: string; /** - * Pass HeaderLeft, HeaderRight and HeaderTitle + * @description Allows for setting text color of the title. */ - children?: React.ReactNode; + titleColor?: string; /** - * @host (iOS only) - * @description Blur effect to be applied to the header. Works with backgroundColor's alpha < 1. + * @description Customize font family to be used for the title. */ - blurEffect?: BlurEffectTypes; + titleFontFamily?: string; + /** + * @description Customize the size of the font to be used for the title. + */ + titleFontSize?: number; + /** + * @host (Android only) + * @description A flag to that lets you opt out of insetting the header. You may want to set this to `false` if you use an opaque status bar. Defaults to `true`. + */ + topInsetEnabled?: boolean; + /** + * @description When set to true, it makes native navigation bar on iOS semi transparent with blur effect. It is a common way of presenting navigation bar introduced in iOS 11. The default value is false + */ + translucent?: boolean; } export const Screen: ComponentClass; diff --git a/src/native-stack/types.tsx b/src/native-stack/types.tsx index 862dfa5382..b6be157cd3 100644 --- a/src/native-stack/types.tsx +++ b/src/native-stack/types.tsx @@ -75,73 +75,60 @@ export type NativeStackNavigationConfig = Record; export type NativeStackNavigationOptions = { /** - * String that can be displayed in the header as a fallback for `headerTitle`. + * Image to display in the header as the back button. + * Defaults to back icon image for the platform (a chevron on iOS and an arrow on Android). */ - title?: string; + backButtonImage?: ImageSourcePropType; /** - * String to display in the header as title. Defaults to scene `title`. + * Whether to show the back button with custom left side of the header. */ - headerTitle?: string; + backButtonInCustomView?: boolean; /** - * Image to display in the header as the back button. - * Defaults to back icon image for the platform (a chevron on iOS and an arrow on Android). + * Style object for the scene content. */ - backButtonImage?: ImageSourcePropType; + contentStyle?: StyleProp; /** - * Title to display in the back button. + * Whether the stack should be in rtl or ltr form. + */ + direction?: 'rtl' | 'ltr'; + /** + * Whether you can use gestures to dismiss this screen. Defaults to `true`. * Only supported on iOS. * * @platform ios */ - headerBackTitle?: string; + gestureEnabled?: boolean; /** - * Whether the back button title should be visible or not. Defaults to `true`. + * Title to display in the back button. * Only supported on iOS. * * @platform ios */ - headerBackTitleVisible?: boolean; - /** - * Whether to show the header. - */ - headerShown?: boolean; - /** - * Whether to show the back button with custom left side of the header. - */ - backButtonInCustomView?: boolean; - /** - * Boolean indicating whether the navigation bar is translucent. - */ - headerTranslucent?: boolean; + headerBackTitle?: string; /** - * Boolean to set native property to prefer large title header (like in iOS setting). - * For large title to collapse on scroll, the content of the screen should be wrapped in a scrollable view such as `ScrollView` or `FlatList`. - * If the scrollable area doesn't fill the screen, the large title won't collapse on scroll. + * Style object for header back title. Supported properties: + * - fontFamily + * - fontSize + * * Only supported on iOS. * * @platform ios */ - headerLargeTitle?: boolean; - /** - * Whether the stack should be in rtl or ltr form. - */ - direction?: 'rtl' | 'ltr'; - /** - * Function which returns a React Element to display on the right side of the header. - */ - headerRight?: (props: { tintColor?: string }) => React.ReactNode; + headerBackTitleStyle?: { + fontFamily?: string; + fontSize?: number; + }; /** - * Function which returns a React Element to display on the left side of the header. + * Whether the back button title should be visible or not. Defaults to `true`. + * Only supported on iOS. + * + * @platform ios */ - headerLeft?: (props: { tintColor?: string }) => React.ReactNode; + headerBackTitleVisible?: boolean; /** * Function which returns a React Element to display in the center of the header. */ headerCenter?: (props: { tintColor?: string }) => React.ReactNode; - /** - * Tint color for the header. Changes the color of back button and title. - */ - headerTintColor?: string; /** * Boolean indicating whether to hide the back button in header. * Only supported on Android. @@ -153,19 +140,6 @@ export type NativeStackNavigationOptions = { * Boolean indicating whether to hide the elevation shadow or the bottom border on the header. */ headerHideShadow?: boolean; - /** - * Boolean that allows for disabling drop shadow under navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar. - */ - headerLargeTitleHideShadow?: boolean; - /** - * Style object for header title. Supported properties: - * - backgroundColor - * - blurEffect - */ - headerStyle?: { - backgroundColor?: string; - blurEffect?: ScreenStackHeaderConfigProps['blurEffect']; - }; /** * Controls the style of the navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar. Supported properties: * - backgroundColor @@ -176,16 +150,18 @@ export type NativeStackNavigationOptions = { backgroundColor?: string; }; /** - * Style object for header title. Supported properties: - * - fontFamily - * - fontSize - * - color + * Boolean to set native property to prefer large title header (like in iOS setting). + * For large title to collapse on scroll, the content of the screen should be wrapped in a scrollable view such as `ScrollView` or `FlatList`. + * If the scrollable area doesn't fill the screen, the large title won't collapse on scroll. + * Only supported on iOS. + * + * @platform ios */ - headerTitleStyle?: { - fontFamily?: string; - fontSize?: number; - color?: string; - }; + headerLargeTitle?: boolean; + /** + * Boolean that allows for disabling drop shadow under navigation header when the edge of any scrollable content reaches the matching edge of the navigation bar. + */ + headerLargeTitleHideShadow?: boolean; /** * Style object for header large title. Supported properties: * - fontFamily @@ -201,17 +177,44 @@ export type NativeStackNavigationOptions = { color?: string; }; /** - * Style object for header back title. Supported properties: + * Function which returns a React Element to display on the left side of the header. + */ + headerLeft?: (props: { tintColor?: string }) => React.ReactNode; + /** + * Function which returns a React Element to display on the right side of the header. + */ + headerRight?: (props: { tintColor?: string }) => React.ReactNode; + /** + * Whether to show the header. + */ + headerShown?: boolean; + /** + * Style object for header title. Supported properties: + * - backgroundColor + * - blurEffect + */ + headerStyle?: { + backgroundColor?: string; + blurEffect?: ScreenStackHeaderConfigProps['blurEffect']; + }; + /** + * Tint color for the header. Changes the color of back button and title. + */ + headerTintColor?: string; + /** + * String to display in the header as title. Defaults to scene `title`. + */ + headerTitle?: string; + /** + * Style object for header title. Supported properties: * - fontFamily * - fontSize - * - * Only supported on iOS. - * - * @platform ios + * - color */ - headerBackTitleStyle?: { + headerTitleStyle?: { fontFamily?: string; fontSize?: number; + color?: string; }; /** * A flag to that lets you opt out of insetting the header. You may want to @@ -223,16 +226,9 @@ export type NativeStackNavigationOptions = { */ headerTopInsetEnabled?: boolean; /** - * Style object for the scene content. - */ - contentStyle?: StyleProp; - /** - * Whether you can use gestures to dismiss this screen. Defaults to `true`. - * Only supported on iOS. - * - * @platform ios + * Boolean indicating whether the navigation bar is translucent. */ - gestureEnabled?: boolean; + headerTranslucent?: boolean; /** * How should the screen replacing another screen animate. Defaults to `pop`. * The following values are currently supported: @@ -240,6 +236,15 @@ export type NativeStackNavigationOptions = { * - "pop" – the new screen will perform pop animation. */ replaceAnimation?: ScreenProps['replaceAnimation']; + /** + * How the screen should appear/disappear when pushed or popped at the top of the stack. + * The following values are currently supported: + * - "default" – uses a platform default animation + * - "fade" – fades screen in or out + * - "flip" – flips the screen, requires stackPresentation: "modal" (iOS only) + * - "none" – the screen appears/dissapears without an animation + */ + stackAnimation?: ScreenProps['stackAnimation']; /** * How should the screen be presented. * The following values are currently supported: @@ -253,14 +258,9 @@ export type NativeStackNavigationOptions = { */ stackPresentation?: ScreenProps['stackPresentation']; /** - * How the screen should appear/disappear when pushed or popped at the top of the stack. - * The following values are currently supported: - * - "default" – uses a platform default animation - * - "fade" – fades screen in or out - * - "flip" – flips the screen, requires stackPresentation: "modal" (iOS only) - * - "none" – the screen appears/dissapears without an animation + * String that can be displayed in the header as a fallback for `headerTitle`. */ - stackAnimation?: ScreenProps['stackAnimation']; + title?: string; }; export type NativeStackNavigatorProps = DefaultNavigatorOptions< diff --git a/src/native-stack/views/HeaderConfig.tsx b/src/native-stack/views/HeaderConfig.tsx index e4a7bca094..f88e16e879 100644 --- a/src/native-stack/views/HeaderConfig.tsx +++ b/src/native-stack/views/HeaderConfig.tsx @@ -15,30 +15,30 @@ type Props = NativeStackNavigationOptions & { }; export default function HeaderConfig({ - route, - title, - headerRight, - headerLeft, - headerCenter, - headerTitle, + backButtonImage, + backButtonInCustomView, + direction, headerBackTitle, + headerBackTitleStyle = {}, headerBackTitleVisible = true, - backButtonImage, + headerCenter, headerHideBackButton, headerHideShadow, + headerLargeStyle = {}, + headerLargeTitle, headerLargeTitleHideShadow, + headerLargeTitleStyle = {}, + headerLeft, + headerRight, + headerShown, + headerStyle = {}, headerTintColor, + headerTitle, + headerTitleStyle = {}, headerTopInsetEnabled = true, - headerLargeTitle, headerTranslucent, - headerStyle = {}, - headerLargeStyle = {}, - headerTitleStyle = {}, - headerLargeTitleStyle = {}, - headerBackTitleStyle = {}, - headerShown, - backButtonInCustomView, - direction, + route, + title, }: Props): JSX.Element { const { colors } = useTheme(); const tintColor = headerTintColor ?? colors.primary;