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