From ba21e4aa550e73a6e8e780ac2bcbed19c254e6a8 Mon Sep 17 00:00:00 2001 From: Yedidya Kennard Date: Wed, 14 Oct 2026 20:40:21 +0300 Subject: [PATCH] fix: View - use React Native's position-aware SafeAreaView for useSafeArea on iOS react-native-safe-area-context's SafeAreaView pads every edge from the nearest SafeAreaProvider's insets regardless of where the view sits, so a header with useSafeArea gets bottom padding whenever the provider extends under a translucent tab bar (iOS 26 Liquid Glass). React Native's SafeAreaView insets only the edges the view actually touches, which is what useSafeArea means. Other platforms keep the safe-area-context SafeAreaView when it is installed. --- .../react-native-ui-lib/src/components/view/index.tsx | 10 ++++++---- .../src/components/view/view.api.json | 6 +++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/react-native-ui-lib/src/components/view/index.tsx b/packages/react-native-ui-lib/src/components/view/index.tsx index 24aeefd700..2822983845 100644 --- a/packages/react-native-ui-lib/src/components/view/index.tsx +++ b/packages/react-native-ui-lib/src/components/view/index.tsx @@ -13,7 +13,9 @@ type ReanimatedProps = Partial, 'entering' | 'exi export interface ViewProps extends Omit, ReanimatedProps, ContainerModifiers, RecorderProps { /** - * If true, will render as SafeAreaView + * If true, will render as SafeAreaView. + * On iOS this is React Native's SafeAreaView, which insets only the edges the view actually touches; + * elsewhere it is react-native-safe-area-context's SafeAreaView when that package is installed. */ useSafeArea?: boolean; /** @@ -108,10 +110,10 @@ function View(props: ViewProps, ref: any) { const ViewContainer = useMemo(() => { let container: React.ComponentType = RNView; - if (useSafeArea && SafeAreaContextPackage?.SafeAreaView) { - container = SafeAreaContextPackage.SafeAreaView; - } else if (useSafeArea && Constants.isIOS) { + if (useSafeArea && Constants.isIOS) { container = SafeAreaView; + } else if (useSafeArea && SafeAreaContextPackage?.SafeAreaView) { + container = SafeAreaContextPackage.SafeAreaView; } if (reanimated) { diff --git a/packages/react-native-ui-lib/src/components/view/view.api.json b/packages/react-native-ui-lib/src/components/view/view.api.json index 9067aac8eb..bce75371c6 100644 --- a/packages/react-native-ui-lib/src/components/view/view.api.json +++ b/packages/react-native-ui-lib/src/components/view/view.api.json @@ -8,7 +8,11 @@ "example": "https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/ViewScreen.js", "images": [], "props": [ - {"name": "useSafeArea", "type": "boolean", "description": "If true, will render as SafeAreaView"}, + { + "name": "useSafeArea", + "type": "boolean", + "description": "If true, will render as SafeAreaView. On iOS this is React Native's SafeAreaView, which insets only the edges the view actually touches; elsewhere it is react-native-safe-area-context's SafeAreaView when that package is installed" + }, {"name": "animated", "type": "boolean", "description": "Use Animate.View as a container"}, { "name": "reanimated",