@react-navigation/native-stack 7.3.28 → 7.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.tsx CHANGED
@@ -12,6 +12,7 @@ import type {
12
12
  Theme,
13
13
  } from '@react-navigation/native';
14
14
  import type {
15
+ ColorValue,
15
16
  ImageSourcePropType,
16
17
  StyleProp,
17
18
  TextStyle,
@@ -20,8 +21,10 @@ import type {
20
21
  import type {
21
22
  ScreenProps,
22
23
  ScreenStackHeaderConfigProps,
24
+ ScrollEdgeEffect,
23
25
  SearchBarProps,
24
26
  } from 'react-native-screens';
27
+ import type { SFSymbol } from 'sf-symbols-typescript';
25
28
 
26
29
  export type NativeStackNavigationEventMap = {
27
30
  /**
@@ -114,7 +117,7 @@ export type NativeStackHeaderProps = {
114
117
  navigation: NativeStackNavigationProp<ParamListBase>;
115
118
  };
116
119
 
117
- export type NativeStackHeaderRightProps = {
120
+ export type NativeStackHeaderItemProps = {
118
121
  /**
119
122
  * Tint color for the header.
120
123
  */
@@ -125,10 +128,10 @@ export type NativeStackHeaderRightProps = {
125
128
  canGoBack?: boolean;
126
129
  };
127
130
 
128
- export type NativeStackHeaderLeftProps = NativeStackHeaderRightProps & {
131
+ export type NativeStackHeaderBackProps = NativeStackHeaderItemProps & {
129
132
  /**
130
133
  * Label text for the button. Usually the title of the previous screen.
131
- * By default, this is only shown on iOS.
134
+ * By default, this is only shown on iOS 18.
132
135
  */
133
136
  label?: string;
134
137
  /**
@@ -137,6 +140,16 @@ export type NativeStackHeaderLeftProps = NativeStackHeaderRightProps & {
137
140
  href?: string;
138
141
  };
139
142
 
143
+ /**
144
+ * @deprecated Use `NativeStackHeaderBackProps` instead.
145
+ */
146
+ export type NativeStackHeaderLeftProps = NativeStackHeaderBackProps;
147
+
148
+ /**
149
+ * @deprecated Use `NativeStackHeaderItemProps` instead.
150
+ */
151
+ export type NativeStackHeaderRightProps = NativeStackHeaderItemProps;
152
+
140
153
  export type NativeStackNavigationOptions = {
141
154
  /**
142
155
  * String that can be displayed in the header as a fallback for `headerTitle`.
@@ -281,12 +294,36 @@ export type NativeStackNavigationOptions = {
281
294
  /**
282
295
  * Function which returns a React Element to display on the left side of the header.
283
296
  * This replaces the back button. See `headerBackVisible` to show the back button along side left element.
297
+ * Will be overriden by `headerLeftItems` on iOS.
284
298
  */
285
- headerLeft?: (props: NativeStackHeaderLeftProps) => React.ReactNode;
299
+ headerLeft?: (props: NativeStackHeaderBackProps) => React.ReactNode;
286
300
  /**
287
301
  * Function which returns a React Element to display on the right side of the header.
302
+ * Will be overriden by `headerRightItems` on iOS.
303
+ */
304
+ headerRight?: (props: NativeStackHeaderItemProps) => React.ReactNode;
305
+ /**
306
+ * Function which returns an array of items to display as on the left side of the header.
307
+ * Overrides `headerLeft`.
308
+ *
309
+ * This is an unstable API and might change in the future.
310
+ *
311
+ * @platform ios
312
+ */
313
+ unstable_headerLeftItems?: (
314
+ props: NativeStackHeaderItemProps
315
+ ) => NativeStackHeaderItem[];
316
+ /**
317
+ * Function which returns an array of items to display as on the right side of the header.
318
+ * Overrides `headerRight`.
319
+ *
320
+ * This is an unstable API and might change in the future.
321
+ *
322
+ * @platform ios
288
323
  */
289
- headerRight?: (props: NativeStackHeaderRightProps) => React.ReactNode;
324
+ unstable_headerRightItems?: (
325
+ props: NativeStackHeaderItemProps
326
+ ) => NativeStackHeaderItem[];
290
327
  /**
291
328
  * String or a function that returns a React Element to be used by the header.
292
329
  * Defaults to screen `title` or route name.
@@ -668,6 +705,24 @@ export type NativeStackNavigationOptions = {
668
705
  * Only supported on iOS and Android.
669
706
  */
670
707
  freezeOnBlur?: boolean;
708
+ /**
709
+ * Configures the scroll edge effect for the _content ScrollView_ (the ScrollView that is present in first descendants chain of the Screen).
710
+ * Depending on values set, it will blur the scrolling content below certain UI elements (Header Items, SearchBar)
711
+ * for the specifed edge of the ScrollView.
712
+ *
713
+ * When set in nested containers, i.e. ScreenStack inside BottomTabs, or the other way around,
714
+ * the ScrollView will use only the innermost one's config.
715
+ *
716
+ * @platform ios
717
+ *
718
+ * @supported iOS 26 or higher
719
+ */
720
+ scrollEdgeEffects?: {
721
+ bottom?: ScrollEdgeEffect;
722
+ left?: ScrollEdgeEffect;
723
+ right?: ScrollEdgeEffect;
724
+ top?: ScrollEdgeEffect;
725
+ };
671
726
  /**
672
727
  * Footer component that can be used alongside formSheet stack presentation style.
673
728
  *
@@ -683,6 +738,289 @@ export type NativeStackNavigationOptions = {
683
738
  unstable_sheetFooter?: () => React.ReactNode;
684
739
  };
685
740
 
741
+ type PlatformIconShared = {
742
+ type: 'image';
743
+ source: ImageSourcePropType;
744
+ /**
745
+ * Whether to apply tint color to the icon.
746
+ * Defaults to `true`.
747
+ *
748
+ * @platform ios
749
+ */
750
+ tinted?: boolean;
751
+ };
752
+
753
+ type PlatformIconIOSSfSymbol = {
754
+ type: 'sfSymbol';
755
+ name: SFSymbol;
756
+ };
757
+
758
+ type PlatformIconIOS = PlatformIconIOSSfSymbol | PlatformIconShared;
759
+
760
+ type SharedHeaderItem = {
761
+ /**
762
+ * Label of the item.
763
+ */
764
+ label: string;
765
+ /**
766
+ * Style for the item label.
767
+ */
768
+ labelStyle?: {
769
+ fontFamily?: string;
770
+ fontSize?: number;
771
+ fontWeight?: string;
772
+ color?: ColorValue;
773
+ };
774
+ /**
775
+ * Icon for the item
776
+ */
777
+ icon?: PlatformIconIOS;
778
+ /**
779
+ * The variant of the item.
780
+ * "prominent" only available from iOS 26.0 and later.
781
+ *
782
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/style-swift.property
783
+ */
784
+ variant?: 'plain' | 'done' | 'prominent';
785
+ /**
786
+ * The tint color to apply to the item.
787
+ *
788
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/tintcolor
789
+ */
790
+ tintColor?: ColorValue;
791
+ /**
792
+ * Whether the item is in a disabled state.
793
+ */
794
+ disabled?: boolean;
795
+ /**
796
+ * The width of the item.
797
+ *
798
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/width
799
+ */
800
+ width?: number;
801
+ /**
802
+ * Whether the background this item may share with other items in the bar should be hidden.
803
+ * Only available from iOS 26.0 and later.
804
+ *
805
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground
806
+ */
807
+ hidesSharedBackground?: boolean;
808
+ /**
809
+ * Whether this item can share a background with other items.
810
+ * Only available from iOS 26.0 and later.
811
+ *
812
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/sharesbackground
813
+ */
814
+ sharesBackground?: boolean;
815
+ /**
816
+ * An identifier used to match items across transitions.
817
+ * Only available from iOS 26.0 and later.
818
+ *
819
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/identifier
820
+ */
821
+ identifier?: string;
822
+ /**
823
+ * A badge to display on a item.
824
+ * Only available from iOS 26.0 and later.
825
+ *
826
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitembadge
827
+ */
828
+ badge?: {
829
+ /**
830
+ * The text to display in the badge.
831
+ */
832
+ value: number | string;
833
+ /**
834
+ * Style of the badge.
835
+ */
836
+ style?: {
837
+ color?: ColorValue;
838
+ backgroundColor?: ColorValue;
839
+ fontFamily?: string;
840
+ fontSize?: number;
841
+ fontWeight?: string;
842
+ };
843
+ };
844
+ /**
845
+ * Accessibility label for the item.
846
+ */
847
+ accessibilityLabel?: string;
848
+ /**
849
+ * Accessibility hint for the item.
850
+ */
851
+ accessibilityHint?: string;
852
+ };
853
+
854
+ /**
855
+ * A button item in the header.
856
+ */
857
+ export type NativeStackHeaderItemButton = SharedHeaderItem & {
858
+ /**
859
+ * Type of the item.
860
+ */
861
+ type: 'button';
862
+ /**
863
+ * Function to call when the item is pressed.
864
+ */
865
+ onPress: () => void;
866
+ /**
867
+ * Whether the item is in a selected state.
868
+ *
869
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/isselected
870
+ */
871
+ selected?: boolean;
872
+ };
873
+
874
+ /**
875
+ * An action item in a menu.
876
+ */
877
+ export type NativeStackHeaderItemMenuAction = {
878
+ type: 'action';
879
+ /**
880
+ * Label for the menu item.
881
+ */
882
+ label: string;
883
+ /**
884
+ * Icon for the menu item.
885
+ */
886
+ icon?: PlatformIconIOSSfSymbol;
887
+ /**
888
+ * Function to call when the menu item is pressed.
889
+ */
890
+ onPress: () => void;
891
+ /**
892
+ * The state of an action- or command-based menu item.
893
+ *
894
+ * Read more: https://developer.apple.com/documentation/uikit/uimenuelement/state
895
+ */
896
+ state?: 'on' | 'off' | 'mixed';
897
+ /**
898
+ * Whether to apply disabled style to the item.
899
+ *
900
+ * Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/disabled
901
+ */
902
+ disabled?: boolean;
903
+ /**
904
+ * Whether to apply destructive style to the item.
905
+ *
906
+ * Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive
907
+ */
908
+ destructive?: boolean;
909
+ /**
910
+ * Whether to apply hidden style to the item.
911
+ *
912
+ * Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/hidden
913
+ */
914
+ hidden?: boolean;
915
+ /**
916
+ * Whether to keep the menu presented after firing the element’s action.
917
+ *
918
+ * Read more: https://developer.apple.com/documentation/uikit/uimenuelement/attributes/keepsmenupresented
919
+ */
920
+ keepsMenuPresented?: boolean;
921
+ /**
922
+ * An elaborated title that explains the purpose of the action.
923
+ *
924
+ * On iOS, the system displays this title in the discoverability heads-up display (HUD).
925
+ * If this is not set, the HUD displays the title property.
926
+ *
927
+ * Read more: https://developer.apple.com/documentation/uikit/uiaction/discoverabilitytitle
928
+ */
929
+ discoverabilityLabel?: string;
930
+ };
931
+
932
+ /**
933
+ * A submenu item that contains other menu items.
934
+ */
935
+ export type NativeStackHeaderItemMenuSubmenu = {
936
+ type: 'submenu';
937
+ /**
938
+ * Label for the submenu item.
939
+ */
940
+ label: string;
941
+ /**
942
+ * Icon for the submenu item.
943
+ */
944
+ icon?: PlatformIconIOSSfSymbol;
945
+ /**
946
+ * Array of menu items (actions or submenus).
947
+ */
948
+ items: NativeStackHeaderItemMenu['menu']['items'];
949
+ };
950
+
951
+ /**
952
+ * An item that shows a menu when pressed.
953
+ */
954
+ export type NativeStackHeaderItemMenu = SharedHeaderItem & {
955
+ type: 'menu';
956
+ /**
957
+ * Whether the menu is a selection menu.
958
+ * Tapping an item in a selection menu will add a checkmark to the selected item.
959
+ *
960
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/changesselectionasprimaryaction
961
+ */
962
+ changesSelectionAsPrimaryAction?: boolean;
963
+ /**
964
+ * Menu for the item.
965
+ */
966
+ menu: {
967
+ /**
968
+ * Optional title to show on top of the menu.
969
+ */
970
+ title?: string;
971
+ /**
972
+ * Array of menu items (actions or submenus).
973
+ */
974
+ items: (
975
+ | NativeStackHeaderItemMenuAction
976
+ | NativeStackHeaderItemMenuSubmenu
977
+ )[];
978
+ };
979
+ };
980
+
981
+ /**
982
+ * An item to add spacing between other items in the header.
983
+ */
984
+ export type NativeStackHeaderItemSpacing = {
985
+ type: 'spacing';
986
+ /**
987
+ * The amount of spacing to add.
988
+ */
989
+ spacing: number;
990
+ };
991
+
992
+ /**
993
+ * A custom item to display any React Element in the header.
994
+ */
995
+ export type NativeStackHeaderItemCustom = {
996
+ type: 'custom';
997
+ /**
998
+ * A React Element to display as the item.
999
+ */
1000
+ element: React.ReactElement;
1001
+ /**
1002
+ * Whether the background this item may share with other items in the bar should be hidden.
1003
+ * Only available from iOS 26.0 and later.
1004
+ *
1005
+ * Read more: https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground
1006
+ */
1007
+ hidesSharedBackground?: boolean;
1008
+ };
1009
+
1010
+ /**
1011
+ * An item that can be displayed in the header.
1012
+ * It can be a button, a menu, spacing, or a custom element.
1013
+ *
1014
+ * On iOS 26, when showing items on the right side of the header,
1015
+ * if the items don't fit the available space, they will be collapsed into a menu automatically.
1016
+ * Items with `type: 'custom'` will not be included in this automatic collapsing behavior.
1017
+ */
1018
+ export type NativeStackHeaderItem =
1019
+ | NativeStackHeaderItemButton
1020
+ | NativeStackHeaderItemMenu
1021
+ | NativeStackHeaderItemSpacing
1022
+ | NativeStackHeaderItemCustom;
1023
+
686
1024
  export type NativeStackNavigatorProps = DefaultNavigatorOptions<
687
1025
  ParamListBase,
688
1026
  string | undefined,
@@ -112,7 +112,7 @@ const SceneView = ({
112
112
  headerBackButtonMenuEnabled,
113
113
  headerShown,
114
114
  headerBackground,
115
- headerTransparent = false,
115
+ headerTransparent,
116
116
  autoHideHomeIndicator,
117
117
  keyboardHandlingEnabled,
118
118
  navigationBarColor,
@@ -132,6 +132,7 @@ const SceneView = ({
132
132
  statusBarTranslucent,
133
133
  statusBarBackgroundColor,
134
134
  unstable_sheetFooter,
135
+ scrollEdgeEffects,
135
136
  freezeOnBlur,
136
137
  contentStyle,
137
138
  } = options;
@@ -335,6 +336,12 @@ const SceneView = ({
335
336
  nativeBackButtonDismissalEnabled={false} // on Android
336
337
  onHeaderBackButtonClicked={onHeaderBackButtonClicked}
337
338
  preventNativeDismiss={isRemovePrevented} // on iOS
339
+ scrollEdgeEffects={{
340
+ bottom: scrollEdgeEffects?.bottom ?? 'automatic',
341
+ top: scrollEdgeEffects?.top ?? 'automatic',
342
+ left: scrollEdgeEffects?.left ?? 'automatic',
343
+ right: scrollEdgeEffects?.right ?? 'automatic',
344
+ }}
338
345
  onNativeDismissCancelled={onNativeDismissCancelled}
339
346
  // Unfortunately, because of the bug that exists on Fabric, where native event drivers
340
347
  // for Animated objects are being created after the first notifications about the header height
@@ -1,17 +1,32 @@
1
1
  import { getHeaderTitle, HeaderTitle } from '@react-navigation/elements';
2
- import { type Route, useLocale, useTheme } from '@react-navigation/native';
2
+ import {
3
+ type Route,
4
+ type Theme,
5
+ useLocale,
6
+ useTheme,
7
+ } from '@react-navigation/native';
8
+ import color from 'color';
3
9
  import { Platform, StyleSheet, type TextStyle, View } from 'react-native';
4
10
  import {
11
+ type HeaderBarButtonItem,
12
+ type HeaderBarButtonItemMenuAction,
13
+ type HeaderBarButtonItemSubmenu,
5
14
  isSearchBarAvailableForCurrentPlatform,
6
15
  ScreenStackHeaderBackButtonImage,
7
16
  ScreenStackHeaderCenterView,
17
+ type ScreenStackHeaderConfigProps,
8
18
  ScreenStackHeaderLeftView,
9
19
  ScreenStackHeaderRightView,
10
20
  ScreenStackHeaderSearchBarView,
11
21
  SearchBar,
12
22
  } from 'react-native-screens';
13
23
 
14
- import type { NativeStackNavigationOptions } from '../types';
24
+ import type {
25
+ NativeStackHeaderItem,
26
+ NativeStackHeaderItemMenuAction,
27
+ NativeStackHeaderItemMenuSubmenu,
28
+ NativeStackNavigationOptions,
29
+ } from '../types';
15
30
  import { processFonts } from './FontProcessor';
16
31
 
17
32
  type Props = NativeStackNavigationOptions & {
@@ -21,6 +36,124 @@ type Props = NativeStackNavigationOptions & {
21
36
  route: Route<string>;
22
37
  };
23
38
 
39
+ const processBarButtonItems = (
40
+ items: NativeStackHeaderItem[] | undefined,
41
+ colors: Theme['colors'],
42
+ fonts: Theme['fonts']
43
+ ) => {
44
+ return items
45
+ ?.map((item, index) => {
46
+ if (item.type === 'custom') {
47
+ // Handled with `ScreenStackHeaderLeftView` or `ScreenStackHeaderRightView`
48
+ return null;
49
+ }
50
+
51
+ if (item.type === 'spacing') {
52
+ if (item.spacing == null) {
53
+ throw new Error(
54
+ `Spacing item must have a 'spacing' property defined: ${JSON.stringify(
55
+ item
56
+ )}`
57
+ );
58
+ }
59
+
60
+ return item;
61
+ }
62
+
63
+ if (item.type === 'button' || item.type === 'menu') {
64
+ if (item.type === 'menu' && item.menu == null) {
65
+ throw new Error(
66
+ `Menu item must have a 'menu' property defined: ${JSON.stringify(
67
+ item
68
+ )}`
69
+ );
70
+ }
71
+
72
+ const { badge, label, labelStyle, icon, ...rest } = item;
73
+
74
+ let processedItem: HeaderBarButtonItem = {
75
+ ...rest,
76
+ index,
77
+ title: label,
78
+ titleStyle: {
79
+ ...fonts.regular,
80
+ ...labelStyle,
81
+ },
82
+ icon:
83
+ icon?.type === 'image'
84
+ ? icon.tinted === false
85
+ ? {
86
+ type: 'imageSource',
87
+ imageSource: icon.source,
88
+ }
89
+ : {
90
+ type: 'templateSource',
91
+ templateSource: icon.source,
92
+ }
93
+ : icon,
94
+ };
95
+
96
+ if (processedItem.type === 'menu' && item.type === 'menu') {
97
+ processedItem = {
98
+ ...processedItem,
99
+ menu: {
100
+ ...processedItem.menu,
101
+ items: item.menu.items.map(getMenuItem),
102
+ },
103
+ };
104
+ }
105
+
106
+ if (badge) {
107
+ const badgeBackgroundColor =
108
+ badge.style?.backgroundColor ?? colors.notification;
109
+ const badgeTextColor = color(badgeBackgroundColor).isLight()
110
+ ? 'black'
111
+ : 'white';
112
+
113
+ processedItem = {
114
+ ...processedItem,
115
+ badge: {
116
+ ...badge,
117
+ value: String(badge.value),
118
+ style: {
119
+ backgroundColor: badgeBackgroundColor,
120
+ color: badgeTextColor,
121
+ ...fonts.regular,
122
+ ...badge.style,
123
+ },
124
+ },
125
+ };
126
+ }
127
+
128
+ return processedItem;
129
+ }
130
+
131
+ throw new Error(
132
+ `Invalid item type: ${JSON.stringify(item)}. Valid types are 'button', 'menu', 'custom' and 'spacing'.`
133
+ );
134
+ })
135
+ .filter((item) => item != null);
136
+ };
137
+
138
+ const getMenuItem = (
139
+ item: NativeStackHeaderItemMenuAction | NativeStackHeaderItemMenuSubmenu
140
+ ): HeaderBarButtonItemMenuAction | HeaderBarButtonItemSubmenu => {
141
+ const { label, ...rest } = item;
142
+
143
+ if (rest.type === 'submenu') {
144
+ return {
145
+ ...rest,
146
+ title: label,
147
+ items: rest.items.map(getMenuItem),
148
+ };
149
+ }
150
+
151
+ return {
152
+ ...rest,
153
+ title: label,
154
+ };
155
+ };
156
+
24
157
  export function useHeaderConfigProps({
25
158
  headerBackImageSource,
26
159
  headerBackButtonDisplayMode,
@@ -49,7 +182,9 @@ export function useHeaderConfigProps({
49
182
  headerBack,
50
183
  route,
51
184
  title,
52
- }: Props) {
185
+ unstable_headerLeftItems: headerLeftItems,
186
+ unstable_headerRightItems: headerRightItems,
187
+ }: Props): ScreenStackHeaderConfigProps {
53
188
  const { direction } = useLocale();
54
189
  const { colors, fonts } = useTheme();
55
190
  const tintColor =
@@ -187,11 +322,43 @@ export function useHeaderConfigProps({
187
322
 
188
323
  const isCenterViewRenderedAndroid = headerTitleAlign === 'center';
189
324
 
325
+ const leftItems = headerLeftItems?.({
326
+ tintColor,
327
+ canGoBack,
328
+ });
329
+
330
+ let rightItems = headerRightItems?.({
331
+ tintColor,
332
+ canGoBack,
333
+ });
334
+
335
+ if (rightItems) {
336
+ // iOS renders right items in reverse order
337
+ // So we need to reverse them here to match the order
338
+ rightItems = [...rightItems].reverse();
339
+ }
340
+
190
341
  const children = (
191
342
  <>
192
343
  {Platform.OS === 'ios' ? (
193
344
  <>
194
- {headerLeftElement != null ? (
345
+ {leftItems ? (
346
+ leftItems.map((item, index) => {
347
+ if (item.type === 'custom') {
348
+ return (
349
+ <ScreenStackHeaderLeftView
350
+ // eslint-disable-next-line @eslint-react/no-array-index-key
351
+ key={index}
352
+ hidesSharedBackground={item.hidesSharedBackground}
353
+ >
354
+ {item.element}
355
+ </ScreenStackHeaderLeftView>
356
+ );
357
+ }
358
+
359
+ return null;
360
+ })
361
+ ) : headerLeftElement != null ? (
195
362
  <ScreenStackHeaderLeftView>
196
363
  {headerLeftElement}
197
364
  </ScreenStackHeaderLeftView>
@@ -247,7 +414,23 @@ export function useHeaderConfigProps({
247
414
  {headerBackImageSource !== undefined ? (
248
415
  <ScreenStackHeaderBackButtonImage source={headerBackImageSource} />
249
416
  ) : null}
250
- {headerRightElement != null ? (
417
+ {rightItems ? (
418
+ rightItems.map((item, index) => {
419
+ if (item.type === 'custom') {
420
+ return (
421
+ <ScreenStackHeaderRightView
422
+ // eslint-disable-next-line @eslint-react/no-array-index-key
423
+ key={index}
424
+ hidesSharedBackground={item.hidesSharedBackground}
425
+ >
426
+ {item.element}
427
+ </ScreenStackHeaderRightView>
428
+ );
429
+ }
430
+
431
+ return null;
432
+ })
433
+ ) : headerRightElement != null ? (
251
434
  <ScreenStackHeaderRightView>
252
435
  {headerRightElement}
253
436
  </ScreenStackHeaderRightView>
@@ -297,5 +480,7 @@ export function useHeaderConfigProps({
297
480
  topInsetEnabled: headerTopInsetEnabled,
298
481
  translucent: translucent === true,
299
482
  children,
483
+ headerLeftBarButtonItems: processBarButtonItems(leftItems, colors, fonts),
484
+ headerRightBarButtonItems: processBarButtonItems(rightItems, colors, fonts),
300
485
  } as const;
301
486
  }