github software-mansion/react-native-screens 5.0.0-alpha.4

pre-release4 hours ago

What's Changed

This is the fourth alpha release of react-native-screens 5.0.0. Tabs on iOS 26.1+ now use the UITab API, which brings UISearchTab with automaticallyActivatesSearch, prominentScreenKey and tabBarSidebarPreferredPlacement for iOS 27, along with a series of fixes for tabs that overflow into More; both platforms also gain custom drawable / symbol tab-bar icons. Stack v5 header items on iOS get visibilityPriority, menuRepresentation, variant and disabled, and the navigation bar's minimization on scroll can now be controlled with minimizationBehavior and restorationBehavior. On Android, Stack v5 detaches covered screens so both screens animate during a transition and handles the direction prop, and fragment restoration is now R8-safe. Stack v4 on iOS 26+ lays out screens under an opaque navigation bar and gains unstable_safeAreaEdges, and the broken types published for tabs and the stack header config are fixed.


iOS 26+: opaque headers in native stack (iOS)

Starting with iOS 26, Apple recommends against custom navigation bar backgrounds. Bars are transparent by default and content is meant to extend under them - see WWDC25: Build a UIKit app with the new design. Opaque headers (headerTransparent: false) aren't deprecated, but UIKit's support for them is getting worse:

  • On iOS 26, edgesForExtendedLayout (which we used to lay out the screen below an opaque header) doesn't position the screen correctly in landscape and in modals. We partially worked around this with a SafeAreaView (#3231).
  • On iPhone Duo (iOS 27) the same problem affects regular screens in portrait. The screen ended up partially under the header. Additionally, changes to internal hierarchy of the header introduced new bugs related to Pressables.
  • An opaque header's background doesn't reach the top of the screen and leaves a strip above it. When this was reported on the Apple Developer Forums, Apple didn't treat it as a bug and pointed to the guidance against custom bar backgrounds instead.

Tip

We recommend following Apple's guidance and using a transparent header on iOS 26+.

✅ Improvements

  • feat(TVOS): add disableDefaultMenuAction prop for opting out automatic screen pop by @kacperzolkiewski in #4665
  • feat(iOS, Tabs): add tabBarSidebarPreferredPlacement prop to choose between sidebar and tab bar on iOS 27 by @Loloekk in #4668
  • feat(Android, Stack v5): handle direction prop and improve RTL collapsing header workaround by @kligarski in #4611
  • feat(Android, Stack v5): detach covered screens by @kligarski in #4633
  • feat(iOS, Tabs): Migrate to UITab API for iOS >= 26.1 by @kmichalikk in #4675
  • feat(iOS, Stack v4): Add visibilityPriority prop to header items by @Loloekk in #4709
  • feat(iOS, Stack v5): add visibilityPriority prop for header items by @Loloekk in #4678
  • feat(iOS, Stack v5): Add menuRepresentation prop to header items by @kmichalikk in #4587
  • feat(iOS, Stack v5): add minimizationBehavior and restorationBehavior to control when the navigation bar minimizes and restores on scroll by @Loloekk in #4703
  • feat(iOS, Stack v5): Add disabled to header items by @kmichalikk in #4620
  • feat(iOS, Stack v5): Add variant prop to header item (plain, prominent) by @kmichalikk in #4621
  • feat(iOS, Tabs): Use UISearchTab with automaticallyActivatesSearch prop by @kmichalikk in #4679
  • feat(Tabs): custom drawable/symbol tab-bar icons — per-slot coloring, per-tab size, indicator sizing, iOS fallback by @stachbial in #4209
  • feat(iOS, Tabs): add prominentScreenKey so a chosen tab stays visible when the tab bar minimizes by @Loloekk in #4724
  • feat(iOS, Stack v4): add unstable_safeAreaEdges prop by @kligarski in #4872
  • feat(iOS, Stack v4): prevent header minimization for opaque header by @kligarski in #4873

