@fto-consult/expo-ui 2.37.7 → 2.38.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.
Files changed (41) hide show
  1. package/metro.config.js +1 -0
  2. package/package.json +7 -6
  3. package/src/components/AutoResizer/index.js +104 -0
  4. package/src/components/Chart/appexChart/index.native.js +1 -1
  5. package/src/components/Chart/index.js +2 -1
  6. package/src/components/Datagrid/Accordion/Filters.js +0 -1
  7. package/src/components/Datagrid/Accordion/index.js +6 -12
  8. package/src/components/Datagrid/Common/Common.js +137 -53
  9. package/src/components/Datagrid/Common/utils.js +4 -1
  10. package/src/components/Datagrid/IndexComponent.js +1 -4
  11. package/src/components/Datagrid/SWRDatagrid.js +2 -16
  12. package/src/components/Datagrid/Table/index.js +10 -39
  13. package/src/components/Dialog/Dialog.js +0 -1
  14. package/src/components/Form/FormData/Dialog.js +1 -6
  15. package/src/components/Form/FormData/FormData.js +1 -2
  16. package/src/components/Form/FormData/FormDataActions.js +6 -9
  17. package/src/components/Hashtag/index.js +2 -2
  18. package/src/components/List/Common.js +0 -1
  19. package/src/components/Table/AbsoluteScrollView.js +3 -2
  20. package/src/components/Table/Cell.js +24 -0
  21. package/src/components/Table/Header.js +25 -0
  22. package/src/components/Table/List.js +196 -0
  23. package/src/components/Table/List.native.js +5 -0
  24. package/src/components/{Datagrid/Common → Table}/ProgressBar.js +0 -0
  25. package/src/components/Table/Row.js +21 -0
  26. package/src/components/Table/Test.js +0 -0
  27. package/src/components/Table/index.js +218 -202
  28. package/src/layouts/Screen/FormData/FormData.js +6 -15
  29. package/src/layouts/Screen/FormData/List.js +7 -8
  30. package/src/layouts/Screen/ScreenWithOrWithoutAuthContainer.js +4 -4
  31. package/src/layouts/Screen/TableData.js +6 -13
  32. package/src/media/file-system/utils/write.js +1 -1
  33. package/src/screens/Auth/Profile.js +2 -3
  34. package/src/screens/Auth/SignIn.js +1 -3
  35. package/src/screens/Help/PrivacyPolicy/index.js +1 -3
  36. package/src/screens/Help/TermsOfUses/index.js +1 -3
  37. package/src/screens/ScreenWrapper.js +82 -0
  38. package/src/screens/index.js +10 -68
  39. package/src/screens/utils.js +2 -0
  40. package/webpack.config.js +9 -1
  41. package/src/components/Datagrid/Table/Cell.js +0 -45
@@ -7,12 +7,9 @@ import {isWeb} from "$cplatform";
7
7
 
