Skip to content
This repository was archived by the owner on Jan 30, 2021. It is now read-only.

Commit 12701e4

Browse files
committed
Update from react-navigation SafeAreaView.
1 parent 4945e56 commit 12701e4

File tree

1 file changed

+85
-7
lines changed

1 file changed

+85
-7
lines changed

index.js

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import {
66
NativeModules,
77
Platform,
88
SafeAreaView,
9+
StyleSheet,
910
View,
1011
} from 'react-native';
1112
import withOrientation from './withOrientation';
1213

13-
const { isIPhoneX_deprecated } = DeviceInfo;
1414
// See https://mydevice.io/devices/ for device dimensions
1515
const X_WIDTH = 375;
1616
const X_HEIGHT = 812;
@@ -23,8 +23,10 @@ const { PlatformConstants = {} } = NativeModules;
2323
const { minor = 0 } = PlatformConstants.reactNativeVersion || {};
2424

2525
const isIPhoneX = (() => {
26+
if (Platform.OS === 'web') return false;
27+
2628
if (minor >= 50) {
27-
return isIPhoneX_deprecated;
29+
return DeviceInfo.isIPhoneX_deprecated;
2830
}
2931

3032
return (
@@ -62,13 +64,27 @@ const statusBarHeight = isLandscape => {
6264
return isLandscape ? 0 : 20;
6365
};
6466

67+
const doubleFromPercentString = percent => {
68+
if (!percent.includes('%')) {
69+
return 0;
70+
}
71+
72+
const dbl = parseFloat(percent) / 100;
73+
74+
if (isNaN(dbl)) return 0;
75+
76+
return dbl;
77+
};
78+
6579
class SafeView extends Component {
6680
state = {
6781
touchesTop: true,
6882
touchesBottom: true,
6983
touchesLeft: true,
7084
touchesRight: true,
7185
orientation: null,
86+
viewWidth: 0,
87+
viewHeight: 0,
7288
};
7389

7490
componentDidMount() {
@@ -88,17 +104,13 @@ class SafeView extends Component {
88104
return <View style={style}>{this.props.children}</View>;
89105
}
90106

91-
if (!forceInset && minor >= 50) {
92-
return <SafeAreaView style={style}>{this.props.children}</SafeAreaView>;
93-
}
94-
95107
const safeAreaStyle = this._getSafeAreaStyle();
96108

97109
return (
98110
<View
99111
ref={c => (this.view = c)}
100112
onLayout={this._onLayout}
101-
style={[style, safeAreaStyle]}
113+
style={safeAreaStyle}
102114
>
103115
{this.props.children}
104116
</View>
@@ -145,6 +157,8 @@ class SafeView extends Component {
145157
touchesLeft,
146158
touchesRight,
147159
orientation: newOrientation,
160+
viewWidth: winWidth,
161+
viewHeight: winHeight,
148162
});
149163
});
150164
};
@@ -153,7 +167,16 @@ class SafeView extends Component {
153167
const { touchesTop, touchesBottom, touchesLeft, touchesRight } = this.state;
154168
const { forceInset, isLandscape } = this.props;
155169

170+
const {
171+
paddingTop,
172+
paddingBottom,
173+
paddingLeft,
174+
paddingRight,
175+
viewStyle,
176+
} = this._getViewStyles();
177+
156178
const style = {
179+
...viewStyle,
157180
paddingTop: touchesTop ? this._getInset('top') : 0,
158181
paddingBottom: touchesBottom ? this._getInset('bottom') : 0,
159182
paddingLeft: touchesLeft ? this._getInset('left') : 0,
@@ -195,9 +218,64 @@ class SafeView extends Component {
195218
});
196219
}
197220

221+
// new height/width should only include padding from insets
222+
// height/width should not be affected by padding from style obj
223+
if (style.height && typeof style.height === 'number') {
224+
style.height += style.paddingTop + style.paddingBottom;
225+
}
226+
227+
if (style.width && typeof style.width === 'number') {
228+
style.width += style.paddingLeft + style.paddingRight;
229+
}
230+
231+
style.paddingTop += paddingTop;
232+
style.paddingBottom += paddingBottom;
233+
style.paddingLeft += paddingLeft;
234+
style.paddingRight += paddingRight;
235+
198236
return style;
199237
};
200238

239+
_getViewStyles = () => {
240+
const { viewWidth } = this.state;
241+
// get padding values from style to add back in after insets are determined
242+
// default precedence: padding[Side] -> vertical | horizontal -> padding -> 0
243+
let {
244+
padding = 0,
245+
paddingVertical = padding,
246+
paddingHorizontal = padding,
247+
paddingTop = paddingVertical,
248+
paddingBottom = paddingVertical,
249+
paddingLeft = paddingHorizontal,
250+
paddingRight = paddingHorizontal,
251+
...viewStyle
252+
} = StyleSheet.flatten(this.props.style || {});
253+
254+
if (typeof paddingTop !== 'number') {
255+
paddingTop = doubleFromPercentString(paddingTop) * viewWidth;
256+
}
257+
258+
if (typeof paddingBottom !== 'number') {
259+
paddingBottom = doubleFromPercentString(paddingBottom) * viewWidth;
260+
}
261+
262+
if (typeof paddingLeft !== 'number') {
263+
paddingLeft = doubleFromPercentString(paddingLeft) * viewWidth;
264+
}
265+
266+
if (typeof paddingRight !== 'number') {
267+
paddingRight = doubleFromPercentString(paddingRight) * viewWidth;
268+
}
269+
270+
return {
271+
paddingTop,
272+
paddingBottom,
273+
paddingLeft,
274+
paddingRight,
275+
viewStyle,
276+
};
277+
};
278+
201279
_getInset = key => {
202280
const { isLandscape } = this.props;
203281
switch (key) {

0 commit comments

Comments
 (0)