@fto-consult/expo-ui 6.24.2 → 6.25.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/app.config.json +1 -1
- package/babel.config.alias.js +2 -1
- package/babel.config.js +1 -1
- package/electron/utils/env.js +80 -0
- package/expo-ui-path.js +2 -2
- package/index.js +14 -13
- package/is-local-dev.js +5 -0
- package/metro.config.js +3 -2
- package/package.json +6 -3
- package/src/App.js +3 -3
- package/src/components/Datagrid/Accordion/Row.js +74 -100
- package/src/components/Datagrid/Accordion/ToogleRow.js +9 -0
- package/src/components/Datagrid/Accordion/index.js +30 -35
- package/src/components/Datagrid/Actions/index.js +12 -44
- package/src/components/Datagrid/Checkbox.js +4 -7
- package/src/components/Datagrid/Common/Common.js +112 -148
- package/src/components/Datagrid/Dashboard/index.js +2 -2
- package/src/components/Datagrid/IndexComponent.js +8 -13
- package/src/components/Datagrid/Table/index.js +53 -51
- package/src/components/Datagrid/Test/index.js +10 -3
- package/src/components/Datagrid/events/evx.js +7 -0
- package/src/components/Datagrid/events/index.js +11 -0
- package/src/components/Datagrid/hooks/Provider.js +6 -0
- package/src/components/Datagrid/hooks/context.js +5 -0
- package/src/components/Datagrid/hooks/index.js +104 -0
- package/src/components/Datagrid/utils.js +6 -4
- package/src/components/Dialog/Dialog.js +13 -12
- package/src/components/Dialog/DialogContent.js +11 -0
- package/src/components/KeyboardAvoidingView/index.js +7 -3
- package/src/components/List/Common.js +5 -3
- package/src/components/List/FlashList.js +13 -13
- package/src/components/List/Virtuoso/index.js +29 -8
- package/src/components/List/Virtuoso/index.native.js +6 -1
- package/src/components/Table/FiltersOrFooters.js +11 -3
- package/src/components/Table/Header/Cell/index.js +10 -0
- package/src/components/Table/Header/Cell/index.native.js +7 -0
- package/src/components/Table/{Header.js → Header/Component.js} +0 -4
- package/src/components/Table/{Row.js → Header/Component.native.js} +3 -3
- package/src/components/Table/Header/index.js +12 -0
- package/src/components/Table/List/index.js +3 -1
- package/src/components/Table/List/index.native.js +2 -1
- package/src/components/Table/Row/Cell/Content.js +17 -0
- package/src/components/Table/Row/Cell/Content.native.js +15 -0
- package/src/components/Table/Row/Cell/index.js +29 -0
- package/src/components/Table/Row/RowWrapper.js +7 -0
- package/src/components/Table/Row/RowWrapper.native.js +10 -0
- package/src/components/Table/Row/index.js +38 -0
- package/src/components/Table/RowTemplate/index.js +10 -0
- package/src/components/Table/RowTemplate/index.web.js +9 -0
- package/src/components/Table/ScrollNative/index.js +7 -0
- package/src/components/Table/ScrollNative/index.native.js +8 -0
- package/src/components/Table/VirtuosoTable/index.js +5 -0
- package/src/components/Table/VirtuosoTable/index.native.js +3 -0
- package/src/components/Table/hooks.js +84 -0
- package/src/components/Table/index.js +88 -247
- package/src/components/Table/styles.js +88 -0
- package/src/components/Table/utils.js +1 -0
- package/src/layouts/AppBar/index.js +11 -10
- package/src/layouts/Screen/ScreenWithoutAuthContainer.js +14 -6
- package/src/navigation/Drawer/items/index.js +2 -1
- package/src/navigation/index.js +11 -3
- package/src/screens/Help/About.js +1 -1
- package/src/screens/Help/openLibraries.js +1 -1
- package/src/test-screens/Home.js +4 -1
- package/webpack.config.js +4 -2
- package/src/components/Table/Cell.js +0 -24
|
@@ -14,6 +14,7 @@ import RenderType from "../RenderType";
|
|
|
14
14
|
import Footer from "../Footer/Footer";
|
|
15
15
|
import theme from "$theme";
|
|
16
16
|
import Table from "$ecomponents/Table";
|
|
17
|
+
import DatagridProvider from "../hooks/Provider";
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
const DatagridFactory = (Factory)=>{
|
|
@@ -276,57 +277,58 @@ const DatagridFactory = (Factory)=>{
|
|
|
276
277
|
</View>
|
|
277
278
|
</ScrollView>
|
|
278
279
|
</View> : null;
|
|
279
|
-
return <
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
280
|
+
return <DatagridProvider context={this}>
|
|
281
|
+
<View style={[styles.container,{flex:1}]} testID={testID+"_TableContainer"} pointerEvents={pointerEvents}>
|
|
282
|
+
<View ref={this.layoutRef} testID={testID+"_LayoutContainer"}>
|
|
283
|
+
{this.props.showActions !== false ? <DatagridActions
|
|
284
|
+
pointerEvents = {pointerEvents}
|
|
285
|
+
title = {this.renderDataSourceSelector()}
|
|
286
|
+
actions = {actions}
|
|
287
|
+
/> : null}
|
|
288
|
+
{rPagination}
|
|
289
|
+
{progressBar}
|
|
290
|
+
</View>
|
|
291
|
+
{canRenderChart ?
|
|
292
|
+
<View testID={testID+"_ChartContainer"} {...chartContainerProps} style={[theme.styles.w100,chartContainerProps.style]}>
|
|
293
|
+
{this.renderChart()}
|
|
294
|
+
</View> :
|
|
295
|
+
<Table
|
|
296
|
+
ref = {this.listRef}
|
|
297
|
+
{...rest}
|
|
298
|
+
withDatagridContext
|
|
299
|
+
sortedColumn = {sortedColumn}
|
|
300
|
+
onRender = {this.onRender.bind(this)}
|
|
301
|
+
getItemType = {this.getFlashListItemType.bind(this)}
|
|
302
|
+
renderItem = {this.renderFlashListItem.bind(this)}
|
|
303
|
+
renderSectionHeader = {this.renderFlashListItem.bind(this)}
|
|
304
|
+
hasFooters = {hasFootersFields && !canRenderChart ? true : false}
|
|
305
|
+
showFilters = {showFilters}
|
|
306
|
+
showFooters = {showFooters && !canRenderChart ? true : false}
|
|
307
|
+
showHeaders = { canRenderChart ? !!showFilters : true}
|
|
308
|
+
headerCellContainerProps = {{
|
|
309
|
+
style : showFilters?{justifyContent:'flex-start'}:null
|
|
310
|
+
}}
|
|
311
|
+
isRowSelected = {this.isRowSelected.bind(this)}
|
|
312
|
+
columns = {this.state.columns}
|
|
313
|
+
//renderRow={this.renderRow.bind(this)}
|
|
314
|
+
getRowKey = {this.getRowKey.bind(this)}
|
|
315
|
+
columnsWidths = {widths}
|
|
316
|
+
renderCell={this.renderRowCell.bind(this)}
|
|
317
|
+
rowContainerProps = {(props)=>{
|
|
318
|
+
return {
|
|
319
|
+
style : getRowStyle(props,{selected:this.isRowSelected.bind(this)}),
|
|
320
|
+
}
|
|
321
|
+
}}
|
|
322
|
+
data = {this.state.data}
|
|
323
|
+
footers = {this.getFooterValues()}
|
|
324
|
+
renderHeaderCell={this.renderHeaderCell.bind(this)}
|
|
325
|
+
renderFilterCell={this.renderFilterCell.bind(this)}
|
|
326
|
+
renderFooterCell={this.renderFooterCell.bind(this)}
|
|
327
|
+
renderEmpty = {this.renderEmpty.bind(this)}
|
|
328
|
+
/>}
|
|
329
|
+
</View>
|
|
330
|
+
|
|
331
|
+
</DatagridProvider>
|
|
330
332
|
}
|
|
331
333
|
}
|
|
332
334
|
clx.propTypes = {
|
|
@@ -2,19 +2,26 @@
|
|
|
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
|
|
6
|
-
import Table from "../Table";
|
|
5
|
+
import Table from "../IndexComponent";
|
|
7
6
|
import React from "$react";
|
|
8
7
|
import { faker } from '@faker-js/faker';
|
|
9
8
|
export default function TestDatagridComponent({count,...props}){
|
|
10
9
|
const data = React.useMemo(()=>{
|
|
11
|
-
count = typeof count =='number' && count > 10 ? count :
|
|
10
|
+
count = typeof count =='number' && count > 10 ? count : 100;
|
|
12
11
|
return faker.helpers.multiple(createRandomUser, {
|
|
13
12
|
count,
|
|
14
13
|
});
|
|
15
14
|
},[count])
|
|
16
15
|
return <Table
|
|
17
16
|
title = "Utilisateurs"
|
|
17
|
+
accordion = {({rowData})=>{
|
|
18
|
+
return {
|
|
19
|
+
content : `${rowData.email}`,
|
|
20
|
+
title : rowData?.username,
|
|
21
|
+
//avatar : rowData.avatar,
|
|
22
|
+
right : rowData.birthdate,
|
|
23
|
+
}
|
|
24
|
+
}}
|
|
18
25
|
columns={{
|
|
19
26
|
userId : {
|
|
20
27
|
primaryKey : true,
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { useContext,useEffect,useMemo,useReducer } from "react";
|
|
2
|
+
import { DatagridContext } from "./context";
|
|
3
|
+
import {isObj,isNonNullString} from "$cutils";
|
|
4
|
+
import events from "../events";
|
|
5
|
+
export const useDatagrid = x=> {
|
|
6
|
+
const t = useContext(DatagridContext)
|
|
7
|
+
if(!t || !t?.context || !t?.context?.state || !t?.context?.state?.data){
|
|
8
|
+
throw "Le composant Datagrid actions doit être enfant d'un contexe de datagrid valide";
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
export const useDatagridContext = ()=>{
|
|
13
|
+
return useDatagrid()?.context;
|
|
14
|
+
}
|
|
15
|
+
export const useData = ()=>{
|
|
16
|
+
const {context} = useDatagrid();
|
|
17
|
+
return Array.isArray(context.state.data) && context.state.data || [];
|
|
18
|
+
}
|
|
19
|
+
export const useSelectedRows = ()=>{
|
|
20
|
+
const {context} = useDatagrid();
|
|
21
|
+
}
|
|
22
|
+
export const useGetRowKey = ({rowData,rowIndex})=>{
|
|
23
|
+
const {context} = useDatagrid();
|
|
24
|
+
return context.getRowKey(rowData,rowIndex);
|
|
25
|
+
};
|
|
26
|
+
/****
|
|
27
|
+
@param {string|Array} event, l'évènement ou les évènements en question, qui est trigger par le contexte de datagrid
|
|
28
|
+
@param {function|string} getter, la fonction getter, est la fonction qui prenant en paramètre le contexte, retourne la valeur liée à l'évènement event
|
|
29
|
+
@param {function} onEvent, la fonction appelée lorsque l'évènement est exécutée
|
|
30
|
+
*/
|
|
31
|
+
export const useOnEvent = (event,getter,onEvent)=>{
|
|
32
|
+
const {context} = useDatagrid();
|
|
33
|
+
if((!isNonNullString(event) && !Array.isArray(event)) || !event.length){
|
|
34
|
+
throw `méthode invalide ${method} supportée par le contexte`;
|
|
35
|
+
}
|
|
36
|
+
if(typeof getter !=='function') {
|
|
37
|
+
throw "méthode getter invalide pour la récupéreration de l'état lié au contexte du datagrid";
|
|
38
|
+
}
|
|
39
|
+
const evBack = event;
|
|
40
|
+
event = Array.isArray(event) ? event : isNonNullString(event)? event.trim().split(",") : [];
|
|
41
|
+
const [state, dispatch] = useReducer(function(state2,action){
|
|
42
|
+
if(event.filter(ev=>action.type.toLowerCase() === ev?.toLowerCase().trim()).length){
|
|
43
|
+
return getter(context,action.type);
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}, getter(context,evBack));
|
|
47
|
+
const callbacks = useMemo((...args)=>{
|
|
48
|
+
const callbacks = {};
|
|
49
|
+
event.map((ev)=>{
|
|
50
|
+
callbacks[ev] = (...args)=>{
|
|
51
|
+
if(typeof onEvent ==='function' && onEvent(ev,...args) === false) return false;
|
|
52
|
+
return dispatch({type:ev});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return callbacks;
|
|
56
|
+
},[event.join(",")]);
|
|
57
|
+
useEffect(()=>{
|
|
58
|
+
Object.map(callbacks,(cb,event)=>{
|
|
59
|
+
context.on(event,cb);
|
|
60
|
+
});
|
|
61
|
+
return ()=>{
|
|
62
|
+
Object.map(callbacks,(cb,ev)=>{
|
|
63
|
+
context.off(ev,cb);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
},[]);
|
|
67
|
+
return state;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
/****
|
|
72
|
+
ecoute l'évènement event sur le contexte de datagrid
|
|
73
|
+
@param {string} event, l'évènement à écouter
|
|
74
|
+
@param {function} onEvent, la fonction appelée lorsque l'évènement est écoutée
|
|
75
|
+
*/
|
|
76
|
+
export const useBindEvent = (event,onEvent)=>{
|
|
77
|
+
const {context} = useDatagrid();
|
|
78
|
+
if(!isNonNullString(event)){
|
|
79
|
+
throw `impossible d'écouter un évènemet invalide pour le contexte de datagrid`;
|
|
80
|
+
}
|
|
81
|
+
useEffect(()=>{
|
|
82
|
+
context.on(event,onEvent);
|
|
83
|
+
return ()=>{
|
|
84
|
+
context.off(event,onEvent);
|
|
85
|
+
}
|
|
86
|
+
},[]);
|
|
87
|
+
return onEvent;
|
|
88
|
+
}
|
|
89
|
+
export const useIsRowSelected = (...args)=>{
|
|
90
|
+
return useOnEvent([events.ON_ROW_TOGGLE,events.ON_ALL_ROWS_TOGGLE],(context)=>{
|
|
91
|
+
return context.isRowSelected(...args);
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const useGetSelectedRowsCount = ()=>{
|
|
96
|
+
return useOnEvent([events.ON_ROW_TOGGLE,events.ON_ALL_ROWS_TOGGLE],(context)=>{
|
|
97
|
+
return context.getSelectedRowsCount();
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
export const useIsAllRowsSelected = ()=>{
|
|
101
|
+
return useOnEvent([events.ON_ROW_TOGGLE,events.ON_ALL_ROWS_TOGGLE],(context)=>{
|
|
102
|
+
return context.isAllRowsSelected();
|
|
103
|
+
});
|
|
104
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import theme,{LINE_HEIGHT} from "$theme";
|
|
1
|
+
import theme,{Colors,LINE_HEIGHT} from "$theme";
|
|
2
2
|
import { StyleSheet } from "react-native";
|
|
3
3
|
import {get as getSession} from "./Common/session";
|
|
4
4
|
import appConfig from "$capp/config";
|
|
@@ -98,7 +98,9 @@ export const ROW_EVEN_STYLE = {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
export const ROW_SELECTED_STYLE = {
|
|
101
|
-
backgroundColor
|
|
101
|
+
get backgroundColor(){
|
|
102
|
+
return theme.isDark()? Colors.lighten(theme.colors.surface) : Colors.darken(theme.colors.surface);
|
|
103
|
+
}
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
export const ROW_BORDER_STYLE = {
|
|
@@ -119,7 +121,7 @@ export const DATE_COLUMN_WIDTH = 200;
|
|
|
119
121
|
|
|
120
122
|
export {LINE_HEIGHT}
|
|
121
123
|
|
|
122
|
-
export const styles =
|
|
124
|
+
export const styles = ({
|
|
123
125
|
approved : ROW_APPROVED_STYLE,
|
|
124
126
|
archived : ROW_ARCHIVED_STYLE,
|
|
125
127
|
selected : ROW_SELECTED_STYLE,
|
|
@@ -167,7 +169,7 @@ export const getRowStyle = ({row,bordered,numColumns,rowData,isAccordion,isTable
|
|
|
167
169
|
if(rowIndex !== undefined){
|
|
168
170
|
style.push(rowIndex%2===0?styles.even : theme.isDark()?styles.oddDark : styles.odd)
|
|
169
171
|
}
|
|
170
|
-
if(
|
|
172
|
+
if(selected){
|
|
171
173
|
style.push(styles.selected,{borderBottomWidth:1,borderBottomColor:theme.colors.primary})
|
|
172
174
|
}
|
|
173
175
|
if(paid || row.paid){
|
|
@@ -20,7 +20,7 @@ import {ACTION_ICON_SIZE} from "$ecomponents/AppBar";
|
|
|
20
20
|
import DialogFooter from "./DialogFooter";
|
|
21
21
|
import { Dimensions } from "react-native";
|
|
22
22
|
import Surface from "$ecomponents/Surface";
|
|
23
|
-
import
|
|
23
|
+
import DialogContent from "./DialogContent";
|
|
24
24
|
|
|
25
25
|
export const FOOTER_HEIGHT = 50;
|
|
26
26
|
export const HEADER_HEIGHT = 50;
|
|
@@ -198,14 +198,14 @@ const DialogComponent = React.forwardRef((props,ref)=>{
|
|
|
198
198
|
testID = {testID}
|
|
199
199
|
contentContainerProps = {contentContainerProps}
|
|
200
200
|
>
|
|
201
|
-
<
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
201
|
+
<DialogContent isFullScreen={isFullScreenDialog} isPreloader={isPreloader}>
|
|
202
|
+
<Surface
|
|
203
|
+
testID = {testID+"_Overlay"}
|
|
204
|
+
ref={overlayRef}
|
|
205
|
+
{...overlayProps}
|
|
206
|
+
style={[styles.overlay,isAlert && styles.overlayAlert,{backgroundColor},overlayProps.style,fullScreenStyle]}
|
|
207
|
+
>
|
|
208
|
+
{(!isAlert && (actions || title || subtitle)) ? <AppBarDialog
|
|
209
209
|
actionsProps = {actionsProps}
|
|
210
210
|
testID = {testID+"_AppBar"}
|
|
211
211
|
{...appBarProps}
|
|
@@ -269,14 +269,15 @@ const DialogComponent = React.forwardRef((props,ref)=>{
|
|
|
269
269
|
isFullScreen = {isFullScreenDialog}
|
|
270
270
|
fullScreen = {customFullScreen}
|
|
271
271
|
children = {footer}
|
|
272
|
-
/> : null}
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
/> : null}
|
|
273
|
+
</Surface>
|
|
274
|
+
</DialogContent>
|
|
275
275
|
</ModalComponent>
|
|
276
276
|
</Portal>
|
|
277
277
|
});
|
|
278
278
|
export default DialogComponent;
|
|
279
279
|
|
|
280
|
+
|
|
280
281
|
DialogComponent.propTypes= {
|
|
281
282
|
...Modal.propTypes,
|
|
282
283
|
isAlert : PropTypes.bool,//si c'est le rendu alert, pour le rendu de l'alerte
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import KeyboardAvoidingView from "../KeyboardAvoidingView";
|
|
2
|
+
import React from "$react";
|
|
3
|
+
import { useWindowDimensions } from "react-native";
|
|
4
|
+
|
|
5
|
+
const DialogContentComponent = ({isPreloader,isFullScreen,...props})=>{
|
|
6
|
+
const isFull = isFullScreen();
|
|
7
|
+
//useWindowDimensions();
|
|
8
|
+
const content = React.useMemo(()=>props.children,[isPreloader]);
|
|
9
|
+
return isPreloader || !isFull ? content : <KeyboardAvoidingView>{content}</KeyboardAvoidingView>
|
|
10
|
+
}
|
|
11
|
+
export default DialogContentComponent;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import View from "$ecomponents/View";
|
|
2
2
|
import React from "$react";
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import {isNonNullString} from "$cutils";
|
|
4
|
+
import theme from "$theme";
|
|
5
|
+
const KeyboardAvoidingViewComponent = React.forwardRef(({children,style,testID,...props},ref)=>{
|
|
6
|
+
return <View {...props} style={[theme.styles.flex1,style]} children={children} testID={isNonNullString(testID) ? `${testID.trim()}_KeyboardAvoidingView` : "RN_KeyboardAvoidingView"}/>
|
|
5
7
|
});
|
|
6
8
|
|
|
7
9
|
KeyboardAvoidingViewComponent.displayName = "KeyboardAvoidingViewComponent";
|
|
8
|
-
KeyboardAvoidingViewComponent.propTypes = Object.assign({},View.propTypes);
|
|
10
|
+
KeyboardAvoidingViewComponent.propTypes = Object.assign({},View.propTypes);
|
|
11
|
+
|
|
12
|
+
export default KeyboardAvoidingViewComponent;
|
|
@@ -3,7 +3,7 @@ import React from "$react";
|
|
|
3
3
|
import { prepareItems as customPrepareItems,getBToTopRef } from "./utils";
|
|
4
4
|
import {grid,StylePropTypes} from "$theme";
|
|
5
5
|
import PropTypes from "prop-types";
|
|
6
|
-
import {defaultObj,extendObj,isObj,defaultDecimal,defaultArray,defaultFunc} from "$cutils";
|
|
6
|
+
import {defaultObj,defaultStr,extendObj,isObj,defaultDecimal,defaultArray,defaultFunc} from "$cutils";
|
|
7
7
|
import {isMobileMedia} from "$cplatform/dimensions";
|
|
8
8
|
import BackToTop from "$ecomponents/BackToTop";
|
|
9
9
|
import {FlatList,StyleSheet,View} from "react-native";
|
|
@@ -13,7 +13,7 @@ import { useList } from "./hooks";
|
|
|
13
13
|
|
|
14
14
|
const CommonListComponent = React.forwardRef((props,ref)=>{
|
|
15
15
|
const context = useList(props);
|
|
16
|
-
let {responsive,defaultItemHeight,itemHeight,windowWidth,onRender,componentProps,columnWrapperStyle,onViewableItemsChanged,withFlatListItem,Component,withBackToTop,backToTopRef:customBackToTopRef,withBackToTopButton,onScroll,onScrollEnd,onMount,onUnmount,renderScrollViewWrapper,prepareItems,getItemKey,getKey,keyExtractor,items,filter,renderItem,numColumns,containerProps,bindResizeEvents,...rest} = props;
|
|
16
|
+
let {responsive,testID,defaultItemHeight,itemHeight,windowWidth,onRender,componentProps,columnWrapperStyle,onViewableItemsChanged,withFlatListItem,Component,withBackToTop,backToTopRef:customBackToTopRef,withBackToTopButton,onScroll,onScrollEnd,onMount,onUnmount,renderScrollViewWrapper,prepareItems,getItemKey,getKey,keyExtractor,items,filter,renderItem,numColumns,containerProps,bindResizeEvents,...rest} = props;
|
|
17
17
|
withBackToTopButton = withBackToTop === true || withBackToTopButton == true || isMobileMedia()? true : false;
|
|
18
18
|
rest = defaultObj(rest);
|
|
19
19
|
containerProps = defaultObj(containerProps);
|
|
@@ -30,6 +30,7 @@ const CommonListComponent = React.forwardRef((props,ref)=>{
|
|
|
30
30
|
const hasCustomBackToTop = typeof customBackToTopRef == 'function'? true : false;
|
|
31
31
|
const backToTopRef = React.useRef(null);
|
|
32
32
|
const isFlatList = Component === FlatList;
|
|
33
|
+
defaultStr(props.testID,"RN_CommonListComponent");
|
|
33
34
|
extendObj(context,{
|
|
34
35
|
getKey : typeof keyExtractor =='function'? keyExtractor : typeof getItemKey =='function'? getItemKey : typeof getKey =='function'? getKey : undefined,
|
|
35
36
|
addItemsRefs : function(ref, itemRef){
|
|
@@ -150,12 +151,13 @@ const CommonListComponent = React.forwardRef((props,ref)=>{
|
|
|
150
151
|
const restP = numColumns > 1 && isFlatList ? {
|
|
151
152
|
columnWrapperStyle : [styles.columnWrapperStyle,props.columnWrapperStyle]
|
|
152
153
|
} : {};
|
|
153
|
-
return <View {...containerProps} style={[styles.container,containerProps.style]}>
|
|
154
|
+
return <View testID={testID+"_CommonListContainer"} {...containerProps} style={[styles.container,containerProps.style]}>
|
|
154
155
|
<Component
|
|
155
156
|
onEndReachedThreshold={0}
|
|
156
157
|
scrollEventThrottle={16}
|
|
157
158
|
{...rest}
|
|
158
159
|
{...restP}
|
|
160
|
+
testID = {testID}
|
|
159
161
|
ref = {listRef}
|
|
160
162
|
onScroll={context.onScroll}
|
|
161
163
|
data = {context.items}
|
|
@@ -7,19 +7,19 @@ import View from "$ecomponents/View";
|
|
|
7
7
|
const FlashListComponent = React.forwardRef((props,ref)=>{
|
|
8
8
|
const {testID} = props
|
|
9
9
|
return (<CommonListComponent
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
testID = {'RN_FlashListComponent'}
|
|
11
|
+
estimatedItemSize = {50}
|
|
12
|
+
ListHeaderComponent={() => (
|
|
13
|
+
<View testID={(testID||'RN_FlashListComponent')+"_Header"}>{props.children}</View>
|
|
14
|
+
)}
|
|
15
|
+
//disableAutoLayout
|
|
16
|
+
//disableHorizontalListHeightMeasurement = {props.horizontal?undefined : true}
|
|
17
|
+
{...props}
|
|
18
|
+
contentContainerStyle = {undefined}
|
|
19
|
+
style = {undefined}
|
|
20
|
+
Component = {FlashList}
|
|
21
|
+
ref={ref}
|
|
22
|
+
/>)
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
FlashListComponent.propTypes = {
|
|
@@ -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 {Virtuoso,VirtuosoGrid} from "react-virtuoso/dist/index.mjs";
|
|
5
|
+
import {Virtuoso,VirtuosoGrid,TableVirtuoso} from "react-virtuoso/dist/index.mjs";
|
|
6
6
|
import React from "$react";
|
|
7
7
|
import PropTypes from "prop-types";
|
|
8
8
|
import {defaultObj,classNames,defaultNumber,isObj,isDOMElement,isNumber,uniqid,isNonNullString,defaultStr} from "$cutils";
|
|
@@ -10,6 +10,8 @@ import { View } from "react-native";
|
|
|
10
10
|
import {useList} from "../hooks";
|
|
11
11
|
import theme,{grid} from "$theme";
|
|
12
12
|
import Dimensions from "$cdimensions";
|
|
13
|
+
import { StyleSheet } from "react-native";
|
|
14
|
+
import {isMobileNative} from "$cplatform";
|
|
13
15
|
|
|
14
16
|
const propTypes = {
|
|
15
17
|
...defaultObj(Virtuoso.propTypes),
|
|
@@ -29,12 +31,19 @@ const propTypes = {
|
|
|
29
31
|
isScrolling : PropTypes.func,
|
|
30
32
|
};
|
|
31
33
|
/***@see : https://virtuoso.dev/virtuoso-api-reference/ */
|
|
32
|
-
const VirtuosoListComponent = React.forwardRef(({onRender,listClassName,components,itemProps,windowWidth,numColumns,responsive,testID,renderItem,onEndReached,onLayout,onContentSizeChange,onScroll,isScrolling,estimatedItemSize,onEndReachedThreshold,containerProps,style,autoSizedStyle,...props},ref)=>{
|
|
33
|
-
|
|
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
|
+
if(renderTable){
|
|
36
|
+
responsive = false;
|
|
37
|
+
}
|
|
38
|
+
const Component = React.useMemo(()=>renderTable ? TableVirtuoso : responsive?VirtuosoGrid:Virtuoso,[responsive,renderTable]);
|
|
34
39
|
const context = useList(props);
|
|
35
40
|
itemProps = defaultObj(itemProps);
|
|
36
41
|
const items = context.items;
|
|
42
|
+
renderTable ? rowProps = defaultObj(rowProps) : null;
|
|
37
43
|
const r2 = {};
|
|
44
|
+
if(renderTable){
|
|
45
|
+
r2.fixedHeaderContent = fixedHeaderContent;
|
|
46
|
+
}
|
|
38
47
|
Object.map(Component.propTypes,(_,i)=>{
|
|
39
48
|
if(i in props){
|
|
40
49
|
r2[i] = props[i];
|
|
@@ -48,7 +57,7 @@ const VirtuosoListComponent = React.forwardRef(({onRender,listClassName,componen
|
|
|
48
57
|
const sizeRef = React.useRef({width:0,height:0});
|
|
49
58
|
const listSize = sizeRef.current;
|
|
50
59
|
const isValid = ()=> listRef.current;
|
|
51
|
-
const listStyle = {height:'100%',width:"100%",overflowX:
|
|
60
|
+
const listStyle = {height:'100%',width:"100%",overflowX:renderTable?"auto":"hidden",maxWidth:"100%"};
|
|
52
61
|
r2["data-test-id"] = testID+"_ListContent";
|
|
53
62
|
if(isObj(estimatedItemSize)){
|
|
54
63
|
if(isNumber(estimatedItemSize.width)){
|
|
@@ -137,8 +146,10 @@ const VirtuosoListComponent = React.forwardRef(({onRender,listClassName,componen
|
|
|
137
146
|
}
|
|
138
147
|
}}
|
|
139
148
|
components = {{
|
|
140
|
-
Item : responsive ? function(props){return <ItemContainer {...props} style={[itemProps.style,props.style]} numColumns={numColumns}/>} : undefined,
|
|
141
|
-
|
|
149
|
+
Item : renderTable ? undefined : responsive ? function(props){return <ItemContainer {...props} style={[itemProps.style,props.style]} numColumns={numColumns}/>} : undefined,
|
|
150
|
+
...(renderTable ? {
|
|
151
|
+
TableRow: TableRowComponent,
|
|
152
|
+
}:{}),
|
|
142
153
|
...defaultObj(components),
|
|
143
154
|
}}
|
|
144
155
|
/>
|
|
@@ -147,7 +158,10 @@ const VirtuosoListComponent = React.forwardRef(({onRender,listClassName,componen
|
|
|
147
158
|
|
|
148
159
|
VirtuosoListComponent.propTypes = {
|
|
149
160
|
...propTypes,
|
|
161
|
+
fixedHeaderContent : PropTypes.func,//la fonction rendant le contenu fixe du tableau
|
|
162
|
+
renderTable : PropTypes.bool,//si le composant Table sera rendu
|
|
150
163
|
numColumns : PropTypes.number,
|
|
164
|
+
rowProps : PropTypes.object,//les props du TableRow, lorsque le rendu est de type table
|
|
151
165
|
items : PropTypes.oneOfType([
|
|
152
166
|
PropTypes.object,
|
|
153
167
|
PropTypes.array,
|
|
@@ -202,7 +216,7 @@ const normalizeEvent = (e)=>{
|
|
|
202
216
|
},[windowWidth,numColumns]);
|
|
203
217
|
const style = width && {width} || grid.col(windowWidth);
|
|
204
218
|
const dataIntex = "index" in props ? props.index : "data-index" in props ? props["data-index"] : ""
|
|
205
|
-
const dataItemIndex = props["data-item-index"];
|
|
219
|
+
const dataItemIndex = "data-item-index" in props ? props["data-item-index"] : "";
|
|
206
220
|
if(isObj(style)){
|
|
207
221
|
style.paddingRight = style.paddingLeft = style.paddingHorizontal = undefined;
|
|
208
222
|
}
|
|
@@ -232,4 +246,11 @@ const normalizeEvent = (e)=>{
|
|
|
232
246
|
.${gridClassName}{display:flex;flex-direction:row;align-items:flex-start;flex-wrap:wrap;justify-content:flex-start;};
|
|
233
247
|
`;
|
|
234
248
|
document.body.appendChild(style);
|
|
235
|
-
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export const TableRowComponent = ({testID,style,...props}) => {
|
|
252
|
+
const index = props['data-index'];
|
|
253
|
+
const isOdd = typeof index =='number' ? index%2 > 0 : false;
|
|
254
|
+
testID = defaultStr(testID,"_VirtuosoTableRow_"+index);
|
|
255
|
+
return <tr data-test-id={testID} {...props} style={StyleSheet.flatten(style)} className={classNames(props.className,"virtuoso-table-row",`table-row-${isOdd?"odd":"even"}`)}/>
|
|
256
|
+
};
|
|
@@ -2,4 +2,9 @@
|
|
|
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
|
-
export {default} from "$ecomponents/List/FlashList";
|
|
5
|
+
export {default} from "$ecomponents/List/FlashList";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export const TableRowComponent = ({children}) => {
|
|
9
|
+
return children;
|
|
10
|
+
};
|
|
@@ -4,13 +4,21 @@
|
|
|
4
4
|
import React from "$react";
|
|
5
5
|
import { View } from "react-native";
|
|
6
6
|
import PropTypes from "prop-types";
|
|
7
|
-
|
|
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}){
|
|
8
14
|
const children = React.useMemo(()=>{
|
|
9
15
|
return cChildren;
|
|
10
16
|
},[cChildren]);
|
|
11
|
-
|
|
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'}])}>
|
|
12
20
|
{children}
|
|
13
|
-
</
|
|
21
|
+
</Component>
|
|
14
22
|
}
|
|
15
23
|
|
|
16
24
|
TableFiltersComponent.propTypes = {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "$react";
|
|
2
|
+
import {classNames} from "$cutils";
|
|
3
|
+
import theme from "$theme";
|
|
4
|
+
|
|
5
|
+
import { StyleSheet } from "react-native";
|
|
6
|
+
const TableHeaderCellComponent = React.forwardRef(({columnDef,className,width,style,children,...props},ref)=>{
|
|
7
|
+
return <th ref={ref} className={classNames(className,"table-header-cell")} children={children} style={StyleSheet.flatten([style])}/>
|
|
8
|
+
});
|
|
9
|
+
TableHeaderCellComponent.displayName = "TableTableHeaderCellComponent";
|
|
10
|
+
export default TableHeaderCellComponent;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import View from "$ecomponents/View";
|
|
2
|
+
import React from "$react";
|
|
3
|
+
const TableHeaderCellComponent = React.forwardRef(({width,style,...props},ref)=>{
|
|
4
|
+
return <View ref={ref} {...props} style={[style,width && {width}]}/>
|
|
5
|
+
});
|
|
6
|
+
TableHeaderCellComponent.displayName = "TableTableHeaderCellComponent";
|
|
7
|
+
export default TableHeaderCellComponent;
|
|
@@ -1,7 +1,3 @@
|
|
|
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
1
|
// Copyright 2023 @fto-consult/Boris Fouomene. All rights reserved.
|
|
6
2
|
// Use of this source code is governed by a BSD-style
|
|
7
3
|
// license that can be found in the LICENSE file.
|