8
8
  export default class FormDataActionComponent extends FormData {
9
9
  isFullScreen(){
10
- const mainProps = this.getMainProps();
10
+ const mainProps = this.props;
11
11
  return typeof mainProps.fullScreen =='boolean'? mainProps.fullScreen : typeof mainProps.fullPage =='boolean'? mainProps.fullPage : mainProps.responsive !== false ? Dimensions.isMobileOrTabletMedia() : false;
12
12
  }
13
- getMainProps (){
14
- return this.props;
15
- }
16
13
  getConfirmTitle(){
17
14
  const {title,subtitle,isEditing} = this.getAppBarProps();
18
15
  if(title){
@@ -22,13 +19,13 @@ export default class FormDataActionComponent extends FormData {
22
19
  }
23
20
  close (){}
24
21
  getNewElementLabel(){
25
- return defaultStr(this.getMainProps().newElementLabel,this.props.newElementLabel,'Nouveau');
22
+ return defaultStr(this.props.newElementLabel,this.props.newElementLabel,'Nouveau');
26
23
  }
27
24
  getIndexFieldProps(){
28
- return defaultVal(this.getMainProps().indexField,this.props.indexField);
25
+ return defaultVal(this.props.indexField,this.props.indexField);
29
26
  }
30
27
  getAppBarProps(){
31
- const mainProps = this.getMainProps();
28
+ const mainProps = this.props;
32
29
  const data = this.getDataProp();
33
30
  const appBarProps = Object.assign({},mainProps.appBarProps);
34
31
  const isEditing = this.isDocEditing(data);
@@ -57,7 +54,7 @@ export default class FormDataActionComponent extends FormData {
57
54
  }
58
55
  onBackActionPress(args,callback){
59
56
  args = defaultObj(args);
60
- const mainProps = this.getMainProps();
57
+ const mainProps = this.props;
61
58
  const hasP = mainProps !== this.props;
62
59
  const cb = ()=>{
63
60
  if(typeof mainProps.onBackActionPress =='function' && mainProps.onBackActionPress(args) === false) return
@@ -89,7 +86,7 @@ export default class FormDataActionComponent extends FormData {
89
86
  return isNonNullString(indexField) && isNonNullString(data[indexField])? data[indexField] : isNonNullString(data.code)? data.code : undefined;
90
87
  }
91
88
  getAppBarActionsProps(props){
92
- props = defaultObj(props,this.getMainProps(),this.props);
89
+ props = defaultObj(props,this.props);
93
90
  let {actions,save2NewAction,save2printAction,save2closeAction,saveAction,newAction} = props;
94
91
  const sArg = {context:this};
95
92
  save2NewAction = typeof save2NewAction =='function' ? save2NewAction (sArg) : save2NewAction;
@@ -1,10 +1,10 @@
1
1
  import {isNonNullString,defaultObj} from "$utils";
2
- //import dataFileManager from "$database/dataFileManager";
3
2
  import {open as showPreloader,close as hidePreloader} from "$epreloader";
4
3
  import Label from "$ecomponents/Label";
5
4
  import templates from "$ecomponents/Form/Fields/sprintfSelectors";
6
5
  import Tooltip from "$ecomponents/Tooltip";
7
6
  import { Pressable } from "react-native";
7
+ import React from "$react";
8
8
 
9
9
  /***
10
10
  * API The component ReactHashtag is actually pretty generic. Is not something that someone can't do in half an hour. But, this one has some generic API that could make you turn.
@@ -65,7 +65,7 @@ const defaultRenderText = ({text,code,value,dbName,table,hashtag})=>{
65
65
  title +=( (title)? "\n":"") +" Table : [" + table.toUpperCase()+"]";
66
66
  }
67
67
  if(dbName){
68
- title +=( (title)? "\n":"") + dataFileManager.dataFileText +" : ["+dbName+"]";
68
+ //title +=( (title)? "\n":"") + dataFileManager.dataFileText +" : ["+dbName+"]";
69
69
  }
70
70
  return <Tooltip Component={Label} cursorPointer primary style={[{textDecorationLine:'underline'}]} title={title}>
71
71
  {"#"+text}
@@ -171,7 +171,6 @@ const CommonListComponent = React.forwardRef((props,ref)=>{
171
171
  ref = {listRef}
172
172
  onScroll={context.onScroll}
173
173
  data = {context.items}
174
- //key = {isFlatList ? 'common-list-'+numColumns:"normal-list"}
175
174
  numColumns={numColumns}
176
175
  keyExtractor = {context.keyExtractor}
177
176
  renderItem = {context.renderItem}
@@ -2,7 +2,7 @@
2
2
  // Use of this source code is governed by a BSD-style
3
3
  // license that can be found in the LICENSE file.
4
4
 
5
- import { ScrollView,StyleSheet,View,useWindowDimensions} from "react-native";
5
+ import { ScrollView,StyleSheet,View,useWindowDimensions,Dimensions} from "react-native";
6
6
  import React from "$react";
7
7
  import {defaultStr,defaultObj,isObj,isNumber} from "$utils";
8
8
  import Portal from "$ecomponents/Portal";
@@ -49,7 +49,8 @@ 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 visible = x >=win.width ? false : true;
52
+ const {width} = Dimensions.get("window");
53
+ const visible = x >= width-10 ? false : true;
53
54
  if(state.visible != visible){
54
55
  return setState({...state,visible});
55
56
  }
@@ -0,0 +1,24 @@
1
+ // Copyright 2023 @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 React from "react";
5
+ import { View } from "react-native";
6
+ import {defaultObj} from "$utils";
7
+ import Label from "$ecomponents/Label";
8
+
9
+ function TableCellComponent({cellArgs,rowArgs,children,renderCell,rowIndex,style,...rest}){
10
+ const {content,containerProps} = React.useCallback(()=>{
11
+ const rArgs = {...cellArgs,...rowArgs,containerProps : {}};
12
+ const r = typeof renderCell =='function' && renderCell (rArgs) || children;
13
+ return {
14
+ content : typeof r =='string' || typeof r =='number'? <Label children={r}/> : React.isValidElement(r)? r : null,
15
+ containerProps : defaultObj(rArgs.containerProps)
16
+ }
17
+ },[children])();
18
+ return (<View {...containerProps} {...rest} style={[style,containerProps.style]} >
19
+ {content}
20
+ </View>);
21
+ }
22
+ //const TableCellComponent = React.memo(TableCellComponent);;
23
+ export default TableCellComponent;
24
+ TableCellComponent.displayName = "TableCellComponent";
@@ -0,0 +1,25 @@
1
+ // Copyright 2023 @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
+ // Copyright 2023 @fto-consult/Boris Fouomene. All rights reserved.
6
+ // Use of this source code is governed by a BSD-style
7
+ // license that can be found in the LICENSE file.
8
+ import React from "$react";
9
+ import { View } from "react-native";
10
+ import PropTypes from "prop-types";
11
+ export default function TableHeaderComponent({cells,columns,...rest}){
12
+ const children = React.useCallback(()=>{
13
+ if(Array.isArray(cells)){
14
+ return null;
15
+ }
16
+ return cells;
17
+ },[cells,columns])();
18
+ return <View {...rest}>
19
+ {children}
20
+ </View>
21
+ }
22
+
23
+ TableHeaderComponent.propTypes = {
24
+ columns : PropTypes.arrayOf(PropTypes.bool)
25
+ }
@@ -0,0 +1,196 @@
1
+ // Copyright 2023 @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 {Virtuoso} from "react-virtuoso/dist/index.mjs";
6
+ import React from "$react";
7
+ import PropTypes from "prop-types";
8
+ import {defaultObj,defaultNumber,isDOMElement,isNumber,uniqid,isNonNullString,defaultStr} from "$utils";
9
+ import { View } from "react-native";
10
+
11
+ const propTypes = {
12
+ ...defaultObj(Virtuoso.propTypes),
13
+ items : PropTypes.array.isRequired,
14
+ alignToBottom : PropTypes.bool,
15
+ /**Called with true / false when the list has reached the bottom / gets scrolled up. Can be used to load newer items, like tail -f. */
16
+ atBottomStateChange : PropTypes.func,
17
+ /***alias : onEndReachedThreshold */
18
+ atBottomThreshold : PropTypes.number,
19
+ atTopStateChange : PropTypes.func,
20
+ atTopThreshold : PropTypes.number,
21
+ defaultItemHeight : PropTypes.number,
22
+ /***(index: number) => void; Gets called when the user scrolls to the end of the list. Receives the last item index as an argument. Can be used to implement endless scrolling. */
23
+ endReached : PropTypes.func,
24
+ firstItemIndex : PropTypes.number,
25
+ /**(isScrolling: boolean) => void */
26
+ isScrolling : PropTypes.func,
27
+ };
28
+ /***@see : https://virtuoso.dev/virtuoso-api-reference/ */
29
+ const VirtuosoListComponent = React.forwardRef(({items,testID,renderItem,onEndReached,onLayout,onContentSizeChange,onScroll,isScrolling,estimatedItemSize,onEndReachedThreshold,containerProps,style,...props},ref)=>{
30
+ const r2 = {};
31
+ for(let i in propTypes){
32
+ if(i in props){
33
+ r2[i] = props[i];
34
+ }
35
+ }
36
+ containerProps = defaultObj(containerProps);
37
+ testID = defaultStr(testID,containerProps.testID,"RN_VirtuosoListComponent");
38
+ const listIdRef = React.useRef(uniqid("virtuoso-list-id"));
39
+ const listId = listIdRef.current;
40
+ const listRef = React.useRef(null);
41
+ const sizeRef = React.useRef({width:0,height:0});
42
+ const listSize = sizeRef.current;
43
+ const isValid = ()=> listRef.current;
44
+ const listStyle = {height:'100%',width:"100%",overflowX:'hidden'};
45
+ r2["data-test-id"] = testID+"_ListContent";
46
+ if(isObj(estimatedItemSize)){
47
+ if(isNumber(estimatedItemSize.width)){
48
+ listStyle.width = estimatedItemSize.width+"px";
49
+ }
50
+ if(isNumber(estimatedItemSize.height)){
51
+ listStyle.height = estimatedItemSize.height+"px";
52
+ }
53
+ }
54
+ React.setRef(ref,{
55
+ scrollToEnd : ()=>{
56
+ return isValid() && listRef.current.scrollToIndex && listRef.current.scrollToIndex({index:"LAST"});
57
+ },
58
+ scrollToTop : ()=>{
59
+ return isValid() && listRef.current.scrollToIndex && listRef.current.scrollToIndex({index:0});
60
+ },
61
+ scrollToIndex : (opts)=>{
62
+ opts = defaultObj(opts);
63
+ opts.index = defaultNumber(opts.index);
64
+ return isValid() && listRef.current.scrollToIndex && listRef.current.scrollToIndex(opts);
65
+ },
66
+ scrollToItem : ()=>null,
67
+ scrollToOffset : (opts)=>{
68
+ opts = defaultObj(opts);
69
+ opts.top = defaultNumber(opts.top,opts.offset);
70
+ return isValid() && listRef.current.scrollTo && listRef.current.scrollTo(opts);
71
+ },
72
+ scrollToLeft : ()=>{
73
+ return isValid() && listRef.current.scrollTo && listRef.current.scrollTo({left:0});
74
+ },
75
+ });
76
+ const checkSize = ()=>{
77
+ const element = document.getElementById(listId);
78
+ if(!element) return;
79
+ const target = element.firstChild?.firstChild;
80
+ if(isDOMElement(target) && onContentSizeChange){
81
+ const {nativeEvent:{contentSize}} = normalizeEvent({target});
82
+ setTimeout(()=>{
83
+ if(contentSize.width !== listSize.width || contentSize.height != listSize.height){
84
+ sizeRef.current = contentSize;
85
+ onContentSizeChange(contentSize.width,contentSize.height);
86
+ }
87
+ },100)
88
+ }
89
+ }
90
+ React.useEffect(()=>{
91
+ checkSize();
92
+ },[props])
93
+ React.useEffect(()=>{
94
+ return ()=>{
95
+ React.setRef(ref,null);
96
+ }
97
+ },[]);
98
+ return <View {...containerProps} {...props} style={[{flex:1},containerProps.style,style,{minWidth:'100%',maxWidth:'100%'}]} onLayout={onLayout} testID={testID}>
99
+ <Virtuoso
100
+ {...r2}
101
+ style = {listStyle}
102
+ ref = {listRef}
103
+ data = {items}
104
+ id = {listId}
105
+ useWindowScroll = {false}
106
+ totalCount = {items.length}
107
+ itemContent = {(index)=>{
108
+ return renderItem({index,item:items[index],items})
109
+ }}
110
+ atBottomThreshold = {typeof onEndReachedThreshold =='number'? onEndReachedThreshold : undefined}
111
+ atBottomStateChange = {()=>{
112
+ if(typeof onEndReached =='function'){
113
+ onEndReached();
114
+ }
115
+ }}
116
+ onScroll={(e) => onScroll && onScroll(normalizeEvent(e))}
117
+ isScrolling = {(isC,a)=>{
118
+ if(typeof isScrolling =='function'){
119
+ return isScrolling(isC);
120
+ }
121
+ }}
122
+ defaultItemHeight = {typeof estimatedItemSize=='number' && estimatedItemSize || undefined}
123
+ />
124
+ </View>
125
+ });
126
+
127
+ VirtuosoListComponent.propTypes = {
128
+ ...propTypes
129
+ };
130
+
131
+ VirtuosoListComponent.displayName = "VirtuosoListComponent";
132
+
133
+ export default VirtuosoListComponent;
134
+
135
+ function isScrollable (node){
136
+ if(!node) return false;
137
+ const dim = dimensions(node);
138
+ if(!dim) return false;
139
+ if(dim.scrollHeight>dim.clientHeight) return true;
140
+ if(dim.totalHeight > (dim.clientHeight+dim.scrollHeight+100)) return true;
141
+ return false;
142
+ }
143
+ function lookupForContent (node,level){
144
+ if(!node || !isDOMElement(node) || level>=5) return null;
145
+ if(typeof level !='number'){
146
+ level = 0;
147
+ }
148
+ console.log("looking for ",node,level,dimensions(node));
149
+ if(isScrollable(node)){
150
+ return node;
151
+ }
152
+ return lookupForContent(node.querySelector("div:first-child"),level+1)
153
+ }
154
+
155
+ function dimensions(el) {
156
+ if(!isDOMElement(el)) return null;
157
+ var elHeight = el.offsetHeight;
158
+ const marginBottom = parseInt(window.getComputedStyle(el).getPropertyValue('margin-bottom'));
159
+ const paddingBottom = parseInt(window.getComputedStyle(el).getPropertyValue('padding-bottom'));
160
+ return {
161
+ height:elHeight,marginBottom,paddingBottom,totalHeight : elHeight+marginBottom+paddingBottom,
162
+ width : el.offsetWidth,scrollHeight : el.scrollHeight,clientHeight : el.clientHeight,
163
+ }
164
+ }
165
+
166
+ const normalizeEvent = (e)=>{
167
+ return {
168
+ nativeEvent: {
169
+ contentOffset: {
170
+ get x() {
171
+ return e.target.scrollLeft;
172
+ },
173
+ get y() {
174
+ return e.target.scrollTop;
175
+ }
176
+ },
177
+ contentSize: {
178
+ get height() {
179
+ return e.target.scrollHeight;
180
+ },
181
+ get width() {
182
+ return e.target.scrollWidth;
183
+ }
184
+ },
185
+ layoutMeasurement: {
186
+ get height() {
187
+ return e.target.offsetHeight;
188
+ },
189
+ get width() {
190
+ return e.target.offsetWidth;
191
+ }
192
+ }
193
+ },
194
+ timeStamp: Date.now()
195
+ };
196
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright 2023 @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
+ export {default} from "$ecomponents/List/FlashList";
@@ -0,0 +1,21 @@
1
+ // Copyright 2023 @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 React from "$react";
5
+ import { View } from "react-native";
6
+ import PropTypes from "prop-types";
7
+ export default function TableRowComponent({cells,columns,...rest}){
8
+ const children = React.useCallback(()=>{
9
+ if(Array.isArray(cells)){
10
+ return cells.map((cell,index)=>columns[index]? <React.Fragment key={index}>{cell}</React.Fragment> : null )
11
+ }
12
+ return cells;
13
+ },[cells,columns])();
14
+ return <View {...rest}>
15
+ {children}
16
+ </View>
17
+ }
18
+
19
+ TableRowComponent.propTypes = {
20
+ columns : PropTypes.arrayOf(PropTypes.bool)
21
+ }
File without changes