@fto-consult/expo-ui 1.2.6 → 1.2.8

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/index.js CHANGED
@@ -9,7 +9,6 @@ import appConfig from "$capp/config";
9
9
  */
10
10
  export default function ExpoUIApp (options){
11
11
  options = options && typeof options =='object' && !Array.isArray(options)? options : {};
12
- const config = defaultObj(options.config);
13
- appConfig.current = config;
12
+ appConfig.current = options.config;
14
13
  registerRootComponent(require('./src/App').default(options));
15
14
  }
package/package.json CHANGED
@@ -1,102 +1,102 @@
1
- {
2
- "name": "@fto-consult/expo-ui",
3
- "version": "1.2.6",
4
- "description": "Bibliothèque de composants UI Expo,react-native",
5
- "main": "index.js",
6
- "scripts": {
7
- "publish1": "npm publish --access=public",
8
- "unpublish": "npm -f unpublish @fto-consult/expo-ui",
9
- "build-web": "",
10
- "dev": "npx expo start -c --no-minify",
11
- "start": "npx expo start --dev --no-minify",
12
- "start-d": "npx expo start -c --no-dev --no-minify",
13
- "start-p": "npm run start-d",
14
- "expo-start-client": "npx expo start --dev --no-minify --dev-client",
15
- "start-m": "npx expo start - c--dev--no -minify",
16
- "android": "npx expo start --android -c",
17
- "ios": "npx expo start --ios",
18
- "web": "npx expo start --web",
19
- "web-c": "npx expo start --web -c",
20
- "eject": "expo eject",
21
- "emulator": "npm run android-emulator",
22
- "web-server": "npx serve web-build",
23
- "build-android": "eas build --clear-cache -p android --profile preview",
24
- "build-android-local": "eas build --platform android --local",
25
- "build-android-dist": "eas build --clear-cache -p android",
26
- "build-ios": "eas build --clear-cache -p ios --profile preview",
27
- "build-ios-dist": "eas build --clear-cache -p ios",
28
- "install-apk": "adb -s emulator-5554 install myapp.apk",
29
- "android-emulator": "emulator -avd EMULATOR",
30
- "flipper": "npx cross-env METRO_SERVER_PORT=19000 E:\\Studies\\react-native\\debugger\\Flipper-win\\Flipper.exe",
31
- "build-electron": "electron-webpack && electron-builder --dir -c.compression=store",
32
- "test:build": "electron-webpack && electron-builder --dir -c.compression=store -c.mac.identity=null",
33
- "compile-electron": "webpack --config ./electron/webpack.config.js",
34
- "compile-electron-p": "webpack --config ./electron/webpack.config.js --mode=production",
35
- "electron": "electron ./electron",
36
- "logcat": "adb -d logcat com.ftc.apps.salite1:E > errors.txt",
37
- "logcat-export": "adb -d logcat com.ftc.apps.salite1 *:S > logcat.txt",
38
- "electron-c": "npm run compile-electron && npm run electron",
39
- "electron-p": "npm run compile-electron-p && npm run electron",
40
- "update-app-version": "node ./update-app-version.js",
41
- "find-licenses": "node ./find-licenses.js",
42
- "fix-dependencies": "expo doctor --fix-dependencies"
43
- },
44
- "repository": {
45
- "type": "git",
46
- "url": "git+https://github.com/borispipo/expo-ui.git"
47
- },
48
- "keywords": [
49
- "Expo",
50
- "React-Native"
51
- ],
52
- "author": "Boris Fouomene",
53
- "license": "ISC",
54
- "bugs": {
55
- "url": "https://github.com/borispipo/expo-ui/issues"
56
- },
57
- "homepage": "https://github.com/borispipo/expo-ui#readme",
58
- "dependencies": {
59
- "@babel/preset-react": "^7.18.6",
60
- "@emotion/native": "^11.10.0",
61
- "@expo/html-elements": "^0.2.0",
62
- "@expo/metro-config": "^0.4.0",
63
- "@expo/webpack-config": "^0.17.2",
64
- "@fto-consult/common": "^1.4.4",
65
- "@gorhom/portal": "^1.0.14",
66
- "@react-native-async-storage/async-storage": "~1.17.3",
67
- "@react-native-community/datetimepicker": "6.2.0",
68
- "@react-native-community/netinfo": "9.3.0",
69
- "@react-navigation/native": "^6.0.13",
70
- "@react-navigation/native-stack": "^6.9.1",
71
- "@shopify/flash-list": "1.1.0",
72
- "babel-plugin-inline-dotenv": "^1.7.0",
73
- "babel-plugin-module-resolver": "^4.1.0",
74
- "babel-plugin-transform-inline-environment-variables": "^0.4.4",
75
- "expo": "^46.0.15",
76
- "expo-camera": "~12.3.0",
77
- "expo-image-picker": "~13.3.1",
78
- "expo-linking": "~3.2.2",
79
- "expo-sqlite": "~10.3.0",
80
- "expo-status-bar": "~1.4.0",
81
- "expo-system-ui": "~1.3.0",
82
- "expo-web-browser": "~11.0.0",
83
- "google-libphonenumber": "^3.2.31",
84
- "htmlparser2-without-node-native": "^3.9.2",
85
- "parent-package-json": "^2.0.1",
86
- "prop-types": "^15.8.1",
87
- "react-apexcharts": "^1.4.0",
88
- "react-content-loader": "^6.2.0",
89
- "react-dom": "18.0.0",
90
- "react-native-big-list": "^1.5.5",
91
- "react-native-gesture-handler": "~2.5.0",
92
- "react-native-paper": "^4.12.5",
93
- "react-native-paper-dates": "^0.9.2",
94
- "react-native-reanimated": "~2.9.1",
95
- "react-native-safe-area-context": "4.3.1",
96
- "react-native-svg": "12.3.0",
97
- "react-native-web": "~0.18.7",
98
- "react-native-webview": "11.23.0",
99
- "sharp-cli": "^2.1.0",
100
- "tippy.js": "^6.3.7"
101
- }
102
- }
1
+ {
2
+ "name": "@fto-consult/expo-ui",
3
+ "version": "1.2.8",
4
+ "description": "Bibliothèque de composants UI Expo,react-native",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "publish1": "npm publish --access=public",
8
+ "unpublish": "npm -f unpublish @fto-consult/expo-ui",
9
+ "build-web": "",
10
+ "dev": "npx expo start -c --no-minify",
11
+ "start": "npx expo start --dev --no-minify",
12
+ "start-d": "npx expo start -c --no-dev --no-minify",
13
+ "start-p": "npm run start-d",
14
+ "expo-start-client": "npx expo start --dev --no-minify --dev-client",
15
+ "start-m": "npx expo start - c--dev--no -minify",
16
+ "android": "npx expo start --android -c",
17
+ "ios": "npx expo start --ios",
18
+ "web": "npx expo start --web",
19
+ "web-c": "npx expo start --web -c",
20
+ "eject": "expo eject",
21
+ "emulator": "npm run android-emulator",
22
+ "web-server": "npx serve web-build",
23
+ "build-android": "eas build --clear-cache -p android --profile preview",
24
+ "build-android-local": "eas build --platform android --local",
25
+ "build-android-dist": "eas build --clear-cache -p android",
26
+ "build-ios": "eas build --clear-cache -p ios --profile preview",
27
+ "build-ios-dist": "eas build --clear-cache -p ios",
28
+ "install-apk": "adb -s emulator-5554 install myapp.apk",
29
+ "android-emulator": "emulator -avd EMULATOR",
30
+ "flipper": "npx cross-env METRO_SERVER_PORT=19000 E:\\Studies\\react-native\\debugger\\Flipper-win\\Flipper.exe",
31
+ "build-electron": "electron-webpack && electron-builder --dir -c.compression=store",
32
+ "test:build": "electron-webpack && electron-builder --dir -c.compression=store -c.mac.identity=null",
33
+ "compile-electron": "webpack --config ./electron/webpack.config.js",
34
+ "compile-electron-p": "webpack --config ./electron/webpack.config.js --mode=production",
35
+ "electron": "electron ./electron",
36
+ "logcat": "adb -d logcat com.ftc.apps.salite1:E > errors.txt",
37
+ "logcat-export": "adb -d logcat com.ftc.apps.salite1 *:S > logcat.txt",
38
+ "electron-c": "npm run compile-electron && npm run electron",
39
+ "electron-p": "npm run compile-electron-p && npm run electron",
40
+ "update-app-version": "node ./update-app-version.js",
41
+ "find-licenses": "node ./find-licenses.js",
42
+ "fix-dependencies": "expo doctor --fix-dependencies"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/borispipo/expo-ui.git"
47
+ },
48
+ "keywords": [
49
+ "Expo",
50
+ "React-Native"
51
+ ],
52
+ "author": "Boris Fouomene",
53
+ "license": "ISC",
54
+ "bugs": {
55
+ "url": "https://github.com/borispipo/expo-ui/issues"
56
+ },
57
+ "homepage": "https://github.com/borispipo/expo-ui#readme",
58
+ "dependencies": {
59
+ "@babel/preset-react": "^7.18.6",
60
+ "@emotion/native": "^11.10.0",
61
+ "@expo/html-elements": "^0.2.0",
62
+ "@expo/metro-config": "^0.4.0",
63
+ "@expo/webpack-config": "^0.17.2",
64
+ "@fto-consult/common": "^1.4.4",
65
+ "@gorhom/portal": "^1.0.14",
66
+ "@react-native-async-storage/async-storage": "~1.17.3",
67
+ "@react-native-community/datetimepicker": "6.2.0",
68
+ "@react-native-community/netinfo": "9.3.0",
69
+ "@react-navigation/native": "^6.0.13",
70
+ "@react-navigation/native-stack": "^6.9.1",
71
+ "@shopify/flash-list": "1.1.0",
72
+ "babel-plugin-inline-dotenv": "^1.7.0",
73
+ "babel-plugin-module-resolver": "^4.1.0",
74
+ "babel-plugin-transform-inline-environment-variables": "^0.4.4",
75
+ "expo": "^46.0.15",
76
+ "expo-camera": "~12.3.0",
77
+ "expo-image-picker": "~13.3.1",
78
+ "expo-linking": "~3.2.2",
79
+ "expo-sqlite": "~10.3.0",
80
+ "expo-status-bar": "~1.4.0",
81
+ "expo-system-ui": "~1.3.0",
82
+ "expo-web-browser": "~11.0.0",
83
+ "google-libphonenumber": "^3.2.31",
84
+ "htmlparser2-without-node-native": "^3.9.2",
85
+ "parent-package-json": "^2.0.1",
86
+ "prop-types": "^15.8.1",
87
+ "react-apexcharts": "^1.4.0",
88
+ "react-content-loader": "^6.2.0",
89
+ "react-dom": "18.0.0",
90
+ "react-native-big-list": "^1.5.5",
91
+ "react-native-gesture-handler": "~2.5.0",
92
+ "react-native-paper": "^4.12.5",
93
+ "react-native-paper-dates": "^0.9.2",
94
+ "react-native-reanimated": "~2.9.1",
95
+ "react-native-safe-area-context": "4.3.1",
96
+ "react-native-svg": "12.3.0",
97
+ "react-native-web": "~0.18.7",
98
+ "react-native-webview": "11.23.0",
99
+ "sharp-cli": "^2.1.0",
100
+ "tippy.js": "^6.3.7"
101
+ }
102
+ }
package/src/auth/Login.js CHANGED
@@ -61,7 +61,7 @@ export default function LoginComponent(props){
61
61
  return defaultObj(props.data);
62
62
  }
