@erxes/ui 3.2.19-2 → 3.2.20-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/date-picker.tsx +67 -23
package/package.json
CHANGED
|
@@ -88,39 +88,58 @@ const getAnchorDate = (value: NormalizedValue) => {
|
|
|
88
88
|
const defaultFormatMultiple = (count: number) =>
|
|
89
89
|
`${count} ${count > 1 ? 'Days' : 'Day'}`;
|
|
90
90
|
|
|
91
|
-
const
|
|
92
|
-
|
|
91
|
+
const DATE_SEGMENT_LENGTHS = [4, 2, 2];
|
|
92
|
+
const DATE_SEPARATOR = /[-./]/;
|
|
93
|
+
const LOOSE_INPUT_FORMATS = [
|
|
94
|
+
DEFAULT_FORMAT,
|
|
95
|
+
'YYYY-M-D',
|
|
96
|
+
'YYYY-MM-D',
|
|
97
|
+
'YYYY-M-DD',
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
const splitDateSegments = (value: string) => {
|
|
101
|
+
const segments = [''];
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
for (const char of value) {
|
|
104
|
+
const index = segments.length - 1;
|
|
105
|
+
const isLastSegment = index === DATE_SEGMENT_LENGTHS.length - 1;
|
|
106
|
+
|
|
107
|
+
if (DATE_SEPARATOR.test(char)) {
|
|
108
|
+
if (segments[index] && !isLastSegment) segments.push('');
|
|
109
|
+
} else if (/\d/.test(char)) {
|
|
110
|
+
if (segments[index].length < DATE_SEGMENT_LENGTHS[index]) {
|
|
111
|
+
segments[index] += char;
|
|
112
|
+
} else if (!isLastSegment) {
|
|
113
|
+
segments.push(char);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
96
116
|
}
|
|
97
117
|
|
|
98
|
-
|
|
99
|
-
|
|
118
|
+
return segments;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const formatDateMask = (value: string) => {
|
|
122
|
+
const [year, month, day] = splitDateSegments(value);
|
|
100
123
|
|
|
101
124
|
const normalizedMonth =
|
|
102
|
-
month
|
|
125
|
+
month?.length === 2
|
|
103
126
|
? String(Math.min(Number(month), 12)).padStart(2, '0')
|
|
104
127
|
: month;
|
|
105
128
|
|
|
106
|
-
if (digits.length <= 6) {
|
|
107
|
-
return `${year}-${normalizedMonth}`;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const day = digits.slice(6, 8);
|
|
111
|
-
|
|
112
129
|
const maxDay = dayjs(
|
|
113
|
-
`${year}-${normalizedMonth}-01`,
|
|
114
|
-
|
|
130
|
+
`${year}-${normalizedMonth?.padStart(2, '0')}-01`,
|
|
131
|
+
DEFAULT_FORMAT,
|
|
115
132
|
true,
|
|
116
133
|
).daysInMonth();
|
|
117
134
|
|
|
118
135
|
const normalizedDay =
|
|
119
|
-
day
|
|
136
|
+
day?.length === 2 && maxDay
|
|
120
137
|
? String(Math.min(Number(day), maxDay)).padStart(2, '0')
|
|
121
138
|
: day;
|
|
122
139
|
|
|
123
|
-
return
|
|
140
|
+
return [year, normalizedMonth, normalizedDay]
|
|
141
|
+
.filter((segment) => segment !== undefined)
|
|
142
|
+
.join('-');
|
|
124
143
|
};
|
|
125
144
|
|
|
126
145
|
const isWithinBounds = (date: dayjs.Dayjs, minBound?: Date, maxBound?: Date) =>
|
|
@@ -155,9 +174,12 @@ const getCalendarDisabled = (
|
|
|
155
174
|
...(maxBound ? [{ after: maxBound }] : []),
|
|
156
175
|
];
|
|
157
176
|
|
|
177
|
+
const getInputFormats = (format: string) =>
|
|
178
|
+
format === DEFAULT_FORMAT ? LOOSE_INPUT_FORMATS : [format];
|
|
179
|
+
|
|
158
180
|
const parseInputDate = (
|
|
159
181
|
text: string,
|
|
160
|
-
format: string,
|
|
182
|
+
format: string | string[],
|
|
161
183
|
minBound?: Date,
|
|
162
184
|
maxBound?: Date,
|
|
163
185
|
) => {
|
|
@@ -230,13 +252,30 @@ export const DatePicker = ({
|
|
|
230
252
|
}
|
|
231
253
|
};
|
|
232
254
|
|
|
255
|
+
const parseTypedDate = () => {
|
|
256
|
+
if (mode !== 'single' || !inputValue) return undefined;
|
|
257
|
+
const parsedDate = parseInputDate(
|
|
258
|
+
inputValue,
|
|
259
|
+
getInputFormats(format),
|
|
260
|
+
minBound,
|
|
261
|
+
maxBound,
|
|
262
|
+
);
|
|
263
|
+
return parsedDate && !dateMatchModifiers(parsedDate, calendarDisabled)
|
|
264
|
+
? parsedDate
|
|
265
|
+
: undefined;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const commitTypedDate = (date: Date) => {
|
|
269
|
+
setInputValue(dayjs(date).format(format));
|
|
270
|
+
if (date.getTime() !== singleTime) onChange(date);
|
|
271
|
+
};
|
|
272
|
+
|
|
233
273
|
const handleInputBlur = () => {
|
|
234
274
|
setIsFocused(false);
|
|
235
|
-
const parsedDate =
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
) {
|
|
275
|
+
const parsedDate = parseTypedDate();
|
|
276
|
+
if (parsedDate) {
|
|
277
|
+
commitTypedDate(parsedDate);
|
|
278
|
+
} else {
|
|
240
279
|
setInputValue(formatSingle());
|
|
241
280
|
}
|
|
242
281
|
};
|
|
@@ -273,6 +312,11 @@ export const DatePicker = ({
|
|
|
273
312
|
if (!opensPopover && e.key !== 'Enter') return;
|
|
274
313
|
e.preventDefault();
|
|
275
314
|
e.stopPropagation();
|
|
315
|
+
const typedDate = e.key === 'Enter' ? parseTypedDate() : undefined;
|
|
316
|
+
if (typedDate && typedDate.getTime() !== singleTime) {
|
|
317
|
+
commitTypedDate(typedDate);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
276
320
|
if (opensPopover) setIsOpen(true);
|
|
277
321
|
};
|
|
278
322
|
|