diff --git a/docs/docs/api/safe-area-provider.mdx b/docs/docs/api/safe-area-provider.mdx
index a617084b..485fe733 100644
--- a/docs/docs/api/safe-area-provider.mdx
+++ b/docs/docs/api/safe-area-provider.mdx
@@ -27,3 +27,7 @@ Accepts all [View](https://reactnative.dev/docs/view) props. Has a default style
Optional, defaults to `null`.
Can be used to provide the initial value for frame and insets, this allows rendering immediately. See [optimization](/optimizations) for more information on how to use this prop.
+
+#### `ref`
+
+Optional ref to the underlying view.
diff --git a/src/CompatNativeSafeAreaProvider.tsx b/src/CompatNativeSafeAreaProvider.tsx
index 114ad8d1..9615371e 100644
--- a/src/CompatNativeSafeAreaProvider.tsx
+++ b/src/CompatNativeSafeAreaProvider.tsx
@@ -6,6 +6,7 @@ export function CompatNativeSafeAreaProvider({
children,
style,
onInsetsChange,
+ ref,
}: NativeSafeAreaProviderProps) {
const window = useWindowDimensions();
React.useEffect(() => {
@@ -24,5 +25,9 @@ export function CompatNativeSafeAreaProvider({
// @ts-ignore: missing properties
onInsetsChange({ nativeEvent: { insets, frame } });
}, [onInsetsChange, window.height, window.width]);
- return {children};
+ return (
+
+ {children}
+
+ );
}
diff --git a/src/NativeSafeAreaProvider.web.tsx b/src/NativeSafeAreaProvider.web.tsx
index 82828693..5bcdf5cd 100644
--- a/src/NativeSafeAreaProvider.web.tsx
+++ b/src/NativeSafeAreaProvider.web.tsx
@@ -16,9 +16,23 @@ export function NativeSafeAreaProvider({
children,
style,
onInsetsChange,
+ ref,
}: NativeSafeAreaProviderProps) {
const viewRef = React.useRef(null);
+ const setRef = React.useCallback(
+ (view: View | null) => {
+ viewRef.current = view;
+
+ if (typeof ref === 'function') {
+ return ref(view);
+ } else if (ref != null) {
+ ref.current = view;
+ }
+ },
+ [ref],
+ );
+
React.useEffect(() => {
// Skip for SSR.
if (typeof document === 'undefined') {
@@ -108,7 +122,7 @@ export function NativeSafeAreaProvider({
}, [onInsetsChange]);
return (
-
+
{children}
);
diff --git a/src/SafeArea.types.ts b/src/SafeArea.types.ts
index d3d23b62..5672e5d6 100644
--- a/src/SafeArea.types.ts
+++ b/src/SafeArea.types.ts
@@ -1,5 +1,5 @@
import type * as React from 'react';
-import type { NativeSyntheticEvent, ViewProps } from 'react-native';
+import type { NativeSyntheticEvent, View, ViewProps } from 'react-native';
import NativeSafeAreaView from './specs/NativeSafeAreaView';
export type Edge = 'top' | 'right' | 'bottom' | 'left';
@@ -32,6 +32,7 @@ export type InsetChangedEvent = NativeSyntheticEvent;
export type InsetChangeNativeCallback = (event: InsetChangedEvent) => void;
export interface NativeSafeAreaProviderProps extends ViewProps {
+ ref?: React.Ref;
children?: React.ReactNode;
onInsetsChange: InsetChangeNativeCallback;
}
diff --git a/src/SafeAreaContext.tsx b/src/SafeAreaContext.tsx
index ed192d76..72f2c0b3 100644
--- a/src/SafeAreaContext.tsx
+++ b/src/SafeAreaContext.tsx
@@ -1,5 +1,10 @@
import * as React from 'react';
-import { Dimensions, StyleSheet, type ViewProps } from 'react-native';
+import {
+ Dimensions,
+ StyleSheet,
+ type View,
+ type ViewProps,
+} from 'react-native';
import { NativeSafeAreaProvider } from './NativeSafeAreaProvider';
import type {
EdgeInsets,
@@ -23,6 +28,7 @@ if (isDev) {
}
export interface SafeAreaProviderProps extends ViewProps {
+ ref?: React.Ref;
children?: React.ReactNode;
initialMetrics?: Metrics | null;
/**
@@ -36,6 +42,7 @@ export function SafeAreaProvider({
initialMetrics,
initialSafeAreaInsets,
style,
+ ref,
...others
}: SafeAreaProviderProps) {
const parentInsets = useParentSafeAreaInsets();
@@ -90,6 +97,7 @@ export function SafeAreaProvider({
return (