63
63
  const goToFirstStep = ()=>{
64
- setState({...state,step:1,data:getData()});
64
+ setState({step:1,data:getData()});
65
65
  }
66
66
  const focusField = (fieldName)=>{
67
67
  const form = _getForm();
@@ -85,7 +85,7 @@ export default function LoginComponent(props){
85
85
  },1000)
86
86
  }
87
87
  },[withPortal])
88
- const {header,children,initialize,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,canSubmit:canSubmitForm,onStepChange,...loginProps} = defaultObj(getProps({
88
+ const {header,children,initialize,contentTop,data:loginData,canGoToNext,keyboardEvents,onSuccess:onLoginSuccess,canSubmit:canSubmitForm,onStepChange,...loginProps} = defaultObj(getProps({
89
89
  ...state,
90
90
  setState,
91
91
  state,
@@ -125,6 +125,10 @@ export default function LoginComponent(props){
125
125
  notifyUser("Impossible de valider le formulaire car celui-ci semble invalide")
126
126
  return;
127
127
  }
128
+ if(!form.isValid()){
129
+ notifyUser(form.getErrorText());
130
+ return;
131
+ }
128
132
  const args = {data,form,state,step,nextButtonRef,previousButtonRef};
129
133
  if(nextButtonRef.current && nextButtonRef.current.isDisabled()){
130
134
  return;
@@ -143,10 +147,6 @@ export default function LoginComponent(props){
143
147
  nextButtonRef.current?.enable();
144
148
  }
145
149
  if(step > 1){
146
- if(!form.isValid()){
147
- notifyUser(form.getErrorText());
148
- return;
149
- }
150
150
  if(canSubmit(args)){
151
151
  Preloader.open("vérification ...");
152
152
  return auth.signIn(data).then((a)=>{
@@ -193,33 +193,36 @@ export default function LoginComponent(props){
193
193
  }}
194
194
  data = {extendObj(state.data,loginData)}
195
195
  >
196
- <View testID={testID+"_ButtonsContainer"} style={[styles.buttonWrapper]}>
197
- <Button
198
- ref = {nextButtonRef}
199
- primary
200
- mode = "contained"
201
- rounded
202
- style = {styles.button}
203
- onPress = {goToNext}
204
- icon = {state.step == 1? 'arrow-right':'login'}
205
- surface
206
- >
207
- {state.step == 1? 'Suivant' : 'Connexion' }
208
- </Button>
209
- {state.step>=2 ? <Button
210
- onPress = {goToFirstStep}
211
- ref = {previousButtonRef}
212
- mode = "contained"
213
- rounded
214
- raised
215
- style = {styles.button}
216
- secondary
217
- surface
218
- icon = {'arrow-left'}
219
- >
220
- Précédent
221
- </Button> : null}
222
- </View>
196
+ <>
197
+ {React.isValidElement(contentTop)? contentTop : null}
198
+ {Object.size(loginProps.fields,true)?<View testID={testID+"_ButtonsContainer"} style={[styles.buttonWrapper]}>
199
+ <Button
200
+ ref = {nextButtonRef}
201
+ primary
202
+ mode = "contained"
203
+ rounded
204
+ style = {styles.button}
205
+ onPress = {goToNext}
206
+ icon = {state.step == 1? 'arrow-right':'login'}
207
+ surface
208
+ >
209
+ {state.step == 1? 'Suivant' : 'Connexion' }
210
+ </Button>
211
+ {state.step>=2 ? <Button
212
+ onPress = {goToFirstStep}
213
+ ref = {previousButtonRef}
214
+ mode = "contained"
215
+ rounded
216
+ raised
217
+ style = {styles.button}
218
+ secondary
219
+ surface
220
+ icon = {'arrow-left'}
221
+ >
222
+ Précédent
223
+ </Button> : null}
224
+ </View> : null}
225
+ </>
223
226
  </FormData>
224
227
  {React.isValidElement(children) ? children : null}
225
228
  </Surface>
@@ -220,7 +220,7 @@ CommonListComponent.propTypes = {
220
220
 
221
221
 
222
222
  const styles = StyleSheet.create({
223
- container: {
223
+ container1: {
224
224
  flex: 1,
225
225
  minHeight : 300,
226
226
  },
@@ -14,6 +14,7 @@ import Icon from "$ecomponents/Icon";
14
14
  import {isDesktopMedia} from "$cplatform/dimensions";
15
15
  import { matchOperators,getSearchTimeout,canAutoFocusSearchField} from "$ecomponents/Dropdown/utils";
16
16
  import Dialog from "$ecomponents/Dialog";
17
+ import stableHash from "stable-hash";
17
18
 
18
19
  const SimpleSelect = React.forwardRef((props,ref)=>{
19
20
  let {style : customStyle,onMount,mode,showSearch,anchorContainerProps,renderText,contentContainerProps,withCheckedIcon,testID,selectionColor,dialogProps,onShow,anchor,onUnmont,controlled,onDismiss,visible:controlledVisible,selectedColor,inputProps,itemProps,itemContainerProps,label,listProps,editable,readOnly,text,filter,renderItem,itemValue,getItemValue,defaultValue,items:menuItems,onPress,onChange,disabled,...rest} = props;
@@ -21,6 +22,7 @@ const SimpleSelect = React.forwardRef((props,ref)=>{
21
22
  const [state,setState] = React.useState({
22
23
  value : defaultValue !== undefined? defaultValue:undefined,
23
24
  visible : controlled?undefined:false,
25
+ items : [],
24
26
  layout : {
25
27
  height: 0,
26
28
  width: 0,
@@ -30,6 +32,7 @@ const SimpleSelect = React.forwardRef((props,ref)=>{
30
32
  const inputLayout = state.layout;
31
33
  const prevLayout = React.usePrevious(inputLayout);
32
34
  filter = defaultFunc(filter,x=>true);
35
+ const {items} = state;
33
36
  const value = state.value,
34
37
  visible = controlled? controlledVisible : state.visible;
35
38
  compare = defaultFunc(compare,(a,b)=> a === b);
@@ -64,9 +67,12 @@ const SimpleSelect = React.forwardRef((props,ref)=>{
64
67
  renderText = typeof renderText ==='function'? renderText : ({item,content,index})=>{
65
68
  return React.getTextContent(content);
66
69
  }
70
+ const prevMenuItems = React.usePrevious(menuItems,stableHash);
67
71
  const prepareItems = React.useCallback(()=>{
68
72
  const items = [];
69
73
  selectedRef.current = null;
74
+ let currentSelectedValue = value;
75
+ const isValueDifferent = !compare(defaultValue,value);
70
76
  Object.map(menuItems,(item,index,_index)=>{
71
77
  if(React.isValidElement(item) || !filter({items:menuItems,item,_index,index})) return null;
72
78
  const backupItem = item;
@@ -82,21 +88,33 @@ const SimpleSelect = React.forwardRef((props,ref)=>{
82
88
  }
83
89
  const mItem = {item:backupItem,value:itValue,index,_index};
84
90
  let content = renderItem ? renderItem({item:backupItem,index,_index,value:itValue}) : defaultVal(label,text,code);
91
+ const rText = renderText(mItem);
92
+ if(!content && typeof content != "number"){
93
+ content = rText;
94
+ }
85
95
  if(isDecimal(content)) content+="";
86
96
  if(!React.isValidElement(content,true)) return null;
87
97
  mItem.content = content;
88
- mItem.textContent = renderText(mItem);
89
- if(isSelected(itValue,index)){
98
+ mItem.textContent = rText;
99
+ if(isValueDifferent && itValue !== undefined && compare(defaultValue,itValue)){
100
+ selectedRef.current = mItem;
101
+ currentSelectedValue = defaultValue;
102
+
103
+ } else if(isSelected(itValue,index)){
90
104
  selectedRef.current = mItem;
91
105
  }
92
106
  items.push(mItem);
93
- })
94
- setItems(items);
95
- },[menuItems])
96
- const [items,setItems] = React.useStateIfMounted([]);
107
+ });
108
+ setState({...state,value:currentSelectedValue,items});
109
+ },[stableHash(menuItems)])
97
110
  React.useEffect(()=>{
98
- prepareItems();
99
- },[menuItems]);
111
+ if(defaultValue == value && menuItems == prevMenuItems) return;
112
+ if(menuItems != prevMenuItems){
113
+ prepareItems();
114
+ } else {
115
+ selectValue(defaultValue);
116
+ }
117
+ },[menuItems,defaultValue]);
100
118
 
101
119
  const context = {};
102
120
  const selectValue = context.selectValue = context.setValue = (defaultValue)=>{
@@ -108,14 +126,12 @@ const SimpleSelect = React.forwardRef((props,ref)=>{
108
126
  break;
109
127
  }
110
128
  }
111
- if(selectedRef.current){
129
+ if(selectedRef.current !== undefined){
112
130
  setState({...state,value:defaultValue});
113
131
  }
114
132
  }
115
133
  context.getValue = ()=> value;
116
- React.useEffect(()=>{
117
- selectValue(defaultValue);
118
- },[defaultValue])
134
+
119
135
  React.useEffect(()=>{
120
136
  if((value !== undefined || prevValue !== undefined) && compare(value,prevValue)) return;
121
137
  if(onChange){
@@ -394,7 +394,7 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
394
394
  right = typeof right ==='function'?right(iconProps) : right;
395
395
  left = typeof left =='function'? left(iconProps) : left;
396
396
  let hasRight = React.isValidElement(right),hasLeft = React.isValidElement(left);
397
- enableCopy = enableCopy !== false ? true : false;
397
+ enableCopy = enableCopy ? true : false;
398
398
  fieldToCopy = defaultStr(fieldToCopy).toLowerCase().trim();
399
399
  if(isEditable || isFilter || defaultStr(contentContainerProps.pointerEvents).toLowerCase().contains("none")){
400
400
  enableCopy = false;