@bigbinary/neeto-atoms 1.1.2 → 1.1.4-beta1

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 (52) hide show
  1. package/dist/{DatePicker-BiUWzq-V.js → DatePicker-CMlA-hNW.js} +475 -272
  2. package/dist/DatePicker-CMlA-hNW.js.map +1 -0
  3. package/dist/{Select-DCVlTRBI.js → Select-DrH-AzOD.js} +32 -9
  4. package/dist/Select-DrH-AzOD.js.map +1 -0
  5. package/dist/{TranslationProvider-BJjfFEgX.js → TranslationProvider-DKdbPweu.js} +9 -2
  6. package/dist/{TranslationProvider-BJjfFEgX.js.map → TranslationProvider-DKdbPweu.js.map} +1 -1
  7. package/dist/cjs/{DatePicker-C_nezxpH.js → DatePicker-CBxWLALJ.js} +474 -271
  8. package/dist/cjs/DatePicker-CBxWLALJ.js.map +1 -0
  9. package/dist/cjs/{Select-DReP9RU1.js → Select-BP2y7-eM.js} +32 -9
  10. package/dist/cjs/Select-BP2y7-eM.js.map +1 -0
  11. package/dist/cjs/{TranslationProvider-C1JDwKEN.js → TranslationProvider-Cao2ugzJ.js} +9 -2
  12. package/dist/cjs/{TranslationProvider-C1JDwKEN.js.map → TranslationProvider-Cao2ugzJ.js.map} +1 -1
  13. package/dist/cjs/components/DatePicker.js +1 -1
  14. package/dist/cjs/components/Select.js +1 -1
  15. package/dist/cjs/components/TranslationProvider.js +1 -1
  16. package/dist/cjs/components/index.js +5 -5
  17. package/dist/cjs/formik/Form.js +1 -0
  18. package/dist/cjs/formik/Form.js.map +1 -1
  19. package/dist/cjs/formik/Select.js +1 -1
  20. package/dist/cjs/formik/index.js +1 -1
  21. package/dist/cjs/index.js +5 -5
  22. package/dist/components/DatePicker/DatePickerFooter.d.ts +1 -1
  23. package/dist/components/DatePicker/RangeCalendar.d.ts +2 -1
  24. package/dist/components/DatePicker/RangeTimeSection.d.ts +37 -0
  25. package/dist/components/DatePicker/SegmentedTimeInput.d.ts +7 -1
  26. package/dist/components/DatePicker/TimeSection.d.ts +3 -0
  27. package/dist/components/DatePicker/types.d.ts +5 -2
  28. package/dist/components/DatePicker/useRangePicker.d.ts +4 -2
  29. package/dist/components/DatePicker/utils.d.ts +1 -0
  30. package/dist/components/DatePicker.js +1 -1
  31. package/dist/components/Select/MultiSelectCombobox.types.d.ts +1 -1
  32. package/dist/components/Select/SelectCombobox.types.d.ts +1 -1
  33. package/dist/components/Select/hooks/useCreatableItems.d.ts +2 -1
  34. package/dist/components/Select/hooks/useMultiSelectState.d.ts +1 -1
  35. package/dist/components/Select/hooks/useReportInputChange.d.ts +1 -0
  36. package/dist/components/Select/hooks/useSelectState.d.ts +1 -1
  37. package/dist/components/Select/types.d.ts +7 -2
  38. package/dist/components/Select.js +1 -1
  39. package/dist/components/TranslationProvider.js +1 -1
  40. package/dist/components/index.js +3 -3
  41. package/dist/formik/Form.js +1 -0
  42. package/dist/formik/Form.js.map +1 -1
  43. package/dist/formik/Select.js +1 -1
  44. package/dist/formik/index.js +1 -1
  45. package/dist/index.js +3 -3
  46. package/dist/translations/index.d.ts +7 -0
  47. package/package.json +2 -2
  48. package/CHANGELOG.md +0 -3
  49. package/dist/DatePicker-BiUWzq-V.js.map +0 -1
  50. package/dist/Select-DCVlTRBI.js.map +0 -1
  51. package/dist/cjs/DatePicker-C_nezxpH.js.map +0 -1
  52. package/dist/cjs/Select-DReP9RU1.js.map +0 -1
@@ -208,6 +208,7 @@ const parseRangeText = (text, displayFormat, maskEnabled, singleDateLen) => {
208
208
  const to = parseDate(parts[1], displayFormat);
209
209
  return from && to ? [from, to] : null;
210
210
  };
