authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-08-28 20:05:40-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-28 20:05:40-07:00
log38dcd7a404d24c2fa514cc82c1a5c4fd6a9d4a7a
tree83c653561ae9b8c04e617ad5a88c27867f1e5b07
parent3e6ab36f6ed303f95f210971f56cc8642214c6fc
signature Signed by PGP key B5690EEEBB952194

fix(mobile): harden native header toolbar items (#8611)

Co-authored-by: Julius Marminge <julius@mac.lan>

2 files changed, 271 insertions(+), 82 deletions(-)

patches/react-native-screens@4.26.2.patch+265-76
...@@ -159,7 +159,7 @@ index 8a41697223f6c4b5cb2dd6d450fc58cbb3b27536..309ba2f762068dcf452c172f7c7cbf2a...@@ -159,7 +159,7 @@ index 8a41697223f6c4b5cb2dd6d450fc58cbb3b27536..309ba2f762068dcf452c172f7c7cbf2a
159 159
160 NS_ASSUME_NONNULL_END160 NS_ASSUME_NONNULL_END
161diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm161diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm
162index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338eff90c694 100644162index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..a60b96b44e85d3f4b29dc0d190b95ab60e185033 100644
163--- a/ios/RNSScreenStackHeaderConfig.mm163--- a/ios/RNSScreenStackHeaderConfig.mm
164+++ b/ios/RNSScreenStackHeaderConfig.mm164+++ b/ios/RNSScreenStackHeaderConfig.mm
165@@ -24,11 +24,46 @@165@@ -24,11 +24,46 @@
...@@ -294,7 +294,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -294,7 +294,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
294 break;294 break;
295 }295 }
296 case RNSScreenStackHeaderSubviewTypeCenter:296 case RNSScreenStackHeaderSubviewTypeCenter:
297@@ -648,10 +693,453 @@ + (void)updateViewController:(UIViewController *)vc297@@ -648,10 +693,470 @@ + (void)updateViewController:(UIViewController *)vc
298 // This assignment should be done after `navitem.titleView = ...` assignment (iOS 16.0 bug).298 // This assignment should be done after `navitem.titleView = ...` assignment (iOS 16.0 bug).
299 // See: https://github.com/software-mansion/react-native-screens/issues/1570 (comments)299 // See: https://github.com/software-mansion/react-native-screens/issues/1570 (comments)
300 navitem.title = config.title;300 navitem.title = config.title;
...@@ -323,21 +323,24 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -323,21 +323,24 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
323+ navitem, &RNSAppliedLeadingHeaderItemsKey, @[ config, headerLeftConfigs, subviewLeftItems ])) {323+ navitem, &RNSAppliedLeadingHeaderItemsKey, @[ config, headerLeftConfigs, subviewLeftItems ])) {
324+ NSArray *items = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems324+ NSArray *items = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems
325+ withCurrentItems:subviewLeftItems325+ withCurrentItems:subviewLeftItems
326+ navigationItem:navitem];326+ navigationItem:navitem
327+ allowsSearchBarPlacement:NO];
327+ navitem.leadingItemGroups = [config barButtonItemGroupsFromItems:items];328+ navitem.leadingItemGroups = [config barButtonItemGroupsFromItems:items];
328+ }329+ }
329+ if (RNSUpdateHeaderItemsCache(330+ if (RNSUpdateHeaderItemsCache(
330+ navitem, &RNSAppliedTrailingHeaderItemsKey, @[ config, headerRightConfigs, subviewRightItems ])) {331+ navitem, &RNSAppliedTrailingHeaderItemsKey, @[ config, headerRightConfigs, subviewRightItems ])) {
331+ NSArray *items = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems332+ NSArray *items = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems
332+ withCurrentItems:subviewRightItems333+ withCurrentItems:subviewRightItems
333+ navigationItem:navitem];334+ navigationItem:navitem
335+ allowsSearchBarPlacement:NO];
334+ navitem.trailingItemGroups = [config barButtonItemGroupsFromItems:items];336+ navitem.trailingItemGroups = [config barButtonItemGroupsFromItems:items];
335+ }337+ }
336+ if (@available(iOS 26.0, *)) {338+ if (@available(iOS 26.0, *)) {
337+ if (RNSUpdateHeaderItemsCache(navitem, &RNSAppliedCenterHeaderItemsKey, @[ config, headerCenterConfigs ])) {339+ if (RNSUpdateHeaderItemsCache(navitem, &RNSAppliedCenterHeaderItemsKey, @[ config, headerCenterConfigs ])) {
338+ NSArray *items = [config barButtonItemsFromConfigs:config.headerCenterBarButtonItems340+ NSArray *items = [config barButtonItemsFromConfigs:config.headerCenterBarButtonItems
339+ withCurrentItems:@[]341+ withCurrentItems:@[]
340+ navigationItem:navitem];342+ navigationItem:navitem
343+ allowsSearchBarPlacement:NO];
341+ navitem.centerItemGroups = [config barButtonItemGroupsFromItems:items];344+ navitem.centerItemGroups = [config barButtonItemGroupsFromItems:items];
342+ }345+ }
343+ }346+ }
...@@ -346,20 +349,27 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -346,20 +349,27 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
346+ {349+ {
347+ NSArray<UIBarButtonItem *> *leftBarButtonItems = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems350+ NSArray<UIBarButtonItem *> *leftBarButtonItems = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems
348+ withCurrentItems:subviewLeftItems351+ withCurrentItems:subviewLeftItems
349+ navigationItem:navitem];352+ navigationItem:navitem
353+ allowsSearchBarPlacement:NO];
350+ NSArray<UIBarButtonItem *> *rightBarButtonItems = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems354+ NSArray<UIBarButtonItem *> *rightBarButtonItems = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems
351+ withCurrentItems:subviewRightItems355+ withCurrentItems:subviewRightItems
352+ navigationItem:navitem];356+ navigationItem:navitem
357+ allowsSearchBarPlacement:NO];
353+ navitem.leftBarButtonItems = leftBarButtonItems;358+ navitem.leftBarButtonItems = leftBarButtonItems;
354+ navitem.rightBarButtonItems = rightBarButtonItems;359+ navitem.rightBarButtonItems = rightBarButtonItems;
355+ }360+ }
356+ NSDictionary<NSString *, id> *mailSearchToolbarConfig = nil;361+ NSDictionary<NSString *, id> *mailSearchToolbarConfig = nil;
362+ NSMutableArray<NSDictionary<NSString *, id> *> *nonMailSearchToolbarConfigs = [NSMutableArray array];
357+ for (NSDictionary<NSString *, id> *toolbarConfig in config.headerToolbarItems) {363+ for (NSDictionary<NSString *, id> *toolbarConfig in config.headerToolbarItems) {
358+ if (toolbarConfig[@"mailSearchToolbar"]) {364+ if (toolbarConfig[@"mailSearchToolbar"]) {
359+ mailSearchToolbarConfig = toolbarConfig;365+ if (mailSearchToolbarConfig == nil) {
360+ break;366+ mailSearchToolbarConfig = toolbarConfig;
367+ }
368+ } else {
369+ [nonMailSearchToolbarConfigs addObject:toolbarConfig];
361+ }370+ }
362+ }371+ }
372+ NSArray<NSDictionary<NSString *, id> *> *navigationToolbarConfigs = [nonMailSearchToolbarConfigs copy];
363+ if (mailSearchToolbarConfig == nil) {373+ if (mailSearchToolbarConfig == nil) {
364+ for (NSDictionary<NSString *, id> *rightConfig in config.headerRightBarButtonItems) {374+ for (NSDictionary<NSString *, id> *rightConfig in config.headerRightBarButtonItems) {
365+ if ([rightConfig[@"bottomMailSearchToolbar"] boolValue]) {375+ if ([rightConfig[@"bottomMailSearchToolbar"] boolValue]) {
...@@ -560,14 +570,6 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -560,14 +570,6 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
560+ searchField.attributedPlaceholder =570+ searchField.attributedPlaceholder =
561+ [[NSAttributedString alloc] initWithString:placeholder attributes:placeholderAttributes];571+ [[NSAttributedString alloc] initWithString:placeholder attributes:placeholderAttributes];
562+ }572+ }
563+ NSString *searchTextChangeId = mailSearchToolbarConfig[@"searchTextChangeId"];
564+ if (searchTextChangeId != nil) {
565+ [searchField addAction:[UIAction actionWithHandler:^(__kindof UIAction *_Nonnull action) {
566+ UISearchTextField *field = (UISearchTextField *)action.sender;
567+ emitButtonPress([NSString stringWithFormat:@"%@:%@", searchTextChangeId, field.text ?: @""]);
568+ }]
569+ forControlEvents:UIControlEventEditingChanged];
570+ }
571+ searchField.borderStyle = UITextBorderStyleNone;573+ searchField.borderStyle = UITextBorderStyleNone;
572+ searchField.font = searchFont;574+ searchField.font = searchFont;
573+ searchField.adjustsFontForContentSizeCategory = YES;575+ searchField.adjustsFontForContentSizeCategory = YES;
...@@ -584,6 +586,25 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -584,6 +586,25 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
584+ ]];586+ ]];
585+ }587+ }
586+588+
589+ NSString *searchTextChangeId = mailSearchToolbarConfig[@"searchTextChangeId"];
590+ NSString *searchTextChangeActionIdentifier = @"org.react-native-screens.mail-search-toolbar.text-change";
591+ if (resolvedSearchTextField != nil) {
592+ [resolvedSearchTextField removeActionForIdentifier:searchTextChangeActionIdentifier
593+ forControlEvents:UIControlEventEditingChanged];
594+ }
595+ if (searchTextChangeId != nil && resolvedSearchTextField != nil) {
596+ [resolvedSearchTextField
597+ addAction:[UIAction actionWithTitle:@""
598+ image:nil
599+ identifier:searchTextChangeActionIdentifier
600+ handler:^(__kindof UIAction *_Nonnull action) {
601+ UITextField *field = (UITextField *)action.sender;
602+ emitButtonPress(
603+ [NSString stringWithFormat:@"%@:%@", searchTextChangeId, field.text ?: @""]);
604+ }]
605+ forControlEvents:UIControlEventEditingChanged];
606+ }
607+
587+ UIButton *filterButton = nil;608+ UIButton *filterButton = nil;
588+ if (hasFilterButton) {609+ if (hasFilterButton) {
589+ filterButton = makeGlassButton(610+ filterButton = makeGlassButton(
...@@ -720,11 +741,6 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -720,11 +741,6 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
720+#endif741+#endif
721+ }742+ }
722+743+
723+ NSArray<NSDictionary<NSString *, id> *> *navigationToolbarConfigs = config.headerToolbarItems;
724+ if (mailSearchToolbarConfig != nil) {
725+ navigationToolbarConfigs = @[];
726+ }
727+
728+ NSArray *toolbarConfigsKey = navigationToolbarConfigs ?: @[];744+ NSArray *toolbarConfigsKey = navigationToolbarConfigs ?: @[];
729+ // Same reuse rule as the header item groups above (including the config745+ // Same reuse rule as the header item groups above (including the config
730+ // identity — cached toolbar items capture this config's event emitter).746+ // identity — cached toolbar items capture this config's event emitter).
...@@ -738,7 +754,8 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -738,7 +754,8 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
738+ if (!reuseToolbarItems) {754+ if (!reuseToolbarItems) {
739+ NSArray<UIBarButtonItem *> *toolbarItems = [config barButtonItemsFromConfigs:navigationToolbarConfigs755+ NSArray<UIBarButtonItem *> *toolbarItems = [config barButtonItemsFromConfigs:navigationToolbarConfigs
740+ withCurrentItems:@[]756+ withCurrentItems:@[]
741+ navigationItem:navitem];757+ navigationItem:navitem
758+ allowsSearchBarPlacement:YES];
742+ if (toolbarItems.count > 0) {759+ if (toolbarItems.count > 0) {
743+ vc.toolbarItems = toolbarItems;760+ vc.toolbarItems = toolbarItems;
744+ [navctr setToolbarHidden:NO animated:animated];761+ [navctr setToolbarHidden:NO animated:animated];
...@@ -752,15 +769,16 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -752,15 +769,16 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
752 769
753 // Setting navigation bar visibility is split to mitigate iOS 26 bug with bar button items770 // Setting navigation bar visibility is split to mitigate iOS 26 bug with bar button items
754 // (setting nav bar visibility should be done after `navitem.*BarButtonItems`).771 // (setting nav bar visibility should be done after `navitem.*BarButtonItems`).
755@@ -784,6 +1272,7 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *772@@ -784,6 +1289,8 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *
756 773
757 - (NSArray<UIBarButtonItem *> *)barButtonItemsFromConfigs:(NSArray<NSDictionary<NSString *, id> *> *)dicts774 - (NSArray<UIBarButtonItem *> *)barButtonItemsFromConfigs:(NSArray<NSDictionary<NSString *, id> *> *)dicts
758 withCurrentItems:(NSArray<UIBarButtonItem *> *)currentItems775 withCurrentItems:(NSArray<UIBarButtonItem *> *)currentItems
759+ navigationItem:(UINavigationItem *)navitem776+ navigationItem:(UINavigationItem *)navitem
777+ allowsSearchBarPlacement:(BOOL)allowsSearchBarPlacement
760 {778 {
761 if (dicts.count == 0) {779 if (dicts.count == 0) {
762 return currentItems;780 return currentItems;
763@@ -792,7 +1281,197 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *781@@ -792,7 +1299,200 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *
764 [items addObjectsFromArray:currentItems];782 [items addObjectsFromArray:currentItems];
765 for (NSUInteger i = 0; i < dicts.count; i++) {783 for (NSUInteger i = 0; i < dicts.count; i++) {
766 NSDictionary *dict = dicts[i];784 NSDictionary *dict = dicts[i];
...@@ -896,6 +914,9 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -896,6 +914,9 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
896+ }914+ }
897+#endif915+#endif
898+ } else if (dict[@"searchBarPlacement"]) {916+ } else if (dict[@"searchBarPlacement"]) {
917+ if (!allowsSearchBarPlacement) {
918+ continue;
919+ }
899+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)920+#if RNS_IPHONE_OS_VERSION_AVAILABLE(26_0)
900+ if (@available(iOS 26.0, *)) {921+ if (@available(iOS 26.0, *)) {
901+ NSNumber *width = dict[@"width"];922+ NSNumber *width = dict[@"width"];
...@@ -959,7 +980,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -959,7 +980,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
959 RNSBarButtonItem *item = [[RNSBarButtonItem alloc] initWithConfig:dict980 RNSBarButtonItem *item = [[RNSBarButtonItem alloc] initWithConfig:dict
960 action:^(NSString *buttonId) {981 action:^(NSString *buttonId) {
961 auto eventEmitter = std::static_pointer_cast<const facebook::react::RNSScreenStackHeaderConfigEventEmitter>(982 auto eventEmitter = std::static_pointer_cast<const facebook::react::RNSScreenStackHeaderConfigEventEmitter>(
962@@ -814,19 +1493,23 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *983@@ -814,19 +1514,23 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *
963 }984 }
964 imageLoader:_imageLoader];985 imageLoader:_imageLoader];
965 NSNumber *index = dict[@"index"];986 NSNumber *index = dict[@"index"];
...@@ -989,7 +1010,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -989,7 +1010,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
989 [items insertObject:item atIndex:index.integerValue];1010 [items insertObject:item atIndex:index.integerValue];
990 } else {1011 } else {
991 [items addObject:item];1012 [items addObject:item];
992@@ -836,6 +1519,47 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *1013@@ -836,6 +1540,47 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *
993 return items;1014 return items;
994 }1015 }
995 1016
...@@ -1037,7 +1058,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -1037,7 +1058,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
1037 RNS_IGNORE_SUPER_CALL_BEGIN1058 RNS_IGNORE_SUPER_CALL_BEGIN
1038 - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex1059 - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex
1039 {1060 {
1040@@ -1023,6 +1747,8 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::1061@@ -1023,6 +1768,8 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
1041 }1062 }
1042 1063
1043 _title = RCTNSStringFromStringNilIfEmpty(newScreenProps.title);1064 _title = RCTNSStringFromStringNilIfEmpty(newScreenProps.title);
...@@ -1046,7 +1067,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -1046,7 +1067,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
1046 if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) {1067 if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) {
1047 _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily);1068 _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily);
1048 }1069 }
1049@@ -1048,6 +1774,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::1070@@ -1048,6 +1795,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
1050 _disableBackButtonMenu = newScreenProps.disableBackButtonMenu;1071 _disableBackButtonMenu = newScreenProps.disableBackButtonMenu;
1051 _backButtonDisplayMode =1072 _backButtonDisplayMode =
1052 [RNSConvert UINavigationItemBackButtonDisplayModeFromCppEquivalent:newScreenProps.backButtonDisplayMode];1073 [RNSConvert UINavigationItemBackButtonDisplayModeFromCppEquivalent:newScreenProps.backButtonDisplayMode];
...@@ -1054,7 +1075,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e...@@ -1054,7 +1075,7 @@ index 1c844846a5c66e31cfa530ca462774d2fb6bbea1..d36bda28552e5ac75088e18d0fde338e
1054 1075
1055 if (newScreenProps.userInterfaceStyle != oldScreenProps.userInterfaceStyle) {1076 if (newScreenProps.userInterfaceStyle != oldScreenProps.userInterfaceStyle) {
1056 _userInterfaceStyle = [RNSConvert UIUserInterfaceStyleFromCppEquivalent:newScreenProps.userInterfaceStyle];1077 _userInterfaceStyle = [RNSConvert UIUserInterfaceStyleFromCppEquivalent:newScreenProps.userInterfaceStyle];
1057@@ -1094,6 +1821,30 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::1078@@ -1094,6 +1842,30 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
1058 _headerRightBarButtonItems = array;1079 _headerRightBarButtonItems = array;
1059 }1080 }
1060 1081
...@@ -1145,10 +1166,10 @@ index add33c4807e038dcd846f6c72b2fc472ded02809..9a7c7a8a775579c85de39f921e7a3622...@@ -1145,10 +1166,10 @@ index add33c4807e038dcd846f6c72b2fc472ded02809..9a7c7a8a775579c85de39f921e7a3622
1145 1166
1146 // Needed because of this: https://github.com/facebook/react-native/pull/372741167 // Needed because of this: https://github.com/facebook/react-native/pull/37274
1147diff --git a/lib/commonjs/components/ScreenStackHeaderConfig.js b/lib/commonjs/components/ScreenStackHeaderConfig.js1168diff --git a/lib/commonjs/components/ScreenStackHeaderConfig.js b/lib/commonjs/components/ScreenStackHeaderConfig.js
1148index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32ba1aca64 1006441169index 8c509f2657105cfd86448347c1a01fb73651ff9e..5e3b5185c0ea33c6b98f5daed69239d2c0d0ce90 100644
1149--- a/lib/commonjs/components/ScreenStackHeaderConfig.js1170--- a/lib/commonjs/components/ScreenStackHeaderConfig.js
1150+++ b/lib/commonjs/components/ScreenStackHeaderConfig.js1171+++ b/lib/commonjs/components/ScreenStackHeaderConfig.js
1151@@ -26,18 +26,42 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_1172@@ -26,17 +26,42 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_
1152 } = (0, _EdgeInsetApplicationContext.useEdgeInsetApplication)(!props.hidden, props.disableTopInsetApplication ?? false, props.disableLeftInsetApplication ?? false, props.disableRightInsetApplication ?? false, props.disableBottomInsetApplication ?? false);1173 } = (0, _EdgeInsetApplicationContext.useEdgeInsetApplication)(!props.hidden, props.disableTopInsetApplication ?? false, props.disableLeftInsetApplication ?? false, props.disableRightInsetApplication ?? false, props.disableBottomInsetApplication ?? false);
1153 const {1174 const {
1154 headerLeftBarButtonItems,1175 headerLeftBarButtonItems,
...@@ -1160,8 +1181,8 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32...@@ -1160,8 +1181,8 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32
1160 const preparedHeaderLeftBarButtonItems = headerLeftBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerLeftBarButtonItems, 'left') : undefined;1181 const preparedHeaderLeftBarButtonItems = headerLeftBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerLeftBarButtonItems, 'left') : undefined;
1161 const preparedHeaderRightBarButtonItems = headerRightBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerRightBarButtonItems, 'right') : undefined;1182 const preparedHeaderRightBarButtonItems = headerRightBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerRightBarButtonItems, 'right') : undefined;
1162- const hasHeaderBarButtonItems = _utils.isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length);1183- const hasHeaderBarButtonItems = _utils.isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length);
1163+ const preparedHeaderCenterBarButtonItems = headerCenterBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerCenterBarButtonItems, 'right') : undefined;1184+ const preparedHeaderCenterBarButtonItems = headerCenterBarButtonItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerCenterBarButtonItems, 'center') : undefined;
1164+ const preparedHeaderToolbarItems = headerToolbarItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerToolbarItems, 'right') : undefined;1185+ const preparedHeaderToolbarItems = headerToolbarItems && _utils.isHeaderBarButtonsAvailableForCurrentPlatform ? (0, _prepareHeaderBarButtonItems.prepareHeaderBarButtonItems)(headerToolbarItems, 'toolbar') : undefined;
1165+ const hasHeaderBarButtonItems = _utils.isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length || preparedHeaderCenterBarButtonItems?.length || preparedHeaderToolbarItems?.length);1186+ const hasHeaderBarButtonItems = _utils.isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length || preparedHeaderCenterBarButtonItems?.length || preparedHeaderToolbarItems?.length);
1166 1187
1167 // Handle bar button item presses1188 // Handle bar button item presses
...@@ -1172,7 +1193,8 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32...@@ -1172,7 +1193,8 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32
1172+ const pressedItem = allItems.find(item => item && 'buttonId' in item && item.buttonId === buttonId);1193+ const pressedItem = allItems.find(item => item && 'buttonId' in item && item.buttonId === buttonId);
1173 if (pressedItem && pressedItem.type === 'button' && pressedItem.onPress) {1194 if (pressedItem && pressedItem.type === 'button' && pressedItem.onPress) {
1174 pressedItem.onPress();1195 pressedItem.onPress();
1175 }1196+ return;
1197+ }
1176+ for (const item of allItems) {1198+ for (const item of allItems) {
1177+ if (!item || item.type !== 'mailSearchToolbar') {1199+ if (!item || item.type !== 'mailSearchToolbar') {
1178+ continue;1200+ continue;
...@@ -1190,11 +1212,10 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32...@@ -1190,11 +1212,10 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32
1190+ item.onSearchTextChange?.(buttonId.slice(searchTextChangePrefix.length));1212+ item.onSearchTextChange?.(buttonId.slice(searchTextChangePrefix.length));
1191+ return;1213+ return;
1192+ }1214+ }
1193+ }1215 }
1194 } : undefined;1216 } : undefined;
1195 1217
1196 // Handle bar button menu item presses by deep-searching nested menus1218@@ -59,7 +84,7 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_
1197@@ -59,7 +83,7 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_
1198 };1219 };
1199 1220
1200 // Check each bar-button item with a menu1221 // Check each bar-button item with a menu
...@@ -1203,7 +1224,7 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32...@@ -1203,7 +1224,7 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32
1203 for (const item of allItems) {1224 for (const item of allItems) {
1204 if (item && item.type === 'menu' && item.menu) {1225 if (item && item.type === 'menu' && item.menu) {
1205 const action = findInMenu(item.menu, event.nativeEvent.menuId);1226 const action = findInMenu(item.menu, event.nativeEvent.menuId);
1206@@ -67,6 +91,15 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_1227@@ -67,6 +92,15 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_
1207 action.onPress();1228 action.onPress();
1208 return;1229 return;
1209 }1230 }
...@@ -1219,7 +1240,7 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32...@@ -1219,7 +1240,7 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32
1219 }1240 }
1220 }1241 }
1221 } : undefined;1242 } : undefined;
1222@@ -74,6 +107,8 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_1243@@ -74,6 +108,8 @@ const ScreenStackHeaderConfig = exports.ScreenStackHeaderConfig = /*#__PURE__*/_
1223 userInterfaceStyle: props.experimental_userInterfaceStyle,1244 userInterfaceStyle: props.experimental_userInterfaceStyle,
1224 headerLeftBarButtonItems: preparedHeaderLeftBarButtonItems,1245 headerLeftBarButtonItems: preparedHeaderLeftBarButtonItems,
1225 headerRightBarButtonItems: preparedHeaderRightBarButtonItems,1246 headerRightBarButtonItems: preparedHeaderRightBarButtonItems,
...@@ -1229,20 +1250,49 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32...@@ -1229,20 +1250,49 @@ index 8c509f2657105cfd86448347c1a01fb73651ff9e..d1f53322a7d2401852732ce46bfc6f32
1229 onPressHeaderBarButtonMenuItem: onPressHeaderBarButtonMenuItem,1250 onPressHeaderBarButtonMenuItem: onPressHeaderBarButtonMenuItem,
1230 ref: ref,1251 ref: ref,
1231diff --git a/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js b/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js1252diff --git a/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js b/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js
1232index ab93f62e4a7049d63c6681cecbd6cf8b1d07ce10..b5ea122473b023f84eabdb1914aef09a28c6d525 1006441253index ab93f62e4a7049d63c6681cecbd6cf8b1d07ce10..9dca2ab640e92161eb647b819a989acd0d41d9fe 100644
1233--- a/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js1254--- a/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js
1234+++ b/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js1255+++ b/lib/commonjs/components/helpers/prepareHeaderBarButtonItems.js
1235@@ -41,10 +41,31 @@ const prepareMenu = (menu, index, side, path = '') => {1256@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
1257 });
1258 exports.prepareHeaderBarButtonItems = void 0;
1259 var _reactNative = require("react-native");
1260-const prepareMenu = (menu, index, side, path = '') => {
1261+const prepareMenu = (menu, index, placement, path = '') => {
1262 return {
1263 ...menu,
1264 items: menu.items.map((menuItem, menuIndex) => {
1265@@ -26,7 +26,7 @@ const prepareMenu = (menu, index, side, path = '') => {
1266 xcassetName,
1267 imageSource,
1268 templateSource,
1269- ...prepareMenu(menuItem, index, side, currentPath)
1270+ ...prepareMenu(menuItem, index, placement, currentPath)
1271 };
1272 }
1273 return {
1274@@ -35,16 +35,40 @@ const prepareMenu = (menu, index, side, path = '') => {
1275 xcassetName,
1276 imageSource,
1277 templateSource,
1278- menuId: `${currentPath}-${index}-${side}`
1279+ menuId: `${currentPath}-${index}-${placement}`
1280 };
1281 })
1236 };1282 };
1237 };1283 };
1238 const prepareHeaderBarButtonItems = (barButtonItems, side) => {1284-const prepareHeaderBarButtonItems = (barButtonItems, side) => {
1239- return barButtonItems?.map((item, index) => {1285- return barButtonItems?.map((item, index) => {
1286+const prepareHeaderBarButtonItems = (barButtonItems, placement) => {
1240+ const items = Array.isArray(barButtonItems) ? barButtonItems : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ? [barButtonItems] : undefined;1287+ const items = Array.isArray(barButtonItems) ? barButtonItems : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ? [barButtonItems] : undefined;
1241+ return items?.map((item, index) => {1288+ return items?.map((item, index) => {
1242 if (item.type === 'spacing') {1289 if (item.type === 'spacing') {
1243 return item;1290 return item;
1244 }1291 }
1245+ if (item.type === 'searchBarPlacement') {1292+ if (item.type === 'searchBarPlacement') {
1293+ if (placement !== 'toolbar') {
1294+ return null;
1295+ }
1246+ return {1296+ return {
1247+ ...item,1297+ ...item,
1248+ searchBarPlacement: true1298+ searchBarPlacement: true
...@@ -1258,18 +1308,40 @@ index ab93f62e4a7049d63c6681cecbd6cf8b1d07ce10..b5ea122473b023f84eabdb1914aef09a...@@ -1258,18 +1308,40 @@ index ab93f62e4a7049d63c6681cecbd6cf8b1d07ce10..b5ea122473b023f84eabdb1914aef09a
1258+ return {1308+ return {
1259+ ...item,1309+ ...item,
1260+ mailSearchToolbar: true,1310+ mailSearchToolbar: true,
1261+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, side, 'filter') : undefined,1311+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined,
1262+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, side, 'compose') : undefined1312+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined
1263+ };1313+ };
1264+ }1314+ }
1265 let imageSource, templateSource;1315 let imageSource, templateSource;
1266 if (item.icon?.type === 'imageSource') {1316 if (item.icon?.type === 'imageSource') {
1267 imageSource = _reactNative.Image.resolveAssetSource(item.icon.imageSource);1317 imageSource = _reactNative.Image.resolveAssetSource(item.icon.imageSource);
1318@@ -77,17 +101,17 @@ const prepareHeaderBarButtonItems = (barButtonItems, side) => {
1319 if (item.type === 'button') {
1320 return {
1321 ...processedItem,
1322- buttonId: `${index}-${side}`
1323+ buttonId: `${index}-${placement}`
1324 };
1325 }
1326 if (item.type === 'menu') {
1327 return {
1328 ...processedItem,
1329- menu: prepareMenu(item.menu, index, side)
1330+ menu: prepareMenu(item.menu, index, placement)
1331 };
1332 }
1333 return null;
1334- });
1335+ }).filter(item => item !== null);
1336 };
1337 exports.prepareHeaderBarButtonItems = prepareHeaderBarButtonItems;
1338 //# sourceMappingURL=prepareHeaderBarButtonItems.js.map
1339\ No newline at end of file
1268diff --git a/lib/module/components/ScreenStackHeaderConfig.js b/lib/module/components/ScreenStackHeaderConfig.js1340diff --git a/lib/module/components/ScreenStackHeaderConfig.js b/lib/module/components/ScreenStackHeaderConfig.js
1269index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f2f4bca00 1006441341index 68e3ba6a78314aba908d07098bb6982d11e6ee80..b787b3cf0284ffb81c80360a06c4059277bf4c1e 100644
1270--- a/lib/module/components/ScreenStackHeaderConfig.js1342--- a/lib/module/components/ScreenStackHeaderConfig.js
1271+++ b/lib/module/components/ScreenStackHeaderConfig.js1343+++ b/lib/module/components/ScreenStackHeaderConfig.js
1272@@ -22,18 +22,42 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref1344@@ -22,17 +22,42 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref
1273 } = useEdgeInsetApplication(!props.hidden, props.disableTopInsetApplication ?? false, props.disableLeftInsetApplication ?? false, props.disableRightInsetApplication ?? false, props.disableBottomInsetApplication ?? false);1345 } = useEdgeInsetApplication(!props.hidden, props.disableTopInsetApplication ?? false, props.disableLeftInsetApplication ?? false, props.disableRightInsetApplication ?? false, props.disableBottomInsetApplication ?? false);
1274 const {1346 const {
1275 headerLeftBarButtonItems,1347 headerLeftBarButtonItems,
...@@ -1281,8 +1353,8 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f...@@ -1281,8 +1353,8 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f
1281 const preparedHeaderLeftBarButtonItems = headerLeftBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerLeftBarButtonItems, 'left') : undefined;1353 const preparedHeaderLeftBarButtonItems = headerLeftBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerLeftBarButtonItems, 'left') : undefined;
1282 const preparedHeaderRightBarButtonItems = headerRightBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerRightBarButtonItems, 'right') : undefined;1354 const preparedHeaderRightBarButtonItems = headerRightBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerRightBarButtonItems, 'right') : undefined;
1283- const hasHeaderBarButtonItems = isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length);1355- const hasHeaderBarButtonItems = isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length);
1284+ const preparedHeaderCenterBarButtonItems = headerCenterBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerCenterBarButtonItems, 'right') : undefined;1356+ const preparedHeaderCenterBarButtonItems = headerCenterBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerCenterBarButtonItems, 'center') : undefined;
1285+ const preparedHeaderToolbarItems = headerToolbarItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerToolbarItems, 'right') : undefined;1357+ const preparedHeaderToolbarItems = headerToolbarItems && isHeaderBarButtonsAvailableForCurrentPlatform ? prepareHeaderBarButtonItems(headerToolbarItems, 'toolbar') : undefined;
1286+ const hasHeaderBarButtonItems = isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length || preparedHeaderCenterBarButtonItems?.length || preparedHeaderToolbarItems?.length);1358+ const hasHeaderBarButtonItems = isHeaderBarButtonsAvailableForCurrentPlatform && (preparedHeaderLeftBarButtonItems?.length || preparedHeaderRightBarButtonItems?.length || preparedHeaderCenterBarButtonItems?.length || preparedHeaderToolbarItems?.length);
1287 1359
1288 // Handle bar button item presses1360 // Handle bar button item presses
...@@ -1293,7 +1365,8 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f...@@ -1293,7 +1365,8 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f
1293+ const pressedItem = allItems.find(item => item && 'buttonId' in item && item.buttonId === buttonId);1365+ const pressedItem = allItems.find(item => item && 'buttonId' in item && item.buttonId === buttonId);
1294 if (pressedItem && pressedItem.type === 'button' && pressedItem.onPress) {1366 if (pressedItem && pressedItem.type === 'button' && pressedItem.onPress) {
1295 pressedItem.onPress();1367 pressedItem.onPress();
1296 }1368+ return;
1369+ }
1297+ for (const item of allItems) {1370+ for (const item of allItems) {
1298+ if (!item || item.type !== 'mailSearchToolbar') {1371+ if (!item || item.type !== 'mailSearchToolbar') {
1299+ continue;1372+ continue;
...@@ -1311,11 +1384,10 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f...@@ -1311,11 +1384,10 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f
1311+ item.onSearchTextChange?.(buttonId.slice(searchTextChangePrefix.length));1384+ item.onSearchTextChange?.(buttonId.slice(searchTextChangePrefix.length));
1312+ return;1385+ return;
1313+ }1386+ }
1314+ }1387 }
1315 } : undefined;1388 } : undefined;
1316 1389
1317 // Handle bar button menu item presses by deep-searching nested menus1390@@ -55,7 +80,7 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref
1318@@ -55,7 +79,7 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref
1319 };1391 };
1320 1392
1321 // Check each bar-button item with a menu1393 // Check each bar-button item with a menu
...@@ -1324,7 +1396,7 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f...@@ -1324,7 +1396,7 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f
1324 for (const item of allItems) {1396 for (const item of allItems) {
1325 if (item && item.type === 'menu' && item.menu) {1397 if (item && item.type === 'menu' && item.menu) {
1326 const action = findInMenu(item.menu, event.nativeEvent.menuId);1398 const action = findInMenu(item.menu, event.nativeEvent.menuId);
1327@@ -63,6 +87,15 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref1399@@ -63,6 +88,15 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref
1328 action.onPress();1400 action.onPress();
1329 return;1401 return;
1330 }1402 }
...@@ -1340,7 +1412,7 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f...@@ -1340,7 +1412,7 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f
1340 }1412 }
1341 }1413 }
1342 } : undefined;1414 } : undefined;
1343@@ -70,6 +103,8 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref1415@@ -70,6 +104,8 @@ export const ScreenStackHeaderConfig = /*#__PURE__*/React.forwardRef((props, ref
1344 userInterfaceStyle: props.experimental_userInterfaceStyle,1416 userInterfaceStyle: props.experimental_userInterfaceStyle,
1345 headerLeftBarButtonItems: preparedHeaderLeftBarButtonItems,1417 headerLeftBarButtonItems: preparedHeaderLeftBarButtonItems,
1346 headerRightBarButtonItems: preparedHeaderRightBarButtonItems,1418 headerRightBarButtonItems: preparedHeaderRightBarButtonItems,
...@@ -1350,20 +1422,47 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f...@@ -1350,20 +1422,47 @@ index 68e3ba6a78314aba908d07098bb6982d11e6ee80..05cb8563d3a7d3811860058df23bbd1f
1350 onPressHeaderBarButtonMenuItem: onPressHeaderBarButtonMenuItem,1422 onPressHeaderBarButtonMenuItem: onPressHeaderBarButtonMenuItem,
1351 ref: ref,1423 ref: ref,
1352diff --git a/lib/module/components/helpers/prepareHeaderBarButtonItems.js b/lib/module/components/helpers/prepareHeaderBarButtonItems.js1424diff --git a/lib/module/components/helpers/prepareHeaderBarButtonItems.js b/lib/module/components/helpers/prepareHeaderBarButtonItems.js
1353index 8a70ffd78617147418d628c03c580bb7ff9a8a72..8dbd0ba2ee61ee54d44cdf286a720ce26af01f26 1006441425index 8a70ffd78617147418d628c03c580bb7ff9a8a72..bca930372d2a7c3f8e0a35c3dcf28474f899f21c 100644
1354--- a/lib/module/components/helpers/prepareHeaderBarButtonItems.js1426--- a/lib/module/components/helpers/prepareHeaderBarButtonItems.js
1355+++ b/lib/module/components/helpers/prepareHeaderBarButtonItems.js1427+++ b/lib/module/components/helpers/prepareHeaderBarButtonItems.js
1356@@ -35,10 +35,31 @@ const prepareMenu = (menu, index, side, path = '') => {1428@@ -1,5 +1,5 @@
1429 import { Image, processColor } from 'react-native';
1430-const prepareMenu = (menu, index, side, path = '') => {
1431+const prepareMenu = (menu, index, placement, path = '') => {
1432 return {
1433 ...menu,
1434 items: menu.items.map((menuItem, menuIndex) => {
1435@@ -20,7 +20,7 @@ const prepareMenu = (menu, index, side, path = '') => {
1436 xcassetName,
1437 imageSource,
1438 templateSource,
1439- ...prepareMenu(menuItem, index, side, currentPath)
1440+ ...prepareMenu(menuItem, index, placement, currentPath)
1441 };
1442 }
1443 return {
1444@@ -29,16 +29,40 @@ const prepareMenu = (menu, index, side, path = '') => {
1445 xcassetName,
1446 imageSource,
1447 templateSource,
1448- menuId: `${currentPath}-${index}-${side}`
1449+ menuId: `${currentPath}-${index}-${placement}`
1450 };
1451 })
1357 };1452 };
1358 };1453 };
1359 export const prepareHeaderBarButtonItems = (barButtonItems, side) => {1454-export const prepareHeaderBarButtonItems = (barButtonItems, side) => {
1360- return barButtonItems?.map((item, index) => {1455- return barButtonItems?.map((item, index) => {
1456+export const prepareHeaderBarButtonItems = (barButtonItems, placement) => {
1361+ const items = Array.isArray(barButtonItems) ? barButtonItems : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ? [barButtonItems] : undefined;1457+ const items = Array.isArray(barButtonItems) ? barButtonItems : barButtonItems && typeof barButtonItems === 'object' && 'type' in barButtonItems ? [barButtonItems] : undefined;
1362+ return items?.map((item, index) => {1458+ return items?.map((item, index) => {
1363 if (item.type === 'spacing') {1459 if (item.type === 'spacing') {
1364 return item;1460 return item;
1365 }1461 }
1366+ if (item.type === 'searchBarPlacement') {1462+ if (item.type === 'searchBarPlacement') {
1463+ if (placement !== 'toolbar') {
1464+ return null;
1465+ }
1367+ return {1466+ return {
1368+ ...item,1467+ ...item,
1369+ searchBarPlacement: true1468+ searchBarPlacement: true
...@@ -1379,13 +1478,53 @@ index 8a70ffd78617147418d628c03c580bb7ff9a8a72..8dbd0ba2ee61ee54d44cdf286a720ce2...@@ -1379,13 +1478,53 @@ index 8a70ffd78617147418d628c03c580bb7ff9a8a72..8dbd0ba2ee61ee54d44cdf286a720ce2
1379+ return {1478+ return {
1380+ ...item,1479+ ...item,
1381+ mailSearchToolbar: true,1480+ mailSearchToolbar: true,
1382+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, side, 'filter') : undefined,1481+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined,
1383+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, side, 'compose') : undefined1482+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined
1384+ };1483+ };
1385+ }1484+ }
1386 let imageSource, templateSource;1485 let imageSource, templateSource;
1387 if (item.icon?.type === 'imageSource') {1486 if (item.icon?.type === 'imageSource') {
1388 imageSource = Image.resolveAssetSource(item.icon.imageSource);1487 imageSource = Image.resolveAssetSource(item.icon.imageSource);
1488@@ -71,16 +95,16 @@ export const prepareHeaderBarButtonItems = (barButtonItems, side) => {
1489 if (item.type === 'button') {
1490 return {
1491 ...processedItem,
1492- buttonId: `${index}-${side}`
1493+ buttonId: `${index}-${placement}`
1494 };
1495 }
1496 if (item.type === 'menu') {
1497 return {
1498 ...processedItem,
1499- menu: prepareMenu(item.menu, index, side)
1500+ menu: prepareMenu(item.menu, index, placement)
1501 };
1502 }
1503 return null;
1504- });
1505+ }).filter(item => item !== null);
1506 };
1507 //# sourceMappingURL=prepareHeaderBarButtonItems.js.map
1508\ No newline at end of file
1509diff --git a/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts b/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts
1510index c41ef943e554754f599f2fcd157dd0dc61d78b7e..ed02d44f78ee3f1387ba93bf292be2b99bb0e3b3 100644
1511--- a/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts
1512+++ b/lib/typescript/components/helpers/prepareHeaderBarButtonItems.d.ts
1513@@ -1,5 +1,5 @@
1514 import { HeaderBarButtonItem } from 'react-native-screens/types';
1515-export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButtonItem[], side: "left" | "right") => (import("react-native-screens/types").HeaderBarButtonItemSpacing | {
1516+export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButtonItem[], side: "left" | "right" | "center" | "toolbar") => (import("react-native-screens/types").HeaderBarButtonItemSpacing | {
1517 buttonId: string;
1518 imageSource: import("react-native").ImageResolvedAssetSource | undefined;
1519 templateSource: import("react-native").ImageResolvedAssetSource | undefined;
1520@@ -161,5 +161,5 @@ export declare const prepareHeaderBarButtonItems: (barButtonItems: HeaderBarButt
1521 identifier?: string | undefined;
1522 accessibilityLabel?: string | undefined;
1523 accessibilityHint?: string | undefined;
1524-} | null)[];
1525+})[];
1526 //# sourceMappingURL=prepareHeaderBarButtonItems.d.ts.map
1527\ No newline at end of file
1389diff --git a/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts b/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts1528diff --git a/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts b/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts
1390index a51d8648567cff29cd2be0d5262bd15c6fc69c61..8b7439aff4d7e6fe8a72bf0bac93c3c19568b1a6 1006441529index a51d8648567cff29cd2be0d5262bd15c6fc69c61..8b7439aff4d7e6fe8a72bf0bac93c3c19568b1a6 100644
1391--- a/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts1530--- a/lib/typescript/fabric/ScreenStackHeaderConfigNativeComponent.d.ts
...@@ -1423,7 +1562,7 @@ index a51d8648567cff29cd2be0d5262bd15c6fc69c61..8b7439aff4d7e6fe8a72bf0bac93c3c1...@@ -1423,7 +1562,7 @@ index a51d8648567cff29cd2be0d5262bd15c6fc69c61..8b7439aff4d7e6fe8a72bf0bac93c3c1
1423 onPressHeaderBarButtonMenuItem?: CT.DirectEventHandler<OnPressHeaderBarButtonMenuItemEvent> | undefined;1562 onPressHeaderBarButtonMenuItem?: CT.DirectEventHandler<OnPressHeaderBarButtonMenuItemEvent> | undefined;
1424 synchronousShadowStateUpdatesEnabled?: CT.WithDefault<boolean, true>;1563 synchronousShadowStateUpdatesEnabled?: CT.WithDefault<boolean, true>;
1425diff --git a/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts b/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts1564diff --git a/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts b/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts
1426index 1ca926e6753294861f5f79ab6267dc7999f70639..15929959d1e274cc6abd55f2eb8db50ba102169a 1006441565index 1ca926e6753294861f5f79ab6267dc7999f70639..94e676fdb08ff9d1cf81a1cf06a45e931b5461f1 100644
1427--- a/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts1566--- a/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts
1428+++ b/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts1567+++ b/lib/typescript/fabric/ScreenStackHeaderSubviewNativeComponent.d.ts
1429@@ -3,6 +3,7 @@ export type HeaderSubviewTypes = 'back' | 'right' | 'left' | 'title' | 'center'1568@@ -3,6 +3,7 @@ export type HeaderSubviewTypes = 'back' | 'right' | 'left' | 'title' | 'center'
...@@ -1576,7 +1715,7 @@ index 10a31341f4eff258a7f8ea6abae3eddf0dd21218..bab5031f5f9b246f15e5396f3f2fee90...@@ -1576,7 +1715,7 @@ index 10a31341f4eff258a7f8ea6abae3eddf0dd21218..bab5031f5f9b246f15e5396f3f2fee90
1576 * Custom Screen Transition1715 * Custom Screen Transition
1577 */1716 */
1578diff --git a/src/components/ScreenStackHeaderConfig.tsx b/src/components/ScreenStackHeaderConfig.tsx1717diff --git a/src/components/ScreenStackHeaderConfig.tsx b/src/components/ScreenStackHeaderConfig.tsx
1579index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc0004ef29 1006441718index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9e8173da567933fd3f6819fb26bf4a0e87640767 100644
1580--- a/src/components/ScreenStackHeaderConfig.tsx1719--- a/src/components/ScreenStackHeaderConfig.tsx
1581+++ b/src/components/ScreenStackHeaderConfig.tsx1720+++ b/src/components/ScreenStackHeaderConfig.tsx
1582@@ -48,7 +48,12 @@ export const ScreenStackHeaderConfig = React.forwardRef<1721@@ -48,7 +48,12 @@ export const ScreenStackHeaderConfig = React.forwardRef<
...@@ -1599,11 +1738,11 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc...@@ -1599,11 +1738,11 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc
1599 : undefined;1738 : undefined;
1600+ const preparedHeaderCenterBarButtonItems =1739+ const preparedHeaderCenterBarButtonItems =
1601+ headerCenterBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform1740+ headerCenterBarButtonItems && isHeaderBarButtonsAvailableForCurrentPlatform
1602+ ? prepareHeaderBarButtonItems(headerCenterBarButtonItems, 'right')1741+ ? prepareHeaderBarButtonItems(headerCenterBarButtonItems, 'center')
1603+ : undefined;1742+ : undefined;
1604+ const preparedHeaderToolbarItems =1743+ const preparedHeaderToolbarItems =
1605+ headerToolbarItems && isHeaderBarButtonsAvailableForCurrentPlatform1744+ headerToolbarItems && isHeaderBarButtonsAvailableForCurrentPlatform
1606+ ? prepareHeaderBarButtonItems(headerToolbarItems, 'right')1745+ ? prepareHeaderBarButtonItems(headerToolbarItems, 'toolbar')
1607+ : undefined;1746+ : undefined;
1608 const hasHeaderBarButtonItems =1747 const hasHeaderBarButtonItems =
1609 isHeaderBarButtonsAvailableForCurrentPlatform &&1748 isHeaderBarButtonsAvailableForCurrentPlatform &&
...@@ -1634,10 +1773,12 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc...@@ -1634,10 +1773,12 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc
1634 );1773 );
1635 if (1774 if (
1636 pressedItem &&1775 pressedItem &&
1637@@ -82,6 +101,31 @@ export const ScreenStackHeaderConfig = React.forwardRef<1776@@ -81,6 +100,32 @@ export const ScreenStackHeaderConfig = React.forwardRef<
1777 pressedItem.onPress
1638 ) {1778 ) {
1639 pressedItem.onPress();1779 pressedItem.onPress();
1640 }1780+ return;
1781+ }
1641+ for (const item of allItems) {1782+ for (const item of allItems) {
1642+ if (!item || item.type !== 'mailSearchToolbar') {1783+ if (!item || item.type !== 'mailSearchToolbar') {
1643+ continue;1784+ continue;
...@@ -1662,11 +1803,10 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc...@@ -1662,11 +1803,10 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc
1662+ );1803+ );
1663+ return;1804+ return;
1664+ }1805+ }
1665+ }1806 }
1666 }1807 }
1667 : undefined;1808 : undefined;
1668 1809@@ -111,6 +156,8 @@ export const ScreenStackHeaderConfig = React.forwardRef<
1669@@ -111,6 +155,8 @@ export const ScreenStackHeaderConfig = React.forwardRef<
1670 const allItems = [1810 const allItems = [
1671 ...(preparedHeaderLeftBarButtonItems ?? []),1811 ...(preparedHeaderLeftBarButtonItems ?? []),
1672 ...(preparedHeaderRightBarButtonItems ?? []),1812 ...(preparedHeaderRightBarButtonItems ?? []),
...@@ -1675,7 +1815,7 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc...@@ -1675,7 +1815,7 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc
1675 ];1815 ];
1676 for (const item of allItems) {1816 for (const item of allItems) {
1677 if (item && item.type === 'menu' && item.menu) {1817 if (item && item.type === 'menu' && item.menu) {
1678@@ -119,6 +165,17 @@ export const ScreenStackHeaderConfig = React.forwardRef<1818@@ -119,6 +166,17 @@ export const ScreenStackHeaderConfig = React.forwardRef<
1679 action.onPress();1819 action.onPress();
1680 return;1820 return;
1681 }1821 }
...@@ -1693,7 +1833,7 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc...@@ -1693,7 +1833,7 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc
1693 }1833 }
1694 }1834 }
1695 }1835 }
1696@@ -130,6 +187,8 @@ export const ScreenStackHeaderConfig = React.forwardRef<1836@@ -130,6 +188,8 @@ export const ScreenStackHeaderConfig = React.forwardRef<
1697 userInterfaceStyle={props.experimental_userInterfaceStyle}1837 userInterfaceStyle={props.experimental_userInterfaceStyle}
1698 headerLeftBarButtonItems={preparedHeaderLeftBarButtonItems}1838 headerLeftBarButtonItems={preparedHeaderLeftBarButtonItems}
1699 headerRightBarButtonItems={preparedHeaderRightBarButtonItems}1839 headerRightBarButtonItems={preparedHeaderRightBarButtonItems}
...@@ -1703,20 +1843,47 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc...@@ -1703,20 +1843,47 @@ index c3a88b6f6c8362cf717372a35cdc35a6b397bdd0..9da8553b2c2e81fa13ef4f5b3e805efc
1703 onPressHeaderBarButtonMenuItem={onPressHeaderBarButtonMenuItem}1843 onPressHeaderBarButtonMenuItem={onPressHeaderBarButtonMenuItem}
1704 ref={ref}1844 ref={ref}
1705diff --git a/src/components/helpers/prepareHeaderBarButtonItems.ts b/src/components/helpers/prepareHeaderBarButtonItems.ts1845diff --git a/src/components/helpers/prepareHeaderBarButtonItems.ts b/src/components/helpers/prepareHeaderBarButtonItems.ts
1706index be2c24dfee77f5883b5ab1d7473be80933b5dc6f..0b038d2005b2d51bbb2ab1d7dba7eaccda83d42f 1006441846index be2c24dfee77f5883b5ab1d7473be80933b5dc6f..2008a342f13806641909c19a9f4ab6829f239016 100644
1707--- a/src/components/helpers/prepareHeaderBarButtonItems.ts1847--- a/src/components/helpers/prepareHeaderBarButtonItems.ts
1708+++ b/src/components/helpers/prepareHeaderBarButtonItems.ts1848+++ b/src/components/helpers/prepareHeaderBarButtonItems.ts
1709@@ -50,13 +50,43 @@ const prepareMenu = (1849@@ -7,7 +7,7 @@ import {
1850 const prepareMenu = (
1851 menu: HeaderBarButtonItemWithMenu['menu'],
1852 index: number,
1853- side: 'left' | 'right',
1854+ placement: 'left' | 'right' | 'center' | 'toolbar',
1855 path: string = '',
1856 ): HeaderBarButtonItemWithMenu['menu'] => {
1857 return {
1858@@ -34,7 +34,7 @@ const prepareMenu = (
1859 xcassetName,
1860 imageSource,
1861 templateSource,
1862- ...prepareMenu(menuItem, index, side, currentPath),
1863+ ...prepareMenu(menuItem, index, placement, currentPath),
1864 };
1865 }
1866 return {
1867@@ -43,20 +43,53 @@ const prepareMenu = (
1868 xcassetName,
1869 imageSource,
1870 templateSource,
1871- menuId: `${currentPath}-${index}-${side}`,
1872+ menuId: `${currentPath}-${index}-${placement}`,
1873 };
1874 }),
1875 };
1710 };1876 };
1711 1877
1712 export const prepareHeaderBarButtonItems = (1878 export const prepareHeaderBarButtonItems = (
1713- barButtonItems: HeaderBarButtonItem[],1879- barButtonItems: HeaderBarButtonItem[],
1880- side: 'left' | 'right',
1714+ barButtonItems:1881+ barButtonItems:
1715+ | HeaderBarButtonItem[]1882+ | HeaderBarButtonItem[]
1716+ | HeaderBarButtonItem1883+ | HeaderBarButtonItem
1717+ | null1884+ | null
1718+ | undefined,1885+ | undefined,
1719 side: 'left' | 'right',1886+ placement: 'left' | 'right' | 'center' | 'toolbar',
1720 ) => {1887 ) => {
1721- return barButtonItems?.map((item, index) => {1888- return barButtonItems?.map((item, index) => {
1722+ const items = Array.isArray(barButtonItems)1889+ const items = Array.isArray(barButtonItems)
...@@ -1730,6 +1897,9 @@ index be2c24dfee77f5883b5ab1d7473be80933b5dc6f..0b038d2005b2d51bbb2ab1d7dba7eacc...@@ -1730,6 +1897,9 @@ index be2c24dfee77f5883b5ab1d7473be80933b5dc6f..0b038d2005b2d51bbb2ab1d7dba7eacc
1730 return item;1897 return item;
1731 }1898 }
1732+ if (item.type === 'searchBarPlacement') {1899+ if (item.type === 'searchBarPlacement') {
1900+ if (placement !== 'toolbar') {
1901+ return null;
1902+ }
1733+ return {1903+ return {
1734+ ...item,1904+ ...item,
1735+ searchBarPlacement: true,1905+ searchBarPlacement: true,
...@@ -1745,13 +1915,32 @@ index be2c24dfee77f5883b5ab1d7473be80933b5dc6f..0b038d2005b2d51bbb2ab1d7dba7eacc...@@ -1745,13 +1915,32 @@ index be2c24dfee77f5883b5ab1d7473be80933b5dc6f..0b038d2005b2d51bbb2ab1d7dba7eacc
1745+ return {1915+ return {
1746+ ...item,1916+ ...item,
1747+ mailSearchToolbar: true,1917+ mailSearchToolbar: true,
1748+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, side, 'filter') : undefined,1918+ filterMenu: item.filterMenu ? prepareMenu(item.filterMenu, index, placement, 'filter') : undefined,
1749+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, side, 'compose') : undefined,1919+ composeMenu: item.composeMenu ? prepareMenu(item.composeMenu, index, placement, 'compose') : undefined,
1750+ };1920+ };
1751+ }1921+ }
1752 let imageSource, templateSource;1922 let imageSource, templateSource;
1753 if (item.icon?.type === 'imageSource') {1923 if (item.icon?.type === 'imageSource') {
1754 imageSource = Image.resolveAssetSource(item.icon.imageSource);1924 imageSource = Image.resolveAssetSource(item.icon.imageSource);
1925@@ -91,15 +124,15 @@ export const prepareHeaderBarButtonItems = (
1926 if (item.type === 'button') {
1927 return {
1928 ...processedItem,
1929- buttonId: `${index}-${side}`,
1930+ buttonId: `${index}-${placement}`,
1931 };
1932 }
1933 if (item.type === 'menu') {
1934 return {
1935 ...processedItem,
1936- menu: prepareMenu(item.menu, index, side),
1937+ menu: prepareMenu(item.menu, index, placement),
1938 };
1939 }
1940 return null;
1941- });
1942+ }).filter(item => item !== null);
1943 };
1755diff --git a/src/fabric/ScreenStackHeaderConfigNativeComponent.ts b/src/fabric/ScreenStackHeaderConfigNativeComponent.ts1944diff --git a/src/fabric/ScreenStackHeaderConfigNativeComponent.ts b/src/fabric/ScreenStackHeaderConfigNativeComponent.ts
1756index a80d9fef0c0ab5ce8221c5e0c7fae65162bc6164..fc16f51425702a418c09de553a54753331f19d15 1006441945index a80d9fef0c0ab5ce8221c5e0c7fae65162bc6164..fc16f51425702a418c09de553a54753331f19d15 100644
1757--- a/src/fabric/ScreenStackHeaderConfigNativeComponent.ts1946--- a/src/fabric/ScreenStackHeaderConfigNativeComponent.ts
pnpm-lock.yaml+6-6
...@@ -94,7 +94,7 @@ patchedDependencies:...@@ -94,7 +94,7 @@ patchedDependencies:
94 react-native-gesture-handler@2.32.0: 808eb26f9e57cf4945efd3985af4d9c764da6f91f4c9764433cc868602bbf4d394 react-native-gesture-handler@2.32.0: 808eb26f9e57cf4945efd3985af4d9c764da6f91f4c9764433cc868602bbf4d3
95 react-native-keyboard-controller@1.21.13: 20be72c84d74253acdcfefbc6defe36dc396944f1a44cab2bdd0e3cd572ae00895 react-native-keyboard-controller@1.21.13: 20be72c84d74253acdcfefbc6defe36dc396944f1a44cab2bdd0e3cd572ae008
96 react-native-nitro-modules@0.35.9: 825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b608842267596 react-native-nitro-modules@0.35.9: 825622aae63a8fb5b904f3c77908a0e216261d727ea171709f2c0b6088422675
97 react-native-screens@4.26.2: 11566900d0c90514867ede5a2333ba412ab3b5a532ba1955e6306fff8b12de1a97 react-native-screens@4.26.2: 5d2e7beefe55f0b7ee157993cbc0ec38d32aa558e4e780764381fe8f96ba728d
9898
99importers:99importers:
100100
...@@ -248,7 +248,7 @@ importers:...@@ -248,7 +248,7 @@ importers:
248 version: 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)248 version: 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
249 '@react-navigation/native-stack':249 '@react-navigation/native-stack':
250 specifier: 7.17.6250 specifier: 7.17.6
251 version: 7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(df02ad16d8d764efad8e903a73894296)251 version: 7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(1d8c6f507069f6f6aada9b6419c84a6c)
252 '@shikijs/core':252 '@shikijs/core':
253 specifier: 4.2.0253 specifier: 4.2.0
254 version: 4.2.0254 version: 4.2.0
...@@ -416,7 +416,7 @@ importers:...@@ -416,7 +416,7 @@ importers:
416 version: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)416 version: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
417 react-native-screens:417 react-native-screens:
418 specifier: ~4.26.0418 specifier: ~4.26.0
419 version: 4.26.2(patch_hash=11566900d0c90514867ede5a2333ba412ab3b5a532ba1955e6306fff8b12de1a)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)419 version: 4.26.2(patch_hash=5d2e7beefe55f0b7ee157993cbc0ec38d32aa558e4e780764381fe8f96ba728d)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
420 react-native-shiki-engine:420 react-native-shiki-engine:
421 specifier: ^0.3.12421 specifier: ^0.3.12
422 version: 0.3.12(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)422 version: 0.3.12(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
...@@ -13880,7 +13880,7 @@ snapshots:...@@ -13880,7 +13880,7 @@ snapshots:
13880 optionalDependencies:13880 optionalDependencies:
13881 '@react-native-masked-view/masked-view': 0.3.2(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)13881 '@react-native-masked-view/masked-view': 0.3.2(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
1388213882
13883 '@react-navigation/native-stack@7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(df02ad16d8d764efad8e903a73894296)':13883 '@react-navigation/native-stack@7.17.6(patch_hash=e667c3cef8c78bb9ff4882ee5bd23a432247b843060a9499eb5f07e9e2295552)(1d8c6f507069f6f6aada9b6419c84a6c)':
13884 dependencies:13884 dependencies:
13885 '@react-navigation/elements': 2.9.26(c10301b6e0c42fc6434d2b643197a81e)13885 '@react-navigation/elements': 2.9.26(c10301b6e0c42fc6434d2b643197a81e)
13886 '@react-navigation/native': 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)13886 '@react-navigation/native': 7.3.4(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
...@@ -13888,7 +13888,7 @@ snapshots:...@@ -13888,7 +13888,7 @@ snapshots:
13888 react: 19.2.313888 react: 19.2.3
13889 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)13889 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)
13890 react-native-safe-area-context: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)13890 react-native-safe-area-context: 5.7.0(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
13891 react-native-screens: 4.26.2(patch_hash=11566900d0c90514867ede5a2333ba412ab3b5a532ba1955e6306fff8b12de1a)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)13891 react-native-screens: 4.26.2(patch_hash=5d2e7beefe55f0b7ee157993cbc0ec38d32aa558e4e780764381fe8f96ba728d)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
13892 sf-symbols-typescript: 2.2.013892 sf-symbols-typescript: 2.2.0
13893 warn-once: 0.1.113893 warn-once: 0.1.1
13894 transitivePeerDependencies:13894 transitivePeerDependencies:
...@@ -19492,7 +19492,7 @@ snapshots:...@@ -19492,7 +19492,7 @@ snapshots:
19492 react: 19.2.319492 react: 19.2.3
19493 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)19493 react-native: 0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)
1949419494
19495 react-native-screens@4.26.2(patch_hash=11566900d0c90514867ede5a2333ba412ab3b5a532ba1955e6306fff8b12de1a)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3):19495 react-native-screens@4.26.2(patch_hash=5d2e7beefe55f0b7ee157993cbc0ec38d32aa558e4e780764381fe8f96ba728d)(react-native@0.86.3(@babel/core@7.29.7)(@react-native/metro-config@0.86.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3):
19496 dependencies:19496 dependencies:
19497 react: 19.2.319497 react: 19.2.3
19498 react-freeze: 1.0.4(react@19.2.3)19498 react-freeze: 1.0.4(react@19.2.3)