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