@fto-consult/expo-ui 6.25.0 → 6.25.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 +3 -3
- package/readChart.txt +4 -1
- package/src/components/Datagrid/Common/Common.js +11 -6
- package/src/components/Datagrid/utils.js +2 -1
- package/src/components/Label/index.js +8 -4
- package/src/components/List/Virtuoso/index.js +40 -3
- package/src/components/Table/Header/index.js +25 -3
- package/src/components/Table/Row/Cell/Content.js +2 -3
- package/src/components/Table/Row/Cell/Content.native.js +1 -1
- package/src/components/Table/Row/Cell/index.js +6 -5
- package/src/components/Table/Row/RowWrapper.native.js +3 -2
- package/src/components/Table/Row/index.js +1 -1
- package/src/components/Table/hooks.js +2 -2
- package/src/components/Table/index.js +15 -14
- package/src/components/Table/styles.js +17 -1
- package/src/context/Provider.js +16 -2
- package/src/components/Table/FiltersOrFooters.js +0 -26
- package/src/components/Table/Header/Component.js +0 -21
- package/src/components/Table/Header/Component.native.js +0 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fto-consult/expo-ui",
|
|
3
|
-
"version": "6.25.
|
|
3
|
+
"version": "6.25.1",
|
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"@emotion/react": "^11.11.1",
|
|
68
68
|
"@expo/html-elements": "^0.5.1",
|
|
69
69
|
"@expo/vector-icons": "^13.0.0",
|
|
70
|
-
"@fto-consult/common": "^3.
|
|
70
|
+
"@fto-consult/common": "^3.28.1",
|
|
71
71
|
"@gorhom/portal": "^1.0.14",
|
|
72
72
|
"@pchmn/expo-material3-theme": "^1.3.1",
|
|
73
73
|
"@react-native-async-storage/async-storage": "1.18.2",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"react-native-iphone-x-helper": "^1.3.1",
|
|
105
105
|
"react-native-mime-types": "^2.4.0",
|
|
106
106
|
"react-native-paper": "^5.10.1",
|
|
107
|
-
"react-native-paper-dates": "^0.18.
|
|
107
|
+
"react-native-paper-dates": "^0.18.14",
|
|
108
108
|
"react-native-reanimated": "~3.3.0",
|
|
109
109
|
"react-native-safe-area-context": "4.6.3",
|
|
110
110
|
"react-native-screens": "~3.22.0",
|
package/readChart.txt
CHANGED
|
@@ -5,4 +5,7 @@
|
|
|
5
5
|
Les valeurs pouvant appartenir au séries groupées des charts peuvent être uniquement les valeurs calculées du footer,
|
|
6
6
|
lorsque les colonnes sont grouépes
|
|
7
7
|
|
|
8
|
-
Configure git credentialHelper http : credential.useHttpPath true, @see : https://microsoft.github.io/Git-Credential-Manager-for-Windows/Docs/Configuration.html#:~:text=useHttpPath,changes%20the%20behavior%20of%20Git.
|
|
8
|
+
Configure git credentialHelper http : credential.useHttpPath true, @see : https://microsoft.github.io/Git-Credential-Manager-for-Windows/Docs/Configuration.html#:~:text=useHttpPath,changes%20the%20behavior%20of%20Git.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
il est possible d'ajouter les propriétés css valide en environnemnet web, dans le theme, en utilisant la props customCSS de type fonction ou chaine de caractère
|
|
@@ -956,11 +956,16 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
956
956
|
if(typeof this.props.onSort =='function' && this.props.onSort({context:this,sort,data:this.INITIAL_STATE.data,fields:this.state.columns,columns:this.state.columns}) === false){
|
|
957
957
|
return;
|
|
958
958
|
}
|
|
959
|
-
|
|
959
|
+
const call = ()=>{
|
|
960
960
|
this.prepareData({data:this.INITIAL_STATE.data,updateFooters:false},(state)=>{
|
|
961
961
|
this.setState(state);
|
|
962
962
|
});
|
|
963
|
-
}
|
|
963
|
+
};
|
|
964
|
+
const max = isMobileOrTabletMedia()? 1000 : 5000;
|
|
965
|
+
if(this.INITIAL_STATE.data.length > max){
|
|
966
|
+
return this.setIsLoading(true,call,true);
|
|
967
|
+
}
|
|
968
|
+
return call();
|
|
964
969
|
}
|
|
965
970
|
|
|
966
971
|
/**** pagine l'objet data passé en parmètre de manière a retourner un objet satisfaisant aux paramètres
|
|
@@ -3631,7 +3636,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3631
3636
|
toggleAll
|
|
3632
3637
|
key = {this.getSelectableColumName()}
|
|
3633
3638
|
secondaryOnCheck
|
|
3634
|
-
style = {style}
|
|
3639
|
+
style = {[style]}
|
|
3635
3640
|
onPress = {({checked})=>{
|
|
3636
3641
|
this.handleAllRowsToggle(!checked);
|
|
3637
3642
|
return;
|
|
@@ -3647,7 +3652,7 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3647
3652
|
this.sort(columnField);
|
|
3648
3653
|
};
|
|
3649
3654
|
return <TouchableRipple disabled={!sortable} style={styles.sortableColumn} onPress={sortMe}>
|
|
3650
|
-
|
|
3655
|
+
<View testID={"RN_DatagridHeaderCellContainer_"+columnField} style={[tableStyles.cell,theme.styles.row,theme.styles.flex1,theme.styles.justifyContentFlexStart,theme.styles.alignItemsCenter]}>
|
|
3651
3656
|
{isColumnSorted ? <Icon
|
|
3652
3657
|
{...sortedColumn}
|
|
3653
3658
|
size = {24}
|
|
@@ -3656,8 +3661,8 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
3656
3661
|
onPress = {sortMe}
|
|
3657
3662
|
primary
|
|
3658
3663
|
/>: null}
|
|
3659
|
-
<Label textBold style={[{fontSize:13}]} primary={isColumnSorted}>{ret}</Label>
|
|
3660
|
-
|
|
3664
|
+
<Label testID={"RN_DatagridHeaderCellLabel_"+columnField} textBold style={[{fontSize:13}]} primary={isColumnSorted}>{ret}</Label>
|
|
3665
|
+
</View>
|
|
3661
3666
|
</TouchableRipple>
|
|
3662
3667
|
}
|
|
3663
3668
|
canScrollTo(){
|
|
@@ -42,6 +42,7 @@ const LabelComponent = React.forwardRef(({ children,role,color,upperCase,fontSiz
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
style = Object.assign({},StyleSheet.flatten(style));
|
|
45
|
+
let hasP = Object.size(style,true);
|
|
45
46
|
testID = defaultStr(testID,"RN_LabelComponent");
|
|
46
47
|
const restProps = {id};
|
|
47
48
|
if(splitText){
|
|
@@ -54,6 +55,9 @@ const LabelComponent = React.forwardRef(({ children,role,color,upperCase,fontSiz
|
|
|
54
55
|
if(wrap){
|
|
55
56
|
r1.flexWrap = "wrap";
|
|
56
57
|
}
|
|
58
|
+
if(disabled){
|
|
59
|
+
r1.pointerEvents = "none";
|
|
60
|
+
}
|
|
57
61
|
if(isNonNullString(children) || isText || typeof children ==='number'){
|
|
58
62
|
if(!isText){
|
|
59
63
|
children +="";
|
|
@@ -69,7 +73,6 @@ const LabelComponent = React.forwardRef(({ children,role,color,upperCase,fontSiz
|
|
|
69
73
|
role={typeof role =='string' && role && supportedRoles.includes(role.trim()) && role.trim() || undefined}
|
|
70
74
|
style={[styles.label,splitText?styles.wrap:null,splitText?styles.w100:null,bold?styles.bold:null,r2,style,r1,styles.webFontFamilly]}>{children}</Text>)
|
|
71
75
|
}
|
|
72
|
-
let hasP = false;
|
|
73
76
|
if(isObj(rest)){
|
|
74
77
|
for(let i in rest){
|
|
75
78
|
if(rest[i]!== undefined) {
|
|
@@ -81,14 +84,15 @@ const LabelComponent = React.forwardRef(({ children,role,color,upperCase,fontSiz
|
|
|
81
84
|
if(children == undefined){
|
|
82
85
|
return null;
|
|
83
86
|
}
|
|
87
|
+
const viewStyle = [bold?styles.bold:null,r2,style,r1];
|
|
84
88
|
if(React.isValidElement(children)){
|
|
85
89
|
if(!hasP) {
|
|
86
90
|
if(id || ref){
|
|
87
|
-
return <View ref = {ref} testID = {testID} id={id}>{children}</View>
|
|
91
|
+
return <View ref = {ref} testID = {testID} id={id} style={viewStyle}>{children}</View>
|
|
88
92
|
}
|
|
89
|
-
return
|
|
93
|
+
return children;
|
|
90
94
|
}
|
|
91
|
-
return <View ref = {ref} selectable={defaultSelectable} {...rest} {...restProps} testID = {testID} style={
|
|
95
|
+
return <View ref = {ref} selectable={defaultSelectable} {...rest} {...restProps} testID = {testID} style={viewStyle} disabled={disabled}>{children}</View>
|
|
92
96
|
}
|
|
93
97
|
return null;
|
|
94
98
|
})
|
|
@@ -12,6 +12,7 @@ import theme,{grid} from "$theme";
|
|
|
12
12
|
import Dimensions from "$cdimensions";
|
|
13
13
|
import { StyleSheet } from "react-native";
|
|
14
14
|
import {isMobileNative} from "$cplatform";
|
|
15
|
+
import {addClassName,removeClassName} from "$cutils/dom";
|
|
15
16
|
|
|
16
17
|
const propTypes = {
|
|
17
18
|
...defaultObj(Virtuoso.propTypes),
|
|
@@ -31,7 +32,7 @@ const propTypes = {
|
|
|
31
32
|
isScrolling : PropTypes.func,
|
|
32
33
|
};
|
|
33
34
|
/***@see : https://virtuoso.dev/virtuoso-api-reference/ */
|
|
34
|
-
const VirtuosoListComponent = React.forwardRef(({onRender,fixedHeaderContent,rowProps,renderTable,listClassName,components,itemProps,windowWidth,numColumns,responsive,testID,renderItem,onEndReached,onLayout,onContentSizeChange,onScroll,isScrolling,estimatedItemSize,onEndReachedThreshold,containerProps,style,autoSizedStyle,...props},ref)=>{
|
|
35
|
+
const VirtuosoListComponent = React.forwardRef(({onRender,id,fixedHeaderContent,rowProps,renderTable,listClassName,components,itemProps,windowWidth,numColumns,responsive,testID,renderItem,onEndReached,onLayout,onContentSizeChange,onScroll,isScrolling,estimatedItemSize,onEndReachedThreshold,containerProps,style,autoSizedStyle,...props},ref)=>{
|
|
35
36
|
if(renderTable){
|
|
36
37
|
responsive = false;
|
|
37
38
|
}
|
|
@@ -50,6 +51,10 @@ const VirtuosoListComponent = React.forwardRef(({onRender,fixedHeaderContent,row
|
|
|
50
51
|
}
|
|
51
52
|
});
|
|
52
53
|
containerProps = defaultObj(containerProps);
|
|
54
|
+
const idRef = React.useRef(defaultStr(id,uniqid("virtuoso-list-id")));
|
|
55
|
+
id = idRef.current;
|
|
56
|
+
const containerId = `${id}-container`;
|
|
57
|
+
const headId = `${id}-table-head`;
|
|
53
58
|
testID = defaultStr(testID,containerProps.testID,"RN_VirtuosoListComponent");
|
|
54
59
|
const listIdRef = React.useRef(uniqid("virtuoso-list-id"));
|
|
55
60
|
const listId = listIdRef.current;
|
|
@@ -58,6 +63,9 @@ const VirtuosoListComponent = React.forwardRef(({onRender,fixedHeaderContent,row
|
|
|
58
63
|
const listSize = sizeRef.current;
|
|
59
64
|
const isValid = ()=> listRef.current;
|
|
60
65
|
const listStyle = {height:'100%',width:"100%",overflowX:renderTable?"auto":"hidden",maxWidth:"100%"};
|
|
66
|
+
if(renderTable){
|
|
67
|
+
listStyle.borderCollapse ="collapse";
|
|
68
|
+
}
|
|
61
69
|
r2["data-test-id"] = testID+"_ListContent";
|
|
62
70
|
if(isObj(estimatedItemSize)){
|
|
63
71
|
if(isNumber(estimatedItemSize.width)){
|
|
@@ -104,12 +112,34 @@ const VirtuosoListComponent = React.forwardRef(({onRender,fixedHeaderContent,row
|
|
|
104
112
|
},100)
|
|
105
113
|
}
|
|
106
114
|
}
|
|
115
|
+
const scrolledTopRef = React.useRef(0);
|
|
116
|
+
const updateTableHeadCss = ()=>{
|
|
117
|
+
const newScrollTop = scrolledTopRef.current;
|
|
118
|
+
const head = document.querySelector(`#${headId}`);
|
|
119
|
+
if(!head || typeof newScrollTop !='number') return;
|
|
120
|
+
const scrolled = newScrollTop > 50
|
|
121
|
+
head.style.background = !scrolled ? "transparent":theme.isDark()? theme.Colors.lighten(theme.surfaceBackgroundColor):theme.Colors.darken(theme.surfaceBackgroundColor);
|
|
122
|
+
head.style.border = !scrolled ? "none" : `1px solid ${theme.colors.divider}`
|
|
123
|
+
}
|
|
107
124
|
React.useEffect(()=>{
|
|
125
|
+
const handleScroll = (e)=>{
|
|
126
|
+
if(!isDOMElement(e?.target)) return;
|
|
127
|
+
const target = e?.target;
|
|
128
|
+
const container = document.querySelector(`#${containerId}`);
|
|
129
|
+
if(!container) return;
|
|
130
|
+
if(container !== target && !container.contains(target)) return;
|
|
131
|
+
if(!target.hasAttribute("data-virtuoso-scroller")) return;
|
|
132
|
+
scrolledTopRef.current = typeof target?.scrollTop =="number"? target.scrollTop : undefined;
|
|
133
|
+
updateTableHeadCss();
|
|
134
|
+
}
|
|
135
|
+
window.addEventListener('scroll', handleScroll,true);
|
|
108
136
|
return ()=>{
|
|
109
137
|
React.setRef(ref,null);
|
|
138
|
+
window.removeEventListener('scroll', handleScroll,true);
|
|
110
139
|
}
|
|
111
140
|
},[]);
|
|
112
141
|
React.useOnRender((a,b,c)=>{
|
|
142
|
+
updateTableHeadCss();
|
|
113
143
|
if(onRender && onRender(a,b,c));
|
|
114
144
|
},Math.max(Array.isArray(items) && items.length/10 || 0,500));
|
|
115
145
|
const listP = responsive ? {
|
|
@@ -121,7 +151,7 @@ const VirtuosoListComponent = React.forwardRef(({onRender,fixedHeaderContent,row
|
|
|
121
151
|
},
|
|
122
152
|
defaultItemHeight : typeof estimatedItemSize=='number' && estimatedItemSize || undefined,
|
|
123
153
|
};
|
|
124
|
-
return <View {...containerProps} {...props} style={[{flex:1},containerProps.style,style,autoSizedStyle,{minWidth:'100%',height:'100%',maxWidth:'100%'}]} onLayout={onLayout} testID={testID}>
|
|
154
|
+
return <View {...containerProps} {...props} id={containerId} className={classNames("virtuoso-list-container",renderTable&& "virtuoso-list-container-render-table")} style={[{flex:1},containerProps.style,style,autoSizedStyle,{minWidth:'100%',height:'100%',maxWidth:'100%'}]} onLayout={onLayout} testID={testID}>
|
|
125
155
|
<Component
|
|
126
156
|
{...r2}
|
|
127
157
|
{...listP}
|
|
@@ -140,10 +170,11 @@ const VirtuosoListComponent = React.forwardRef(({onRender,fixedHeaderContent,row
|
|
|
140
170
|
}
|
|
141
171
|
}}
|
|
142
172
|
onScroll={(e) => onScroll && onScroll(normalizeEvent(e))}
|
|
143
|
-
isScrolling = {(isC,
|
|
173
|
+
isScrolling = {(isC,)=>{
|
|
144
174
|
if(typeof isScrolling =='function'){
|
|
145
175
|
return isScrolling(isC);
|
|
146
176
|
}
|
|
177
|
+
if(!renderTable) return;
|
|
147
178
|
}}
|
|
148
179
|
components = {{
|
|
149
180
|
Item : renderTable ? undefined : responsive ? function(props){return <ItemContainer {...props} style={[itemProps.style,props.style]} numColumns={numColumns}/>} : undefined,
|
|
@@ -151,6 +182,12 @@ const VirtuosoListComponent = React.forwardRef(({onRender,fixedHeaderContent,row
|
|
|
151
182
|
TableRow: TableRowComponent,
|
|
152
183
|
}:{}),
|
|
153
184
|
...defaultObj(components),
|
|
185
|
+
...(renderTable ? {
|
|
186
|
+
TableHead : React.forwardRef((props,ref)=>{
|
|
187
|
+
const restProps = {id:headId,className:classNames(props.className,"virtuoso-list-render-table-thead")};
|
|
188
|
+
return <thead ref={ref} {...props} {...restProps}/>
|
|
189
|
+
})
|
|
190
|
+
} : {})
|
|
154
191
|
}}
|
|
155
192
|
/>
|
|
156
193
|
</View>
|
|
@@ -3,10 +3,32 @@
|
|
|
3
3
|
// license that can be found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import Cell from "./Cell";
|
|
6
|
-
import
|
|
6
|
+
import React from "$react";
|
|
7
|
+
import { View } from "react-native";
|
|
8
|
+
import PropTypes from "prop-types";
|
|
9
|
+
import { StyleSheet } from "react-native";
|
|
10
|
+
import {isMobileNative} from "$cplatform";
|
|
11
|
+
import {classNames} from "$cutils";
|
|
12
|
+
const isNative = isMobileNative();
|
|
13
|
+
const Component = isNative ? View : "tr";
|
|
14
|
+
import theme from "$theme";
|
|
15
|
+
|
|
16
|
+
export default function RowHeaderComponent({visible,className,children:cChildren,...rest}){
|
|
17
|
+
const children = React.useMemo(()=>{
|
|
18
|
+
return cChildren;
|
|
19
|
+
},[cChildren]);
|
|
20
|
+
const rP = isNative ? rest : {className:classNames(className,"table-footer-or-header-row")}
|
|
21
|
+
if(!isNative && !visible) return null;
|
|
22
|
+
//const backgroundColor = theme.isDark()? theme.Colors.lighten(theme.surfaceBackgroundColor):theme.Colors.darken(theme.surfaceBackgroundColor);
|
|
23
|
+
return <Component {...rP} style={StyleSheet.flatten([rest.style,!visible && {height:0,opacity:0,display:'none'}])}>
|
|
24
|
+
{children}
|
|
25
|
+
</Component>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
RowHeaderComponent.propTypes = {
|
|
29
|
+
visible : PropTypes.bool,
|
|
30
|
+
}
|
|
7
31
|
|
|
8
32
|
export {Cell};
|
|
9
33
|
|
|
10
34
|
RowHeaderComponent.Cell = Cell;
|
|
11
|
-
|
|
12
|
-
export default RowHeaderComponent;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import {classNames} from "$cutils";
|
|
6
6
|
import { StyleSheet } from "react-native";
|
|
7
|
-
import
|
|
7
|
+
import Label from "$ecomponents/Label";
|
|
8
8
|
|
|
9
9
|
function TableCellContentComponent({children,style,...rest}){
|
|
10
10
|
return (<td {...rest} className={classNames(rest.className,"table-row-cell")} style={StyleSheet.flatten([style])}>
|
|
@@ -13,5 +13,4 @@ function TableCellContentComponent({children,style,...rest}){
|
|
|
13
13
|
}
|
|
14
14
|
//const TableCellContentComponent = React.memo(TableCellContentComponent);;
|
|
15
15
|
export default TableCellContentComponent;
|
|
16
|
-
TableCellContentComponent.displayName = "TableCellContentComponent";
|
|
17
|
-
const styles = {paddingLeft:"10px",paddingTop:"5px",paddingBottom:"5px",paddingRight:"10px"};
|
|
16
|
+
TableCellContentComponent.displayName = "TableCellContentComponent";
|
|
@@ -6,7 +6,7 @@ import View from "$ecomponents/View";
|
|
|
6
6
|
import { StyleSheet } from "react-native";
|
|
7
7
|
|
|
8
8
|
function TableCellContentComponent({children,style,colSpan,...rest}){
|
|
9
|
-
return (<View testID={"RN_TableRowCellContentComponent"} {...rest} style={
|
|
9
|
+
return (<View testID={"RN_TableRowCellContentComponent"} {...rest} style={style}>
|
|
10
10
|
{children}
|
|
11
11
|
</View>);
|
|
12
12
|
}
|
|
@@ -3,23 +3,24 @@ import CellContent from "./Content";
|
|
|
3
3
|
import { useTable } from "../../hooks";
|
|
4
4
|
import {defaultObj} from "$cutils";
|
|
5
5
|
import Label from "$ecomponents/Label";
|
|
6
|
-
|
|
6
|
+
import styles from "../../styles";
|
|
7
|
+
const TableRowCellComponent = React.forwardRef(({children,columnDef,rowData,colSpan,isSectionListHeader,rowIndex,style,...rest},ref)=>{
|
|
7
8
|
if(isSectionListHeader){
|
|
8
|
-
return <CellContent colSpan={colSpan} ref={ref} style={[style]} >
|
|
9
|
+
return <CellContent colSpan={colSpan} ref={ref} style={[styles.sectionListHeader,style]} >
|
|
9
10
|
{children}
|
|
10
11
|
</CellContent>
|
|
11
12
|
}
|
|
12
13
|
const {renderCell} = useTable();
|
|
13
14
|
const {content,containerProps} = React.useMemo(()=>{
|
|
14
|
-
const rArgs = {...rest,rowData,rowIndex,containerProps : {}};
|
|
15
|
+
const rArgs = {...rest,columnDef,rowData,rowIndex,containerProps : {}};
|
|
15
16
|
const r = typeof renderCell =='function' && renderCell (rArgs) || children;
|
|
16
17
|
return {
|
|
17
|
-
content :
|
|
18
|
+
content : r && React.isValidElement(r,true)? r : children,
|
|
18
19
|
containerProps : defaultObj(rArgs.containerProps)
|
|
19
20
|
}
|
|
20
21
|
},[children]);
|
|
21
22
|
return (<CellContent ref={ref} {...containerProps} style={[style,containerProps.style]} >
|
|
22
|
-
{content}
|
|
23
|
+
{columnDef.isSelectableColumnName ? content : <Label testID="RN_TableRowCell" style={[styles.cell]}>{content}</Label>}
|
|
23
24
|
</CellContent>);
|
|
24
25
|
});
|
|
25
26
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { forwardRef } from "react";
|
|
2
|
-
import View from "$ecomponents/View"
|
|
2
|
+
import View from "$ecomponents/View";
|
|
3
|
+
import styles from "../styles";
|
|
3
4
|
|
|
4
5
|
const TableRowWrapperComponent = forwardRef(({children,colSpan,...props},ref)=>{
|
|
5
|
-
return <View ref={ref} {...props} children={children}/>
|
|
6
|
+
return <View ref={ref} {...props} style={[styles.row,props.style]} children={children}/>
|
|
6
7
|
});
|
|
7
8
|
|
|
8
9
|
TableRowWrapperComponent.displayName = "TableRowWrapperComponent";
|
|
@@ -21,7 +21,7 @@ export default function TableRowComponent({cells,rowKey,rowData,index,...rest}){
|
|
|
21
21
|
return visibleColsNames.map((columnField,cIndex)=>{
|
|
22
22
|
const columnDef = columns[columnField];
|
|
23
23
|
if(!isObj(columnDef)) return null;
|
|
24
|
-
return <Cell rowData={rowData} rowKey={rowKey} children={
|
|
24
|
+
return <Cell rowData={rowData} rowKey={rowKey} children={rowData[columnField]} rowIndex={index} columnDef={columnDef} index={cIndex} key={columnField} columnField={columnField}/>
|
|
25
25
|
});
|
|
26
26
|
},[rowKey,index,JSON.stringify(visibleColsNames)]);
|
|
27
27
|
return <RowWrapper style={[styles.row]}>
|
|
@@ -34,11 +34,11 @@ export const usePrepareColumns = ({columns,sortedColumn,forceRender,testID,rende
|
|
|
34
34
|
}
|
|
35
35
|
const rArgs = {columnDef,width};
|
|
36
36
|
headers[columnField] = <HeaderCell {...rArgs} testID={testID+"_HeaderCell_"+columnField} {...headerCellContainerProps} {...hContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,headerCellContainerProps.style,hContainerProps.style,style]}>
|
|
37
|
-
<Label splitText numberOfLines={
|
|
37
|
+
<Label splitText numberOfLines={1} style={[theme.styles.w100,theme.styles.h100,{maxHeight:70},width&&{width}]} textBold primary>{content}</Label>
|
|
38
38
|
</HeaderCell>;
|
|
39
39
|
if(typeof renderFilterCell =='function'){
|
|
40
40
|
const filterCell = renderFilterCell(colArgs);
|
|
41
|
-
filters[columnField] = <HeaderCell {...rArgs} testID={testID+"_Filter_Cell_"+columnField} {...filterCellContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,styles.filterCell,filterCellContainerProps.style,style]}>
|
|
41
|
+
filters[columnField] = <HeaderCell {...rArgs} testID={testID+"_Filter_Cell_"+columnField} {...filterCellContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,styles.filterCell,filterCellContainerProps.style,styles.cell,style]}>
|
|
42
42
|
{React.isValidElement(filterCell)? filterCell : null}
|
|
43
43
|
</HeaderCell>
|
|
44
44
|
}
|
|
@@ -8,13 +8,13 @@ import theme from "$theme";
|
|
|
8
8
|
import AbsoluteScrollView from "./AbsoluteScrollView";
|
|
9
9
|
import Row from "./Row";
|
|
10
10
|
import List,{TableRowComponent} from "./List";
|
|
11
|
-
import
|
|
11
|
+
import Header from "./Header";
|
|
12
12
|
import { usePrepareColumns,TableContext,useTable} from "./hooks";
|
|
13
13
|
import styles from "./styles";
|
|
14
14
|
import {useIsRowSelected} from "$ecomponents/Datagrid/hooks";
|
|
15
15
|
import {getRowStyle} from "$ecomponents/Datagrid/utils";
|
|
16
16
|
import ScrollNative from "./ScrollNative";
|
|
17
|
-
import
|
|
17
|
+
import VirtuosoTableComponent from "./VirtuosoTable";
|
|
18
18
|
export {styles};
|
|
19
19
|
|
|
20
20
|
const isSCrollingRef = React.createRef();
|
|
@@ -62,9 +62,12 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
|
|
|
62
62
|
const {columns:cols,testID,headers,footers,getItem,withDatagridContext,filters,getRowByIndex,itemsChanged,hasFooters:stateHasFooters,visibleColsNames,keyExtractor,items,data} = useTable();
|
|
63
63
|
headerContainerProps = defaultObj(headerContainerProps);
|
|
64
64
|
footerContainerProps = defaultObj(footerContainerProps);
|
|
65
|
-
const
|
|
65
|
+
const hasData = !!Object.size(data,true);
|
|
66
|
+
const emptyData = !hasData && renderListContent === false ?null : typeof renderEmpty =='function' ? renderEmpty() : null;
|
|
66
67
|
const hasEmptyData = emptyData && React.isValidElement(emptyData);
|
|
67
|
-
|
|
68
|
+
const emptyContent = <View onRender={onComponentRender} testID={testID+"_EmptyData"} style={styles.hasNotData}>
|
|
69
|
+
{emptyData}
|
|
70
|
+
</View>
|
|
68
71
|
const {fFilters,headersContent,footersContent,totalWidths} = React.useMemo(()=>{
|
|
69
72
|
const headersContent = [],footersContent = [],fFilters = [];
|
|
70
73
|
let totalWidths = 0;
|
|
@@ -159,15 +162,15 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
|
|
|
159
162
|
}
|
|
160
163
|
};
|
|
161
164
|
const headerFootersFilters = <>
|
|
162
|
-
<
|
|
165
|
+
<Header visible={!!(showTableHeaders && headersContent.length)} testID={testID+"_Header"} {...headerContainerProps} style={[styles.header,headerContainerProps.style,footersContent.length]}>
|
|
163
166
|
{headersContent}
|
|
164
|
-
</
|
|
165
|
-
<
|
|
167
|
+
</Header>
|
|
168
|
+
<Header visible = {!!fFilters.length} {...headerContainerProps} testID={testID+"_Filters"} style={[styles.header,styles.footers,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0,headerContainerProps.style]}>
|
|
166
169
|
{fFilters}
|
|
167
|
-
</
|
|
168
|
-
<
|
|
170
|
+
</Header>
|
|
171
|
+
<Header visible={!!(showTableHeaders && footersContent.length)} testID={testID+"_Footer"} {...footerContainerProps} style={[styles.header,styles.footers,headerContainerProps.style,footerContainerProps.style,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}>
|
|
169
172
|
{footersContent}
|
|
170
|
-
</
|
|
173
|
+
</Header>
|
|
171
174
|
</>
|
|
172
175
|
return <View testID= {testID+"_Container"} {...containerProps} onLayout={(e)=>{
|
|
173
176
|
layoutRef.current = e.nativeEvent.layout;
|
|
@@ -191,9 +194,7 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
|
|
|
191
194
|
</View>
|
|
192
195
|
</ScrollView>
|
|
193
196
|
</RNView>}
|
|
194
|
-
{hasEmptyData ? <
|
|
195
|
-
{emptyData}
|
|
196
|
-
</View> : <ScrollNative {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle,{height:'100%'}]} showsVerticalScrollIndicator={false}
|
|
197
|
+
{hasEmptyData && isNative ? emptyContent : <ScrollNative {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle,{height:'100%'}]} showsVerticalScrollIndicator={false}
|
|
197
198
|
onScroll = {getOnScrollCb([headerScrollViewRef,footerScrollViewRef],null,(args)=>{
|
|
198
199
|
const nativeEvent = args.nativeEvent;
|
|
199
200
|
if(absoluteScrollViewRef.current && absoluteScrollViewRef.current.checkVisibility){
|
|
@@ -281,7 +282,7 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
|
|
|
281
282
|
args.isSelected = withDatagridContext ? isRowSelected(args) : false;
|
|
282
283
|
return <TableRowComponent {...props} style={[getRowStyle(args),props.style]}/>
|
|
283
284
|
},
|
|
284
|
-
Table:
|
|
285
|
+
Table: VirtuosoTableComponent,
|
|
285
286
|
}}
|
|
286
287
|
/>
|
|
287
288
|
{isNative ? <AbsoluteScrollView
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { StyleSheet } from "react-native";
|
|
2
|
+
import {isMobileNative} from "$cplatform";
|
|
2
3
|
|
|
3
4
|
const styles = StyleSheet.create({
|
|
4
5
|
datagrid : {
|
|
@@ -11,7 +12,7 @@ const styles = StyleSheet.create({
|
|
|
11
12
|
width : '100%',
|
|
12
13
|
minHeight : 300,
|
|
13
14
|
paddingBottom : 10,
|
|
14
|
-
paddingLeft :
|
|
15
|
+
paddingLeft : 0,
|
|
15
16
|
paddingRight : 0,
|
|
16
17
|
flex : 1,
|
|
17
18
|
position : 'relative',
|
|
@@ -83,6 +84,21 @@ const styles = StyleSheet.create({
|
|
|
83
84
|
width : '100%',
|
|
84
85
|
justifyContent : 'center',
|
|
85
86
|
alignItems : 'center'
|
|
87
|
+
},
|
|
88
|
+
cell : isMobileNative()? {
|
|
89
|
+
paddingLeft:10,
|
|
90
|
+
paddingRight : 5,
|
|
91
|
+
paddingBottom : 5,
|
|
92
|
+
paddingTop : 5,
|
|
93
|
+
} : {
|
|
94
|
+
paddingLeft: 10,
|
|
95
|
+
paddingTop:5,
|
|
96
|
+
paddingBottom:5,
|
|
97
|
+
paddingRight: 10
|
|
98
|
+
},
|
|
99
|
+
sectionListHeader : {
|
|
100
|
+
paddingVertical : 10,
|
|
101
|
+
paddingHorizontal : 10,
|
|
86
102
|
}
|
|
87
103
|
});
|
|
88
104
|
export default styles;
|
package/src/context/Provider.js
CHANGED
|
@@ -3,7 +3,7 @@ import appConfig from "$capp/config";
|
|
|
3
3
|
import {MD3LightTheme,MD3DarkTheme} from "react-native-paper";
|
|
4
4
|
import { useMaterial3Theme } from '@pchmn/expo-material3-theme';
|
|
5
5
|
import {colorsAlias,Colors} from "$theme";
|
|
6
|
-
import {isObj,isNonNullString} from "$cutils";
|
|
6
|
+
import {isObj,isNonNullString,defaultStr} from "$cutils";
|
|
7
7
|
import eMainScreens from "$escreens/mainScreens";
|
|
8
8
|
import {ExpoUIContext} from "./hooks";
|
|
9
9
|
import Login from "$eauth/Login";
|
|
@@ -78,8 +78,22 @@ const Provider = ({children,getTableData,navigation,components,convertFiltersToS
|
|
|
78
78
|
}
|
|
79
79
|
theme.fonts = newTheme.fonts;
|
|
80
80
|
const r = typeof extendAppTheme == 'function'? extendAppTheme(theme) : theme;
|
|
81
|
+
const _theme = (isObj(r) ? r : theme);
|
|
82
|
+
const customCSS = _theme.customCSS;
|
|
81
83
|
return {
|
|
82
|
-
...
|
|
84
|
+
..._theme,
|
|
85
|
+
get customCSS(){
|
|
86
|
+
const prevCSS = defaultStr(typeof customCSS ==='function'? customCSS(theme) : customCSS);
|
|
87
|
+
return `
|
|
88
|
+
.virtuoso-table-component,
|
|
89
|
+
.virtuoso-table-component th,
|
|
90
|
+
.virtuoso-table-component tr,
|
|
91
|
+
.virtuoso-table-component td{
|
|
92
|
+
border-collapse : collapse!important;
|
|
93
|
+
}
|
|
94
|
+
${prevCSS}
|
|
95
|
+
`;
|
|
96
|
+
},
|
|
83
97
|
get textFieldMode (){
|
|
84
98
|
/***** possibilité de charger le mode d'affichage par défaut des champs textuels dans le theme de l'application */
|
|
85
99
|
if(typeof theme.textFieldMode =='string' && theme.textFieldMode && modes[theme.textFieldMode]){
|
|
@@ -1,26 +0,0 @@
|
|
|
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
|
-
import { StyleSheet } from "react-native";
|
|
8
|
-
import {isMobileNative} from "$cplatform";
|
|
9
|
-
import {classNames} from "$cutils";
|
|
10
|
-
const isNative = isMobileNative();
|
|
11
|
-
const Component = isNative ? View : "tr";
|
|
12
|
-
|
|
13
|
-
export default function TableFiltersComponent({visible,className,children:cChildren,...rest}){
|
|
14
|
-
const children = React.useMemo(()=>{
|
|
15
|
-
return cChildren;
|
|
16
|
-
},[cChildren]);
|
|
17
|
-
const rP = isNative ? rest : {className:classNames(className,"table-footer-or-header-row")}
|
|
18
|
-
if(!isNative && !visible) return null;
|
|
19
|
-
return <Component {...rP} style={StyleSheet.flatten([rest.style,!visible && {height:0,opacity:0,display:'none'}])}>
|
|
20
|
-
{children}
|
|
21
|
-
</Component>
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
TableFiltersComponent.propTypes = {
|
|
25
|
-
visible : PropTypes.bool,
|
|
26
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
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 TableHeaderComponent({cells,columns,...rest}){
|
|
8
|
-
const children = React.useMemo(()=>{
|
|
9
|
-
if(Array.isArray(cells)){
|
|
10
|
-
return null;
|
|
11
|
-
}
|
|
12
|
-
return cells;
|
|
13
|
-
},[cells,columns]);
|
|
14
|
-
return <View {...rest}>
|
|
15
|
-
{children}
|
|
16
|
-
</View>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
TableHeaderComponent.propTypes = {
|
|
20
|
-
columns : PropTypes.arrayOf(PropTypes.bool)
|
|
21
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
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 TableHeaderComponent({cells,columns,...rest}){
|
|
8
|
-
const children = React.useMemo(()=>{
|
|
9
|
-
if(Array.isArray(cells)){
|
|
10
|
-
return null;
|
|
11
|
-
}
|
|
12
|
-
return cells;
|
|
13
|
-
},[cells,columns]);
|
|
14
|
-
return <View {...rest}>
|
|
15
|
-
{children}
|
|
16
|
-
</View>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
TableHeaderComponent.propTypes = {
|
|
20
|
-
columns : PropTypes.arrayOf(PropTypes.bool)
|
|
21
|
-
}
|