import * as React from 'react'; import { StyleSheet, View, ViewProps } from 'react-native'; import { EdgeInsets, InsetChangedEvent } from './SafeArea.types'; import NativeSafeAreaView from './NativeSafeAreaView'; export const SafeAreaContext = React.createContext(null); export interface SafeAreaViewProps { children?: React.ReactNode; } export function SafeAreaProvider({ children }: SafeAreaViewProps) { let parentInsets = useParentSafeArea(); const [insets, setInsets] = React.useState(null); const onInsetsChange = React.useCallback((event: InsetChangedEvent) => { setInsets(event.nativeEvent.insets); }, []); // If a provider is nested inside of another provider then we can just use // the parent insets, without rendering another native safe area view if (parentInsets) { return {children}; } else { return ( {insets !== null ? ( {children} ) : null} ); } } const styles = StyleSheet.create({ fill: { flex: 1 }, }); export const SafeAreaConsumer = SafeAreaContext.Consumer; function useParentSafeArea(): React.ContextType { return React.useContext(SafeAreaContext); } export function useSafeArea(): EdgeInsets { const safeArea = React.useContext(SafeAreaContext); if (safeArea == null) { throw new Error( 'No safe area value available. Make sure you are rendering `` at the top of your app.', ); } return safeArea; } export function SafeAreaView({ style, ...rest }: ViewProps & { children: React.ReactNode }) { const insets = useSafeArea(); return ( ); } export type EdgeInsets = EdgeInsets;