🐞 Bug fixes

  • fix(iOS, Tabs): prevent tab bar hidden animation on first render by @kkafar in #4673
  • fix(Android, Tabs): let touches through the strip a hidden tab bar leaves behind by @dyankov91 in #4489
  • fix(iOS, Stack v4): send dismiss event to js when pop animation ends by @kacperzolkiewski in #4714
  • fix(Android, Stack v5): restore valid header collapse state after re-showing the header by @kligarski in #4606
  • fix(Android, Stack v5): add explicitParentProvider to ColorSchemeCoordinator to ensure correct resolution during transition by @kligarski in #4634
  • fix(Android): always emit warn, error and wtf RNSLog levels by @kkafar in #4733
  • fix(Android): make fragment restoration R8-safe by @ngocdevv in #4540
  • fix(Android): don't run header update for a screen detached from its stack by @nsingh-ut in #4498
  • fix(iOS, Stack v4): stop form sheet from resizing a recycled scroll view by @kkafar in #4791
  • fix(Android): don't crash in setupFabric during instance teardown by @kkafar in #4790
  • fix(iOS, Tabs): enforce consistent bottom accessory width by @kligarski in #4792
  • fix(android): restore touch coordinates after covered screens rotate by @savv in #4760
  • fix(Android, Stack v4): remove orphaned fragments when ScreenContainer detaches by @kkafar in #4814
  • fix(iOS, Tabs): Hide "Edit" button in sidebar for UITab API by @kmichalikk in #4804
  • fix(iOS, Tabs): Reorder tab image configuration calls by @kmichalikk in #4813
  • fix(android): prevent legacy and tabs containers from delaying child pressed state by @j-piasecki in #4771
  • fix(iOS, Stack v5): make stack screen a SafeAreaView provider by @Loloekk in #4738
  • fix(iOS, Stack v4): use native screen origin as shadow tree offset by @kkafar in #4725
  • fix(iOS, Tabs): don't drop user selection of UISearchTab on mount transactions by @kkafar in #4862
  • fix: fix broken types being published for tabs host and screen by @satya164 in #4871
  • fix: fix broken types being published for stack header config by @satya164 in #4875
  • fix(iOS, Stack v4): lay out screens under an opaque navigation bar on iOS 26+ by @kligarski in #4757
  • fix(iOS, Stack v4): update header subview positions after navigation bar layout on iOS 26+ by @kligarski in #4758
  • fix(iOS, Stack v4): report minimized header height on iOS 27+ via useHeaderHeight by @kligarski in #4734
  • fix(iOS, Tabs): apply async-loaded icons to tabs that overflow into More on the UITab path by @t0maboro in #4889
  • fix(iOS, Tabs): filter UIKit's didSelectTab: for programmatic selection while More is active by @t0maboro in #4890

🔢 Misc

  • chore(iOS, FabricExample): use scene lifecycle by default by @kligarski in #4676
  • chore(test): split e2e-utils into framework/app helper tiers behind @e2e alias by @LKuchno in #4635
  • chore(iOS, TVOSExample): use scene lifecycle by default by @kligarski in #4710
  • refactor(Android, Stack v5): move invalidation flags to native implementation by @kligarski in #4599
  • chore(test): mark stack-v5 and form-sheet scenarios as smoke tests by @LKuchno in #4707
  • chore(e2e): Adding iPad configuration to e2e suite in CI by @LKuchno in #4704
  • chore(deps): bump vm2 from 3.11.6 to 3.12.2 by @dependabot[bot] in #4765
  • chore(deps): bump brace-expansion from 1.1.18 to 1.1.21 in /docs by @dependabot[bot] in #4766
  • chore(deps): bump brace-expansion from 1.1.16 to 1.1.21 by @dependabot[bot] in #4754
  • docs: remove README-Fabric.md by @kkafar in #4783
  • chore(Android, Stack v4): remove dead ScreenModalFragment and helpers by @kkafar in #4795
  • refactor(Android, FormSheet): inject activity provider into dimming manager by @kkafar in #4735
  • refactor(Android, FormSheet): move to core and react packages by @kkafar in #4739
  • chore(Android): check core/react layer boundary in lint-android by @kkafar in #4742
  • refactor(Android): drop PixelUtil fallback from DimensionUtils by @kkafar in #4796
  • chore(Stack v5): remove unused ScreenStackNativeProps type from web by @kkafar in #4797
  • test(e2e, iOS): skip tab tests broken by UITab API migration (#4675) by @LKuchno in #4778
  • chore(test): move tabBarSidebarPreferredPlacement test to component integration tests by @Loloekk in #4816
  • refactor(Android): resolve container fragment manager through host delegates by @kkafar in #4803
  • chore(CI): remove obsolete cocoapods 1.15.2 install step from iOS workflows by @kkafar in #4798
  • chore(Android, Stack v5): gate debug logs behind RNSLog by @kkafar in #4799
  • test(e2e, iOS): fix context menu dismissal in Stack Header Menu test by @LKuchno in #4820
  • chore(test): e2e coverage for test-form-sheet-base by @LKuchno in #4661
  • refactor(JS, Stack v5): accept ref as a regular prop in StackHeaderConfig by @t0maboro in #4876
  • refactor(Android): make legacy screen containers take part in the container hierarchy by @kkafar in #4859
  • chore(Example): disable LogBox notifications in example apps by @kkafar in #4874
  • chore(deps): bump proxy-addr from 2.0.7 to 2.0.8 in /docs by @dependabot[bot] in #4806
  • test(e2e, iOS): re-enable tab system-item icon tests fixed by #4813 by @LKuchno in #4870
  • refactor(Android): route tabs pop-to-root through the container hierarchy by @kkafar in #4828
  • chore(Android): allow generated BuildConfig and R in the core layer check by @kkafar in #4843
  • refactor(Android): move createTransactionWithReordering to ext by @kkafar in #4844
  • chore: aggregate dependabot updates by @kkafar in #4898
  • refactor(Android): decouple SafeAreaProvider from SafeAreaView by @kkafar in #4845

New Contributors

Full Changelog: 5.0.0-alpha.3...5.0.0-alpha.4

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

NewReleases is sending notifications on new releases.