@bigbinary/neeto-atoms 1.0.145 → 1.1.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.
Files changed (99) hide show
  1. package/dist/{DatePicker-DznpJnhm.js → DatePicker-BC9AOZJ2.js} +696 -131
  2. package/dist/DatePicker-BC9AOZJ2.js.map +1 -0
  3. package/dist/{HelpIcon-CEHRtxZ5.js → HelpIcon-DAi3_HhO.js} +4 -6
  4. package/dist/HelpIcon-DAi3_HhO.js.map +1 -0
  5. package/dist/{Label-C2ZO0-dt.js → Label-CEujas4-.js} +2 -2
  6. package/dist/{Label-C2ZO0-dt.js.map → Label-CEujas4-.js.map} +1 -1
  7. package/dist/{TimePicker-BA7JhrYd.js → TimePicker-CJ8K2zea.js} +192 -17
  8. package/dist/TimePicker-CJ8K2zea.js.map +1 -0
  9. package/dist/{TranslationProvider-Dd0ITHC0.js → TranslationProvider-BJjfFEgX.js} +12 -1
  10. package/dist/{TranslationProvider-Dd0ITHC0.js.map → TranslationProvider-BJjfFEgX.js.map} +1 -1
  11. package/dist/cjs/{DatePicker-CMcp7TGb.js → DatePicker-aGLz-3Bz.js} +707 -141
  12. package/dist/cjs/DatePicker-aGLz-3Bz.js.map +1 -0
  13. package/dist/cjs/{HelpIcon-39gUuk1F.js → HelpIcon-f8_h5Eap.js} +4 -6
  14. package/dist/cjs/HelpIcon-f8_h5Eap.js.map +1 -0
  15. package/dist/cjs/{Label-BLgCH5sc.js → Label-C8u4fXTy.js} +2 -2
  16. package/dist/cjs/{Label-BLgCH5sc.js.map → Label-C8u4fXTy.js.map} +1 -1
  17. package/dist/cjs/{TimePicker-CVGXEgk5.js → TimePicker-BhOW7vbV.js} +217 -41
  18. package/dist/cjs/TimePicker-BhOW7vbV.js.map +1 -0
  19. package/dist/cjs/{TranslationProvider-DOeyGtbV.js → TranslationProvider-C1JDwKEN.js} +12 -1
  20. package/dist/cjs/{TranslationProvider-DOeyGtbV.js.map → TranslationProvider-C1JDwKEN.js.map} +1 -1
  21. package/dist/cjs/components/Checkbox.js +1 -1
  22. package/dist/cjs/components/DatePicker.js +8 -7
  23. package/dist/cjs/components/DatePicker.js.map +1 -1
  24. package/dist/cjs/components/Input.js +1 -1
  25. package/dist/cjs/components/Label.js +2 -2
  26. package/dist/cjs/components/MultiEmailInput.js +1 -1
  27. package/dist/cjs/components/RadioGroup.js +1 -1
  28. package/dist/cjs/components/Select.js +1 -1
  29. package/dist/cjs/components/Slider.js +1 -1
  30. package/dist/cjs/components/Switch.js +1 -1
  31. package/dist/cjs/components/Textarea.js +1 -1
  32. package/dist/cjs/components/TimePicker.js +8 -8
  33. package/dist/cjs/components/TranslationProvider.js +1 -1
  34. package/dist/cjs/components/TreeSelect.js +1 -1
  35. package/dist/cjs/components/index.js +9 -9
  36. package/dist/cjs/formik/Checkbox.js +1 -1
  37. package/dist/cjs/formik/Input.js +1 -1
  38. package/dist/cjs/formik/MultiEmailInput.js +1 -1
  39. package/dist/cjs/formik/RadioGroup.js +1 -1
  40. package/dist/cjs/formik/Select.js +1 -1
  41. package/dist/cjs/formik/Slider.js +1 -1
  42. package/dist/cjs/formik/Switch.js +1 -1
  43. package/dist/cjs/formik/Textarea.js +1 -1
  44. package/dist/cjs/formik/TreeSelect.js +1 -1
  45. package/dist/cjs/formik/index.js +1 -1
  46. package/dist/cjs/index.js +10 -10
  47. package/dist/cjs/primitives/Field.js +1 -1
  48. package/dist/cjs/primitives/index.js +1 -1
  49. package/dist/cjs/{TimePickerPanel-DvVRLqeM.js → utils-S4yTubWZ.js} +25 -197
  50. package/dist/cjs/utils-S4yTubWZ.js.map +1 -0
  51. package/dist/components/Checkbox.js +1 -1
  52. package/dist/components/DatePicker/DatePickerFooter.d.ts +1 -0
  53. package/dist/components/DatePicker/RangeCalendar.d.ts +2 -1
  54. package/dist/components/DatePicker/SegmentedTimeInput.d.ts +17 -0
  55. package/dist/components/DatePicker/TimeSection.d.ts +22 -0
  56. package/dist/components/DatePicker/constants.d.ts +1 -1
  57. package/dist/components/DatePicker/segmentedTime.d.ts +58 -0
  58. package/dist/components/DatePicker/types.d.ts +33 -4
  59. package/dist/components/DatePicker/utils.d.ts +3 -0
  60. package/dist/components/DatePicker.js +8 -7
  61. package/dist/components/DatePicker.js.map +1 -1
  62. package/dist/components/Input.js +1 -1
  63. package/dist/components/Label.js +2 -2
  64. package/dist/components/MultiEmailInput.js +1 -1
  65. package/dist/components/RadioGroup.js +1 -1
  66. package/dist/components/Select.js +1 -1
  67. package/dist/components/Slider.js +1 -1
  68. package/dist/components/Switch.js +1 -1
  69. package/dist/components/Textarea.js +1 -1
  70. package/dist/components/TimePicker.js +7 -7
  71. package/dist/components/TranslationProvider.js +1 -1
  72. package/dist/components/TreeSelect.js +1 -1
  73. package/dist/components/index.js +8 -8
  74. package/dist/formik/Checkbox.js +1 -1
  75. package/dist/formik/Input.js +1 -1
  76. package/dist/formik/MultiEmailInput.js +1 -1
  77. package/dist/formik/RadioGroup.js +1 -1
  78. package/dist/formik/Select.js +1 -1
  79. package/dist/formik/Slider.js +1 -1
  80. package/dist/formik/Switch.js +1 -1
  81. package/dist/formik/Textarea.js +1 -1
  82. package/dist/formik/TreeSelect.js +1 -1
  83. package/dist/formik/index.js +1 -1
  84. package/dist/index.js +10 -10
  85. package/dist/primitives/Field.js +1 -1
  86. package/dist/primitives/index.js +1 -1
  87. package/dist/translations/index.d.ts +11 -0
  88. package/dist/utils/inputMask.d.ts +2 -1
  89. package/dist/{TimePickerPanel-n-Dz1p5N.js → utils-Ca3DmOrC.js} +22 -197
  90. package/dist/utils-Ca3DmOrC.js.map +1 -0
  91. package/package.json +1 -1
  92. package/dist/DatePicker-DznpJnhm.js.map +0 -1
  93. package/dist/HelpIcon-CEHRtxZ5.js.map +0 -1
  94. package/dist/TimePicker-BA7JhrYd.js.map +0 -1
  95. package/dist/TimePickerPanel-n-Dz1p5N.js.map +0 -1
  96. package/dist/cjs/DatePicker-CMcp7TGb.js.map +0 -1
  97. package/dist/cjs/HelpIcon-39gUuk1F.js.map +0 -1
  98. package/dist/cjs/TimePicker-CVGXEgk5.js.map +0 -1
  99. package/dist/cjs/TimePickerPanel-DvVRLqeM.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { forwardRef, useState, useCallback, useMemo, useId, useRef, useEffect } from 'react';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import React__default, { forwardRef, useRef, useState, useEffect, useId, useCallback, useMemo } from 'react';
