@fto-consult/expo-ui 2.5.0 → 2.5.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/package.json +1 -1
- package/src/components/BottomSheet/Menu.js +4 -2
- package/src/components/Datagrid/Accordion/index.js +6 -5
- package/src/components/Datagrid/Common/Common.js +26 -11
- package/src/components/Datagrid/Footer/Footer.js +10 -12
- package/src/components/Datagrid/Table/index.js +29 -42
- package/src/components/Date/DatePickerInput/index.js +1 -1
- package/src/components/Date/DateTime.js +11 -6
- package/src/components/Date/Time.js +5 -1
- package/src/components/DragResize/Connector.js +132 -0
- package/src/components/DragResize/DragResizeBlock.js +809 -0
- package/src/components/DragResize/DragResizeContainer.js +52 -0
- package/src/components/DragResize/index.js +42 -0
- package/src/components/Dropdown/index.js +4 -5
- package/src/components/Filter/index.js +16 -8
- package/src/components/Resizable/index.js +7 -0
- package/src/components/Resizable/index.web.js +33 -0
- package/src/components/Table/AbsoluteScrollView.js +38 -10
- package/src/components/Table/index.js +78 -30
- package/src/components/TextField/index.js +2 -2
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ import PropTypes from "prop-types";
|
|
|
8
8
|
import {getContentHeight} from "./utils";
|
|
9
9
|
|
|
10
10
|
const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
11
|
-
let {anchor,screenIndent,height:customHeight,bindResizeEvent,onDismiss,testID,visible:customVisible,controlled,mobile,animateOnClose,renderMenuContent,sheet,children,...rest} = props;
|
|
11
|
+
let {anchor,anchorProps,screenIndent,height:customHeight,bindResizeEvent,onDismiss,testID,visible:customVisible,controlled,mobile,animateOnClose,renderMenuContent,sheet,children,...rest} = props;
|
|
12
12
|
rest = defaultObj(rest);
|
|
13
13
|
const isControlled = controlled ? true : false;
|
|
14
14
|
const visibleRef = React.useRef(null);
|
|
@@ -44,12 +44,13 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
44
44
|
setState({...state,visible:false})
|
|
45
45
|
}
|
|
46
46
|
const Component = isMob ? BottomSheet : Menu;
|
|
47
|
+
anchorProps = defaultObj(anchorProps);
|
|
47
48
|
if(isMob){
|
|
48
49
|
if(typeof anchor ==='function'){
|
|
49
50
|
anchor = anchor(!isControlled?{onPress:open}:{});
|
|
50
51
|
}
|
|
51
52
|
if(React.isValidElement(anchor)){
|
|
52
|
-
anchor = <View testID={testID+"_Anchor"} ref={anchorRef} collapsable={false}>{anchor}</View>
|
|
53
|
+
anchor = <View testID={testID+"_Anchor"} ref={anchorRef} {...anchorProps} collapsable={false}>{anchor}</View>
|
|
53
54
|
}
|
|
54
55
|
if(renderMenuContent !== false){
|
|
55
56
|
children = renderItems({testID:testID+".Items",...props,closeMenu:close,openMenu:open,isBottomSheetItem:true});
|
|
@@ -101,6 +102,7 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
|
|
|
101
102
|
height = {controlled?customHeight:height}
|
|
102
103
|
ref = {React.useMergeRefs(innerRef,ref)}
|
|
103
104
|
anchor = {anchor}
|
|
105
|
+
anchorProps = {anchorProps}
|
|
104
106
|
children = {visible && (React.isValidElement(children) || Array.isArray(children))?children:undefined}
|
|
105
107
|
/>
|
|
106
108
|
</>
|
|
@@ -385,7 +385,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
385
385
|
if(toggleFilters === false){
|
|
386
386
|
filters = false;
|
|
387
387
|
}
|
|
388
|
-
let {showFilters,
|
|
388
|
+
let {showFilters,showFooters} = this.state;
|
|
389
389
|
let max = this.getMaxSelectableRows();
|
|
390
390
|
let restItems = [];
|
|
391
391
|
|
|
@@ -499,9 +499,9 @@ const DatagridFactory = (Factory)=>{
|
|
|
499
499
|
closeOnPress : false,
|
|
500
500
|
} : null,
|
|
501
501
|
hasFooterFields ? {
|
|
502
|
-
onPress : ()=>{
|
|
503
|
-
,icon :
|
|
504
|
-
,text : (
|
|
502
|
+
onPress : ()=>{showFooters?this.hideFooter():this.showFooters()}
|
|
503
|
+
,icon : showFooters?'view-column':'view-module'
|
|
504
|
+
,text : (showFooters?'Masquer/Ligne des totaux':'Afficher/Ligne des totaux')
|
|
505
505
|
}:null,
|
|
506
506
|
...restItems,
|
|
507
507
|
this.canScrollTo() && {
|
|
@@ -557,7 +557,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
557
557
|
/>
|
|
558
558
|
{datagridHeader}
|
|
559
559
|
{_progressBar}
|
|
560
|
-
{
|
|
560
|
+
{showFooters ? (
|
|
561
561
|
<View testID={testID+"_FooterContainer"} pointerEvents={pointerEvents} style={[{justifyContent:'center'}]}>
|
|
562
562
|
<View testID={testID+"_FooterContentContainer"} style={[styles.footersContainer]}>
|
|
563
563
|
<ScrollView testID={testID+"_FooterScrollView"} horizontal contentContainerStyle={[styles.contentContainerStyle]}>
|
|
@@ -567,6 +567,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
567
567
|
key = {field}
|
|
568
568
|
testID={testID+"_FooterItem_"+field}
|
|
569
569
|
{...footer}
|
|
570
|
+
anchorProps = {{style:[theme.styles.ph1,theme.styles.mh05]}}
|
|
570
571
|
/>
|
|
571
572
|
})}
|
|
572
573
|
</View>
|
|
@@ -71,13 +71,13 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
71
71
|
});
|
|
72
72
|
selectedRows = sRows;
|
|
73
73
|
let sData = this.getSessionData()
|
|
74
|
-
sData.
|
|
74
|
+
sData.showFooters = defaultVal(sData.showFooters,true);
|
|
75
75
|
sData.fixedTable = defaultBool(sData.fixedTable,false);
|
|
76
76
|
extendObj(this.state, {
|
|
77
77
|
data,
|
|
78
78
|
sort :defaultObj(props.sort),
|
|
79
79
|
showFilters : defaultBool(props.showFilters,(sData.showFilter? true : this.isPivotDatagrid())),
|
|
80
|
-
|
|
80
|
+
showFooters : defaultBool(props.showFooters,(sData.showFooters? true : false)),
|
|
81
81
|
fixedTable : sData.fixedTable
|
|
82
82
|
});
|
|
83
83
|
Object.defineProperties(this,{
|
|
@@ -784,16 +784,16 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
784
784
|
}
|
|
785
785
|
|
|
786
786
|
|
|
787
|
-
|
|
787
|
+
showFooters(){
|
|
788
788
|
if(!this._isMounted()) {
|
|
789
789
|
this.isUpdating = false;
|
|
790
790
|
return;
|
|
791
791
|
}
|
|
792
792
|
if(this.isUpdating) return false;
|
|
793
793
|
this.isUpdating = true;
|
|
794
|
-
this.setState( {
|
|
794
|
+
this.setState( {showFooters:true},()=>{
|
|
795
795
|
this.isUpdating = false;
|
|
796
|
-
this.setSessionData({
|
|
796
|
+
this.setSessionData({showFooters:true})
|
|
797
797
|
})
|
|
798
798
|
}
|
|
799
799
|
hideFooter (){
|
|
@@ -802,9 +802,9 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
802
802
|
return;
|
|
803
803
|
}
|
|
804
804
|
if(this.isUpdating) return false;
|
|
805
|
-
this.setState({
|
|
805
|
+
this.setState({showFooters:false},()=>{
|
|
806
806
|
this.isUpdating = false;
|
|
807
|
-
this.setSessionData({
|
|
807
|
+
this.setSessionData({showFooters:false});
|
|
808
808
|
})
|
|
809
809
|
}
|
|
810
810
|
|
|
@@ -899,14 +899,18 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
899
899
|
let colFilter = defaultVal(restCol.filter,true);
|
|
900
900
|
field = header.field = defaultStr(header.field,field,headerIndex);
|
|
901
901
|
delete restCol.filter;
|
|
902
|
+
|
|
903
|
+
const type = defaultStr(header.type).toLowerCase();
|
|
904
|
+
sortType = defaultStr(sortType,type).toLowerCase();
|
|
902
905
|
width = defaultDecimal(width);
|
|
903
906
|
if(width <COLUMN_WIDTH/2){
|
|
904
907
|
width = COLUMN_WIDTH;
|
|
905
908
|
}
|
|
906
|
-
const type = defaultStr(header.type).toLowerCase();
|
|
907
|
-
sortType = defaultStr(sortType,type).toLowerCase();
|
|
908
909
|
if(type.contains("date")|| type.contains("time")){
|
|
909
|
-
|
|
910
|
+
const mWidth = type.toLowerCase().contains('datetime')? (DATE_COLUMN_WIDTH+30) : DATE_COLUMN_WIDTH;
|
|
911
|
+
width = Math.max(width,mWidth);
|
|
912
|
+
} else if((type.contains("number") || type.contains("decimal") && this.props.format)){
|
|
913
|
+
width = Math.max(width,DATE_COLUMN_WIDTH-30);
|
|
910
914
|
}
|
|
911
915
|
totalWidths +=width;
|
|
912
916
|
widths[header.field] = width;
|
|
@@ -953,6 +957,17 @@ export default class CommonDatagridComponent extends AppComponent {
|
|
|
953
957
|
delete restCol.sortable;
|
|
954
958
|
filterProps = {
|
|
955
959
|
...restCol,
|
|
960
|
+
columnIndex,
|
|
961
|
+
visibleColumnIndex,
|
|
962
|
+
sortable:isColumnSortable,
|
|
963
|
+
sorted:isColumnSorted,
|
|
964
|
+
sortedColumn :sortedProps,///les props de la columns triée
|
|
965
|
+
sortedProps,
|
|
966
|
+
width,
|
|
967
|
+
columnField : field,
|
|
968
|
+
columnDef : header,
|
|
969
|
+
index : headerIndex,
|
|
970
|
+
visible,
|
|
956
971
|
key : header.field,
|
|
957
972
|
label : defaultStr(header.label,header.text),
|
|
958
973
|
orOperator : filterOrOperator,
|
|
@@ -1710,7 +1725,7 @@ CommonDatagridComponent.propTypes = {
|
|
|
1710
1725
|
/*** affiche ou masque les filtres */
|
|
1711
1726
|
showFilters : PropTypes.bool,
|
|
1712
1727
|
/*** si le pied de page sera affiché */
|
|
1713
|
-
|
|
1728
|
+
showFooters : PropTypes.bool,
|
|
1714
1729
|
/*** les donnnées peuvent être soient retournées par une fonction, soit par un tableau soit une promesse */
|
|
1715
1730
|
data : PropTypes.oneOfType([PropTypes.array, PropTypes.func,PropTypes.object]),//.isRequired,
|
|
1716
1731
|
columns:PropTypes.oneOfType([PropTypes.array,PropTypes.object]),//.isRequired,
|
|
@@ -3,7 +3,7 @@ import Menu from "$ecomponents/BottomSheet/Menu";
|
|
|
3
3
|
import View from "$ecomponents/View";
|
|
4
4
|
import {Pressable,StyleSheet} from "react-native";
|
|
5
5
|
import Label from "$ecomponents/Label";
|
|
6
|
-
import {defaultVal} from "$utils";
|
|
6
|
+
import {defaultVal,defaultObj} from "$utils";
|
|
7
7
|
import React from "$react";
|
|
8
8
|
import theme from "$theme"
|
|
9
9
|
|
|
@@ -18,7 +18,9 @@ const formatValue = ({value,format,method})=>{
|
|
|
18
18
|
return (format === 'money' && method != 'count')? value.formatMoney():value.formatNumber();
|
|
19
19
|
}
|
|
20
20
|
export default function DGGridFooterValue (props){
|
|
21
|
-
let {label,text,displayLabel,style,format} = props;
|
|
21
|
+
let {label,text,displayLabel,style,format,testID,anchorProps} = props;
|
|
22
|
+
anchorProps = defaultObj(anchorProps);
|
|
23
|
+
testID = defaultStr(testID,"RN_DatagridFooterComponent");
|
|
22
24
|
label = defaultVal(label,text);
|
|
23
25
|
const defLabel = label;
|
|
24
26
|
if(displayLabel !== false){
|
|
@@ -50,19 +52,19 @@ export default function DGGridFooterValue (props){
|
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
return <Menu
|
|
55
|
+
testID = {testID+"_Menu"}
|
|
53
56
|
items = {menuItems}
|
|
54
|
-
style = {{minWidth:220}}
|
|
55
57
|
title = {'Totaux de la colonne '+(defLabel?("[ "+defLabel+"]"):'')}
|
|
56
58
|
animateOnClose
|
|
57
59
|
anchor = {(p)=>{
|
|
58
|
-
return <Pressable {...p} style={[styles.anchor,style,label?styles.row:null]} title={title}>
|
|
60
|
+
return <Pressable {...anchorProps} {...p} testID={testID} style={[styles.anchor,anchorProps.style,label?styles.row:null]} title={title}>
|
|
59
61
|
{label ?
|
|
60
62
|
<>
|
|
61
|
-
<View><Label style={[styles.label]}>{label}</Label></View>
|
|
62
|
-
<View><Label style = {styles.label}> : </Label></View>
|
|
63
|
+
<View testID={testID+"_Label"}><Label style={[styles.label]}>{label}</Label></View>
|
|
64
|
+
<View testID={testID+"_LabelPoint"}><Label style = {styles.label}> : </Label></View>
|
|
63
65
|
</>
|
|
64
66
|
: null}
|
|
65
|
-
<Label primary style={[styles.value]}>
|
|
67
|
+
<Label testID={testID+"_LabelContent"} primary style={[styles.value]}>
|
|
66
68
|
{formatValue({value:defaultDecimal(props[active]),method:active,format})}
|
|
67
69
|
</Label>
|
|
68
70
|
</Pressable>
|
|
@@ -75,11 +77,7 @@ const styles = StyleSheet.create({
|
|
|
75
77
|
flexDirection : 'row',
|
|
76
78
|
alignItems : 'center',
|
|
77
79
|
},
|
|
78
|
-
anchor : {
|
|
79
|
-
paddingVertical : 10,
|
|
80
|
-
marginHorizontal : 10,
|
|
81
|
-
paddingHorizontal : 5,
|
|
82
|
-
},
|
|
80
|
+
anchor : {},
|
|
83
81
|
value : {
|
|
84
82
|
fontWeight : 'bold'
|
|
85
83
|
}
|
|
@@ -13,6 +13,7 @@ import React from "$react";
|
|
|
13
13
|
import {Menu as BottomSheetMenu} from "$ecomponents/BottomSheet"
|
|
14
14
|
import RenderType from "../RenderType";
|
|
15
15
|
import Footer from "../Footer/Footer";
|
|
16
|
+
import theme from "$theme";
|
|
16
17
|
import Table from "$ecomponents/Table";
|
|
17
18
|
|
|
18
19
|
|
|
@@ -62,41 +63,23 @@ const DatagridFactory = (Factory)=>{
|
|
|
62
63
|
}
|
|
63
64
|
return null;
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
if(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}}
|
|
81
|
-
/>
|
|
82
|
-
</View>
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return ret;
|
|
86
|
-
}
|
|
87
|
-
beforePrepareColumns(){
|
|
88
|
-
this.customFilteredColumns = {};
|
|
89
|
-
}
|
|
90
|
-
prepareColumn({filterProps,columnField,columnDef,key,field,visible,filter},filters){
|
|
91
|
-
this.customFilteredColumns = defaultObj(this.customFilteredColumns);
|
|
92
|
-
if(visible){
|
|
93
|
-
if(filter){
|
|
94
|
-
this.customFilteredColumns[columnField] = filterProps;
|
|
95
|
-
} else {
|
|
96
|
-
this.customFilteredColumns[columnField] = null;
|
|
97
|
-
}
|
|
66
|
+
renderFilterCell(props){
|
|
67
|
+
const {columnField,style} = props;
|
|
68
|
+
const filterC = this.currentFilteringColumns[columnField];
|
|
69
|
+
if(isObj(filterC)){
|
|
70
|
+
return <Filter
|
|
71
|
+
{...filterC}
|
|
72
|
+
withLabel = {false}
|
|
73
|
+
style = {[styles.filter,theme.styles.pv0,theme.styles.mv0]}
|
|
74
|
+
anchorProps ={{size:20}}
|
|
75
|
+
mode = "flat"
|
|
76
|
+
inputProps = {{
|
|
77
|
+
style : [styles.filter],
|
|
78
|
+
mode : "flat",
|
|
79
|
+
}}
|
|
80
|
+
/>
|
|
98
81
|
}
|
|
99
|
-
return
|
|
82
|
+
return null;
|
|
100
83
|
}
|
|
101
84
|
updateLayout(e){
|
|
102
85
|
if(this.state.fixedTable === false) return;
|
|
@@ -176,7 +159,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
176
159
|
})*/
|
|
177
160
|
const {visibleColumns} = this.preparedColumns;
|
|
178
161
|
const hasFooterFields = this.hasFooterFields();
|
|
179
|
-
const {columnsWidths:widths,showFilters,
|
|
162
|
+
const {columnsWidths:widths,showFilters,showFooters} = this.state;
|
|
180
163
|
let isAllRowsSelected = this.isAllRowsSelected();
|
|
181
164
|
const isLoading = this.isLoading();
|
|
182
165
|
let _progressBar = this.getProgressBar();
|
|
@@ -227,10 +210,10 @@ const DatagridFactory = (Factory)=>{
|
|
|
227
210
|
{hasFooterFields ? <Button
|
|
228
211
|
normal
|
|
229
212
|
style={styles.paginationItem}
|
|
230
|
-
onPress = {()=>{
|
|
231
|
-
icon = {
|
|
213
|
+
onPress = {()=>{showFooters?this.hideFooter():this.showFooters()} }
|
|
214
|
+
icon = {showFooters?'view-column':'view-module'}
|
|
232
215
|
>
|
|
233
|
-
{
|
|
216
|
+
{showFooters?'Masquer/Ligne des totaux':'Afficher/Ligne des totaux'}
|
|
234
217
|
</Button>:null}
|
|
235
218
|
{selectableMultiple && (<>
|
|
236
219
|
{restItems.map((item,index)=>{
|
|
@@ -287,9 +270,9 @@ const DatagridFactory = (Factory)=>{
|
|
|
287
270
|
,text : (showFilters?'Masquer/Filtres':'Afficher/Filtres')
|
|
288
271
|
} : null,
|
|
289
272
|
isMobile && hasFooterFields?{
|
|
290
|
-
onPress : ()=>{
|
|
291
|
-
,icon :
|
|
292
|
-
,text : (
|
|
273
|
+
onPress : ()=>{showFooters?this.hideFooter():this.showFooters()}
|
|
274
|
+
,icon : showFooters?'view-column':'view-module'
|
|
275
|
+
,text : (showFooters?'Masquer/Ligne des totaux':'Afficher/Ligne des totaux')
|
|
293
276
|
} : null,
|
|
294
277
|
...(selectableMultiple ? restItems : [])
|
|
295
278
|
] : visibleColumns}
|
|
@@ -340,7 +323,7 @@ const DatagridFactory = (Factory)=>{
|
|
|
340
323
|
ref = {this.listRef}
|
|
341
324
|
hasFooters = {hasFooterFields}
|
|
342
325
|
showFilters = {showFilters}
|
|
343
|
-
showFooters = {
|
|
326
|
+
showFooters = {showFooters}
|
|
344
327
|
headerContainerProps = {{}}
|
|
345
328
|
headerCellContainerProps = {{
|
|
346
329
|
style : showFilters?{justifyContent:'flex-start'}:null
|
|
@@ -358,7 +341,9 @@ const DatagridFactory = (Factory)=>{
|
|
|
358
341
|
}}
|
|
359
342
|
data = {this.state.data}
|
|
360
343
|
renderHeaderCell={this.renderHeaderCell.bind(this)}
|
|
344
|
+
renderFilterCell={this.renderFilterCell.bind(this)}
|
|
361
345
|
renderFooterCell={this.renderFooterCell.bind(this)}
|
|
346
|
+
renderEmpty = {this.renderEmpty.bind(this)}
|
|
362
347
|
/>
|
|
363
348
|
</View>
|
|
364
349
|
}
|
|
@@ -440,8 +425,10 @@ const styles = StyleSheet.create({
|
|
|
440
425
|
maxHeight : 40,
|
|
441
426
|
height : 40,
|
|
442
427
|
width : "100%",
|
|
428
|
+
alignSelf : 'flex-start',
|
|
443
429
|
flexGrow : 1,
|
|
444
430
|
minHeight : 40,
|
|
431
|
+
backgroundColor : 'transparent'
|
|
445
432
|
},
|
|
446
433
|
layoutContent : {
|
|
447
434
|
maxWidth : '100%',
|
|
@@ -166,7 +166,7 @@ const DatePickerInput = React.forwardRef(({
|
|
|
166
166
|
onChange({dateObject:state.inputDate,date:state.inputDate,sqlDate:date,value:date})
|
|
167
167
|
}
|
|
168
168
|
},[state])
|
|
169
|
-
const labelText = render_filter ? label :
|
|
169
|
+
const labelText = withLabel === false ? null: (render_filter ? label : getLabel({ label, inputFormat:inputFormatLabel, withDateFormatInLabel }));
|
|
170
170
|
return (
|
|
171
171
|
<>
|
|
172
172
|
<TextField
|
|
@@ -13,7 +13,7 @@ import { toDateObj } from "./utils";
|
|
|
13
13
|
import TextField from "$components/TextField";
|
|
14
14
|
import PeriodActionComponent from "./PeriodAction";
|
|
15
15
|
|
|
16
|
-
export default function DateTimePickerComponent({left,isPeriodAction,withSeconds,right,format,dateFormat,timeFormat,defaultValue,onChange,testID,dateProps,disabled,readOnly,timeProps,...rest}){
|
|
16
|
+
export default function DateTimePickerComponent({left,isPeriodAction,contentProps,withSeconds,right,format,dateFormat,timeFormat,defaultValue,onChange,testID,dateProps,disabled,readOnly,timeProps,...rest}){
|
|
17
17
|
if(!isPeriodAction){
|
|
18
18
|
isPeriodAction = isNonNullString(defaultValue) && defaultValue.contains("=>");
|
|
19
19
|
}
|
|
@@ -28,6 +28,7 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
28
28
|
}
|
|
29
29
|
dateProps = defaultObj(dateProps);
|
|
30
30
|
timeProps = defaultObj(timeProps);
|
|
31
|
+
contentProps = defaultObj(contentProps);
|
|
31
32
|
testID = defaultStr(testID,"RN_DateTimeComponent")
|
|
32
33
|
const anchorTimeProps = defaultObj(timeProps.anchorProps);
|
|
33
34
|
const timePropsContainerProps = defaultObj(timeProps.containerProps);
|
|
@@ -52,8 +53,8 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
52
53
|
const timeDefaultValue = getTimeValue(dateObj);
|
|
53
54
|
const changedTimeArgsRef = {current:{...defaultObj(parseTime(timeDefaultValue,withSeconds))}};
|
|
54
55
|
withSeconds = defaultBool(timeProps.withSeconds,withSeconds,true);
|
|
55
|
-
|
|
56
|
-
const maxWidth =
|
|
56
|
+
const cStyle = [theme.styles.noPadding,theme.styles.noMargin];
|
|
57
|
+
const maxWidth = 110;
|
|
57
58
|
const callOnChange = ()=>{
|
|
58
59
|
if(onChange){
|
|
59
60
|
const dObj = changeDateArgsRef.current;
|
|
@@ -71,6 +72,8 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
71
72
|
onChange(args);
|
|
72
73
|
}
|
|
73
74
|
}
|
|
75
|
+
const tInputProps = defaultObj(timeProps.inputProps);
|
|
76
|
+
const dStyle = flattenStyle([rest.style,dateProps.style]);
|
|
74
77
|
return <DateComponent
|
|
75
78
|
defaultValue = {dateObj}
|
|
76
79
|
disabled = {disabled}
|
|
@@ -79,7 +82,7 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
79
82
|
{...rest}
|
|
80
83
|
format = {dateFormat}
|
|
81
84
|
{...dateProps}
|
|
82
|
-
style = {
|
|
85
|
+
style = {dStyle}
|
|
83
86
|
calendarIconBefore = {true}
|
|
84
87
|
onChange = {(args)=>{
|
|
85
88
|
changeDateArgsRef.current = args;
|
|
@@ -102,15 +105,17 @@ export default function DateTimePickerComponent({left,isPeriodAction,withSeconds
|
|
|
102
105
|
}}
|
|
103
106
|
withLabel = {false}
|
|
104
107
|
mode = {"flat"}
|
|
105
|
-
|
|
108
|
+
contentProps = {{style:cStyle}}
|
|
109
|
+
containerProps = {{...timePropsContainerProps,style:[{maxWidth},theme.styles.noPadding,theme.styles.noMargin,timePropsContainerProps.style]}}
|
|
106
110
|
divider = {false}
|
|
111
|
+
style = {[theme.styles.noPadding,{maxHeight:40},theme.styles.noMargin,timeProps.style,dStyle.backgroundColor && {backgroundColor:dStyle.backgroundColor}]}
|
|
107
112
|
anchorProps = {{
|
|
108
113
|
...anchorTimeProps,
|
|
109
114
|
testID:testID+"_TimeAnchor",
|
|
110
115
|
style : [theme.styles.noPadding,{borderRadius:0},theme.styles.noMargin,anchorTimeProps.style]
|
|
111
116
|
}}
|
|
112
117
|
inputProps = {{
|
|
113
|
-
...
|
|
118
|
+
...tInputProps,
|
|
114
119
|
mode : "flat",
|
|
115
120
|
}}
|
|
116
121
|
/>
|
|
@@ -44,8 +44,9 @@ export const timeToString = (value,withSeconds)=>{
|
|
|
44
44
|
return value.substring(0,5);
|
|
45
45
|
}
|
|
46
46
|
export default function TimePickerComponent (props){
|
|
47
|
-
let {right:customRight,upper,anchorProps,dialogProps,withLabel,containerProps,mode,onChange,withSeconds,cancelLabel,confirmLabel,label,text,upperCase,defaultValue,disabled,editable,withModal,readOnly,...rest} = props;
|
|
47
|
+
let {right:customRight,upper,anchorProps,dialogProps,withLabel,inputProps,containerProps,mode,onChange,withSeconds,cancelLabel,confirmLabel,label,text,upperCase,defaultValue,disabled,editable,withModal,readOnly,...rest} = props;
|
|
48
48
|
rest = defaultObj(rest);
|
|
49
|
+
inputProps = defaultObj(inputProps);
|
|
49
50
|
const isEditable = disabled !== true && readOnly !== true && editable !== false?true : false;
|
|
50
51
|
withModal = defaultBool(withModal,true);
|
|
51
52
|
if(!isEditable){
|
|
@@ -110,6 +111,7 @@ export default function TimePickerComponent (props){
|
|
|
110
111
|
if(!disabled){
|
|
111
112
|
containerProps.style = [containerProps.style,{opacity:1}]
|
|
112
113
|
}
|
|
114
|
+
const iContainerProps = defaultObj(inputProps.containerProps);
|
|
113
115
|
return <>
|
|
114
116
|
<TouchableRipple {...containerProps}
|
|
115
117
|
disabled = {!isEditable}
|
|
@@ -120,6 +122,8 @@ export default function TimePickerComponent (props){
|
|
|
120
122
|
<TextField
|
|
121
123
|
mode = {mode||theme.textFieldMode}
|
|
122
124
|
{...rest}
|
|
125
|
+
{...inputProps}
|
|
126
|
+
containerProps = {{...iContainerProps,style:[containerProps.style,iContainerProps.style]}}
|
|
123
127
|
label = {label}
|
|
124
128
|
right = {right}
|
|
125
129
|
disabled = {disabled}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Copyright 2022 @fto-consult/Boris Fouomene. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style
|
|
3
|
+
// license that can be found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import React, {Component} from 'react';
|
|
6
|
+
import {
|
|
7
|
+
PanResponder,
|
|
8
|
+
View,
|
|
9
|
+
} from 'react-native';
|
|
10
|
+
import PropTypes from 'prop-types';
|
|
11
|
+
|
|
12
|
+
export const CONNECTOR_TOP_LEFT = 'tl';
|
|
13
|
+
export const CONNECTOR_TOP_MIDDLE = 'tm';
|
|
14
|
+
export const CONNECTOR_TOP_RIGHT = 'tr';
|
|
15
|
+
export const CONNECTOR_MIDDLE_RIGHT = 'mr';
|
|
16
|
+
export const CONNECTOR_BOTTOM_RIGHT = 'br';
|
|
17
|
+
export const CONNECTOR_BOTTOM_MIDDLE = 'bm';
|
|
18
|
+
export const CONNECTOR_BOTTOM_LEFT = 'bl';
|
|
19
|
+
export const CONNECTOR_MIDDLE_LEFT = 'ml';
|
|
20
|
+
export const CONNECTOR_CENTER = 'c';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Connector component for handle touch events.
|
|
24
|
+
*/
|
|
25
|
+
export class Connector extends Component {
|
|
26
|
+
|
|
27
|
+
constructor(props) {
|
|
28
|
+
super(props);
|
|
29
|
+
|
|
30
|
+
this.position = {
|
|
31
|
+
x: 0,
|
|
32
|
+
y: 0,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
this._panResponder = PanResponder.create({
|
|
36
|
+
// Ask to be the responder:
|
|
37
|
+
onStartShouldSetPanResponder: (event, gestureState) => true,
|
|
38
|
+
onStartShouldSetPanResponderCapture: (event, gestureState) => true,
|
|
39
|
+
onMoveShouldSetPanResponder: (event, gestureState) => true,
|
|
40
|
+
onMoveShouldSetPanResponderCapture: (event, gestureState) => true,
|
|
41
|
+
|
|
42
|
+
onPanResponderGrant: (event, gestureState) => {
|
|
43
|
+
// The gesture has started. Show visual feedback so the user knows
|
|
44
|
+
// what is happening!
|
|
45
|
+
// gestureState.d{x,y} will be set to zero now
|
|
46
|
+
const {
|
|
47
|
+
onStart
|
|
48
|
+
} = this.props;
|
|
49
|
+
|
|
50
|
+
this.position = {
|
|
51
|
+
x: 0,
|
|
52
|
+
y: 0,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
onStart([
|
|
56
|
+
0,
|
|
57
|
+
0,
|
|
58
|
+
]);
|
|
59
|
+
},
|
|
60
|
+
onPanResponderMove: (event, gestureState) => {
|
|
61
|
+
const {
|
|
62
|
+
onMove
|
|
63
|
+
} = this.props;
|
|
64
|
+
|
|
65
|
+
onMove([
|
|
66
|
+
gestureState.dx - this.position.x,
|
|
67
|
+
gestureState.dy - this.position.y,
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
this.position = {
|
|
71
|
+
x: gestureState.dx,
|
|
72
|
+
y: gestureState.dy,
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
onPanResponderTerminationRequest: (event, gestureState) => true,
|
|
76
|
+
onPanResponderRelease: (event, gestureState) => {
|
|
77
|
+
// The user has released all touches while this view is the
|
|
78
|
+
// responder. This typically means a gesture has succeeded
|
|
79
|
+
const {
|
|
80
|
+
onEnd
|
|
81
|
+
} = this.props;
|
|
82
|
+
|
|
83
|
+
onEnd([
|
|
84
|
+
gestureState.moveX,
|
|
85
|
+
gestureState.moveY,
|
|
86
|
+
]);
|
|
87
|
+
},
|
|
88
|
+
onPanResponderTerminate: (event, gestureState) => {
|
|
89
|
+
// Another component has become the responder, so this gesture
|
|
90
|
+
// should be cancelled
|
|
91
|
+
},
|
|
92
|
+
onShouldBlockNativeResponder: (event, gestureState) => {
|
|
93
|
+
// Returns whether this component should block native components from becoming the JS
|
|
94
|
+
// responder. Returns true by default. Is currently only supported on android.
|
|
95
|
+
return true;
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
render() {
|
|
101
|
+
const {
|
|
102
|
+
x,
|
|
103
|
+
y,
|
|
104
|
+
size,
|
|
105
|
+
} = this.props;
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<View
|
|
109
|
+
style={{
|
|
110
|
+
position: 'absolute',
|
|
111
|
+
left: x,
|
|
112
|
+
top: y,
|
|
113
|
+
width: size,
|
|
114
|
+
height: size,
|
|
115
|
+
borderWidth: 2,
|
|
116
|
+
borderColor: 'black',
|
|
117
|
+
backgroundColor: 'white'
|
|
118
|
+
}}
|
|
119
|
+
{...this._panResponder.panHandlers}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
Connector.propTypes = {
|
|
126
|
+
x: PropTypes.number,
|
|
127
|
+
y: PropTypes.number,
|
|
128
|
+
size: PropTypes.number,
|
|
129
|
+
onStart: PropTypes.func.isRequired,
|
|
130
|
+
onMove: PropTypes.func.isRequired,
|
|
131
|
+
onEnd: PropTypes.func.isRequired,
|
|
132
|
+
};
|