@fto-consult/expo-ui 3.4.0 → 3.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "3.4.0",
3
+ "version": "3.6.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.10.0",
62
62
  "@expo/html-elements": "^0.2.0",
63
63
  "@expo/vector-icons": "^13.0.0",
64
- "@fto-consult/common": "^2.15.2",
64
+ "@fto-consult/common": "^2.15.4",
65
65
  "@gorhom/portal": "^1.0.14",
66
66
  "@react-native-async-storage/async-storage": "~1.17.3",
67
67
  "@react-native-community/datetimepicker": "6.5.2",
@@ -105,7 +105,7 @@
105
105
  "react-native-svg": "13.4.0",
106
106
  "react-native-web": "~0.18.7",
107
107
  "react-native-webview": "11.23.1",
108
- "react-virtuoso": "^4.0.3",
108
+ "react-virtuoso": "^4.0.6",
109
109
  "sharp-cli": "^2.1.0",
110
110
  "tippy.js": "^6.3.7",
111
111
  "use-event-callback": "^0.1.0",
@@ -0,0 +1,88 @@
1
+ import React from '$react';
2
+ import { Dimensions} from 'react-native';
3
+ import PropTypes from "prop-types";
4
+ import View from "$ecomponents/View";
5
+ import theme from "$theme";
6
+ import {defaultStr,defaultObj,defaultNumber} from "$utils";
7
+ import APP from "$capp/instance";
8
+ import ActivityIndicator from "$ecomponents/ActivityIndicator";
9
+ import {isWeb} from "$cplatform";
10
+
11
+ /***
12
+ * ce composant a pour but de définir la taille d'un contenu en se basant sur sa positin top, de manière à ce que, le contentu du composant fit
13
+ * le reste de la taille de la page, avec comme valeur de la props minHeight
14
+ */
15
+ const AutoSizerVerticalComponent = React.forwardRef(({onLayout,isScrollView,withActivityIndicator,testID,withPadding,maxHeight,minHeight,style,children:cChildren,...rest},ref) => {
16
+ testID = defaultStr(testID,'RN_AutoSizerVerticalComponent');
17
+ const hasUpdateLayoutRef = React.useRef(false);
18
+ const layoutRef = React.useRef(null);
19
+ const [layout,setLayout] = React.useState(Dimensions.get("window"));
20
+ const {height,width} = layout;
21
+ const hasInitializedRef = React.useRef(false);
22
+ const children = React.useStableMemo(()=>cChildren,[cChildren]);
23
+ const updateLayout = ()=>{
24
+ return new Promise((resolve)=>{
25
+ hasUpdateLayoutRef.current = true;
26
+ if(layoutRef.current && layoutRef.current.measureInWindow){
27
+ layoutRef.current.measureInWindow((x, y, width, height) => {
28
+ const r = {...Dimensions.get("window"),layout:{ x, y, width, height }};
29
+ setLayout(r);
30
+ hasInitializedRef.current = true;
31
+ resolve(r);
32
+ });
33
+ } else {
34
+ setLayout(Dimensions.get("window"))
35
+ }
36
+ })
37
+ }
38
+ React.setRef(ref,{
39
+ updateLayout,
40
+ layoutRef,
41
+ ref : layoutRef
42
+ });
43
+ React.useEffect(()=>{
44
+ const onResizePage = ()=>{
45
+ setTimeout(()=>{
46
+ updateLayout();
47
+ },300);
48
+ }
49
+ APP.on(APP.EVENTS.RESIZE_PAGE,onResizePage);
50
+ return ()=>{
51
+ APP.off(APP.EVENTS.RESIZE_PAGE,onResizePage);
52
+ React.setRef(ref,null);
53
+ }
54
+ },[]);
55
+ const hasUpdateLayout = hasUpdateLayoutRef.current;
56
+ const cStyle ={width:'100%',maxHeight:Math.max(height-100,250)};
57
+ const contentLayout = defaultObj(layout.layout);
58
+ cStyle.minHeight = Math.min(Math.max(layout.height-defaultNumber(contentLayout.y),minHeight && minHeight ||250));
59
+ const cMaxHeight = layout.height-defaultNumber(contentLayout.y);
60
+ if(cMaxHeight>=250){
61
+ cStyle.maxHeight = cMaxHeight;
62
+ }
63
+ if(withPadding !== false){
64
+ cStyle.paddingBottom = 50;
65
+ }
66
+ const fStyle = !hasUpdateLayout && withActivityIndicator !== false && {flex:1,flexDirection:'column',maxHeight:cStyle.maxHeight,maxWidth : Math.max(layout.width-defaultNumber(contentLayout.x)),justifyContent:'center',alignItems:'center'} || {};
67
+ return <View ref={layoutRef}
68
+ onLayout={(a,b,c)=>{
69
+ if(onLayout && onLayout(a,b,c) === false) return;
70
+ if(!hasInitializedRef.current){
71
+ updateLayout();
72
+ }
73
+ }}
74
+ {...rest}
75
+ style={[theme.styles.w100,cStyle,style,fStyle,maxHeight && {maxHeight}, minHeight && {minHeight}]} testID={testID+"_ScrollViewContainer"}>
76
+ {hasUpdateLayout || withActivityIndicator === false ?children : <ActivityIndicator size={'large'}/>}
77
+ </View>
78
+ });
79
+
80
+ AutoSizerVerticalComponent.displayName = "AutoSizerVerticalComponent";
81
+ export default AutoSizerVerticalComponent;
82
+
83
+ AutoSizerVerticalComponent.propTypes = {
84
+ ...defaultObj(View.propTypes),
85
+ withActivityIndicator : PropTypes.bool,//si l'on utilisera l'activity indicator pour le chargement du contentu
86
+ maxHeight : PropTypes.number,
87
+ minHeight : PropTypes.number,
88
+ }
@@ -0,0 +1,3 @@
1
+ export {default as Vertical} from "./Vertical";
2
+
3
+ export {default} from "./AutoResizer";
@@ -406,7 +406,6 @@ const DatagridFactory = (Factory)=>{
406
406
  }
