@idealyst/datepicker 1.0.0 → 1.0.41
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 +6 -2
- package/src/DatePicker/Calendar.native.tsx +180 -78
- package/src/DatePicker/Calendar.styles.tsx +73 -70
- package/src/DatePicker/DatePicker.native.tsx +24 -6
- package/src/DatePicker/DatePicker.styles.tsx +18 -11
- package/src/DatePicker/DatePicker.web.tsx +1 -1
- package/src/DatePicker/index.ts +1 -1
- package/src/DateRangePicker/RangeCalendar.native.tsx +143 -55
- package/src/DateRangePicker/RangeCalendar.styles.tsx +65 -39
- package/src/DateRangePicker/RangeCalendar.web.tsx +169 -60
- package/src/DateRangePicker/types.ts +9 -0
- package/src/DateTimePicker/DateTimePicker.native.tsx +11 -69
- package/src/DateTimePicker/DateTimePicker.tsx +12 -70
- package/src/DateTimePicker/DateTimePickerBase.tsx +241 -0
- package/src/DateTimePicker/TimePicker.native.tsx +9 -196
- package/src/DateTimePicker/TimePicker.styles.tsx +4 -2
- package/src/DateTimePicker/TimePicker.tsx +9 -401
- package/src/DateTimePicker/TimePickerBase.tsx +232 -0
- package/src/DateTimePicker/primitives/ClockFace.native.tsx +195 -0
- package/src/DateTimePicker/primitives/ClockFace.web.tsx +168 -0
- package/src/DateTimePicker/primitives/TimeInput.native.tsx +53 -0
- package/src/DateTimePicker/primitives/TimeInput.web.tsx +66 -0
- package/src/DateTimePicker/primitives/index.native.ts +2 -0
- package/src/DateTimePicker/primitives/index.ts +2 -0
- package/src/DateTimePicker/primitives/index.web.ts +2 -0
- package/src/DateTimePicker/types.ts +0 -4
- package/src/DateTimePicker/utils/dimensions.native.ts +9 -0
- package/src/DateTimePicker/utils/dimensions.ts +9 -0
- package/src/DateTimePicker/utils/dimensions.web.ts +33 -0
- package/src/DateTimeRangePicker/DateTimeRangePicker.native.tsx +10 -199
- package/src/DateTimeRangePicker/DateTimeRangePicker.styles.tsx +3 -0
- package/src/DateTimeRangePicker/DateTimeRangePicker.web.tsx +11 -131
- package/src/DateTimeRangePicker/DateTimeRangePickerBase.tsx +391 -0
- package/src/DateTimeRangePicker/types.ts +0 -2
- package/src/examples/DatePickerExamples.tsx +42 -118
- /package/src/DatePicker/{Calendar.tsx → Calendar.web.tsx} +0 -0
|
@@ -1,212 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { DateTimeRangePickerProps } from './types';
|
|
3
|
+
import { DateTimeRangePickerBase } from './DateTimeRangePickerBase';
|
|
4
4
|
import { RangeCalendar } from '../DateRangePicker/RangeCalendar.native';
|
|
5
5
|
import { TimePicker } from '../DateTimePicker/TimePicker.native';
|
|
6
6
|
import { dateTimeRangePickerStyles } from './DateTimeRangePicker.styles';
|
|
7
7
|
|
|
8
|
-
const DateTimeRangePicker: React.FC<DateTimeRangePickerProps> = ({
|
|
9
|
-
value,
|
|
10
|
-
onChange,
|
|
11
|
-
minDate,
|
|
12
|
-
maxDate,
|
|
13
|
-
disabled = false,
|
|
14
|
-
placeholder = 'Select date/time range',
|
|
15
|
-
label,
|
|
16
|
-
error,
|
|
17
|
-
helperText,
|
|
18
|
-
format = 'MM/dd/yyyy HH:mm',
|
|
19
|
-
locale,
|
|
20
|
-
size = 'medium',
|
|
21
|
-
variant = 'outlined',
|
|
22
|
-
timeMode = '12h',
|
|
23
|
-
showSeconds = false,
|
|
24
|
-
timeStep = 1,
|
|
25
|
-
allowSameDay = true,
|
|
26
|
-
maxDays,
|
|
27
|
-
style,
|
|
28
|
-
testID,
|
|
29
|
-
}) => {
|
|
30
|
-
const formatDateTime = (date: Date): string => {
|
|
31
|
-
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
32
|
-
const day = String(date.getDate()).padStart(2, '0');
|
|
33
|
-
const year = date.getFullYear();
|
|
34
|
-
|
|
35
|
-
let hours = date.getHours();
|
|
36
|
-
const minutes = String(date.getMinutes()).padStart(2, '0');
|
|
37
|
-
const seconds = String(date.getSeconds()).padStart(2, '0');
|
|
38
|
-
|
|
39
|
-
let timeString = '';
|
|
40
|
-
if (timeMode === '12h') {
|
|
41
|
-
const ampm = hours >= 12 ? 'PM' : 'AM';
|
|
42
|
-
hours = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
|
|
43
|
-
timeString = showSeconds
|
|
44
|
-
? `${String(hours).padStart(2, '0')}:${minutes}:${seconds} ${ampm}`
|
|
45
|
-
: `${String(hours).padStart(2, '0')}:${minutes} ${ampm}`;
|
|
46
|
-
} else {
|
|
47
|
-
timeString = showSeconds
|
|
48
|
-
? `${String(hours).padStart(2, '0')}:${minutes}:${seconds}`
|
|
49
|
-
: `${String(hours).padStart(2, '0')}:${minutes}`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return `${month}/${day}/${year} ${timeString}`;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const formatRange = (range: DateTimeRange): string => {
|
|
56
|
-
if (!range.startDate) return '';
|
|
57
|
-
if (!range.endDate) return `${formatDateTime(range.startDate)} - ...`;
|
|
58
|
-
return `${formatDateTime(range.startDate)} - ${formatDateTime(range.endDate)}`;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const handleDateRangeChange = (newRange: { startDate?: Date; endDate?: Date }) => {
|
|
62
|
-
// Preserve existing times when date changes
|
|
63
|
-
const updatedRange: DateTimeRange = {};
|
|
64
|
-
|
|
65
|
-
if (newRange.startDate) {
|
|
66
|
-
updatedRange.startDate = new Date(newRange.startDate);
|
|
67
|
-
if (value?.startDate) {
|
|
68
|
-
updatedRange.startDate.setHours(
|
|
69
|
-
value.startDate.getHours(),
|
|
70
|
-
value.startDate.getMinutes(),
|
|
71
|
-
value.startDate.getSeconds()
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (newRange.endDate) {
|
|
77
|
-
updatedRange.endDate = new Date(newRange.endDate);
|
|
78
|
-
if (value?.endDate) {
|
|
79
|
-
updatedRange.endDate.setHours(
|
|
80
|
-
value.endDate.getHours(),
|
|
81
|
-
value.endDate.getMinutes(),
|
|
82
|
-
value.endDate.getSeconds()
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
onChange(updatedRange.startDate || updatedRange.endDate ? updatedRange : null);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const handleStartTimeChange = (newTime: Date) => {
|
|
91
|
-
if (value?.startDate) {
|
|
92
|
-
const updatedDate = new Date(value.startDate);
|
|
93
|
-
updatedDate.setHours(newTime.getHours(), newTime.getMinutes(), newTime.getSeconds());
|
|
94
|
-
onChange({ ...value, startDate: updatedDate });
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const handleEndTimeChange = (newTime: Date) => {
|
|
99
|
-
if (value?.endDate) {
|
|
100
|
-
const updatedDate = new Date(value.endDate);
|
|
101
|
-
updatedDate.setHours(newTime.getHours(), newTime.getMinutes(), newTime.getSeconds());
|
|
102
|
-
onChange({ ...value, endDate: updatedDate });
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
const daysDifference = (range: DateTimeRange): number => {
|
|
107
|
-
if (!range.startDate || !range.endDate) return 0;
|
|
108
|
-
const diffTime = range.endDate.getTime() - range.startDate.getTime();
|
|
109
|
-
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const hoursDifference = (range: DateTimeRange): number => {
|
|
113
|
-
if (!range.startDate || !range.endDate) return 0;
|
|
114
|
-
const diffTime = range.endDate.getTime() - range.startDate.getTime();
|
|
115
|
-
return Math.ceil(diffTime / (1000 * 60 * 60));
|
|
116
|
-
};
|
|
117
|
-
|
|
8
|
+
const DateTimeRangePicker: React.FC<DateTimeRangePickerProps> = (props) => {
|
|
118
9
|
dateTimeRangePickerStyles.useVariants({});
|
|
119
10
|
|
|
120
11
|
return (
|
|
121
|
-
<
|
|
122
|
-
{
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
</Text>
|
|
126
|
-
)}
|
|
127
|
-
|
|
128
|
-
<View style={dateTimeRangePickerStyles.picker}>
|
|
129
|
-
{/* Selected Range Summary */}
|
|
130
|
-
{value?.startDate && value?.endDate && (
|
|
131
|
-
<View style={dateTimeRangePickerStyles.selectedRangeHeader}>
|
|
132
|
-
<Text style={dateTimeRangePickerStyles.selectedRangeLabel}>
|
|
133
|
-
Selected Range ({daysDifference(value)} days, {hoursDifference(value)} hours):
|
|
134
|
-
</Text>
|
|
135
|
-
<Text style={dateTimeRangePickerStyles.selectedRangeValue}>
|
|
136
|
-
{formatRange(value)}
|
|
137
|
-
</Text>
|
|
138
|
-
</View>
|
|
139
|
-
)}
|
|
140
|
-
|
|
141
|
-
{/* Date Section */}
|
|
142
|
-
<View style={dateTimeRangePickerStyles.section}>
|
|
143
|
-
<Text style={dateTimeRangePickerStyles.sectionLabel}>Date Range</Text>
|
|
144
|
-
<View style={dateTimeRangePickerStyles.sectionContent}>
|
|
145
|
-
<RangeCalendar
|
|
146
|
-
value={value || {}}
|
|
147
|
-
onChange={handleDateRangeChange}
|
|
148
|
-
minDate={minDate}
|
|
149
|
-
maxDate={maxDate}
|
|
150
|
-
disabled={disabled}
|
|
151
|
-
allowSameDay={allowSameDay}
|
|
152
|
-
maxDays={maxDays}
|
|
153
|
-
/>
|
|
154
|
-
</View>
|
|
155
|
-
</View>
|
|
156
|
-
|
|
157
|
-
{/* Time Section */}
|
|
158
|
-
{(value?.startDate || value?.endDate) && (
|
|
159
|
-
<View style={dateTimeRangePickerStyles.section}>
|
|
160
|
-
<Text style={dateTimeRangePickerStyles.sectionLabel}>Time Selection</Text>
|
|
161
|
-
<View style={dateTimeRangePickerStyles.sectionContent}>
|
|
162
|
-
<View style={dateTimeRangePickerStyles.timeSection}>
|
|
163
|
-
{/* Start Time */}
|
|
164
|
-
{value?.startDate && (
|
|
165
|
-
<View style={dateTimeRangePickerStyles.timeGroup}>
|
|
166
|
-
<Text style={dateTimeRangePickerStyles.timeGroupLabel}>Start Time</Text>
|
|
167
|
-
<TimePicker
|
|
168
|
-
value={value.startDate}
|
|
169
|
-
onChange={handleStartTimeChange}
|
|
170
|
-
disabled={disabled}
|
|
171
|
-
mode={timeMode}
|
|
172
|
-
showSeconds={showSeconds}
|
|
173
|
-
step={timeStep}
|
|
174
|
-
/>
|
|
175
|
-
</View>
|
|
176
|
-
)}
|
|
177
|
-
|
|
178
|
-
{/* End Time */}
|
|
179
|
-
{value?.endDate && (
|
|
180
|
-
<View style={dateTimeRangePickerStyles.timeGroup}>
|
|
181
|
-
<Text style={dateTimeRangePickerStyles.timeGroupLabel}>End Time</Text>
|
|
182
|
-
<TimePicker
|
|
183
|
-
value={value.endDate}
|
|
184
|
-
onChange={handleEndTimeChange}
|
|
185
|
-
disabled={disabled}
|
|
186
|
-
mode={timeMode}
|
|
187
|
-
showSeconds={showSeconds}
|
|
188
|
-
step={timeStep}
|
|
189
|
-
/>
|
|
190
|
-
</View>
|
|
191
|
-
)}
|
|
192
|
-
</View>
|
|
193
|
-
</View>
|
|
194
|
-
</View>
|
|
195
|
-
)}
|
|
196
|
-
</View>
|
|
197
|
-
|
|
198
|
-
{error && (
|
|
199
|
-
<Text style={dateTimeRangePickerStyles.errorText}>
|
|
200
|
-
{error}
|
|
201
|
-
</Text>
|
|
12
|
+
<DateTimeRangePickerBase
|
|
13
|
+
{...props}
|
|
14
|
+
renderRangeCalendar={(rangeCalendarProps) => (
|
|
15
|
+
<RangeCalendar {...rangeCalendarProps} />
|
|
202
16
|
)}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
<Text style={dateTimeRangePickerStyles.helperText}>
|
|
206
|
-
{helperText}
|
|
207
|
-
</Text>
|
|
17
|
+
renderTimePicker={(timePickerProps) => (
|
|
18
|
+
<TimePicker {...timePickerProps} />
|
|
208
19
|
)}
|
|
209
|
-
|
|
20
|
+
/>
|
|
210
21
|
);
|
|
211
22
|
};
|
|
212
23
|
|
|
@@ -17,6 +17,7 @@ export const dateTimeRangePickerStyles = StyleSheet.create((theme) => ({
|
|
|
17
17
|
},
|
|
18
18
|
|
|
19
19
|
selectedRangeHeader: {
|
|
20
|
+
flexDirection: 'column',
|
|
20
21
|
padding: theme.spacing?.sm || 12,
|
|
21
22
|
backgroundColor: theme.colors?.surface?.secondary || '#f9fafb',
|
|
22
23
|
borderRadius: theme.borderRadius?.md || 8,
|
|
@@ -25,6 +26,8 @@ export const dateTimeRangePickerStyles = StyleSheet.create((theme) => ({
|
|
|
25
26
|
gap: theme.spacing?.xs || 4,
|
|
26
27
|
|
|
27
28
|
_web: {
|
|
29
|
+
display: 'flex',
|
|
30
|
+
flexDirection: 'column',
|
|
28
31
|
border: `1px solid ${theme.colors?.border?.primary || '#e5e7eb'}`,
|
|
29
32
|
},
|
|
30
33
|
},
|
|
@@ -1,140 +1,20 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { DateTimeRangePickerProps, DateTimeRange } from './types';
|
|
2
|
+
import { DateTimeRangePickerProps } from './types';
|
|
3
|
+
import { DateTimeRangePickerBase } from './DateTimeRangePickerBase';
|
|
5
4
|
import { RangeCalendar } from '../DateRangePicker/RangeCalendar.web';
|
|
6
5
|
import { TimePicker } from '../DateTimePicker/TimePicker';
|
|
7
|
-
import { dateTimeRangePickerStyles } from './DateTimeRangePicker.styles';
|
|
8
|
-
|
|
9
|
-
const DateTimeRangePicker: React.FC<DateTimeRangePickerProps> = ({
|
|
10
|
-
value,
|
|
11
|
-
onChange,
|
|
12
|
-
minDate,
|
|
13
|
-
maxDate,
|
|
14
|
-
disabled = false,
|
|
15
|
-
timeMode = '12h',
|
|
16
|
-
showSeconds = false,
|
|
17
|
-
timeStep = 1,
|
|
18
|
-
allowSameDay = true,
|
|
19
|
-
maxDays,
|
|
20
|
-
style,
|
|
21
|
-
testID,
|
|
22
|
-
}) => {
|
|
23
|
-
|
|
24
|
-
const handleDateRangeChange = (newRange: { startDate?: Date; endDate?: Date }) => {
|
|
25
|
-
// Preserve existing times when date changes
|
|
26
|
-
const updatedRange: DateTimeRange = {};
|
|
27
|
-
|
|
28
|
-
if (newRange.startDate) {
|
|
29
|
-
updatedRange.startDate = new Date(newRange.startDate);
|
|
30
|
-
if (value?.startDate) {
|
|
31
|
-
updatedRange.startDate.setHours(
|
|
32
|
-
value.startDate.getHours(),
|
|
33
|
-
value.startDate.getMinutes(),
|
|
34
|
-
value.startDate.getSeconds()
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (newRange.endDate) {
|
|
40
|
-
updatedRange.endDate = new Date(newRange.endDate);
|
|
41
|
-
if (value?.endDate) {
|
|
42
|
-
updatedRange.endDate.setHours(
|
|
43
|
-
value.endDate.getHours(),
|
|
44
|
-
value.endDate.getMinutes(),
|
|
45
|
-
value.endDate.getSeconds()
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
onChange(updatedRange.startDate || updatedRange.endDate ? updatedRange : null);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const handleStartTimeChange = (newTime: Date) => {
|
|
54
|
-
if (value?.startDate) {
|
|
55
|
-
const updatedDate = new Date(value.startDate);
|
|
56
|
-
updatedDate.setHours(newTime.getHours(), newTime.getMinutes(), newTime.getSeconds());
|
|
57
|
-
onChange({ ...value, startDate: updatedDate });
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const handleEndTimeChange = (newTime: Date) => {
|
|
62
|
-
if (value?.endDate) {
|
|
63
|
-
const updatedDate = new Date(value.endDate);
|
|
64
|
-
updatedDate.setHours(newTime.getHours(), newTime.getMinutes(), newTime.getSeconds());
|
|
65
|
-
onChange({ ...value, endDate: updatedDate });
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
dateTimeRangePickerStyles.useVariants({});
|
|
71
|
-
|
|
72
|
-
const containerProps = getWebProps([dateTimeRangePickerStyles.container, style]);
|
|
73
|
-
const sectionProps = getWebProps([dateTimeRangePickerStyles.section]);
|
|
74
|
-
const sectionLabelProps = getWebProps([dateTimeRangePickerStyles.sectionLabel]);
|
|
75
|
-
const sectionContentProps = getWebProps([dateTimeRangePickerStyles.sectionContent]);
|
|
76
|
-
const timeSectionProps = getWebProps([dateTimeRangePickerStyles.timeSection]);
|
|
77
|
-
const timeGroupProps = getWebProps([dateTimeRangePickerStyles.timeGroup]);
|
|
78
|
-
const timeGroupLabelProps = getWebProps([dateTimeRangePickerStyles.timeGroupLabel]);
|
|
79
6
|
|
|
7
|
+
const DateTimeRangePicker: React.FC<DateTimeRangePickerProps> = (props) => {
|
|
80
8
|
return (
|
|
81
|
-
<
|
|
82
|
-
{
|
|
83
|
-
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
onChange={handleDateRangeChange}
|
|
89
|
-
minDate={minDate}
|
|
90
|
-
maxDate={maxDate}
|
|
91
|
-
disabled={disabled}
|
|
92
|
-
allowSameDay={allowSameDay}
|
|
93
|
-
maxDays={maxDays}
|
|
94
|
-
/>
|
|
95
|
-
</div>
|
|
96
|
-
</div>
|
|
97
|
-
|
|
98
|
-
{/* Time Section */}
|
|
99
|
-
{(value?.startDate || value?.endDate) && (
|
|
100
|
-
<div {...sectionProps}>
|
|
101
|
-
<div {...sectionLabelProps}>Time Selection</div>
|
|
102
|
-
<div {...sectionContentProps}>
|
|
103
|
-
<div {...timeSectionProps}>
|
|
104
|
-
{/* Start Time */}
|
|
105
|
-
{value?.startDate && (
|
|
106
|
-
<div {...timeGroupProps}>
|
|
107
|
-
<div {...timeGroupLabelProps}>Start Time</div>
|
|
108
|
-
<TimePicker
|
|
109
|
-
value={value.startDate}
|
|
110
|
-
onChange={handleStartTimeChange}
|
|
111
|
-
disabled={disabled}
|
|
112
|
-
mode={timeMode}
|
|
113
|
-
showSeconds={showSeconds}
|
|
114
|
-
step={timeStep}
|
|
115
|
-
/>
|
|
116
|
-
</div>
|
|
117
|
-
)}
|
|
118
|
-
|
|
119
|
-
{/* End Time */}
|
|
120
|
-
{value?.endDate && (
|
|
121
|
-
<div {...timeGroupProps}>
|
|
122
|
-
<div {...timeGroupLabelProps}>End Time</div>
|
|
123
|
-
<TimePicker
|
|
124
|
-
value={value.endDate}
|
|
125
|
-
onChange={handleEndTimeChange}
|
|
126
|
-
disabled={disabled}
|
|
127
|
-
mode={timeMode}
|
|
128
|
-
showSeconds={showSeconds}
|
|
129
|
-
step={timeStep}
|
|
130
|
-
/>
|
|
131
|
-
</div>
|
|
132
|
-
)}
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
</div>
|
|
9
|
+
<DateTimeRangePickerBase
|
|
10
|
+
{...props}
|
|
11
|
+
renderRangeCalendar={(rangeCalendarProps) => (
|
|
12
|
+
<RangeCalendar {...rangeCalendarProps} />
|
|
13
|
+
)}
|
|
14
|
+
renderTimePicker={(timePickerProps) => (
|
|
15
|
+
<TimePicker {...timePickerProps} />
|
|
136
16
|
)}
|
|
137
|
-
|
|
17
|
+
/>
|
|
138
18
|
);
|
|
139
19
|
};
|
|
140
20
|
|