@fto-consult/expo-ui 8.12.7 → 8.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
@@ -0,0 +1,75 @@
|
|
1
|
+
import { StyleSheet, Dimensions } from "react-native"
|
2
|
+
|
3
|
+
const { width, height } = Dimensions.get("screen")
|
4
|
+
|
5
|
+
export const _staticBackground = (logoOpacity, backgroundColor) => [
|
6
|
+
logoOpacity,
|
7
|
+
StyleSheet.absoluteFill,
|
8
|
+
{ backgroundColor: backgroundColor || null },
|
9
|
+
]
|
10
|
+
|
11
|
+
export const _dynamicImageBackground = (
|
12
|
+
imageScale,
|
13
|
+
logoOpacity,
|
14
|
+
backgroundColor
|
15
|
+
) => [
|
16
|
+
imageScale,
|
17
|
+
logoOpacity,
|
18
|
+
{
|
19
|
+
...StyleSheet.absoluteFill,
|
20
|
+
width,
|
21
|
+
height,
|
22
|
+
top: 0,
|
23
|
+
alignItems: "center",
|
24
|
+
justifyContent: "center",
|
25
|
+
tintColor: backgroundColor || null,
|
26
|
+
},
|
27
|
+
]
|
28
|
+
|
29
|
+
export const _dynamicLogoStyle = (
|
30
|
+
logoScale,
|
31
|
+
logoOpacity,
|
32
|
+
logoWidth,
|
33
|
+
logoHeight
|
34
|
+
) => [
|
35
|
+
logoScale,
|
36
|
+
logoOpacity,
|
37
|
+
{
|
38
|
+
width: logoWidth || 150,
|
39
|
+
height: logoHeight || 150,
|
40
|
+
},
|
41
|
+
]
|
42
|
+
|
43
|
+
export const _dynamicCustomComponentStyle = (
|
44
|
+
logoScale,
|
45
|
+
logoOpacity,
|
46
|
+
logoWidth,
|
47
|
+
logoHeight
|
48
|
+
) => [
|
49
|
+
logoScale,
|
50
|
+
logoOpacity,
|
51
|
+
{
|
52
|
+
width: logoWidth || 150,
|
53
|
+
height: logoHeight || 150,
|
54
|
+
alignItems: "center",
|
55
|
+
justifyContent: "center",
|
56
|
+
},
|
57
|
+
]
|
58
|
+
|
59
|
+
export default {
|
60
|
+
container: {
|
61
|
+
flex: 1,
|
62
|
+
},
|
63
|
+
containerGlue: {
|
64
|
+
flex: 1,
|
65
|
+
alignContent: "center",
|
66
|
+
justifyContent: "center",
|
67
|
+
},
|
68
|
+
flex: {
|
69
|
+
flex: 1,
|
70
|
+
},
|
71
|
+
logoStyle: {
|
72
|
+
alignItems: "center",
|
73
|
+
justifyContent: "center",
|
74
|
+
},
|
75
|
+
}
|
@@ -0,0 +1,132 @@
|
|
1
|
+
/* @flow */
|
2
|
+
/*** fork of https://www.npmjs.com/package/react-native-animated-splash-screen */
|
3
|
+
import PropTypes from "prop-types"
|
4
|
+
import React from "$react"
|
5
|
+
import {Animated, StyleSheet } from "react-native";
|
6
|
+
import View from "$ecomponents/View";
|
7
|
+
import {isNativeMobile} from "$cplatform";
|
8
|
+
import {defaultDecimal} from "$cutils";
|
9
|
+
import {LogoProgress} from "$ecomponents/Logo";
|
10
|
+
import { Portal } from "react-native-paper";
|
11
|
+
import {defaultStr} from "$cutils";
|
12
|
+
import styles, {
|
13
|
+
_solidBackground,
|
14
|
+
_staticBackground,
|
15
|
+
_dynamicLogoStyle,
|
16
|
+
_dynamicCustomComponentStyle,
|
17
|
+
_dynamicImageBackground,
|
18
|
+
_dynamicBackgroundOpacity,
|
19
|
+
} from "./styles"
|
20
|
+
import {useAppComponent} from "$econtext/hooks";
|
21
|
+
|
22
|
+
const SplashScreenComponent = ({isLoaded,children , duration, delay,logoWidth,logoHeight,backgroundColor,imageBackgroundSource,imageBackgroundResizeMode,
|
23
|
+
testID})=>{
|
24
|
+
const [state,setState] = React.useState({
|
25
|
+
animationDone: false,
|
26
|
+
loadingProgress: new Animated.Value(0),
|
27
|
+
});
|
28
|
+
const { loadingProgress, animationDone} = state;
|
29
|
+
const prevIsLoaded = React.usePrevious(isLoaded);
|
30
|
+
const timerRef = React.useRef(null);
|
31
|
+
React.useEffect(()=>{
|
32
|
+
if(isLoaded && !prevIsLoaded){
|
33
|
+
Animated.timing(loadingProgress, {
|
34
|
+
toValue: 100,
|
35
|
+
duration: duration || 100,
|
36
|
+
delay: delay || 0,
|
37
|
+
useNativeDriver: isNativeMobile(),
|
38
|
+
}).start(() => {
|
39
|
+
setState({
|
40
|
+
...state,
|
41
|
+
animationDone:true,
|
42
|
+
})
|
43
|
+
})
|
44
|
+
} else if(isLoaded){
|
45
|
+
clearTimeout(timerRef.current);
|
46
|
+
timerRef.current = setTimeout(()=>{
|
47
|
+
if(isLoaded && !animationDone){
|
48
|
+
setState({...state,animationDone:true});
|
49
|
+
}
|
50
|
+
clearTimeout(timerRef.current);
|
51
|
+
},delay|2000);
|
52
|
+
}
|
53
|
+
},[isLoaded,prevIsLoaded,animationDone]);
|
54
|
+
testID = defaultStr(testID,"RN_SplashscreenComponent")
|
55
|
+
logoWidth = defaultDecimal(logoWidth,150);
|
56
|
+
logoHeight = defaultDecimal(logoHeight,250);
|
57
|
+
const Component = useAppComponent("SplashScreen");
|
58
|
+
|
59
|
+
const logoScale = {
|
60
|
+
transform: [
|
61
|
+
{
|
62
|
+
scale: loadingProgress.interpolate({
|
63
|
+
inputRange: [0, 10, 100],
|
64
|
+
outputRange: [1, 0.8, 10],
|
65
|
+
}),
|
66
|
+
},
|
67
|
+
],
|
68
|
+
}
|
69
|
+
|
70
|
+
const logoOpacity = {
|
71
|
+
opacity: loadingProgress.interpolate({
|
72
|
+
inputRange: [0, 20, 100],
|
73
|
+
outputRange: [1, 0, 0],
|
74
|
+
extrapolate: "clamp",
|
75
|
+
}),
|
76
|
+
}
|
77
|
+
if(isLoaded && animationDone){
|
78
|
+
return React.isValidElement(children)?children:null;
|
79
|
+
}
|
80
|
+
return <>
|
81
|
+
{!animationDone || !isLoaded ? <Portal>
|
82
|
+
<View style={[styles.container,{backgroundColor}]} testID={testID} id={testID}>
|
83
|
+
{<View style={[StyleSheet.absoluteFill,{backgroundColor}]} testID={testID+"_Animation"}/>}
|
84
|
+
<View style={styles.containerGlue} testID={testID+"_ContainerGlue"}>
|
85
|
+
{(
|
86
|
+
<Animated.View
|
87
|
+
style={_staticBackground(logoOpacity, backgroundColor)}
|
88
|
+
testID={testID+"_AnimationDone"}
|
89
|
+
/>
|
90
|
+
)}
|
91
|
+
{(
|
92
|
+
React.isComponent(Component)? <Component testID={testID+"_CustomSplashComponent"}/> :
|
93
|
+
<View testID={testID+"_LogoContainer"} style={[StyleSheet.absoluteFill,{backgroundColor}, styles.logoStyle]}>
|
94
|
+
<Animated.View
|
95
|
+
testID={testID+"_Logo"}
|
96
|
+
style={_dynamicCustomComponentStyle(
|
97
|
+
logoScale,
|
98
|
+
logoOpacity,
|
99
|
+
logoWidth,
|
100
|
+
logoHeight
|
101
|
+
)}>
|
102
|
+
{<LogoProgress />}
|
103
|
+
</Animated.View>
|
104
|
+
</View>
|
105
|
+
)}
|
106
|
+
</View>
|
107
|
+
</View>
|
108
|
+
</Portal> : null}
|
109
|
+
</>
|
110
|
+
}
|
111
|
+
|
112
|
+
|
113
|
+
SplashScreenComponent.propTypes = {
|
114
|
+
preload: PropTypes.bool,
|
115
|
+
logoWidth: PropTypes.number,
|
116
|
+
children: PropTypes.element,
|
117
|
+
logoHeight: PropTypes.number,
|
118
|
+
backgroundColor: PropTypes.string,
|
119
|
+
isLoaded: PropTypes.bool.isRequired,
|
120
|
+
disableBackgroundImage: PropTypes.bool,
|
121
|
+
logoImage: PropTypes.oneOfType([
|
122
|
+
PropTypes.string,
|
123
|
+
PropTypes.number,
|
124
|
+
PropTypes.object,
|
125
|
+
]),
|
126
|
+
disableAppScale: PropTypes.bool,
|
127
|
+
duration: PropTypes.number,
|
128
|
+
delay: PropTypes.number,
|
129
|
+
}
|
130
|
+
|
131
|
+
SplashScreenComponent.displayName = "SplashScreenComponent";
|
132
|
+
export default SplashScreenComponent;
|
@@ -1,96 +1,134 @@
|
|
1
|
+
//@see : https://www.npmjs.com/package/react-native-animated-splash-screen
|
2
|
+
|
1
3
|
/* @flow */
|
2
|
-
/*** fork of https://www.npmjs.com/package/react-native-animated-splash-screen */
|
3
4
|
import PropTypes from "prop-types"
|
4
|
-
import React from "
|
5
|
-
import {Animated, StyleSheet } from "react-native"
|
6
|
-
import View from "$ecomponents/View";
|
7
|
-
import {isNativeMobile} from "$cplatform";
|
8
|
-
import {defaultDecimal} from "$cutils";
|
9
|
-
import {LogoProgress} from "$ecomponents/Logo";
|
10
|
-
import { Portal } from "react-native-paper";
|
11
|
-
import {defaultStr} from "$cutils";
|
5
|
+
import * as React from "react"
|
6
|
+
import { Animated, StatusBar, StyleSheet } from "react-native"
|
12
7
|
import styles, {
|
13
|
-
_solidBackground,
|
14
8
|
_staticBackground,
|
15
9
|
_dynamicLogoStyle,
|
16
10
|
_dynamicCustomComponentStyle,
|
17
11
|
_dynamicImageBackground,
|
18
12
|
_dynamicBackgroundOpacity,
|
19
|
-
} from "./
|
20
|
-
import
|
13
|
+
} from "./AnimatedSplash.style";
|
14
|
+
import View from "$ecomponents/View";
|
15
|
+
import {isNativeMobile} from "$cplatform";
|
16
|
+
import {defaultDecimal} from "$cutils";
|
17
|
+
import {LogoProgress} from "$ecomponents/Logo";
|
18
|
+
import { Portal } from "react-native-paper";
|
19
|
+
import {defaultStr} from "$cutils";
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
class AnimatedSplash extends React.Component {
|
22
|
+
static defaultProps = {
|
23
|
+
isLoaded: false,
|
24
|
+
}
|
25
|
+
|
26
|
+
state = {
|
25
27
|
animationDone: false,
|
26
28
|
loadingProgress: new Animated.Value(0),
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
showStatusBar: true,
|
30
|
+
}
|
31
|
+
|
32
|
+
componentDidUpdate(prevProps) {
|
33
|
+
const { isLoaded , duration, delay } = this.props
|
34
|
+
const { loadingProgress } = this.state
|
35
|
+
if (isLoaded && !prevProps.isLoaded) {
|
33
36
|
Animated.timing(loadingProgress, {
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
toValue: 100,
|
38
|
+
duration: duration || 1000,
|
39
|
+
delay: delay || 0,
|
40
|
+
useNativeDriver: isNativeMobile(),
|
38
41
|
}).start(() => {
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
})
|
42
|
+
this.setState({
|
43
|
+
animationDone: true,
|
44
|
+
})
|
43
45
|
})
|
44
|
-
} else if(isLoaded){
|
45
|
-
clearTimeout(timerRef.current);
|
46
|
-
timerRef.current = setTimeout(()=>{
|
47
|
-
if(isLoaded && !animationDone){
|
48
|
-
setState({...state,animationDone:true});
|
49
|
-
}
|
50
|
-
clearTimeout(timerRef.current);
|
51
|
-
},delay|2000);
|
52
46
|
}
|
53
|
-
},[isLoaded,prevIsLoaded,animationDone]);
|
54
|
-
testID = defaultStr(testID,"RN_SplashscreenComponent")
|
55
|
-
logoWidth = defaultDecimal(logoWidth,150);
|
56
|
-
logoHeight = defaultDecimal(logoHeight,250);
|
57
|
-
const Component = useAppComponent("SplashScreen");
|
58
|
-
|
59
|
-
const logoScale = {
|
60
|
-
transform: [
|
61
|
-
{
|
62
|
-
scale: loadingProgress.interpolate({
|
63
|
-
inputRange: [0, 10, 100],
|
64
|
-
outputRange: [1, 0.8, 10],
|
65
|
-
}),
|
66
|
-
},
|
67
|
-
],
|
68
47
|
}
|
69
48
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
}
|
77
|
-
if(isLoaded && animationDone){
|
78
|
-
return React.isValidElement(children)?children:null;
|
49
|
+
renderChildren() {
|
50
|
+
const { children, preload, isLoaded } = this.props
|
51
|
+
if (isLoaded) {
|
52
|
+
return children
|
53
|
+
}
|
54
|
+
return null
|
79
55
|
}
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
56
|
+
|
57
|
+
render() {
|
58
|
+
const { loadingProgress, animationDone } = this.state
|
59
|
+
const {
|
60
|
+
logoImage,
|
61
|
+
logoWidth,
|
62
|
+
logoHeight,
|
63
|
+
backgroundColor,
|
64
|
+
customComponent,
|
65
|
+
disableAppScale,
|
66
|
+
} = this.props
|
67
|
+
|
68
|
+
const opacityClearToVisible = {
|
69
|
+
opacity: loadingProgress.interpolate({
|
70
|
+
inputRange: [0, 15, 30],
|
71
|
+
outputRange: [0, 0, 1],
|
72
|
+
extrapolate: "clamp",
|
73
|
+
}),
|
74
|
+
}
|
75
|
+
|
76
|
+
const imageScale = {
|
77
|
+
transform: [
|
78
|
+
{
|
79
|
+
scale: loadingProgress.interpolate({
|
80
|
+
inputRange: [0, 10, 100],
|
81
|
+
outputRange: [1, 1, 65],
|
82
|
+
}),
|
83
|
+
},
|
84
|
+
],
|
85
|
+
}
|
86
|
+
|
87
|
+
const logoScale = {
|
88
|
+
transform: [
|
89
|
+
{
|
90
|
+
scale: loadingProgress.interpolate({
|
91
|
+
inputRange: [0, 10, 100],
|
92
|
+
outputRange: [1, 0.8, 10],
|
93
|
+
}),
|
94
|
+
},
|
95
|
+
],
|
96
|
+
}
|
97
|
+
|
98
|
+
const logoOpacity = {
|
99
|
+
opacity: loadingProgress.interpolate({
|
100
|
+
inputRange: [0, 20, 100],
|
101
|
+
outputRange: [1, 0, 0],
|
102
|
+
extrapolate: "clamp",
|
103
|
+
}),
|
104
|
+
}
|
105
|
+
|
106
|
+
const appScale = {
|
107
|
+
transform: [
|
108
|
+
{
|
109
|
+
scale: loadingProgress.interpolate({
|
110
|
+
inputRange: [0, 7, 100],
|
111
|
+
outputRange: [1.1, 1.05, 1],
|
112
|
+
}),
|
113
|
+
},
|
114
|
+
],
|
115
|
+
}
|
116
|
+
const testID = defaultStr(testID,"RN_MainSplashScreen")
|
117
|
+
return (
|
118
|
+
<View testID={testID} style={[styles.container]}>
|
119
|
+
{!animationDone && <View style={StyleSheet.absoluteFill} />}
|
120
|
+
<View style={styles.containerGlue}>
|
121
|
+
{!animationDone && (
|
122
|
+
<Animated.View
|
123
|
+
style={_staticBackground(logoOpacity, backgroundColor)}
|
124
|
+
/>
|
125
|
+
)}
|
126
|
+
<Animated.View style={[!disableAppScale && appScale, opacityClearToVisible, styles.flex]}>
|
127
|
+
{this.renderChildren()}
|
128
|
+
</Animated.View>
|
129
|
+
{!animationDone && (
|
130
|
+
<View style={[StyleSheet.absoluteFill, styles.logoStyle]}>
|
131
|
+
{<View testID={testID+"_LogoContainer"} style={[StyleSheet.absoluteFill,{backgroundColor}, styles.logoStyle]}>
|
94
132
|
<Animated.View
|
95
133
|
testID={testID+"_Logo"}
|
96
134
|
style={_dynamicCustomComponentStyle(
|
@@ -101,32 +139,27 @@ const SplashScreenComponent = ({isLoaded,children , duration, delay,logoWidth,lo
|
|
101
139
|
)}>
|
102
140
|
{<LogoProgress />}
|
103
141
|
</Animated.View>
|
104
|
-
</View>
|
105
|
-
)}
|
142
|
+
</View>}
|
106
143
|
</View>
|
107
|
-
|
108
|
-
|
109
|
-
|
144
|
+
)}
|
145
|
+
</View>
|
146
|
+
</View>
|
147
|
+
)
|
148
|
+
}
|
110
149
|
}
|
111
150
|
|
112
|
-
|
113
|
-
SplashScreenComponent.propTypes = {
|
151
|
+
AnimatedSplash.propTypes = {
|
114
152
|
preload: PropTypes.bool,
|
115
153
|
logoWidth: PropTypes.number,
|
116
154
|
children: PropTypes.element,
|
117
155
|
logoHeight: PropTypes.number,
|
118
156
|
backgroundColor: PropTypes.string,
|
119
157
|
isLoaded: PropTypes.bool.isRequired,
|
120
|
-
|
121
|
-
|
122
|
-
PropTypes.string,
|
123
|
-
PropTypes.number,
|
124
|
-
PropTypes.object,
|
125
|
-
]),
|
158
|
+
translucent: PropTypes.bool,
|
159
|
+
customComponent: PropTypes.element,
|
126
160
|
disableAppScale: PropTypes.bool,
|
127
161
|
duration: PropTypes.number,
|
128
162
|
delay: PropTypes.number,
|
129
163
|
}
|
130
164
|
|
131
|
-
|
132
|
-
export default SplashScreenComponent;
|
165
|
+
export default AnimatedSplash
|