Browse Source

fix: don't use .web extension (#77)

.web extension is not supported by node or webpack by default and using it requires additional configuration. the .native extension is supported by default in metro, so using .native.ts and .ts instead of .ts and .web.ts is better because it needs minimal configuration when using in SSR.
Satyajit Sahoo 4 years ago
parent
commit
72774fffd4
No account linked to committer's email address

+ 17
- 0
src/InitialWindow.native.ts View File

@@ -0,0 +1,17 @@
1
+import { UIManager } from 'react-native';
2
+import { Metrics } from './SafeArea.types';
3
+
4
+const RNCSafeAreaViewConfig = UIManager.getViewManagerConfig(
5
+  'RNCSafeAreaView',
6
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+) as any;
8
+
9
+export const initialWindowMetrics = (RNCSafeAreaViewConfig != null &&
10
+RNCSafeAreaViewConfig.Constants != null
11
+  ? RNCSafeAreaViewConfig.Constants.initialWindowMetrics
12
+  : null) as Metrics | null;
13
+
14
+/**
15
+ * @deprecated
16
+ */
17
+export const initialWindowSafeAreaInsets = initialWindowMetrics?.insets;

+ 3
- 12
src/InitialWindow.ts View File

@@ -1,17 +1,8 @@
1
-import { UIManager } from 'react-native';
2
-import { Metrics } from './SafeArea.types';
1
+import { EdgeInsets, Metrics } from './SafeArea.types';
3 2
 
4
-const RNCSafeAreaViewConfig = UIManager.getViewManagerConfig(
5
-  'RNCSafeAreaView',
6
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
-) as any;
8
-
9
-export const initialWindowMetrics = (RNCSafeAreaViewConfig != null &&
10
-RNCSafeAreaViewConfig.Constants != null
11
-  ? RNCSafeAreaViewConfig.Constants.initialWindowMetrics
12
-  : null) as Metrics | null;
3
+export const initialWindowMetrics: Metrics | null = null;
13 4
 
14 5
 /**
15 6
  * @deprecated
16 7
  */
17
-export const initialWindowSafeAreaInsets = initialWindowMetrics?.insets;
8
+export const initialWindowSafeAreaInsets: EdgeInsets | null = null;

+ 0
- 8
src/InitialWindow.web.ts View File

@@ -1,8 +0,0 @@
1
-import { EdgeInsets, Metrics } from './SafeArea.types';
2
-
3
-export const initialWindowMetrics: Metrics | null = null;
4
-
5
-/**
6
- * @deprecated
7
- */
8
-export const initialWindowSafeAreaInsets: EdgeInsets | null = null;

+ 6
- 0
src/NativeSafeAreaView.native.tsx View File

@@ -0,0 +1,6 @@
1
+import { requireNativeComponent } from 'react-native';
2
+import { NativeSafeAreaViewProps } from './SafeArea.types';
3
+
4
+export default requireNativeComponent<NativeSafeAreaViewProps>(
5
+  'RNCSafeAreaView',
6
+);

+ 127
- 4
src/NativeSafeAreaView.tsx View File

@@ -1,6 +1,129 @@
1
-import { requireNativeComponent } from 'react-native';
1
+import * as React from 'react';
2
+import { View } from 'react-native';
2 3
 import { NativeSafeAreaViewProps } from './SafeArea.types';
3 4
 
