Skip to content

Commit 8b5d629

Browse files
fix: using edge modes on web
1 parent b8650b0 commit 8b5d629

File tree

1 file changed

+72
-44
lines changed

1 file changed

+72
-44
lines changed

src/SafeAreaView.web.tsx

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,58 @@
11
import * as React from 'react';
2-
import { View, StyleSheet } from 'react-native';
3-
import { useSafeAreaInsets } from './SafeAreaContext';
4-
import type {
2+
import { StyleSheet, View } from 'react-native';
3+
import {
54
Edge,
5+
EdgeMode,
6+
EdgeRecord,
67
NativeSafeAreaViewInstance,
78
NativeSafeAreaViewProps,
89
} from './SafeArea.types';
10+
import { useSafeAreaInsets } from './SafeAreaContext';
911

10-
// prettier-ignore
11-
const TOP = 0b1000,
12-
RIGHT = 0b0100,
13-
BOTTOM = 0b0010,
14-
LEFT = 0b0001,
15-
ALL = 0b1111;
16-
17-
/* eslint-disable no-bitwise */
18-
19-
const edgeBitmaskMap: Record<Edge, number> = {
20-
top: TOP,
21-
right: RIGHT,
22-
bottom: BOTTOM,
23-
left: LEFT,
12+
const defaultEdges: Record<Edge, EdgeMode> = {
13+
top: 'additive',
14+
left: 'additive',
15+
bottom: 'additive',
16+
right: 'additive',
2417
};
2518

26-
export const SafeAreaView = React.forwardRef<
19+
function getEdgeValue(
20+
inset: number,
21+
current: number,
22+
mode: EdgeMode | undefined,
23+
) {
24+
switch (mode) {
25+
case 'off':
26+
return current;
27+
case 'maximum':
28+
return Math.max(current, inset);
29+
case 'additive':
30+
default:
31+
return current + inset;
32+
}
33+
}
34+
35+
export const JsSafeAreaView = React.forwardRef<
2736
NativeSafeAreaViewInstance,
2837
NativeSafeAreaViewProps
2938
>(({ style = {}, mode, edges, ...rest }, ref) => {
3039
const insets = useSafeAreaInsets();
3140

32-
const edgeBitmask =
33-
edges != null
34-
? Array.isArray(edges)
35-
? edges.reduce(
36-
(acc: number, edge: Edge) => acc | edgeBitmaskMap[edge],
37-
0,
38-
)
39-
: Object.keys(edges).reduce(
40-
(acc, edge) => acc | edgeBitmaskMap[edge as Edge],
41-
0,
42-
)
43-
: ALL;
41+
const edgesRecord = React.useMemo(() => {
42+
if (edges == null) {
43+
return defaultEdges;
44+
}
45+
46+
return Array.isArray(edges)
47+
? edges.reduce<EdgeRecord>((acc, edge: Edge) => {
48+
acc[edge] = 'additive';
49+
return acc;
50+
}, {})
51+
: // ts has trouble with refining readonly arrays.
52+
(edges as EdgeRecord);
53+
}, [edges]);
4454

4555
const appliedStyle = React.useMemo(() => {
46-
const insetTop = edgeBitmask & TOP ? insets.top : 0;
47-
const insetRight = edgeBitmask & RIGHT ? insets.right : 0;
48-
const insetBottom = edgeBitmask & BOTTOM ? insets.bottom : 0;
49-
const insetLeft = edgeBitmask & LEFT ? insets.left : 0;
50-
5156
const flatStyle = StyleSheet.flatten(style) as Record<string, number>;
5257

5358
if (mode === 'margin') {
@@ -62,10 +67,14 @@ export const SafeAreaView = React.forwardRef<
6267
} = flatStyle;
6368

6469
const marginStyle = {
65-
marginTop: marginTop + insetTop,
66-
marginRight: marginRight + insetRight,
67-
marginBottom: marginBottom + insetBottom,
68-
marginLeft: marginLeft + insetLeft,
70+
marginTop: getEdgeValue(insets.top, marginTop, edgesRecord.top),
71+
marginRight: getEdgeValue(insets.right, marginRight, edgesRecord.right),
72+
marginBottom: getEdgeValue(
73+
insets.bottom,
74+
marginBottom,
75+
edgesRecord.bottom,
76+
),
77+
marginLeft: getEdgeValue(insets.left, marginLeft, edgesRecord.left),
6978
};
7079

7180
return [style, marginStyle];
@@ -81,15 +90,34 @@ export const SafeAreaView = React.forwardRef<
8190
} = flatStyle;
8291

8392
const paddingStyle = {
84-
paddingTop: paddingTop + insetTop,
85-
paddingRight: paddingRight + insetRight,
86-
paddingBottom: paddingBottom + insetBottom,
87-
paddingLeft: paddingLeft + insetLeft,
93+
paddingTop: getEdgeValue(insets.top, paddingTop, edgesRecord.top),
94+
paddingRight: getEdgeValue(
95+
insets.right,
96+
paddingRight,
97+
edgesRecord.right,
98+
),
99+
paddingBottom: getEdgeValue(
100+
insets.bottom,
101+
paddingBottom,
102+
edgesRecord.bottom,
103+
),
104+
paddingLeft: getEdgeValue(insets.left, paddingLeft, edgesRecord.left),
88105
};
89106

90107
return [style, paddingStyle];
91108
}
92-
}, [style, insets, mode, edgeBitmask]);
109+
}, [
110+
edgesRecord.bottom,
111+
edgesRecord.left,
112+
edgesRecord.right,
113+
edgesRecord.top,
114+
insets.bottom,
115+
insets.left,
116+
insets.right,
117+
insets.top,
118+
mode,
119+
style,
120+
]);
93121

94122
return <View style={appliedStyle} {...rest} ref={ref} />;
95123
});

0 commit comments

Comments
 (0)