@fto-consult/expo-ui 2.42.1 → 2.43.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "2.42.1",
3
+ "version": "2.43.1",
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.3.0",
64
+ "@fto-consult/common": "^2.4.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",
package/src/App.js CHANGED
@@ -32,7 +32,8 @@ import { AppState } from 'react-native'
32
32
  import {canFetchOffline} from "$capi/utils";
33
33
  import {defaultNumber} from "$utils";
34
34
  import { timeout as SWR_REFRESH_TIMEOUT} from '$ecomponents/Datagrid/SWRDatagrid';
35
-
35
+ import { Dimensions,Keyboard } from 'react-native';
36
+ import {isTouchDevice} from "$platform";
36
37
  import * as Utils from "$utils";
37
38
  Object.map(Utils,(v,i)=>{
38
39
  if(typeof v =='function' && typeof window !='undefined' && window && !window[i]){
@@ -48,6 +49,7 @@ export default function getIndex(options){
48
49
  const activeScreenRef = React.useRef('');
49
50
  const prevActiveScreenRef = React.useRef('');
50
51
  const appStateRef = React.useRef({});
52
+ const isKeyboardOpenRef = React.useRef(false);
51
53
  React.useEffect(()=>{
52
54
  ///la fonction de rappel lorsque le composant est monté
53
55
  let cb = typeof onMount =='function'? onMount() : null;
@@ -64,9 +66,39 @@ export default function getIndex(options){
64
66
  }
65
67
  APP.on(APP.EVENTS.SCREEN_FOCUS,onScreenFocus);
66
68
  APP.on(APP.EVENTS.SCREEN_BLUR,onScreenBlur);
69
+ const triggerKeyboardToggle = (status)=>{
70
+ APP.trigger(APP.EVENTS.KEYBOARD_DID_TOGGLE,{shown:status,status,visible:status,hide : !status});
71
+ }
72
+ const keyBoardDidShow = ()=>{
73
+ APP.trigger(APP.EVENTS.KEYBOARD_DID_SHOW);
74
+ triggerKeyboardToggle(true);
75
+ },keyBoardDidHide = ()=>{
76
+ APP.trigger(APP.EVENTS.KEYBOARD_DID_HIDE);
77
+ triggerKeyboardToggle(false);
78
+ }
79
+ const keyBoardDidShowListener = Keyboard.addListener("keyboardDidShow",keyBoardDidShow);
80
+ const keyBoardDidHideListener = Keyboard.addListener("keyboardDidHide",keyBoardDidHide);
81
+ const listener = isTouchDevice() && typeof window !=='undefined' && window && window.visualViewport && typeof window.visualViewport.addEventListener =='function'?
82
+ () => {
83
+ const minKeyboardHeight = 300;
84
+ const screen = Dimensions.get("screen");
85
+ const newState = screen.height - minKeyboardHeight > window.visualViewport.height
86
+ if (isKeyboardOpenRef.current != newState) {
87
+ isKeyboardOpenRef.current = newState;
88
+ newState ? keyBoardDidShow() : keyBoardDidHide();
89
+ }
90
+ } : undefined;
91
+ if(listener){
92
+ window.visualViewport.addEventListener('resize', listener);
93
+ }
67
94
  return ()=>{
68
95
  APP.off(APP.EVENTS.SCREEN_FOCUS,onScreenFocus);
69
96
  APP.off(APP.EVENTS.SCREEN_BLUR,onScreenBlur);
97
+ keyBoardDidShowListener && keyBoardDidShowListener.remove && keyBoardDidShowListener.remove();
98
+ keyBoardDidHideListener && keyBoardDidHideListener.remove && keyBoardDidHideListener.remove();
99
+ if(listener){
100
+ window.visualViewport.removeEventListener('resize', listener);
101
+ }
70
102
  if(typeof onUnmount =='function'){
71
103
  onUnmount();
72
104
  }
@@ -16,7 +16,7 @@ import {defaultStr} from "$utils";
16
16
  import View from "$ecomponents/View";
17
17
  import {Easing} from "react-native";
18
18
  import Portal from "$ecomponents/Portal";
19
- import ScrollView from "$ecomponents/ScrollView";
19
+ import { ScrollView } from "react-native";
20
20
 
21
21
  import {
22
22
  BackHandler,
@@ -1,8 +1,7 @@
1
1
  import CommonDatagrid,{TableData as CommonDatagridTableData} from "../Common";
2
2
  import {defaultObj,defaultArray,defaultStr,defaultDecimal,isNonNullString} from "$utils";
3
3
  import View from "$ecomponents/View";
4
- import { StyleSheet,Dimensions,Pressable } from "react-native";
5
- import ScrollView from "$ecomponents/ScrollView";
4
+ import { StyleSheet,Dimensions,Pressable ,ScrollView} from "react-native";
6
5
  import {isMobileOrTabletMedia} from "$cplatform/dimensions";
7
6
  import DatagridActions from "../Actions";
8
7
  import {SELECTABLE_COLUMN_WIDTH,getRowStyle} from "../utils";
@@ -161,7 +160,7 @@ const DatagridFactory = (Factory)=>{
161
160
  last:pagLast,
162
161
  total:pagination.rows,pages:countPages
163
162
  })*/
164
- const {visibleColumns} = this.preparedColumns;
163
+ const {visibleColumns,sortedColumn} = this.preparedColumns;
165
164
  const hasFootersFields = this.hasFootersFields();
166
165
  const {columnsWidths:widths} = this.state;
167
166
  const showFooters = this.canShowFooters(), showFilters = this.canShowFilters();
@@ -319,6 +318,7 @@ const DatagridFactory = (Factory)=>{
319
318
  }
320
319
  this.updateLayout(args);
321
320
  }}
321
+ sortedColumn = {sortedColumn}
322
322
  onRender = {this.onRender.bind(this)}
323
323
  getItemType = {this.getFlashListItemType.bind(this)}
324
324
  renderItem = {this.renderFlashListItem.bind(this)}
@@ -342,6 +342,7 @@ const DatagridFactory = (Factory)=>{
342
342
  }
343
343
  }}
344
344
  data = {this.state.data}
345
+ footers = {this.getFooterValues()}
345
346
  renderHeaderCell={this.renderHeaderCell.bind(this)}
346
347
  renderFilterCell={this.renderFilterCell.bind(this)}
347
348
  renderFooterCell={this.renderFooterCell.bind(this)}
@@ -2,8 +2,8 @@
2
2
  import {defaultStr,isObj} from "$utils";
3
3
  import {Dialog} from "react-native-paper";
4
4
  import {isNonNullString,defaultVal,defaultNumber,defaultObj,defaultBool } from "$utils";
5
- import {StyleSheet} from "react-native";
6
- import ScrollView from "$ecomponents/ScrollView";
5
+ import {StyleSheet,ScrollView} from "react-native";
6
+ //import ScrollView from "$ecomponents/ScrollView";
7
7
  import Modal from "$ecomponents/Modal";
8
8
  import PropTypes from "prop-types";
9
9
  import React from "$react";
@@ -1,6 +1,5 @@
1
1
  import React from "$react";
2
- import {StyleSheet } from "react-native";
3
- import ScrollView from "$ecomponents/ScrollView";
2
+ import {StyleSheet,ScrollView } from "react-native";
4
3
  import DrawerItems from "./DrawerItems";
5
4
  import {MINIMIZED_ICON_SIZE,ICON_SIZE, canBeMinimizedOrPermanent} from './utils';
6
5
  import DrawerHeader from "./DrawerHeader";
@@ -1,6 +1,5 @@
1
1
  import {StyleSheet,useWindowDimensions} from 'react-native';
2
2
  import DrawerLayout from './DrawerLayout';
3
- import ScrollView from "$ecomponents/ScrollView";
4
3
  import {isIos} from "$cplatform";
5
4
  import React from "$react";
6
5
  import PropTypes from "prop-types";
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react'
2
2
  import Types from 'prop-types';
3
- import {StyleSheet,View,useWindowDimensions} from "react-native";
4
- import ScrollView from "$ecomponents/ScrollView";
3
+ import {StyleSheet,ScrollView,View,useWindowDimensions} from "react-native";
5
4
  import {Paragraph,Button,List } from "react-native-paper";
6
5
  import Portal from "$ecomponents/Portal";
7
6
  import theme from "$theme";
@@ -1,6 +1,6 @@
1
1
  import React,{BaseComponent as AppComponent} from '$react';
2
2
  import View from "$components/View";
3
- import ScrollView from "$components/ScrollView";
3
+ import { ScrollView } from 'react-native';
4
4
  import {
5
5
  Platform,
6
6
  StyleSheet,
@@ -1,49 +1,42 @@
1
1
  import React from '$react';
2
- import { FlatList } from 'react-native';
3
- import { ScrollView,Dimensions,useWindowDimensions } from 'react-native';
2
+ import { ScrollView,Dimensions } from 'react-native';
4
3
  import PropTypes from "prop-types";
5
4
  import View from "$ecomponents/View";
6
- import {isMobileNative,isTouchDevice} from "$cplatform";
7
- import {isDesktopMedia} from "$cdimensions";
5
+ import theme from "$theme";
8
6
  import {defaultStr,defaultObj} from "$utils";
9
- const isNative = isMobileNative();
10
7
  import APP from "$capp/instance";
11
- const ScrollViewComponent = React.forwardRef((props,ref) => {
12
- const {virtualized,contentProps,mediaQueryUpdateNativeProps,testID:customTestID,children,screenIndent:sIndent,...rest} = props;
8
+ const ScrollViewComponent = React.forwardRef(({virtualized,contentProps,containerProps,mediaQueryUpdateNativeProps,testID:customTestID,children,screenIndent:sIndent,...rest},ref) => {
9
+ const isKeyboardOpenRef = React.useRef(false);
13
10
  const testID = defaultStr(customTestID,'RN_ScrollViewComponent');
14
- const cProps = defaultObj(contentProps);
11
+ containerProps = defaultObj(containerProps)
15
12
  const [layout,setLayout] = React.useState(Dimensions.get("window"));
16
13
  const {height} = layout;
17
14
  React.useEffect(()=>{
15
+ const onKeyboardToggle = ({visible})=>{
16
+ isKeyboardOpenRef.current = visible;
17
+ };
18
18
  const onResizePage = ()=>{
19
- if(isTouchDevice()) return;
20
19
  setTimeout(()=>{
20
+ //if(isKeyboardOpenRef.current) return;
21
21
  setLayout(Dimensions.get("window"))
22
- },200);
22
+ },300);
23
23
  }
24
24
  APP.on(APP.EVENTS.RESIZE_PAGE,onResizePage);
25
+ APP.on(APP.EVENTS.KEYBOARD_DID_TOGGLE,onKeyboardToggle)
25
26
  return ()=>{
26
27
  APP.off(APP.EVENTS.RESIZE_PAGE,onResizePage);
28
+ APP.off(APP.EVENTS.KEYBOARD_DID_TOGGLE,onKeyboardToggle);
27
29
  }
28
- },[])
29
- const showIndicator = true;//!isTouchDevice() || isDesktopMedia();
30
- return virtualized ? <FlatList
31
- //showsHorizontalScrollIndicator = {showIndicator}
32
- //showsVerticalScrollIndicator={showIndicator}
33
- {...rest}
34
- ref = {ref}
35
- testID = {testID}
36
- data={[]}
37
- keyExtractor={(_e, i) => 'dom' + i.toString()}
38
- ListEmptyComponent={null}
39
- renderItem={null}
40
- contentContainerStyle = {[!isNative && {flex:1,flexGrow: 1,maxHeight:Math.max(height-100,250)},rest.contentContainerStyle]}
41
- ListHeaderComponent={() => <View testID={testID+'_FlatListContent'} {...cProps} mediaQueryUpdateNativeProps = {mediaQueryUpdateNativeProps}
42
- >{children}</View>}
43
- /> : <ScrollView
44
- //showsHorizontalScrollIndicator = {showIndicator}
45
- //showsVerticalScrollIndicator={showIndicator}
46
- ref={ref} {...rest} testID={testID} children={children}/>
30
+ },[]);
31
+ const contentContainerStyle = [{maxHeight:Math.max(height-100,250),width:'100%'},rest.contentContainerStyle];
32
+ return <View {...containerProps} style={[theme.styles.w100,containerProps.style]} testID={testID+"_ScrollViewContainer"}>
33
+ <ScrollView
34
+ ref={ref} {...rest}
35
+ testID={testID}
36
+ children={children}
37
+ contentContainerStyle = {contentContainerStyle}
38
+ />
39
+ </View>
47
40
  });
48
41
 
49
42
  ScrollViewComponent.displayName = "ScrollViewComponent";
@@ -45,7 +45,7 @@ const getOnScrollCb = (refs,pos,cb2)=>{
45
45
  return isMobileNative()? cb : debounce(cb,200);
46
46
  }
47
47
 
48
- const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRender,height,progressBar,filter:customFilter,renderListContent,children,renderEmpty,renderItem,isRowSelected,headerScrollViewProps,footerScrollViewProps,scrollViewProps,showFooters,renderFooterCell,footerCellContainerProps,filterCellContainerProps,headerContainerProps,headerCellContainerProps,headerProps,rowProps:customRowProps,renderCell,cellContainerProps,hasFooters,renderHeaderCell,renderFilterCell,columnProps,getRowKey,columnsWidths,colsWidths,footerContainerProps,showHeaders,showFilters,columns,data,testID,...props},tableRef)=>{
48
+ const TableComponent = React.forwardRef(({containerProps,sortedColumn,listContainerStyle,onRender,height,progressBar,filter:customFilter,renderListContent,children,renderEmpty,renderItem,isRowSelected,headerScrollViewProps,footerScrollViewProps,scrollViewProps,showFooters,renderFooterCell,footerCellContainerProps,filterCellContainerProps,headerContainerProps,headerCellContainerProps,headerProps,rowProps:customRowProps,renderCell,cellContainerProps,hasFooters,renderHeaderCell,renderFilterCell,columnProps,getRowKey,columnsWidths,colsWidths,footerContainerProps,showHeaders,showFilters,columns,data,testID,...props},tableRef)=>{
49
49
  containerProps = defaultObj(containerProps);
50
50
  testID = defaultStr(testID,"RN_TableComponent");
51
51
  cellContainerProps = defaultObj(cellContainerProps);
@@ -128,7 +128,7 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
128
128
  columnIndex++;
129
129
  });
130
130
  return {columns:cols,columnsNames,headers,visibleColumns,vColumnsMapping,hasFooters,footers,filters};
131
- },[columns]);
131
+ },[columns,sortedColumn,props.footers]);
132
132
  const {columns:cols,headers,footers,filters,hasFooters:stateHasFooters,columnsNames,vColumnsMapping,visibleColumns} = preparedColumns;