4
-export default requireNativeComponent<NativeSafeAreaViewProps>(
5
-  'RNCSafeAreaView',
6
-);
5
+/**
6
+ * TODO:
7
+ * Currently insets and frame are based on the window and are not
8
+ * relative to the provider view. This is inconsistent with iOS and Android.
9
+ * However in most cases if the provider view covers the screen this is not
10
+ * an issue.
11
+ */
12
+
13
+const CSSTransitions: Record<string, string> = {
14
+  WebkitTransition: 'webkitTransitionEnd',
15
+  Transition: 'transitionEnd',
16
+  MozTransition: 'transitionend',
17
+  MSTransition: 'msTransitionEnd',
18
+  OTransition: 'oTransitionEnd',
19
+};
20
+
21
+export default function NativeSafeAreaView({
22
+  children,
23
+  style,
24
+  onInsetsChange,
25
+}: NativeSafeAreaViewProps) {
26
+  React.useEffect(() => {
27
+    // Skip for SSR.
28
+    if (typeof document === 'undefined') {
29
+      return;
30
+    }
31
+
32
+    const element = createContextElement();
33
+    document.body.appendChild(element);
34
+    const onEnd = () => {
35
+      const {
36
+        paddingTop,
37
+        paddingBottom,
38
+        paddingLeft,
39
+        paddingRight,
40
+      } = window.getComputedStyle(element);
41
+
42
+      const insets = {
43
+        top: paddingTop ? parseInt(paddingTop, 10) : 0,
44
+        bottom: paddingBottom ? parseInt(paddingBottom, 10) : 0,
45
+        left: paddingLeft ? parseInt(paddingLeft, 10) : 0,
46
+        right: paddingRight ? parseInt(paddingRight, 10) : 0,
47
+      };
48
+      const frame = {
49
+        x: 0,
50
+        y: 0,
51
+        width: document.documentElement.offsetWidth,
52
+        height: document.documentElement.offsetHeight,
53
+      };
54
+      // @ts-ignore: missing properties
55
+      onInsetsChange({ nativeEvent: { insets, frame } });
56
+    };
57
+    element.addEventListener(getSupportedTransitionEvent(), onEnd);
58
+    onEnd();
59
+    return () => {
60
+      document.body.removeChild(element);
61
+      element.removeEventListener(getSupportedTransitionEvent(), onEnd);
62
+    };
63
+  }, [onInsetsChange]);
64
+
65
+  return <View style={style}>{children}</View>;
66
+}
67
+
68
+let _supportedTransitionEvent: string | null = null;
69
+function getSupportedTransitionEvent(): string {
70
+  if (_supportedTransitionEvent !== null) {
71
+    return _supportedTransitionEvent;
72
+  }
73
+  const element = document.createElement('invalidtype');
74
+
75
+  _supportedTransitionEvent = CSSTransitions.Transition;
76
+  for (const key in CSSTransitions) {
77
+    if (element.style[key as keyof CSSStyleDeclaration] !== undefined) {
78
+      _supportedTransitionEvent = CSSTransitions[key];
79
+      break;
80
+    }
81
+  }
82
+  return _supportedTransitionEvent;
83
+}
84
+
85
+type CssEnv = 'constant' | 'env';
86
+
87
+let _supportedEnv: CssEnv | null = null;
88
+function getSupportedEnv(): CssEnv {
89
+  if (_supportedEnv !== null) {
90
+    return _supportedEnv;
91
+  }
92
+  const { CSS } = window;
93
+  if (
94
+    CSS &&
95
+    CSS.supports &&
96
+    CSS.supports('top: constant(safe-area-inset-top)')
97
+  ) {
98
+    _supportedEnv = 'constant';
99
+  } else {
100
+    _supportedEnv = 'env';
101
+  }
102
+  return _supportedEnv;
103
+}
104
+
105
+function getInset(side: string): string {
106
+  return `${getSupportedEnv()}(safe-area-inset-${side})`;
107
+}
108
+
109
+function createContextElement(): HTMLElement {
110
+  const element = document.createElement('div');
111
+  const { style } = element;
112
+  style.position = 'fixed';
113
+  style.left = '0';
114
+  style.top = '0';
115
+  style.width = '0';
116
+  style.height = '0';
117
+  style.zIndex = '-1';
118
+  style.overflow = 'hidden';
119
+  style.visibility = 'hidden';
120
+  // Bacon: Anything faster than this and the callback will be invoked too early with the wrong insets
121
+  style.transitionDuration = '0.05s';
122
+  style.transitionProperty = 'padding';
123
+  style.transitionDelay = '0s';
124
+  style.paddingTop = getInset('top');
125
+  style.paddingBottom = getInset('bottom');
126
+  style.paddingLeft = getInset('left');
127
+  style.paddingRight = getInset('right');
128
+  return element;
129
+}

+ 0
- 129
src/NativeSafeAreaView.web.tsx View File

