import type { ReactNode } from 'react';
import { useMemo } from 'react';
import { Platform, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { FullWindowOverlay } from '../../helpers/internal/components';
import type { ToastInsets } from './types';
interface InsetsContainerProps {
/**
* When true, uses a regular View instead of FullWindowOverlay on iOS.
* Enables element inspector but toasts won't appear above native modals.
* @default false
*/
disableFullWindowOverlay: boolean;
/**
* Controls whether VoiceOver treats the overlay window as a modal container.
* When `false`, VoiceOver can still access elements behind the overlay.
* When `true`, VoiceOver is restricted to elements inside the overlay.
* @default false
* @platform ios
* @unstable This prop maps directly to the native `accessibilityViewIsModal`
* on the container view and may change in a future react-native-screens release.
*/
unstable_accessibilityContainerViewIsModal?: boolean;
/**
* Optional inset values for all edges
* If not provided, defaults to platform-specific values:
* - iOS: safe area insets + 0px (top), + 6px (bottom), + 12px (left/right)
* - Android: safe area insets + 12px (all edges)
*/
insets?: ToastInsets;
/**
* Custom wrapper function to wrap the toast content
* Receives children and should return a component that wraps them
* The wrapper should apply flex: 1 (via className or style) to ensure proper layout
* Can be any component wrapper - KeyboardAvoidingView, View, or any custom component
*/
contentWrapper?: (children: ReactNode) => React.ReactElement;
/**
* Children to render inside the container
*/
children: ReactNode;
}
/**
* Container component that applies inset padding to position toasts
* away from screen edges and safe areas
*
* Combines custom insets with safe area insets:
* - If custom inset is provided, it overrides safe area + default padding
* - If not provided, uses platform-specific defaults:
* - iOS: safe area inset + 0px for top, + 6px for bottom, + 12px for left/right
* - Android: safe area inset + 12px for all edges
*/
export function InsetsContainer({
insets,
contentWrapper,
children,
disableFullWindowOverlay,
unstable_accessibilityContainerViewIsModal,
}: InsetsContainerProps) {
const safeAreaInsets = useSafeAreaInsets();
const finalInsets = useMemo(() => {
return {
top: insets?.top ?? safeAreaInsets.top + (Platform.OS === 'ios' ? 0 : 12),
bottom:
insets?.bottom ??
safeAreaInsets.bottom + (Platform.OS === 'ios' ? 6 : 12),
left: insets?.left ?? safeAreaInsets.left + 12,
right: insets?.right ?? safeAreaInsets.right + 12,
};
}, [safeAreaInsets, insets]);
const content = (
{contentWrapper ? contentWrapper(children) : children}
);
if (Platform.OS !== 'ios') {
return content;
}
return (
{content}
);
}