@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "2.3.5",
3
+ "version": "2.4.5",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -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(props.visible,false));
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 props.visible =='boolean' && props.visible !== visible){
315
- setVisible(props.visible);
315
+ if(typeof dVisible =='boolean' && dVisible !== visible){
316
+ setVisible(dVisible);
316
317
  }
317
- },[props])
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},display?null: styles.hidden]}
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({prevDefaultValue:this.state.defaultValue,defaultValue:arg.value},()=>{
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,prevDefaultValue,action,ignoreCase,operator} = this.state;
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
- let prev = JSON.stringify(defaultObj(this.previousObj)),//{value:this.previousValue,operator:this.previousOperator,action:this.previousAction}
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
- let isFilterInitialized = this.props.dynamicRendered || this.isFilterInitialized;
196
- if(prev == "{}" && (isNullOrEmpty(tV) || value === 0) && (!isFilterInitialized) && (force !== true)) {
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.isFilterInitialized = true;
203
- this.previousObj = current;
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,prevDefaultValue:this.state.defaultValue},()=>{
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
  };
@@ -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.isRequired,
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 !== false ? <Fab
106
+ const fab = withFab ? <Fab
110
107
  {...fabProps}
111
108
  screenName={screenName}
112
109
  /> : null;