3
3
  import { Calendar as Calendar$1 } from './primitives/Calendar.js';
4
4
  import { PopoverAnchor, Popover, PopoverTrigger, PopoverContent } from './primitives/Popover.js';
5
5
  import { c as cn } from './utils-BJnb9o5c.js';
6
- import { u as useControlledOpen, l as isFixedWidthFormat, m as buildRangeMaskTemplate, d as buildMaskTemplate, b as useOutsideClickClose, e as useCursorRestore, T as TimePickerPanel, j as applyMask, n as dateToTimeValue } from './TimePickerPanel-n-Dz1p5N.js';
6
+ import { t as to12Hour, a as to24Hour, p as padNumber, d as timeValueEquals, C as Clock, u as useControlledOpen, q as isFixedWidthFormat, r as buildRangeMaskTemplate, h as buildMaskTemplate, e as useOutsideClickClose, j as useCursorRestore, m as applyMask, s as dateToTimeValue } from './utils-Ca3DmOrC.js';
7
7
  import pureDayjs from 'dayjs';
8
8
  import customParseFormat from 'dayjs/plugin/customParseFormat';
9
9
  import { dayjs } from '@bigbinary/neeto-commons-frontend/utils';
@@ -12,6 +12,9 @@ import { Button } from './primitives/Button.js';
12
12
  import { Field, FieldLabel, FieldContent, FieldError, FieldDescription } from './primitives/Field.js';
13
13
  import { c as createLucideIcon } from './createLucideIcon-C8ycilSN.js';
14
14
  import { X } from './x-_o2T3n6D.js';
15
+ import { useTranslation } from 'react-i18next';
16
+ import { Label } from './primitives/Label.js';
17
+ import { Switch } from './primitives/Switch.js';
15
18
  import { C as ChevronLeft } from './chevron-left-BDoT8E2-.js';
16
19
  import { C as ChevronRight } from './chevron-right-DQnrO-ek.js';
17
20
 
@@ -23,16 +26,31 @@ import { C as ChevronRight } from './chevron-right-DQnrO-ek.js';
23
26
  */
24
27
 
25
28
 
26
- const __iconNode = [
29
+ const __iconNode$1 = [
27
30
  ["path", { d: "M8 2v4", key: "1cmpym" }],
28
31
  ["path", { d: "M16 2v4", key: "4m81vk" }],
29
32
  ["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", key: "1hopcy" }],
30
33
  ["path", { d: "M3 10h18", key: "8toen8" }]
31
34
  ];