@@ -1,129 +0,0 @@
1
-import * as React from 'react';
2
-import { View } from 'react-native';
3
-import { NativeSafeAreaViewProps } from './SafeArea.types';
4
-
5
-/**
6
- * TODO:
7
- * Currently insets and frame are based on the window and are not
8
- * relative to the provider view. This is inconsistent with iOS and Android.
9
- * However in most cases if the provider view covers the screen this is not
10
- * an issue.
11
- */
12
-
13
-const CSSTransitions: Record<string, string> = {
14
-  WebkitTransition: 'webkitTransitionEnd',
15
-  Transition: 'transitionEnd',
16
-  MozTransition: 'transitionend',
17
-  MSTransition: 'msTransitionEnd',
18
-  OTransition: 'oTransitionEnd',
19
-};
20
-
21
-export default function NativeSafeAreaView({
22
-  children,
23
-  style,
24
-  onInsetsChange,
25
-}: NativeSafeAreaViewProps) {
26
-  React.useEffect(() => {
27
-    // Skip for SSR.
28
-    if (typeof document === 'undefined') {
29
-      return;
30
-    }
31
-
32
-    const element = createContextElement();
33
-    document.body.appendChild(element);
34
-    const onEnd = () => {
35
-      const {
36
-        paddingTop,
37
-        paddingBottom,
38
-        paddingLeft,
39
-        paddingRight,
40
-      } = window.getComputedStyle(element);
41
-
42
-      const insets = {
43
-        top: paddingTop ? parseInt(paddingTop, 10) : 0,
44
-        bottom: paddingBottom ? parseInt(paddingBottom, 10) : 0,
45
-        left: paddingLeft ? parseInt(paddingLeft, 10) : 0,
46
-        right: paddingRight ? parseInt(paddingRight, 10) : 0,
47
-      };
48
-      const frame = {
49
-        x: 0,
50
-        y: 0,
51
-        width: document.documentElement.offsetWidth,
52
-        height: document.documentElement.offsetHeight,
53
-      };
54
-      // @ts-ignore: missing properties
55
-      onInsetsChange({ nativeEvent: { insets, frame } });
56
-    };
57
-    element.addEventListener(getSupportedTransitionEvent(), onEnd);
58
-    onEnd();
59
-    return () => {
60
-      document.body.removeChild(element);
61
-      element.removeEventListener(getSupportedTransitionEvent(), onEnd);
62
-    };
63
-  }, [onInsetsChange]);
64
-
65
-  return <View style={style}>{children}</View>;
66
-}
67
-
68
-let _supportedTransitionEvent: string | null = null;
69
-function getSupportedTransitionEvent(): string {
70
-  if (_supportedTransitionEvent !== null) {
71
-    return _supportedTransitionEvent;
72
-  }
73
-  const element = document.createElement('invalidtype');
74
-
75
-  _supportedTransitionEvent = CSSTransitions.Transition;
76
-  for (const key in CSSTransitions) {
77
-    if (element.style[key as keyof CSSStyleDeclaration] !== undefined) {
78
-      _supportedTransitionEvent = CSSTransitions[key];
79
-      break;
80
-    }
81
-  }
82
-  return _supportedTransitionEvent;
83
-}
84
-
85
-type CssEnv = 'constant' | 'env';
86
-
87
-let _supportedEnv: CssEnv | null = null;
88
-function getSupportedEnv(): CssEnv {
89
-  if (_supportedEnv !== null) {
90
-    return _supportedEnv;
91
-  }
92
-  const { CSS } = window;
93
-  if (
94
-    CSS &&
95
-    CSS.supports &&
96
-    CSS.supports('top: constant(safe-area-inset-top)')
97
-  ) {
98
-    _supportedEnv = 'constant';
99
-  } else {
100
-    _supportedEnv = 'env';
101
-  }
102
-  return _supportedEnv;
103
-}
104
-
105
-function getInset(side: string): string {
106
-  return `${getSupportedEnv()}(safe-area-inset-${side})`;
107
-}
108
-
109
-function createContextElement(): HTMLElement {
110
-  const element = document.createElement('div');
111
-  const { style } = element;
112
-  style.position = 'fixed';
113
-  style.left = '0';
114
-  style.top = '0';
115
-  style.width = '0';
116
-  style.height = '0';
117
-  style.zIndex = '-1';
118
-  style.overflow = 'hidden';
119
-  style.visibility = 'hidden';
120
-  // Bacon: Anything faster than this and the callback will be invoked too early with the wrong insets
121
-  style.transitionDuration = '0.05s';
122
-  style.transitionProperty = 'padding';
123
-  style.transitionDelay = '0s';
124
-  style.paddingTop = getInset('top');
125
-  style.paddingBottom = getInset('bottom');
126
-  style.paddingLeft = getInset('left');
127
-  style.paddingRight = getInset('right');
128
-  return element;
129
-}