| 
				
			 | 
			
			
				@@ -0,0 +1,112 @@ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				1
			 | 
			
			
				+import * as React from 'react'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				2
			 | 
			
			
				+import { ViewStyle, View } from 'react-native'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				3
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				4
			 | 
			
			
				+import { InsetChangeNativeCallback } from './SafeArea.types'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				5
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				6
			 | 
			
			
				+interface NativeSafeAreaViewProps { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				7
			 | 
			
			
				+  children?: React.ReactNode; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				8
			 | 
			
			
				+  style: ViewStyle; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				9
			 | 
			
			
				+  onInsetsChange: InsetChangeNativeCallback; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				10
			 | 
			
			
				+} 
			 | 
		
	
		
			
			| 
				
			 | 
			
				11
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				12
			 | 
			
			
				+enum CSSTransitions { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				13
			 | 
			
			
				+  WebkitTransition = 'webkitTransitionEnd', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				14
			 | 
			
			
				+  Transition = 'transitionEnd', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				15
			 | 
			
			
				+  MozTransition = 'transitionend', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				16
			 | 
			
			
				+  MSTransition = 'msTransitionEnd', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				17
			 | 
			
			
				+  OTransition = 'oTransitionEnd', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				18
			 | 
			
			
				+} 
			 | 
		
	
		
			
			| 
				
			 | 
			
				19
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				20
			 | 
			
			
				+export default function NativeSafeAreaView({ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				21
			 | 
			
			
				+  children, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				22
			 | 
			
			
				+  style, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				23
			 | 
			
			
				+  onInsetsChange, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				24
			 | 
			
			
				+}: NativeSafeAreaViewProps) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				25
			 | 
			
			
				+  const element = createContextElement(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				26
			 | 
			
			
				+  document.body.appendChild(element); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				27
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				28
			 | 
			
			
				+  const onEnd = () => { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				29
			 | 
			
			
				+    const { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				30
			 | 
			
			
				+      paddingTop, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				31
			 | 
			
			
				+      paddingBottom, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				32
			 | 
			
			
				+      paddingLeft, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				33
			 | 
			
			
				+      paddingRight, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				34
			 | 
			
			
				+    } = getComputedStyle(element); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				35
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				+    const insets = { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				+      top: paddingTop ? parseInt(paddingTop, 10) : 0, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				38
			 | 
			
			
				+      bottom: paddingBottom ? parseInt(paddingBottom, 10) : 0, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				39
			 | 
			
			
				+      left: paddingLeft ? parseInt(paddingLeft, 10) : 0, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				40
			 | 
			
			
				+      right: paddingRight ? parseInt(paddingRight, 10) : 0, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				41
			 | 
			
			
				+    }; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				42
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				43
			 | 
			
			
				+    console.log('onEnd'); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				44
			 | 
			
			
				+    // @ts-ignore: missing properties 
			 | 
		
	
		
			
			| 
				
			 | 
			
				45
			 | 
			
			
				+    onInsetsChange({ nativeEvent: { insets } }); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				46
			 | 
			
			
				+  }; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				+  React.useEffect(() => { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				48
			 | 
			
			
				+    console.log( 
			 | 
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				+      'SUPPORTED_TRANSITION_EVENT', 
			 | 
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				+      SUPPORTED_TRANSITION_EVENT, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				51
			 | 
			
			
				+      SUPPORTED_ENV, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				+    ); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				+    element.addEventListener(SUPPORTED_TRANSITION_EVENT, onEnd); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				54
			 | 
			
			
				+    onEnd(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				55
			 | 
			
			
				+    return () => { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				56
			 | 
			
			
				+      document.body.removeChild(element); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				57
			 | 
			
			
				+      element.removeEventListener(SUPPORTED_TRANSITION_EVENT, onEnd); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				58
			 | 
			
			
				+    }; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				59
			 | 
			
			
				+  }, [onInsetsChange]); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				60
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				61
			 | 
			
			
				+  return <View style={style}>{children}</View>; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				62
			 | 
			
			
				+} 
			 | 
		
	
		
			
			| 
				
			 | 
			
				63
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				64
			 | 
			
			
				+const SUPPORTED_TRANSITION_EVENT: string = (() => { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				+  const element = document.createElement('invalidtype'); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				+  for (const key in CSSTransitions) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				68
			 | 
			
			
				+    if (element.style[key] !== undefined) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				+      return CSSTransitions[key]; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				70
			 | 
			
			
				+    } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				+  } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				+  return CSSTransitions.Transition; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				+})(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				+const SUPPORTED_ENV: 'constant' | 'env' = (() => { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				+  // @ts-ignore: Property 'CSS' does not exist on type 'Window'.ts(2339) 
			 | 
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				+  const { CSS } = window; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				+  if ( 
			 | 
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				+    CSS && 
			 | 
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				+    CSS.supports && 
			 | 
		
	
		
			
			| 
				
			 | 
			
				81
			 | 
			
			
				+    CSS.supports('top: constant(safe-area-inset-top)') 
			 | 
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				+  ) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				+    return 'constant'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				+  } 
			 | 
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				+  return 'env'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				86
			 | 
			
			
				+})(); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				87
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				88
			 | 
			
			
				+function getInset(side: string): string { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				89
			 | 
			
			
				+  return `${SUPPORTED_ENV}(safe-area-inset-${side})`; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				90
			 | 
			
			
				+} 
			 | 
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				+ 
			 | 
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				+function createContextElement(): HTMLElement { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				+  const element = document.createElement('div'); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				+  const { style } = element; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				+  style.position = 'fixed'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				96
			 | 
			
			
				+  style.left = '0'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				97
			 | 
			
			
				+  style.top = '0'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				98
			 | 
			
			
				+  style.width = '0'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				99
			 | 
			
			
				+  style.height = '0'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				+  style.zIndex = '-1'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				+  style.overflow = 'hidden'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				+  style.visibility = 'hidden'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				+  // Bacon: Anything faster than this and the callback will be invoked too early with the wrong insets 
			 | 
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				+  style.transitionDuration = '0.05s'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				+  style.transitionProperty = 'padding'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				+  style.transitionDelay = '0s'; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				+  style.paddingTop = getInset('top'); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				+  style.paddingBottom = getInset('bottom'); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				109
			 | 
			
			
				+  style.paddingLeft = getInset('left'); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				110
			 | 
			
			
				+  style.paddingRight = getInset('right'); 
			 | 
		
	
		
			
			| 
				
			 | 
			
				111
			 | 
			
			
				+  return element; 
			 | 
		
	
		
			
			| 
				
			 | 
			
				112
			 | 
			
			
				+} 
			 |