32
- const Calendar = createLucideIcon("calendar", __iconNode);
35
+ const Calendar = createLucideIcon("calendar", __iconNode$1);
36
+
37
+ /**
38
+ * @license lucide-react v0.577.0 - ISC
39
+ *
40
+ * This source code is licensed under the ISC license.
41
+ * See the LICENSE file in the root directory of this source tree.
42
+ */
43
+
44
+
45
+ const __iconNode = [
46
+ ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
47
+ ["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
48
+ ["path", { d: "M2 12h20", key: "9i4pu4" }]
49
+ ];
50
+ const Globe = createLucideIcon("globe", __iconNode);
33
51
 
34
52
  const DEFAULT_DATE_FORMAT = "dd/MM/yyyy";
35
- const DEFAULT_TIME_FORMAT = "HH:mm:ss";
53
+ const DEFAULT_TIME_FORMAT = "hh:mm A";
36
54
  const CALENDAR_NAVIGATION_YEAR_RANGE = 100;
37
55
  const INITIAL_TIME_VALUE = {
38
56
  hours: 0,
@@ -103,6 +121,33 @@ const getInitialCalendarMonth = (value, defaultValue, type) => {
103
121
  };
104
122
  const normalizeToDayjsFormat = (fmt) => fmt.replace(/\byyyy\b/g, "YYYY").replace(/\byy\b/g, "YY").replace(/\bdd\b/g, "DD").replace(/\bd\b/g, "D");
105
123
  const normalizeToDateFnsFormat = (fmt) => fmt.replace(/YYYY/g, "yyyy").replace(/YY/g, "yy").replace(/DD/g, "dd").replace(/\bD\b/g, "d");
124
+ const roundToMinuteStep = (date, step) => {
125
+ const rounded = new Date(date);
126
+ const minutes = Math.min(
127
+ 60 - step,
128
+ Math.round(date.getMinutes() / step) * step
129
+ );
130
+ rounded.setMinutes(minutes, 0, 0);
131
+ return rounded;
132
+ };
133
+ const getTimezoneLabel = (timezone) => {
134
+ const zone = timezone === "utc" ? "UTC" : dayjs().$x?.$timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;
135
+ try {
136
+ const zoneName = (timeZoneName) => new Intl.DateTimeFormat("en-US", { timeZone: zone, timeZoneName }).formatToParts(/* @__PURE__ */ new Date()).find((part) => part.type === "timeZoneName")?.value;
137
+ const name = zoneName("long") ?? zone;
138
+ const offset = (zoneName("longOffset") ?? "GMT").replace("GMT", "UTC").replace(/([+-])0?(\d+):00$/, "$1$2").replace(/([+-])0(\d)/, "$1$2");
139
+ return `${name} (${offset === "UTC" ? "UTC+0" : offset})`;
140
+ } catch {
141
+ return zone;
142
+ }
143
+ };
144
+ const roundUpToMinuteStep = (date, step) => {
145
+ const rounded = new Date(date);
146
+ const hasSeconds = date.getSeconds() > 0 || date.getMilliseconds() > 0;
147
+ const minutes = date.getMinutes() + (hasSeconds ? 1 : 0);
148
+ rounded.setMinutes(Math.ceil(minutes / step) * step, 0, 0);
149
+ return rounded;
150
+ };
106
151
  const formatDate = (date, formatStr) => {
107
152
  if (!date) return "";
108
153
  try {
@@ -261,6 +306,7 @@ const DatePickerFooter = ({
261
306
  timezone,
262
307
  onTimezoneChange,
263
308
  nowDisabled,
309
+ showNow = true,
264
310
  onNow,
265
311
  onOk,
266
312
  okLabel = "OK",
@@ -275,7 +321,7 @@ const DatePickerFooter = ({
275
321
  className
276
322
  ),
277
323
  children: [
278
- /* @__PURE__ */ jsx(
324
+ showNow && /* @__PURE__ */ jsx(
279
325
  Button,
280
326
  {
281
327
  variant: "ghost",
@@ -435,6 +481,443 @@ const DatePickerTrigger = forwardRef(
435
481
  );
436
482
  DatePickerTrigger.displayName = "DatePickerTrigger";
437
483
 
484
+ const SEGMENT_KEYS = ["hour", "minute", "period"];
485
+ const EMPTY_SEGMENT = { text: "", done: false, auto: false };
486
+ const segment = (text, done, auto = false) => ({
487
+ text,
488
+ done,
489
+ auto
490
+ });
491
+ const clampIndex = (index) => Math.max(0, Math.min(2, index));
492
+ const withSegment = (state, key, value) => ({ ...state, [key]: value });
493
+ const snapMinute = (minutes, step = 1) => padNumber(Math.min(60 - step, Math.round(Number(minutes) / step) * step));
494
+ const emptySegmentedTime = () => ({
495
+ hour: EMPTY_SEGMENT,
496
+ minute: EMPTY_SEGMENT,
497
+ period: EMPTY_SEGMENT,
498
+ active: 0
499
+ });
500
+ const segmentedTimeFromValue = (value, step = 1) => {
501
+ const { hour12, period } = to12Hour(value.hours);
502
+ return {
503
+ hour: segment(String(hour12), true),
504
+ minute: segment(snapMinute(value.minutes, step), true),
505
+ period: segment(period, true),
506
+ active: 0
507
+ };
508
+ };
509
+ const isSegmentedTimeEmpty = (state) => SEGMENT_KEYS.every((key) => state[key].text === "");
510
+ const getSegmentedTimeError = (state) => {
511
+ if (isSegmentedTimeEmpty(state)) return "timeRequired";
512
+ if (!state.hour.text) return "hourRequired";
513
+ if (!state.minute.text) return "minuteRequired";
514
+ if (!state.period.text) return "periodRequired";
515
+ return null;
516
+ };
517
+ const segmentedTimeToValue = (state) => {
518
+ if (getSegmentedTimeError(state)) return null;
519
+ return {
520
+ hours: to24Hour(Number(state.hour.text), state.period.text),
521
+ minutes: Number(state.minute.text),
522
+ seconds: 0
523
+ };
524
+ };
525
+ const finishSegment = (state, key, step) => {
526
+ const { text } = state[key];
527
+ if (!text) return state;
528
+ if (key === "hour" && text === "0") {
529
+ return withSegment(state, "hour", EMPTY_SEGMENT);
530
+ }
531
+ if (key === "minute" && text.length === 1) {
532
+ return withSegment(
533
+ state,
534
+ "minute",
535
+ segment(snapMinute(text, step), true, true)
536
+ );
537
+ }
538
+ return withSegment(state, key, { ...state[key], done: true });
539
+ };
540
+ const finishActiveSegment = (state, step = 1) => finishSegment(state, SEGMENT_KEYS[state.active], step);
541
+ const focusSegment = (state, index, step = 1) => {
542
+ const next = clampIndex(index);
543
+ const finished = next > state.active ? finishActiveSegment(state, step) : state;
544
+ return { ...finished, active: next };
545
+ };
546
+ const focusFirstEmptySegment = (state) => {
547
+ const index = SEGMENT_KEYS.findIndex((key) => !state[key].text);
548
+ return { ...state, active: index === -1 ? 2 : index };
549
+ };
550
+ const nextSegment = (state, step = 1) => state[SEGMENT_KEYS[state.active]].text ? focusSegment(state, state.active + 1, step) : state;
551
+ const previousSegment = (state) => focusSegment(state, state.active - 1);
552
+ const typeDigit = (state, digit, step = 1) => {
553
+ const advance = (next, index) => focusSegment(next, index, step);
554
+ const key = SEGMENT_KEYS[state.active];
555
+ if (key === "period") return state;
556
+ const current = state[key];
557
+ const text = current.done ? "" : current.text;
558
+ if (key === "hour") {
559
+ if (text === "") {
560
+ if (digit === "0" || digit === "1") {
561
+ return withSegment(state, "hour", segment(digit, false));
562
+ }
563
+ return advance(withSegment(state, "hour", segment(digit, true)), 1);
564
+ }
565
+ if (text === "1") {
566
+ if ("012".includes(digit)) {
567
+ return advance(
568
+ withSegment(state, "hour", segment(`1${digit}`, true)),
569
+ 1
570
+ );
571
+ }
572
+ const moved = advance(withSegment(state, "hour", segment("1", true)), 1);
573
+ return typeDigit(moved, digit, step);
574
+ }
575
+ if (digit === "0") return state;
576
+ return advance(withSegment(state, "hour", segment(digit, true)), 1);
577
+ }
578
+ if (text === "") {
579
+ if (digit >= "6") {
580
+ return advance(
581
+ withSegment(
582
+ state,
583
+ "minute",
584
+ segment(snapMinute(digit, step), true, true)
585
+ ),
586
+ 2
587
+ );
588
+ }
589
+ return withSegment(state, "minute", segment(digit, false));
590
+ }
591
+ return advance(
592
+ withSegment(state, "minute", segment(snapMinute(text + digit, step), true)),
593
+ 2
594
+ );
595
+ };
596
+ const typePeriod = (state, letter, step = 1) => withSegment(
597
+ focusSegment(state, 2, step),
598
+ "period",
599
+ segment(letter === "a" ? "AM" : "PM", true)
600
+ );
601
+ const togglePeriod = (state) => withSegment(
602
+ state,
603
+ "period",
604
+ segment(state.period.text === "AM" ? "PM" : "AM", true)
605
+ );
606
+ const stepSegment = (state, direction, step = 1) => {
607
+ const key = SEGMENT_KEYS[state.active];
608
+ if (key === "hour") {
609
+ const hour = Number(state.hour.text) || (direction > 0 ? 0 : 1);
610
+ const next = (hour - 1 + direction + 12) % 12 + 1;
611
+ return withSegment(state, "hour", segment(String(next), true));
612
+ }
613
+ if (key === "minute") {
614
+ const minute = state.minute.text === "" ? direction > 0 ? -step : 0 : Number(state.minute.text);
615
+ const stepped = direction > 0 ? Math.floor(minute / step) * step + step : Math.ceil(minute / step) * step - step;
616
+ return withSegment(
617
+ state,
618
+ "minute",
619
+ segment(padNumber((stepped + 60) % 60), true)
620
+ );
621
+ }
622
+ return togglePeriod(state);
623
+ };
624
+ const backspace = (state) => {
625
+ const moveBack = state[SEGMENT_KEYS[state.active]].text === "" && state.active > 0;
626
+ const active = moveBack ? clampIndex(state.active - 1) : state.active;
627
+ const key = SEGMENT_KEYS[active];
628
+ const current = state[key];
629
+ const text = key === "period" || current.auto ? "" : current.text.slice(0, -1);
630
+ return { ...withSegment(state, key, segment(text, false)), active };
631
+ };
632
+ const parsePastedTime = (text, step = 1) => {
633
+ const match = text.trim().toLowerCase().match(/^(\d{1,2}):?(\d{2})?\s*([ap])?\.?m?\.?$/);
634
+ if (!match) return null;
635
+ let hours = Number(match[1]);
636
+ const minutes = Number(match[2] ?? 0);
637
+ const period = match[3];
638
+ if (minutes > 59) return null;
639
+ if (period) {
640
+ if (hours < 1 || hours > 12) return null;
641
+ hours = hours % 12 + (period === "p" ? 12 : 0);
642
+ } else if (hours > 23) {
643
+ return null;
644
+ }
645
+ return { hours, minutes: Number(snapMinute(minutes, step)), seconds: 0 };
646
+ };
647
+
648
+ const PLACEHOLDERS = ["hh", "mm", "--"];
649
+ const SegmentedTimeInput = ({
650
+ value,
651
+ minuteStep,
652
+ onChange,
653
+ onErrorChange,
654
+ invalid = false,
655
+ disabled = false,
656
+ autoFocus = false,
657
+ "aria-describedby": ariaDescribedBy
658
+ }) => {
659
+ const { t } = useTranslation();
660
+ const fieldRef = useRef(null);
661
+ const step = minuteStep ?? 1;
662
+ const [time, setTime] = useState(
663
+ () => segmentedTimeFromValue(value, step)
664
+ );
665
+ const lastEmittedRef = useRef(value);
666
+ useEffect(() => {
667
+ if (timeValueEquals(value, lastEmittedRef.current)) return;
668
+ lastEmittedRef.current = value;
669
+ setTime(segmentedTimeFromValue(value, step));
670
+ }, [value]);
671
+ const error = getSegmentedTimeError(time);
672
+ useEffect(() => {
673
+ onErrorChange(error);
674
+ }, [error, onErrorChange]);
675
+ useEffect(() => {
676
+ const snapped = segmentedTimeToValue(time);
677
+ if (snapped && !timeValueEquals(snapped, value)) {
678
+ lastEmittedRef.current = snapped;
679
+ onChange(snapped);
680
+ }
681
+ }, []);
682
+ useEffect(() => {
683
+ if (autoFocus) fieldRef.current?.focus();
684
+ }, [autoFocus]);
685
+ const update = (next) => {
686
+ setTime(next);
687
+ const nextValue = segmentedTimeToValue(next);
688
+ if (!nextValue || timeValueEquals(nextValue, lastEmittedRef.current)) {
689
+ return;
690
+ }
691
+ lastEmittedRef.current = nextValue;
692
+ onChange(nextValue);
693
+ };
694
+ const consume = (event) => {
695
+ event.preventDefault();
696
+ event.stopPropagation();
697
+ };
698
+ const handleKeyDown = (event) => {
699
+ const { key } = event;
700
+ if (key === "Tab") {
701
+ if (!event.shiftKey || time.active !== 2) return;
702
+ consume(event);
703
+ update(togglePeriod(time));
704
+ return;
705
+ }
706
+ if ((event.metaKey || event.ctrlKey) && key === "Backspace") {
707
+ consume(event);
708
+ update(emptySegmentedTime());
709
+ return;
710
+ }
711
+ if (event.metaKey || event.ctrlKey || event.altKey) return;
712
+ let next = null;
713
+ if (/^[0-9]$/.test(key)) next = typeDigit(time, key, step);
714
+ else if (/^[ap]$/i.test(key)) {
715
+ next = typePeriod(time, key.toLowerCase(), step);
716
+ } else if (/^m$/i.test(key))
717
+ next = time;
718
+ else if (key === ":" || key === " " || key === "ArrowRight") {
719
+ next = nextSegment(time, step);
720
+ } else if (key === "ArrowLeft") next = previousSegment(time);
721
+ else if (key === "ArrowUp") next = stepSegment(time, 1, step);
722
+ else if (key === "ArrowDown") next = stepSegment(time, -1, step);
723
+ else if (key === "Backspace" || key === "Delete") next = backspace(time);
724
+ if (!next) return;
725
+ consume(event);
726
+ update(next);
727
+ };
728
+ const handlePaste = (event) => {
729
+ event.preventDefault();
730
+ const pasted = parsePastedTime(event.clipboardData.getData("text"), step);
731
+ if (pasted) update({ ...segmentedTimeFromValue(pasted, step), active: 2 });
732
+ };
733
+ const handleMouseDown = (event) => {
734
+ if (disabled) return;
735
+ const segmentEl = event.target.closest(
736
+ "[data-segment]"
737
+ );
738
+ if (segmentEl) {
739
+ event.preventDefault();
740
+ fieldRef.current?.focus();
741
+ update(focusSegment(time, Number(segmentEl.dataset.segment), step));
742
+ return;
743
+ }
744
+ update(focusFirstEmptySegment(time));
745
+ };
746
+ const segmentText = (index) => {
747
+ const { text, done } = time[SEGMENT_KEYS[index]];
748
+ if (!text) return PLACEHOLDERS[index];
749
+ return index < 2 && !done ? `${text}_` : text;
750
+ };
751
+ return /* @__PURE__ */ jsx(
752
+ "div",
753
+ {
754
+ ref: fieldRef,
755
+ role: "group",
756
+ tabIndex: disabled ? -1 : 0,
757
+ "aria-label": t("neetoatoms.datePicker.timeField", "Time"),
758
+ "aria-describedby": ariaDescribedBy,
759
+ "aria-invalid": invalid || void 0,
760
+ "aria-disabled": disabled || void 0,
761
+ "data-testid": "datepicker-time-input",
762
+ className: cn(
763
+ "group/time flex h-9 w-full cursor-text items-center rounded-md border border-input bg-transparent px-3 text-sm tabular-nums outline-none select-none",
764
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
765
+ invalid && "border-destructive",
766
+ disabled && "pointer-events-none cursor-not-allowed opacity-50"
767
+ ),
768
+ onBlur: () => update(finishActiveSegment(time, step)),
769
+ onKeyDown: handleKeyDown,
770
+ onMouseDown: handleMouseDown,
771
+ onPaste: handlePaste,
772
+ children: SEGMENT_KEYS.map((key, index) => /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
773
+ index === 1 && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "px-0.5 text-muted-foreground", children: ":" }),
774
+ index === 2 && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "w-1" }),
775
+ /* @__PURE__ */ jsx(
776
+ "span",
777
+ {
778
+ "data-segment": index,
779
+ "data-testid": `datepicker-time-${key}`,
780
+ className: cn(
781
+ "min-w-[2ch] px-0.5 text-center whitespace-pre",
782
+ !time[key].text && "text-muted-foreground",
783
+ index === time.active && "group-focus/time:shadow-[inset_0_-1.5px_0_var(--color-muted-foreground)]"
784
+ ),
785
+ children: segmentText(index)
786
+ }
787
+ )
788
+ ] }, key))
789
+ }
790
+ );
791
+ };
792
+ SegmentedTimeInput.displayName = "SegmentedTimeInput";
793
+
794
+ const ERROR_DEFAULTS = {
795
+ timeRequired: "Enter a time, or turn off Add time.",
796
+ hourRequired: "Enter an hour.",
797
+ minuteRequired: "Enter minutes.",
798
+ periodRequired: "Type a or p for AM or PM."
799
+ };
800
+ const stepExamples = (step) => {
801
+ const pad = (minutes) => `1:${String(minutes).padStart(2, "0")}`;
802
+ if (step * 2 >= 60) return [pad(0), pad(step)];
803
+ return [pad(step), pad(30 % step === 0 && step < 30 ? 30 : step * 2)];
804
+ };
805
+ const TimeSection = ({
806
+ value,
807
+ minuteStep,
808
+ onChange,
809
+ onErrorChange,
810
+ showError,
811
+ optional,
812
+ hasTime,
813
+ onHasTimeChange,
814
+ timezoneLabel,
815
+ disabled = false,
816
+ className
817
+ }) => {
818
+ const { t } = useTranslation();
819
+ const id = useId();
820
+ const switchId = `datepicker-add-time-${id}`;
821
+ const hintId = `datepicker-time-hint-${id}`;
822
+ const errorId = `datepicker-time-error-${id}`;
823
+ const [error, setError] = useState(null);
824
+ const [focusOnMount, setFocusOnMount] = useState(false);
825
+ const handleErrorChange = useCallback(
826
+ (nextError) => {
827
+ setError(nextError);
828
+ onErrorChange(!!nextError);
829
+ },
830
+ [onErrorChange]
831
+ );
832
+ const handleHasTimeChange = (checked) => {
833
+ setFocusOnMount(checked);
834
+ if (!checked) {
835
+ setError(null);
836
+ onErrorChange(false);
837
+ }
838
+ onHasTimeChange(checked);
839
+ };
840
+ const isTimeOn = !optional || hasTime;
841
+ const showHint = (minuteStep ?? 1) > 1;
842
+ const errorMessage = isTimeOn && showError && error ? t(`neetoatoms.datePicker.errors.${error}`, ERROR_DEFAULTS[error]) : null;
843
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
844
+ optional && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
845
+ /* @__PURE__ */ jsxs(
846
+ Label,
847
+ {
848
+ htmlFor: switchId,
849
+ className: "flex items-center gap-2 font-medium",
850
+ children: [
851
+ /* @__PURE__ */ jsx(Clock, { "aria-hidden": true, className: "size-4 text-muted-foreground" }),
852
+ t("neetoatoms.datePicker.addTime", "Add time")
853
+ ]
854
+ }
855
+ ),
856
+ /* @__PURE__ */ jsx(
857
+ Switch,
858
+ {
859
+ id: switchId,
860
+ checked: hasTime,
861
+ "data-testid": "datepicker-add-time-switch",
862
+ disabled,
863
+ onCheckedChange: handleHasTimeChange
864
+ }
865
+ )
866
+ ] }),
867
+ isTimeOn && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
868
+ /* @__PURE__ */ jsx(
869
+ SegmentedTimeInput,
870
+ {
871
+ "aria-describedby": [showHint ? hintId : null, errorMessage ? errorId : null].filter(Boolean).join(" ") || void 0,
872
+ autoFocus: focusOnMount,
873
+ disabled,
874
+ invalid: !!errorMessage,
875
+ minuteStep,
876
+ value,
877
+ onChange,
878
+ onErrorChange: handleErrorChange
879
+ }
880
+ ),
881
+ showHint && /* @__PURE__ */ jsx(
882
+ "p",
883
+ {
884
+ id: hintId,
885
+ className: "text-xs text-muted-foreground",
886
+ "data-testid": "datepicker-time-hint",
887
+ children: t("neetoatoms.datePicker.timeHint", {
888
+ step: minuteStep,
889
+ first: stepExamples(minuteStep)[0],
890
+ second: stepExamples(minuteStep)[1],
891
+ defaultValue: "Only {{step}}-minute steps are allowed, like {{first}} or {{second}}."
892
+ })
893
+ }
894
+ ),
895
+ errorMessage && /* @__PURE__ */ jsx(
896
+ "p",
897
+ {
898
+ id: errorId,
899
+ className: "text-xs text-destructive",
900
+ "data-testid": "datepicker-time-error",
901
+ role: "alert",
902
+ children: errorMessage
903
+ }
904
+ ),
905
+ timezoneLabel && /* @__PURE__ */ jsxs(
906
+ "p",
907
+ {
908
+ className: "mt-1 flex items-center gap-2 text-xs text-muted-foreground",
909
+ "data-testid": "datepicker-timezone",
910
+ children: [
911
+ /* @__PURE__ */ jsx(Globe, { "aria-hidden": true, className: "size-3.5 shrink-0" }),
912
+ timezoneLabel
913
+ ]
914
+ }
915
+ )
916
+ ] })
917
+ ] });
918
+ };
919
+ TimeSection.displayName = "TimeSection";
920
+
438
921
  const MonthPicker = ({
439
922
  value,
440
923
  displayedYear,
@@ -507,7 +990,8 @@ const RangeCalendar = ({
507
990
  endMonth,
508
991
  onHoverIn,
509
992
  onHoverOut,
510
- numberOfMonths = 2
993
+ numberOfMonths = 2,
994
+ className
511
995
  }) => /* @__PURE__ */ jsx("div", { onMouseOver: onHoverIn, onMouseLeave: onHoverOut, children: /* @__PURE__ */ jsx(
512
996
  Calendar$1,
513
997
  {
@@ -516,7 +1000,10 @@ const RangeCalendar = ({
516
1000
  captionLayout: "dropdown",
517
1001
  today: todayDate,
518
1002
  weekStartsOn,
519
- className: "[&_[data-outside][data-selected=true]]:!bg-transparent [&_[data-outside][data-selected=true]]:after:!bg-transparent [&_[data-outside]_button]:!bg-transparent [&_[data-outside]_button]:!text-muted-foreground",
1003
+ className: cn(
1004
+ "[&_[data-outside][data-selected=true]]:!bg-transparent [&_[data-outside][data-selected=true]]:after:!bg-transparent [&_[data-outside]_button]:!bg-transparent [&_[data-outside]_button]:!text-muted-foreground",
1005
+ className
1006
+ ),
520
1007
  month,
521
1008
  onMonthChange,
522
1009
  selected,
@@ -690,6 +1177,11 @@ const YearPicker = ({
690
1177
  ] });
691
1178
  };
692
1179
 
1180
+ const TIME_SECTION_CLASS_NAME = "w-0 min-w-full border-t border-border px-3 py-3";
1181
+ const SHOW_TIME_CALENDAR_CLASS_NAME = "[--cell-size:--spacing(8.125)]";
1182
+ const DEFAULT_ADDED_TIME = { hours: 12, minutes: 0, seconds: 0 };
1183
+ const noop = () => {
1184
+ };
693
1185
  const DatePicker = forwardRef(
694
1186
  ({
695
1187
  value,
@@ -700,8 +1192,10 @@ const DatePicker = forwardRef(
700
1192
  dateFormat = DEFAULT_DATE_FORMAT,
701
1193
  timeFormat = DEFAULT_TIME_FORMAT,
702
1194
  showTime = false,
703
- timePickerFormat,
704
- showSeconds = false,
1195
+ showNow = true,
1196
+ minuteStep,
1197
+ timeOptional = true,
1198
+ hasTime: hasTimeProp,
705
1199
  minDate,
706
1200
  maxDate,
707
1201
  disabledDate,
@@ -714,6 +1208,7 @@ const DatePicker = forwardRef(
714
1208
  allowClear = true,
715
1209
  required = false,
716
1210
  timezone,
1211
+ timezoneLabel: timezoneLabelProp,
717
1212
  onTimezoneChange,
718
1213
  onOk,
719
1214
  needConfirm = false,
@@ -748,6 +1243,15 @@ const DatePicker = forwardRef(
748
1243
  const [pendingDate, setPendingDate] = useState(null);
749
1244
  const [pendingTime, setPendingTime] = useState(INITIAL_TIME_VALUE);
750
1245
  const [pendingTimeTo, setPendingTimeTo] = useState(INITIAL_TIME_VALUE);
1246
+ const [hasTimeError, setHasTimeError] = useState(false);
1247
+ const [isTimeErrorRequested, setIsTimeErrorRequested] = useState(false);
1248
+ const isTimeOptional = showTime && timeOptional && type === "date";
1249
+ const [internalHasTime, setInternalHasTime] = useState(
1250
+ () => hasTimeProp ?? (value ?? defaultValue) != null
1251
+ );
1252
+ const committedHasTime = showTime && (!isTimeOptional || (hasTimeProp ?? internalHasTime));
1253
+ const [pendingHasTime, setPendingHasTime] = useState(committedHasTime);
1254
+ const isPendingTimeOn = showTime && (!isTimeOptional || pendingHasTime);
751
1255
  const currentValue = useMemo(
752
1256
  () => value !== void 0 ? coerceDateValue(value, type) : internalValue,
753
1257
  [value, type, internalValue]
@@ -760,10 +1264,13 @@ const DatePicker = forwardRef(
760
1264
  () => toNativeDate(maxDate) ?? void 0,
761
1265
  [maxDate]
762
1266
  );
763
- const displayFormat = getDisplayFormat(dateFormat, timeFormat, showTime);
1267
+ const displayFormat = getDisplayFormat(
1268
+ dateFormat,
1269
+ timeFormat,
1270
+ committedHasTime
1271
+ );
764
1272
  const sizeConfig = SIZE_CONFIG[size];
765
1273
  const maskEnabled = isFixedWidthFormat(displayFormat);
766
- const effectiveTimePickerFormat = timePickerFormat ?? (/\ba\b/i.test(timeFormat) ? "12" : "24");
767
1274
  const defaultPlaceholder = getDatePlaceholder(
768
1275
  dateFormat,
769
1276
  timeFormat,
@@ -800,38 +1307,46 @@ const DatePicker = forwardRef(
800
1307
  return `${from} - ${to}`;
801
1308
  }, [currentValue, displayFormat, type]);
802
1309
  const [inputText, setInputText] = useState(() => getDisplayText());
803
- const commitValue = (date) => {
1310
+ const emitChange = (changed, formatted, withTime) => {
1311
+ if (isTimeOptional) onChange?.(changed, formatted, { hasTime: withTime });
1312
+ else onChange?.(changed, formatted);
1313
+ };
1314
+ const commitValue = (date, withTime = committedHasTime) => {
804
1315
  if (date === null) {
805
1316
  setInternalValue(null);
1317
+ setInternalHasTime(false);
806
1318
  if (type === "range") {
807
- onChange?.([null, null], ["", ""]);
1319
+ emitChange([null, null], ["", ""], false);
808
1320
  } else {
809
- onChange?.(null, "");
1321
+ emitChange(null, "", false);
810
1322
  }
811
1323
  setInputText("");
812
1324
  return;
813
1325
  }
1326
+ const commitFormat = getDisplayFormat(dateFormat, timeFormat, withTime);
814
1327
  const toSerializableDayjs = (d) => {
815
1328
  const userTzDayjs = toUserTzDayjs(d);
816
- if (showTime) return userTzDayjs;
1329
+ if (withTime) return userTzDayjs;
817
1330
  return userTzDayjs.hour(12).minute(0).second(0).millisecond(0);
818
1331
  };
819
1332
  if (Array.isArray(date)) {
820
1333
  setInternalValue(date);
821
1334
  const formatted2 = [
822
- formatDate(date[0], displayFormat),
823
- formatDate(date[1], displayFormat)
1335
+ formatDate(date[0], commitFormat),
1336
+ formatDate(date[1], commitFormat)
824
1337
  ];
825
- onChange?.(
1338
+ emitChange(
826
1339
  [toSerializableDayjs(date[0]), toSerializableDayjs(date[1])],
827
- formatted2
1340
+ formatted2,
1341
+ withTime
828
1342
  );
829
1343
  setInputText(`${formatted2[0]} - ${formatted2[1]}`);
830
1344
  return;
831
1345
  }
832
1346
  setInternalValue(date);
833
- const formatted = formatDate(date, displayFormat);
834
- onChange?.(toSerializableDayjs(date), formatted);
1347
+ setInternalHasTime(withTime);
1348
+ const formatted = formatDate(date, commitFormat);
1349
+ emitChange(toSerializableDayjs(date), formatted, withTime);
835
1350
  setInputText(formatted);
836
1351
  };
837
1352
  const {
@@ -891,30 +1406,33 @@ const DatePicker = forwardRef(
891
1406
  };
892
1407
  const commitPendingOnClose = useCallback(() => {
893
1408
  const hasOkButton = showTime || needConfirm;
894
- if (!hasOkButton || !pendingDate) {
1409
+ if (!hasOkButton || !pendingDate || isPendingTimeOn && hasTimeError) {
895
1410
  setInputText(getDisplayText());
896
1411
  return;
897
1412
  }
898
- const finalDate = showTime ? applyTimeToDate(pendingDate, pendingTime) : pendingDate;
1413
+ const finalDate = isPendingTimeOn ? applyTimeToDate(pendingDate, pendingTime) : pendingDate;
899
1414
  const currentSingle = type === "date" ? currentValue : null;
900
- const isSame = currentSingle && finalDate.getTime() === currentSingle.getTime();
1415
+ const isSame = currentSingle && isPendingTimeOn === committedHasTime && finalDate.getTime() === currentSingle.getTime();
901
1416
  if (isSame) {
902
1417
  setInputText(getDisplayText());
903
1418
  return;
904
1419
  }
905
- commitValue(finalDate);
1420
+ commitValue(finalDate, isPendingTimeOn);
906
1421
  }, [
907
1422
  showTime,
908
1423
  needConfirm,
909
1424
  pendingDate,
910
1425
  pendingTime,
1426
+ isPendingTimeOn,
1427
+ committedHasTime,
911
1428
  type,
912
1429
  currentValue,
913
1430
  getDisplayText,
914
- onChange
1431
+ onChange,
1432
+ hasTimeError
915
1433
  ]);
916
1434
  const closePopover = useCallback(() => {
917
- if (type === "range" && pendingRange?.[0] && pendingRange?.[1]) {
1435
+ if (type === "range" && pendingRange?.[0] && pendingRange?.[1] && !(showTime && hasTimeError)) {
918
1436
  const [fromBase, toBase] = orderRange(
919
1437
  pendingRange[0],
920
1438
  pendingRange[1]
@@ -935,7 +1453,8 @@ const DatePicker = forwardRef(
935
1453
  pendingTime,
936
1454
  pendingTimeTo,
937
1455
  showTime,
938
- resetTransientState
1456
+ resetTransientState,
1457
+ hasTimeError
939
1458
  ]);
940
1459
  useOutsideClickClose({
941
1460
  enabled: open,
@@ -946,6 +1465,7 @@ const DatePicker = forwardRef(
946
1465
  const openPopover = () => {
947
1466
  setOpen(true);
948
1467
  resetTransientState();
1468
+ setIsTimeErrorRequested(false);
949
1469
  if (type === "range") {
950
1470
  const rangeVal = currentValue;
951
1471
  const fromDate = rangeVal?.[0] ?? null;
@@ -958,14 +1478,19 @@ const DatePicker = forwardRef(
958
1478
  return;
959
1479
  }
960
1480
  const dateVal = currentValue;
1481
+ setPendingHasTime(committedHasTime);
961
1482
  if (!dateVal) {
962
1483
  setPendingDate(null);
963
- setPendingTime(INITIAL_TIME_VALUE);
1484
+ setPendingTime(
1485
+ isTimeOptional ? DEFAULT_ADDED_TIME : INITIAL_TIME_VALUE
1486
+ );
964
1487
  return;
965
1488
  }
966
1489
  setCalendarMonth(dateVal);
967
1490
  setPendingDate(dateVal);
968
- setPendingTime(dateToTimeValue(dateVal));
1491
+ setPendingTime(
1492
+ committedHasTime || !isTimeOptional ? dateToTimeValue(dateVal) : DEFAULT_ADDED_TIME
1493
+ );
969
1494
  };
970
1495
  const handleDateSelect = (selected) => {
971
1496
  if (!selected) return;
@@ -978,7 +1503,9 @@ const DatePicker = forwardRef(
978
1503
  setOpen(false);
979
1504
  };
980
1505
  const handleNow = () => {
981
- const now = toBrowserLocalDate(/* @__PURE__ */ new Date());
1506
+ const now = toBrowserLocalDate(
1507
+ showTime && minuteStep ? roundUpToMinuteStep(/* @__PURE__ */ new Date(), minuteStep) : /* @__PURE__ */ new Date()
1508
+ );
982
1509
  if (calendarDisabled(now)) return;
983
1510
  setCalendarMonth(now);
984
1511
  if (type === "range") {
@@ -993,12 +1520,17 @@ const DatePicker = forwardRef(
993
1520
  if (showTime || needConfirm) {
994
1521
  setPendingDate(now);
995
1522
  setPendingTime(dateToTimeValue(now));
1523
+ if (isTimeOptional) setPendingHasTime(true);
996
1524
  return;
997
1525
  }
998
1526
  commitValue(now);
999
1527
  setOpen(false);
1000
1528
  };
1001
1529
  const handleOk = () => {
1530
+ if (isPendingTimeOn && hasTimeError) {
1531
+ setIsTimeErrorRequested(true);
1532
+ return;
1533
+ }
1002
1534
  if (type === "range" && (showTime || needConfirm)) {
1003
1535
  const committedRange = currentValue;
1004
1536
  const fromValue = pendingRange?.[0] ?? committedRange?.[0] ?? null;
@@ -1017,7 +1549,7 @@ const DatePicker = forwardRef(
1017
1549
  const [fromBase, toBase] = orderRange(fromValue, toValue);
1018
1550
  const fromFinal = showTime ? applyTimeToDate(fromBase, pendingTime) : fromBase;
1019
1551
  const toFinal = showTime ? applyTimeToDate(toBase, pendingTimeTo) : toBase;
1020
- commitValue([fromFinal, toFinal]);
1552
+ commitValue([fromFinal, toFinal], showTime);
1021
1553
  onOk?.([fromFinal, toFinal]);
1022
1554
  resetTransientState();
1023
1555
  setOpen(false);
@@ -1026,8 +1558,8 @@ const DatePicker = forwardRef(
1026
1558
  return;
1027
1559
  }
1028
1560
  if (pendingDate) {
1029
- const finalDate = showTime ? applyTimeToDate(pendingDate, pendingTime) : pendingDate;
1030
- commitValue(finalDate);
1561
+ const finalDate = isPendingTimeOn ? applyTimeToDate(pendingDate, pendingTime) : pendingDate;
1562
+ commitValue(finalDate, isPendingTimeOn);
1031
1563
  onOk?.(finalDate);
1032
1564
  }
1033
1565
  setOpen(false);
@@ -1082,10 +1614,21 @@ const DatePicker = forwardRef(
1082
1614
  maskEnabled,
1083
1615
  singleDateLen
1084
1616
  );
1085
- if (range) commitValue(range);
1617
+ if (range) {
1618
+ commitValue(
1619
+ showTime && minuteStep ? [
1620
+ roundToMinuteStep(range[0], minuteStep),
1621
+ roundToMinuteStep(range[1], minuteStep)
1622
+ ] : range
1623
+ );
1624
+ }
1086
1625
  } else {
1087
1626
  const parsed = parseDate(inputText, displayFormat);
1088
- if (parsed) commitValue(parsed);
1627
+ if (parsed) {
1628
+ commitValue(
1629
+ committedHasTime && minuteStep ? roundToMinuteStep(parsed, minuteStep) : parsed
1630
+ );
1631
+ }
1089
1632
  }
1090
1633
  setOpen(false);
1091
1634
  };
@@ -1105,10 +1648,20 @@ const DatePicker = forwardRef(
1105
1648
  const dateVal = currentValue;
1106
1649
  if (dateVal instanceof Date) setCalendarMonth(dateVal);
1107
1650
  }, [open]);
1651
+ const timezoneLabel = showTime && !onTimezoneChange ? (timezoneLabelProp ?? getTimezoneLabel(timezone)) || null : null;
1108
1652
  const hasField = !!(label || error || helpText);
1109
1653
  const testIdPrefix = buildTestIdPrefix(dataTestId, label);
1110
1654
  const showFooter = showTime || needConfirm || !!onTimezoneChange;
1111
1655
  const todayDate = toBrowserLocalDate(/* @__PURE__ */ new Date());
1656
+ const handleHasTimeChange = (checked) => {
1657
+ setPendingHasTime(checked);
1658
+ setIsTimeErrorRequested(false);
1659
+ if (!checked) setHasTimeError(false);
1660
+ if (checked && !pendingDate && !calendarDisabled(todayDate)) {
1661
+ setPendingDate(todayDate);
1662
+ setCalendarMonth(todayDate);
1663
+ }
1664
+ };
1112
1665
  const defaultStartMonth = new Date(
1113
1666
  todayDate.getFullYear() - CALENDAR_NAVIGATION_YEAR_RANGE,
1114
1667
  0,
@@ -1207,99 +1760,110 @@ const DatePicker = forwardRef(
1207
1760
  onPointerDownOutside: (e) => e.preventDefault(),
1208
1761
  onInteractOutside: (e) => e.preventDefault(),
1209
1762
  children: [
1210
- /* @__PURE__ */ jsxs("div", { className: cn("flex", showTime && "flex-row"), children: [
1211
- type === "date" && picker === "month" ? /* @__PURE__ */ jsx(
1212
- MonthPicker,
1213
- {
1214
- value: currentValue ?? null,
1215
- displayedYear: calendarMonth.getFullYear(),
1216
- onYearChange: (year) => setCalendarMonth(
1217
- new Date(year, calendarMonth.getMonth(), 1)
1218
- ),
1219
- onSelect: handleGridPickerSelect,
1220
- isDisabled: (date) => isMonthDisabled(date, normalizedMinDate, normalizedMaxDate)
1221
- }
1222
- ) : type === "date" && picker === "year" ? /* @__PURE__ */ jsx(
1223
- YearPicker,
1224
- {
1225
- value: currentValue ?? null,
1226
- displayedYear: calendarMonth.getFullYear(),
1227
- onYearChange: (year) => setCalendarMonth(new Date(year, 0, 1)),
1228
- onSelect: handleGridPickerSelect,
1229
- isDisabled: (date) => isYearDisabled(date, normalizedMinDate, normalizedMaxDate)
1230
- }
1231
- ) : type === "date" ? /* @__PURE__ */ jsx(
1232
- Calendar$1,
1233
- {
1234
- mode: "single",
1235
- captionLayout: "dropdown",
1236
- today: todayDate,
1237
- month: calendarMonth,
1238
- onMonthChange: setCalendarMonth,
1239
- selected: calendarSelected(),
1240
- onSelect: handleSingleDateSelectWithPicker,
1241
- disabled: calendarDisabled,
1242
- weekStartsOn,
1243
- classNames: weekRowHoverClassName ? { week: cn("mt-2 flex w-full", weekRowHoverClassName) } : void 0,
1244
- ...weekHighlightProps,
1245
- startMonth: calendarStartMonth,
1246
- endMonth: calendarEndMonth
1247
- }
1248
- ) : showTime ? /* @__PURE__ */ jsxs(Fragment, { children: [
1249
- /* @__PURE__ */ jsx(
1250
- RangeCalendar,
1251
- {
1252
- todayDate,
1253
- weekStartsOn,
1254
- month: calendarMonth,
1255
- onMonthChange: setCalendarMonth,
1256
- selected: memoizedRangeSelected,
1257
- onSelect: handleRangeSelect,
1258
- disabled: calendarDisabled,
1259
- startMonth: calendarStartMonth,
1260
- endMonth: calendarEndMonth,
1261
- onHoverIn: handleHoverIn,
1262
- onHoverOut: handleHoverOut,
1263
- numberOfMonths: 1
1264
- }
1763
+ /* @__PURE__ */ jsx("div", { className: "flex", children: type === "date" && picker === "month" ? /* @__PURE__ */ jsx(
1764
+ MonthPicker,
1765
+ {
1766
+ value: currentValue ?? null,
1767
+ displayedYear: calendarMonth.getFullYear(),
1768
+ onYearChange: (year) => setCalendarMonth(
1769
+ new Date(year, calendarMonth.getMonth(), 1)
1265
1770
  ),
1266
- /* @__PURE__ */ jsx("div", { className: "border-inline-start border-border pt-2", children: /* @__PURE__ */ jsx(
1267
- TimePickerPanel,
1268
- {
1269
- value: rangeSelectionStep === "from" ? pendingTime : pendingTimeTo,
1270
- onChange: rangeSelectionStep === "from" ? setPendingTime : setPendingTimeTo,
1271
- format: effectiveTimePickerFormat,
1272
- showSeconds,
1273
- disabled
1274
- }
1275
- ) })
1276
- ] }) : /* @__PURE__ */ jsx(
1277
- RangeCalendar,
1278
- {
1279
- todayDate,
1280
- weekStartsOn,
1281
- month: calendarMonth,
1282
- onMonthChange: setCalendarMonth,
1283
- selected: memoizedRangeSelected,
1284
- onSelect: handleRangeSelect,
1285
- disabled: calendarDisabled,
1286
- startMonth: calendarStartMonth,
1287
- endMonth: calendarEndMonth,
1288
- onHoverIn: handleHoverIn,
1289
- onHoverOut: handleHoverOut
1290
- }
1291
- ),
1292
- showTime && type !== "range" && /* @__PURE__ */ jsx("div", { className: "border-inline-start border-border", children: /* @__PURE__ */ jsx(
1293
- TimePickerPanel,
1294
- {
1295
- value: pendingTime,
1296
- onChange: setPendingTime,
1297
- format: effectiveTimePickerFormat,
1298
- showSeconds,
1299
- disabled
1300
- }
1301
- ) })
1302
- ] }),
1771
+ onSelect: handleGridPickerSelect,
1772
+ isDisabled: (date) => isMonthDisabled(date, normalizedMinDate, normalizedMaxDate)
1773
+ }
1774
+ ) : type === "date" && picker === "year" ? /* @__PURE__ */ jsx(
1775
+ YearPicker,
1776
+ {
1777
+ value: currentValue ?? null,
1778
+ displayedYear: calendarMonth.getFullYear(),
1779
+ onYearChange: (year) => setCalendarMonth(new Date(year, 0, 1)),
1780
+ onSelect: handleGridPickerSelect,
1781
+ isDisabled: (date) => isYearDisabled(date, normalizedMinDate, normalizedMaxDate)
1782
+ }
1783
+ ) : type === "date" ? /* @__PURE__ */ jsx(
1784
+ Calendar$1,
1785
+ {
1786
+ className: cn(showTime && SHOW_TIME_CALENDAR_CLASS_NAME),
1787
+ mode: "single",
1788
+ captionLayout: "dropdown",
1789
+ today: todayDate,
1790
+ month: calendarMonth,
1791
+ onMonthChange: setCalendarMonth,
1792
+ selected: calendarSelected(),
1793
+ onSelect: handleSingleDateSelectWithPicker,
1794
+ disabled: calendarDisabled,
1795
+ weekStartsOn,
1796
+ classNames: weekRowHoverClassName ? { week: cn("mt-2 flex w-full", weekRowHoverClassName) } : void 0,
1797
+ ...weekHighlightProps,
1798
+ startMonth: calendarStartMonth,
1799
+ endMonth: calendarEndMonth
1800
+ }
1801
+ ) : showTime ? /* @__PURE__ */ jsx(
1802
+ RangeCalendar,
1803
+ {
1804
+ className: SHOW_TIME_CALENDAR_CLASS_NAME,
1805
+ todayDate,
1806
+ weekStartsOn,
1807
+ month: calendarMonth,
1808
+ onMonthChange: setCalendarMonth,
1809
+ selected: memoizedRangeSelected,
1810
+ onSelect: handleRangeSelect,
1811
+ disabled: calendarDisabled,
1812
+ startMonth: calendarStartMonth,
1813
+ endMonth: calendarEndMonth,
1814
+ onHoverIn: handleHoverIn,
1815
+ onHoverOut: handleHoverOut,
1816
+ numberOfMonths: 1
1817
+ }
1818
+ ) : /* @__PURE__ */ jsx(
1819
+ RangeCalendar,
1820
+ {
1821
+ todayDate,
1822
+ weekStartsOn,
1823
+ month: calendarMonth,
1824
+ onMonthChange: setCalendarMonth,
1825
+ selected: memoizedRangeSelected,
1826
+ onSelect: handleRangeSelect,
1827
+ disabled: calendarDisabled,
1828
+ startMonth: calendarStartMonth,
1829
+ endMonth: calendarEndMonth,
1830
+ onHoverIn: handleHoverIn,
1831
+ onHoverOut: handleHoverOut
1832
+ }
1833
+ ) }),
1834
+ showTime && type === "range" && /* @__PURE__ */ jsx(
1835
+ TimeSection,
1836
+ {
1837
+ className: TIME_SECTION_CLASS_NAME,
1838
+ disabled,
1839
+ hasTime: true,
1840
+ optional: false,
1841
+ showError: isTimeErrorRequested,
1842
+ timezoneLabel,
1843
+ value: rangeSelectionStep === "from" ? pendingTime : pendingTimeTo,
1844
+ onChange: rangeSelectionStep === "from" ? setPendingTime : setPendingTimeTo,
1845
+ minuteStep,
1846
+ onErrorChange: setHasTimeError,
1847
+ onHasTimeChange: noop
1848
+ },
1849
+ rangeSelectionStep
1850
+ ),
1851
+ showTime && type !== "range" && /* @__PURE__ */ jsx(
1852
+ TimeSection,
1853
+ {
1854
+ className: TIME_SECTION_CLASS_NAME,
1855
+ disabled,
1856
+ hasTime: pendingHasTime,
1857
+ optional: isTimeOptional,
1858
+ showError: isTimeErrorRequested,
1859
+ timezoneLabel,
1860
+ value: pendingTime,
1861
+ onChange: setPendingTime,
1862
+ minuteStep,
1863
+ onErrorChange: setHasTimeError,
1864
+ onHasTimeChange: handleHasTimeChange
1865
+ }
1866
+ ),
1303
1867
  showFooter && /* @__PURE__ */ jsx(
1304
1868
  DatePickerFooter,
1305
1869
  {
@@ -1308,6 +1872,7 @@ const DatePicker = forwardRef(
1308
1872
  timezone,
1309
1873
  onTimezoneChange,
1310
1874
  nowDisabled: calendarDisabled(todayDate),
1875
+ showNow,
1311
1876
  onNow: handleNow,
1312
1877
  onOk: handleOk,
1313
1878
  okLabel: type === "range" && (showTime || needConfirm) && rangeSelectionStep === "from" ? "Next" : "OK"
@@ -1344,4 +1909,4 @@ const DatePicker = forwardRef(
1344
1909
  DatePicker.displayName = "DatePicker";
1345
1910
 
1346
1911
  export { DatePicker as D };
1347
- //# sourceMappingURL=DatePicker-DznpJnhm.js.map
1912
+ //# sourceMappingURL=DatePicker-BC9AOZJ2.js.map