Skip to content

fix(TabView): respect user-supplied tabBarHidden#524

Draft
spokodev wants to merge 1 commit into
callstack:mainfrom
spokodev:fix/tab-bar-hidden-respects-user-prop
Draft

fix(TabView): respect user-supplied tabBarHidden#524
spokodev wants to merge 1 commit into
callstack:mainfrom
spokodev:fix/tab-bar-hidden-respects-user-prop

Conversation

@spokodev

Copy link
Copy Markdown

Closes #521.

tabBarHidden is wired natively (SwiftUI .hideTabBar(props.tabBarHidden), landed in #76) but the JS wrapper in packages/react-native-bottom-tabs/src/TabView.tsx hardcoded tabBarHidden={!!renderCustomTabBar} after the {...props} spread, so any caller-supplied value was overwritten before it reached NativeTabView. The prop was also absent from the Props<Route> interface so it never surfaced at the type level either.

This PR:

  • adds tabBarHidden?: boolean to the TabView Props<Route> interface with a JSDoc note that explains the default and the iOS 26+ use case from the issue
  • destructures it from the function parameters alongside the other named props
  • keeps the existing !!renderCustomTabBar behavior as the fallback when the caller does not pass a value (tabBarHidden ?? !!renderCustomTabBar)

Effect:

  • callers can now set <TabView ... tabBarHidden={true} /> to hide the native bar without rendering a custom tabBar, which is what the issue needs on iOS 26 where the UITabBar.isHidden workarounds from outside React Native no longer reach the SwiftUI-backed bar
  • callers that do not pass tabBarHidden get the same behavior as before (hidden iff tabBar is provided)
  • TypeScript users see the prop in IntelliSense and on the public type

Verification:

  • tsc -b clean on the package
  • eslint packages/react-native-bottom-tabs/src/TabView.tsx reports only the pre-existing no-shadow warning on loaded (line 293), unrelated to this change
  • existing jest setup in this repo is it.todo('write a test') and yarn test fails on main due to Flow type syntax in react-native/jest/setup.js, so a behavioural test would require fixing the jest config first which is outside the scope of this PR
  • changeset added: .changeset/respect-user-tab-bar-hidden.md (react-native-bottom-tabs: patch)

Out of scope:

  • the React Navigation adapter package (@bottom-tabs/react-navigation) does not reference tabBarHidden, so the <Tabs.Navigator tabBarHidden={shouldHide}> mention in the issue would need a separate change in that package's screen-options forwarding

The native side wired tabBarHidden into the SwiftUI tab bar via callstack#76,
but the JS wrapper hardcoded tabBarHidden={!!renderCustomTabBar}
after the {...props} spread, so any value the caller passed was
overwritten before it reached NativeTabView. The prop was also
absent from the TabView Props interface so it never type-checked
at all.

Add tabBarHidden to Props, destructure it explicitly, and keep the
renderCustomTabBar default only as a fallback when the caller does
not supply a value.

Closes callstack#521
labeled = Platform.OS !== 'android' ? true : undefined,
getFreezeOnBlur = ({ route }: { route: Route }) => route.freezeOnBlur,
tabBar: renderCustomTabBar,
tabBarHidden,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add the default false value 🙏🏻

Suggested change
tabBarHidden,
tabBarHidden = false,

Comment on lines +215 to +221
/**
* Whether to hide the native tab bar. Defaults to `true` when a custom
* `tabBar` is provided (so the native bar does not stack on top of the
* custom one), otherwise `false`. Set explicitly to override the default,
* which is required on iOS 26+ where `UITabBar.isHidden` workarounds from
* outside React Native no longer reach the SwiftUI-backed tab bar.
*/

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for such a big wall of text, let's keep it simple

Suggested change
/**
* Whether to hide the native tab bar. Defaults to `true` when a custom
* `tabBar` is provided (so the native bar does not stack on top of the
* custom one), otherwise `false`. Set explicitly to override the default,
* which is required on iOS 26+ where `UITabBar.isHidden` workarounds from
* outside React Native no longer reach the SwiftUI-backed tab bar.
*/
/**
* Whether to hide the native tab bar.
*/

'react-native-bottom-tabs': patch
---

Respect user-supplied `tabBarHidden` on `TabView`. The prop was wired natively but the JS wrapper hardcoded `tabBarHidden={!!renderCustomTabBar}` after the `{...props}` spread, so any user value was silently overwritten. The prop is now declared on the public `TabView` API and only falls back to the custom-tab-bar default when the caller omits it, which lets iOS 26+ users hide the SwiftUI-backed tab bar from JS again.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, we don't need the whole explanation on the changelogs

Suggested change
Respect user-supplied `tabBarHidden` on `TabView`. The prop was wired natively but the JS wrapper hardcoded `tabBarHidden={!!renderCustomTabBar}` after the `{...props}` spread, so any user value was silently overwritten. The prop is now declared on the public `TabView` API and only falls back to the custom-tab-bar default when the caller omits it, which lets iOS 26+ users hide the SwiftUI-backed tab bar from JS again.
Respect user-supplied `tabBarHidden` on `TabView`.

@thiagobrez

Copy link
Copy Markdown
Collaborator

Thanks @spokodev! Left some easy comments. If you can fix them and mark the PR as ready, we can merge soon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

tabBarHidden navigator prop is silently ignored — hardcoded in JS wrapper

2 participants