@fto-consult/expo-ui 6.25.0 → 6.25.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@FTO-CONSULT/EXPO-UI",
3
- "version": "6.24.2",
3
+ "version": "6.25.2",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "bin": {
6
6
  "expo-ui": "./bin/index.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "6.25.0",
3
+ "version": "6.25.2",
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.27.0",
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.13",
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
- this.setIsLoading(true,()=>{
959
+ const call = ()=>{
960
960
  this.prepareData({data:this.INITIAL_STATE.data,updateFooters:false},(state)=>{
961
961
  this.setState(state);
962
962
  });
963
- },true);
963
+ };
964
+ const max = isMobileOrTabletMedia()? 200 : 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(){
@@ -113,7 +113,8 @@ export const ROW_BORDER_STYLE = {
113
113
  borderRightColor : ROW_BORDER_COLOR,
114
114
  borderRightWidth : 0,
115
115
  borderTopColor : ROW_BORDER_COLOR,
116
- borderTopWidth : 0
116
+ borderTopWidth : 0,
117
+ borderStyle : "solid",
117
118
  }
118
119
 
119
120
 
@@ -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 <>{children}</>
93
+ return children;
90
94
  }
91
- return <View ref = {ref} selectable={defaultSelectable} {...rest} {...restProps} testID = {testID} style={[bold?styles.bold:null,r2,style,r1]} disabled={disabled} pointerEvents={disabled?'none':'auto'}>{children}</View>
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,a)=>{
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>
@@ -1,7 +1,8 @@
1
1
  import View from "$ecomponents/View";
2
2
  import React from "$react";
3
+ import styles from "../../styles";
3
4
  const TableHeaderCellComponent = React.forwardRef(({width,style,...props},ref)=>{
4
- return <View ref={ref} {...props} style={[style,width && {width}]}/>
5
+ return <View ref={ref} {...props} style={[styles.cell,style,width && {width}]}/>
5
6
  });
6
7
  TableHeaderCellComponent.displayName = "TableTableHeaderCellComponent";
7
8
  export default TableHeaderCellComponent;
@@ -0,0 +1,22 @@
1
+ import React from "$react";
2
+ import Cell from "./Cell";
3
+ import useTable from "../useTable";
4
+ import Label from "$ecomponents/Label";
5
+ import {defaultVal} from "$cutils";
6
+ import theme from "$theme";
7
+ import styles from "../styles";
8
+
9
+ export default function TableCellMainHeaderComponent({columnField,columnDef,style,colArgs,...props}){
10
+ const {sortedColumn,renderHeaderCell,colsWidths} = useTable();
11
+ const width = colsWidths[columnField];
12
+ const isSelectableColumnName = columnDef.isSelectableColumnName;
13
+ const children = React.useMemo(()=>{
14
+ const content = typeof renderHeaderCell =='function'? renderHeaderCell(colArgs) : defaultVal(columnDef.text,columnDef.label,columnField);
15
+ if(!React.isValidElement(content,true)){
16
+ console.error(content," is not valid element of header ",columnDef," it could not be render on table");
17
+ return null;
18
+ }
19
+ return <Label splitText numberOfLines={1} style={[theme.styles.w100,theme.styles.h100,{maxHeight:70},width&&{width}]} textBold primary>{content}</Label>
20
+ },[sortedColumn,columnField])
21
+ return <Cell {...props} style={[styles.headerItem,style]} children={children}/>
22
+ }
@@ -3,10 +3,47 @@
3
3
  // license that can be found in the LICENSE file.
4
4
 
5
5
  import Cell from "./Cell";
6
- import RowHeaderComponent from "./Header";
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,defaultObj} from "$cutils";
12
+ const isNative = isMobileNative();
13
+ const Component = isNative ? View : "tr";
14
+ import { useTable } from "../hooks";
15
+ import styles from "../styles";
16
+ import CellHeader from "./CellHeader";
17
+
18
+ export default function RowHeaderComponent({isFilter,isFooter,isHeader,className,children:cChildren,...rest}){
19
+ const {showHeaders,visibleColsNames,visibleColsNamesStr,headerContainerProps,footerContainerProps,filtersContainerProps,showFilters,footers,headers,filters,showFooters} = useTable();
20
+ const canV = showHeaders === false ? false : Array.isArray(children)? !!children.length : true;
21
+ const visible = canV && (isHeader ? true : isFilter ? !!showFilters : isFooter ? !!showFooters: true);
22
+ const containerProps = defaultObj( isHeader ? headerContainerProps : isFooter ? footerContainerProps : filtersContainerProps);
23
+ const style = filters ? styles.filters : isFooter ? styles.footer : null;
24
+ const children = React.useMemo(()=>{
25
+ const contents = isFilter ? filters : isFooter ? footers : headers;
26
+ return visibleColsNames.map((columnField,cIndex)=>{
27
+ return contents[columnField] || null;
28
+ });
29
+ },[visibleColsNamesStr]);
30
+ const rP = isNative ? rest : {className:classNames(className,"table-footer-or-header-row")}
31
+ return <Component {...rP} {...containerProps} style={StyleSheet.flatten([styles.header,style,rest.style,containerProps.style,!visible && hStyle.hidden])}>
32
+ {children}
33
+ </Component>
34
+ }
35
+
36
+ RowHeaderComponent.propTypes = {
37
+ visible : PropTypes.bool,
38
+ }
7
39
 
