@xsolla/xui-date-picker 0.184.0 → 0.185.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/README.md +31 -2
- package/native/index.d.mts +146 -2
- package/native/index.d.ts +146 -2
- package/native/index.js +731 -55
- package/native/index.js.map +1 -1
- package/native/index.mjs +727 -55
- package/native/index.mjs.map +1 -1
- package/package.json +5 -5
- package/web/index.d.mts +146 -2
- package/web/index.d.ts +146 -2
- package/web/index.js +731 -55
- package/web/index.js.map +1 -1
- package/web/index.mjs +727 -55
- package/web/index.mjs.map +1 -1
package/native/index.mjs
CHANGED
|
@@ -8,7 +8,14 @@ import {
|
|
|
8
8
|
} from "@xsolla/xui-calendar";
|
|
9
9
|
|
|
10
10
|
// src/DatePicker.tsx
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
forwardRef,
|
|
13
|
+
useCallback,
|
|
14
|
+
useEffect,
|
|
15
|
+
useMemo,
|
|
16
|
+
useRef,
|
|
17
|
+
useState
|
|
18
|
+
} from "react";
|
|
12
19
|
|
|
13
20
|
// ../../foundation/primitives-native/src/Box.tsx
|
|
14
21
|
import {
|
|
@@ -194,9 +201,257 @@ var isNative = true;
|
|
|
194
201
|
|
|
195
202
|
// src/DatePicker.tsx
|
|
196
203
|
import { Input } from "@xsolla/xui-input";
|
|
197
|
-
import {
|
|
204
|
+
import { parse, isValid } from "date-fns";
|
|
198
205
|
import { Calendar, DualCalendar } from "@xsolla/xui-calendar";
|
|
206
|
+
|
|
207
|
+
// src/utils.ts
|
|
208
|
+
import { format } from "date-fns";
|
|
209
|
+
import * as locales from "date-fns/locale";
|
|
210
|
+
var defaultLocale = "enUS";
|
|
211
|
+
function formatDate(date, formatStr, locale = defaultLocale) {
|
|
212
|
+
const localeObj = locales[locale] || locales[defaultLocale];
|
|
213
|
+
return format(date, formatStr, {
|
|
214
|
+
locale: localeObj
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
var SEGMENT_WIDTH = {
|
|
218
|
+
day: 2,
|
|
219
|
+
month: 2,
|
|
220
|
+
year: 4
|
|
221
|
+
};
|
|
222
|
+
var SEGMENT_TOKEN = {
|
|
223
|
+
day: "dd",
|
|
224
|
+
month: "mm",
|
|
225
|
+
year: "yyyy"
|
|
226
|
+
};
|
|
227
|
+
function parseDateFormat(format2) {
|
|
228
|
+
const tokens = [];
|
|
229
|
+
let i = 0;
|
|
230
|
+
while (i < format2.length) {
|
|
231
|
+
const c = format2[i];
|
|
232
|
+
if (c === "d" || c === "M" || c === "y") {
|
|
233
|
+
while (i < format2.length && format2[i] === c) i++;
|
|
234
|
+
tokens.push({
|
|
235
|
+
kind: "segment",
|
|
236
|
+
type: c === "d" ? "day" : c === "M" ? "month" : "year"
|
|
237
|
+
});
|
|
238
|
+
} else {
|
|
239
|
+
let text = "";
|
|
240
|
+
while (i < format2.length && !"dMy".includes(format2[i])) {
|
|
241
|
+
text += format2[i];
|
|
242
|
+
i++;
|
|
243
|
+
}
|
|
244
|
+
tokens.push({ kind: "literal", text });
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return tokens;
|
|
248
|
+
}
|
|
249
|
+
var EMPTY_PARTS = { day: null, month: null, year: null };
|
|
250
|
+
function datePartsFromDate(date) {
|
|
251
|
+
if (!date) return { ...EMPTY_PARTS };
|
|
252
|
+
return {
|
|
253
|
+
day: date.getDate(),
|
|
254
|
+
month: date.getMonth() + 1,
|
|
255
|
+
year: date.getFullYear()
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
function datePartsToDate(parts) {
|
|
259
|
+
const { day, month, year } = parts;
|
|
260
|
+
if (day == null || month == null || year == null) return null;
|
|
261
|
+
const date = new Date(year, month - 1, day);
|
|
262
|
+
if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
return date;
|
|
266
|
+
}
|
|
267
|
+
function isDatePartsComplete(parts) {
|
|
268
|
+
return parts.day != null && parts.month != null && parts.year != null;
|
|
269
|
+
}
|
|
270
|
+
function clampDatePart(type, value, parts) {
|
|
271
|
+
if (type === "month") return Math.min(12, Math.max(1, value));
|
|
272
|
+
if (type === "year") return Math.max(1, value);
|
|
273
|
+
const year = parts.year ?? (/* @__PURE__ */ new Date()).getFullYear();
|
|
274
|
+
const monthIndex = (parts.month ?? (/* @__PURE__ */ new Date()).getMonth() + 1) - 1;
|
|
275
|
+
return Math.min(daysInMonth(year, monthIndex), Math.max(1, value));
|
|
276
|
+
}
|
|
277
|
+
function stepDatePart(type, current, delta, parts) {
|
|
278
|
+
if (type === "month") return ((current - 1 + delta) % 12 + 12) % 12 + 1;
|
|
279
|
+
if (type === "year") return Math.max(1, current + delta);
|
|
280
|
+
const year = parts.year ?? (/* @__PURE__ */ new Date()).getFullYear();
|
|
281
|
+
const monthIndex = (parts.month ?? (/* @__PURE__ */ new Date()).getMonth() + 1) - 1;
|
|
282
|
+
const dim = daysInMonth(year, monthIndex);
|
|
283
|
+
return ((current - 1 + delta) % dim + dim) % dim + 1;
|
|
284
|
+
}
|
|
285
|
+
function buildSegmentedValue(format2, parts, active) {
|
|
286
|
+
const tokens = parseDateFormat(format2);
|
|
287
|
+
let text = "";
|
|
288
|
+
const ranges = [];
|
|
289
|
+
for (const token of tokens) {
|
|
290
|
+
if (token.kind === "literal") {
|
|
291
|
+
text += token.text;
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
const { type } = token;
|
|
295
|
+
const width = SEGMENT_WIDTH[type];
|
|
296
|
+
const value = parts[type];
|
|
297
|
+
let rendered;
|
|
298
|
+
let filled;
|
|
299
|
+
if (active && active.type === type && active.buffer.length > 0) {
|
|
300
|
+
rendered = active.buffer;
|
|
301
|
+
filled = false;
|
|
302
|
+
} else if (value != null) {
|
|
303
|
+
rendered = String(value).padStart(width, "0");
|
|
304
|
+
filled = true;
|
|
305
|
+
} else {
|
|
306
|
+
rendered = SEGMENT_TOKEN[type];
|
|
307
|
+
filled = false;
|
|
308
|
+
}
|
|
309
|
+
const start = text.length;
|
|
310
|
+
text += rendered;
|
|
311
|
+
ranges.push({ type, start, end: text.length, filled });
|
|
312
|
+
}
|
|
313
|
+
return { text, ranges };
|
|
314
|
+
}
|
|
315
|
+
function isSegmentComplete(type, buffer) {
|
|
316
|
+
const width = SEGMENT_WIDTH[type];
|
|
317
|
+
if (buffer.length >= width) return true;
|
|
318
|
+
if (buffer.length === 1 && type !== "year") {
|
|
319
|
+
const first = Number(buffer);
|
|
320
|
+
return type === "month" ? first > 1 : first > 3;
|
|
321
|
+
}
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
function daysInMonth(year, monthIndex) {
|
|
325
|
+
return new Date(year, monthIndex + 1, 0).getDate();
|
|
326
|
+
}
|
|
327
|
+
function getDateSegments(format2, value) {
|
|
328
|
+
const segments = [];
|
|
329
|
+
let fi = 0;
|
|
330
|
+
let vi = 0;
|
|
331
|
+
while (fi < format2.length && vi < value.length) {
|
|
332
|
+
const fc = format2[fi];
|
|
333
|
+
if (fc === "d" || fc === "M" || fc === "y") {
|
|
334
|
+
while (fi < format2.length && format2[fi] === fc) fi++;
|
|
335
|
+
const start = vi;
|
|
336
|
+
while (vi < value.length && value[vi] >= "0" && value[vi] <= "9") vi++;
|
|
337
|
+
if (vi > start) {
|
|
338
|
+
segments.push({
|
|
339
|
+
type: fc === "d" ? "day" : fc === "M" ? "month" : "year",
|
|
340
|
+
start,
|
|
341
|
+
end: vi
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
fi++;
|
|
346
|
+
vi++;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return segments;
|
|
350
|
+
}
|
|
351
|
+
function stepDateSegment(date, type, delta) {
|
|
352
|
+
const year = date.getFullYear();
|
|
353
|
+
const month = date.getMonth();
|
|
354
|
+
const day = date.getDate();
|
|
355
|
+
if (type === "year") {
|
|
356
|
+
const nextYear = year + delta;
|
|
357
|
+
return new Date(
|
|
358
|
+
nextYear,
|
|
359
|
+
month,
|
|
360
|
+
Math.min(day, daysInMonth(nextYear, month))
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
if (type === "month") {
|
|
364
|
+
const nextMonth = ((month + delta) % 12 + 12) % 12;
|
|
365
|
+
return new Date(
|
|
366
|
+
year,
|
|
367
|
+
nextMonth,
|
|
368
|
+
Math.min(day, daysInMonth(year, nextMonth))
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
const dim = daysInMonth(year, month);
|
|
372
|
+
const nextDay = ((day - 1 + delta) % dim + dim) % dim + 1;
|
|
373
|
+
return new Date(year, month, nextDay);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// src/DatePicker.tsx
|
|
199
377
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
378
|
+
var PLACEMENT_OFFSET = 4;
|
|
379
|
+
var DEFAULT_DATE_FORMAT = "MM/dd/yyyy";
|
|
380
|
+
var RANGE_SEPARATOR = /\s*[-–—]\s*/;
|
|
381
|
+
var RANGE_DISPLAY_SEP = " - ";
|
|
382
|
+
var CalendarFieldIcon = () => /* @__PURE__ */ jsx2(
|
|
383
|
+
"svg",
|
|
384
|
+
{
|
|
385
|
+
viewBox: "0 0 24 24",
|
|
386
|
+
width: "100%",
|
|
387
|
+
height: "100%",
|
|
388
|
+
style: { fill: "currentColor", stroke: "none" },
|
|
389
|
+
children: /* @__PURE__ */ jsx2(
|
|
390
|
+
"path",
|
|
391
|
+
{
|
|
392
|
+
fillOpacity: 0.6,
|
|
393
|
+
d: "M8 4H16V2H18V4H21.5C21.7761 4 22 4.22386 22 4.5V19.5C22 19.7761 21.7761 20 21.5 20H2.5C2.22386 20 2 19.7761 2 19.5V4.5C2 4.22386 2.22386 4 2.5 4H6V2H8V4ZM4 18H20V10H4V18ZM4 8H20V6H4V8Z"
|
|
394
|
+
}
|
|
395
|
+
)
|
|
396
|
+
}
|
|
397
|
+
);
|
|
398
|
+
var FALLBACK_PANEL_SIZE = { width: 320, height: 360 };
|
|
399
|
+
var resolveAutoPlacement = (container, panel, viewport, offset) => {
|
|
400
|
+
const spaceBelow = viewport.height - container.bottom;
|
|
401
|
+
const spaceAbove = container.top;
|
|
402
|
+
const spaceRight = viewport.width - container.right;
|
|
403
|
+
const spaceLeft = container.left;
|
|
404
|
+
const neededVertical = panel.height + offset;
|
|
405
|
+
const neededHorizontal = panel.width + offset;
|
|
406
|
+
if (spaceBelow >= neededVertical) return "bottom";
|
|
407
|
+
if (spaceAbove >= neededVertical) return "top";
|
|
408
|
+
if (spaceLeft >= neededHorizontal) return "left";
|
|
409
|
+
if (spaceRight >= neededHorizontal) return "right";
|
|
410
|
+
const gaps = [
|
|
411
|
+
{ side: "bottom", space: spaceBelow },
|
|
412
|
+
{ side: "top", space: spaceAbove },
|
|
413
|
+
{ side: "left", space: spaceLeft },
|
|
414
|
+
{ side: "right", space: spaceRight }
|
|
415
|
+
];
|
|
416
|
+
return gaps.reduce(
|
|
417
|
+
(best, current) => current.space > best.space ? current : best
|
|
418
|
+
).side;
|
|
419
|
+
};
|
|
420
|
+
var parsePlacement = (placement) => {
|
|
421
|
+
const [side, align] = placement.split("-");
|
|
422
|
+
return { side, align: align ?? null };
|
|
423
|
+
};
|
|
424
|
+
var alignFromDropdownPosition = (dropdownPosition) => dropdownPosition === "right" ? "end" : "start";
|
|
425
|
+
var resolveForcedLayout = (placement, dropdownPosition) => {
|
|
426
|
+
const { side, align } = parsePlacement(placement);
|
|
427
|
+
if (align) return { side, align };
|
|
428
|
+
if (side === "top" || side === "bottom")
|
|
429
|
+
return { side, align: alignFromDropdownPosition(dropdownPosition) };
|
|
430
|
+
return { side, align: "start" };
|
|
431
|
+
};
|
|
432
|
+
var resolveAlignForSide = (side, container, panel, viewport, preferred) => {
|
|
433
|
+
if (preferred === "center") return "center";
|
|
434
|
+
const isVerticalSide = side === "left" || side === "right";
|
|
435
|
+
const fits = (align) => {
|
|
436
|
+
if (isVerticalSide) {
|
|
437
|
+
return align === "start" ? container.top + panel.height <= viewport.height : container.bottom - panel.height >= 0;
|
|
438
|
+
}
|
|
439
|
+
return align === "start" ? container.left + panel.width <= viewport.width : container.right - panel.width >= 0;
|
|
440
|
+
};
|
|
441
|
+
if (fits(preferred)) return preferred;
|
|
442
|
+
const opposite = preferred === "start" ? "end" : "start";
|
|
443
|
+
return fits(opposite) ? opposite : preferred;
|
|
444
|
+
};
|
|
445
|
+
var getPlacementStyle = (side, align, offset) => {
|
|
446
|
+
if (side === "top" || side === "bottom") {
|
|
447
|
+
const vertical2 = side === "bottom" ? { top: "100%", bottom: "auto", marginTop: offset, marginBottom: 0 } : { top: "auto", bottom: "100%", marginTop: 0, marginBottom: offset };
|
|
448
|
+
const horizontal2 = align === "center" ? { left: "50%", right: "auto", transform: "translateX(-50%)" } : align === "end" ? { left: "auto", right: 0 } : { left: 0, right: "auto" };
|
|
449
|
+
return { marginLeft: 0, marginRight: 0, ...vertical2, ...horizontal2 };
|
|
450
|
+
}
|
|
451
|
+
const horizontal = side === "right" ? { left: "100%", right: "auto", marginLeft: offset, marginRight: 0 } : { left: "auto", right: "100%", marginLeft: 0, marginRight: offset };
|
|
452
|
+
const vertical = align === "center" ? { top: "50%", bottom: "auto", transform: "translateY(-50%)" } : align === "end" ? { top: "auto", bottom: 0 } : { top: 0, bottom: "auto" };
|
|
453
|
+
return { marginTop: 0, marginBottom: 0, ...horizontal, ...vertical };
|
|
454
|
+
};
|
|
200
455
|
var DatePicker = forwardRef(
|
|
201
456
|
({
|
|
202
457
|
onChange,
|
|
@@ -207,63 +462,126 @@ var DatePicker = forwardRef(
|
|
|
207
462
|
startDate,
|
|
208
463
|
endDate,
|
|
209
464
|
selectedDate,
|
|
465
|
+
minDate,
|
|
466
|
+
maxDate,
|
|
210
467
|
placeholder,
|
|
468
|
+
dateFormat = DEFAULT_DATE_FORMAT,
|
|
211
469
|
backgroundColor,
|
|
212
470
|
testID,
|
|
213
471
|
chips,
|
|
214
472
|
activeChip,
|
|
215
473
|
onChipSelect,
|
|
474
|
+
showChipLabel = true,
|
|
216
475
|
dropdownPosition = "left",
|
|
476
|
+
placement,
|
|
217
477
|
themeMode,
|
|
218
478
|
themeProductContext,
|
|
219
479
|
overlayThemeMode,
|
|
220
480
|
overlayThemeProductContext,
|
|
481
|
+
iconRight = /* @__PURE__ */ jsx2(CalendarFieldIcon, {}),
|
|
482
|
+
iconLeft,
|
|
483
|
+
error,
|
|
484
|
+
errorMessage,
|
|
485
|
+
readOnly,
|
|
486
|
+
onFocus: onFocusProp,
|
|
487
|
+
onBlur: onBlurProp,
|
|
488
|
+
onClick: onClickProp,
|
|
489
|
+
onKeyDown: onKeyDownProp,
|
|
490
|
+
onPaste: onPasteProp,
|
|
221
491
|
...rest
|
|
222
492
|
}, ref) => {
|
|
493
|
+
const editable = !readOnly && !rest.disabled;
|
|
223
494
|
const isDual = variant === "dual";
|
|
224
495
|
const isRange = isDual || selectsRange;
|
|
496
|
+
const propGroups = useCallback(
|
|
497
|
+
() => isRange ? [datePartsFromDate(startDate), datePartsFromDate(endDate)] : [datePartsFromDate(selectedDate)],
|
|
498
|
+
[isRange, startDate, endDate, selectedDate]
|
|
499
|
+
);
|
|
225
500
|
const [open, setOpen] = useState(false);
|
|
226
|
-
const [
|
|
501
|
+
const [groups, setGroups] = useState(propGroups);
|
|
502
|
+
const [edit, setEdit] = useState(null);
|
|
503
|
+
const [focused, setFocused] = useState(false);
|
|
504
|
+
const [activeSegment, setActiveSegment] = useState(null);
|
|
227
505
|
const [internalChip, setInternalChip] = useState(null);
|
|
506
|
+
const [parseError, setParseError] = useState(null);
|
|
507
|
+
const [layout, setLayout] = useState(
|
|
508
|
+
() => placement ? resolveForcedLayout(placement, dropdownPosition) : { side: "bottom", align: alignFromDropdownPosition(dropdownPosition) }
|
|
509
|
+
);
|
|
228
510
|
const containerRef = useRef(null);
|
|
511
|
+
const calendarRef = useRef(null);
|
|
512
|
+
const inputRef = useRef(null);
|
|
229
513
|
const chipSelectionRef = useRef(false);
|
|
514
|
+
const suppressReopenRef = useRef(false);
|
|
230
515
|
const activeChipValue = activeChip !== void 0 ? activeChip : internalChip;
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
516
|
+
const chipLabel = showChipLabel && activeChipValue && chips ? chips.find((c) => c.value === activeChipValue)?.label : void 0;
|
|
517
|
+
const isWithinBounds = (date) => {
|
|
518
|
+
const day = new Date(
|
|
519
|
+
date.getFullYear(),
|
|
520
|
+
date.getMonth(),
|
|
521
|
+
date.getDate()
|
|
522
|
+
).getTime();
|
|
523
|
+
if (minDate) {
|
|
524
|
+
const min = new Date(
|
|
525
|
+
minDate.getFullYear(),
|
|
526
|
+
minDate.getMonth(),
|
|
527
|
+
minDate.getDate()
|
|
528
|
+
).getTime();
|
|
529
|
+
if (day < min) return false;
|
|
237
530
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
531
|
+
if (maxDate) {
|
|
532
|
+
const max = new Date(
|
|
533
|
+
maxDate.getFullYear(),
|
|
534
|
+
maxDate.getMonth(),
|
|
535
|
+
maxDate.getDate()
|
|
536
|
+
).getTime();
|
|
537
|
+
if (day > max) return false;
|
|
243
538
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
539
|
+
return true;
|
|
540
|
+
};
|
|
541
|
+
const composeField = () => {
|
|
542
|
+
const build = (group) => buildSegmentedValue(
|
|
543
|
+
dateFormat,
|
|
544
|
+
groups[group] ?? { day: null, month: null, year: null },
|
|
545
|
+
edit && edit.group === group ? { type: edit.type, buffer: edit.buffer } : void 0
|
|
546
|
+
);
|
|
547
|
+
if (!isRange) {
|
|
548
|
+
const { text: text2, ranges } = build(0);
|
|
549
|
+
return { text: text2, segments: ranges.map((r) => ({ ...r, group: 0 })) };
|
|
253
550
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
551
|
+
const a = build(0);
|
|
552
|
+
const b = build(1);
|
|
553
|
+
const text = `${a.text}${RANGE_DISPLAY_SEP}${b.text}`;
|
|
554
|
+
const offset = a.text.length + RANGE_DISPLAY_SEP.length;
|
|
555
|
+
return {
|
|
556
|
+
text,
|
|
557
|
+
segments: [
|
|
558
|
+
...a.ranges.map((r) => ({ ...r, group: 0 })),
|
|
559
|
+
...b.ranges.map((r) => ({
|
|
560
|
+
...r,
|
|
561
|
+
group: 1,
|
|
562
|
+
start: r.start + offset,
|
|
563
|
+
end: r.end + offset
|
|
564
|
+
}))
|
|
565
|
+
]
|
|
566
|
+
};
|
|
260
567
|
};
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
568
|
+
const composed = composeField();
|
|
569
|
+
const hasAnyFilled = groups.some(
|
|
570
|
+
(g) => g.day != null || g.month != null || g.year != null
|
|
571
|
+
);
|
|
572
|
+
const showMask = hasAnyFilled || focused && isWeb;
|
|
573
|
+
const inputValue = chipLabel ?? (showMask ? composed.text : "");
|
|
574
|
+
const orderedSegments = () => composeField().segments;
|
|
575
|
+
const firstSegmentKey = () => {
|
|
576
|
+
const first = orderedSegments()[0];
|
|
577
|
+
return first ? { group: first.group, type: first.type } : null;
|
|
578
|
+
};
|
|
579
|
+
const segmentKeyAtCaret = (caret) => {
|
|
580
|
+
const segments = orderedSegments();
|
|
581
|
+
const seg = segments.find((s) => caret >= s.start && caret <= s.end) ?? segments.find((s) => caret < s.start) ?? segments[segments.length - 1];
|
|
582
|
+
return seg ? { group: seg.group, type: seg.type } : null;
|
|
265
583
|
};
|
|
266
|
-
const
|
|
584
|
+
const applySelection = (date, closeOnComplete = true) => {
|
|
267
585
|
if (!chipSelectionRef.current) {
|
|
268
586
|
setInternalChip(null);
|
|
269
587
|
onChipSelect?.(null);
|
|
@@ -271,13 +589,278 @@ var DatePicker = forwardRef(
|
|
|
271
589
|
chipSelectionRef.current = false;
|
|
272
590
|
if (!isRange) {
|
|
273
591
|
onChange?.(date);
|
|
274
|
-
setOpen(false);
|
|
592
|
+
if (closeOnComplete) setOpen(false);
|
|
275
593
|
} else {
|
|
276
594
|
const range = date;
|
|
277
595
|
onChange?.(range);
|
|
278
|
-
if (range[0] && range[1]) setOpen(false);
|
|
596
|
+
if (closeOnComplete && range[0] && range[1]) setOpen(false);
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
const emit = (next) => {
|
|
600
|
+
if (!isRange) {
|
|
601
|
+
const date = datePartsToDate(next[0]);
|
|
602
|
+
if (date && isWithinBounds(date)) applySelection(date, false);
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
const start = datePartsToDate(next[0]);
|
|
606
|
+
const end = datePartsToDate(next[1]);
|
|
607
|
+
if (start && !isWithinBounds(start)) return;
|
|
608
|
+
if (end && !isWithinBounds(end)) return;
|
|
609
|
+
if (start && end && start.getTime() > end.getTime()) {
|
|
610
|
+
setParseError("End date must be after start date");
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
if (start || end) applySelection([start, end], false);
|
|
614
|
+
};
|
|
615
|
+
const commitPart = (group, type, rawValue) => {
|
|
616
|
+
const clamped = clampDatePart(type, rawValue, groups[group]);
|
|
617
|
+
const next = groups.map((g, i) => {
|
|
618
|
+
if (i !== group) return g;
|
|
619
|
+
const updated = { ...g, [type]: clamped };
|
|
620
|
+
if (type !== "day" && updated.day != null) {
|
|
621
|
+
updated.day = clampDatePart("day", updated.day, updated);
|
|
622
|
+
}
|
|
623
|
+
return updated;
|
|
624
|
+
});
|
|
625
|
+
const assembled = datePartsToDate(next[group]);
|
|
626
|
+
if (assembled && !isWithinBounds(assembled)) {
|
|
627
|
+
setParseError("Date must be within the allowed range");
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
setParseError(null);
|
|
631
|
+
setGroups(next);
|
|
632
|
+
emit(next);
|
|
633
|
+
return clamped;
|
|
634
|
+
};
|
|
635
|
+
const commitBuffer = () => {
|
|
636
|
+
if (!edit) return;
|
|
637
|
+
commitPart(edit.group, edit.type, Number(edit.buffer));
|
|
638
|
+
setEdit(null);
|
|
639
|
+
};
|
|
640
|
+
const defaultPart = (type) => {
|
|
641
|
+
const now = /* @__PURE__ */ new Date();
|
|
642
|
+
if (type === "day") return now.getDate();
|
|
643
|
+
if (type === "month") return now.getMonth() + 1;
|
|
644
|
+
return now.getFullYear();
|
|
645
|
+
};
|
|
646
|
+
const advance = (active) => {
|
|
647
|
+
const segments = orderedSegments();
|
|
648
|
+
const index = segments.findIndex(
|
|
649
|
+
(s) => s.group === active.group && s.type === active.type
|
|
650
|
+
);
|
|
651
|
+
const next = segments[index + 1];
|
|
652
|
+
setActiveSegment(next ? { group: next.group, type: next.type } : active);
|
|
653
|
+
};
|
|
654
|
+
const handleDigit = (digit) => {
|
|
655
|
+
const active = activeSegment ?? firstSegmentKey();
|
|
656
|
+
if (!active) return;
|
|
657
|
+
const sameActive = edit && edit.group === active.group && edit.type === active.type;
|
|
658
|
+
const buffer = (sameActive ? edit.buffer : "") + digit;
|
|
659
|
+
if (isSegmentComplete(active.type, buffer)) {
|
|
660
|
+
const committed = commitPart(active.group, active.type, Number(buffer));
|
|
661
|
+
setEdit(null);
|
|
662
|
+
if (committed !== null) advance(active);
|
|
663
|
+
} else {
|
|
664
|
+
setEdit({ group: active.group, type: active.type, buffer });
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
const handleArrowStep = (e, delta) => {
|
|
668
|
+
e.preventDefault();
|
|
669
|
+
const active = activeSegment ?? firstSegmentKey();
|
|
670
|
+
if (!active) return;
|
|
671
|
+
const parts = groups[active.group];
|
|
672
|
+
const current = parts[active.type];
|
|
673
|
+
const value = current == null ? defaultPart(active.type) : stepDatePart(active.type, current, delta, parts);
|
|
674
|
+
commitPart(active.group, active.type, value);
|
|
675
|
+
setEdit(null);
|
|
676
|
+
if (!activeSegment) setActiveSegment(active);
|
|
677
|
+
};
|
|
678
|
+
const handleArrowMove = (e, direction) => {
|
|
679
|
+
const segments = orderedSegments();
|
|
680
|
+
if (!segments.length) return;
|
|
681
|
+
const active = activeSegment ?? firstSegmentKey();
|
|
682
|
+
if (!active) return;
|
|
683
|
+
let index = segments.findIndex(
|
|
684
|
+
(s) => s.group === active.group && s.type === active.type
|
|
685
|
+
);
|
|
686
|
+
if (index === -1) index = direction > 0 ? -1 : segments.length;
|
|
687
|
+
const next = index + direction;
|
|
688
|
+
if (next < 0 || next >= segments.length) return;
|
|
689
|
+
e.preventDefault();
|
|
690
|
+
if (edit) {
|
|
691
|
+
commitPart(edit.group, edit.type, Number(edit.buffer));
|
|
692
|
+
setEdit(null);
|
|
279
693
|
}
|
|
694
|
+
const target = segments[next];
|
|
695
|
+
setActiveSegment({ group: target.group, type: target.type });
|
|
280
696
|
};
|
|
697
|
+
const handleBackspace = (e) => {
|
|
698
|
+
e.preventDefault();
|
|
699
|
+
const active = activeSegment ?? firstSegmentKey();
|
|
700
|
+
if (!active) return;
|
|
701
|
+
const sameActive = edit && edit.group === active.group && edit.type === active.type;
|
|
702
|
+
if (sameActive && edit.buffer.length > 0) {
|
|
703
|
+
const buffer = edit.buffer.slice(0, -1);
|
|
704
|
+
setEdit(buffer ? { ...edit, buffer } : null);
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
const next = groups.map(
|
|
708
|
+
(g, i) => i === active.group ? { ...g, [active.type]: null } : g
|
|
709
|
+
);
|
|
710
|
+
setGroups(next);
|
|
711
|
+
setEdit(null);
|
|
712
|
+
setParseError(null);
|
|
713
|
+
emit(next);
|
|
714
|
+
const segments = orderedSegments();
|
|
715
|
+
const index = segments.findIndex(
|
|
716
|
+
(s) => s.group === active.group && s.type === active.type
|
|
717
|
+
);
|
|
718
|
+
const prev = segments[index - 1];
|
|
719
|
+
if (prev) setActiveSegment({ group: prev.group, type: prev.type });
|
|
720
|
+
};
|
|
721
|
+
const handleKeyDown = (e) => {
|
|
722
|
+
onKeyDownProp?.(e);
|
|
723
|
+
if (e.defaultPrevented) return;
|
|
724
|
+
if (e.key === "Escape") {
|
|
725
|
+
setOpen(false);
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
if (!isWeb || !editable) return;
|
|
729
|
+
if (e.key === "Enter") {
|
|
730
|
+
commitBuffer();
|
|
731
|
+
setOpen(false);
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
if (e.key === "ArrowUp") return handleArrowStep(e, 1);
|
|
735
|
+
if (e.key === "ArrowDown") return handleArrowStep(e, -1);
|
|
736
|
+
if (e.key === "ArrowLeft") return handleArrowMove(e, -1);
|
|
737
|
+
if (e.key === "ArrowRight") return handleArrowMove(e, 1);
|
|
738
|
+
if (e.key === "Backspace") return handleBackspace(e);
|
|
739
|
+
if (/^[0-9]$/.test(e.key)) {
|
|
740
|
+
e.preventDefault();
|
|
741
|
+
handleDigit(e.key);
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
if (e.key.length === 1 && !e.metaKey && !e.ctrlKey) e.preventDefault();
|
|
745
|
+
};
|
|
746
|
+
const handleFieldFocus = (e) => {
|
|
747
|
+
onFocusProp?.(e);
|
|
748
|
+
if (suppressReopenRef.current) {
|
|
749
|
+
suppressReopenRef.current = false;
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
setFocused(true);
|
|
753
|
+
setOpen(true);
|
|
754
|
+
if (isWeb && editable) setActiveSegment(firstSegmentKey());
|
|
755
|
+
};
|
|
756
|
+
const handleFieldClick = (e) => {
|
|
757
|
+
onClickProp?.(e);
|
|
758
|
+
if (!isWeb || !editable || !hasAnyFilled) return;
|
|
759
|
+
const input = inputRef.current;
|
|
760
|
+
if (!input) return;
|
|
761
|
+
const key = segmentKeyAtCaret(input.selectionStart ?? 0);
|
|
762
|
+
if (key) setActiveSegment(key);
|
|
763
|
+
};
|
|
764
|
+
const handleFieldBlur = (e) => {
|
|
765
|
+
onBlurProp?.(e);
|
|
766
|
+
setFocused(false);
|
|
767
|
+
setActiveSegment(null);
|
|
768
|
+
if (!editable) return;
|
|
769
|
+
let next = groups;
|
|
770
|
+
if (edit) {
|
|
771
|
+
const clamped = clampDatePart(
|
|
772
|
+
edit.type,
|
|
773
|
+
Number(edit.buffer),
|
|
774
|
+
groups[edit.group]
|
|
775
|
+
);
|
|
776
|
+
next = groups.map(
|
|
777
|
+
(g, i) => i === edit.group ? { ...g, [edit.type]: clamped } : g
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
const props = propGroups();
|
|
781
|
+
next = next.map((g, i) => isDatePartsComplete(g) ? g : props[i]);
|
|
782
|
+
setEdit(null);
|
|
783
|
+
setParseError(null);
|
|
784
|
+
setGroups(next);
|
|
785
|
+
emit(next);
|
|
786
|
+
};
|
|
787
|
+
const parseOne = (token) => {
|
|
788
|
+
const trimmed = token.trim();
|
|
789
|
+
if (!trimmed) return null;
|
|
790
|
+
const parsed = parse(trimmed, dateFormat, /* @__PURE__ */ new Date());
|
|
791
|
+
return isValid(parsed) ? parsed : null;
|
|
792
|
+
};
|
|
793
|
+
const handlePaste = (e) => {
|
|
794
|
+
onPasteProp?.(e);
|
|
795
|
+
if (e.defaultPrevented) return;
|
|
796
|
+
if (!isWeb || !editable) return;
|
|
797
|
+
const text = e.clipboardData?.getData("text") ?? "";
|
|
798
|
+
if (!text.trim()) return;
|
|
799
|
+
e.preventDefault();
|
|
800
|
+
let next;
|
|
801
|
+
if (isRange) {
|
|
802
|
+
const [startText, endText] = text.split(RANGE_SEPARATOR);
|
|
803
|
+
const start = parseOne(startText ?? "");
|
|
804
|
+
const end = parseOne(endText ?? "");
|
|
805
|
+
if (!start) {
|
|
806
|
+
setParseError(
|
|
807
|
+
`Enter a valid date range (${dateFormat} - ${dateFormat})`
|
|
808
|
+
);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
next = [datePartsFromDate(start), datePartsFromDate(end)];
|
|
812
|
+
} else {
|
|
813
|
+
const date = parseOne(text);
|
|
814
|
+
if (!date) {
|
|
815
|
+
setParseError(`Enter a valid date (${dateFormat})`);
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
next = [datePartsFromDate(date)];
|
|
819
|
+
}
|
|
820
|
+
const outOfBounds = next.map(datePartsToDate).some((d) => d instanceof Date && !isWithinBounds(d));
|
|
821
|
+
if (outOfBounds) {
|
|
822
|
+
setParseError("Date must be within the allowed range");
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
setParseError(null);
|
|
826
|
+
setEdit(null);
|
|
827
|
+
setGroups(next);
|
|
828
|
+
emit(next);
|
|
829
|
+
};
|
|
830
|
+
const handleChipSelect = (value) => {
|
|
831
|
+
chipSelectionRef.current = true;
|
|
832
|
+
setInternalChip(value);
|
|
833
|
+
onChipSelect?.(value);
|
|
834
|
+
};
|
|
835
|
+
const handleDateChange = (date) => applySelection(date);
|
|
836
|
+
const propKey = `${selectedDate?.getTime() ?? ""}|${startDate?.getTime() ?? ""}|${endDate?.getTime() ?? ""}|${isRange}`;
|
|
837
|
+
useEffect(() => {
|
|
838
|
+
if (focused) return;
|
|
839
|
+
setGroups(propGroups());
|
|
840
|
+
setEdit(null);
|
|
841
|
+
setParseError(null);
|
|
842
|
+
}, [propKey]);
|
|
843
|
+
useEffect(() => {
|
|
844
|
+
if (!isWeb || !activeSegment) return;
|
|
845
|
+
const input = inputRef.current;
|
|
846
|
+
if (!input) return;
|
|
847
|
+
const segment = composeField().segments.find(
|
|
848
|
+
(s) => s.group === activeSegment.group && s.type === activeSegment.type
|
|
849
|
+
);
|
|
850
|
+
if (!segment) return;
|
|
851
|
+
let rafId = 0;
|
|
852
|
+
let attempts = 0;
|
|
853
|
+
const apply = () => {
|
|
854
|
+
if (document.activeElement !== input) return;
|
|
855
|
+
if (input.value === inputValue) {
|
|
856
|
+
input.setSelectionRange(segment.start, segment.end);
|
|
857
|
+
} else if (attempts++ < 5) {
|
|
858
|
+
rafId = window.requestAnimationFrame(apply);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
rafId = window.requestAnimationFrame(apply);
|
|
862
|
+
return () => window.cancelAnimationFrame(rafId);
|
|
863
|
+
}, [activeSegment, inputValue]);
|
|
281
864
|
useEffect(() => {
|
|
282
865
|
if (isNative) return;
|
|
283
866
|
const handleClickOutside = (event) => {
|
|
@@ -288,16 +871,86 @@ var DatePicker = forwardRef(
|
|
|
288
871
|
document.addEventListener("mousedown", handleClickOutside);
|
|
289
872
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
290
873
|
}, []);
|
|
874
|
+
useEffect(() => {
|
|
875
|
+
if (!open || !isWeb) return;
|
|
876
|
+
const handleEscape = (event) => {
|
|
877
|
+
if (event.key !== "Escape") return;
|
|
878
|
+
setOpen(false);
|
|
879
|
+
const input = inputRef.current;
|
|
880
|
+
if (input && document.activeElement !== input) {
|
|
881
|
+
suppressReopenRef.current = true;
|
|
882
|
+
input.focus?.();
|
|
883
|
+
}
|
|
884
|
+
};
|
|
885
|
+
document.addEventListener("keydown", handleEscape);
|
|
886
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
887
|
+
}, [open]);
|
|
888
|
+
useEffect(() => {
|
|
889
|
+
if (!open || !isWeb) return;
|
|
890
|
+
if (placement) {
|
|
891
|
+
const next = resolveForcedLayout(placement, dropdownPosition);
|
|
892
|
+
setLayout(
|
|
893
|
+
(prev) => prev.side === next.side && prev.align === next.align ? prev : next
|
|
894
|
+
);
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
const compute = () => {
|
|
898
|
+
const container = containerRef.current;
|
|
899
|
+
if (!container) return;
|
|
900
|
+
const containerRect = container.getBoundingClientRect();
|
|
901
|
+
const panelRect = calendarRef.current ? calendarRef.current.getBoundingClientRect() : FALLBACK_PANEL_SIZE;
|
|
902
|
+
const panel = { width: panelRect.width, height: panelRect.height };
|
|
903
|
+
const viewport = {
|
|
904
|
+
width: window.innerWidth,
|
|
905
|
+
height: window.innerHeight
|
|
906
|
+
};
|
|
907
|
+
const side = resolveAutoPlacement(
|
|
908
|
+
containerRect,
|
|
909
|
+
panel,
|
|
910
|
+
viewport,
|
|
911
|
+
PLACEMENT_OFFSET
|
|
912
|
+
);
|
|
913
|
+
const preferred = side === "top" || side === "bottom" ? alignFromDropdownPosition(dropdownPosition) : "start";
|
|
914
|
+
const align = resolveAlignForSide(
|
|
915
|
+
side,
|
|
916
|
+
containerRect,
|
|
917
|
+
panel,
|
|
918
|
+
viewport,
|
|
919
|
+
preferred
|
|
920
|
+
);
|
|
921
|
+
setLayout(
|
|
922
|
+
(prev) => prev.side === side && prev.align === align ? prev : { side, align }
|
|
923
|
+
);
|
|
924
|
+
};
|
|
925
|
+
const rafId = window.requestAnimationFrame(compute);
|
|
926
|
+
const handleResize = () => compute();
|
|
927
|
+
window.addEventListener("resize", handleResize);
|
|
928
|
+
return () => {
|
|
929
|
+
window.cancelAnimationFrame(rafId);
|
|
930
|
+
window.removeEventListener("resize", handleResize);
|
|
931
|
+
};
|
|
932
|
+
}, [open, placement, dropdownPosition]);
|
|
291
933
|
const overlayThemeProps = {
|
|
292
934
|
themeMode: overlayThemeMode ?? themeMode,
|
|
293
935
|
themeProductContext: overlayThemeProductContext ?? themeProductContext
|
|
294
936
|
};
|
|
937
|
+
const activeParts = activeSegment ? groups[activeSegment.group] : null;
|
|
938
|
+
const editingAnchor = activeParts && activeParts.month != null && activeParts.year != null ? new Date(activeParts.year, activeParts.month - 1, 1) : null;
|
|
939
|
+
const viewAnchor = editingAnchor ?? selectedDate ?? startDate ?? endDate ?? null;
|
|
940
|
+
const viewMonth = useMemo(
|
|
941
|
+
() => viewAnchor ? new Date(viewAnchor.getFullYear(), viewAnchor.getMonth(), 1) : void 0,
|
|
942
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
943
|
+
[viewAnchor?.getFullYear(), viewAnchor?.getMonth()]
|
|
944
|
+
);
|
|
295
945
|
const renderCalendar = () => isDual ? /* @__PURE__ */ jsx2(
|
|
296
946
|
DualCalendar,
|
|
297
947
|
{
|
|
298
948
|
locale,
|
|
299
949
|
startDate,
|
|
300
950
|
endDate,
|
|
951
|
+
minDate,
|
|
952
|
+
maxDate,
|
|
953
|
+
month: viewMonth,
|
|
301
954
|
onChange: handleDateChange,
|
|
302
955
|
chips,
|
|
303
956
|
activeChip: activeChipValue,
|
|
@@ -312,6 +965,9 @@ var DatePicker = forwardRef(
|
|
|
312
965
|
startDate,
|
|
313
966
|
endDate,
|
|
314
967
|
selectedDate,
|
|
968
|
+
minDate,
|
|
969
|
+
maxDate,
|
|
970
|
+
month: viewMonth,
|
|
315
971
|
onChange: handleDateChange,
|
|
316
972
|
selectsRange,
|
|
317
973
|
chips,
|
|
@@ -331,16 +987,26 @@ var DatePicker = forwardRef(
|
|
|
331
987
|
},
|
|
332
988
|
position: "relative",
|
|
333
989
|
width: "100%",
|
|
990
|
+
...isWeb ? { onClick: () => setOpen(true) } : {},
|
|
334
991
|
children: [
|
|
335
992
|
/* @__PURE__ */ jsx2(
|
|
336
993
|
Input,
|
|
337
994
|
{
|
|
338
995
|
...rest,
|
|
996
|
+
ref: inputRef,
|
|
339
997
|
size,
|
|
340
|
-
placeholder: placeholder || (isRange ? "
|
|
998
|
+
placeholder: placeholder || (isRange ? "Enter a date range" : "Choose a date"),
|
|
341
999
|
value: inputValue,
|
|
342
|
-
|
|
343
|
-
onFocus:
|
|
1000
|
+
readOnly,
|
|
1001
|
+
onFocus: handleFieldFocus,
|
|
1002
|
+
onBlur: handleFieldBlur,
|
|
1003
|
+
onKeyDown: handleKeyDown,
|
|
1004
|
+
onClick: handleFieldClick,
|
|
1005
|
+
onPaste: handlePaste,
|
|
1006
|
+
iconRight,
|
|
1007
|
+
iconLeft,
|
|
1008
|
+
error: error || !!parseError,
|
|
1009
|
+
errorMessage: parseError ?? errorMessage,
|
|
344
1010
|
backgroundColor,
|
|
345
1011
|
testID,
|
|
346
1012
|
themeMode,
|
|
@@ -350,12 +1016,18 @@ var DatePicker = forwardRef(
|
|
|
350
1016
|
open && (isWeb ? /* @__PURE__ */ jsx2(
|
|
351
1017
|
Box,
|
|
352
1018
|
{
|
|
1019
|
+
ref: calendarRef,
|
|
1020
|
+
role: "dialog",
|
|
1021
|
+
"aria-modal": true,
|
|
1022
|
+
"aria-label": isRange ? "Choose a date range" : "Choose a date",
|
|
1023
|
+
onClick: (e) => e.stopPropagation(),
|
|
353
1024
|
position: "absolute",
|
|
354
|
-
top: "100%",
|
|
355
|
-
left: dropdownPosition === "left" ? 0 : "auto",
|
|
356
|
-
right: dropdownPosition === "right" ? 0 : "auto",
|
|
357
|
-
marginTop: 4,
|
|
358
1025
|
zIndex: 1e3,
|
|
1026
|
+
style: getPlacementStyle(
|
|
1027
|
+
layout.side,
|
|
1028
|
+
layout.align,
|
|
1029
|
+
PLACEMENT_OFFSET
|
|
1030
|
+
),
|
|
359
1031
|
children: renderCalendar()
|
|
360
1032
|
}
|
|
361
1033
|
) : /* @__PURE__ */ jsx2(Box, { marginTop: 4, children: renderCalendar() }))
|
|
@@ -365,17 +1037,6 @@ var DatePicker = forwardRef(
|
|
|
365
1037
|
}
|
|
366
1038
|
);
|
|
367
1039
|
DatePicker.displayName = "DatePicker";
|
|
368
|
-
|
|
369
|
-
// src/utils.ts
|
|
370
|
-
import { format as format2 } from "date-fns";
|
|
371
|
-
import * as locales from "date-fns/locale";
|
|
372
|
-
var defaultLocale = "enUS";
|
|
373
|
-
function formatDate(date, formatStr, locale = defaultLocale) {
|
|
374
|
-
const localeObj = locales[locale] || locales[defaultLocale];
|
|
375
|
-
return format2(date, formatStr, {
|
|
376
|
-
locale: localeObj
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
1040
|
export {
|
|
380
1041
|
Calendar2 as Calendar,
|
|
381
1042
|
CalendarChips,
|
|
@@ -383,6 +1044,17 @@ export {
|
|
|
383
1044
|
CalendarHeader,
|
|
384
1045
|
DatePicker,
|
|
385
1046
|
DualCalendar2 as DualCalendar,
|
|
386
|
-
|
|
1047
|
+
buildSegmentedValue,
|
|
1048
|
+
clampDatePart,
|
|
1049
|
+
datePartsFromDate,
|
|
1050
|
+
datePartsToDate,
|
|
1051
|
+
daysInMonth,
|
|
1052
|
+
formatDate,
|
|
1053
|
+
getDateSegments,
|
|
1054
|
+
isDatePartsComplete,
|
|
1055
|
+
isSegmentComplete,
|
|
1056
|
+
parseDateFormat,
|
|
1057
|
+
stepDatePart,
|
|
1058
|
+
stepDateSegment
|
|
387
1059
|
};
|
|
388
1060
|
//# sourceMappingURL=index.mjs.map
|