yarn react-native-screens 4.26.0

4 hours ago

What's Changed

This release brings a stable Tabs API along with numerous fixes, including improved coordination of FormSheet animations and keyboard interaction on Android, and fixed touch handling for Pressables in transparent headers on iOS.

We're also actively working on v5 of the library — this release adds an experimental standalone FormSheet component for both Android and iOS, and extends the menu API of the new Native Stack with several new features.

Note

This version supports React Native 0.84+.

✅ Improvements

  • feat(iOS): Enable synchronous header config shadow state updates by default by @kmichalikk in #3932
  • feat(iOS): Enable synchronous header subview shadow state updates by default by @kmichalikk in #3933
  • feat(iOS): Enable synchronous screen shadow state updates by default by @kmichalikk in #3931
  • feat(Android, Stack v5): add support for header scroll flags by @kligarski in #3908
  • feat(tabs): add 'programmatic-native' actionOrigin variant by @kkafar in #3951
  • feat(tabs): cohesive cross-platform native API + observer registry by @kkafar in #3966
  • feat(Split): add colorScheme by @sgaczol in #3961
  • feat(iOS, FormSheet v5): Add basic setup for standalone FormSheet native component by @t0maboro in #3947
  • feat(iOS, FormSheet v5): Add preferredCornerRadius prop by @t0maboro in #3988
  • feat(iOS, FormSheet v5): Add prefersGrabberVisible prop by @t0maboro in #3987
  • feat(iOS, FormSheet v5): Add largestUndimmedDetentIndex support by @t0maboro in #3992
  • feat(iOS, FormSheet v5): Add support for initialDetentIndex by @t0maboro in #3995
  • feat(iOS, FormSheet v5): Add prefersScrollingExpandsWhenScrolledToEdge support by @t0maboro in #4014
  • feat(iOS, FormSheet v5): Add onDetentChanged event by @t0maboro in #4031
  • feat(Android, Stack v5): ensure StackHeaderCoordinator teardown on Screen fragment destroyed by @kligarski in #4096
  • feat(Android, Stack v5): add toolbar menu items base implementation to header by @kligarski in #3965
  • feat(iOS, FormSheet v5): Introduce PresentationManager for FormSheet component by @t0maboro in #4086
  • feat(iOS, FormSheet v5): Add support for preventNativeDismiss & onNativeDismissPrevented by @t0maboro in #4022
  • feat(Android, Stack v5): expose showAsAction prop for toolbar menu items by @kligarski in #4101
  • feat(iOS, FormSheet v5): Add support for fitToContents by @t0maboro in #4095
  • feat: Implement subviews layout in header for iOS stack v5 by @kmichalikk in #3868
  • feat(iOS, FormSheet v5): Add lifecycle events by @t0maboro in #4123
  • feat(iOS, FormSheet v5): Add support for nativeContainerStyle by @t0maboro in #4122
  • feat(iOS, FormSheet v5): Emit onDismiss event when dismissed from JS by @t0maboro in #4124
  • feat: Initial code for menu in header items by @kmichalikk in #4138
  • feat(Android, Stack v5): toolbar menu item icon and icon tint color by @kligarski in #4105
  • feat(Android, Stack v5): add support for extended tinting and enforce M3 icon size for back button by @kligarski in #4126
  • feat: Handle onPress in iOS Menu by @kmichalikk in #4148
  • feat: Add toggling items with managed flow to menu by @kmichalikk in #4194
  • feat: Rename label and key to title and id in Stack v5 header items by @kmichalikk in #4208
  • feat(iOS, Tabs): integration with ScrollViewMarker by @kkafar in #4191
  • feat(Android, Tabs): integrate with ScrollViewMarker for special effects by @kkafar in #4192
  • feat(Android, Stack v5): add support for nested menus in toolbar menu by @kligarski in #4210
  • feat(Stack v5): Add onPress to Header Item on iOS by @kmichalikk in #4217
  • feat(Android, FormSheet v5): Setup basic structure for standalone FormSheet by @t0maboro in #4189
  • feat(Android, FormSheet v5): Setup TouchHandler on Dialog window by @t0maboro in #4204
  • feat(Android, Stack v4): add disable*InsetApplication props by @sgaczol in #4220
  • feat(Android, Stack, Tabs, SVM): improve nested container integration -> introduce Container & ContainerItem by @kkafar in #4216
  • feat(Android, FormSheet v5): Replace native animations with custom slide+fade by @t0maboro in #4218
  • feat(Android, FormSheet v5): Add support for prefersGrabberVisible by @t0maboro in #4225
  • feat(Android, Stack v5): add support for groups in toolbar menu by @kligarski in #4228
  • feat(Android, Stack v5): add support for disabling menu items by @kligarski in #4236
  • feat(Android, Stack v5): add toolbar menu item text related props by @kligarski in #4234
  • feat(Android, Stack v5): add support for menuTitle (headerTitle) in submenus by @kligarski in #4241
  • feat(iOS, Stack, Tabs): improve nested container integration -> introduce Container & ContainerItem by @kkafar in #4227
  • feat(Android, FormSheet v5): Add support for fractional detents by @t0maboro in #4251
  • feat(iOS, Stack v5): Refactor Stack Header implementation and handle selective updates by @kmichalikk in #4248
  • feat(Stack v5, iOS): Add keepsMenuPresented prop to menuItems by @kmichalikk in #4261
  • feat(Android, FormSheet v5): Handle presentation state updates during transitions by @t0maboro in #4259
  • feat(Android, FormSheet v5): Add support for fitToContents by @t0maboro in #4267
  • feat(iOS, Tabs): add bottomAccessoryHidden prop by @kligarski in #4291
  • feat(Tabs): mark Tabs API as stable by @kkafar in #4296

