@fto-consult/expo-ui 6.1.5 → 6.2.0

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/appConfig.txt CHANGED
@@ -8,9 +8,7 @@
8
8
 
9
9
  /*** le nombre maximal de courbes qu'on peut afficher sur le même graphe***/
10
10
  maxSupportedChartSeries {number}
11
-
12
- ///fonction de rappel appelée avant d'exit l'application, doit retourner une promesse que lorsque résolue, exit l'application
13
- beforeExit : ()=><Promise>
11
+
14
12
 
15
13
  /***les fonctions d'aggregations du datagrid**/
16
14
  datagridAggregatorFunctions : {objectOf({code:{string},label:{string},eval:{function}})|| arrayOf({code:{string},label:{string},eval:{function}})}
@@ -19,7 +17,6 @@
19
17
  "&libele&" : selectLabel,
20
18
  }
21
19
  getTableData : {function(tableName)=>table} retourne l'ojet table data,
22
- swrRefreshTimeout : {number} le délai d'inactivité auquel, une fois l'application active, les données de type listData sont rafraichies
23
20
  handleHelpScreen : {boolean}, //if Help screen will be added on navigation's main drawer
24
21
 
25
22
  checkNavigationPermsOnTableOrStructData : {boolean}, si le test de la permission sur la table data où sur la struct data sera effectuée lorsqu'on appelera la fonction navigateToTableData ou navigateToStructData
