11import * 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