8
40
  export {Cell};
9
41
 
10
42
  RowHeaderComponent.Cell = Cell;
43
+ RowHeaderComponent.CellHeader = CellHeader;
44
+
45
+ export {CellHeader};
11
46
 
12
- export default RowHeaderComponent;
47
+ const hStyle = StyleSheet.create({
48
+ hidden : {height:0,opacity:0,display:'none'}
49
+ });
@@ -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 theme from "$theme";
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";
@@ -3,10 +3,11 @@
3
3
  // license that can be found in the LICENSE file.
4
4
  import React from "react";
5
5
  import View from "$ecomponents/View";
6
- import { StyleSheet } from "react-native";
7
-
8
- function TableCellContentComponent({children,style,colSpan,...rest}){
9
- return (<View testID={"RN_TableRowCellContentComponent"} {...rest} style={StyleSheet.flatten(style)}>
6
+ import {useTable} from "../../hooks";
7
+ function TableCellContentComponent({children,columnField,style,colSpan,...rest}){
8
+ const {colsWidths} = useTable();
9
+ const width = columnField ? colsWidths[columnField] : 0;
10
+ return (<View testID={"RN_TableRowCellContentComponent"} {...rest} style={[style,width && {width}]}>
10
11
  {children}
11
12
  </View>);
12
13
  }
@@ -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
- const TableRowCellComponent = React.forwardRef(({children,rowData,colSpan,isSectionListHeader,rowIndex,style,...rest},ref)=>{
6
+ import styles from "../../styles";
7
+ const TableRowCellComponent = React.forwardRef(({children,columnDef,columnField,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,columnField,rowData,rowIndex,containerProps : {}};
15
16
  const r = typeof renderCell =='function' && renderCell (rArgs) || children;
16
17
  return {
17
- content : typeof r =='string' || typeof r =='number' && r ? <Label children={r}/> : React.isValidElement(r)? r : children,
18
+ content : r && React.isValidElement(r,true)? r : children,
18
19
  containerProps : defaultObj(rArgs.containerProps)
19
20
  }
20
21
  },[children]);
21
- return (<CellContent ref={ref} {...containerProps} style={[style,containerProps.style]} >
22
- {content}
22
+ return (<CellContent ref={ref} {...containerProps} columnField={columnField} style={[style,containerProps.style]} >
23
+ {columnDef.isSelectableColumnName ? content : <Label testID="RN_TableRowCell" style={[styles.cell]}>{content}</Label>}
23
24
  </CellContent>);
24
25
  });
25
26
 
@@ -1,8 +1,17 @@
1
- import { forwardRef } from "react";
2
- import View from "$ecomponents/View"
1
+ import { forwardRef,useMemo } from "react";
2
+ import View from "$ecomponents/View";
3
+ import styles from "../styles";
4
+ import { useTable } from "../hooks";
5
+ import {useIsRowSelected} from "$ecomponents/Datagrid/hooks";
6
+ import { getRowStyle } from "$ecomponents/Datagrid/utils";
3
7
 
4
8
  const TableRowWrapperComponent = forwardRef(({children,colSpan,...props},ref)=>{
5
- return <View ref={ref} {...props} children={children}/>
9
+ const {bordered,withDatagridContext} = useTable();
10
+ const selected = withDatagridContext ? useIsRowSelected(props) : false;
11
+ const rowStyle = useMemo(()=>{
12
+ return getRowStyle({...props,bordered});
13
+ },[selected])
14
+ return <View ref={ref} {...props} style={[styles.row,rowStyle,props.style]} children={children}/>
6
15
  });
7
16
 
8
17
  TableRowWrapperComponent.displayName = "TableRowWrapperComponent";
@@ -11,7 +11,8 @@ import RowWrapper from "./RowWrapper";
11
11
  import React from "$react";
12
12
  import theme from "$theme";
13
13
  export default function TableRowComponent({cells,rowKey,rowData,index,...rest}){
14
- const {visibleColsNames,renderItem,renderSectionHeader,columns} = useTable();
14
+ const {visibleColsNames,visibleColsNamesStr,renderSectionHeader,columns} = useTable();
15
+ if(!isObj(rowData)) return null;
15
16
  const content = React.useMemo(()=>{
16
17
  if(rowData.isSectionListHeader && typeof renderSectionHeader ==='function'){
17
18
  return <RowWrapper style={[styles.row,theme.styles.pv1]}>
@@ -21,10 +22,10 @@ export default function TableRowComponent({cells,rowKey,rowData,index,...rest}){
21
22
  return visibleColsNames.map((columnField,cIndex)=>{
22
23
  const columnDef = columns[columnField];
23
24
  if(!isObj(columnDef)) return null;
24
- return <Cell rowData={rowData} rowKey={rowKey} children={columnDef[columnField]} rowIndex={index} columnDef={columnDef} index={cIndex} key={columnField} columnField={columnField}/>
25
+ return <Cell rowData={rowData} rowKey={rowKey} children={rowData[columnField]} rowIndex={index} columnDef={columnDef} index={cIndex} key={columnField} columnField={columnField}/>
25
26
  });
26
- },[rowKey,index,JSON.stringify(visibleColsNames)]);
27
- return <RowWrapper style={[styles.row]}>
27
+ },[rowKey,index,visibleColsNamesStr]);
28
+ return <RowWrapper {...rest} rowKey={rowKey} rowData={rowData} rowIndex={index} style={[styles.row]}>
28
29
  {content}
29
30
  </RowWrapper>;
30
31
  }
@@ -1,16 +1,15 @@
1
- import React,{useMemo,useContext,createContext} from "$react";
1
+ import React,{useMemo} from "$react";
2
2
  import {defaultStr,isObj} from "$cutils";
3
3
  import {DEFAULT_COLUMN_WIDTH} from "./utils";
4
4
  import Label from "$ecomponents/Label";
5
5
  import HeaderCell from "./Header/Cell";
6
- import { StyleSheet } from "react-native";
6
+ import MainHeaderCell from "./Header/CellHeader";
7
7
  import styles from "./styles";
8
- import theme from "$theme";
9
8
 
10
- export const usePrepareColumns = ({columns,sortedColumn,forceRender,testID,renderFooterCell,renderHeaderCell,renderFilterCell,columnsWidths,headerCellContainerProps,colsWidths,columnProps,footers,footerCellContainerProps,filterCellContainerProps})=>{
9
+ export const usePrepareColumns = ({columns,forceRender,testID,renderFooterCell,renderHeaderCell,renderFilterCell,columnsWidths,headerCellContainerProps,colsWidths,columnProps,footers,footerCellContainerProps,filterCellContainerProps})=>{
11
10
  return useMemo(()=>{
12
11
  testID = defaultStr(testID,"RN_TableColumns")
13
- const cols = {},headers = {},footers = {},filters = {},visibleColsNames = [],columnsVisibilities=[],columnsNames = [];
12
+ const cols = {},headers = {},footers = {},filters = {},visibleColsNames = [],columnsVisibilities=[],columnsNames = [],colsWidths={};
14
13
  let hasFooters = false;
15
14
  columnProps = defaultObj(columnProps);
16
15
  let columnIndex = 0;
@@ -18,27 +17,22 @@ export const usePrepareColumns = ({columns,sortedColumn,forceRender,testID,rende
18
17
  headerCellContainerProps = defaultObj(headerCellContainerProps);
19
18
  footerCellContainerProps = defaultObj(footerCellContainerProps);
20
19
  filterCellContainerProps = defaultObj(filterCellContainerProps);
20
+ let totalWidths = 0;
21
21
  Object.map(columns,(columnDef,field)=>{
22
22
  if(!isObj(columnDef)) return;
23
23
  const columnField = defaultStr(columnDef.field,field);
24
24
  let {visible,width,type,style} = columnDef;
25
25
  visible = typeof visible =='boolean'? visible : true;
26
26
  type = defaultStr(type,"text").toLowerCase().trim();
27
- width = defaultDecimal(widths[columnField],width,DEFAULT_COLUMN_WIDTH);
27
+ width = colsWidths[columnField] = defaultDecimal(widths[columnField],width,DEFAULT_COLUMN_WIDTH);
28
28
  const colArgs = {width,type,columnDef,containerProps:{},columnField,index:columnIndex,columnIndex};
29
- const content = typeof renderHeaderCell =='function'? renderHeaderCell(colArgs) : defaultVal(columnDef.text,columnDef.label,columnField);
30
29
  const hContainerProps = defaultObj(colArgs.containerProps);
31
- if(!React.isValidElement(content,true)){
32
- console.error(content," is not valid element of header ",columnDef," it could not be render on table");
33
- return null;
34
- }
30
+ totalWidths+=width;
35
31
  const rArgs = {columnDef,width};
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={2} style={[theme.styles.w100,theme.styles.h100,{maxHeight:70}]} textBold primary>{content}</Label>
38
- </HeaderCell>;
32
+ headers[columnField] = <MainHeaderCell colArgs={colArgs} {...rArgs} columnField={columnField} width={width} testID={testID+"_HeaderCell_"+columnField} {...headerCellContainerProps} {...hContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,headerCellContainerProps.style,hContainerProps.style,style]}/>
39
33
  if(typeof renderFilterCell =='function'){
40
34
  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]}>
35
+ filters[columnField] = <HeaderCell {...rArgs} width={width} testID={testID+"_Filter_Cell_"+columnField} {...filterCellContainerProps} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,styles.filterCell,filterCellContainerProps.style,styles.cell,style]}>
42
36
  {React.isValidElement(filterCell)? filterCell : null}
43
37
  </HeaderCell>
44
38
  }
@@ -56,7 +50,7 @@ export const usePrepareColumns = ({columns,sortedColumn,forceRender,testID,rende
56
50
  if(!hasFooters && cellFooter){
57
51
  hasFooters = true;
58
52
  }
59
- footers[columnField] = <HeaderCell {...rArgs} testID={testID+"_Footer_Cell_"+columnField} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,footerCellContainerProps.style,style]}>
53
+ footers[columnField] = <HeaderCell {...rArgs} width={width} testID={testID+"_Footer_Cell_"+columnField} key={columnField} style={[styles.headerItem,styles.headerItemOrCell,footerCellContainerProps.style,style]}>
60
54
  <Label primary children={cellFooter}/>
61
55
  </HeaderCell>
62
56
  }
@@ -75,10 +69,11 @@ export const usePrepareColumns = ({columns,sortedColumn,forceRender,testID,rende
75
69
  };
76
70
  columnIndex++;
77
71
  });
78
- return {columns:cols,columnsNames,headers,columnsVisibilities,visibleColsNames,hasFooters,footers,filters};
79
- },[columns,sortedColumn,footers,forceRender]);
72
+ return {columns:cols,columnsNames,headers,colsWidths,columnsVisibilities,totalWidths,totalColsWidths:totalWidths,visibleColsNamesStr:JSON.stringify(visibleColsNames),visibleColsNames,hasFooters,footers,filters};
73
+ },[columns,footers,forceRender]);
80
74
  }
