@fto-consult/expo-ui 2.3.5 → 2.4.5
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 +1 -1
- package/src/components/Dialog/Dialog.js +6 -5
- package/src/components/Fab/Group.js +12 -3
- package/src/components/Fab/GroupComponent.js +8 -5
- package/src/components/Filter/index.js +14 -9
- package/src/components/Form/FormData/DialogProvider.js +2 -0
- package/src/layouts/Fab/index.js +1 -2
- package/src/layouts/Screen/ScreenWithOrWithoutAuthContainer.js +1 -4
package/package.json
CHANGED
|
@@ -20,6 +20,7 @@ import {ACTION_ICON_SIZE} from "$ecomponents/AppBar";
|
|
|
20
20
|
import DialogFooter from "./DialogFooter";
|
|
21
21
|
import { Dimensions } from "react-native";
|
|
22
22
|
import Surface from "$ecomponents/Surface";
|
|
23
|
+
import stableHash from "stable-hash";
|
|
23
24
|
|
|
24
25
|
export const FOOTER_HEIGHT = 50;
|
|
25
26
|
export const HEADER_HEIGHT = 50;
|
|
@@ -307,14 +308,14 @@ DialogComponent.propTypes= {
|
|
|
307
308
|
}
|
|
308
309
|
|
|
309
310
|
|
|
310
|
-
export const DialogControlledComponent = React.forwardRef((props,ref)=>{
|
|
311
|
-
const [visible,setVisible] = React.useStateIfMounted(defaultBool(
|
|
311
|
+
export const DialogControlledComponent = React.forwardRef(({visible:dVisible,...props},ref)=>{
|
|
312
|
+
const [visible,setVisible] = React.useStateIfMounted(defaultBool(dVisible,false));
|
|
312
313
|
const {onDismiss,onClose,onVisibilityChanged,...rest} = props;
|
|
313
314
|
React.useEffect(()=>{
|
|
314
|
-
if(typeof
|
|
315
|
-
setVisible(
|
|
315
|
+
if(typeof dVisible =='boolean' && dVisible !== visible){
|
|
316
|
+
setVisible(dVisible);
|
|
316
317
|
}
|
|
317
|
-
},[
|
|
318
|
+
},[dVisible])
|
|
318
319
|
const close = x=> setVisible(false);
|
|
319
320
|
const open = x => setVisible(true);
|
|
320
321
|
const isOpen=x=>visible,isClosed = x=>!visible;
|
|
@@ -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)=>{
|
|
@@ -62,6 +64,7 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
|
62
64
|
a.small = typeof a.small =='boolean'? a.small : false;
|
|
63
65
|
const {perm,isAllowed,primary,secondary,...restItem} = a;
|
|
64
66
|
if(typeof isAllowed =='function' && isAllowed() === false) return null;
|
|
67
|
+
if(isNonNullString(perm) && !Auth.isAllowedFromStr(perm)) return false;
|
|
65
68
|
if(primary){
|
|
66
69
|
restItem.style = StyleSheet.flatten([restItem.style,{color:theme.colors.primaryText,backgroundColor:theme.colors.primary}])
|
|
67
70
|
} else if(secondary){
|
|
@@ -72,7 +75,7 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
|
72
75
|
});
|
|
73
76
|
}
|
|
74
77
|
return actions;
|
|
75
|
-
},[customActions,prepareActions])();
|
|
78
|
+
},[customActions,prepareActions,open])();
|
|
76
79
|
|
|
77
80
|
React.useEffect(()=>{
|
|
78
81
|
React.setRef(innerRef,context);
|
|
@@ -85,7 +88,7 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
|
85
88
|
{...rest}
|
|
86
89
|
color = {color}
|
|
87
90
|
style = {[rest.style,styles.container]}
|
|
88
|
-
fabStyle = {[styles.fab,fabStyle,{backgroundColor}
|
|
91
|
+
fabStyle = {[styles.fab,fabStyle,{backgroundColor},!display && styles.hidden]}
|
|
89
92
|
open={open ?true : false}
|
|
90
93
|
icon={open ? openedIcon : closedIcon}
|
|
91
94
|
actions={actions}
|
|
@@ -135,6 +138,12 @@ const styles = StyleSheet.create({
|
|
|
135
138
|
},
|
|
136
139
|
hidden : {
|
|
137
140
|
display : 'none'
|
|
141
|
+
},
|
|
142
|
+
fab : {
|
|
143
|
+
position: 'absolute',
|
|
144
|
+
margin: 16,
|
|
145
|
+
right: 0,
|
|
146
|
+
bottom: 0,
|
|
138
147
|
}
|
|
139
148
|
})
|
|
140
149
|
|
|
@@ -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
|
|
|
@@ -181,7 +182,7 @@ const FABGroup = ({
|
|
|
181
182
|
accessibilityComponentType="button"
|
|
182
183
|
accessibilityRole="button"
|
|
183
184
|
accessibilityState={{ expanded: open }}
|
|
184
|
-
style={[styles.fab, fabStyle]}
|
|
185
|
+
style={StyleSheet.flatten([styles.fab, fabStyle])}
|
|
185
186
|
visible={visible}
|
|
186
187
|
testID={testID}
|
|
187
188
|
/>
|
|
@@ -278,8 +279,9 @@ FABGroup.propTypes = {
|
|
|
278
279
|
|
|
279
280
|
|
|
280
281
|
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;
|
|
282
|
+
const {children,label,disabled:customDisabled,pointerEvents,open,close,testID:customTestID,labelStyle,labelColor,accessibilityLabel,icon,backgroundColor,scale,opacity,color,style,small,onPress,...rest} = props;
|
|
282
283
|
const disabled = typeof customDisabled =='boolean'? customDisabled : false;
|
|
284
|
+
const testID = defaultStr(customTestID,"RN_FabGroupComponent")
|
|
283
285
|
const _onPress = ()=>{
|
|
284
286
|
if(onPress){
|
|
285
287
|
onPress();
|
|
@@ -289,8 +291,9 @@ export const FabItem = function(props){
|
|
|
289
291
|
const dStyle = disabled ? disabledStyle : null;
|
|
290
292
|
return <>
|
|
291
293
|
{label ? (
|
|
292
|
-
<View style={dStyle} pointerEvents={pointerEvents}>
|
|
294
|
+
<View testID = {testID+"_LabelContainer"} style={dStyle} pointerEvents={pointerEvents}>
|
|
293
295
|
<Card
|
|
296
|
+
testID={testID+"_Card"}
|
|
294
297
|
style={
|
|
295
298
|
[
|
|
296
299
|
styles.label,
|
|
@@ -311,7 +314,7 @@ export const FabItem = function(props){
|
|
|
311
314
|
accessibilityComponentType="button"
|
|
312
315
|
accessibilityRole="button"
|
|
313
316
|
>
|
|
314
|
-
<Text style={{ color : labelColor }}>
|
|
317
|
+
<Text testID={testID+"_Label"} style={{ color : labelColor }}>
|
|
315
318
|
{label}
|
|
316
319
|
</Text>
|
|
317
320
|
</Card>
|
|
@@ -347,7 +350,7 @@ export const FabItem = function(props){
|
|
|
347
350
|
accessibilityRole="button"
|
|
348
351
|
testID={testID}
|
|
349
352
|
visible={open}
|
|
350
|
-
|
|
353
|
+
/>
|
|
351
354
|
</>
|
|
352
355
|
}
|
|
353
356
|
|
|
@@ -88,6 +88,12 @@ export default class Filter extends AppComponent {
|
|
|
88
88
|
Object.defineProperties(this,{
|
|
89
89
|
fireFilterSearch : {
|
|
90
90
|
value : this.filterValidationTimeout ? debounce(this.fireValueChanged.bind(this),this.filterValidationTimeout) : this.fireValueChanged.bind(this),
|
|
91
|
+
},
|
|
92
|
+
isInitializedRef : {
|
|
93
|
+
value : {current:false}
|
|
94
|
+
},
|
|
95
|
+
previousRef : {
|
|
96
|
+
value : {current : null}
|
|
91
97
|
}
|
|
92
98
|
})
|
|
93
99
|
extendObj(this.state,{
|
|
@@ -134,7 +140,7 @@ export default class Filter extends AppComponent {
|
|
|
134
140
|
if(JSON.stringify(this.state.defaultValue) === JSON.stringify(arg.value)){
|
|
135
141
|
return;
|
|
136
142
|
}
|
|
137
|
-
this.setState({
|
|
143
|
+
this.setState({defaultValue:arg.value},()=>{
|
|
138
144
|
this.callOnValidate(arg);
|
|
139
145
|
if(!isNumber(this.filterValidationTimeout)){
|
|
140
146
|
this.filterValidationTimeout = 0;
|
|
@@ -178,7 +184,7 @@ export default class Filter extends AppComponent {
|
|
|
178
184
|
}
|
|
179
185
|
fireValueChanged (forceRun){
|
|
180
186
|
if(this.willRunManually() && !forceRun) return;
|
|
181
|
-
let {defaultValue:value,
|
|
187
|
+
let {defaultValue:value,action,ignoreCase,operator} = this.state;
|
|
182
188
|
let force = forceRun ===true ? true : false;
|
|
183
189
|
if(!isObjOrArray(value) && (isNullOrEmpty(value,true) || value ==='undefined') ){
|
|
184
190
|
value = undefined;
|
|
@@ -189,18 +195,17 @@ export default class Filter extends AppComponent {
|
|
|
189
195
|
if(action =="$today" || action =='$yesterday'){
|
|
190
196
|
force = true;
|
|
191
197
|
}
|
|
192
|
-
|
|
193
|
-
current = {value,operator,action,ignoreCase};
|
|
198
|
+
const prev = JSON.stringify(defaultObj(this.previousRef.current)), current = {value,operator,action,ignoreCase};
|
|
194
199
|
let tV = isArray(value) && value.length <= 0 ? undefined : value;
|
|
195
|
-
|
|
196
|
-
if(prev == "{}" && (isNullOrEmpty(tV) || value === 0) && (!
|
|
200
|
+
this.isInitializedRef.current = this.props.dynamicRendered || this.isInitializedRef.current;
|
|
201
|
+
if(prev == "{}" && (isNullOrEmpty(tV) || value === 0) && (!this.isInitializedRef.current) && (force !== true)) {
|
|
197
202
|
return this;
|
|
198
203
|
}
|
|
199
204
|
if(prev == JSON.stringify(current) && (force !== true)){
|
|
200
205
|
return this;
|
|
201
206
|
}
|
|
202
|
-
this.
|
|
203
|
-
this.
|
|
207
|
+
this.isInitializedRef.current = true;
|
|
208
|
+
this.previousRef.current = current;
|
|
204
209
|
if(isFunction(this.props.onChange)){
|
|
205
210
|
let selector = {};
|
|
206
211
|
selector[this.props.field] = action;
|
|
@@ -353,7 +358,7 @@ export default class Filter extends AppComponent {
|
|
|
353
358
|
})
|
|
354
359
|
}
|
|
355
360
|
clearFilter(event){
|
|
356
|
-
this.setState({defaultValue:undefined
|
|
361
|
+
this.setState({defaultValue:undefined},()=>{
|
|
357
362
|
this.callOnValidate();
|
|
358
363
|
this.fireValueChanged(true);
|
|
359
364
|
let {onClearFilter,onResetFilter} = this.props;
|
|
@@ -21,6 +21,7 @@ const FormDataDialogProvider = React.forwardRef((props,innerRef)=>{
|
|
|
21
21
|
const {closeAction,onDismiss} = props;
|
|
22
22
|
const context = {
|
|
23
23
|
open : (props)=>{
|
|
24
|
+
if(state.visible) return;
|
|
24
25
|
let sData = {};
|
|
25
26
|
if(formRef.current && formRef.current.formDataContext && formRef.current.formDataContext.getData){
|
|
26
27
|
sData.data = formRef.current.formDataContext.getData();
|
|
@@ -28,6 +29,7 @@ const FormDataDialogProvider = React.forwardRef((props,innerRef)=>{
|
|
|
28
29
|
return setState({...state,...sData,onDismiss:undefined,...defaultObj(props),visible:true})
|
|
29
30
|
},
|
|
30
31
|
close : (props)=>{
|
|
32
|
+
if(!state.visible) return;
|
|
31
33
|
setState({...state,...defaultObj(props),visible:false});
|
|
32
34
|
},
|
|
33
35
|
};
|
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;
|