407
407
  ]
408
408
  }
409
- const maxHeight = this.getMaxListHeight();
410
409
  const isLoading = this.isLoading();
411
410
  const _progressBar = this.getProgressBar();
412
411
  const pointerEvents = this.getPointerEvents();
@@ -524,7 +523,7 @@ const DatagridFactory = (Factory)=>{
524
523
  </ScrollView>
525
524
  </View>
526
525
  return <View testID={testID+"_Container"} pointerEvents={pointerEvents} style={[styles.container]} collapsable={false}>
527
- { <View testID={testID+"_ContentContainer"} style={[{maxHeight,height:maxHeight}]}>
526
+ { <View testID={testID+"_ContentContainer"}>
528
527
  <View testID={testID+"_AccordionHeader"} style={[styles.accordionHeader]} ref={this.layoutRef} onLayout={this.updateLayout.bind(this)}>
529
528
  {this.props.showActions !== false ? <DatagridActions
530
529
  testID={testID+"_Actions"}
@@ -564,7 +563,6 @@ const DatagridFactory = (Factory)=>{
564
563
  prepareItems = {false}
565
564
  {...rest}
566
565
  {...accordionProps}
567
- containerProps = {{style:[{maxHeight}]}}
568
566
  onRender = {this.onRender.bind(this)}
569
567
  testID = {testID}
570
568
  extraData = {this.state.refresh}
@@ -558,6 +558,9 @@ export default class CommonDatagridComponent extends AppComponent {
558
558
  isDatagrid(){
559
559
  return false;
560
560
  }
561
+ isSWRDatagrid(){
562
+ return !!this.props.isSWRDatagrid;
563
+ }
561
564
  callSRowCallback({selected,row,rowIndex,key,cb}){
562
565
  let count = Object.size(this.selectedRows);
563
566
  let sArg = this.getActionsArgs(selected);
@@ -3338,6 +3341,9 @@ export default class CommonDatagridComponent extends AppComponent {
3338
3341
  delete fetchOptions.limit
3339
3342
  }
3340
3343
  }
3344
+ if(this.isSWRDatagrid()){
3345
+ fetchOptions.withTotal = true;
3346
+ }
3341
3347
  return fetchOptions;
3342
3348
  }
3343
3349
  getFetchDataOpts(){
@@ -416,6 +416,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
416
416
  opts = getFetchOptions({showError:showProgressRef.current,...opts});
417
417
  isInitializedRef.current = true;
418
418
  fetchOptionsRef.current = opts;
419
+ opts.withTotal = true;
419
420
  sortRef.current = opts.fetchOptions.sort;
420
421
  if(force){
421
422
  pageRef.current = firstPage;
@@ -423,6 +424,7 @@ const SWRDatagridComponent = React.forwardRef((props,ref)=>{
423
424
  doRefresh(force);
424
425
  return false;
425
426
  }}
427
+ isSWRDatagrid
426
428
  isTableData
427
429
  fetchData = {undefined}
428
430
  data = {dataRef.current}
@@ -190,8 +190,8 @@ const DatagridFactory = (Factory)=>{
190
190
  }
191
191
  const maxHeight = this.getMaxListHeight();
192
192
  const rPagination = showPagination ? <View style={[styles.paginationContainer]}>
193
- <ScrollView horizontal style={styles.paginationContainerStyle} contentContainerStyle={styles.minW100}>
194
- <View style={[styles.paginationContent]}>
193
+ <ScrollView testID={testID+"_Datagrid_Headers"} horizontal style={styles.paginationContainerStyle} contentContainerStyle={styles.minW100}>
194
+ <View testID={testID+"_HeaderPaginationContent"} style={[styles.paginationContent]}>
195
195
  <View testID={testID+"_HeaderQueryLimit"}>
196
196
  {this.renderQueryLimit(this.getStateDataSize().formatNumber())}
197
197
  </View>
@@ -229,6 +229,7 @@ const DatagridFactory = (Factory)=>{
229
229
  })}
230
230
  </>}
231
231
  <BottomSheetMenu
232
+ testID = {testID+"_BottomSheetMenu"}
232
233
  anchor = {(props)=>{
233
234
  return <Icon {...props} title={isMobile?"Actions":"Colonnes"} name={isMobile?MENU_ICON:'view-column'}></Icon>
234
235
  }}
@@ -292,8 +293,8 @@ const DatagridFactory = (Factory)=>{
292
293
  </View>
293
294
  </ScrollView>
294
295
  </View> : null;
295
- return <View style={[styles.container,{flex:1,maxHeight}]} pointerEvents={pointerEvents}>
296
- <View ref={this.layoutRef}>
296
+ return <View style={[styles.container,{flex:1,maxHeight}]} testID={testID+"_TableContainer"} pointerEvents={pointerEvents}>
297
+ <View ref={this.layoutRef} testID={testID+"_LayoutContainer"}>
297
298
  {this.props.showActions !== false ? <DatagridActions
298
299
  pointerEvents = {pointerEvents}
299
300
  title = {title}
@@ -312,12 +313,6 @@ const DatagridFactory = (Factory)=>{
312
313
  <Table
313
314
  ref = {this.listRef}
314
315
  {...rest}
315
- onLayout = {(args)=>{
316
- if(rest.onLayout){
317
- rest.onLayout(args);
318
- }
319
- this.updateLayout(args);
320
- }}
321
316
  sortedColumn = {sortedColumn}
322
317
  onRender = {this.onRender.bind(this)}
323
318
  getItemType = {this.getFlashListItemType.bind(this)}
@@ -0,0 +1,38 @@
1
+ import React from '$react';
2
+ import { ScrollView} from 'react-native';
3
+ import PropTypes from "prop-types";
4
+ import {defaultStr,defaultObj} from "$utils";
5
+ import {Vertical as AutoSizeVertical} from "$ecomponents/AutoSizer";
6
+
7
+ const ScrollViewComponent = React.forwardRef(({withAutoSizer,autoSizerProps,testID,...rest},ref) => {
8
+ testID = defaultStr(testID,'RN_ScrollViewComponent');
9
+ const autoSize = React.useRef(withAutoSizer).current;
10
+ if(!autoSize || rest.horizontal === true || rest.vertical === false){
11
+ return <ScrollView testID={testID} ref={ref} {...rest}/>
12
+ }
13
+ autoSizerProps = defaultObj(autoSizerProps);
14
+ const autoSizeRef = React.useRef(null);
15
+ return <AutoSizeVertical {...autoSizerProps} ref = {autoSizeRef} testID={testID+"_ScrollViewContainer"}>
16
+ <ScrollView
17
+ ref={ref}
18
+ {...rest}
19
+ testID={testID}
20
+ onContentSizeChange = {(a,b,c,d)=>{
21
+ if(rest.onContentSizeChange && rest.onContentSizeChange(a,b,c,d)===false) return;
22
+ if(autoSizeRef.current && autoSizeRef.current.updateLayout){
23
+ return autoSizeRef.current.updateLayout();
24
+ }
25
+ }}
26
+ />
27
+ </AutoSizeVertical>
28
+ });
29
+
30
+ ScrollViewComponent.displayName = "ScrollViewComponent";
31
+ export default ScrollViewComponent;
32
+
33
+ ScrollViewComponent.propTypes = {
34
+ ...defaultObj(ScrollView.propTypes),
35
+ withAutoSizer : PropTypes.bool,//si le contenu du scrollView sera wrap par le composant AutoSizer
36
+ maxHeight : PropTypes.number,
37
+ minHeight : PropTypes.number,
38
+ }
@@ -0,0 +1,84 @@
1
+ import React from '$react';
2
+ import { ScrollView,Dimensions} from 'react-native';
3
+ import PropTypes from "prop-types";
4
+ import View from "$ecomponents/View";
5
+ import theme from "$theme";
6
+ import {defaultStr,defaultObj,defaultNumber} from "$utils";
7
+ import APP from "$capp/instance";
8
+ import ActivityIndicator from "$ecomponents/ActivityIndicator";
9
+ const ScrollViewComponent = React.forwardRef(({withAutoSizer,containerProps,maxHeight,minHeight,testID:customTestID,children:cChildren,...rest},ref) => {
10
+ const testID = defaultStr(customTestID,'RN_ScrollViewComponent');
11
+ const autoSizeRef = React.useRef(withAutoSizer);
12
+ if(!autoSizeRef.current || rest.horizontal === true || rest.vertical === false){
13
+ return <ScrollView testID={testID} ref={ref} {...rest} children={cChildren}/>
14
+ }
15
+ containerProps = defaultObj(containerProps)
16
+ const hasUpdateLayoutRef = React.useRef(false);
17
+ const isKeyboardOpenRef = React.useRef(false);
18
+ const layoutRef = React.useRef(null);
19
+ const [layout,setLayout] = React.useState(Dimensions.get("window"));
20
+ const {height} = layout;
21
+ const hasInitializedRef = React.useRef(false);
22
+ const children = React.useStableMemo(()=>cChildren,[cChildren]);
23
+ const updateLayout = ()=>{
24
+ return new Promise((resolve)=>{
25
+ hasUpdateLayoutRef.current = true;
26
+ if(layoutRef.current && layoutRef.current.measureInWindow){
27
+ layoutRef.current.measureInWindow((x, y, width, height) => {
28
+ const r = {...Dimensions.get("window"),layout:{ x, y, width, height }};
29
+ setLayout(r);
30
+ hasInitializedRef.current = true;
31
+ resolve(r);
32
+ });
33
+ } else {
34
+ setLayout(Dimensions.get("window"))
35
+ }
36
+ })
37
+ }
38
+ React.useEffect(()=>{
39
+ const onKeyboardToggle = ({visible})=>{
40
+ isKeyboardOpenRef.current = visible;
41
+ };
42
+ const onResizePage = ()=>{
43
+ setTimeout(()=>{
44
+ if(isKeyboardOpenRef.current) return;
45
+ updateLayout();
46
+ },300);
47
+ }
48
+ APP.on(APP.EVENTS.RESIZE_PAGE,onResizePage);
49
+ APP.on(APP.EVENTS.KEYBOARD_DID_TOGGLE,onKeyboardToggle)
50
+ return ()=>{
51
+ APP.off(APP.EVENTS.RESIZE_PAGE,onResizePage);
52
+ APP.off(APP.EVENTS.KEYBOARD_DID_TOGGLE,onKeyboardToggle);
53
+ }
54
+ },[]);
55
+ const hasUpdateLayout = hasUpdateLayoutRef.current;
56
+ const cStyle ={width:'100%',maxHeight:Math.max(height-100,250)};
57
+ const contentLayout = defaultObj(layout.layout);
58
+ cStyle.minHeight = Math.min(Math.max(layout.height-defaultNumber(contentLayout.y),250));
59
+ const contentContainerStyle = ([cStyle,rest.contentContainerStyle]);
60
+ const fStyle = !hasUpdateLayout && {flex:1,maxWidth:layout.width - defaultNumber(contentLayout.x)};
61
+ return <View ref={layoutRef} onLayout={()=>{
62
+ if(!hasInitializedRef.current){
63
+ updateLayout();
64
+ }
65
+ }} {...containerProps} style={[theme.styles.w100,containerProps.style,fStyle]} testID={testID+"_ScrollViewContainer"}>
66
+ <ScrollView
67
+ ref={ref} {...rest}
68
+ testID={testID}
69
+ children={hasUpdateLayout?children : <ActivityIndicator size={'large'}
70
+ style={[{flex:1}]}/>}
71
+ contentContainerStyle = {[contentContainerStyle,fStyle]}
72
+ />
73
+ </View>
74
+ });
75
+
76
+ ScrollViewComponent.displayName = "ScrollViewComponent";
77
+ export default ScrollViewComponent;
78
+
79
+ ScrollViewComponent.propTypes = {
80
+ ...defaultObj(ScrollView.propTypes),
81
+ withAutoSizer : PropTypes.bool,//si la taille du scrollView sera withAutoSizer
82
+ maxHeight : PropTypes.number,
83
+ minHeight : PropTypes.number,
84
+ }
@@ -1,74 +1,33 @@
1
1
  import React from '$react';
2
- import { ScrollView,Dimensions } from 'react-native';
2
+ import { ScrollView} from 'react-native';
3
3
  import PropTypes from "prop-types";
4
- import View from "$ecomponents/View";
5
- import theme from "$theme";
6
4
  import {defaultStr,defaultObj} from "$utils";
7
- import APP from "$capp/instance";
8
- const ScrollViewComponent = React.forwardRef(({virtualized,vertical,horizontal,contentProps,containerProps,mediaQueryUpdateNativeProps,testID:customTestID,children:cChildren,screenIndent:sIndent,...rest},ref) => {
9
- const testID = defaultStr(customTestID,'RN_ScrollViewComponent');
10
- containerProps = defaultObj(containerProps)
11
- if(horizontal === true || vertical === false){
12
- return <ScrollView horizontal testID={testID} ref={ref} {...rest} children={cChildren}/>
13
- }
14
- const isKeyboardOpenRef = React.useRef(false);
15
- const layoutRef = React.useRef(null);
16
- const [layout,setLayout] = React.useState(Dimensions.get("window"));
17
- const {height} = layout;
18
- const hasInitializedRef = React.useRef(false);
19
- const children = React.useStableMemo(()=>cChildren,[cChildren]);
20
- const updateLayout = ()=>{
21
- return new Promise((resolve)=>{
22
- if(layoutRef.current && layoutRef.current.measureInWindow){
23
- layoutRef.current.measureInWindow((x, y, width, height) => {
24
- const r = {...Dimensions.get("window"),layout:{ x, y, width, height }};
25
- setLayout(r);
26
- hasInitializedRef.current = true;
27
- resolve(r);
28
- });
29
- }
30
- })
31
- }
32
- React.useEffect(()=>{
33
- const onKeyboardToggle = ({visible})=>{
34
- isKeyboardOpenRef.current = visible;
35
- };
36
- const onResizePage = ()=>{
37
- setTimeout(()=>{
38
- if(isKeyboardOpenRef.current) return;
39
- updateLayout();
40
- },300);
41
- }
42
- APP.on(APP.EVENTS.RESIZE_PAGE,onResizePage);
43
- APP.on(APP.EVENTS.KEYBOARD_DID_TOGGLE,onKeyboardToggle)
44
- return ()=>{
45
- APP.off(APP.EVENTS.RESIZE_PAGE,onResizePage);
46
- APP.off(APP.EVENTS.KEYBOARD_DID_TOGGLE,onKeyboardToggle);
47
- }
48
- },[]);
5
+ import {Vertical as AutoSizeVertical} from "$ecomponents/AutoSizer";
49
6
 
50
- const cStyle = {maxHeight:Math.max(height-100,250),width:'100%'};
51
- if(isObj(layout.layout) && typeof layout.layout.y =='number' && layout.layout.y>=10){
52
- const {layout : {x,y}} = layout;
53
- const minHeight = height - y;
54
- if(minHeight> 0){
55
- cStyle.minHeight = minHeight;
56
- }
7
+ const ScrollViewComponent = React.forwardRef(({withAutoSizer,autoSizerProps,testID,...rest},ref) => {
8
+ testID = defaultStr(testID,'RN_ScrollViewComponent');
9
+ const autoSize = React.useRef(withAutoSizer).current;
10
+ if(!autoSize || rest.horizontal === true || rest.vertical === false){
11
+ return <ScrollView testID={testID} ref={ref} {...rest}/>
57
12
  }
58
- const contentContainerStyle = [cStyle,rest.contentContainerStyle];
59
- return <View ref={layoutRef} onLayout={()=>{
60
- if(!hasInitializedRef.current){
61
- updateLayout();
62
- }
63
- }} {...containerProps} style={[theme.styles.w100,containerProps.style]} testID={testID+"_ScrollViewContainer"}>
13
+ autoSizerProps = defaultObj(autoSizerProps);
14
+ const autoSizerRef = React.useRef(null);
15
+ return <AutoSizeVertical ref={autoSizerRef} isScrollView {...autoSizerProps} testID={testID+"_ScrollViewContainer"}>
64
16
  <ScrollView
65
17
  ref={ref} {...rest}
66
- vertical = {vertical}
67
18
  testID={testID}
68
- children={children}
69
- contentContainerStyle = {contentContainerStyle}
19
+ onContentSizeChange = {(a,b,c,d)=>{
20
+ if(rest.onContentSizeChange && rest.onContentSizeChange(a,b,c,d)===false) return;
21
+ return;
22
+ if(autoSizerRef.current && autoSizerRef.current.updateLayout){
23
+ console.log("updating layout ",autoSizerRef.current);
24
+ autoSizerRef.current.updateLayout();
25
+ }
26
+ }}
27
+ style = {[{flex:1}]}
28
+ contentContainerStyle = {[{flex:1,height:'100%'},rest.contentContainerStyle]}
70
29
  />
71
- </View>
30
+ </AutoSizeVertical>
72
31
  });
73
32
 
74
33
  ScrollViewComponent.displayName = "ScrollViewComponent";
@@ -76,8 +35,7 @@ export default ScrollViewComponent;
76
35
 
77
36
  ScrollViewComponent.propTypes = {
78
37
  ...defaultObj(ScrollView.propTypes),
79
- horizontal : PropTypes.bool,
80
- vertical : PropTypes.bool,
81
- virtualized : PropTypes.bool,
82
- contentProps : PropTypes.object,
38
+ withAutoSizer : PropTypes.bool,//si le contenu du scrollView sera wrap par le composant AutoSizer
39
+ maxHeight : PropTypes.number,
40
+ minHeight : PropTypes.number,
83
41
  }
@@ -0,0 +1,83 @@
1
+ import React from '$react';
2
+ import { ScrollView,Dimensions } from 'react-native';
3
+ import PropTypes from "prop-types";
4
+ import View from "$ecomponents/View";
5
+ import theme from "$theme";
6
+ import {defaultStr,defaultObj} from "$utils";
7
+ import APP from "$capp/instance";
8
+ import {isWeb as isw} from "$cplatform";
9
+ const ScrollViewComponent = React.forwardRef(({containerProps,withAutoSizer,testID,...rest},ref) => {
10
+ testID = defaultStr(testID,'RN_ScrollViewComponent');
11
+ const autoSize = React.useRef(withAutoSizer).current;
12
+ if(!autoSize || rest.horizontal === true || rest.vertical === false){
13
+ return <ScrollView testID={testID} ref={ref} {...rest}/>
14
+ }
15
+ containerProps = defaultObj(containerProps)
16
+ const isWeb = isw();
17
+ const isKeyboardOpenRef = React.useRef(false);
18
+ const layoutRef = React.useRef(null);
19
+ const [layout,setLayout] = React.useState(Dimensions.get("window"));
20
+ const {height} = layout;
21
+ const hasInitializedRef = React.useRef(false);
22
+ const children = React.useStableMemo(()=>rest.children,[rest.children]);
23
+ const updateLayout = ()=>{
24
+ return new Promise((resolve)=>{
25
+ if(layoutRef.current && layoutRef.current.measureInWindow){
26
+ layoutRef.current.measureInWindow((x, y, width, height) => {
27
+ const r = {...Dimensions.get("window"),layout:{ x, y, width, height }};
28
+ setLayout(r);
29
+ hasInitializedRef.current = true;
30
+ resolve(r);
31
+ });
32
+ }
33
+ })
34
+ }
35
+ React.useEffect(()=>{
36
+ const onKeyboardToggle = ({visible})=>{
37
+ isKeyboardOpenRef.current = visible;
38
+ };
39
+ const onResizePage = ()=>{
40
+ setTimeout(()=>{
41
+ if(isKeyboardOpenRef.current) return;
42
+ updateLayout();
43
+ },300);
44
+ }
45
+ APP.on(APP.EVENTS.RESIZE_PAGE,onResizePage);
46
+ APP.on(APP.EVENTS.KEYBOARD_DID_TOGGLE,onKeyboardToggle)
47
+ return ()=>{
48
+ APP.off(APP.EVENTS.RESIZE_PAGE,onResizePage);
49
+ APP.off(APP.EVENTS.KEYBOARD_DID_TOGGLE,onKeyboardToggle);
50
+ }
51
+ },[]);
52
+
53
+ const cStyle = {maxHeight:Math.max(height-100,250),width:'100%'};
54
+ if(isObj(layout.layout) && typeof layout.layout.y =='number' && layout.layout.y>=10){
55
+ const {layout : {x,y}} = layout;
56
+ const minHeight = height - y;
57
+ if(minHeight> 0){
58
+ cStyle.minHeight = minHeight;
59
+ }
60
+ }
61
+ const contentContainerStyle = [cStyle,rest.contentContainerStyle];
62
+ return <View ref={layoutRef} onLayout={()=>{
63
+ if(!hasInitializedRef.current){
64
+ updateLayout();
65
+ }
66
+ }} {...containerProps} style={[theme.styles.w100,containerProps.style]} testID={testID+"_ScrollViewContainer"}>
67
+ <ScrollView
68
+ ref={ref}
69
+ {...rest}
70
+ testID={testID}
71
+ children={children}
72
+ contentContainerStyle = {contentContainerStyle}
73
+ />
74
+ </View>
75
+ });
76
+
77
+ ScrollViewComponent.displayName = "ScrollViewComponent";
78
+ export default ScrollViewComponent;
79
+
80
+ ScrollViewComponent.propTypes = {
81
+ ...defaultObj(ScrollView.propTypes),
82
+ withAutoSizer : PropTypes.bool,
83
+ }
@@ -49,8 +49,9 @@ const AbsoluteScrollView = React.forwardRef(({testID,contentProps,listRef,contai
49
49
  args = defaultObj(args);
50
50
  if(isObj(args.contentOffset) && isObj(args.contentSize)){
51
51
  const {x} = args.contentOffset;
52
+ const {width:contentWidth} = args.contentSize;
52
53
  const {width} = Dimensions.get("window");
53
- const visible = x >= width-10 ? false : true;
54
+ const visible = x >= width-10 && (contentWidth-x)<10 ? false : true;
54
55
  if(state.visible != visible){
55
56
  return setState({...state,visible});
56
57
  }
@@ -67,13 +68,22 @@ const AbsoluteScrollView = React.forwardRef(({testID,contentProps,listRef,contai
67
68
  React.useEffect(()=>{
68
69
  toggleVisible();
69
70
  },[styles])
71
+ let canBeVisible = true;
72
+ if(isObj(styles.content) && isObj(styles.contentContainer)){
73
+ if(typeof styles.content.height =='number' && typeof styles.contentContainer.height =='number'){
74
+ if(styles.content.height -10 <= styles.contentContainer.height){
75
+ canBeVisible = false;
76
+ }
77
+ }
78
+ }
79
+ const hidden = (!canBeVisible || !visible || !layoutVisible) ;
70
80
  return <Portal>
71
- {<View testID={testID+"_Containter"} {...containerProps} style={[mainStyles.container,containerProps.style,styles.container,{left:win.width-10},(!visible || !layoutVisible) &&{display:'none',width:0,opacity:0}]}>
81
+ {<View testID={testID+"_Containter"} {...containerProps} style={[mainStyles.container,containerProps.style,styles.container,{left:win.width-10},hidden &&{display:'none',width:0,opacity:0}]}>
72
82
  <ScrollView
73
83
  {...props}
74
84
  ref = {scrollViewRef}
75
85
  testID={testID}
76
- contentContainerStyle = {[props.contentContainerStyle,mainStyles.contentContainer,styles.containerContainer]}
86
+ contentContainerStyle = {[props.contentContainerStyle,mainStyles.contentContainer,styles.contentContainer]}
77
87
  vertical
78
88
  >
79
89
  <View
@@ -96,7 +96,7 @@ const VirtuosoListComponent = React.forwardRef(({items,onRender,testID,renderIte
96
96
  }
97
97
  },[]);
98
98
  React.useOnRender(onRender,Math.max(Array.isArray(items) && items.length/10 || 0,500))
99
- return <View {...containerProps} {...props} style={[{flex:1},containerProps.style,style,{minWidth:'100%',maxWidth:'100%'}]} onLayout={onLayout} testID={testID}>
99
+ return <View {...containerProps} {...props} style={[{flex:1},containerProps.style,style,{minWidth:'100%',height:'100%',maxWidth:'100%'}]} onLayout={onLayout} testID={testID}>
100
100
  <Virtuoso
101
101
  {...r2}
102
102
  style = {listStyle}
@@ -0,0 +1,15 @@
1
+ import React from "$react";
2
+ import {Vertical as AutoSizeVertical} from "$ecomponents/AutoSizer";
3
+ import List from "./List";
4
+ import {defaultStr,defaultObj} from "$utils";
5
+ const AutoSizeVerticalList = React.forwardRef(({testID,autoSizerProps,...props},ref)=>{
6
+ testID = defaultStr(testID,"RN_AutoSizeVerticalListComponent")
7
+ autoSizerProps = defaultObj(autoSizerProps);
8
+ return <AutoSizeVertical testID={testID+"_AutoSizerVertical"} {...autoSizerProps} >
9
+ <List {...props} ref={ref}/>
10
+ </AutoSizeVertical>
11
+ })
12
+
13
+ AutoSizeVerticalList.displayName = "AutoSizeVerticalListComponent";
14
+
15
+ export default AutoSizeVerticalList;
@@ -7,7 +7,6 @@ import Label from "$ecomponents/Label";
7
7
  import { StyleSheet,View as RNView,ScrollView,Dimensions} from "react-native";
8
8
  import { getRowStyle } from "$ecomponents/Datagrid/utils";
9
9
  import {isMobileNative} from "$cplatform";
10
- import {isMobileMedia} from "$dimensions";
11
10
  import theme from "$theme";
12
11
  import AbsoluteScrollView from "./AbsoluteScrollView";
13
12
  import Cell from "./Cell";
@@ -357,7 +356,7 @@ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContai
357
356
  testID = {testID}
358
357
  prepareItems = {false}
359
358
  items = {items}
360
- contentContainerStyle = {[styles.contentContainer,{width:listWidth,minWidth:totalWidths,position:'absolute',right:'0'}]}
359
+ contentContainerStyle = {[styles.contentContainer,{width:listWidth,minWidth:totalWidths}]}
361
360
  style = {[styles.datagrid,{width:listWidth,minWidth:totalWidths}]}
362
361
  keyExtractor = {typeof getRowKey =='function'? getRowKey : React.getKey}
363
362
  onScroll = {getOnScrollCb([absoluteScrollViewRef],(args)=>{
@@ -394,7 +394,11 @@ export default class TableDataScreenComponent extends FormDataScreen{
394
394
  const isMobile = isMobileOrTabletMedia();
395
395
  const contentProps = restProps.contentProps;
396
396
  const elevation = restProps.elevation;
397
- const renderingTabsProps = {tabs,data:this.getCurrentData(),isMobile,sessionName:this.INITIAL_STATE.sessionName,props:restProps,tabProps,tabsProps,context,tabKey};
397
+ const renderingTabsProps = {tabs,data:this.getCurrentData(),tabsPropsMutator:({tabs,tabsProps})=>{
398
+ if(!isMobileOrTabletMedia()){
399
+ tabsProps.withScrollView = false;
400
+ }
401
+ },isMobile,sessionName:this.INITIAL_STATE.sessionName,props:restProps,tabProps,tabsProps,context,tabKey};
398
402
  const hasTabs = Object.size(tabs,true);
399
403
  let mainContent = undefined;
400
404
  testID = defaultStr(testID,"RN_TableDataScreenItem_"+restProps.tableName);
@@ -417,7 +421,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
417
421
  mainContent = ct;
418
422
  } else {
419
423
  mainContent = <View {...contentProps} testID={testID+"_ContentContainer"} style={[styles.container,styles.noPadding]}>
420
- <ScrollView testID={testID+"_MainContentScrollView"} contentProps={{style:theme.styles.p1}}>
424
+ <ScrollView withAutoSizer testID={testID+"_MainContentScrollView"} contentProps={{style:theme.styles.p1}}>
421
425
  <Surface elevation={elevation} testID={testID+"_ContentHeader"} style={[styles.screenContent,theme.styles.p1,header?styles.screenContentWithHeader:null]}>
422
426
  {header}
423
427
  {content}
@@ -443,7 +447,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
443
447
  appBarProps.elevation = 0;
444
448
  restProps.elevation = 0;
445
449
  }
446
- return <ScreenContainer {...restProps} appBarProps = {appBarProps} testID={testID}>
450
+ return <ScreenContainer {...restProps} withScrollView={false} appBarProps = {appBarProps} testID={testID}>
447
451
  {this.wrapRenderingContent(mainContent,{testID})}
448
452
  </ScreenContainer>
449
453
  }
@@ -8,13 +8,13 @@ import {getTableDataRouteName} from "$enavigation/utils";
8
8
  //@seee : https://github.com/typeorm/typeorm/blob/master/src/entity-schema/EntitySchemaColumnOptions.ts
9
9
  export const generatedColumnsProperties = ["createDate","updateDate","deleteDate","createBy","updateBy","deleteBy"]
10
10
 
11
- export const renderTabsContent = ({tabs,context,data,sessionName,isMobile,props,firstTab,tabKey,tabProps,tabsProps})=>{
11
+ export const renderTabsContent = ({tabs,context,data,sessionName,tabsPropsMutator,isMobile,props,firstTab,tabKey,tabProps,tabsProps})=>{
12
12
  let tabsArr = [],hasFirstTab = false;
13
13
  if(React.isValidElement(firstTab)){
14
14
  tabsArr.push(firstTab);
15
15
  hasFirstTab = true;
16
16
  }
17
- tabsProps = Object.assign({},tabsProps);
17
+ tabsProps = Object.clone(tabsProps);
18
18
  tabsProps.centered = false;
19
19
  tabKey = typeof tabKey =='string' || typeof tabKey =='number'? tabKey : 'first-tab-key';
20
20
  let idx = tabsArr.length-1;
@@ -52,6 +52,9 @@ export const renderTabsContent = ({tabs,context,data,sessionName,isMobile,props,
52
52
  })
53
53
  }
54
54
  if(tabsArr.length> (hasFirstTab ? 1 : 0)){
55
+ if(typeof tabsPropsMutator =='function' && tabsPropsMutator({tabsProps,tabs:tabsArr,hasFirstTab}) === false){
56
+ return null;
57
+ }
55
58
  return <Tab testID={testID}
56
59
  {...tabsProps}
57
60
  onChange={(args)=>{
@@ -87,43 +87,45 @@ export default function HelpScreen(props){
87
87
  <Label primary textBold style={theme.styles.mv05} >{appConfig.name+", Notes de mise à jour."}</Label>
88
88
  </Link>
89
89
  </View>
90
- {Object.size(openLibraries,true) ? <View style={[theme.styles.w100]}>
91
- <Expandable
92
- testID={testID+"_OpenLibraries"}
93
- title = {"A propos des librairies tiers"}
94
- titleProps = {{style:theme.styles.ph1}}
95
- style = {{backgroundColor:'transparent'}}
96
- >
97
- <View testID={testID+"_OpenLibraries_Header"} style={[theme.styles.row,theme.styles.flexWrap]}>
98
- <Label testID={testID+"_OpenLibraries_HeaderLabel"} primary textBold>{appConfig.name+" "}</Label>
99
- <Label>est bâti sur un ensemble d'outils et librairies open Source</Label>
100
- </View>
101
- <View testID={testID+"_OpenLibrariesContent"} style={[theme.styles.w100,theme.styles.pv1]}>
102
- <Grid.Row style={borderStyle}>
103
- <Label style={gridStyles[0]} textBold>#</Label>
104
- <Label style={gridStyles[1]} textBold>Librairie/Outil</Label>
105
- <Label style={gridStyles[2]} textBold>Version</Label>
106
- <Label style={gridStyles[3]} textBold>Licence</Label>
107
- </Grid.Row>
108
- {Object.mapToArray(openLibraries,(lib,i,_i)=>{
109
- return <Grid.Row key={i} style={borderStyle}>
110
- <Label style={gridStyles[0]}>
111
- {_i.formatNumber()}
112
- </Label>
113
- <AutoLink style={gridStyles[1]} url={lib.url}>
114
- <Label splitText>{i}</Label>
115
- </AutoLink>
116
- <AutoLink style={gridStyles[2]}>
117
- <Label splitText numberOfLines={2}>{defaultStr(lib.version)}</Label>
118
- </AutoLink>
119
- <AutoLink url={lib.licenseUrl} style={gridStyles[3]}>
120
- <Label splitText>{lib.license}</Label>
121
- </AutoLink>
90
+ <View style={theme.styles.w100}>
91
+ {Object.size(openLibraries,true) ? <View style={[theme.styles.w100]}>
92
+ <Expandable
93
+ testID={testID+"_OpenLibraries"}
94
+ title = {"A propos des librairies tiers"}
95
+ titleProps = {{style:theme.styles.ph1}}
96
+ style = {{backgroundColor:'transparent'}}
97
+ >
98
+ <View testID={testID+"_OpenLibraries_Header"} style={[theme.styles.row,theme.styles.flexWrap]}>
99
+ <Label testID={testID+"_OpenLibraries_HeaderLabel"} primary textBold>{appConfig.name+" "}</Label>
100
+ <Label>est bâti sur un ensemble d'outils et librairies open Source</Label>
101
+ </View>
102
+ <View testID={testID+"_OpenLibrariesContent"} style={[theme.styles.w100,theme.styles.pv1]}>
103
+ <Grid.Row style={borderStyle}>
104
+ <Label style={gridStyles[0]} textBold>#</Label>
105
+ <Label style={gridStyles[1]} textBold>Librairie/Outil</Label>
106
+ <Label style={gridStyles[2]} textBold>Version</Label>
107
+ <Label style={gridStyles[3]} textBold>Licence</Label>
122
108
  </Grid.Row>
123
- })}
124
- </View>
125
- </Expandable>
126
- </View>: null}
109
+ {Object.mapToArray(openLibraries,(lib,i,_i)=>{
110
+ return <Grid.Row key={i} style={borderStyle}>
111
+ <Label style={gridStyles[0]}>
112
+ {_i.formatNumber()}
113
+ </Label>
114
+ <AutoLink style={gridStyles[1]} url={lib.url}>
115
+ <Label splitText>{i}</Label>
116
+ </AutoLink>
117
+ <AutoLink style={gridStyles[2]}>
118
+ <Label splitText numberOfLines={2}>{defaultStr(lib.version)}</Label>
119
+ </AutoLink>
120
+ <AutoLink url={lib.licenseUrl} style={gridStyles[3]}>
121
+ <Label splitText>{lib.license}</Label>
122
+ </AutoLink>
123
+ </Grid.Row>
124
+ })}
125
+ </View>
126
+ </Expandable>
127
+ </View>: null}
128
+ </View>
127
129
  </View>
128
130
  </Screen>
129
131
  }