81
75
 
82
- export const TableContext = createContext(null);
83
76
 
84
- export const useTable = ()=> useContext(TableContext);
77
+ export {default as useTable} from "./useTable";
78
+
79
+ export * from "./useTable";
@@ -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 FiltersOrFooters from "./FiltersOrFooters";
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 VituosoTableComonent from "./VirtuosoTable";
17
+ import VirtuosoTableComponent from "./VirtuosoTable";
18
18
  export {styles};
19
19
 
20
20
  const isSCrollingRef = React.createRef();
@@ -51,7 +51,7 @@ const getOnScrollCb = (refs,pos,cb2)=>{
51
51
  return isMobileNative()? cb : debounce(cb,200);
52
52
  }
53
53
 
54
- const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRender,height,progressBar,renderListContent,children,renderEmpty,renderItem,isRowSelected,headerScrollViewProps,footerScrollViewProps,scrollViewProps,showFooters,renderFooterCell,footerCellContainerProps,filterCellContainerProps,headerContainerProps,headerCellContainerProps,headerProps,rowProps:customRowProps,cellContainerProps,hasFooters,renderHeaderCell,renderFilterCell,columnProps,getRowKey,columnsWidths,colsWidths,footerContainerProps,showHeaders,showFilters,columns,...props},tableRef)=>{
54
+ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRender,height,progressBar,renderListContent,children,renderEmpty,renderItem,isRowSelected,headerScrollViewProps,footerScrollViewProps,scrollViewProps,renderFooterCell,footerCellContainerProps,filterCellContainerProps,headerCellContainerProps,headerProps,rowProps:customRowProps,cellContainerProps,hasFooters,renderHeaderCell,renderFilterCell,columnProps,getRowKey,columnsWidths,colsWidths,columns,...props},tableRef)=>{
55
55
  containerProps = defaultObj(containerProps);
56
56
  cellContainerProps = defaultObj(cellContainerProps);
57
57
  scrollViewProps = defaultObj(scrollViewProps);
@@ -59,39 +59,23 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
59
59
  footerScrollViewProps = defaultObj(footerScrollViewProps);
60
60
  const listRef = React.useRef(null),scrollViewRef = React.useRef(null),headerScrollViewRef = React.useRef(null);
61
61
  const layoutRef = React.useRef({});
62
- const {columns:cols,testID,headers,footers,getItem,withDatagridContext,filters,getRowByIndex,itemsChanged,hasFooters:stateHasFooters,visibleColsNames,keyExtractor,items,data} = useTable();
63
- headerContainerProps = defaultObj(headerContainerProps);
64
- footerContainerProps = defaultObj(footerContainerProps);
65
- const emptyData = renderListContent === false ?null : typeof renderEmpty =='function' && !Object.size(data,true)? renderEmpty() : null;
62
+ const {testID,withDatagridContext,filters,getRowByIndex,itemsChanged,hasFooters:stateHasFooters,bordered,totalWidths,keyExtractor,items,data} = useTable();
63
+ const hasData = !!Object.size(data,true);
64
+ const emptyData = !hasData && renderListContent === false ?null : typeof renderEmpty =='function' ? renderEmpty() : null;
66
65
  const hasEmptyData = emptyData && React.isValidElement(emptyData);
67
-
68
- const {fFilters,headersContent,footersContent,totalWidths} = React.useMemo(()=>{
69
- const headersContent = [],footersContent = [],fFilters = [];
70
- let totalWidths = 0;
71
- visibleColsNames.map((i,index)=>{
72
- headersContent.push(headers[i]);
73
- totalWidths+=cols[i].width;
74
- if(showFooters && stateHasFooters){
75
- footersContent.push(footers[i]);
76
- }
77
- if(showFilters && filters[i]){
78
- fFilters.push(filters[i]);
79
- }
80
- });
81
-
82
- return {headersContent,totalWidths,footersContent,fFilters};
83
- },[visibleColsNames,showFilters,showFooters,layoutRef.current]);
84
-
85
-
66
+ const emptyContent = <View onRender={onComponentRender} testID={testID+"_EmptyData"} style={styles.hasNotData}>
67
+ {emptyData}
68
+ </View>
86
69
  const scrollContentContainerStyle = {flex:1,width:listWidth,minWidth:totalWidths,height:'100%'};
87
70
  const scrollEventThrottle = isMobileNative()?200:50;
88
71
  const scrollViewFlexGrow = {flexGrow:0};
89
- const maxScrollheight = footersContent.length && fFilters.length ? 170 : footersContent.length ?120 : fFilters.length ? 140 : 80;
72
+ const maxScrollheight = 170;//footersContent.length && fFilters.length ? 170 : footersContent.length ?120 : fFilters.length ? 140 : 80;
90
73
  const allScrollViewProps = {
91
74
  scrollEventThrottle,
92
75
  horizontal : true,
93
76
  ...scrollViewProps,
94
- style : [{maxHeight:maxScrollheight},scrollViewProps.style],
77
+ style : [{maxHeight:maxScrollheight},
78
+ scrollViewProps.style],
95
79
  contentContainerStyle : [styles.scrollView,scrollViewProps.contentContainerStyle,scrollViewFlexGrow,scrollContentContainerStyle]
96
80
  }
97
81
  const listWidth = '100%';
@@ -125,7 +109,6 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
125
109
  get scrollViewContext(){ return scrollViewRef.current},
126
110
  get headerScrollViewContext(){return headerScrollViewRef.current},
127
111
  }
