@fto-consult/expo-ui 2.4.0 → 2.4.6
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
|
@@ -7,15 +7,16 @@ import {MENU_ICON} from "$ecomponents/Icon";
|
|
|
7
7
|
import theme,{Colors} from "$theme";
|
|
8
8
|
import Group from "./GroupComponent";
|
|
9
9
|
import Portal from "$ecomponents/Portal";
|
|
10
|
+
import Auth from "$cauth";
|
|
10
11
|
|
|
11
12
|
const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
12
13
|
let {openedIcon,screenName,display:customDisplay,primary,actionMutator,secondary,onOpen,prepareActions,fabStyle,open:customOpen,onClose,onStateChange:customOnStateChange,closedIcon,color,actions:customActions,children,...customRest} = props;
|
|
13
|
-
|
|
14
14
|
const [state, setState] = React.useStateIfMounted({
|
|
15
15
|
open: typeof customOpen =='boolean'? customOpen : false,
|
|
16
16
|
display : typeof customDisplay ==='boolean'? customDisplay : true,
|
|
17
17
|
});
|
|
18
18
|
const onStateChange = ({ open,...rest}) => {
|
|
19
|
+
if(state.open == open) return;
|
|
19
20
|
setState({ ...state,open });
|
|
20
21
|
if(customOnStateChange){
|
|
21
22
|
customOnStateChange({open,...rest})
|
|
@@ -52,6 +53,7 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
|
52
53
|
color = theme.colors.secondaryText;
|
|
53
54
|
}
|
|
54
55
|
const actions = React.useCallback(()=>{
|
|
56
|
+
if(!open) return []
|
|
55
57
|
const actions = prepareActions === false && Array.isArray(customActions)? customActions : [];
|
|
56
58
|
if((prepareActions !== false || !actions.length)){
|
|
57
59
|
Object.map(customActions,(act,i)=>{
|
|
@@ -59,9 +61,9 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
|
59
61
|
act.label = defaultStr(act.label,act.text);
|
|
60
62
|
const a = actionMutator ? actionMutator ({action:act,key:i,isFab:true,fab:true}) : act;
|
|
61
63
|
if(!isObj(a) || !isNonNullString(a.label)) return null;
|
|
62
|
-
a.small = typeof a.small =='boolean'? a.small : false;
|
|
63
64
|
const {perm,isAllowed,primary,secondary,...restItem} = a;
|
|
64
65
|
if(typeof isAllowed =='function' && isAllowed() === false) return null;
|
|
66
|
+
if(isNonNullString(perm) && !Auth.isAllowedFromStr(perm)) return false;
|
|
65
67
|
if(primary){
|
|
66
68
|
restItem.style = StyleSheet.flatten([restItem.style,{color:theme.colors.primaryText,backgroundColor:theme.colors.primary}])
|
|
67
69
|
} else if(secondary){
|
|
@@ -72,7 +74,7 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
|
72
74
|
});
|
|
73
75
|
}
|
|
74
76
|
return actions;
|
|
75
|
-
},[customActions,prepareActions])();
|
|
77
|
+
},[customActions,prepareActions,open])();
|
|
76
78
|
|
|
77
79
|
React.useEffect(()=>{
|
|
78
80
|
React.setRef(innerRef,context);
|
|
@@ -85,7 +87,7 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
|
85
87
|
{...rest}
|
|
86
88
|
color = {color}
|
|
87
89
|
style = {[rest.style,styles.container]}
|
|
88
|
-
fabStyle = {[styles.fab,fabStyle,{backgroundColor}
|
|
90
|
+
fabStyle = {[styles.fab,fabStyle,{backgroundColor},!display && styles.hidden]}
|
|
89
91
|
open={open ?true : false}
|
|
90
92
|
icon={open ? openedIcon : closedIcon}
|
|
91
93
|
actions={actions}
|
|
@@ -135,6 +137,12 @@ const styles = StyleSheet.create({
|
|
|
135
137
|
},
|
|
136
138
|
hidden : {
|
|
137
139
|
display : 'none'
|
|
140
|
+
},
|
|
141
|
+
fab : {
|
|
142
|
+
position: 'absolute',
|
|
143
|
+
margin: 16,
|
|
144
|
+
right: 0,
|
|
145
|
+
bottom: 0,
|
|
138
146
|
}
|
|
139
147
|
})
|
|
140
148
|
|
|
@@ -13,6 +13,7 @@ import PropTypes from "prop-types";
|
|
|
13
13
|
import { StylePropTypes } from '$theme';
|
|
14
14
|
import Action from "$ecomponents/Form/Action";
|
|
15
15
|
import { disabledStyle,cursorNotAllowed } from '$theme';
|
|
16
|
+
import {defaultStr} from "$utils";
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
|
|
@@ -29,12 +30,12 @@ const FABGroup = ({
|
|
|
29
30
|
screenName,
|
|
30
31
|
fabStyle,
|
|
31
32
|
visible,
|
|
32
|
-
testID,
|
|
33
33
|
onStateChange,
|
|
34
34
|
color: colorProp,
|
|
35
|
+
testID,
|
|
35
36
|
...rest
|
|
36
37
|
}) => {
|
|
37
|
-
|
|
38
|
+
testID = defaultStr(testID,"RN_FabGroupComponent")
|
|
38
39
|
const { current: backdrop } = React.useRef(
|
|
39
40
|
new Animated.Value(0)
|
|
40
41
|
);
|
|
@@ -120,9 +121,10 @@ const FABGroup = ({
|
|
|
120
121
|
const Item = isFormAction ? Action : FabItem;
|
|
121
122
|
const itemComponentProps = isFormAction ? {Component : FabItem} : {};
|
|
122
123
|
return (
|
|
123
|
-
<View pointerEvents="box-none" style={[styles.container, style]}>
|
|
124
|
-
<TouchableWithoutFeedback onPress={close}>
|
|
124
|
+
<View testID={testID+"_Container"} pointerEvents="box-none" style={[styles.container, style]}>
|
|
125
|
+
<TouchableWithoutFeedback testID={testID+"_TouchableOpacity"} onPress={close}>
|
|
125
126
|
<Animated.View
|
|
127
|
+
testID={testID+"_AnimatedView"}
|
|
126
128
|
pointerEvents={open ? 'auto' : 'none'}
|
|
127
129
|
style={[
|
|
128
130
|
styles.backdrop,
|
|
@@ -133,8 +135,8 @@ const FABGroup = ({
|
|
|
133
135
|
]}
|
|
134
136
|
/>
|
|
135
137
|
</TouchableWithoutFeedback>
|
|
136
|
-
<SafeAreaView pointerEvents="box-none" style={styles.safeArea}>
|
|
137
|
-
<View pointerEvents={open ? 'box-none' : 'none'}>
|
|
138
|
+
<SafeAreaView testID={testID+"_SafeAreaView"} pointerEvents="box-none" style={styles.safeArea}>
|
|
139
|
+
<View testID={testID+"_ItemsContainer"} style={[styles.itemsContainer]} pointerEvents={open ? 'box-none' : 'none'}>
|
|
138
140
|
{actions.map((it, i) => {
|
|
139
141
|
const itemProps = {
|
|
140
142
|
labelColor : it.labelTextColor ?? it.labelColor ?? labelColor,
|
|
@@ -147,12 +149,13 @@ const FABGroup = ({
|
|
|
147
149
|
}
|
|
148
150
|
return (
|
|
149
151
|
<View
|
|
152
|
+
testID={testID+"_Item_"+i}
|
|
150
153
|
key={i} // eslint-disable-line react/no-array-index-key
|
|
151
154
|
style={[
|
|
152
155
|
styles.item,
|
|
153
156
|
{
|
|
154
157
|
marginHorizontal:
|
|
155
|
-
typeof it.small
|
|
158
|
+
typeof it.small || it.small ? 24 : 16,
|
|
156
159
|
},
|
|
157
160
|
]}
|
|
158
161
|
pointerEvents={open ? 'box-none' : 'none'}
|
|
@@ -181,7 +184,7 @@ const FABGroup = ({
|
|
|
181
184
|
accessibilityComponentType="button"
|
|
182
185
|
accessibilityRole="button"
|
|
183
186
|
accessibilityState={{ expanded: open }}
|
|
184
|
-
style={[styles.fab, fabStyle]}
|
|
187
|
+
style={StyleSheet.flatten([styles.fab, fabStyle])}
|
|
185
188
|
visible={visible}
|
|
186
189
|
testID={testID}
|
|
187
190
|
/>
|
|
@@ -278,8 +281,9 @@ FABGroup.propTypes = {
|
|
|
278
281
|
|
|
279
282
|
|
|
280
283
|
export const FabItem = function(props){
|
|
281
|
-
const {children,label,disabled:customDisabled,pointerEvents,open,close,testID,labelStyle,labelColor,accessibilityLabel,icon,backgroundColor,scale,opacity,color,style,small,onPress,...rest} = props;
|
|
284
|
+
const {children,label,disabled:customDisabled,pointerEvents,open,close,testID:customTestID,labelStyle,labelColor,accessibilityLabel,icon,backgroundColor,scale,opacity,color,style,small,onPress,...rest} = props;
|
|
282
285
|
const disabled = typeof customDisabled =='boolean'? customDisabled : false;
|
|
286
|
+
const testID = defaultStr(customTestID,"RN_FabItemComponent")
|
|
283
287
|
const _onPress = ()=>{
|
|
284
288
|
if(onPress){
|
|
285
289
|
onPress();
|
|
@@ -289,8 +293,9 @@ export const FabItem = function(props){
|
|
|
289
293
|
const dStyle = disabled ? disabledStyle : null;
|
|
290
294
|
return <>
|
|
291
295
|
{label ? (
|
|
292
|
-
<View style={dStyle} pointerEvents={pointerEvents}>
|
|
296
|
+
<View testID = {testID+"_LabelContainer"} style={dStyle} pointerEvents={pointerEvents}>
|
|
293
297
|
<Card
|
|
298
|
+
testID={testID+"_Card"}
|
|
294
299
|
style={
|
|
295
300
|
[
|
|
296
301
|
styles.label,
|
|
@@ -311,14 +316,14 @@ export const FabItem = function(props){
|
|
|
311
316
|
accessibilityComponentType="button"
|
|
312
317
|
accessibilityRole="button"
|
|
313
318
|
>
|
|
314
|
-
<Text style={{ color : labelColor }}>
|
|
319
|
+
<Text testID={testID+"_Label"} style={{ color : labelColor }}>
|
|
315
320
|
{label}
|
|
316
321
|
</Text>
|
|
317
322
|
</Card>
|
|
318
323
|
</View>
|
|
319
324
|
) : null}
|
|
320
325
|
<FAB
|
|
321
|
-
small={typeof small
|
|
326
|
+
small={typeof small =='boolean' ? small : true}
|
|
322
327
|
icon={icon}
|
|
323
328
|
color={color}
|
|
324
329
|
disabled = {disabled}
|
|
@@ -347,7 +352,7 @@ export const FabItem = function(props){
|
|
|
347
352
|
accessibilityRole="button"
|
|
348
353
|
testID={testID}
|
|
349
354
|
visible={open}
|
|
350
|
-
|
|
355
|
+
/>
|
|
351
356
|
</>
|
|
352
357
|
}
|
|
353
358
|
|
|
@@ -355,6 +360,9 @@ const styles = StyleSheet.create({
|
|
|
355
360
|
safeArea: {
|
|
356
361
|
alignItems: 'flex-end',
|
|
357
362
|
},
|
|
363
|
+
itemsContainer : {
|
|
364
|
+
marginBottom : 70,
|
|
365
|
+
},
|
|
358
366
|
container: {
|
|
359
367
|
...StyleSheet.absoluteFillObject,
|
|
360
368
|
justifyContent: 'flex-end',
|
package/src/layouts/Fab/index.js
CHANGED
|
@@ -11,7 +11,6 @@ import {sanitizeName} from "$escreens/utils";
|
|
|
11
11
|
export * from "./utils";
|
|
12
12
|
|
|
13
13
|
const FABContainer = React.forwardRef((props,ref)=>{
|
|
14
|
-
return null;
|
|
15
14
|
const {state,actions:customActions,screenName,...rest} = props;
|
|
16
15
|
const sScreenName = sanitizeName(screenName);
|
|
17
16
|
ref = ref || createFabRef(screenName);
|
|
@@ -55,6 +54,6 @@ const styles = StyleSheet.create({
|
|
|
55
54
|
export default FABContainer;
|
|
56
55
|
|
|
57
56
|
FABContainer.propTypes = {
|
|
58
|
-
screenName : PropTypes.string
|
|
57
|
+
screenName : PropTypes.string,
|
|
59
58
|
}
|
|
60
59
|
FABContainer.displayName = "FABContainer";
|
|
@@ -83,9 +83,6 @@ export default function MainScreenScreenWithOrWithoutAuthContainer(props) {
|
|
|
83
83
|
if(authRequired === false){
|
|
84
84
|
withFab = false;
|
|
85
85
|
}
|
|
86
|
-
if(typeof withFab !=='boolean'){
|
|
87
|
-
withFab = withDrawer;
|
|
88
|
-
}
|
|
89
86
|
React.useEffect(() => {
|
|
90
87
|
if((title||subtitle) && navigation && navigation.setOptions){
|
|
91
88
|
const appName = APP.getName().toUpperCase();
|
|
@@ -106,7 +103,7 @@ export default function MainScreenScreenWithOrWithoutAuthContainer(props) {
|
|
|
106
103
|
}
|
|
107
104
|
}, [title,subtitle]);
|
|
108
105
|
const Wrapper = modal ? Portal : React.Fragment;
|
|
109
|
-
const fab = withFab
|
|
106
|
+
const fab = withFab ? <Fab
|
|
110
107
|
{...fabProps}
|
|
111
108
|
screenName={screenName}
|
|
112
109
|
/> : null;
|