@bigbinary/neeto-atoms 1.1.9 → 1.1.11
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/dist/{DatePicker-DUx9Qggg.js → DatePicker-DYsyV9BJ.js} +120 -280
- package/dist/DatePicker-DYsyV9BJ.js.map +1 -0
- package/dist/{TranslationProvider-DKdbPweu.js → TranslationProvider-CQyQt55W.js} +2 -4
- package/dist/{TranslationProvider-DKdbPweu.js.map → TranslationProvider-CQyQt55W.js.map} +1 -1
- package/dist/cjs/{DatePicker-DRNGTBHW.js → DatePicker-D6a3J1WA.js} +118 -279
- package/dist/cjs/DatePicker-D6a3J1WA.js.map +1 -0
- package/dist/cjs/{TranslationProvider-Cao2ugzJ.js → TranslationProvider-CJlcb83b.js} +2 -4
- package/dist/cjs/{TranslationProvider-Cao2ugzJ.js.map → TranslationProvider-CJlcb83b.js.map} +1 -1
- package/dist/cjs/components/DatePicker.js +1 -1
- package/dist/cjs/components/TranslationProvider.js +1 -1
- package/dist/cjs/components/index.js +2 -2
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/primitives/AlertDialog.js +7 -39
- package/dist/cjs/primitives/AlertDialog.js.map +1 -1
- package/dist/cjs/primitives/index.js +1 -1
- package/dist/components/DatePicker/RangeTimeSection.d.ts +2 -2
- package/dist/components/DatePicker/TimeInput.d.ts +27 -0
- package/dist/components/DatePicker/TimeSection.d.ts +2 -2
- package/dist/components/DatePicker/timeText.d.ts +32 -0
- package/dist/components/DatePicker.js +1 -1
- package/dist/components/TranslationProvider.js +1 -1
- package/dist/components/index.js +2 -2
- package/dist/index.js +2 -2
- package/dist/translations/index.d.ts +1 -3
- package/package.json +1 -1
- package/dist/DatePicker-DUx9Qggg.js.map +0 -1
- package/dist/cjs/DatePicker-DRNGTBHW.js.map +0 -1
- package/dist/components/DatePicker/SegmentedTimeInput.d.ts +0 -23
- package/dist/components/DatePicker/segmentedTime.d.ts +0 -58
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
2
|
+
import { forwardRef, useRef, useState, useEffect, useImperativeHandle, 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 { t as to12Hour,
|
|
6
|
+
import { t as to12Hour, p as padNumber, a as to24Hour, 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';
|
|
@@ -493,172 +493,56 @@ const DatePickerTrigger = forwardRef(
|
|
|
493
493
|
);
|
|
494
494
|
DatePickerTrigger.displayName = "DatePickerTrigger";
|
|
495
495
|
|
|
496
|
-
const
|
|
497
|
-
const
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
});
|
|
503
|
-
const clampIndex = (index) => Math.max(0, Math.min(2, index));
|
|
504
|
-
const withSegment = (state, key, value) => ({ ...state, [key]: value });
|
|
505
|
-
const snapMinute = (minutes, step = 1) => padNumber(Math.min(60 - step, Math.round(Number(minutes) / step) * step));
|
|
506
|
-
const emptySegmentedTime = () => ({
|
|
507
|
-
hour: EMPTY_SEGMENT,
|
|
508
|
-
minute: EMPTY_SEGMENT,
|
|
509
|
-
period: EMPTY_SEGMENT,
|
|
510
|
-
active: 0
|
|
496
|
+
const MINUTES_IN_DAY = 24 * 60;
|
|
497
|
+
const snapMinute = (minutes, step = 1) => Math.min(60 - step, Math.round(minutes / step) * step);
|
|
498
|
+
const snapTimeValue = (value, step = 1) => ({
|
|
499
|
+
hours: value.hours,
|
|
500
|
+
minutes: snapMinute(value.minutes, step),
|
|
501
|
+
seconds: 0
|
|
511
502
|
});
|
|
512
|
-
const
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
minute: segment(snapMinute(value.minutes, step), true),
|
|
517
|
-
period: segment(period, true),
|
|
518
|
-
active: 0
|
|
519
|
-
};
|
|
520
|
-
};
|
|
521
|
-
const isSegmentedTimeEmpty = (state) => SEGMENT_KEYS.every((key) => state[key].text === "");
|
|
522
|
-
const getSegmentedTimeError = (state) => {
|
|
523
|
-
if (isSegmentedTimeEmpty(state)) return "timeRequired";
|
|
524
|
-
if (!state.hour.text) return "hourRequired";
|
|
525
|
-
if (!state.minute.text) return "minuteRequired";
|
|
526
|
-
if (!state.period.text) return "periodRequired";
|
|
527
|
-
return null;
|
|
528
|
-
};
|
|
529
|
-
const segmentedTimeToValue = (state) => {
|
|
530
|
-
if (getSegmentedTimeError(state)) return null;
|
|
531
|
-
return {
|
|
532
|
-
hours: to24Hour(Number(state.hour.text), state.period.text),
|
|
533
|
-
minutes: Number(state.minute.text),
|
|
534
|
-
seconds: 0
|
|
535
|
-
};
|
|
536
|
-
};
|
|
537
|
-
const finishSegment = (state, key, step) => {
|
|
538
|
-
const { text } = state[key];
|
|
539
|
-
if (!text) return state;
|
|
540
|
-
if (key === "hour" && text === "0") {
|
|
541
|
-
return withSegment(state, "hour", EMPTY_SEGMENT);
|
|
542
|
-
}
|
|
543
|
-
if (key === "minute" && text.length === 1) {
|
|
544
|
-
return withSegment(
|
|
545
|
-
state,
|
|
546
|
-
"minute",
|
|
547
|
-
segment(snapMinute(text, step), true, true)
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
return withSegment(state, key, { ...state[key], done: true });
|
|
503
|
+
const toMinutes = (value) => value.hours * 60 + value.minutes;
|
|
504
|
+
const fromMinutes = (minutes) => {
|
|
505
|
+
const clamped = Math.max(0, Math.min(MINUTES_IN_DAY - 1, minutes));
|
|
506
|
+
return { hours: Math.floor(clamped / 60), minutes: clamped % 60, seconds: 0 };
|
|
551
507
|
};
|
|
552
|
-
const
|
|
553
|
-
const
|
|
554
|
-
const
|
|
555
|
-
|
|
556
|
-
return { ...finished, active: next };
|
|
557
|
-
};
|
|
558
|
-
const focusFirstEmptySegment = (state) => {
|
|
559
|
-
const index = SEGMENT_KEYS.findIndex((key) => !state[key].text);
|
|
560
|
-
return { ...state, active: index === -1 ? 2 : index };
|
|
561
|
-
};
|
|
562
|
-
const nextSegment = (state, step = 1) => state[SEGMENT_KEYS[state.active]].text ? focusSegment(state, state.active + 1, step) : state;
|
|
563
|
-
const previousSegment = (state) => focusSegment(state, state.active - 1);
|
|
564
|
-
const typeDigit = (state, digit, step = 1) => {
|
|
565
|
-
const advance = (next, index) => focusSegment(next, index, step);
|
|
566
|
-
const key = SEGMENT_KEYS[state.active];
|
|
567
|
-
if (key === "period") return state;
|
|
568
|
-
const current = state[key];
|
|
569
|
-
const text = current.done ? "" : current.text;
|
|
570
|
-
if (key === "hour") {
|
|
571
|
-
if (text === "") {
|
|
572
|
-
if (digit === "0" || digit === "1") {
|
|
573
|
-
return withSegment(state, "hour", segment(digit, false));
|
|
574
|
-
}
|
|
575
|
-
return advance(withSegment(state, "hour", segment(digit, true)), 1);
|
|
576
|
-
}
|
|
577
|
-
if (text === "1") {
|
|
578
|
-
if ("012".includes(digit)) {
|
|
579
|
-
return advance(
|
|
580
|
-
withSegment(state, "hour", segment(`1${digit}`, true)),
|
|
581
|
-
1
|
|
582
|
-
);
|
|
583
|
-
}
|
|
584
|
-
const moved = advance(withSegment(state, "hour", segment("1", true)), 1);
|
|
585
|
-
return typeDigit(moved, digit, step);
|
|
586
|
-
}
|
|
587
|
-
if (digit === "0") return state;
|
|
588
|
-
return advance(withSegment(state, "hour", segment(digit, true)), 1);
|
|
589
|
-
}
|
|
590
|
-
if (text === "") {
|
|
591
|
-
if (digit >= "6") {
|
|
592
|
-
return advance(
|
|
593
|
-
withSegment(
|
|
594
|
-
state,
|
|
595
|
-
"minute",
|
|
596
|
-
segment(snapMinute(digit, step), true, true)
|
|
597
|
-
),
|
|
598
|
-
2
|
|
599
|
-
);
|
|
600
|
-
}
|
|
601
|
-
return withSegment(state, "minute", segment(digit, false));
|
|
602
|
-
}
|
|
603
|
-
return advance(
|
|
604
|
-
withSegment(state, "minute", segment(snapMinute(text + digit, step), true)),
|
|
605
|
-
2
|
|
606
|
-
);
|
|
508
|
+
const lastMinuteOfDay = (step = 1) => 23 * 60 + Math.floor(59 / step) * step;
|
|
509
|
+
const formatTimeText = (value) => {
|
|
510
|
+
const { hour12, period } = to12Hour(value.hours);
|
|
511
|
+
return `${hour12}:${padNumber(value.minutes)} ${period}`;
|
|
607
512
|
};
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
);
|
|
613
|
-
const
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
);
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
const minute = state.minute.text === "" ? direction > 0 ? -step : 0 : Number(state.minute.text);
|
|
627
|
-
const stepped = direction > 0 ? Math.floor(minute / step) * step + step : Math.ceil(minute / step) * step - step;
|
|
628
|
-
return withSegment(
|
|
629
|
-
state,
|
|
630
|
-
"minute",
|
|
631
|
-
segment(padNumber((stepped + 60) % 60), true)
|
|
632
|
-
);
|
|
513
|
+
const parseTimeText = (text, step = 1) => {
|
|
514
|
+
const normalized = text.toLowerCase().trim().replace(/(\d)\s+(?=\d)/g, "$1:").replace(/\s+/g, "").replace(/([ap])\.?m?\.?$/, "$1");
|
|
515
|
+
if (!normalized) return null;
|
|
516
|
+
const match = normalized.match(/^(\d{1,4})(?:[:.](\d{0,2}))?([ap])?$/);
|
|
517
|
+
if (!match) return "invalid";
|
|
518
|
+
const [, digits, minuteText, period] = match;
|
|
519
|
+
let hourText = digits;
|
|
520
|
+
let minutes = 0;
|
|
521
|
+
if (minuteText !== void 0) {
|
|
522
|
+
if (digits.length > 2) return "invalid";
|
|
523
|
+
minutes = Number(minuteText.padEnd(2, "0"));
|
|
524
|
+
} else if (digits.length === 4) {
|
|
525
|
+
hourText = digits.slice(0, 2);
|
|
526
|
+
minutes = Number(digits.slice(2));
|
|
527
|
+
} else if (digits.length === 3) {
|
|
528
|
+
const isTwoDigitHour = /^1[0-2][0-5]$/.test(digits);
|
|
529
|
+
hourText = isTwoDigitHour ? digits.slice(0, 2) : digits.slice(0, 1);
|
|
530
|
+
minutes = isTwoDigitHour ? Number(digits[2]) * 10 : Number(digits.slice(1));
|
|
633
531
|
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
const backspace = (state) => {
|
|
637
|
-
const moveBack = state[SEGMENT_KEYS[state.active]].text === "" && state.active > 0;
|
|
638
|
-
const active = moveBack ? clampIndex(state.active - 1) : state.active;
|
|
639
|
-
const key = SEGMENT_KEYS[active];
|
|
640
|
-
const current = state[key];
|
|
641
|
-
const text = key === "period" || current.auto ? "" : current.text.slice(0, -1);
|
|
642
|
-
return { ...withSegment(state, key, segment(text, false)), active };
|
|
643
|
-
};
|
|
644
|
-
const parsePastedTime = (text, step = 1) => {
|
|
645
|
-
const match = text.trim().toLowerCase().match(/^(\d{1,2}):?(\d{2})?\s*([ap])?\.?m?\.?$/);
|
|
646
|
-
if (!match) return null;
|
|
647
|
-
let hours = Number(match[1]);
|
|
648
|
-
const minutes = Number(match[2] ?? 0);
|
|
649
|
-
const period = match[3];
|
|
650
|
-
if (minutes > 59) return null;
|
|
532
|
+
let hours = Number(hourText);
|
|
533
|
+
if (minutes > 59) return "invalid";
|
|
651
534
|
if (period) {
|
|
652
|
-
if (hours < 1 || hours > 12) return
|
|
653
|
-
hours = hours
|
|
535
|
+
if (hours < 1 || hours > 12) return "invalid";
|
|
536
|
+
hours = to24Hour(hours, period === "a" ? "AM" : "PM");
|
|
654
537
|
} else if (hours > 23) {
|
|
655
|
-
return
|
|
538
|
+
return "invalid";
|
|
656
539
|
}
|
|
657
|
-
return { hours, minutes
|
|
540
|
+
return snapTimeValue({ hours, minutes}, step);
|
|
658
541
|
};
|
|
542
|
+
const getTimeTextError = (parsed) => parsed === null ? "timeRequired" : null;
|
|
659
543
|
|
|
660
|
-
const
|
|
661
|
-
const
|
|
544
|
+
const FALLBACK_TIME = { hours: 12, minutes: 0, seconds: 0 };
|
|
545
|
+
const TimeInput = forwardRef(
|
|
662
546
|
({
|
|
663
547
|
value,
|
|
664
548
|
minuteStep,
|
|
@@ -672,153 +556,98 @@ const SegmentedTimeInput = forwardRef(
|
|
|
672
556
|
"data-testid": dataTestId = "datepicker-time-input"
|
|
673
557
|
}, ref) => {
|
|
674
558
|
const { t } = useTranslation();
|
|
675
|
-
const fieldRef = useRef(null);
|
|
676
559
|
const step = minuteStep ?? 1;
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
);
|
|
560
|
+
const inputRef = useRef(null);
|
|
561
|
+
const isPointerFocusRef = useRef(false);
|
|
680
562
|
const lastEmittedRef = useRef(value);
|
|
563
|
+
const [text, setText] = useState(
|
|
564
|
+
() => formatTimeText(snapTimeValue(value, step))
|
|
565
|
+
);
|
|
566
|
+
const emit = (next) => {
|
|
567
|
+
if (timeValueEquals(next, lastEmittedRef.current)) return;
|
|
568
|
+
lastEmittedRef.current = next;
|
|
569
|
+
onChange(next);
|
|
570
|
+
};
|
|
681
571
|
useEffect(() => {
|
|
682
572
|
if (timeValueEquals(value, lastEmittedRef.current)) return;
|
|
683
573
|
lastEmittedRef.current = value;
|
|
684
|
-
|
|
574
|
+
setText(formatTimeText(value));
|
|
575
|
+
onErrorChange(null);
|
|
685
576
|
}, [value]);
|
|
686
|
-
const error = getSegmentedTimeError(time);
|
|
687
577
|
useEffect(() => {
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
useEffect(() => {
|
|
691
|
-
const snapped = segmentedTimeToValue(time);
|
|
692
|
-
if (snapped && !timeValueEquals(snapped, value)) {
|
|
693
|
-
lastEmittedRef.current = snapped;
|
|
694
|
-
onChange(snapped);
|
|
695
|
-
}
|
|
578
|
+
const snapped = snapTimeValue(value, step);
|
|
579
|
+
if (!timeValueEquals(snapped, value)) emit(snapped);
|
|
696
580
|
}, []);
|
|
581
|
+
const focusAndSelect = () => {
|
|
582
|
+
inputRef.current?.focus();
|
|
583
|
+
inputRef.current?.select();
|
|
584
|
+
};
|
|
697
585
|
useEffect(() => {
|
|
698
|
-
if (autoFocus)
|
|
586
|
+
if (autoFocus) focusAndSelect();
|
|
699
587
|
}, [autoFocus]);
|
|
700
|
-
useImperativeHandle(ref, () => ({
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
setTime(next);
|
|
708
|
-
const nextValue = segmentedTimeToValue(next);
|
|
709
|
-
if (!nextValue || timeValueEquals(nextValue, lastEmittedRef.current)) {
|
|
710
|
-
return;
|
|
711
|
-
}
|
|
712
|
-
lastEmittedRef.current = nextValue;
|
|
713
|
-
onChange(nextValue);
|
|
588
|
+
useImperativeHandle(ref, () => ({ focus: focusAndSelect }));
|
|
589
|
+
const handleChange = (event) => {
|
|
590
|
+
const nextText = event.target.value;
|
|
591
|
+
setText(nextText);
|
|
592
|
+
const parsed = parseTimeText(nextText, step);
|
|
593
|
+
onErrorChange(getTimeTextError(parsed));
|
|
594
|
+
if (parsed !== null && parsed !== "invalid") emit(parsed);
|
|
714
595
|
};
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
|
|
596
|
+
const tidy = () => {
|
|
597
|
+
const parsed = parseTimeText(text, step);
|
|
598
|
+
if (parsed === null) return;
|
|
599
|
+
const next = parsed === "invalid" ? FALLBACK_TIME : parsed;
|
|
600
|
+
setText(formatTimeText(next));
|
|
601
|
+
onErrorChange(null);
|
|
602
|
+
emit(next);
|
|
718
603
|
};
|
|
719
604
|
const handleKeyDown = (event) => {
|
|
720
|
-
|
|
721
|
-
if (key === "Tab") {
|
|
722
|
-
if (!event.shiftKey || time.active !== 2) return;
|
|
723
|
-
consume(event);
|
|
724
|
-
update(togglePeriod(time));
|
|
725
|
-
return;
|
|
726
|
-
}
|
|
727
|
-
if ((event.metaKey || event.ctrlKey) && key === "Backspace") {
|
|
728
|
-
consume(event);
|
|
729
|
-
update(emptySegmentedTime());
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
732
|
-
if (event.metaKey || event.ctrlKey || event.altKey) return;
|
|
733
|
-
let next = null;
|
|
734
|
-
if (/^[0-9]$/.test(key)) next = typeDigit(time, key, step);
|
|
735
|
-
else if (/^[ap]$/i.test(key)) {
|
|
736
|
-
next = typePeriod(time, key.toLowerCase(), step);
|
|
737
|
-
} else if (/^m$/i.test(key))
|
|
738
|
-
next = time;
|
|
739
|
-
else if (key === ":" || key === " " || key === "ArrowRight") {
|
|
740
|
-
next = nextSegment(time, step);
|
|
741
|
-
} else if (key === "ArrowLeft") next = previousSegment(time);
|
|
742
|
-
else if (key === "ArrowUp") next = stepSegment(time, 1, step);
|
|
743
|
-
else if (key === "ArrowDown") next = stepSegment(time, -1, step);
|
|
744
|
-
else if (key === "Backspace" || key === "Delete") next = backspace(time);
|
|
745
|
-
if (!next) return;
|
|
746
|
-
consume(event);
|
|
747
|
-
update(next);
|
|
748
|
-
};
|
|
749
|
-
const handlePaste = (event) => {
|
|
605
|
+
if (event.key !== "Enter") return;
|
|
750
606
|
event.preventDefault();
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
update({ ...segmentedTimeFromValue(pasted, step), active: 2 });
|
|
754
|
-
};
|
|
755
|
-
const handleMouseDown = (event) => {
|
|
756
|
-
if (disabled) return;
|
|
757
|
-
const segmentEl = event.target.closest(
|
|
758
|
-
"[data-segment]"
|
|
759
|
-
);
|
|
760
|
-
if (segmentEl) {
|
|
761
|
-
event.preventDefault();
|
|
762
|
-
fieldRef.current?.focus();
|
|
763
|
-
update(focusSegment(time, Number(segmentEl.dataset.segment), step));
|
|
764
|
-
return;
|
|
765
|
-
}
|
|
766
|
-
update(focusFirstEmptySegment(time));
|
|
607
|
+
event.stopPropagation();
|
|
608
|
+
tidy();
|
|
767
609
|
};
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
return index < 2 && !done ? `${text}_` : text;
|
|
610
|
+
const handleFocus = () => {
|
|
611
|
+
if (!isPointerFocusRef.current) inputRef.current?.select();
|
|
612
|
+
isPointerFocusRef.current = false;
|
|
772
613
|
};
|
|
773
614
|
return /* @__PURE__ */ jsx(
|
|
774
|
-
"
|
|
615
|
+
"input",
|
|
775
616
|
{
|
|
776
|
-
ref:
|
|
777
|
-
role: "group",
|
|
778
|
-
tabIndex: disabled ? -1 : 0,
|
|
779
|
-
"aria-label": ariaLabel ?? t("neetoatoms.datePicker.timeField", "Time"),
|
|
617
|
+
ref: inputRef,
|
|
780
618
|
"aria-describedby": ariaDescribedBy,
|
|
781
619
|
"aria-invalid": invalid || void 0,
|
|
782
|
-
"aria-
|
|
620
|
+
"aria-label": ariaLabel ?? t("neetoatoms.datePicker.timeField", "Time"),
|
|
621
|
+
autoComplete: "off",
|
|
783
622
|
"data-testid": dataTestId,
|
|
623
|
+
disabled,
|
|
624
|
+
placeholder: t("neetoatoms.datePicker.timePlaceholder", "Time"),
|
|
625
|
+
spellCheck: false,
|
|
626
|
+
type: "text",
|
|
627
|
+
value: text,
|
|
784
628
|
className: cn(
|
|
785
|
-
"
|
|
629
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 text-sm tabular-nums outline-none placeholder:text-muted-foreground",
|
|
786
630
|
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
787
631
|
invalid && "border-destructive",
|
|
788
|
-
disabled && "
|
|
632
|
+
disabled && "cursor-not-allowed opacity-50"
|
|
789
633
|
),
|
|
790
|
-
onBlur:
|
|
634
|
+
onBlur: tidy,
|
|
635
|
+
onChange: handleChange,
|
|
636
|
+
onFocus: handleFocus,
|
|
791
637
|
onKeyDown: handleKeyDown,
|
|
792
|
-
onMouseDown:
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
/* @__PURE__ */ jsx(
|
|
798
|
-
"span",
|
|
799
|
-
{
|
|
800
|
-
"data-segment": index,
|
|
801
|
-
"data-testid": `datepicker-time-${key}`,
|
|
802
|
-
className: cn(
|
|
803
|
-
"min-w-[2ch] px-0.5 text-center whitespace-pre",
|
|
804
|
-
!time[key].text && "text-muted-foreground",
|
|
805
|
-
index === time.active && "group-focus/time:shadow-[inset_0_-1.5px_0_var(--color-muted-foreground)]"
|
|
806
|
-
),
|
|
807
|
-
children: segmentText(index)
|
|
808
|
-
}
|
|
809
|
-
)
|
|
810
|
-
] }, key))
|
|
638
|
+
onMouseDown: () => {
|
|
639
|
+
if (document.activeElement !== inputRef.current) {
|
|
640
|
+
isPointerFocusRef.current = true;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
811
643
|
}
|
|
812
644
|
);
|
|
813
645
|
}
|
|
814
646
|
);
|
|
815
|
-
|
|
647
|
+
TimeInput.displayName = "TimeInput";
|
|
816
648
|
|
|
817
649
|
const ERROR_DEFAULTS = {
|
|
818
|
-
timeRequired: "Enter a time, or turn off Add time."
|
|
819
|
-
hourRequired: "Enter an hour.",
|
|
820
|
-
minuteRequired: "Enter minutes.",
|
|
821
|
-
periodRequired: "Type a or p for AM or PM."
|
|
650
|
+
timeRequired: "Enter a time, or turn off Add time."
|
|
822
651
|
};
|
|
823
652
|
const stepExamples = (step) => {
|
|
824
653
|
const pad = (minutes) => `1:${String(minutes).padStart(2, "0")}`;
|
|
@@ -889,7 +718,7 @@ const TimeSection = ({
|
|
|
889
718
|
] }),
|
|
890
719
|
isTimeOn && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
891
720
|
/* @__PURE__ */ jsx(
|
|
892
|
-
|
|
721
|
+
TimeInput,
|
|
893
722
|
{
|
|
894
723
|
"aria-describedby": [showHint ? hintId : null, errorMessage ? errorId : null].filter(Boolean).join(" ") || void 0,
|
|
895
724
|
autoFocus: focusOnMount,
|
|
@@ -1038,6 +867,7 @@ const RangeCalendar = ({
|
|
|
1038
867
|
}
|
|
1039
868
|
) });
|
|
1040
869
|
|
|
870
|
+
const SAME_DAY_END_GAP = 30;
|
|
1041
871
|
const ENDPOINT_LABELS = {
|
|
1042
872
|
from: "Start",
|
|
1043
873
|
to: "End"
|
|
@@ -1083,12 +913,21 @@ const RangeTimeSection = ({
|
|
|
1083
913
|
[handleErrorChange]
|
|
1084
914
|
);
|
|
1085
915
|
const showHint = (minuteStep ?? 1) > 1;
|
|
916
|
+
const handleFromChange = (value) => {
|
|
917
|
+
onFromChange(value);
|
|
918
|
+
if (!isEndOnStartDay) return;
|
|
919
|
+
const step = minuteStep ?? 1;
|
|
920
|
+
const gap = Math.ceil(SAME_DAY_END_GAP / step) * step;
|
|
921
|
+
onToChange(
|
|
922
|
+
fromMinutes(Math.min(toMinutes(value) + gap, lastMinuteOfDay(step)))
|
|
923
|
+
);
|
|
924
|
+
};
|
|
1086
925
|
const endpoints = [
|
|
1087
926
|
{
|
|
1088
927
|
endpoint: "from",
|
|
1089
928
|
dateLabel: fromDateLabel,
|
|
1090
929
|
value: fromValue,
|
|
1091
|
-
onChange:
|
|
930
|
+
onChange: handleFromChange,
|
|
1092
931
|
onFieldErrorChange: handleFromErrorChange
|
|
1093
932
|
},
|
|
1094
933
|
{
|
|
@@ -1136,7 +975,7 @@ const RangeTimeSection = ({
|
|
|
1136
975
|
}
|
|
1137
976
|
),
|
|
1138
977
|
/* @__PURE__ */ jsx(
|
|
1139
|
-
|
|
978
|
+
TimeInput,
|
|
1140
979
|
{
|
|
1141
980
|
"aria-describedby": [
|
|
1142
981
|
showHint ? hintId : null,
|
|
@@ -1880,7 +1719,7 @@ const DatePicker = forwardRef(
|
|
|
1880
1719
|
const handleRangeCalendarKeyDown = (e) => {
|
|
1881
1720
|
if (e.key !== "Tab" || e.shiftKey || !draftRange) return;
|
|
1882
1721
|
e.preventDefault();
|
|
1883
|
-
fromTimeRef.current?.
|
|
1722
|
+
fromTimeRef.current?.focus();
|
|
1884
1723
|
};
|
|
1885
1724
|
const handleGridPickerSelect = (date) => {
|
|
1886
1725
|
commitValue(date);
|
|
@@ -1960,7 +1799,8 @@ const DatePicker = forwardRef(
|
|
|
1960
1799
|
PopoverContent,
|
|
1961
1800
|
{
|
|
1962
1801
|
id: popoverContentId,
|
|
1963
|
-
className: "w-auto p-0",
|
|
1802
|
+
className: "max-h-(--radix-popover-content-available-height) w-auto overflow-y-auto p-0",
|
|
1803
|
+
collisionPadding: 8,
|
|
1964
1804
|
align,
|
|
1965
1805
|
side,
|
|
1966
1806
|
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
@@ -2107,4 +1947,4 @@ const DatePicker = forwardRef(
|
|
|
2107
1947
|
DatePicker.displayName = "DatePicker";
|
|
2108
1948
|
|
|
2109
1949
|
export { DatePicker as D };
|
|
2110
|
-
//# sourceMappingURL=DatePicker-
|
|
1950
|
+
//# sourceMappingURL=DatePicker-DYsyV9BJ.js.map
|