@fto-consult/expo-ui 2.6.1 → 2.7.2
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/delete-node-modules.txt +6 -0
- package/package.json +7 -4
- package/src/App.js +10 -1
- package/src/components/Icon/Font.js +138 -0
- package/src/components/Icon/index.js +5 -3
- package/src/components/Table/index.js +3 -2
- package/src/index.js +27 -12
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style
|
|
3
|
+
// license that can be found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
1.Installer le package rimraf: npm i -g rimraf
|
|
6
|
+
2. Executer le script : npm run delete-node-modules
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"resolutions": {
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"electron-p": "npm run compile-electron-p && npm run electron",
|
|
43
43
|
"update-app-version": "node ./update-app-version.js",
|
|
44
44
|
"find-licenses": "node ./find-licenses.js",
|
|
45
|
-
"fix-dependencies": "expo doctor --fix-dependencies"
|
|
45
|
+
"fix-dependencies": "expo doctor --fix-dependencies",
|
|
46
|
+
"delete-node-modules": "rimraf ./**/node_modules"
|
|
46
47
|
},
|
|
47
48
|
"repository": {
|
|
48
49
|
"type": "git",
|
|
@@ -64,8 +65,9 @@
|
|
|
64
65
|
"@emotion/native": "^11.10.0",
|
|
65
66
|
"@expo/html-elements": "^0.2.0",
|
|
66
67
|
"@expo/metro-config": "^0.4.0",
|
|
68
|
+
"@expo/vector-icons": "^13.0.0",
|
|
67
69
|
"@expo/webpack-config": "^0.17.2",
|
|
68
|
-
"@fto-consult/common": "^1.
|
|
70
|
+
"@fto-consult/common": "^1.13.1",
|
|
69
71
|
"@gorhom/portal": "^1.0.14",
|
|
70
72
|
"@react-native-async-storage/async-storage": "~1.17.3",
|
|
71
73
|
"@react-native-community/datetimepicker": "6.5.2",
|
|
@@ -106,6 +108,7 @@
|
|
|
106
108
|
"react-native-web": "~0.18.7",
|
|
107
109
|
"react-native-webview": "11.23.1",
|
|
108
110
|
"sharp-cli": "^2.1.0",
|
|
109
|
-
"tippy.js": "^6.3.7"
|
|
111
|
+
"tippy.js": "^6.3.7",
|
|
112
|
+
"expo-font": "~11.0.1"
|
|
110
113
|
}
|
|
111
114
|
}
|
package/src/App.js
CHANGED
|
@@ -22,10 +22,12 @@ import StatusBar from "$ecomponents/StatusBar";
|
|
|
22
22
|
import SimpleSelect from '$ecomponents/SimpleSelect';
|
|
23
23
|
import {Provider as AlertProvider} from '$ecomponents/Dialog/confirm/Alert';
|
|
24
24
|
import APP from "$app";
|
|
25
|
+
import FontIcon from "$ecomponents/Icon/Font"
|
|
25
26
|
import {isMobileNative} from "$cplatform";
|
|
26
27
|
import {setDeviceIdRef} from "$capp";
|
|
27
28
|
import appConfig from "$capp/config";
|
|
28
29
|
import {showPrompt} from "$components/Dialog/confirm";
|
|
30
|
+
|
|
29
31
|
import * as Utils from "$utils";
|
|
30
32
|
Object.map(Utils,(v,i)=>{
|
|
31
33
|
if(typeof v =='function' && typeof window !='undefined' && window && !window[i]){
|
|
@@ -63,7 +65,14 @@ export default function getIndex(options){
|
|
|
63
65
|
const children = typeof App =='function'? App({children:child,APP}) : child;
|
|
64
66
|
return (
|
|
65
67
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
|
66
|
-
<PaperProvider
|
|
68
|
+
<PaperProvider
|
|
69
|
+
theme={theme}
|
|
70
|
+
settings={{
|
|
71
|
+
icon: (props) => {
|
|
72
|
+
return <FontIcon {...props}/>
|
|
73
|
+
},
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
67
76
|
<SafeAreaProvider>
|
|
68
77
|
<AuthProvider>
|
|
69
78
|
<PortalProvider>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style
|
|
3
|
+
// license that can be found in the LICENSE file.
|
|
4
|
+
import theme from "$theme";
|
|
5
|
+
import React from "react";
|
|
6
|
+
import {defaultStr,isNonNullString} from "$utils";
|
|
7
|
+
import PropTypes from "prop-types";
|
|
8
|
+
import { StyleSheet } from "react-native";
|
|
9
|
+
import * as FontAsset from 'expo-font';
|
|
10
|
+
|
|
11
|
+
/*** @see : https://materialdesignicons.com/ pour les icon MaterialComunityIcons*/
|
|
12
|
+
import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
|
|
13
|
+
import FontAwesome5 from "@expo/vector-icons/FontAwesome5";
|
|
14
|
+
import AntDesign from "@expo/vector-icons/AntDesign";
|
|
15
|
+
import Fontisto from "@expo/vector-icons/Fontisto";
|
|
16
|
+
import Foundation from "@expo/vector-icons/Foundation";
|
|
17
|
+
import Ionicons from "@expo/vector-icons/Ionicons";
|
|
18
|
+
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
|
|
19
|
+
import Octicons from "@expo/vector-icons/Octicons";
|
|
20
|
+
import SimpleLineIcons from "@expo/vector-icons/SimpleLineIcons";
|
|
21
|
+
import Zocial from "@expo/vector-icons/Zocial";
|
|
22
|
+
|
|
23
|
+
/*** @see : https://icons.expo.fyi/ popur tous les icons supportés*/
|
|
24
|
+
/*** L'iconSet par défaut est le MaterialCommunityIcon qui ne nécessite pas de préfixer les noms des icones
|
|
25
|
+
* Les prefix suivant doivent être utilisés :
|
|
26
|
+
* fa - pour l'iconSet FontAweSome5
|
|
27
|
+
* ant - pour l'iconSet AntDesign
|
|
28
|
+
* fontisto - pour l'iconSet Fontisto
|
|
29
|
+
* foundation - pour l'iconSet Foundation
|
|
30
|
+
* ionic - pour l'iconSet IonicIcons
|
|
31
|
+
* octicons - pour l'iconSet Octicons
|
|
32
|
+
* simple-line - pour l'iconSet SimpleLinesIcons
|
|
33
|
+
* zocial - pour l'iconSet Zocial
|
|
34
|
+
*/
|
|
35
|
+
const FontIcon = React.forwardRef(({icon,name,testID,color,iconStyle,backgroundColor,style,...props},ref)=>{
|
|
36
|
+
icon = defaultStr(icon,name).trim();
|
|
37
|
+
testID = defaultStr(testID,"RN_FontIconComponent");
|
|
38
|
+
const fStyle = StyleSheet.flatten(style) || {};
|
|
39
|
+
color = theme.Colors.isValid(color)? color : fStyle.color || theme.colors.text;
|
|
40
|
+
backgroundColor = theme.Colors.isValid(backgroundColor)? backgroundColor : fStyle.backgroundColor || 'transparent';
|
|
41
|
+
const isMaterial = isIcon(name,"material");
|
|
42
|
+
const isFa = isIcon(name,"fa");
|
|
43
|
+
const isAnt = isIcon(name,"ant");
|
|
44
|
+
const isFontisto = isIcon(name,"fontisto");
|
|
45
|
+
const isFoundation = isIcon(name,"foundation");
|
|
46
|
+
const isIonicons = isIcon(name,"ionic");
|
|
47
|
+
const isOcticons = isIcon(name,"octicons");
|
|
48
|
+
const isSimpleLineIcons = isIcon(name,"simple-line");
|
|
49
|
+
const isZocial = isIcon(name,"zocial");
|
|
50
|
+
let Icon = isMaterial ? MaterialIcons :
|
|
51
|
+
isFa ? FontAwesome5 :
|
|
52
|
+
isFontisto ? Fontisto :
|
|
53
|
+
isAnt ? AntDesign :
|
|
54
|
+
isFoundation ? Foundation :
|
|
55
|
+
isIonicons ? Ionicons :
|
|
56
|
+
isOcticons ? Octicons:
|
|
57
|
+
isSimpleLineIcons ? SimpleLineIcons :
|
|
58
|
+
isZocial ? Zocial :
|
|
59
|
+
MaterialCommunityIcons;
|
|
60
|
+
if(!icon || !Icon){
|
|
61
|
+
console.warn("Icone non définie pour le composant FontIcon, icon [{0}], merci de spécifier une icone supportée par la liste du module https://github.com/expo/vector-icons/MaterialCommunityIcons".sprintf(icon),props);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const iconName = icon.ltrim("")
|
|
65
|
+
return <Icon {...props}
|
|
66
|
+
ref = {ref}
|
|
67
|
+
testID = {testID}
|
|
68
|
+
color={color}
|
|
69
|
+
name = {icon}
|
|
70
|
+
backgroundColor = {backgroundColor}
|
|
71
|
+
/>
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
FontIcon.propTypes = {
|
|
75
|
+
name : PropTypes.string,
|
|
76
|
+
icon : PropTypes.string,
|
|
77
|
+
color : PropTypes.string,
|
|
78
|
+
size : PropTypes.number,
|
|
79
|
+
borderRadius : PropTypes.oneOfType([
|
|
80
|
+
PropTypes.number,
|
|
81
|
+
]),
|
|
82
|
+
onPress : PropTypes.func,
|
|
83
|
+
direction: PropTypes.oneOf(['rtl','ltr','auto']),
|
|
84
|
+
iconStyle : theme.StyleProps,
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
FontIcon.displayName = "FontIconComponent";
|
|
88
|
+
|
|
89
|
+
/*** vérfie si l'icon passé en paramètre est un icon pour l'icon set
|
|
90
|
+
* @param {string} name le nom de l'icone à vérifier
|
|
91
|
+
* @param {string} iconSet, le set d'icon dans lequel vérifier
|
|
92
|
+
*/
|
|
93
|
+
export const isIcon = (name,iconSet)=>{
|
|
94
|
+
if(!isNonNullString(name) || !isNonNullString(iconSet)) return false;
|
|
95
|
+
name = name.toLowerCase();
|
|
96
|
+
iconSet = iconSet.toLowerCase().trim();
|
|
97
|
+
return name.startsWith(iconSet+"-") || name.startsWith(iconSet+"s"+"-") ? true : false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export default theme.withStyles(FontIcon,{displayName:FontIcon.displayName,mode:'normal'});
|
|
101
|
+
export const fonts = [
|
|
102
|
+
MaterialCommunityIcons.font,
|
|
103
|
+
FontAwesome5.font,
|
|
104
|
+
AntDesign.font,
|
|
105
|
+
Fontisto.font,
|
|
106
|
+
Foundation.font,
|
|
107
|
+
Ionicons.font,
|
|
108
|
+
MaterialIcons.font,
|
|
109
|
+
Octicons.font,
|
|
110
|
+
SimpleLineIcons.font,
|
|
111
|
+
Zocial.font,
|
|
112
|
+
];
|
|
113
|
+
export const fontsNames = {};
|
|
114
|
+
Object.map(fonts,(f,k)=>{
|
|
115
|
+
if(isObj(f)){
|
|
116
|
+
for(let i in f){
|
|
117
|
+
fontsNames[i] = true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
/*** chage les fonts liés à l'application
|
|
123
|
+
* @param {function} filter, le filtre prenant en paramètr ele fontAsset en suite et le nom de la font en question
|
|
124
|
+
* @return {Promise}
|
|
125
|
+
*/
|
|
126
|
+
export function loadFonts(filter) {
|
|
127
|
+
filter = typeof filter =='function'? filter : (f,name,nameLower)=> name.toLowerCase().contains("material") ? true : false;
|
|
128
|
+
return Promise.all(fonts.map(font => {
|
|
129
|
+
if(!isObj(font)) return Promise.reject({message:'Invalid font'});
|
|
130
|
+
const fontName = Object.keys(font)[0]?.toLowerCase();
|
|
131
|
+
if(!isNonNullString(fontName) || !fontsNames[fontName] || !filter(font,fontName,fontName.toLowerCase)) return Promise.resolve({
|
|
132
|
+
status : false,
|
|
133
|
+
message : 'Font {0} introuvable'.sprintf(fontName)
|
|
134
|
+
});
|
|
135
|
+
return FontAsset.loadAsync(font);
|
|
136
|
+
}))
|
|
137
|
+
};
|
|
138
|
+
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import Checkbox from "./Checkbox";
|
|
2
2
|
import Icon from "./Icon";
|
|
3
|
-
|
|
3
|
+
import Font from "./Font";
|
|
4
4
|
export * from "./utils";
|
|
5
|
+
export * from "./Font";
|
|
5
6
|
|
|
6
7
|
Icon.Checkbox = Checkbox;
|
|
8
|
+
Icon.Font = Font;
|
|
7
9
|
|
|
8
|
-
export {Checkbox};
|
|
10
|
+
export {Checkbox,Font};
|
|
9
11
|
|
|
10
|
-
export default Icon;
|
|
12
|
+
export default Icon;
|
|
@@ -160,11 +160,12 @@ const TableComponent = React.forwardRef(({containerProps,renderEmpty,isRowSelect
|
|
|
160
160
|
const scrollContentContainerStyle = {flex:1,width:listWidth,minWidth:totalWidths,height:'100%'};
|
|
161
161
|
const scrollEventThrottle = isMobileNative()?200:50;
|
|
162
162
|
const scrollViewFlexGrow = {flexGrow:0};
|
|
163
|
+
const maxScrollheight = f.length && fFilters.length ? 170 : f.length || fFilters.length ? 120 : 80;
|
|
163
164
|
const allScrollViewProps = {
|
|
164
165
|
scrollEventThrottle,
|
|
165
166
|
horizontal : true,
|
|
166
167
|
...scrollViewProps,
|
|
167
|
-
style : [{maxHeight:
|
|
168
|
+
style : [{maxHeight:maxScrollheight},scrollViewProps.style],
|
|
168
169
|
contentContainerStyle : [styles.scrollView,scrollViewProps.contentContainerStyle,scrollViewFlexGrow,scrollContentContainerStyle]
|
|
169
170
|
}
|
|
170
171
|
const listWidth = '100%';
|
|
@@ -377,7 +378,7 @@ const styles = StyleSheet.create({
|
|
|
377
378
|
flexWrap : 'wrap',
|
|
378
379
|
},
|
|
379
380
|
footers : {
|
|
380
|
-
minHeight :
|
|
381
|
+
minHeight : 40,
|
|
381
382
|
},
|
|
382
383
|
headerItemOrCell : {
|
|
383
384
|
alignItems: 'flex-start',
|
package/src/index.js
CHANGED
|
@@ -17,13 +17,16 @@ import {notify} from "$ecomponents/Dialog";
|
|
|
17
17
|
import {decycle} from "$utils/json";
|
|
18
18
|
import init from "$capp/init";
|
|
19
19
|
import { setIsInitialized} from "$capp/utils";
|
|
20
|
+
import {isObj,isNonNullString} from "$cutils";
|
|
21
|
+
import {loadFonts} from "$ecomponents/Icon/Font";
|
|
22
|
+
import appConfig from "$capp/config";
|
|
20
23
|
|
|
21
24
|
let MAX_BACK_COUNT = 1;
|
|
22
25
|
let countBack = 0;
|
|
23
26
|
let isBackConfirmShowing = false;
|
|
24
27
|
|
|
25
28
|
const resetExitCounter = ()=>{
|
|
26
|
-
countBack = 0
|
|
29
|
+
countBack = 0
|
|
27
30
|
isBackConfirmShowing = false;
|
|
28
31
|
};
|
|
29
32
|
|
|
@@ -38,6 +41,16 @@ function App(props) {
|
|
|
38
41
|
isInitialized:true,
|
|
39
42
|
});
|
|
40
43
|
React.useEffect(() => {
|
|
44
|
+
const loadResources = ()=>{
|
|
45
|
+
return new Promise((resolve)=>{
|
|
46
|
+
//FontsIconsFilter porte le nom de la props de appConfig dans lequel définir les filtres à utiliser pour charger l'iconSet désirée pour l'appication
|
|
47
|
+
loadFonts(appConfig.get("FontsIconsFilter")).catch((e)=>{
|
|
48
|
+
console.warn(e," ierror loading app resources fonts");
|
|
49
|
+
}).finally(()=>{
|
|
50
|
+
resolve(true);
|
|
51
|
+
});
|
|
52
|
+
})
|
|
53
|
+
}
|
|
41
54
|
const restoreState = () => {
|
|
42
55
|
return new Promise((resolve,reject)=>{
|
|
43
56
|
(async ()=>{
|
|
@@ -102,16 +115,18 @@ function App(props) {
|
|
|
102
115
|
NetInfo.fetch().catch((e)=>{
|
|
103
116
|
console.log(e," is net info heinn")
|
|
104
117
|
});
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
Auth.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
118
|
+
loadResources().finally(()=>{
|
|
119
|
+
init().then(()=>{
|
|
120
|
+
if(Auth.isLoggedIn()){
|
|
121
|
+
Auth.loginUser(false);
|
|
122
|
+
}
|
|
123
|
+
setState({
|
|
124
|
+
...state,isInitialized:true,isLoading : false,
|
|
125
|
+
});
|
|
126
|
+
}).catch((e)=>{
|
|
127
|
+
console.error(e," initializing app")
|
|
128
|
+
setState({...state,isInitialized:true,isLoading : false});
|
|
129
|
+
})
|
|
115
130
|
});
|
|
116
131
|
|
|
117
132
|
const Events = {}
|
|
@@ -139,7 +154,7 @@ function App(props) {
|
|
|
139
154
|
}, []);
|
|
140
155
|
const {isInitialized} = state;
|
|
141
156
|
const hasGetStarted = true;
|
|
142
|
-
const isLoading = state.isLoading || !isInitialized || !appReadyRef.current
|
|
157
|
+
const isLoading = state.isLoading || !isInitialized || !appReadyRef.current? true : false;
|
|
143
158
|
React.useEffect(()=>{
|
|
144
159
|
if(isInitialized){
|
|
145
160
|
setIsInitialized(true);
|