133
133
  headerContainerProps = defaultObj(headerContainerProps);
134
134
  footerContainerProps = defaultObj(footerContainerProps);
@@ -340,7 +340,7 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
340
340
  testID = {testID}
341
341
  prepareItems = {false}
342
342
  items = {items}
343
- contentContainerStyle = {[styles.contentContainer,{with:listWidth,minWidth:totalWidths,position:'absolute',right:'0'}]}
343
+ contentContainerStyle = {[styles.contentContainer,{width:listWidth,minWidth:totalWidths,position:'absolute',right:'0'}]}
344
344
  style = {[styles.datagrid,{width:listWidth,minWidth:totalWidths}]}
345
345
  keyExtractor = {typeof getRowKey =='function'? getRowKey : React.getKey}
346
346
  onScroll = {getOnScrollCb([absoluteScrollViewRef],(args)=>{
@@ -3,7 +3,6 @@ import {StyleSheet} from 'react-native';
3
3
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
4
  import PropTypes from "prop-types";
5
5
  import {defaultObj,defaultStr,defaultNumber,defaultBool} from "$utils";
6
- import ScrollView from '$ecomponents/ScrollView';
7
6
  import View from "$ecomponents/View";
8
7
  import { useNavigation} from '$cnavigation';
9
8
  import Fab from "$elayouts/Fab";
@@ -13,6 +12,7 @@ import ErrorBoundary from "$ecomponents/ErrorBoundary";
13
12
  import Portal from "$ecomponents/Portal";
14
13
  import theme,{StyleProp} from "$theme";
15
14
  import StatusBar from "$ecomponents/StatusBar";
15
+ import { ScrollView } from 'react-native';
16
16
 
17
17
  const getDefaultTitle = (nTitle,returnStr)=>{
18
18
  let titleStr = React.getTextContent(nTitle);
@@ -88,7 +88,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
88
88
  args = {...f,...args,fetch,columnField:name,fieldName:name,id:args.value};
89
89
  const {context} = args;
90
90
  const r = typeof onBlur =='function'? onBlur (args) : undefined;
91
- if(r === false) return r;
91
+ if(r === false || (!args.value && typeof args.value != 'number')) return r;
92
92
  //on applique la validation seulement en cas de non mise à jour
93
93
  if(!this.isCurrentDocEditingUpdate() && context && typeof context.onNoValidate =='function'){
94
94
  const cb = typeof field.fetchUniqueId =='function'? field.fetchUniqueId : typeof this.fetchUniqueId =='function'? this.fetchUniqueId : undefined;
@@ -181,7 +181,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
181
181
  }
182
182
  /**** retourne les props en cours d'édition */
183
183
  getCurrentEditingProps (){
184
- return defaultObj(this.INITIAL_STATE.props);
184
+ return defaultObj(this.currentRenderingProps);
185
185
  }
186
186
  /* Attention, cette méthode est appélée dans la méthode getComponentProps de la classe parente.
187
187
  * Tenir de cette information capitale pour bien négocier l'appel de la dite méthode. Elle permet de retourner
@@ -303,7 +303,7 @@ export default class TableDataScreenComponent extends FormDataScreen{
303
303
  isUpdated,
304
304
  fields,
305
305
  });
306
- const rActionsArg = this.INITIAL_STATE.props = {
306
+ const rActionsArg = this.currentRenderingProps = {
307
307
  ...rest,
308
308
  ...formProps,
309
309
  context,
@@ -1,33 +0,0 @@
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
- import React from "$react";
6
- import { Keyboard, Text, TextInput, StyleSheet, View } from "react-native";
7
-
8
- /****
9
- * rewrite of @see : https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/KeyboardAvoidingView/index.js
10
- */
11
- const KeyboardAvoidingView = ({behavior,contentContainerStyle,keyboardVerticalOffset,...rest})=>{
12
- const frameRef = React.useRef(null);
13
- const onLayout = (event)=>{
14
- frameRef.current = event.nativeEvent.layout;
15
- };
16
- React.useEffect(() => {
17
- const keyboardDidShowListener = Keyboard.addListener(
18
- 'keyboardDidShow',
19
- (args) => {}
20
- );
21
- const keyboardDidHideListener = Keyboard.addListener(
22
- 'keyboardDidHide',
23
- (args) => {}
24
- );
25
- return () => {
26
- keyboardDidHideListener.remove();
27
- keyboardDidShowListener.remove();
28
- };
29
- }, []);
30
- return <View onLayout={onLayout} {...rest} />;
31
- }
32
-
33
- export default KeyboardAvoidingView;