浏览代码

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 年前
父节点
当前提交
72774fffd4
没有帐户链接到提交者的电子邮件

+ 17
- 0
src/InitialWindow.native.ts 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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
-}