🐞 Bugfixes

  • fix(Android, FormSheet): Prevent BottomSheetBehavior override when using FormSheets by @t0maboro in #3912
  • fix(Android, FormSheet): Create SheetAnimationCoordinator to synchronize animations coming from different sources by @t0maboro in #3914
  • fix(Android, FormSheet): Prioritize keyboard animation over content resize animation by @t0maboro in #3924
  • fix(Android, Stack v5): prevent crash when subview with (0, 0) size is added to small header by @kligarski in #3927
  • fix(iOS): unregister tabs accessory observer from observed wrapper by @safaiyeh in #3948
  • fix(web, SafeAreaView): replace default export with named export by @roryabraham in #3956
  • fix(iOS, Tabs): fix moreNavigationController navigation bar visible on nav by @kkafar in #3993
  • fix(iOS, Tabs): correctly pass action origin to progressNavigationState by @kkafar in #3994
  • fix(Android, Tabs): propagate actionOrigin into navigation state progression by @kkafar in #3996
  • fix(iOS): forward-declare RCTSurfaceTouchHandler in UIView+RNSUtility.h by @zhe-qi in #3986
  • fix(iOS, Tabs): register navigation state observer outside RCTAssert by @kkafar in #4004
  • fix: add web fallback for ScrollViewMarker by @satya164 in #4008
  • fix(Android, FormSheet): dismiss form sheet only on ACTION_UP to prevent double-back by @t0maboro in #4034
  • fix(Android, Tabs): handle Tabs reattachment to window by @kligarski in #4035
  • fix(iOS, SplitView): Fix SplitView crash on assertion when maxWidth wasn't defined for column by @t0maboro in #4068
  • fix(Android, FormSheet): include keyboard translationY in shadow update by @jiroscripts in #4065
  • fix(iOS, FormSheet v5): Fix symbols for FormSheet with disabled gamma by @t0maboro in #4071
  • fix(Android, Tabs): trigger appearance update on user tab selection by @kkafar in #4075
  • fix(Android, Stack v5): change header subview type to render callback by @kligarski in #4079
  • fix(iOS): remove FormSheet scroll view KVO observer synchronously on invalidate by @phewphewb in #4091
  • fix(Android): fix translucent header first layout correction by @sorinc03 in #4116
  • fix(iOS, Tabs): weak-capture tab bar item and screen view in async image callbacks by @cortinico in #4111
  • fix(Tabs): re-export TabSelectionPreventedEvent from package root by @Ubax in #4142
  • fix(Android): use per-display density for px→dp conversion in FabricEnabledViewGroup.updateState by @ziponia in #4160
  • fix(Android): route all px→dp Shadow Tree state pushes through per-display density by @kkafar in #4169
  • fix(iOS, Tabs): remove invalidate call in RNSTabsBottomAccessoryComponentView.didMoveToWindow by @sgaczol in #4155
  • fix(Android): drive ScreenFooter keyboard insets from the sheet, not the decor view by @stachbial in #4149
  • fix(Android, Tabs): fix flickering tab bar height & contents when entering on ScreenStackFragment by @kkafar in #4161
  • fix(FabricExample, FormSheet v5): Fix stacking FormSheets by @t0maboro in #4016
  • fix(Android, Stack, Tabs): fix crash on simple navigation with stack nested in tabs by @kkafar in #4202
  • fix(Android, Stack v5): set needsCustomLayoutForChildren to true for StackHost by @kligarski in #4200
  • fix(Android, FormSheet v5): Fix fast refresh inside Dialog window by @t0maboro in #4221
  • fix(Android, FormSheet v5): Precalculate react's content space for sheet by @t0maboro in #4219
  • fix(Android): handle nullable Fresco bitmap by @cortinico in #4242
  • fix(Android, FormSheet v4): Prevent FormSheet over-translation on keyboard appear in nested containers by @t0maboro in #4240
  • fix(iOS, TabsBottomAccessory): use hidden instead of opacity to switch bottom accessory content views by @sgaczol in #4196
  • fix(Android, Tabs): prevent crash on appearance change after remount when detached from window by @kligarski in #4271
  • fix(Android): prevent Fresco recycled bitmap crash in ImageLoader by copying the bitmap by @kligarski in #4274
  • fix(Android, FormSheet v4): refine keyboard avoidance to prevent layout reflows with SafeAreaView by @t0maboro in #4244
  • fix(Android): prevent Fabric layout updates from resurrecting header subviews hidden by an expanded search bar by @Dwynr in #4264
  • fix(Android, Tabs): handle platform color in tabs appearance props by @kligarski in #4284
  • fix(iOS, Stack v4): fix header positioning in shadow tree by @kligarski in #4286
  • fix(iOS): hide react symbols from swift by @radoslawrolka in #4224

