@fto-consult/expo-ui 2.4.7 → 2.5.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 +3 -3
- package/src/components/Datagrid/Accordion/index.js +8 -5
- package/src/components/Datagrid/Common/Common.js +16 -11
- package/src/components/Dialog/confirm/showConfirmOrAlertOrPrompt.js +4 -0
- package/src/components/Fab/Group.js +2 -2
- package/src/components/Fab/GroupComponent.js +4 -3
- package/src/components/Filter/index.js +2 -1
- package/src/components/Table/AbsoluteScrollView.js +63 -0
- package/src/components/Table/index.js +66 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@expo/html-elements": "^0.2.0",
|
|
63
63
|
"@expo/metro-config": "^0.4.0",
|
|
64
64
|
"@expo/webpack-config": "^0.17.2",
|
|
65
|
-
"@fto-consult/common": "^1.
|
|
65
|
+
"@fto-consult/common": "^1.12.2",
|
|
66
66
|
"@gorhom/portal": "^1.0.14",
|
|
67
67
|
"@react-native-async-storage/async-storage": "~1.17.3",
|
|
68
68
|
"@react-native-community/datetimepicker": "6.5.2",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"babel-plugin-inline-dotenv": "^1.7.0",
|
|
74
74
|
"babel-plugin-module-resolver": "^4.1.0",
|
|
75
75
|
"babel-plugin-transform-inline-environment-variables": "^0.4.4",
|
|
76
|
-
"expo": "^47.0.
|
|
76
|
+
"expo": "^47.0.8",
|
|
77
77
|
"expo-camera": "~13.0.0",
|
|
78
78
|
"expo-clipboard": "~4.0.1",
|
|
79
79
|
"expo-image-picker": "~14.0.1",
|
|
@@ -245,9 +245,6 @@ const DatagridFactory = (Factory)=>{
|
|
|
245
245
|
getMaxSelectedRows(){
|
|
246
246
|
return isMobileMedia()? 30 : 50;
|
|
247
247
|
}
|
|
248
|
-
prepareFilter(props,headerFilters){
|
|
249
|
-
return headerFilters.push(props);
|
|
250
|
-
}
|
|
251
248
|
showFilters(){
|
|
252
249
|
if(!this._isMounted()) {
|
|
253
250
|
this.isUpdating = false;
|
|
@@ -299,6 +296,12 @@ const DatagridFactory = (Factory)=>{
|
|
|
299
296
|
</View>
|
|
300
297
|
})
|
|
301
298
|
}
|
|
299
|
+
renderEmpty(){
|
|
300
|
+
if(isObj(this.currentAccordionProps) && typeof this.currentAccordionProps.renderEmpty =='function'){
|
|
301
|
+
return this.currentAccordionProps.renderEmpty();
|
|
302
|
+
}
|
|
303
|
+
return super.renderEmpty();
|
|
304
|
+
}
|
|
302
305
|
render (){
|
|
303
306
|
let {
|
|
304
307
|
filters,
|
|
@@ -332,6 +335,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
332
335
|
if(isObj(accordion)){
|
|
333
336
|
accordionProps = {...accordion,...accordionProps};
|
|
334
337
|
}
|
|
338
|
+
this.currentAccordionProps = accordionProps;
|
|
335
339
|
backToTopRef = defaultVal(backToTopRef,accordionProps.backToTopRef,true);
|
|
336
340
|
|
|
337
341
|
let descOrContentProps = isObj(accordionProps.descriptionProps)? Object.assign({},accordionProps.descriptionProps) : isObj(accordionProps.contentProps)? Object.assign({},accordionProps.contentProps) : {};
|
|
@@ -539,7 +543,6 @@ const DatagridFactory = (Factory)=>{
|
|
|
539
543
|
</View>
|
|
540
544
|
</ScrollView>
|
|
541
545
|
</View>
|
|
542
|
-
renderEmpty = defaultFunc(accordionProps.renderEmpty,renderEmpty,x=>null)
|
|
543
546
|
return <View testID={testID+"_Container"} pointerEvents={pointerEvents} style={[styles.container]} collapsable={false}>
|
|
544
547
|
{ <View testID={testID+"_ContentContainer"} style={[this.bindResizeEvents()?{height:this.renderedListHeight}:undefined]}>
|
|
545
548
|
<View testID={testID+"_AccordionHeader"} style={[styles.accordionHeader]} ref={this.layoutRef} onLayout={this.updateLayout.bind(this)}>
|
|
@@ -591,7 +594,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
591
594
|
}:false}
|
|
592
595
|
keyExtractor = {this.getRowKey.bind(this)}
|
|
593
596
|
/> : <View style={styles.hasNotData}>
|
|
594
|
-
{renderEmpty()}
|
|
597
|
+
{this.renderEmpty()}
|
|
595
598
|
</View>}
|
|
596
599
|
</View>}
|
|
597
600
|
{backToTopRef ? <BackToTop testID={testID+"_BackToTop"} {...backToTopProps} ref={this.backToTopRef} style={[styles.backToTop,backToTopProps.style]} onPress={this.scrollToTop.bind(this)}/>:null}
|
|
@@ -96,6 +96,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
96
96
|
[footerFieldName] : {
|
|
97
97
|
value : uniqid(footerFieldName),override:false, writable: false
|
|
98
98
|
},
|
|
99
|
+
currentFilteringColumns : {value:{}}
|
|
99
100
|
})
|
|
100
101
|
|
|
101
102
|
this.state.sort.dir = defaultStr(this.state.sort.dir,this.state.sort.column == "date"?"desc":'asc')
|
|
@@ -847,13 +848,20 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
847
848
|
});
|
|
848
849
|
}
|
|
849
850
|
prepareFilter(props,filteredColumns){
|
|
850
|
-
|
|
851
|
+
filteredColumns.push(props);
|
|
851
852
|
}
|
|
852
853
|
renderFilter(props){
|
|
853
854
|
return <Filter {...props}/>
|
|
854
855
|
}
|
|
855
856
|
prepareColumn(){}
|
|
856
857
|
beforePrepareColumns(){}
|
|
858
|
+
renderEmpty(){
|
|
859
|
+
if(typeof this.props.renderEmpty =='function'){
|
|
860
|
+
const r = this.props.renderEmpty();
|
|
861
|
+
return React.isValidElement(r)? r : null;
|
|
862
|
+
}
|
|
863
|
+
return null;
|
|
864
|
+
}
|
|
857
865
|
prepareColumns (args){
|
|
858
866
|
this.beforePrepareColumns();
|
|
859
867
|
args = defaultObj(args);
|
|
@@ -958,6 +966,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
958
966
|
operator : fCol.operator,
|
|
959
967
|
action : defaultStr(fCol.originAction,fCol.action),
|
|
960
968
|
};
|
|
969
|
+
this.currentFilteringColumns[header.field] = filterProps;
|
|
961
970
|
this.prepareFilter(filterProps,headerFilters);
|
|
962
971
|
}
|
|
963
972
|
this.prepareColumn({
|
|
@@ -1169,19 +1178,15 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
1169
1178
|
onFilterChange(arg){
|
|
1170
1179
|
this.filteredValues = defaultObj(this.filteredValues);
|
|
1171
1180
|
let {field,operator,originAction,action,value} = defaultObj(arg);
|
|
1172
|
-
const
|
|
1173
|
-
if(
|
|
1181
|
+
const filter = isNonNullString(field)? this.currentFilteringColumns[field] : null;
|
|
1182
|
+
if(!isObj(filter)) return;
|
|
1183
|
+
if(isNonNullString(operator) && isNonNullString(action)){
|
|
1174
1184
|
this.filteredValues[field] = {
|
|
1175
1185
|
operator,action,value,field
|
|
1176
1186
|
}
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
filter.operator = operator;
|
|
1181
|
-
filter.action = defaultStr(originAction,action);
|
|
1182
|
-
}
|
|
1183
|
-
});
|
|
1184
|
-
|
|
1187
|
+
filter.originValue = filter.defaultValue = arg.defaultValue;
|
|
1188
|
+
filter.operator = operator;
|
|
1189
|
+
filter.action = defaultStr(originAction,action);
|
|
1185
1190
|
}
|
|
1186
1191
|
return this.doFilter(arg);
|
|
1187
1192
|
}
|
|
@@ -30,6 +30,7 @@ export default function showConfirm (p,cb){
|
|
|
30
30
|
buttons,
|
|
31
31
|
messageProps,
|
|
32
32
|
inputProps,
|
|
33
|
+
format,
|
|
33
34
|
placeholder,
|
|
34
35
|
children,
|
|
35
36
|
withInputField,
|
|
@@ -116,8 +117,11 @@ export default function showConfirm (p,cb){
|
|
|
116
117
|
{messageContent}
|
|
117
118
|
{withInputField !== false ? <Component
|
|
118
119
|
type = {type}
|
|
120
|
+
enableCopy = {false}
|
|
119
121
|
defaultValue = {defaultValue}
|
|
120
122
|
placeholder = {placeholder}
|
|
123
|
+
affix = {false}
|
|
124
|
+
format = {format}
|
|
121
125
|
{...inputProps}
|
|
122
126
|
ref = {inputRef}
|
|
123
127
|
onChange = {(args)=>{
|
|
@@ -7,7 +7,7 @@ import {MENU_ICON} from "$ecomponents/Icon";
|
|
|
7
7
|
import theme,{Colors} from "$theme";
|
|
8
8
|
import Group from "./GroupComponent";
|
|
9
9
|
import Portal from "$ecomponents/Portal";
|
|
10
|
-
import
|
|
10
|
+
import {isAllowedFromStr} from "$cauth/perms";
|
|
11
11
|
|
|
12
12
|
const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
13
13
|
let {openedIcon,screenName,display:customDisplay,primary,actionMutator,secondary,onOpen,prepareActions,fabStyle,open:customOpen,onClose,onStateChange:customOnStateChange,closedIcon,color,actions:customActions,children,...customRest} = props;
|
|
@@ -63,7 +63,7 @@ const FabGroupComponent = React.forwardRef((props,innerRef)=>{
|
|
|
63
63
|
if(!isObj(a) || !isNonNullString(a.label)) return null;
|
|
64
64
|
const {perm,isAllowed,primary,secondary,...restItem} = a;
|
|
65
65
|
if(typeof isAllowed =='function' && isAllowed() === false) return null;
|
|
66
|
-
if(isNonNullString(perm) && !
|
|
66
|
+
if(isNonNullString(perm) && !isAllowedFromStr(perm)) return false;
|
|
67
67
|
if(primary){
|
|
68
68
|
restItem.style = StyleSheet.flatten([restItem.style,{color:theme.colors.primaryText,backgroundColor:theme.colors.primary}])
|
|
69
69
|
} else if(secondary){
|
|
@@ -11,7 +11,7 @@ import {FAB,Text,Card,withTheme} from "react-native-paper";
|
|
|
11
11
|
import colorFn from 'color';
|
|
12
12
|
import PropTypes from "prop-types";
|
|
13
13
|
import Action from "$ecomponents/Form/Action";
|
|
14
|
-
import theme,{ disabledStyle,StylePropTypes,Colors,cursorNotAllowed } from '$theme';
|
|
14
|
+
import theme,{ disabledStyle,StylePropTypes,cursorPointer,Colors,cursorNotAllowed } from '$theme';
|
|
15
15
|
import {defaultStr} from "$utils";
|
|
16
16
|
|
|
17
17
|
|
|
@@ -279,6 +279,7 @@ const _FabItem = function({children,label,disabled:customDisabled,pointerEvents,
|
|
|
279
279
|
style = StyleSheet.flatten(style) || {};
|
|
280
280
|
color = Colors.isValid(color)? color : style.color;
|
|
281
281
|
backgroundColor = Colors.isValid(backgroundColor)? backgroundColor : style.backgroundColor;
|
|
282
|
+
const cursorStyle = disabled? cursorNotAllowed : cursorPointer;
|
|
282
283
|
const _onPress = ()=>{
|
|
283
284
|
if(onPress){
|
|
284
285
|
onPress();
|
|
@@ -312,7 +313,7 @@ const _FabItem = function({children,label,disabled:customDisabled,pointerEvents,
|
|
|
312
313
|
accessibilityComponentType="button"
|
|
313
314
|
accessibilityRole="button"
|
|
314
315
|
>
|
|
315
|
-
<Text testID={testID+"_Label"} style={{ color}}>
|
|
316
|
+
<Text testID={testID+"_Label"} style={StyleSheet.flatten([{ color},cursorStyle])}>
|
|
316
317
|
{label}
|
|
317
318
|
</Text>
|
|
318
319
|
</Card>
|
|
@@ -328,7 +329,7 @@ const _FabItem = function({children,label,disabled:customDisabled,pointerEvents,
|
|
|
328
329
|
[
|
|
329
330
|
style,
|
|
330
331
|
dStyle,
|
|
331
|
-
|
|
332
|
+
cursorStyle,
|
|
332
333
|
{
|
|
333
334
|
transform: [{ scale}],
|
|
334
335
|
opacity,
|
|
@@ -324,7 +324,8 @@ export default class Filter extends AppComponent {
|
|
|
324
324
|
diff = DateLib.currentMonthDaysLimits(currentDate);
|
|
325
325
|
break;
|
|
326
326
|
case "$week":
|
|
327
|
-
diff = DateLib.currentWeekDaysLimits(currentDate)
|
|
327
|
+
diff = DateLib.currentWeekDaysLimits(currentDate);
|
|
328
|
+
console.log(diff," is diffffff");
|
|
328
329
|
break;
|
|
329
330
|
case "$prevWeek":
|
|
330
331
|
diff = DateLib.previousWeekDaysLimits(currentDate)
|
|
@@ -0,0 +1,63 @@
|
|
|
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 { ScrollView,StyleSheet,View,useWindowDimensions} from "react-native";
|
|
6
|
+
import React from "$react";
|
|
7
|
+
import {defaultStr,defaultObj,isObj} from "$utils";
|
|
8
|
+
import Portal from "$ecomponents/Portal";
|
|
9
|
+
|
|
10
|
+
const AbsoluteScrollView = React.forwardRef(({testID,contentProps,containerProps,...props},ref)=>{
|
|
11
|
+
containerProps = defaultObj(containerProps);
|
|
12
|
+
contentProps = defaultObj(contentProps);
|
|
13
|
+
const win = useWindowDimensions();
|
|
14
|
+
const scrollViewRef = React.useRef(null);
|
|
15
|
+
testID = defaultStr(testID,"RN_TableAbsoluteScrollViewComponent");
|
|
16
|
+
const [styles,setStyles] = React.useState({});
|
|
17
|
+
React.setRef(ref,{
|
|
18
|
+
setStyles : (s)=>{
|
|
19
|
+
if(isObj(s)){
|
|
20
|
+
setStyles({...styles,...s});
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
scrollViewRef
|
|
24
|
+
})
|
|
25
|
+
React.useEffect(()=>{
|
|
26
|
+
return ()=>{
|
|
27
|
+
React.setRef(ref,null);
|
|
28
|
+
}
|
|
29
|
+
},[])
|
|
30
|
+
return <Portal>
|
|
31
|
+
<View testID={testID+"_Containter"} {...containerProps} style={[mainStyles.container,containerProps.style,styles.container,{left:win.width-10}]}>
|
|
32
|
+
<ScrollView
|
|
33
|
+
{...props}
|
|
34
|
+
ref = {scrollViewRef}
|
|
35
|
+
testID={testID}
|
|
36
|
+
contentContainerStyle = {[props.contentContainerStyle,mainStyles.contentContainer,styles.containerContainer]}
|
|
37
|
+
vertical
|
|
38
|
+
>
|
|
39
|
+
<View
|
|
40
|
+
testID={testID+"Content"}
|
|
41
|
+
{...contentProps}
|
|
42
|
+
style={[mainStyles.content,contentProps.style,styles.content]}
|
|
43
|
+
/>
|
|
44
|
+
</ScrollView>
|
|
45
|
+
</View>
|
|
46
|
+
</Portal>
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export default AbsoluteScrollView;
|
|
50
|
+
|
|
51
|
+
const mainStyles = StyleSheet.create({
|
|
52
|
+
container : {
|
|
53
|
+
...StyleSheet.absoluteFill,
|
|
54
|
+
width : 10,
|
|
55
|
+
},
|
|
56
|
+
content : {
|
|
57
|
+
width:10,
|
|
58
|
+
},
|
|
59
|
+
contentContainer : {
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
AbsoluteScrollView.displayName = "TableVerticalScrollView";
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import {FlashList
|
|
1
|
+
import {FlashList} from "$ecomponents/List";
|
|
2
2
|
import View from "$ecomponents/View";
|
|
3
|
-
import {defaultObj,defaultStr,debounce,
|
|
3
|
+
import {defaultObj,defaultStr,debounce,defaultNumber,defaultVal} from "$utils";
|
|
4
4
|
import PropTypes from "prop-types";
|
|
5
5
|
export const DEFAULT_COLUMN_WIDTH = 60;
|
|
6
6
|
import React from "$react";
|
|
7
7
|
import Label from "$ecomponents/Label";
|
|
8
|
-
import { StyleSheet,ScrollView,Dimensions} from "react-native";
|
|
8
|
+
import { StyleSheet,View as RNView,ScrollView,Dimensions} from "react-native";
|
|
9
9
|
import { getRowStyle } from "$ecomponents/Datagrid/utils";
|
|
10
10
|
import {isMobileNative} from "$cplatform";
|
|
11
11
|
import theme from "$theme";
|
|
12
|
+
import AbsoluteScrollView from "./AbsoluteScrollView";
|
|
13
|
+
|
|
12
14
|
const isSCrollingRef = React.createRef();
|
|
13
15
|
const scrollLists = (opts,refs)=>{
|
|
14
16
|
refs.map((ref)=>{
|
|
@@ -18,14 +20,24 @@ const scrollLists = (opts,refs)=>{
|
|
|
18
20
|
});
|
|
19
21
|
isSCrollingRef.current = false;
|
|
20
22
|
}
|
|
21
|
-
const getOnScrollCb = (refs)=>{
|
|
23
|
+
const getOnScrollCb = (refs,pos,cb2)=>{
|
|
22
24
|
const cb = (args)=>{
|
|
23
25
|
if(isSCrollingRef.current) return;
|
|
24
26
|
if(!isObj(args) || !args.nativeEvent) {
|
|
25
27
|
isSCrollingRef.current = false;
|
|
26
28
|
}
|
|
27
29
|
isSCrollingRef.current = true;
|
|
28
|
-
|
|
30
|
+
if(typeof pos =='function'){
|
|
31
|
+
pos(args);
|
|
32
|
+
isSCrollingRef.current = false;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
pos = pos && (pos =='x' || pos=='y')? pos : "x";
|
|
36
|
+
const a = {[pos]:args.nativeEvent.contentOffset?.[pos]};
|
|
37
|
+
scrollLists(a,refs);
|
|
38
|
+
if(typeof cb2 == 'function'){
|
|
39
|
+
cb2(args);
|
|
40
|
+
}
|
|
29
41
|
};
|
|
30
42
|
return isMobileNative()? cb : debounce(cb,200);
|
|
31
43
|
}
|
|
@@ -178,8 +190,10 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
178
190
|
fContent = f.length ? <View testID={testID+"_Footer"} {...footerContainerProps} style={[styles.header,styles.footers,footerContainerProps.style]}>
|
|
179
191
|
{f}
|
|
180
192
|
</View> : null;
|
|
193
|
+
const absoluteScrollViewRefCanScroll = React.useRef(true);
|
|
181
194
|
React.setRef(tableRef,context);
|
|
182
195
|
const cStyle = {width:listWidth}
|
|
196
|
+
const absoluteScrollViewRef = React.useRef(null);
|
|
183
197
|
return <View testID= {testID+"_Container"} {...containerProps} style={[styles.container,{alignItems:'stretch'},containerProps.style]}>
|
|
184
198
|
<View autoHeight style={[cStyle]} testID={testID+"_Headers_ScrollViewContainer"}>
|
|
185
199
|
<ScrollView
|
|
@@ -194,12 +208,36 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
194
208
|
{hContent}
|
|
195
209
|
</ScrollView>
|
|
196
210
|
</View>
|
|
197
|
-
<ScrollView {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle]} showsVerticalScrollIndicator={false}
|
|
211
|
+
<ScrollView {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle]} showsVerticalScrollIndicator={false}
|
|
212
|
+
onScroll = {getOnScrollCb([headerScrollViewRef,footerScrollViewRef],null,(args)=>{
|
|
213
|
+
})} ref={scrollViewRef} testID={testID+"_ScrollView"}>
|
|
198
214
|
<FlashList
|
|
199
215
|
containerProps = {{style:[cStyle]}}
|
|
200
216
|
//prepareItems = {Array.isArray(items)? false : undefined}
|
|
201
217
|
estimatedItemSize = {200}
|
|
202
218
|
{...props}
|
|
219
|
+
onContentSizeChange = {(width,height)=>{
|
|
220
|
+
if(props.onContentSizeChange){
|
|
221
|
+
props.onContentSizeChange(width,height);
|
|
222
|
+
}
|
|
223
|
+
if(!absoluteScrollViewRef.current) return;
|
|
224
|
+
absoluteScrollViewRef.current.setStyles({
|
|
225
|
+
content : {height}
|
|
226
|
+
});
|
|
227
|
+
}}
|
|
228
|
+
onLayout = {(args)=>{
|
|
229
|
+
if(props.onLayout){
|
|
230
|
+
props.onLayout(args);
|
|
231
|
+
}
|
|
232
|
+
if(!absoluteScrollViewRef.current) return;
|
|
233
|
+
const {nativeEvent:{layout}}=args;
|
|
234
|
+
const top = defaultNumber(layout.top,layout.y);
|
|
235
|
+
const height = layout.height;
|
|
236
|
+
absoluteScrollViewRef.current.setStyles({
|
|
237
|
+
container : {top,height},
|
|
238
|
+
contentContainer : {height},
|
|
239
|
+
});
|
|
240
|
+
}}
|
|
203
241
|
ref = {listRef}
|
|
204
242
|
numberOfLines = {1}
|
|
205
243
|
responsive = {false}
|
|
@@ -209,6 +247,17 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
209
247
|
style = {[styles.datagrid,{width:listWidth,minWidth:totalWidths}]}
|
|
210
248
|
keyExtractor = {typeof getRowKey =='function'? getRowKey : React.getKey}
|
|
211
249
|
//stickyHeaderIndices={[0]}
|
|
250
|
+
onScroll = {getOnScrollCb([absoluteScrollViewRef],(args)=>{
|
|
251
|
+
const offset = args?.nativeEvent?.contentOffset.y;
|
|
252
|
+
const scrollViewRef = absoluteScrollViewRef.current?.scrollViewRef;
|
|
253
|
+
if(typeof offset =='number' && scrollViewRef.current && scrollViewRef.current.scrollTo){
|
|
254
|
+
absoluteScrollViewRefCanScroll.current = false;
|
|
255
|
+
scrollViewRef.current.scrollTo({animated:false,y:offset});
|
|
256
|
+
setTimeout(()=>{
|
|
257
|
+
absoluteScrollViewRefCanScroll.current = true;
|
|
258
|
+
},500);
|
|
259
|
+
}
|
|
260
|
+
})}
|
|
212
261
|
renderItem = {(arg)=>{
|
|
213
262
|
const item = arg.item, data = arg.item,allData=Array.isArray(item.items)? item.items : data;
|
|
214
263
|
const cells = visibleColumns.map((i,index)=>{
|
|
@@ -237,11 +286,21 @@ const TableComponent = React.forwardRef(({containerProps,isRowSelected,headerScr
|
|
|
237
286
|
</View>;
|
|
238
287
|
}}
|
|
239
288
|
/>
|
|
289
|
+
<AbsoluteScrollView
|
|
290
|
+
ref={absoluteScrollViewRef}
|
|
291
|
+
scrollEventThrottle = {scrollEventThrottle}
|
|
292
|
+
onScroll = {(args)=>{
|
|
293
|
+
if(!absoluteScrollViewRefCanScroll.current) return;
|
|
294
|
+
const offset = args?.nativeEvent?.contentOffset.y;
|
|
295
|
+
if(typeof offset =='number' && listRef.current && listRef.current.scrollToOffset){
|
|
296
|
+
listRef.current.scrollToOffset({animated:true,offset});
|
|
297
|
+
}
|
|
298
|
+
}}
|
|
299
|
+
/>
|
|
240
300
|
</ScrollView>
|
|
241
301
|
</View>
|
|
242
302
|
});
|
|
243
303
|
|
|
244
|
-
|
|
245
304
|
const ColumnType = PropTypes.shape({
|
|
246
305
|
field : PropTypes.string,
|
|
247
306
|
label : PropTypes.text,
|
|
@@ -364,19 +423,6 @@ TableComponent.popTypes = {
|
|
|
364
423
|
footerScrollViewProps : PropTypes.object,
|
|
365
424
|
}
|
|
366
425
|
|
|
367
|
-
const ScrollViewCustom = React.forwardRef((props,ref)=>{
|
|
368
|
-
const {testID,onScroll,style,handle} = props;
|
|
369
|
-
const context = {};
|
|
370
|
-
React.setRef(ref,context);
|
|
371
|
-
return <View
|
|
372
|
-
{...props}
|
|
373
|
-
ref = {ref}
|
|
374
|
-
style = {[styles.scrollViewCustom,style,{backgroundColor:theme.colors.primary}]}
|
|
375
|
-
onScroll={onScroll}
|
|
376
|
-
testID={(testID||'RN_TableComponentScrollViewCustom')}
|
|
377
|
-
/>
|
|
378
|
-
});
|
|
379
|
-
ScrollViewCustom.displayName = "TableComponentScrollViewCustom";
|
|
380
426
|
|
|
381
427
|
TableComponent.displayName = "TableComponent";
|
|
382
428
|
|