@@ -133,6 +133,10 @@ module.exports = (opts)=>{
133
133
  //le chemin ver le repertoire electron
134
134
  r.$eelectron = r["$e-electron"] = $electron;
135
135
  r.$electron = r.$electron || r.$eelectron;
136
+ r.$econtext = path.resolve(expo,"context");
137
+ if(!r.$context){
138
+ r.$context = r.$econtext;
139
+ }
136
140
  const electronAssetsPath = path.resolve(dir,"electron","assets");
137
141
  if($assets){
138
142
  const l1 = path.resolve($assets,"logo.png"), l2 = path.resolve($assets,"logo.png");
package/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { registerRootComponent } from "expo";
2
2
  import {Platform } from 'react-native';
3
3
  import App from "./src/App";
4
+ import { Provider } from "$econtext";
4
5
  const isWeb = Platform.OS === "web";
6
+ import {isObj} from "$cutils";
5
7
 
6
8
  /****
7
9
  * les options sont de la forme :
@@ -16,9 +18,9 @@ const isWeb = Platform.OS === "web";
16
18
  * }
17
19
  */
18
20
  export default function registerApp (options){
19
- options = options && typeof options =='object' && !Array.isArray(options)? options : {};
21
+ const {onMount,onUnmount,onRender,swrConfig,...rest} = isObj(options)? options : {};
20
22
  registerRootComponent(function(props){
21
- return <App {...props} {...options}/>
23
+ return <Provider {...props} {...rest} swrConfig={isObj(swrConfig) && swrConfig || {}} children={<App onMount={onMount} onUnmount={onUnmount} onRender={onRender}/>}/>
22
24
  });
23
25
  }
24
26
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "6.1.5",
3
+ "version": "6.2.0",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -61,7 +61,7 @@
61
61
  "@emotion/native": "^11.11.0",
62
62
  "@expo/html-elements": "^0.5.1",
63
63
  "@expo/vector-icons": "^13.0.0",
64
- "@fto-consult/common": "^3.18.32",
64
+ "@fto-consult/common": "^3.19.0",
65
65
  "@gorhom/portal": "^1.0.14",
66
66
  "@pchmn/expo-material3-theme": "^1.0.1",
67
67
  "@react-native-async-storage/async-storage": "1.18.2",
@@ -72,7 +72,7 @@
72
72
  "@react-navigation/native-stack": "^6.9.12",
73
73
  "@shopify/flash-list": "1.4.3",
74
74
  "apexcharts": "^3.41.0",
75
- "expo": "^49.0.0",
75
+ "expo": "^49.0.3",
76
76
  "expo-camera": "~13.4.2",
77
77
  "expo-clipboard": "~4.3.0",
78
78
  "expo-font": "~11.4.0",
package/src/App.js CHANGED
@@ -9,7 +9,6 @@ import {GestureHandlerRootView} from "react-native-gesture-handler";
9
9
  import APP from "$app";
10
10
  import {isMobileNative} from "$cplatform";
11
11
  import {setDeviceIdRef} from "$capp";
12
- import appConfig from "$capp/config";
13
12
  import {showPrompt} from "$ecomponents/Dialog/confirm";
14
13
  import { AppState } from 'react-native'
15
14
  import {canFetchOffline} from "$capi/utils";
@@ -18,51 +17,17 @@ import { timeout as SWR_REFRESH_TIMEOUT} from '$ecomponents/Datagrid/SWRDatagrid
18
17
  import { Dimensions,Keyboard } from 'react-native';
19
18
  import {isTouchDevice} from "$platform";
20
19
  import * as Utils from "$cutils";
21
- import {MD3LightTheme,MD3DarkTheme} from "react-native-paper";
22
- import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
23
- import { useColorScheme } from 'react-native';
24
- import {colorsAlias,Colors} from "$theme";
20
+ import useContext from "$econtext";
25
21
 
26
- import { configureFonts} from 'react-native-paper';
27
22
  Object.map(Utils,(v,i)=>{
28
23
  if(typeof v =='function' && typeof window !='undefined' && window && !window[i]){
29
24
  window[i] = v;
30
25
  }
31
26
  });
32
- const themeAttributes = ["primary","secondary","background",""]
33
- export default function getIndex({onMount,onUnmount,swrConfig,onRender,...rest}){
34
- const {extendAppTheme} = appConfig;
35
- const { theme : pTheme } = useMaterial3Theme();
36
- //const colorScheme = useColorScheme();
37
- appConfig.extendAppTheme = (theme)=>{
38
- if(!isObj(theme)) return;
39
- const newTheme = theme.dark || theme.isDark ? { ...MD3DarkTheme, colors: pTheme.dark } : { ...MD3LightTheme, colors: pTheme.light };
40
- for(let i in newTheme){
41
- if(i !== 'colors' && !(i in theme)){
42
- theme[i] = newTheme[i];
43
- }
44
- }
45
- if(isObj(theme.colors)){
46
- colorsAlias.map((color)=>{
47
- color = color.trim();
48
- const cUpper = color.ucFirst();
49
- //math theme colors to material desgin V3
50
- const textA = `${color}Text`,onColor=`on${cUpper}`//,containerA = `${color}Container`,onColorContainer=`on${cUpper}Container`;
51
- const c = Colors.isValid(theme.colors[onColor])? theme.colors[onColor] : (theme.colors[textA]) || undefined;
52
- if(c){
53
- theme.colors[onColor] = c;
54
- }
55
- });
56
- for(let i in newTheme.colors){
57
- if(!(i in theme.colors)){
58
- theme.colors[i] = newTheme.colors[i];
59
- }
60
- }
61
- }
62
- theme.fonts = newTheme.fonts;
63
- return typeof extendAppTheme == 'function'? extendAppTheme(theme) : theme;
64
- }
65
- const isScreenFocusedRef = React.useRef(true);
27
+
28
+ export default function getIndex({onMount,onUnmount,onRender}){
29
+ const {swrConfig,appConfig} = useContext();
30
+ const isScreenFocusedRef = React.useRef(true);
66
31
  ///garde pour chaque écran sa date de dernière activité
67
32
  const screensRef = React.useRef({});//la liste des écrans actifs
68
33
  const activeScreenRef = React.useRef('');
@@ -70,7 +35,6 @@ export default function getIndex({onMount,onUnmount,swrConfig,onRender,...rest})
70
35
  const appStateRef = React.useRef({});
71
36
  const isKeyboardOpenRef = React.useRef(false);
72
37
  React.useOnRender(onRender);
73
- swrConfig = defaultObj(swrConfig);
74
38
  React.useEffect(()=>{
75
39
  ///la fonction de rappel lorsque le composant est monté
76
40
  const onScreenFocus = ({sanitizedName})=>{
@@ -144,7 +108,7 @@ export default function getIndex({onMount,onUnmount,swrConfig,onRender,...rest})
144
108
  }
145
109
  const date = screensRef.current[screen];
146
110
  const diff = new Date().getTime() - date.getTime();
147
- const timeout = defaultNumber(appConfig.get("swrRefreshTimeout"),SWR_REFRESH_TIMEOUT)
111
+ const timeout = defaultNumber(swrConfig.refreshTimeout,SWR_REFRESH_TIMEOUT)
148
112
  screensRef.current[screen] = new Date();
149
113
  return diff >= timeout ? true : false;
150
114
  },
@@ -174,7 +138,7 @@ export default function getIndex({onMount,onUnmount,swrConfig,onRender,...rest})
174
138
  }
175
139
  }}
176
140
  >
177
- <GestureHandlerRootView style={{ flex: 1 }}>
141
+ <GestureHandlerRootView style={{ flex: 1 }}>
178
142
  <SafeAreaProvider>
179
143
  <Index {...rest} onMount={onMount}/>
180
144
  </SafeAreaProvider>
@@ -114,15 +114,6 @@ const AppBarComponent = React.forwardRef((props,ref)=> {
114
114
  titleProps = defaultObj(titleProps);
115
115
  React.setRef(ref,context);
116
116
  testID = defaultStr(testID,"RN_AppBarComponent")
117
- const renderedActions = renderSplitedActions(splitedActions,{
118
- ...defaultObj(menuProps,appBarProps.menuProps),
119
- anchorProps : {
120
- style : anchorStyle,
121
- color : anchorStyle.color,
122
- }
123
- });
124
- const renderedRight = React.isValidElement(rightContent) && rightContent || right;
125
- const hasRight = React.isValidElement(renderedActions) || React.isValidElement(renderedRight);
126
117
  return (
127
118
  <Appbar.Header elevation={elevation} {...appBarProps} testID={testID} style={[styles.header,{backgroundColor},elevStyle,appBarProps.style]} onLayout={onPageResize}>
128
119
  {backAction}
@@ -132,8 +123,14 @@ const AppBarComponent = React.forwardRef((props,ref)=> {
132
123
  subtitle = {defaultVal(subtitle,params.subtitle,options.subtitle)}
133
124
  subtitleProps = {subtitleProps}
134
125
  />
135
- {renderedActions}
136
- {renderedRight}
126
+ {renderSplitedActions(splitedActions,{
127
+ ...defaultObj(menuProps,appBarProps.menuProps),
128
+ anchorProps : {
129
+ style : anchorStyle,
130
+ color : anchorStyle.color,
131
+ }
132
+ })}
133
+ {React.isValidElement(rightContent) && rightContent || React.isValidElement(right) && right || null}
137
134
  </Appbar.Header>
138
135
  );
139
136
  });
@@ -3371,7 +3371,7 @@ export default class CommonDatagridComponent extends AppComponent {
3371
3371
  fetchOptions.dataSources = this.currentDataSources;
3372
3372
  fetchOptions.selector = fetchFilters;
3373
3373
  fetchOptions.sort = this.getSort();
3374
- const canIncludeField = typeof this.props.includeFieldsInFetchOptions =='boolean'? this.props.includeFieldsInFetchOptions : defaultBool(appConfig.get("includeFieldsInDatagridFetchOptions"),appConfig.includeFieldsInDatagridFetchOptions) !== false;
3374
+ const canIncludeField = typeof this.props.includeFieldsInFetchOptions =='boolean'? this.props.includeFieldsInFetchOptions : defaultBool(appConfig.get("includeFieldsInDatagridFetchOptions")) !== false;
3375
3375
  if(canIncludeField){
3376
3376
  const ff = this.getFilterableColumnsNames();
3377
3377
  let fields = ff;
@@ -25,6 +25,7 @@ import {getRowsPerPagesLimits} from "./Common/utils";
25
25
  import PropTypes from "prop-types";
26
26
  import {Menu} from "$ecomponents/BottomSheet";
27
27
  import session from "$session";
28
+ import useContext from "$econtext";
28
29
 
29
30
  export const getSessionKey = ()=>{
30
31
  return Auth.getSessionKey("swrDatagrid");
@@ -48,8 +49,8 @@ export const setSessionData = (key,value)=>{
48
49
  export const timeout = 5000*60;//5 minutes
49
50
  /***@see : https://swr.vercel.app/docs/api */
50
51
 
51
- export const getSWROptions = ()=>{
52
- const delay = defaultNumber(appConfig.get("swrRefreshTimeout"),timeout);
52
+ export const getSWROptions = (defTimeout)=>{
53
+ const delay = defaultNumber(defTimeout,timeout);
53
54
  return {
54
55
  dedupingInterval : delay,
55
56
  errorRetryInterval : Math.max(delay*2,timeout),
@@ -101,6 +102,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
101
102
  defaultSortOrder,
102
103
  ...rest
103
104
  } = props;
105
+ const {swrConfig} = useContext();
104
106
  rest = defaultObj(rest);
105
107
  rest.exportTableProps = defaultObj(rest.exportTableProps)
106
108
  const firstPage = 1;
@@ -227,10 +229,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
227
229
  });
228
230
  },
229
231
  showError : false,
230
- swrOptions : {
231
- ...getSWROptions(),
232
- ...defaultObj(appConfig.swr),
233
- },
232
+ swrOptions : getSWROptions(swrConfig.refreshTimeout)
234
233
  });
235
234
  const isLoading = isLoadingRef.current && customIsLoading || false;
236
235
  /*React.useEffect(()=>{
@@ -34,8 +34,7 @@ const Provider = React.forwardRef((_props,innerRef)=>{
34
34
  }
35
35
  },
36
36
  isOpen : x=> {
37
- console.log("checking message ref",messageRef.current);
38
- return messageRef.current && messageRef.current.setNativeProps ? true : false
37
+ return messageRef.current && messageRef.current? true : false
39
38
  },
40
39
  });
41
40
  setRef(ref,context);
@@ -124,6 +124,7 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
124
124
  }
125
125
  const isSecureText = type =="password"?true : false;
126
126
  const [secureTextEntry,setSecureTextEntry] = React.useState(isSecureText);
127
+ const [toggle,setToggle] = React.useState(false);
127
128
  const prevSecureTextEntry = React.usePrevious(secureTextEntry);
128
129
  containerProps = defaultObj(containerProps);
129
130
  mode = defaultStr(mode,theme.textFieldMode);
@@ -271,10 +272,8 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
271
272
  }
272
273
  }
273
274
  let hasLabel = label && (isShadowMode || isNormalMode || alwaysUseLabel || text || (isFocused || (!usePlaceholderWhenEmpty && canValueBeFormattable)))? true : labelText !== placeholder;
274
- const innerRef = (el)=>{
275
- ref.current = el;
276
- React.setRef(inputRef,el,setRef);
277
- };
275
+ const innerRef = React.useRef(null);
276
+ const componentRef = React.useMergeRefs(innerRef,ref,setRef);
278
277
  validType = defaultStr(validType,validRule).toLowerCase();
279
278
  multiline = isFilter ? false : defaultBool(multiline,multiple,!!numberOfLines);
280
279
  let inputColor = (isFocused || error) ? labelColor : Colors.isValid(color)?color : theme.colors.text;
@@ -304,7 +303,7 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
304
303
  keyboardAppearance : theme.isDark()? 'dark': 'default',
305
304
  caretHidden : false,
306
305
  ...props,
307
- innerRef,
306
+ innerRef:componentRef,
308
307
  placeholder : (isFocused || isShadowMode || isNormalMode) && labelText ? "":placeholder,
309
308
  placeholderTextColor : error ? theme.colors.error : placeholderColor,
310
309
  selectionColor,
@@ -377,12 +376,12 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
377
376
  text2 = "0"+text2;
378
377
  }
379
378
  if(multiline){
380
- const minHeight = Math.max(tHeight,target.scrollHeight);
381
- if( tHeight < minHeight) {
382
- heightRef.current = minHeight;
383
- if(!isFocused && innerRef.current?.setNativeProps){
384
- innerRef.current.setNativeProps({style:{minHeight}})
385
- }
379
+ if(!text2 || text2.length < 30){
380
+ heightRef.current = HEIGHT;
381
+ setToggle(!toggle);
382
+ } else if(target.scrollHeight > heightRef.current){
383
+ heightRef.current = target.scrollHeight;
384
+ setToggle(!toggle);
386
385
  }
387
386
  }
388
387
  const tVal = toCase(text2);
@@ -475,7 +474,7 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
475
474
  } else affix = undefined;
476
475
  }
477
476
  elevation = defaultNumber(contentContainerProps.elevation,elevation,isShadowMode?4:0);
478
- const paddingVertical = (hasRight || hasLeft)? isMob?5 : 0 : 10;
477
+ const paddingVertical = multiline ? 0 : (hasRight || hasLeft)? isMob?5 : 0 : 10;
479
478
  const contentContainerStyle = isOutlinedMode ? {
480
479
  borderColor,
481
480
  borderWidth,
@@ -540,7 +539,7 @@ const TextFieldComponent = React.forwardRef((componentProps,inputRef)=>{
540
539
  typeof render ==="function"? render(inputProps):
541
540
  <RNTextInput
542
541
  {...inputProps}
543
- ref = {innerRef}
542
+ ref = {componentRef}
544
543
  />
545
544
  }
546
545
  </KeyboardAvoidingView>
@@ -0,0 +1,57 @@
1
+ import React from "$react";
2
+ import appConfig from "$capp/config";
3
+ import {MD3LightTheme,MD3DarkTheme} from "react-native-paper";
4
+ import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
5
+ import {colorsAlias,Colors} from "$theme";
6
+
7
+ const ExpoUIContext = React.createContext(null);
8
+
9
+
10
+ export const useExpoUI = ()=> React.useContext(ExpoUIContext);
11
+
12
+
13
+ /*****
14
+ les utilitaires disponibles à passer au provider :
15
+ FontsIconsFilter : (font{object},fontName{string},fontNameLower{string})=><boolean> //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
16
+ ///fonction de rappel appelée avant d'exit l'application, doit retourner une promesse que lorsque résolue, exit l'application
17
+ beforeExit : ()=><Promise>
18
+
19
+ */
20
+ export const Provider = ({children,...props})=>{
21
+ const {extendAppTheme} = appConfig;
22
+ const { theme : pTheme } = useMaterial3Theme();
23
+ //const colorScheme = useColorScheme();
24
+ appConfig.extendAppTheme = (theme)=>{
25
+ if(!isObj(theme)) return;
26
+ const newTheme = theme.dark || theme.isDark ? { ...MD3DarkTheme, colors: pTheme.dark } : { ...MD3LightTheme, colors: pTheme.light };
27
+ for(let i in newTheme){
28
+ if(i !== 'colors' && !(i in theme)){
29
+ theme[i] = newTheme[i];
30
+ }
31
+ }
32
+ if(isObj(theme.colors)){
33
+ colorsAlias.map((color)=>{
34
+ color = color.trim();
35
+ const cUpper = color.ucFirst();
36
+ //math theme colors to material desgin V3
37
+ const textA = `${color}Text`,onColor=`on${cUpper}`//,containerA = `${color}Container`,onColorContainer=`on${cUpper}Container`;
38
+ const c = Colors.isValid(theme.colors[onColor])? theme.colors[onColor] : (theme.colors[textA]) || undefined;
39
+ if(c){
40
+ theme.colors[onColor] = c;
41
+ }
42
+ });
43
+ for(let i in newTheme.colors){
44
+ if(!(i in theme.colors)){
45
+ theme.colors[i] = newTheme.colors[i];
46
+ }
47
+ }
48
+ }
49
+ theme.fonts = newTheme.fonts;
50
+ return typeof extendAppTheme == 'function'? extendAppTheme(theme) : theme;
51
+ }
52
+ return <ExpoUIContext.Provider value={{...props,appConfig}} children={children}/>;
53
+ }
54
+
55
+ export default useExpoUI;
56
+
57
+ export const useContext = useExpoUI;
package/src/index.js CHANGED
@@ -39,6 +39,7 @@ import {updateTheme,defaultTheme} from "$theme";
39
39
  import StatusBar from "$ecomponents/StatusBar";
40
40
  import {Provider as PaperProvider } from 'react-native-paper';
41
41
  import FontIcon from "$ecomponents/Icon/Font";
42
+ import useContext from "$econtext";
42
43
 
43
44
  let MAX_BACK_COUNT = 1;
44
45
  let countBack = 0;
@@ -58,17 +59,17 @@ const NAVIGATION_PERSISTENCE_KEY = 'NAVIGATION_STATE';
58
59
  */
59
60
  function App({init:initApp,initialRouteName:appInitialRouteName,render,onMount,preferences:appPreferences,getStartedRouteName}) {
60
61
  AppStateService.init();
62
+ const {FontsIconsFilter,beforeExit} = useContext();
61
63
  const [initialState, setInitialState] = React.useState(undefined);
62
64
  const appReadyRef = React.useRef(true);
63
65
  const [state,setState] = React.useState({
64
66
  isLoading : true,
65
67
  isInitialized:false,
66
68
  });
67
- React.useEffect(() => {
69
+ React.useEffect(() => {
68
70
  const loadResources = ()=>{
69
71
  return new Promise((resolve)=>{
70
- //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
71
- loadFonts(appConfig.get("FontsIconsFilter")).catch((e)=>{
72
+ loadFonts(FontsIconsFilter).catch((e)=>{
72
73
  console.warn(e," ierror loading app resources fonts");
73
74
  }).finally(()=>{
74
75
  resolve(true);
@@ -111,10 +112,10 @@ function App({init:initApp,initialRouteName:appInitialRouteName,render,onMount,p
111
112
  }
112
113
  }
113
114
  const exit = ()=>{
114
- if(typeof appConfig.beforeExit =='function'){
115
- const r2 = appConfig.beforeExit()
115
+ if(typeof beforeExit =='function'){
116
+ const r2 = beforeExit()
116
117
  if(!isPromise(r2)){
117
- throw {message:'La fonction before exit de appConfig.beforeExit doit retourner une promesse',returnedResult:r2}
118
+ throw {message:'La fonction before exit du contexte doit retourner une promesse',returnedResult:r2}
118
119
  }
119
120
  return r2.then(foreceExit).catch(reject);
120
121
  }
@@ -1,132 +0,0 @@
1
- import React from '$react';
2
- import {Platform,StyleSheet,Pressable,View} from 'react-native';
3
- import Label from "$ecomponents/Label";
4
- import theme,{Colors,StyleProp} from "$theme";
5
- import PropTypes from "prop-types";
6
- import {defaultObj,defaultStr} from "$cutils";
7
- import {isIos,isAndroid,isWeb} from "$cplatform";
8
-
9
- const AppbarContent = React.forwardRef(({
10
- color: titleColor,
11
- subtitle,
12
- subtitleProps,
13
- subtitleStyle,
14
- onPress,
15
- style,
16
- titleProps,
17
- titleRef,
18
- titleStyle,
19
- title,
20
- testID,
21
- containerProps,
22
- ...rest
23
- },ref) => {
24
-
25
- const titleTextColor = titleColor ? titleColor : theme.colors.primaryText;
26
- titleProps = defaultObj(titleProps);
27
- subtitleProps = defaultObj(subtitleProps);
28
- testID = defaultStr(testID,"RN_AppBarContentComponent")
29
- subtitle = subtitle === false ? null : subtitle;
30
- const subtitleColor = Colors.setAlpha(titleTextColor,0.7);
31
-
32
- return (
33
- <Pressable testID={testID+"_Container"} {...defaultObj(containerProps)} onPress={onPress} disabled={!onPress}>
34
- <View
35
- pointerEvents="box-none"
36
- style={[styles.container, style]}
37
- {...rest}
38
- testID = {testID}
39
- ref = {ref}
40
- >
41
- <Label
42
- ref={titleRef}
43
- testID = {testID+"_Title"}
44
- {...titleProps}
45
- style={[
46
- {
47
- color: titleTextColor,
48
- ...(isIos()? theme.fonts.regular: theme.fonts.medium),
49
- },
50
- isWeb() && theme.styles.webFontFamilly,
51
- titleProps.style,
52
- titleStyle,
53
- ]}
54
- numberOfLines={1}
55
- accessible
56
- // @ts-ignore Type '"heading"' is not assignable to type ...
57
- role={Platform.OS === 'web' ? 'heading' : 'header'}
58
- >
59
- {title}
60
- </Label>
61
- {subtitle ? (
62
- <Label
63
- testID = {testID+"_Subtitle"}
64
- {...subtitleProps}
65
- style={[styles.subtitle, { color: subtitleColor }, subtitleProps.style, subtitleStyle]}
66
- numberOfLines={1}
67
- >
68
- {subtitle}
69
- </Label>
70
- ) : null}
71
- </View>
72
- </Pressable>
73
- );
74
- });
75
-
76
- AppbarContent.displayName = 'Appbar.Content';
77
-
78
- const styles = StyleSheet.create({
79
- container: {
80
- flex: 1,
81
- paddingHorizontal: 5,
82
- justifyContent : 'center',
83
- alignItems : 'flex-start',
84
- },
85
- title: {
86
- fontSize: Platform.OS === 'ios' ? 17 : 20,
87
- },
88
- subtitle: {
89
- fontSize: Platform.OS === 'ios' ? 11 : 14,
90
- },
91
- });
92
-
93
- export default AppbarContent;
94
- const titleType = PropTypes.oneOfType([
95
- PropTypes.string,
96
- PropTypes.node,
97
- PropTypes.bool,
98
- ])
99
-
100
- AppbarContent.propTypes = {
101
- /**
102
- * Custom StyleProp for the text.
103
- */
104
- StyleProp: PropTypes.string,
105
- /**
106
- * Text for the title.
107
- */
108
- title: titleType,
109
- /**
110
- * Style for the title.
111
- */
112
- titleStyle: StyleProp,
113
- /**
114
- * Reference for the title.
115
- */
116
- titleRef : PropTypes.any,
117
- /**
118
- * @deprecated Deprecated in v5.x
119
- * Text for the subtitle.
120
- */
121
- subtitle : titleType,
122
- /**
123
- * @deprecated Deprecated in v5.x
124
- * Style for the subtitle.
125
- */
126
- subtitleStyle: StyleProp,
127
- /**
128
- * Function to execute on press.
129
- */
130
- onPress : PropTypes.func,
131
- style : StyleProp
132
- }
@@ -1,148 +0,0 @@
1
- /**** see : https://github.com/danilowoz/react-content-loader */
2
- import {defaultObj} from "$cutils";
3
- import View from "$ecomponents/View";
4
- import {StyleSheet,Dimensions,useWindowDimensions} from "react-native";
5
- import React from "react";
6
- import ContentLoaderF, {Facebook as CLFacebook,Instagram as CLInstagram} from './Loader';
7
- import PropTypes from "prop-types";
8
- import BarcharComponent from "./BarChar";
9
- import PieChartComponent from "./PieChart";
10
- import FormComponent,{HEIGHT as formHeight} from "./Form";
11
- import DatagridContentLoader,{HEIGHT as datagridHeight} from "./Datagrid";
12
- import ProfileComponent from "./Profile";
13
- import { getBackgroundColor } from "./utils";
14
- import TaskListComponent from "./TaskList";
15
- import theme,{Colors} from "$theme"
16
- import Rect from "./Rect";
17
- import Circle from "./Circle";
18
-
19
- export * from "./utils";
20
-
21
- export {Rect};
22
-
23
- export {Circle};
24
-
25
- export {default as Table} from "./Table";
26
-
27
-
28
- export default function ContentLoaderWrapper (props){
29
- let {instance,containerProps,mediaQueryUpdateNativeProps,instances,Component,count,...rest} = props;
30
- const innerRef = React.useRef(null);
31
- Component = defaultVal(Component,ContentLoaderF);
32
- containerProps = defaultObj(containerProps);
33
- const getChildren = ({width,height,count})=>{
34
- const dimensions = Dimensions.get("window");
35
- width = width || dimensions.width;
36
- height = height || dimensions.height;
37
- rest = {...defaultObj(rest),width,height}
38
- const r = [];
39
- rest = defaultObj(rest);
40
- count = Math.ceil(defaultNumber(instances,instance,count,3))
41
- rest.backgroundColor = Colors.isValid(rest.backgroundColor)? rest.backgroundColor : Colors.darken(theme.colors.background);
42
- rest.backgroundColor= getBackgroundColor(rest.backgroundColor)// '#cecece';
43
- if(count <= 1) count = 1;
44
- for(let i = 1; i<= count; i++){
45
- r.push(<Component {...rest} key={i+""} />)
46
- }
47
- return r;
48
- }
49
- const children = getChildren({count});
50
- return <View ref={innerRef} onLayout = {React.mediaQueryUpdateNativePropsCallback(({target,...args})=>{
51
- args.layout = args.nativeEvent.layout;
52
- if(typeof mediaQueryUpdateNativeProps ==='function'){
53
- const children = getChildren(defaultObj(mediaQueryUpdateNativeProps(args)));
54
- console.log("will update target ",target,children);
55
- target.setNativeProps({children});
56
- }
57
- },innerRef)} {...containerProps}
58
- style={[styles.container,styles.fullWidth,containerProps.style]}
59
- >
60
- {children}
61
- </View>
62
- }
63
-
64
- ContentLoaderWrapper.propTypes = {
65
- //le nombre d'instance du content loader
66
- instances : PropTypes.number,
67
- instance : PropTypes.number,
68
- count : PropTypes.number,
69
- }
70
-
71
- export function Facebook (props){
72
- return <ContentLoaderWrapper {...props} Component={CLFacebook}/>
73
- }
74
- export function Instagram (props){
75
- return <ContentLoaderWrapper {...props} Component={CLInstagram}/>
76
- }
77
- export function ContentLoader (props){
78
- return <ContentLoaderWrapper {...props} Component={ContentLoaderF}/>
79
- }
80
-
81
- export function BarChart (props){
82
- return <ContentLoaderWrapper {...props} Component={BarcharComponent}/>
83
- }
84
-
85
- export function PieChart (props){
86
- return <ContentLoaderWrapper {...props} Component={PieChartComponent}/>
87
- }
88
-
89
- export function Form (props){
90
- const {height} = Dimensions.get("window");
91
- return <ContentLoaderWrapper
92
- mediaQueryUpdateNativeProps = {({layout:{width,height}})=>{
93
- width = Math.max(width-50,200);
94
- return {width,count:Math.max(Math.trunc(height/formHeight),2)}
95
- }}
96
- {...props}
97
- count = {Math.max(Math.trunc(height/formHeight),2)}
98
- Component={FormComponent}
99
- />
100
- }
101
-
102
- export function Profile (props){
103
- let {containerProps,...rest} = props;
104
- containerProps = Object.assign({},containerProps);
105
- containerProps.style = [styles.taskListContainer,containerProps.style];
106
- return <ContentLoaderWrapper count={3} {...props} Component={ProfileComponent}/>
107
- }
108
-
109
- export function TaskList (props){
110
- return <ContentLoaderWrapper count={3} {...props} Component={TaskListComponent}/>
111
- }
112
-
113
- export function Datagrid (props){
114
- const {height} = Dimensions.get("window");
115
- return <ContentLoaderWrapper
116
- name = "ddddd"
117
- mediaQueryUpdateNativeProps ={({layout:{width,height}})=>{
118
- width = Math.max(props.width-50,200);
119
- return {width,count:Math.max(Math.trunc((height-100)/datagridHeight),2)}
120
- }}
121
- {...props}
122
- Component={DatagridContentLoader}
123
- count = {Math.max(Math.trunc((height-100)/datagridHeight),2)}
124
- />
125
- }
126
-
127
-
128
- const styles = StyleSheet.create({
129
- fullWidth : {
130
- width : '100%'
131
- },
132
- center : {
133
- flex : 1,
134
- justifyContent: 'center',
135
- alignItems :'center',
136
- },
137
- container : {
138
- marginHorizontal : 0,
139
- paddingHorizontal : 0,
140
- marginTop : 10,
141
- alignItems : 'center',
142
- justifyContent : 'flex-start'
143
- },
144
- taskListContainer : {
145
- alignItems : 'flex-end',
146
- alignSelf : 'flex-start',
147
- },
148
- })