🔢 Misc

  • chore(CI): refine dry-run description and disable action git ops by @kkafar in #3917
  • docs(Android, Stack v5): add missing docs to StackHeaderConfig by @kligarski in #3897
  • chore(types): remove nullability from some children props in unstable/experimental components by @kligarski in #3918
  • chore(test): scenario for prevent native selection by @LKuchno in #3911
  • refactor(Android, FormSheet): Minor cleanups in SheetAnimationCoordinator by @t0maboro in #3921
  • refactor(Android, FormSheet): Align animators implementation to use ValueAnimator by @t0maboro in #3922
  • chore(release): set main sentinel version and guard stable publishes by @kkafar in #3923
  • chore(examples): bump ios podfile.lock files after rnscreens version bump by @kkafar in #3929
  • refactor(test): Changing android emulator for e2e workflow from pixel_2 to pixel_9 by @LKuchno in #3926
  • chore(AI): upstream Claude.md by @kkafar in #3930
  • docs(agents): add build & run section, list TVOSExample by @kkafar in #3941
  • fix(FabricExample): Add insets handling to prevent rendering toast behind navigation bar by @t0maboro in #3942
  • fix(FabricExample): Wrap some components with SAV to prevent hiding behind navigation bar by @t0maboro in #3944
  • refactor(tabs): rename TabsHost navState prop to navStateRequest by @kkafar in #3943
  • chore(test): new screen and scenario for specialEffects: scrollToTop prop by @LKuchno in #3934
  • refactor(tabs): replace isNativeAction with actionOrigin enum by @kkafar in #3949
  • refactor(tabs): split native nav state into state and update request by @kkafar in #3950
  • chore(test): e2e and scenario for tabs specialEffects scrollToTop by @LKuchno in #3953
  • refactor(Example): TabsContainer and StackContainer refactor by @sgaczol in #3925
  • chore(example): use prebuilt React Native for iOS on CI in FabricExample by @radoslawrolka in #3955
  • chore(examples): Apply RNRepo to FabricExample by @radoslawrolka in #3963
  • refactor(tests): test-tabs-tab-bar-more-navigation-controller + scenario by @LKuchno in #3861
  • chore(test): test-tabs-tab-bar-experimental-user-interface-style-ios with scenario by @LKuchno in #3881
  • refactor(test): add scenario for overrideScrollViewContentInsetAdjustmentBehavior (iOS) by @LKuchno in #3957
  • refactor(test): adding TestTabsTabBarExperimentalUserInterfaceStyle to index file by @LKuchno in #3971
  • chore: Bump clang-format to 22 by @t0maboro in #3972
  • chore(test): add e2e tests for overrideScrollViewContentInsetAdjustmentBehavior (iOS) by @LKuchno in #3960
  • chore(test): e2e test-tabs-tab-bar-layout-direction by @LKuchno in #3899
  • refactor(test): change screen and add scenario for tabs bottomAccessory (iOS) by @LKuchno in #3964
  • chore(example): use prebuilt ReactNativeDependencies by default by @radoslawrolka in #3978
  • chore: Enable gamma for TVOS builds on CI by @t0maboro in #3981
  • refactor(tabs): rename rejectedProvenance to rejectedBaseProvenance by @kkafar in #3982
  • chore: fix opt-out comment of RNRepo by @radoslawrolka in #3975
  • refactor: clean-up code related to feature flags by @sgaczol in #3901
  • fix(Examples): Wrap only selection screen with SAV instead of all examples by @t0maboro in #3991
  • refactor(test): update Android API level label and rename moreNavigationController scenario to iOS-specific by @LKuchno in #4005
  • chore(Example): add SVM to SFT scenario groups by @kligarski in #4018
  • chore(test): test-tabs-events screen with scenario by @LKuchno in #3936
  • refactor(test): fix scroll-to-top e2e test on Android by @LKuchno in #4017
  • refactor(test): emulator set to pixel 8 by @LKuchno in #4024
  • refactor(test): add scenario.md and restructure stale update rejection test by @LKuchno in #4019
  • chore(test): e2e tests for stale update rejection by @LKuchno in #4023
  • chore(deps): aggregate dependabot updates by @kkafar in #4032
  • chore(test): e2e test-tabs-lifecycle-events by @LKuchno in #3937
  • chore(test): E2E test-tabs-prevent-native-selection by @LKuchno in #3928
  • refactor(test): update afterAll for e2e test-tabs-tab-bar-layout-direction by @LKuchno in #4033
  • chore(iOS, Tabs): remove legacy architecture related code by @sgaczol in #4007
  • chore(iOS, Tabs): make properties readonly in Tabs on iOS side by @sgaczol in #4042
  • refactor(iOS, FormSheet v5): Move detents resolving to dedicated class by @t0maboro in #4038
  • refactor(iOS, FormSheet v5): Prepare AppearanceCoordinator logic by @t0maboro in #4039
  • refactor(iOS, FormSheet v5): Introduce AppearanceApplicator by @t0maboro in #4040
  • refactor(iOS, FormSheet v5): Rename protocol to RNSFormSheetContentControllerDelegate by @t0maboro in #4060
  • refactor(iOS, FormSheet v5): Move presentation logic from HostView to ContentController by @t0maboro in #4041
  • chore: Udpate prefersScrollingExpandsWhenScrolledToEdge scenario description by @t0maboro in #4063
  • refactor(docs): Update documentation of scrollEdgeAppearance for TabsScreenAppearanceIOS by @LKuchno in #4045
  • chore(test): add e2e tests for tabs bottomAccessory on iOS by @LKuchno in #3976
  • refactor(test): updates screen and scenario for test-tabs-tab-bar-layout-direction to include specific behaviors and edge-cases by @LKuchno in #4057
  • chore(iOS): remove guards regarding RN < 0.82 version by @sgaczol in #4062
  • chore(Example): ScenarioDescription refactor by @sgaczol in #4059
  • chore(Example): remove default exports from scenario-description.ts files by @sgaczol in #4080
  • refactor(iOS, FormSheet v5): Move AppearanceCoordinator/Applicator to ContentController by @t0maboro in #4074
  • chore(tabs): add tab-item-title appearance scenario for iOS by @LKuchno in #4083
  • chore(iOS): remove legacy architecture related code - misc by @sgaczol in #4061
  • refactor(test): expand e2e coverage for tab bar layout direction by @LKuchno in #4072
  • chore(Example): Turn apps/ into a separate module by @sgaczol in #4052
  • chore: add typescript configuration files to scripts directory by @sgaczol in #4093
  • chore: include apps directory in format-js script by @sgaczol in #4082
  • refactor(iOS, FormSheet v5): Separate Behavior and Appearance by @t0maboro in #4084
  • chore: Pull latest react-navigation@7.x by @t0maboro in #4097
  • chore(iOS): update library build code by @sgaczol in #4094
  • docs: expand contributing guide by @kkafar in #4028
  • chore: fix ios build for FabricExample by @satya164 in #4020
  • chore(readme): add readme banners by @p-malecki in #4112
  • chore: Fix readme banner redirect URL by @p-malecki in #4119
  • chore: remove Paper and unsupported RN versions leftovers by @sgaczol in #4110
  • chore(tests): add checkmark script for tests by @sgaczol in #4087
  • refactor(test): update test-tabs-ime-insets name and create scenario for it by @LKuchno in #4109
  • refactor(docs): update systemitem type documentation by @LKuchno in #4121
  • refactor(test): Update scenario-description and scenario files for existing tabs and formsheet tests by @LKuchno in #4092
  • chore(test): test-tabs-item-title appearance scenario by @LKuchno in #4106
  • chore(docs): remove banner rotator by @p-malecki in #4129
  • chore: Remove redundant scenarioDescription from iOS header items test by @kmichalikk in #4136
  • chore: Separate header item building from HeaderItem(Spacer)ComponentView by @kmichalikk in #4135
  • chore(test): add test-tabs-system-item-ios scenario by @LKuchno in #4120
  • chore: add RNS_USE_CXXBRIDGE to compile out legacy code by @kligarski in #4143
  • chore(test): add iOS 18 tab bar general appearance scenario by @LKuchno in #3997
  • chore: bump lib and example apps to react-native@0.86.0 by @kligarski in #4125
  • chore(test): test-tabs-native-container-style test screen with scenario by @LKuchno in #4134
  • fix(Example): add ESLint rule to enforce top-level component exports in SFT and CIT by @sgaczol in #3959
  • chore(test): add e2e test for test-tabs-system-item-ios scenario by @LKuchno in #4147
  • chore: exclude local agent configuration from repo by @kkafar in #4166
  • chore(deps): aggregate dependabot updates by @kkafar in #4167
  • chore(Tabs, iOS): add test-tabs-layout-appearances-ios screen and scenario by @LKuchno in #4085
  • chore(test): add test-tabs-item-icon appearance scenario by @LKuchno in #4108
  • refactor(test): remove "Expected:" prefix from scenario step assertions by @LKuchno in #4172
  • chore(test): e2e test-tabs-ime-insets-android by @LKuchno in #4154
  • chore(test): add test-tabs-general-appearance-android scenario by @LKuchno in #4118
  • chore(test): test-tabs-item-badge test screen with scenario by @LKuchno in #4128
  • docs: add dynamic topbar banner by @p-malecki in #4177
  • chore(test): e2e: test-tabs-item-badge by @LKuchno in #4170
  • refactor(test): test files formatting fix by @LKuchno in #4178
  • chore(test): add @smoke tag to tabs e2e test suites by @LKuchno in #4173
  • chore(deps): aggregate dependabot updates by @kkafar in #4185
  • refactor(CI, Android): bust AVD cache when emulator profile changes by @LKuchno in #4188
  • refactor(test): align tabs test structure with rules from rfc by @LKuchno in #4180
  • chore: follow-up with review cleanup for #4202 by @kkafar in #4205
  • refactor(Android, Stack v5): separate React and native domains in header implementation by @kligarski in #4150
  • chore(Android, Stack v5): update showAsAction test with icon configuration by @kligarski in #4198
  • chore: Replace useEffect with useLayoutEffect in header items test by @kmichalikk in #4213
  • fix(CI): add brew trust for installing Applesimutils in iOS e2e workflow by @kligarski in #4214
  • chore(test): e2e test for test-tabs-general-appearance-android by @LKuchno in #4158
  • refactor(test): export test components for direct importing by @LKuchno in #4201
  • refactor(test): test-tabs-appearance-defined-by-selected-tab by @LKuchno in #4179
  • refactor(iOS, Tabs): extract controller mounting infrastructure to shared utils by @kkafar in #4230
  • refactor(test): test-tabs-simple-nav: e2e test and scenario by @LKuchno in #4165
  • refactor(iOS, Stack): use RNSContainerHelpers for controller mounting by @kkafar in #4231
  • refactor(iOS, Split): use RNSContainerHelpers for controller mounting by @kkafar in #4232
  • refactor(Android, FormSheet v5): Add EventEmitter for FormSheetHost by @t0maboro in #4222
  • chore(deps): aggregate dependabot updates by @kkafar in #4235
  • refactor(Android, FormSheet v5): Decouple FormSheetDialogManager from React's FormSheetContentView by @t0maboro in #4226
  • refactor(test, iOS): resolve Detox simulator target so device name and OS version stay in sync by @LKuchno in #4195
  • chore(test): Add e2e test for SVM in stack & tabs with special effects by @LKuchno in #4229
  • refactor(test): improve Android emulator device resolution logic by @LKuchno in #4246
  • chore(Android): make ImageLoader onLoaded's result nullable by @kligarski in #4247
  • chore(test): Add iPad e2e coverage for tabBarControllerMode by @LKuchno in #4212
  • refactor(test): e2e test: tab-bar-hidden implementation for iPad by @LKuchno in #4233
  • chore(Examples): Drop local eslint plugin by @t0maboro in #4260
  • refactor(Android, FormSheet v5): Extract FormSheetLifecycleCoordinator for cleaner dialog event handling by @t0maboro in #4252
  • refactor(Android, FormSheet v5): Separate layout management for FormSheet by @t0maboro in #4256
  • refactor(test): align toolbar-menu test screen naming (scenario-description, StackHeaderToolbarMenuElementOptionsAndroid) by @LKuchno in #4269
  • refactor(test): e2e ipad test for preventNativeSelection by @LKuchno in #4239
  • refactor(Android, FormSheet v5): Introduce invalidation flags for updates by @t0maboro in #4262
  • chore(Android): Remove explicit versions setting in build.gradle by @m-bert in #4146
  • chore(test): Add iPad e2e coverage for tabs bottomAccessory layout by @LKuchno in #4255
  • chore(test): Strip all whitespace from scenarioGroup in single-feature-tests helpers by @LKuchno in #4293
  • chore: bump minimal supported RN version to 0.84 by @kkafar in #4302
  • chore: udpate libs lock file after min. RN version bump by @kkafar in #4303
  • chore(deps): aggregate dependabot updates by @kkafar in #4297
  • release: 4.26.0 by @kligarski in #4304

New Contributors

Full Changelog: 4.25.2...4.26.0

Don't miss a new react-native-screens release

NewReleases is sending notifications on new releases.