211
+ const startOfDay = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate());
211
212
  const startOfWeek = (date, weekStartsOn = 0) => {
212
213
  const d = new Date(date);
213
214
  const diff = (d.getDay() - weekStartsOn + 7) % 7;
@@ -268,10 +269,12 @@ const computeRangePreview = ({
268
269
  let from = pendingRange ? pendingRange[0] : committed?.[0] ?? null;
269
270
  let to = pendingRange ? pendingRange[1] : committed?.[1] ?? null;
270
271
  if (hoveredDate) {
271
- if (rangeStep === "from" && !pendingRange?.[0]) {
272
- from = hoveredDate;
273
- if (to && hoveredDate.getTime() > to.getTime()) to = null;
274
- } else if (rangeStep === "to" && !pendingRange?.[1] && !isSameDay(from, hoveredDate)) {
272
+ if (rangeStep === "from") {
273
+ if (!(from && to)) {
274
+ from = hoveredDate;
275
+ if (to && hoveredDate.getTime() > to.getTime()) to = null;
276
+ }
277
+ } else if (!isSameDay(from, hoveredDate)) {
275
278
  to = hoveredDate;
276
279
  if (from && hoveredDate.getTime() < from.getTime()) from = null;
277
280
  }
@@ -317,7 +320,7 @@ const DatePickerFooter = ({
317
320
  showNow = true,
318
321
  onNow,
319
322
  onOk,
320
- okLabel = "OK",
323
+ okDisabled = false,
321
324
  className
322
325
  }) => {
323
326
  const showOkButton = showTime || needConfirm;
@@ -349,7 +352,16 @@ const DatePickerFooter = ({
349
352
  className: "me-2"
350
353
  }
351
354
  ),
352
- showOkButton && /* @__PURE__ */ jsxRuntime.jsx(primitives_Button.Button, { size: "sm", onClick: onOk, className: "text-xs", children: okLabel })
355
+ showOkButton && /* @__PURE__ */ jsxRuntime.jsx(
356
+ primitives_Button.Button,
357
+ {
358
+ size: "sm",
359
+ disabled: okDisabled,
360
+ onClick: onOk,
361
+ className: "text-xs",
362
+ children: "OK"
363
+ }
364
+ )
353
365
  ]
354
366
  }
355
367
  );
@@ -654,149 +666,160 @@ const parsePastedTime = (text, step = 1) => {
654
666
  };
655
667
 
656
668
  const PLACEHOLDERS = ["hh", "mm", "--"];
657
- const SegmentedTimeInput = ({
658
- value,
659
- minuteStep,
660
- onChange,
661
- onErrorChange,
662
- invalid = false,
663
- disabled = false,
664
- autoFocus = false,
665
- "aria-describedby": ariaDescribedBy
666
- }) => {
667
- const { t } = reactI18next.useTranslation();
668
- const fieldRef = React.useRef(null);
669
- const step = minuteStep ?? 1;
670
- const [time, setTime] = React.useState(
671
- () => segmentedTimeFromValue(value, step)
672
- );
673
- const lastEmittedRef = React.useRef(value);
674
- React.useEffect(() => {
675
- if (utils$2.timeValueEquals(value, lastEmittedRef.current)) return;
676
- lastEmittedRef.current = value;
677
- setTime(segmentedTimeFromValue(value, step));
678
- }, [value]);
679
- const error = getSegmentedTimeError(time);
680
- React.useEffect(() => {
681
- onErrorChange(error);
682
- }, [error, onErrorChange]);
683
- React.useEffect(() => {
684
- const snapped = segmentedTimeToValue(time);
685
- if (snapped && !utils$2.timeValueEquals(snapped, value)) {
686
- lastEmittedRef.current = snapped;
687
- onChange(snapped);
688
- }
689
- }, []);
690
- React.useEffect(() => {
691
- if (autoFocus) fieldRef.current?.focus();
692
- }, [autoFocus]);
693
- const update = (next) => {
694
- setTime(next);
695
- const nextValue = segmentedTimeToValue(next);
696
- if (!nextValue || utils$2.timeValueEquals(nextValue, lastEmittedRef.current)) {
697
- return;
698
- }
699
- lastEmittedRef.current = nextValue;
700
- onChange(nextValue);
701
- };
702
- const consume = (event) => {
703
- event.preventDefault();
704
- event.stopPropagation();
705
- };
706
- const handleKeyDown = (event) => {
707
- const { key } = event;
708
- if (key === "Tab") {
709
- if (!event.shiftKey || time.active !== 2) return;
710
- consume(event);
711
- update(togglePeriod(time));
712
- return;
713
- }
714
- if ((event.metaKey || event.ctrlKey) && key === "Backspace") {
715
- consume(event);
716
- update(emptySegmentedTime());
717
- return;
718
- }
719
- if (event.metaKey || event.ctrlKey || event.altKey) return;
720
- let next = null;
721
- if (/^[0-9]$/.test(key)) next = typeDigit(time, key, step);
722
- else if (/^[ap]$/i.test(key)) {
723
- next = typePeriod(time, key.toLowerCase(), step);
724
- } else if (/^m$/i.test(key))
725
- next = time;
726
- else if (key === ":" || key === " " || key === "ArrowRight") {
727
- next = nextSegment(time, step);
728
- } else if (key === "ArrowLeft") next = previousSegment(time);
729
- else if (key === "ArrowUp") next = stepSegment(time, 1, step);
730
- else if (key === "ArrowDown") next = stepSegment(time, -1, step);
731
- else if (key === "Backspace" || key === "Delete") next = backspace(time);
732
- if (!next) return;
733
- consume(event);
734
- update(next);
735
- };
736
- const handlePaste = (event) => {
737
- event.preventDefault();
738
- const pasted = parsePastedTime(event.clipboardData.getData("text"), step);
739
- if (pasted) update({ ...segmentedTimeFromValue(pasted, step), active: 2 });
740
- };
741
- const handleMouseDown = (event) => {
742
- if (disabled) return;
743
- const segmentEl = event.target.closest(
744
- "[data-segment]"
669
+ const SegmentedTimeInput = React.forwardRef(
670
+ ({
671
+ value,
672
+ minuteStep,
673
+ onChange,
674
+ onErrorChange,
675
+ invalid = false,
676
+ disabled = false,
677
+ autoFocus = false,
678
+ "aria-label": ariaLabel,
679
+ "aria-describedby": ariaDescribedBy,
680
+ "data-testid": dataTestId = "datepicker-time-input"
681
+ }, ref) => {
682
+ const { t } = reactI18next.useTranslation();
683
+ const fieldRef = React.useRef(null);
684
+ const step = minuteStep ?? 1;
685
+ const [time, setTime] = React.useState(
686
+ () => segmentedTimeFromValue(value, step)
745
687
  );
746
- if (segmentEl) {
688
+ const lastEmittedRef = React.useRef(value);
689
+ React.useEffect(() => {
690
+ if (utils$2.timeValueEquals(value, lastEmittedRef.current)) return;
691
+ lastEmittedRef.current = value;
692
+ setTime(segmentedTimeFromValue(value, step));
693
+ }, [value]);
694
+ const error = getSegmentedTimeError(time);
695
+ React.useEffect(() => {
696
+ onErrorChange(error);
697
+ }, [error, onErrorChange]);
698
+ React.useEffect(() => {
699
+ const snapped = segmentedTimeToValue(time);
700
+ if (snapped && !utils$2.timeValueEquals(snapped, value)) {
701
+ lastEmittedRef.current = snapped;
702
+ onChange(snapped);
703
+ }
704
+ }, []);
705
+ React.useEffect(() => {
706
+ if (autoFocus) fieldRef.current?.focus();
707
+ }, [autoFocus]);
708
+ React.useImperativeHandle(ref, () => ({
709
+ focusHour: () => {
710
+ fieldRef.current?.focus();
711
+ setTime((current) => ({ ...current, active: 0 }));
712
+ }
713
+ }));
714
+ const update = (next) => {
715
+ setTime(next);
716
+ const nextValue = segmentedTimeToValue(next);
717
+ if (!nextValue || utils$2.timeValueEquals(nextValue, lastEmittedRef.current)) {
718
+ return;
719
+ }
720
+ lastEmittedRef.current = nextValue;
721
+ onChange(nextValue);
722
+ };
723
+ const consume = (event) => {
747
724
  event.preventDefault();
748
- fieldRef.current?.focus();
749
- update(focusSegment(time, Number(segmentEl.dataset.segment), step));
750
- return;
751
- }
752
- update(focusFirstEmptySegment(time));
753
- };
754
- const segmentText = (index) => {
755
- const { text, done } = time[SEGMENT_KEYS[index]];
756
- if (!text) return PLACEHOLDERS[index];
757
- return index < 2 && !done ? `${text}_` : text;
758
- };
759
- return /* @__PURE__ */ jsxRuntime.jsx(
760
- "div",
761
- {
762
- ref: fieldRef,
763
- role: "group",
764
- tabIndex: disabled ? -1 : 0,
765
- "aria-label": t("neetoatoms.datePicker.timeField", "Time"),
766
- "aria-describedby": ariaDescribedBy,
767
- "aria-invalid": invalid || void 0,
768
- "aria-disabled": disabled || void 0,
769
- "data-testid": "datepicker-time-input",
770
- className: utils$1.cn(
771
- "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",
772
- "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
773
- invalid && "border-destructive",
774
- disabled && "pointer-events-none cursor-not-allowed opacity-50"
775
- ),
776
- onBlur: () => update(finishActiveSegment(time, step)),
777
- onKeyDown: handleKeyDown,
778
- onMouseDown: handleMouseDown,
779
- onPaste: handlePaste,
780
- children: SEGMENT_KEYS.map((key, index) => /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
781
- index === 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "px-0.5 text-muted-foreground", children: ":" }),
782
- index === 2 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "w-1" }),
783
- /* @__PURE__ */ jsxRuntime.jsx(
784
- "span",
785
- {
786
- "data-segment": index,
787
- "data-testid": `datepicker-time-${key}`,
788
- className: utils$1.cn(
789
- "min-w-[2ch] px-0.5 text-center whitespace-pre",
790
- !time[key].text && "text-muted-foreground",
791
- index === time.active && "group-focus/time:shadow-[inset_0_-1.5px_0_var(--color-muted-foreground)]"
792
- ),
793
- children: segmentText(index)
794
- }
795
- )
796
- ] }, key))
797
- }
798
- );
799
- };
725
+ event.stopPropagation();
726
+ };
727
+ const handleKeyDown = (event) => {
728
+ const { key } = event;
729
+ if (key === "Tab") {
730
+ if (!event.shiftKey || time.active !== 2) return;
731
+ consume(event);
732
+ update(togglePeriod(time));
733
+ return;
734
+ }
735
+ if ((event.metaKey || event.ctrlKey) && key === "Backspace") {
736
+ consume(event);
737
+ update(emptySegmentedTime());
738
+ return;
739
+ }
740
+ if (event.metaKey || event.ctrlKey || event.altKey) return;
741
+ let next = null;
742
+ if (/^[0-9]$/.test(key)) next = typeDigit(time, key, step);
743
+ else if (/^[ap]$/i.test(key)) {
744
+ next = typePeriod(time, key.toLowerCase(), step);
745
+ } else if (/^m$/i.test(key))
746
+ next = time;
747
+ else if (key === ":" || key === " " || key === "ArrowRight") {
748
+ next = nextSegment(time, step);
749
+ } else if (key === "ArrowLeft") next = previousSegment(time);
750
+ else if (key === "ArrowUp") next = stepSegment(time, 1, step);
751
+ else if (key === "ArrowDown") next = stepSegment(time, -1, step);
752
+ else if (key === "Backspace" || key === "Delete") next = backspace(time);
753
+ if (!next) return;
754
+ consume(event);
755
+ update(next);
756
+ };
757
+ const handlePaste = (event) => {
758
+ event.preventDefault();
759
+ const pasted = parsePastedTime(event.clipboardData.getData("text"), step);
760
+ if (pasted)
761
+ update({ ...segmentedTimeFromValue(pasted, step), active: 2 });
762
+ };
763
+ const handleMouseDown = (event) => {
764
+ if (disabled) return;
765
+ const segmentEl = event.target.closest(
766
+ "[data-segment]"
767
+ );
768
+ if (segmentEl) {
769
+ event.preventDefault();
770
+ fieldRef.current?.focus();
771
+ update(focusSegment(time, Number(segmentEl.dataset.segment), step));
772
+ return;
773
+ }
774
+ update(focusFirstEmptySegment(time));
775
+ };
776
+ const segmentText = (index) => {
777
+ const { text, done } = time[SEGMENT_KEYS[index]];
778
+ if (!text) return PLACEHOLDERS[index];
779
+ return index < 2 && !done ? `${text}_` : text;
780
+ };
781
+ return /* @__PURE__ */ jsxRuntime.jsx(
782
+ "div",
783
+ {
784
+ ref: fieldRef,
785
+ role: "group",
786
+ tabIndex: disabled ? -1 : 0,
787
+ "aria-label": ariaLabel ?? t("neetoatoms.datePicker.timeField", "Time"),
788
+ "aria-describedby": ariaDescribedBy,
789
+ "aria-invalid": invalid || void 0,
790
+ "aria-disabled": disabled || void 0,
791
+ "data-testid": dataTestId,
792
+ className: utils$1.cn(
793
+ "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",
794
+ "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
795
+ invalid && "border-destructive",
796
+ disabled && "pointer-events-none cursor-not-allowed opacity-50"
797
+ ),
798
+ onBlur: () => update(finishActiveSegment(time, step)),
799
+ onKeyDown: handleKeyDown,
800
+ onMouseDown: handleMouseDown,
801
+ onPaste: handlePaste,
802
+ children: SEGMENT_KEYS.map((key, index) => /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
803
+ index === 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "px-0.5 text-muted-foreground", children: ":" }),
804
+ index === 2 && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "w-1" }),
805
+ /* @__PURE__ */ jsxRuntime.jsx(
806
+ "span",
807
+ {
808
+ "data-segment": index,
809
+ "data-testid": `datepicker-time-${key}`,
810
+ className: utils$1.cn(
811
+ "min-w-[2ch] px-0.5 text-center whitespace-pre",
812
+ !time[key].text && "text-muted-foreground",
813
+ index === time.active && "group-focus/time:shadow-[inset_0_-1.5px_0_var(--color-muted-foreground)]"
814
+ ),
815
+ children: segmentText(index)
816
+ }
817
+ )
818
+ ] }, key))
819
+ }
820
+ );
821
+ }
822
+ );
800
823
  SegmentedTimeInput.displayName = "SegmentedTimeInput";
