authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-08-27 20:47:42-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-27 20:47:42-07:00
logb982847ab201795711884d1dfadfddb3864adb23
tree07fab8122e5c4ef31493d936cd087c2c7b0a7078
parentb0ae3f3a8527bdcccb6a5cbda93548ad66fbcfea
signature Signed by PGP key B5690EEEBB952194

fix(mobile): keep iOS home header stable (#8467)

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

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

patches/react-native-screens@4.25.2.patch+75-28
...@@ -226,7 +226,45 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -226,7 +226,45 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
226 226
227 // appearance does not apply to the tvOS so we need to use lagacy customization227 // appearance does not apply to the tvOS so we need to use lagacy customization
228 #if TARGET_OS_TV228 #if TARGET_OS_TV
229@@ -637,10 +675,458 @@ + (void)updateViewController:(UIViewController *)vc229@@ -550,31 +588,25 @@ + (void)updateViewController:(UIViewController *)vc
230 navitem.titleView = nil;
231- navitem.leftBarButtonItems = nil;
232- navitem.rightBarButtonItems = nil;
233-
234+
235 #if !TARGET_OS_TV
236 // We want to set navitem.searchController to nil only if we are sure
237 // that we are removing the search bar from the header.
238 bool searchBarPresent = false;
239 #endif /* !TARGET_OS_TV */
240-
241+
242+ NSMutableArray<UIBarButtonItem *> *subviewLeftItems = [NSMutableArray array];
243+ NSMutableArray<UIBarButtonItem *> *subviewRightItems = [NSMutableArray array];
244 for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) {
245 // This code should be kept in sync on Fabric with analogous switch statement in
246 // `- [RNSScreenStackHeaderConfig replaceNavigationBarViewsWithSnapshotOfSubview:]` method.
247 switch (subview.type) {
248 case RNSScreenStackHeaderSubviewTypeLeft: {
249- NSArray<UIBarButtonItem *> *currentItems = navitem.leftBarButtonItems ?: @[];
250- NSMutableArray<UIBarButtonItem *> *mutableItems = [currentItems mutableCopy];
251- [mutableItems addObject:[subview getUIBarButtonItem]];
252- navitem.leftBarButtonItems = mutableItems;
253+ [subviewLeftItems addObject:[subview getUIBarButtonItem]];
254 break;
255 }
256 case RNSScreenStackHeaderSubviewTypeRight: {
257- NSArray<UIBarButtonItem *> *currentItems = navitem.rightBarButtonItems ?: @[];
258- NSMutableArray<UIBarButtonItem *> *mutableItems = [currentItems mutableCopy];
259- [mutableItems addObject:[subview getUIBarButtonItem]];
260- navitem.rightBarButtonItems = mutableItems;
261+ [subviewRightItems addObject:[subview getUIBarButtonItem]];
262 break;
263 }
264 case RNSScreenStackHeaderSubviewTypeCenter:
265 case RNSScreenStackHeaderSubviewTypeTitle: {
266 navitem.titleView = subview;
267@@ -637,10 +669,467 @@ + (void)updateViewController:(UIViewController *)vc
230 // This assignment should be done after `navitem.titleView = ...` assignment (iOS 16.0 bug).268 // This assignment should be done after `navitem.titleView = ...` assignment (iOS 16.0 bug).
231 // See: https://github.com/software-mansion/react-native-screens/issues/1570 (comments)269 // See: https://github.com/software-mansion/react-native-screens/issues/1570 (comments)
232 navitem.title = config.title;270 navitem.title = config.title;
...@@ -237,29 +275,43 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -237,29 +275,43 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
237+ NSArray *headerLeftConfigs = config.headerLeftBarButtonItems ?: @[];275+ NSArray *headerLeftConfigs = config.headerLeftBarButtonItems ?: @[];
238+ NSArray *headerRightConfigs = config.headerRightBarButtonItems ?: @[];276+ NSArray *headerRightConfigs = config.headerRightBarButtonItems ?: @[];
239+ NSArray *headerCenterConfigs = config.headerCenterBarButtonItems ?: @[];277+ NSArray *headerCenterConfigs = config.headerCenterBarButtonItems ?: @[];
240+ NSArray<UIBarButtonItem *> *subviewLeftItems = navitem.leftBarButtonItems ?: @[];278+ // Retain the config in the key so its address cannot be reused while cached.
241+ NSArray<UIBarButtonItem *> *subviewRightItems = navitem.rightBarButtonItems ?: @[];279+ // Items capture this config's event emitter in their press handlers, so a
242+ // The key includes the config instance's identity: cached items capture280+ // remounted header-config view with value-equal configs must still rebuild
243+ // this config's event emitter in their press handlers, so a remounted281+ // instead of dispatching presses into the old config's emitter.
244+ // header-config view with value-equal configs must still rebuild — reusing282+ // getUIBarButtonItem is stable for the lifetime of its React header
245+ // the old items would dispatch presses into the dead config's emitter.283+ // subview. Include those native identities in the key so React-backed
246+ NSArray *headerItemsKey =284+ // items can use the same cache without reusing a group after its view was
247+ @[ @((uintptr_t)config), headerLeftConfigs, headerRightConfigs, headerCenterConfigs ];285+ // replaced.
286+ NSArray *headerItemsKey = @[
287+ config,
288+ headerLeftConfigs,
289+ headerRightConfigs,
290+ headerCenterConfigs,
291+ subviewLeftItems,
292+ subviewRightItems,
293+ ];
248+ // Rebuilding bar button items creates brand-new native buttons (glass294+ // Rebuilding bar button items creates brand-new native buttons (glass
249+ // UIButton custom views on iOS 26). Replacing them while UIKit animates an295+ // UIButton custom views on iOS 26). Replacing them while UIKit animates an
250+ // existing one (menu capsule morph, push/pop glass transitions) strands the296+ // existing one (menu capsule morph, push/pop glass transitions) strands the
251+ // animation overlay — a stuck expanded capsule or an unmasked square back297+ // animation overlay — a stuck expanded capsule or an unmasked square back
252+ // button. When the JS configs are unchanged, keep the already-applied items.298+ // button. When both the JS configs and React-backed item identities are
253+ // Subview-backed items are re-derived every pass, so their presence forces299+ // unchanged, keep the already-applied item groups. Item groups are only
254+ // the rebuild path.300+ // available from iOS 16, so older platforms keep the legacy rebuild path.
255+ BOOL reuseHeaderBarButtonItems = subviewLeftItems.count == 0 && subviewRightItems.count == 0 &&301+ BOOL canReuseHeaderBarButtonItems = NO;
302+#if !TARGET_OS_TV
303+ if (@available(iOS 16.0, *)) {
304+ canReuseHeaderBarButtonItems = YES;
305+ }
306+#endif
307+ BOOL reuseHeaderBarButtonItems = canReuseHeaderBarButtonItems &&
256+ [objc_getAssociatedObject(navitem, &RNSAppliedHeaderBarButtonConfigsKey) isEqual:headerItemsKey];308+ [objc_getAssociatedObject(navitem, &RNSAppliedHeaderBarButtonConfigsKey) isEqual:headerItemsKey];
257+ if (!reuseHeaderBarButtonItems) {309+ if (!reuseHeaderBarButtonItems) {
258+ NSArray<UIBarButtonItem *> *leftBarButtonItems = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems310+ NSArray<UIBarButtonItem *> *leftBarButtonItems = [config barButtonItemsFromConfigs:config.headerLeftBarButtonItems
259+ withCurrentItems:navitem.leftBarButtonItems311+ withCurrentItems:subviewLeftItems
260+ navigationItem:navitem];312+ navigationItem:navitem];
261+ NSArray<UIBarButtonItem *> *rightBarButtonItems = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems313+ NSArray<UIBarButtonItem *> *rightBarButtonItems = [config barButtonItemsFromConfigs:config.headerRightBarButtonItems
262+ withCurrentItems:navitem.rightBarButtonItems314+ withCurrentItems:subviewRightItems
263+ navigationItem:navitem];315+ navigationItem:navitem];
264+ NSArray<UIBarButtonItem *> *centerBarButtonItems = [config barButtonItemsFromConfigs:config.headerCenterBarButtonItems316+ NSArray<UIBarButtonItem *> *centerBarButtonItems = [config barButtonItemsFromConfigs:config.headerCenterBarButtonItems
265+ withCurrentItems:@[]317+ withCurrentItems:@[]
...@@ -271,8 +323,6 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -271,8 +323,6 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
271+ if (@available(iOS 26.0, *)) {323+ if (@available(iOS 26.0, *)) {
272+ navitem.centerItemGroups = [config barButtonItemGroupsFromItems:centerBarButtonItems];324+ navitem.centerItemGroups = [config barButtonItemGroupsFromItems:centerBarButtonItems];
273+ }325+ }
274+ navitem.leftBarButtonItems = nil;
275+ navitem.rightBarButtonItems = nil;
276+ } else {326+ } else {
277+ navitem.leftBarButtonItems = leftBarButtonItems;327+ navitem.leftBarButtonItems = leftBarButtonItems;
278+ navitem.rightBarButtonItems = rightBarButtonItems;328+ navitem.rightBarButtonItems = rightBarButtonItems;
...@@ -281,13 +331,10 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -281,13 +331,10 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
281+ navitem.leftBarButtonItems = leftBarButtonItems;331+ navitem.leftBarButtonItems = leftBarButtonItems;
282+ navitem.rightBarButtonItems = rightBarButtonItems;332+ navitem.rightBarButtonItems = rightBarButtonItems;
283+#endif333+#endif
284+ // Only dict-driven items can be reused: with subview-backed items in the
285+ // mix the applied state depends on view identity, so clear the key to
286+ // force a rebuild on the next pass.
287+ objc_setAssociatedObject(334+ objc_setAssociatedObject(
288+ navitem,335+ navitem,
289+ &RNSAppliedHeaderBarButtonConfigsKey,336+ &RNSAppliedHeaderBarButtonConfigsKey,
290+ subviewLeftItems.count == 0 && subviewRightItems.count == 0 ? headerItemsKey : nil,337+ headerItemsKey,
291+ OBJC_ASSOCIATION_RETAIN_NONATOMIC);338+ OBJC_ASSOCIATION_RETAIN_NONATOMIC);
292+ }339+ }
293+ NSDictionary<NSString *, id> *mailSearchToolbarConfig = nil;340+ NSDictionary<NSString *, id> *mailSearchToolbarConfig = nil;
...@@ -689,7 +736,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -689,7 +736,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
689 736
690 // Setting navigation bar visibility is split to mitigate iOS 26 bug with bar button items737 // Setting navigation bar visibility is split to mitigate iOS 26 bug with bar button items
691 // (setting nav bar visibility should be done after `navitem.*BarButtonItems`).738 // (setting nav bar visibility should be done after `navitem.*BarButtonItems`).
692@@ -773,6 +1259,7 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *739@@ -773,6 +1262,7 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *
693 740
694 - (NSArray<UIBarButtonItem *> *)barButtonItemsFromConfigs:(NSArray<NSDictionary<NSString *, id> *> *)dicts741 - (NSArray<UIBarButtonItem *> *)barButtonItemsFromConfigs:(NSArray<NSDictionary<NSString *, id> *> *)dicts
695 withCurrentItems:(NSArray<UIBarButtonItem *> *)currentItems742 withCurrentItems:(NSArray<UIBarButtonItem *> *)currentItems
...@@ -697,7 +744,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -697,7 +744,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
697 {744 {
698 if (dicts.count == 0) {745 if (dicts.count == 0) {
699 return currentItems;746 return currentItems;
700@@ -781,7 +1268,197 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *747@@ -781,7 +1271,197 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *
701 [items addObjectsFromArray:currentItems];748 [items addObjectsFromArray:currentItems];
702 for (NSUInteger i = 0; i < dicts.count; i++) {749 for (NSUInteger i = 0; i < dicts.count; i++) {
703 NSDictionary *dict = dicts[i];750 NSDictionary *dict = dicts[i];
...@@ -896,7 +943,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -896,7 +943,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
896 RNSBarButtonItem *item = [[RNSBarButtonItem alloc] initWithConfig:dict943 RNSBarButtonItem *item = [[RNSBarButtonItem alloc] initWithConfig:dict
897 action:^(NSString *buttonId) {944 action:^(NSString *buttonId) {
898 auto eventEmitter = std::static_pointer_cast<const facebook::react::RNSScreenStackHeaderConfigEventEmitter>(945 auto eventEmitter = std::static_pointer_cast<const facebook::react::RNSScreenStackHeaderConfigEventEmitter>(
899@@ -803,19 +1480,23 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *946@@ -803,19 +1483,23 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *
900 }947 }
901 imageLoader:_imageLoader];948 imageLoader:_imageLoader];
902 NSNumber *index = dict[@"index"];949 NSNumber *index = dict[@"index"];
...@@ -926,7 +973,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -926,7 +973,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
926 [items insertObject:item atIndex:index.integerValue];973 [items insertObject:item atIndex:index.integerValue];
927 } else {974 } else {
928 [items addObject:item];975 [items addObject:item];
929@@ -825,6 +1506,47 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *976@@ -825,6 +1509,47 @@ - (void)applySemanticContentAttributeIfNeededToNavCtrl:(UINavigationController *
930 return items;977 return items;
931 }978 }
932 979
...@@ -974,7 +1021,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -974,7 +1021,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
974 RNS_IGNORE_SUPER_CALL_BEGIN1021 RNS_IGNORE_SUPER_CALL_BEGIN
975 - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex1022 - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex
976 {1023 {
977@@ -1013,6 +1735,8 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::1024@@ -1013,6 +1738,8 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
978 }1025 }
979 1026
980 _title = RCTNSStringFromStringNilIfEmpty(newScreenProps.title);1027 _title = RCTNSStringFromStringNilIfEmpty(newScreenProps.title);
...@@ -983,7 +1030,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -983,7 +1030,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
983 if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) {1030 if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) {
984 _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily);1031 _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily);
985 }1032 }
986@@ -1038,6 +1762,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::1033@@ -1038,6 +1765,7 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
987 _disableBackButtonMenu = newScreenProps.disableBackButtonMenu;1034 _disableBackButtonMenu = newScreenProps.disableBackButtonMenu;
988 _backButtonDisplayMode =1035 _backButtonDisplayMode =
989 [RNSConvert UINavigationItemBackButtonDisplayModeFromCppEquivalent:newScreenProps.backButtonDisplayMode];1036 [RNSConvert UINavigationItemBackButtonDisplayModeFromCppEquivalent:newScreenProps.backButtonDisplayMode];
...@@ -991,7 +1038,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21...@@ -991,7 +1038,7 @@ index 5970e3e3a624b9498b8dedfc16831df03a274d0c..5ebff085788d813f1139eb6f9129fb21
991 1038
992 if (newScreenProps.userInterfaceStyle != oldScreenProps.userInterfaceStyle) {1039 if (newScreenProps.userInterfaceStyle != oldScreenProps.userInterfaceStyle) {
993 _userInterfaceStyle = [RNSConvert UIUserInterfaceStyleFromCppEquivalent:newScreenProps.userInterfaceStyle];1040 _userInterfaceStyle = [RNSConvert UIUserInterfaceStyleFromCppEquivalent:newScreenProps.userInterfaceStyle];
994@@ -1084,6 +1809,30 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::1041@@ -1084,6 +1812,30 @@ - (void)updateProps:(react::Props::Shared const &)props oldProps:(react::Props::
995 _headerRightBarButtonItems = array;1042 _headerRightBarButtonItems = array;
996 }1043 }
997 1044
pnpm-lock.yaml+7-7
...@@ -94,7 +94,7 @@ patchedDependencies:...@@ -94,7 +94,7 @@ patchedDependencies:
94 react-native-gesture-handler@2.31.2: 808eb26f9e57cf4945efd3985af4d9c764da6f91f4c9764433cc868602bbf4d394 react-native-gesture-handler@2.31.2: 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.25.2: 59bfd7b84af01708b6e581c4ccdd5ecf05f8b205383802d66b64ed7ea7bb219997 react-native-screens@4.25.2: b3d86ac8bf77b40f4112672f92225853bce6faca485a4aeb609a07a70162a5cc
9898
99importers:99importers:
100100
...@@ -413,7 +413,7 @@ importers:...@@ -413,7 +413,7 @@ importers:
413 version: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)413 version: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
414 react-native-screens:414 react-native-screens:
415 specifier: 4.25.2415 specifier: 4.25.2
416 version: 4.25.2(patch_hash=59bfd7b84af01708b6e581c4ccdd5ecf05f8b205383802d66b64ed7ea7bb2199)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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: 4.25.2(patch_hash=b3d86ac8bf77b40f4112672f92225853bce6faca485a4aeb609a07a70162a5cc)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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-shiki-engine:417 react-native-shiki-engine:
418 specifier: ^0.3.12418 specifier: ^0.3.12
419 version: 0.3.12(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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: 0.3.12(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
...@@ -14273,7 +14273,7 @@ snapshots:...@@ -14273,7 +14273,7 @@ snapshots:
14273 react: 19.2.314273 react: 19.2.3
14274 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)14274 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
14275 react-native-safe-area-context: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)14275 react-native-safe-area-context: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
14276 react-native-screens: 4.25.2(patch_hash=59bfd7b84af01708b6e581c4ccdd5ecf05f8b205383802d66b64ed7ea7bb2199)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)14276 react-native-screens: 4.25.2(patch_hash=b3d86ac8bf77b40f4112672f92225853bce6faca485a4aeb609a07a70162a5cc)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
14277 sf-symbols-typescript: 2.2.014277 sf-symbols-typescript: 2.2.0
14278 warn-once: 0.1.114278 warn-once: 0.1.1
14279 transitivePeerDependencies:14279 transitivePeerDependencies:
...@@ -17090,7 +17090,7 @@ snapshots:...@@ -17090,7 +17090,7 @@ snapshots:
17090 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6)17090 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6)
17091 react-native-drawer-layout: 4.2.4(de9b2f2dc96a3557fdc0df187a8417ee)17091 react-native-drawer-layout: 4.2.4(de9b2f2dc96a3557fdc0df187a8417ee)
17092 react-native-safe-area-context: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6))(react@19.2.6)17092 react-native-safe-area-context: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6))(react@19.2.6)
17093 react-native-screens: 4.25.2(patch_hash=59bfd7b84af01708b6e581c4ccdd5ecf05f8b205383802d66b64ed7ea7bb2199)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6))(react@19.2.6)17093 react-native-screens: 4.25.2(patch_hash=b3d86ac8bf77b40f4112672f92225853bce6faca485a4aeb609a07a70162a5cc)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6))(react@19.2.6)
17094 server-only: 0.0.117094 server-only: 0.0.1
17095 sf-symbols-typescript: 2.2.017095 sf-symbols-typescript: 2.2.0
17096 shallowequal: 1.1.017096 shallowequal: 1.1.0
...@@ -17141,7 +17141,7 @@ snapshots:...@@ -17141,7 +17141,7 @@ snapshots:
17141 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)17141 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
17142 react-native-drawer-layout: 4.2.4(05364bd849de538917a7364cc7dee3f5)17142 react-native-drawer-layout: 4.2.4(05364bd849de538917a7364cc7dee3f5)
17143 react-native-safe-area-context: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)17143 react-native-safe-area-context: 5.7.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
17144 react-native-screens: 4.25.2(patch_hash=59bfd7b84af01708b6e581c4ccdd5ecf05f8b205383802d66b64ed7ea7bb2199)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)17144 react-native-screens: 4.25.2(patch_hash=b3d86ac8bf77b40f4112672f92225853bce6faca485a4aeb609a07a70162a5cc)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
17145 server-only: 0.0.117145 server-only: 0.0.1
17146 sf-symbols-typescript: 2.2.017146 sf-symbols-typescript: 2.2.0
17147 shallowequal: 1.1.017147 shallowequal: 1.1.0
...@@ -19956,14 +19956,14 @@ snapshots:...@@ -19956,14 +19956,14 @@ snapshots:
19956 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6)19956 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6)
19957 optional: true19957 optional: true
1995819958
19959 react-native-screens@4.25.2(patch_hash=59bfd7b84af01708b6e581c4ccdd5ecf05f8b205383802d66b64ed7ea7bb2199)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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):19959 react-native-screens@4.25.2(patch_hash=b3d86ac8bf77b40f4112672f92225853bce6faca485a4aeb609a07a70162a5cc)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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):
19960 dependencies:19960 dependencies:
19961 react: 19.2.319961 react: 19.2.3
19962 react-freeze: 1.0.4(react@19.2.3)19962 react-freeze: 1.0.4(react@19.2.3)
19963 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)19963 react-native: 0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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)
19964 warn-once: 0.1.119964 warn-once: 0.1.1
1996519965
19966 react-native-screens@4.25.2(patch_hash=59bfd7b84af01708b6e581c4ccdd5ecf05f8b205383802d66b64ed7ea7bb2199)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6))(react@19.2.6):19966 react-native-screens@4.25.2(patch_hash=b3d86ac8bf77b40f4112672f92225853bce6faca485a4aeb609a07a70162a5cc)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.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.6)(utf-8-validate@6.0.6))(react@19.2.6):
19967 dependencies:19967 dependencies:
19968 react: 19.2.619968 react: 19.2.6
19969 react-freeze: 1.0.4(react@19.2.6)19969 react-freeze: 1.0.4(react@19.2.6)