128
- const showTableHeaders = showHeaders !== false || showFilters ;
129
112
  const absoluteScrollViewRefCanScroll = React.useRef(true);
130
113
  React.setRef(tableRef,context);
131
114
  const cStyle = {width:listWidth}
@@ -159,15 +142,9 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
159
142
  }
160
143
  };
161
144
  const headerFootersFilters = <>
162
- <FiltersOrFooters visible={!!(showTableHeaders && headersContent.length)} testID={testID+"_Header"} {...headerContainerProps} style={[styles.header,headerContainerProps.style,footersContent.length]}>
163
- {headersContent}
164
- </FiltersOrFooters>
165
- <FiltersOrFooters visible = {!!fFilters.length} testID={testID+"_Filters"} style={[styles.header,styles.footers,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}>
166
- {fFilters}
167
- </FiltersOrFooters>
168
- <FiltersOrFooters visible={!!(showTableHeaders && footersContent.length)} testID={testID+"_Footer"} {...footerContainerProps} style={[styles.header,styles.footers,footerContainerProps.style,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}>
169
- {footersContent}
170
- </FiltersOrFooters>
145
+ <Header isHeader={true} testID={testID+"_Header"}/>
146
+ <Header isFilter={true} testID={testID+"_Filters"} style={[styles.header,styles.footers,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}/>
147
+ <Header isFooter testID={testID+"_Footer"} style={[styles.header,styles.footers,theme.styles.pt0,theme.styles.pb0,theme.styles.ml0,theme.styles.mr0]}/>
171
148
  </>
172
149
  return <View testID= {testID+"_Container"} {...containerProps} onLayout={(e)=>{
173
150
  layoutRef.current = e.nativeEvent.layout;
@@ -191,9 +168,7 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
191
168
  </View>
192
169
  </ScrollView>
193
170
  </RNView>}
194
- {hasEmptyData ? <View onRender={onComponentRender} testID={testID+"_Empty"} style={styles.hasNotData}>
195
- {emptyData}
196
- </View> : <ScrollNative {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle,{height:'100%'}]} showsVerticalScrollIndicator={false}
171
+ {hasEmptyData && isNative ? emptyContent : <ScrollNative {...scrollViewProps} scrollEventThrottle = {scrollEventThrottle} horizontal contentContainerStyle={[scrollContentContainerStyle,scrollViewProps.contentContainerStyle,{height:'100%'}]} showsVerticalScrollIndicator={false}
197
172
  onScroll = {getOnScrollCb([headerScrollViewRef,footerScrollViewRef],null,(args)=>{
198
173
  const nativeEvent = args.nativeEvent;
199
174
  if(absoluteScrollViewRef.current && absoluteScrollViewRef.current.checkVisibility){
@@ -277,11 +252,11 @@ const TableComponent = React.forwardRef(({containerProps,listContainerStyle,onRe
277
252
  const index = props['data-index'];
278
253
  const item = getRowByIndex(index) || props?.item || null;
279
254
  if(!item) return null;
280
- const args = {rowData:item,rowIndex:index,bordered:true,isTable:true};
255
+ const args = {rowData:item,rowIndex:index,bordered,isTable:true};
281
256
  args.isSelected = withDatagridContext ? isRowSelected(args) : false;
282
257
  return <TableRowComponent {...props} style={[getRowStyle(args),props.style]}/>
283
258
  },
284
- Table: VituosoTableComonent,
259
+ Table: VirtuosoTableComponent,
285
260
  }}
286
261
  />
287
262
  {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 : 10,
15
+ paddingLeft : 0,
15
16
  paddingRight : 0,
16
17
  flex : 1,
17
18
  position : 'relative',
@@ -31,6 +32,13 @@ const styles = StyleSheet.create({
31
32
  paddingVertical : 7,
32
33
  alignItems : 'center',
33
34
  width : '100%',
35
+ minHeight : 40,
36
+ },
37
+ filters : {
38
+ height : 50,
39
+ },
40
+ footers : {
41
+ minHeight : 40,
34
42
  },
35
43
  footerContainer : {
36
44
  width : '100%',
@@ -70,7 +78,7 @@ const styles = StyleSheet.create({
70
78
  row : {
71
79
  flexDirection : "row",
72
80
  justifyContent : "flex-start",
73
- alignItems : 'flex-start',
81
+ alignItems : 'center',
74
82
  width : '100%',
75
83
  },
76
84
  rowNoPadding : {
@@ -83,6 +91,21 @@ const styles = StyleSheet.create({
83
91
  width : '100%',
84
92
  justifyContent : 'center',
85
93
  alignItems : 'center'
94
+ },
95
+ cell : isMobileNative()? {
96
+ paddingLeft:10,
97
+ paddingRight : 5,
98
+ paddingBottom : 2,
99
+ paddingTop : 2,
100
+ } : {
101
+ paddingLeft: 10,
102
+ paddingTop:5,
103
+ paddingBottom:5,
104
+ paddingRight: 10
105
+ },
106
+ sectionListHeader : {
107
+ paddingVertical : 10,
108
+ paddingHorizontal : 10,
86
109
  }
87
110
  });
88
111
  export default styles;
@@ -0,0 +1,7 @@
1
+ import {createContext,useContext} from "react";
2
+
3
+ export const TableContext = createContext(null);
4
+
5
+ const useTable = ()=> useContext(TableContext);
6
+
7
+ export default useTable;
@@ -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
- ...(isObj(r) ? r : theme),
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 +1 @@
1
- module.exports = {"@fto-consult/expo-ui":{"name":"@fto-consult/expo-ui","version":"6.24.2","repository":{"type":"git","url":"git+https://github.com/borispipo/expo-ui.git"},"homepage":"https://github.com/borispipo/expo-ui#readme"}};
1
+ module.exports = {"@FTO-CONSULT/EXPO-UI":{"name":"@FTO-CONSULT/EXPO-UI","version":"6.25.2","homepage":"https://github.com/borispipo/expo-ui#readme"}};
@@ -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
- }