801
824
 
802
825
  const ERROR_DEFAULTS = {
@@ -998,9 +1021,10 @@ const RangeCalendar = ({
998
1021
  endMonth,
999
1022
  onHoverIn,
1000
1023
  onHoverOut,
1024
+ onKeyDown,
1001
1025
  numberOfMonths = 2,
1002
1026
  className
1003
- }) => /* @__PURE__ */ jsxRuntime.jsx("div", { onMouseOver: onHoverIn, onMouseLeave: onHoverOut, children: /* @__PURE__ */ jsxRuntime.jsx(
1027
+ }) => /* @__PURE__ */ jsxRuntime.jsx("div", { onKeyDown, onMouseLeave: onHoverOut, onMouseOver: onHoverIn, children: /* @__PURE__ */ jsxRuntime.jsx(
1004
1028
  primitives_Calendar.Calendar,
1005
1029
  {
1006
1030
  mode: "range",
@@ -1022,6 +1046,180 @@ const RangeCalendar = ({
1022
1046
  }
1023
1047
  ) });
1024
1048
 
1049
+ const ENDPOINT_LABELS = {
1050
+ from: "Start",
1051
+ to: "End"
1052
+ };
1053
+ const RangeTimeSection = ({
1054
+ fromDateLabel,
1055
+ toDateLabel,
1056
+ isEndOnStartDay,
1057
+ fromValue,
1058
+ toValue,
1059
+ onFromChange,
1060
+ onToChange,
1061
+ activeEndpoint,
1062
+ onEndpointSelect,
1063
+ minuteStep,
1064
+ onErrorChange,
1065
+ showError,
1066
+ isOrderInvalid,
1067
+ timezoneLabel,
1068
+ fromTimeRef,
1069
+ disabled = false,
1070
+ className
1071
+ }) => {
1072
+ const { t } = reactI18next.useTranslation();
1073
+ const id = React.useId();
1074
+ const hintId = `datepicker-time-hint-${id}`;
1075
+ const orderErrorId = `datepicker-time-order-error-${id}`;
1076
+ const [errors, setErrors] = React.useState({ from: null, to: null });
1077
+ const hasError = !!(errors.from || errors.to);
1078
+ React.useEffect(() => {
1079
+ onErrorChange(hasError);
1080
+ }, [hasError, onErrorChange]);
1081
+ const handleErrorChange = React.useCallback(
1082
+ (endpoint, error) => setErrors((previous) => ({ ...previous, [endpoint]: error })),
1083
+ []
1084
+ );
1085
+ const handleFromErrorChange = React.useCallback(
1086
+ (error) => handleErrorChange("from", error),
1087
+ [handleErrorChange]
1088
+ );
1089
+ const handleToErrorChange = React.useCallback(
1090
+ (error) => handleErrorChange("to", error),
1091
+ [handleErrorChange]
1092
+ );
1093
+ const showHint = (minuteStep ?? 1) > 1;
1094
+ const endpoints = [
1095
+ {
1096
+ endpoint: "from",
1097
+ dateLabel: fromDateLabel,
1098
+ value: fromValue,
1099
+ onChange: onFromChange,
1100
+ onFieldErrorChange: handleFromErrorChange
1101
+ },
1102
+ {
1103
+ endpoint: "to",
1104
+ dateLabel: isEndOnStartDay ? t("neetoatoms.datePicker.sameDay", "Same day") : toDateLabel,
1105
+ value: toValue,
1106
+ onChange: onToChange,
1107
+ onFieldErrorChange: handleToErrorChange
1108
+ }
1109
+ ];
1110
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils$1.cn("flex flex-col gap-2", className), children: [
1111
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 gap-3", children: endpoints.map(
1112
+ ({ endpoint, dateLabel, value, onChange, onFieldErrorChange }) => {
1113
+ const isActive = endpoint === activeEndpoint;
1114
+ const endpointLabel = t(
1115
+ `neetoatoms.datePicker.${endpoint === "from" ? "start" : "end"}`,
1116
+ ENDPOINT_LABELS[endpoint]
1117
+ );
1118
+ const error = errors[endpoint];
1119
+ const errorId = `datepicker-${endpoint}-time-error-${id}`;
1120
+ const errorMessage = showError && error ? t(
1121
+ `neetoatoms.datePicker.errors.${error}`,
1122
+ ERROR_DEFAULTS[error]
1123
+ ) : null;
1124
+ const isInvalid = !!errorMessage || endpoint === "to" && isOrderInvalid;
1125
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1.5", children: [
1126
+ /* @__PURE__ */ jsxRuntime.jsxs(
1127
+ "button",
1128
+ {
1129
+ type: "button",
1130
+ "aria-pressed": isActive,
1131
+ tabIndex: -1,
1132
+ "data-testid": `datepicker-${endpoint}-endpoint`,
1133
+ disabled,
1134
+ className: utils$1.cn(
1135
+ "flex min-w-0 items-baseline gap-1.5 rounded-sm text-start text-sm outline-none",
1136
+ "focus-visible:ring-[3px] focus-visible:ring-ring/50",
1137
+ isActive ? "font-medium text-foreground" : "text-muted-foreground hover:text-foreground"
1138
+ ),
1139
+ onClick: () => onEndpointSelect(endpoint),
1140
+ children: [
1141
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: endpointLabel }),
1142
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs font-normal text-muted-foreground", children: dateLabel || t("neetoatoms.datePicker.pickADay", "Pick a day") })
1143
+ ]
1144
+ }
1145
+ ),
1146
+ /* @__PURE__ */ jsxRuntime.jsx(
1147
+ SegmentedTimeInput,
1148
+ {
1149
+ "aria-describedby": [
1150
+ showHint ? hintId : null,
1151
+ errorMessage ? errorId : null,
1152
+ endpoint === "to" && isOrderInvalid ? orderErrorId : null
1153
+ ].filter(Boolean).join(" ") || void 0,
1154
+ "aria-label": t(
1155
+ `neetoatoms.datePicker.${endpoint === "from" ? "startTime" : "endTime"}`,
1156
+ `${ENDPOINT_LABELS[endpoint]} time`
1157
+ ),
1158
+ "data-testid": `datepicker-${endpoint}-time-input`,
1159
+ disabled,
1160
+ invalid: isInvalid,
1161
+ minuteStep,
1162
+ ref: endpoint === "from" ? fromTimeRef : void 0,
1163
+ value,
1164
+ onChange,
1165
+ onErrorChange: onFieldErrorChange
1166
+ }
1167
+ ),
1168
+ errorMessage && /* @__PURE__ */ jsxRuntime.jsx(
1169
+ "p",
1170
+ {
1171
+ id: errorId,
1172
+ className: "text-xs text-destructive",
1173
+ "data-testid": `datepicker-${endpoint}-time-error`,
1174
+ role: "alert",
1175
+ children: errorMessage
1176
+ }
1177
+ )
1178
+ ] }, endpoint);
1179
+ }
1180
+ ) }),
1181
+ showHint && /* @__PURE__ */ jsxRuntime.jsx(
1182
+ "p",
1183
+ {
1184
+ id: hintId,
1185
+ className: "text-xs text-muted-foreground",
1186
+ "data-testid": "datepicker-time-hint",
1187
+ children: t("neetoatoms.datePicker.timeHint", {
1188
+ step: minuteStep,
1189
+ first: stepExamples(minuteStep)[0],
1190
+ second: stepExamples(minuteStep)[1],
1191
+ defaultValue: "Only {{step}}-minute steps are allowed, like {{first}} or {{second}}."
1192
+ })
1193
+ }
1194
+ ),
1195
+ isOrderInvalid && /* @__PURE__ */ jsxRuntime.jsx(
1196
+ "p",
1197
+ {
1198
+ id: orderErrorId,
1199
+ className: "text-xs text-destructive",
1200
+ "data-testid": "datepicker-time-order-error",
1201
+ role: "alert",
1202
+ children: t(
1203
+ "neetoatoms.datePicker.errors.endBeforeStart",
1204
+ "End time must be after the start time."
1205
+ )
1206
+ }
1207
+ ),
1208
+ timezoneLabel && /* @__PURE__ */ jsxRuntime.jsxs(
1209
+ "p",
1210
+ {
1211
+ className: "mt-1 flex items-center gap-2 text-xs text-muted-foreground",
1212
+ "data-testid": "datepicker-timezone",
1213
+ children: [
1214
+ /* @__PURE__ */ jsxRuntime.jsx(Globe, { "aria-hidden": true, className: "size-3.5 shrink-0" }),
1215
+ timezoneLabel
1216
+ ]
1217
+ }
1218
+ )
1219
+ ] });
1220
+ };
1221
+ RangeTimeSection.displayName = "RangeTimeSection";
1222
+
1025
1223
  const useRangePicker = ({
1026
1224
  currentValue,
1027
1225
  showTime,
@@ -1030,52 +1228,49 @@ const useRangePicker = ({
1030
1228
  setOpen
1031
1229
  }) => {
1032
1230
  const [pendingRange, setPendingRange] = React.useState(null);
1033
- const [rangeSelectionStep, setRangeSelectionStep] = React.useState(
1034
- "from"
1035
- );
1231
+ const [activeEndpoint, setActiveEndpoint] = React.useState("from");
1036
1232
  const [hoveredDate, setHoveredDate] = React.useState(null);
1037
1233
  const committed = currentValue ?? null;
1038
1234
  const resetTransientState = React.useCallback(() => {
1039
1235
  setPendingRange(null);
1040
- setRangeSelectionStep("from");
1236
+ setActiveEndpoint("from");
1041
1237
  setHoveredDate(null);
1042
1238
  }, []);
1043
1239
  const handleRangeSelect = React.useCallback(
1044
1240
  (_range, triggerDate) => {
1045
1241
  if (!triggerDate) return;
1046
- if (showTime || needConfirm) {
1047
- if (rangeSelectionStep === "from") {
1048
- const existingTo = pendingRange?.[1] ?? committed?.[1] ?? null;
1049
- const nextTo = existingTo && triggerDate <= existingTo ? existingTo : null;
1050
- setPendingRange([triggerDate, nextTo]);
1051
- } else {
1052
- const existingFrom = pendingRange?.[0] ?? committed?.[0] ?? null;
1053
- const nextFrom = existingFrom && triggerDate >= existingFrom ? existingFrom : null;
1054
- setPendingRange([nextFrom, triggerDate]);
1055
- }
1242
+ const from = pendingRange ? pendingRange[0] : committed?.[0] ?? null;
1243
+ const to = pendingRange ? pendingRange[1] : committed?.[1] ?? null;
1244
+ const isBeforeFrom = !!from && triggerDate < startOfDay(from);
1245
+ if (activeEndpoint === "from" || !from) {
1246
+ const nextTo = to && triggerDate <= to ? to : null;
1247
+ setPendingRange([triggerDate, nextTo]);
1248
+ setActiveEndpoint("to");
1056
1249
  return;
1057
1250
  }
1058
- if (rangeSelectionStep === "from" || !pendingRange?.[0]) {
1059
- const existingTo = pendingRange?.[1] ?? committed?.[1] ?? null;
1060
- const nextTo = existingTo && triggerDate <= existingTo ? existingTo : null;
1061
- setPendingRange([triggerDate, nextTo]);
1062
- setRangeSelectionStep("to");
1251
+ if (showTime || needConfirm) {
1252
+ if (isBeforeFrom) {
1253
+ setPendingRange([triggerDate, null]);
1254
+ return;
1255
+ }
1256
+ setPendingRange([from, triggerDate]);
1257
+ setActiveEndpoint("from");
1063
1258
  return;
1064
1259
  }
1065
- const [from, to] = orderRange(pendingRange[0], triggerDate);
1066
- setRangeSelectionStep("from");
1067
- setPendingRange(null);
1068
- commitValue([from, to]);
1260
+ const [orderedFrom, orderedTo] = orderRange(from, triggerDate);
1261
+ resetTransientState();
1262
+ commitValue([orderedFrom, orderedTo]);
1069
1263
  setOpen(false);
1070
1264
  },
1071
1265
  [
1072
- rangeSelectionStep,
1266
+ activeEndpoint,
1073
1267
  pendingRange,
1074
1268
  committed,
1075
1269
  showTime,
1076
1270
  needConfirm,
1077
1271
  commitValue,
1078
- setOpen
1272
+ setOpen,
1273
+ resetTransientState
1079
1274
  ]
1080
1275
  );
1081
1276
  const handleHoverIn = React.useCallback(
@@ -1088,29 +1283,25 @@ const useRangePicker = ({
1088
1283
  [hoveredDate]
1089
1284
  );
1090
1285
  const handleHoverOut = React.useCallback(() => setHoveredDate(null), []);
1091
- const memoizedRangeSelected = React.useMemo(() => {
1092
- const { from, to } = computeRangePreview({
1093
- pendingRange,
1094
- committed,
1095
- hoveredDate,
1096
- rangeStep: rangeSelectionStep
1097
- });
1098
- if (!from && !to) return void 0;
1099
- return { from: from ?? void 0, to: to ?? void 0 };
1100
- }, [pendingRange, committed, hoveredDate, rangeSelectionStep]);
1101
1286
  const getPreviewParts = React.useCallback(
1102
1287
  () => computeRangePreview({
1103
1288
  pendingRange,
1104
1289
  committed,
1105
1290
  hoveredDate,
1106
- rangeStep: rangeSelectionStep
1291
+ rangeStep: activeEndpoint
1107
1292
  }),
1108
- [pendingRange, committed, hoveredDate, rangeSelectionStep]
1293
+ [pendingRange, committed, hoveredDate, activeEndpoint]
1109
1294
  );
1295
+ const memoizedRangeSelected = React.useMemo(() => {
1296
+ const { from, to } = getPreviewParts();
1297
+ if (!from && !to) return void 0;
1298
+ return { from: from ?? void 0, to: to ?? void 0 };
1299
+ }, [getPreviewParts]);
1110
1300
  return {
1111
1301
  pendingRange,
1112
- rangeSelectionStep,
1113
- setRangeSelectionStep,
1302
+ setPendingRange,
1303
+ activeEndpoint,
1304
+ setActiveEndpoint,
1114
1305
  hoveredDate,
1115
1306
  handleRangeSelect,
1116
1307
  handleHoverIn,
@@ -1188,8 +1379,12 @@ const YearPicker = ({
1188
1379
  const TIME_SECTION_CLASS_NAME = "w-0 min-w-full border-t border-border px-3 py-3";
1189
1380
  const SHOW_TIME_CALENDAR_CLASS_NAME = "[--cell-size:--spacing(8.125)]";
1190
1381
  const DEFAULT_ADDED_TIME = { hours: 12, minutes: 0, seconds: 0 };
1191
- const noop = () => {
1192
- };
1382
+ const getDefaultEndTime = (minuteStep = 1) => ({
1383
+ hours: 23,
1384
+ minutes: Math.floor(59 / minuteStep) * minuteStep,
1385
+ seconds: 0
1386
+ });
1387
+ const isSameRange = (a, b) => a?.[0]?.getTime() === b?.[0]?.getTime() && a?.[1]?.getTime() === b?.[1]?.getTime();
1193
1388
  const DatePicker = React.forwardRef(
1194
1389
  ({
1195
1390
  value,
@@ -1238,6 +1433,7 @@ const DatePicker = React.forwardRef(
1238
1433
  const containerRef = React.useRef(null);
1239
1434
  const inputRef = React.useRef(null);
1240
1435
  const cursorPosRef = React.useRef(null);
1436
+ const fromTimeRef = React.useRef(null);
1241
1437
  const popoverContentId = React.useRef(
1242
1438
  `datepicker-popover-${generatedId}`
1243
1439
  ).current;
@@ -1354,8 +1550,9 @@ const DatePicker = React.forwardRef(
1354
1550
  };
1355
1551
  const {
1356
1552
  pendingRange,
1357
- rangeSelectionStep,
1358
- setRangeSelectionStep,
1553
+ setPendingRange,
1554
+ activeEndpoint,
1555
+ setActiveEndpoint,
1359
1556
  handleRangeSelect,
1360
1557
  handleHoverIn,
1361
1558
  handleHoverOut,
@@ -1369,9 +1566,38 @@ const DatePicker = React.forwardRef(
1369
1566
  commitValue,
1370
1567
  setOpen
1371
1568
  });
1569
+ const isRangeConfirm = type === "range" && (showTime || needConfirm);
1570
+ const committedRange = type === "range" ? currentValue : null;
1571
+ const [draftFrom, draftTo] = orderRange(
1572
+ pendingRange ? pendingRange[0] : committedRange?.[0] ?? null,
1573
+ pendingRange ? pendingRange[1] : committedRange?.[1] ?? null
1574
+ );
1575
+ const draftEnd = draftTo ?? (showTime ? draftFrom : null);
1576
+ const isEndOnStartDay = showTime && !!draftFrom && isSameDay(draftFrom, draftEnd);
1577
+ const draftRange = React.useMemo(() => {
1578
+ if (!draftFrom || !draftEnd) return null;
1579
+ return showTime ? [
1580
+ applyTimeToDate(draftFrom, pendingTime),
1581
+ applyTimeToDate(draftEnd, pendingTimeTo)
1582
+ ] : [draftFrom, draftEnd];
1583
+ }, [draftFrom, draftEnd, showTime, pendingTime, pendingTimeTo]);
1584
+ const isRangeOrderInvalid = showTime && !!draftRange && draftRange[1].getTime() <= draftRange[0].getTime();
1585
+ const applyTypedRange = (range) => {
1586
+ const snapped = range.map(
1587
+ (date) => showTime && minuteStep ? roundToMinuteStep(date, minuteStep) : date
1588
+ );
1589
+ const [from, to] = orderRange(snapped[0], snapped[1]);
1590
+ setPendingRange([startOfDay(from), startOfDay(to)]);
1591
+ setActiveEndpoint("from");
1592
+ if (showTime) {
1593
+ setPendingTime(utils$2.dateToTimeValue(from));
1594
+ setPendingTimeTo(utils$2.dateToTimeValue(to));
1595
+ }
1596
+ };
1372
1597
  React.useEffect(() => {
1373
1598
  if (type !== "range" || !open) return;
1374
- const { from, to } = getPreviewParts();
1599
+ const { from, to: previewTo } = getPreviewParts();
1600
+ const to = previewTo ?? (showTime ? from : null);
1375
1601
  const fromWithTime = from && showTime ? applyTimeToDate(from, pendingTime) : from;
1376
1602
  const toWithTime = to && showTime ? applyTimeToDate(to, pendingTimeTo) : to;
1377
1603
  const fromText = fromWithTime ? formatDate(fromWithTime, displayFormat) : "";
@@ -1405,7 +1631,9 @@ const DatePicker = React.forwardRef(
1405
1631
  maskEnabled,
1406
1632
  singleDateLen
1407
1633
  );
1408
- if (range) commitValue(range);
1634
+ if (!range) return;
1635
+ if (isRangeConfirm) applyTypedRange(range);
1636
+ else commitValue(range);
1409
1637
  };
1410
1638
  const commitPendingOnClose = React.useCallback(() => {
1411
1639
  const hasOkButton = showTime || needConfirm;
@@ -1435,14 +1663,9 @@ const DatePicker = React.forwardRef(
1435
1663
  hasTimeError
1436
1664
  ]);
1437
1665
  const closePopover = React.useCallback(() => {
1438
- if (type === "range" && pendingRange?.[0] && pendingRange?.[1] && !(showTime && hasTimeError)) {
1439
- const [fromBase, toBase] = orderRange(
1440
- pendingRange[0],
1441
- pendingRange[1]
1442
- );
1443
- const fromFinal = showTime ? applyTimeToDate(fromBase, pendingTime) : fromBase;
1444
- const toFinal = showTime ? applyTimeToDate(toBase, pendingTimeTo) : toBase;
1445
- commitValue([fromFinal, toFinal]);
1666
+ if (type === "range") {
1667
+ const canCommit = draftRange && !(showTime && (hasTimeError || isRangeOrderInvalid)) && !isSameRange(draftRange, committedRange);
1668
+ if (canCommit) commitValue(draftRange);
1446
1669
  } else {
1447
1670
  commitPendingOnClose();
1448
1671
  }
@@ -1452,9 +1675,9 @@ const DatePicker = React.forwardRef(
1452
1675
  commitPendingOnClose,
1453
1676
  setOpen,
1454
1677
  type,
1455
- pendingRange,
1456
- pendingTime,
1457
- pendingTimeTo,
1678
+ draftRange,
1679
+ committedRange,
1680
+ isRangeOrderInvalid,
1458
1681
  showTime,
1459
1682
  resetTransientState,
1460
1683
  hasTimeError
@@ -1477,7 +1700,10 @@ const DatePicker = React.forwardRef(
1477
1700
  setPendingTime(
1478
1701
  fromDate ? utils$2.dateToTimeValue(fromDate) : INITIAL_TIME_VALUE
1479
1702
  );
1480
- setPendingTimeTo(toDate ? utils$2.dateToTimeValue(toDate) : INITIAL_TIME_VALUE);
1703
+ setPendingTimeTo(
1704
+ toDate ? utils$2.dateToTimeValue(toDate) : getDefaultEndTime(minuteStep)
1705
+ );
1706
+ if (fromDate) setCalendarMonth(fromDate);
1481
1707
  return;
1482
1708
  }
1483
1709
  const dateVal = currentValue;
@@ -1513,11 +1739,6 @@ const DatePicker = React.forwardRef(
1513
1739
  setCalendarMonth(now);
1514
1740
  if (type === "range") {
1515
1741
  handleRangeSelect(void 0, now);
1516
- if (showTime) {
1517
- const nowTime = utils$2.dateToTimeValue(now);
1518
- if (rangeSelectionStep === "from") setPendingTime(nowTime);
1519
- else setPendingTimeTo(nowTime);
1520
- }
1521
1742
  return;
1522
1743
  }
1523
1744
  if (showTime || needConfirm) {
@@ -1534,30 +1755,12 @@ const DatePicker = React.forwardRef(
1534
1755
  setIsTimeErrorRequested(true);
1535
1756
  return;
1536
1757
  }
1537
- if (type === "range" && (showTime || needConfirm)) {
1538
- const committedRange = currentValue;
1539
- const fromValue = pendingRange?.[0] ?? committedRange?.[0] ?? null;
1540
- const toValue = pendingRange?.[1] ?? committedRange?.[1] ?? null;
1541
- if (rangeSelectionStep === "from" && fromValue) {
1542
- setRangeSelectionStep("to");
1543
- setCalendarMonth(
1544
- new Date(fromValue.getFullYear(), fromValue.getMonth(), 1)
1545
- );
1546
- if (showTime && pendingRange?.[0]) {
1547
- setPendingTimeTo(INITIAL_TIME_VALUE);
1548
- }
1549
- return;
1550
- }
1551
- if (rangeSelectionStep === "to" && fromValue && toValue) {
1552
- const [fromBase, toBase] = orderRange(fromValue, toValue);
1553
- const fromFinal = showTime ? applyTimeToDate(fromBase, pendingTime) : fromBase;
1554
- const toFinal = showTime ? applyTimeToDate(toBase, pendingTimeTo) : toBase;
1555
- commitValue([fromFinal, toFinal], showTime);
1556
- onOk?.([fromFinal, toFinal]);
1557
- resetTransientState();
1558
- setOpen(false);
1559
- return;
1560
- }
1758
+ if (isRangeConfirm) {
1759
+ if (!draftRange || isRangeOrderInvalid) return;
1760
+ commitValue(draftRange, showTime);
1761
+ onOk?.(draftRange);
1762
+ resetTransientState();
1763
+ setOpen(false);
1561
1764
  return;
1562
1765
  }
1563
1766
  if (pendingDate) {
@@ -1618,12 +1821,8 @@ const DatePicker = React.forwardRef(
1618
1821
  singleDateLen
1619
1822
  );
1620
1823
  if (range) {
1621
- commitValue(
1622
- showTime && minuteStep ? [
1623
- roundToMinuteStep(range[0], minuteStep),
1624
- roundToMinuteStep(range[1], minuteStep)
1625
- ] : range
1626
- );
1824
+ const snapped = showTime && minuteStep ? range.map((date) => roundToMinuteStep(date, minuteStep)) : range;
1825
+ commitValue(orderRange(snapped[0], snapped[1]));
1627
1826
  }
1628
1827
  } else {
1629
1828
  const parsed = parseDate(inputText, displayFormat);
@@ -1677,6 +1876,20 @@ const DatePicker = React.forwardRef(
1677
1876
  );
1678
1877
  const calendarStartMonth = normalizedMinDate ?? (calendarMonth < defaultStartMonth ? calendarMonth : defaultStartMonth);
1679
1878
  const calendarEndMonth = normalizedMaxDate ?? (calendarMonth > defaultEndMonth ? calendarMonth : defaultEndMonth);
1879
+ const handleEndpointSelect = (endpoint) => {
1880
+ setActiveEndpoint(endpoint);
1881
+ const date = endpoint === "from" ? draftFrom : draftEnd;
1882
+ if (!date) return;
1883
+ const monthsAhead = (date.getFullYear() - calendarMonth.getFullYear()) * 12 + date.getMonth() - calendarMonth.getMonth();
1884
+ if (monthsAhead < 0 || monthsAhead > 1) {
1885
+ setCalendarMonth(new Date(date.getFullYear(), date.getMonth(), 1));
1886
+ }
1887
+ };
1888
+ const handleRangeCalendarKeyDown = (e) => {
1889
+ if (e.key !== "Tab" || e.shiftKey || !draftRange) return;
1890
+ e.preventDefault();
1891
+ fromTimeRef.current?.focusHour();
1892
+ };
1680
1893
  const handleGridPickerSelect = (date) => {
1681
1894
  commitValue(date);
1682
1895
  setOpen(false);
@@ -1801,26 +2014,10 @@ const DatePicker = React.forwardRef(
1801
2014
  startMonth: calendarStartMonth,
1802
2015
  endMonth: calendarEndMonth
1803
2016
  }
1804
- ) : showTime ? /* @__PURE__ */ jsxRuntime.jsx(
1805
- RangeCalendar,
1806
- {
1807
- className: SHOW_TIME_CALENDAR_CLASS_NAME,
1808
- todayDate,
1809
- weekStartsOn,
1810
- month: calendarMonth,
1811
- onMonthChange: setCalendarMonth,
1812
- selected: memoizedRangeSelected,
1813
- onSelect: handleRangeSelect,
1814
- disabled: calendarDisabled,
1815
- startMonth: calendarStartMonth,
1816
- endMonth: calendarEndMonth,
1817
- onHoverIn: handleHoverIn,
1818
- onHoverOut: handleHoverOut,
1819
- numberOfMonths: 1
1820
- }
1821
2017
  ) : /* @__PURE__ */ jsxRuntime.jsx(
1822
2018
  RangeCalendar,
1823
2019
  {
2020
+ className: utils$1.cn(showTime && SHOW_TIME_CALENDAR_CLASS_NAME),
1824
2021
  todayDate,
1825
2022
  weekStartsOn,
1826
2023
  month: calendarMonth,
@@ -1831,25 +2028,31 @@ const DatePicker = React.forwardRef(
1831
2028
  startMonth: calendarStartMonth,
1832
2029
  endMonth: calendarEndMonth,
1833
2030
  onHoverIn: handleHoverIn,
1834
- onHoverOut: handleHoverOut
2031
+ onHoverOut: handleHoverOut,
2032
+ onKeyDown: showTime ? handleRangeCalendarKeyDown : void 0
1835
2033
  }
1836
2034
  ) }),
1837
2035
  showTime && type === "range" && /* @__PURE__ */ jsxRuntime.jsx(
1838
- TimeSection,
2036
+ RangeTimeSection,
1839
2037
  {
2038
+ activeEndpoint,
1840
2039
  className: TIME_SECTION_CLASS_NAME,
1841
2040
  disabled,
1842
- hasTime: true,
1843
- optional: false,
2041
+ fromDateLabel: formatDate(draftFrom, dateFormat),
2042
+ fromTimeRef,
2043
+ fromValue: pendingTime,
2044
+ isOrderInvalid: isRangeOrderInvalid,
2045
+ minuteStep,
1844
2046
  showError: isTimeErrorRequested,
1845
2047
  timezoneLabel,
1846
- value: rangeSelectionStep === "from" ? pendingTime : pendingTimeTo,
1847
- onChange: rangeSelectionStep === "from" ? setPendingTime : setPendingTimeTo,
1848
- minuteStep,
2048
+ isEndOnStartDay,
2049
+ toDateLabel: formatDate(draftTo, dateFormat),
2050
+ toValue: pendingTimeTo,
2051
+ onEndpointSelect: handleEndpointSelect,
1849
2052
  onErrorChange: setHasTimeError,
1850
- onHasTimeChange: noop
1851
- },
1852
- rangeSelectionStep
2053
+ onFromChange: setPendingTime,
2054
+ onToChange: setPendingTimeTo
2055
+ }
1853
2056
  ),
1854
2057
  showTime && type !== "range" && /* @__PURE__ */ jsxRuntime.jsx(
1855
2058
  TimeSection,
@@ -1875,10 +2078,10 @@ const DatePicker = React.forwardRef(
1875
2078
  timezone,
1876
2079
  onTimezoneChange,
1877
2080
  nowDisabled: calendarDisabled(todayDate),
1878
- showNow,
2081
+ showNow: showNow && !(type === "range" && showTime),
1879
2082
  onNow: handleNow,
1880
- onOk: handleOk,
1881
- okLabel: type === "range" && (showTime || needConfirm) && rangeSelectionStep === "from" ? "Next" : "OK"
2083
+ okDisabled: isRangeConfirm && (!draftRange || isRangeOrderInvalid),
2084
+ onOk: handleOk
1882
2085
  }
1883
2086
  )
1884
2087
  ]
@@ -1912,4 +2115,4 @@ const DatePicker = React.forwardRef(
1912
2115
  DatePicker.displayName = "DatePicker";
1913
2116
 
1914
2117
  exports.DatePicker = DatePicker;
1915
- //# sourceMappingURL=DatePicker-C_nezxpH.js.map
2118
+ //# sourceMappingURL=DatePicker-CBxWLALJ.js.map