@kalyx/react 0.3.0 → 1.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +152 -0
- package/dist/index.cjs +497 -72
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +287 -6
- package/dist/index.d.ts +287 -6
- package/dist/index.js +496 -74
- package/dist/index.js.map +1 -1
- package/package.json +12 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, forwardRef, useState, useCallback, useContext, useId, useRef, useMemo, useEffect } from 'react';
|
|
2
|
-
import { parseInputValue, formatTimeString, parseTimeString, getTime, DateFnsAdapter, DEFAULT_DATEPICKER_LABELS, getMonthName, getWeekdayNames, getCalendarDays, formatMonthYear, isDateDisabled, DEFAULT_RANGEPICKER_LABELS, DEFAULT_TIMEPICKER_LABELS, setTime, to12Hour, to24Hour, generateMinutes, generateHours, formatFullDate } from '@kalyx/core';
|
|
2
|
+
import { parseInputValue, formatTimeString, parseTimeString, getTimeInTimezone, getTime, DateFnsAdapter, DEFAULT_DATEPICKER_LABELS, civilMidnightFromUtcDay, getMonthName, getWeekdayNames, getCalendarDays, formatMonthYear, isDateDisabled, DEFAULT_RANGEPICKER_LABELS, DEFAULT_TIMEPICKER_LABELS, setTimeInTimezone, setTime, to12Hour, to24Hour, generateMinutes, generateHours, formatFullDate } from '@kalyx/core';
|
|
3
3
|
export { DateFnsAdapter } from '@kalyx/core';
|
|
4
4
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
5
|
import { useFloating, autoUpdate, offset, flip, shift } from '@floating-ui/react';
|
|
@@ -20,15 +20,29 @@ function useDatePickerContext(componentName) {
|
|
|
20
20
|
}
|
|
21
21
|
return context;
|
|
22
22
|
}
|
|
23
|
+
function useChangeEffect(value, callback) {
|
|
24
|
+
const callbackRef = useRef(callback);
|
|
25
|
+
callbackRef.current = callback;
|
|
26
|
+
const prevRef = useRef(value);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (prevRef.current !== value) {
|
|
29
|
+
prevRef.current = value;
|
|
30
|
+
callbackRef.current?.(value);
|
|
31
|
+
}
|
|
32
|
+
}, [value]);
|
|
33
|
+
}
|
|
23
34
|
function DatePickerRoot({
|
|
24
35
|
value: controlledValue,
|
|
25
36
|
defaultValue,
|
|
26
37
|
onChange,
|
|
38
|
+
onOpenChange,
|
|
39
|
+
onCalendarNavigate,
|
|
27
40
|
disabled = false,
|
|
28
41
|
readOnly = false,
|
|
29
42
|
weekStartsOn = 0,
|
|
30
43
|
displayFormat = "yyyy-MM-dd",
|
|
31
44
|
locale = "en-US",
|
|
45
|
+
displayTimezone,
|
|
32
46
|
adapter = DateFnsAdapter,
|
|
33
47
|
labels: labelsProp,
|
|
34
48
|
children
|
|
@@ -42,11 +56,14 @@ function DatePickerRoot({
|
|
|
42
56
|
const currentValue = isControlled ? controlledValue ?? null : uncontrolledValue;
|
|
43
57
|
const [isOpen, setIsOpen] = useState(false);
|
|
44
58
|
const [viewMonth, setViewMonth] = useState(
|
|
45
|
-
currentValue ?? adapter.today()
|
|
59
|
+
currentValue ?? adapter.today(displayTimezone)
|
|
46
60
|
);
|
|
47
61
|
const [focusedDate, setFocusedDate] = useState(
|
|
48
|
-
currentValue ?? adapter.today()
|
|
62
|
+
currentValue ?? adapter.today(displayTimezone)
|
|
49
63
|
);
|
|
64
|
+
useChangeEffect(isOpen, onOpenChange);
|
|
65
|
+
const viewMonthStart = useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
|
|
66
|
+
useChangeEffect(viewMonthStart, onCalendarNavigate);
|
|
50
67
|
const mergedLabels = useMemo(
|
|
51
68
|
() => ({ ...DEFAULT_DATEPICKER_LABELS, ...labelsProp }),
|
|
52
69
|
[labelsProp]
|
|
@@ -59,21 +76,22 @@ function DatePickerRoot({
|
|
|
59
76
|
const selectDate = useCallback(
|
|
60
77
|
(iso) => {
|
|
61
78
|
if (isDisabled || readOnly) return;
|
|
79
|
+
const normalized = iso && displayTimezone ? civilMidnightFromUtcDay(iso, displayTimezone) : iso;
|
|
62
80
|
if (!isControlled) {
|
|
63
|
-
setUncontrolledValue(
|
|
81
|
+
setUncontrolledValue(normalized);
|
|
64
82
|
}
|
|
65
|
-
onChange?.(
|
|
83
|
+
onChange?.(normalized);
|
|
66
84
|
setIsOpen(false);
|
|
67
85
|
},
|
|
68
|
-
[isControlled, isDisabled, readOnly, onChange]
|
|
86
|
+
[isControlled, isDisabled, readOnly, onChange, displayTimezone]
|
|
69
87
|
);
|
|
70
88
|
const open = useCallback(() => {
|
|
71
89
|
if (isDisabled || readOnly) return;
|
|
72
90
|
setIsOpen(true);
|
|
73
|
-
const target = currentValue ?? adapter.today();
|
|
91
|
+
const target = currentValue ?? adapter.today(displayTimezone);
|
|
74
92
|
setViewMonth(target);
|
|
75
93
|
setFocusedDate(target);
|
|
76
|
-
}, [isDisabled, readOnly, currentValue, adapter]);
|
|
94
|
+
}, [isDisabled, readOnly, currentValue, adapter, displayTimezone]);
|
|
77
95
|
const close = useCallback(() => {
|
|
78
96
|
setIsOpen(false);
|
|
79
97
|
}, []);
|
|
@@ -102,6 +120,7 @@ function DatePickerRoot({
|
|
|
102
120
|
weekStartsOn,
|
|
103
121
|
displayFormat,
|
|
104
122
|
locale,
|
|
123
|
+
displayTimezone,
|
|
105
124
|
isDisabled,
|
|
106
125
|
isReadOnly: readOnly,
|
|
107
126
|
pickerId,
|
|
@@ -121,6 +140,7 @@ function DatePickerRoot({
|
|
|
121
140
|
weekStartsOn,
|
|
122
141
|
displayFormat,
|
|
123
142
|
locale,
|
|
143
|
+
displayTimezone,
|
|
124
144
|
isDisabled,
|
|
125
145
|
readOnly,
|
|
126
146
|
pickerId,
|
|
@@ -137,7 +157,7 @@ var DatePickerInput = forwardRef(
|
|
|
137
157
|
let formattedValue = "";
|
|
138
158
|
if (ctx.value) {
|
|
139
159
|
try {
|
|
140
|
-
formattedValue = ctx.adapter.format(ctx.value, displayFormat);
|
|
160
|
+
formattedValue = ctx.adapter.format(ctx.value, displayFormat, ctx.displayTimezone);
|
|
141
161
|
} catch {
|
|
142
162
|
formattedValue = ctx.value;
|
|
143
163
|
}
|
|
@@ -385,13 +405,14 @@ function DatePickerCalendar({ classNames, onTitleClick, ...props }) {
|
|
|
385
405
|
const ctx = useDatePickerContext("DatePicker.Calendar");
|
|
386
406
|
const gridRef = useRef(null);
|
|
387
407
|
const [announcement, setAnnouncement] = useState("");
|
|
388
|
-
const { adapter, viewMonth, focusedDate, weekStartsOn, disabled, locale } = ctx;
|
|
408
|
+
const { adapter, viewMonth, focusedDate, weekStartsOn, disabled, locale, displayTimezone } = ctx;
|
|
389
409
|
const weekdays = getWeekdayNames(locale, weekStartsOn);
|
|
390
410
|
const weeks = getCalendarDays(viewMonth, adapter, {
|
|
391
411
|
weekStartsOn,
|
|
392
412
|
selected: ctx.value,
|
|
393
413
|
focusedDate,
|
|
394
|
-
disabled
|
|
414
|
+
disabled,
|
|
415
|
+
timezone: displayTimezone
|
|
395
416
|
});
|
|
396
417
|
const year = adapter.getYear(viewMonth);
|
|
397
418
|
const month = adapter.getMonth(viewMonth);
|
|
@@ -772,6 +793,95 @@ function DatePickerYearGrid({
|
|
|
772
793
|
)
|
|
773
794
|
] });
|
|
774
795
|
}
|
|
796
|
+
function DatePickerPresets({ classNames, children, ...props }) {
|
|
797
|
+
const ctx = useDatePickerContext("DatePicker.Presets");
|
|
798
|
+
return /* @__PURE__ */ jsx(
|
|
799
|
+
"div",
|
|
800
|
+
{
|
|
801
|
+
role: "group",
|
|
802
|
+
"aria-label": ctx.labels.popoverLabel,
|
|
803
|
+
className: classNames?.root,
|
|
804
|
+
...props,
|
|
805
|
+
children
|
|
806
|
+
}
|
|
807
|
+
);
|
|
808
|
+
}
|
|
809
|
+
function resolveDatePreset(key, today, adapter) {
|
|
810
|
+
switch (key) {
|
|
811
|
+
case "today":
|
|
812
|
+
return today;
|
|
813
|
+
case "tomorrow":
|
|
814
|
+
return adapter.addDays(today, 1);
|
|
815
|
+
case "yesterday":
|
|
816
|
+
return adapter.addDays(today, -1);
|
|
817
|
+
case "startOfMonth":
|
|
818
|
+
return adapter.startOfMonth(today);
|
|
819
|
+
case "endOfMonth":
|
|
820
|
+
return adapter.startOfDay(adapter.endOfMonth(today));
|
|
821
|
+
case "startOfYear": {
|
|
822
|
+
const currentMonth = adapter.getMonth(today);
|
|
823
|
+
return adapter.startOfMonth(adapter.addMonths(today, -currentMonth));
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
function DatePickerPreset({
|
|
828
|
+
value: presetKey,
|
|
829
|
+
date: directDate,
|
|
830
|
+
children,
|
|
831
|
+
onClick,
|
|
832
|
+
...props
|
|
833
|
+
}) {
|
|
834
|
+
const ctx = useDatePickerContext("DatePicker.Preset");
|
|
835
|
+
const handleClick = useCallback(
|
|
836
|
+
(e) => {
|
|
837
|
+
if (ctx.isDisabled || ctx.isReadOnly) return;
|
|
838
|
+
let resolved;
|
|
839
|
+
if (directDate) {
|
|
840
|
+
resolved = directDate;
|
|
841
|
+
} else if (presetKey) {
|
|
842
|
+
resolved = resolveDatePreset(
|
|
843
|
+
presetKey,
|
|
844
|
+
ctx.adapter.today(ctx.displayTimezone),
|
|
845
|
+
ctx.adapter
|
|
846
|
+
);
|
|
847
|
+
} else {
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
ctx.selectDate(resolved);
|
|
851
|
+
onClick?.(e);
|
|
852
|
+
},
|
|
853
|
+
[ctx, presetKey, directDate, onClick]
|
|
854
|
+
);
|
|
855
|
+
const isActive = (() => {
|
|
856
|
+
if (!ctx.value) return false;
|
|
857
|
+
let target;
|
|
858
|
+
if (directDate) {
|
|
859
|
+
target = directDate;
|
|
860
|
+
} else if (presetKey) {
|
|
861
|
+
target = resolveDatePreset(
|
|
862
|
+
presetKey,
|
|
863
|
+
ctx.adapter.today(ctx.displayTimezone),
|
|
864
|
+
ctx.adapter
|
|
865
|
+
);
|
|
866
|
+
} else {
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
return ctx.adapter.isSameDay(ctx.value, target, ctx.displayTimezone);
|
|
870
|
+
})();
|
|
871
|
+
return /* @__PURE__ */ jsx(
|
|
872
|
+
"button",
|
|
873
|
+
{
|
|
874
|
+
type: "button",
|
|
875
|
+
role: "option",
|
|
876
|
+
"aria-selected": isActive,
|
|
877
|
+
"data-active": isActive || void 0,
|
|
878
|
+
disabled: ctx.isDisabled,
|
|
879
|
+
onClick: handleClick,
|
|
880
|
+
...props,
|
|
881
|
+
children
|
|
882
|
+
}
|
|
883
|
+
);
|
|
884
|
+
}
|
|
775
885
|
|
|
776
886
|
// src/components/DatePicker/index.ts
|
|
777
887
|
var DatePicker = Object.assign(DatePickerRoot, {
|
|
@@ -780,7 +890,9 @@ var DatePicker = Object.assign(DatePickerRoot, {
|
|
|
780
890
|
Popover: DatePickerPopover,
|
|
781
891
|
Calendar: DatePickerCalendar,
|
|
782
892
|
MonthGrid: DatePickerMonthGrid,
|
|
783
|
-
YearGrid: DatePickerYearGrid
|
|
893
|
+
YearGrid: DatePickerYearGrid,
|
|
894
|
+
Presets: DatePickerPresets,
|
|
895
|
+
Preset: DatePickerPreset
|
|
784
896
|
});
|
|
785
897
|
var RangePickerContext = createContext(null);
|
|
786
898
|
function useRangePickerContext(componentName) {
|
|
@@ -802,11 +914,14 @@ function RangePickerRoot({
|
|
|
802
914
|
value: controlledValue,
|
|
803
915
|
defaultValue,
|
|
804
916
|
onChange,
|
|
917
|
+
onOpenChange,
|
|
918
|
+
onCalendarNavigate,
|
|
805
919
|
disabled = false,
|
|
806
920
|
readOnly = false,
|
|
807
921
|
weekStartsOn = 0,
|
|
808
922
|
displayFormat = "yyyy-MM-dd",
|
|
809
923
|
locale = "en-US",
|
|
924
|
+
displayTimezone,
|
|
810
925
|
adapter = DateFnsAdapter,
|
|
811
926
|
labels: labelsProp,
|
|
812
927
|
children
|
|
@@ -822,11 +937,14 @@ function RangePickerRoot({
|
|
|
822
937
|
const [selectingTarget, setSelectingTarget] = useState("start");
|
|
823
938
|
const [hoverDate, setHoverDate] = useState(null);
|
|
824
939
|
const [viewMonth, setViewMonth] = useState(
|
|
825
|
-
currentValue.start ?? adapter.today()
|
|
940
|
+
currentValue.start ?? adapter.today(displayTimezone)
|
|
826
941
|
);
|
|
827
942
|
const [focusedDate, setFocusedDate] = useState(
|
|
828
|
-
currentValue.start ?? adapter.today()
|
|
943
|
+
currentValue.start ?? adapter.today(displayTimezone)
|
|
829
944
|
);
|
|
945
|
+
useChangeEffect(isOpen, onOpenChange);
|
|
946
|
+
const viewMonthStart = useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
|
|
947
|
+
useChangeEffect(viewMonthStart, onCalendarNavigate);
|
|
830
948
|
const mergedLabels = useMemo(
|
|
831
949
|
() => ({ ...DEFAULT_RANGEPICKER_LABELS, ...labelsProp }),
|
|
832
950
|
[labelsProp]
|
|
@@ -849,23 +967,24 @@ function RangePickerRoot({
|
|
|
849
967
|
const selectDate = useCallback(
|
|
850
968
|
(iso) => {
|
|
851
969
|
if (isDisabled || readOnly) return;
|
|
970
|
+
const normalized = displayTimezone ? civilMidnightFromUtcDay(iso, displayTimezone) : iso;
|
|
852
971
|
if (selectingTarget === "start") {
|
|
853
|
-
const newRange = { start:
|
|
972
|
+
const newRange = { start: normalized, end: null };
|
|
854
973
|
setRange(newRange);
|
|
855
974
|
setSelectingTarget("end");
|
|
856
975
|
setHoverDate(null);
|
|
857
976
|
} else {
|
|
858
977
|
const start = currentValue.start;
|
|
859
978
|
if (!start) {
|
|
860
|
-
setRange({ start:
|
|
979
|
+
setRange({ start: normalized, end: null });
|
|
861
980
|
setSelectingTarget("end");
|
|
862
981
|
return;
|
|
863
982
|
}
|
|
864
983
|
let newRange;
|
|
865
|
-
if (adapter.isBefore(
|
|
866
|
-
newRange = { start:
|
|
984
|
+
if (adapter.isBefore(normalized, start)) {
|
|
985
|
+
newRange = { start: normalized, end: start };
|
|
867
986
|
} else {
|
|
868
|
-
newRange = { start, end:
|
|
987
|
+
newRange = { start, end: normalized };
|
|
869
988
|
}
|
|
870
989
|
setRange(newRange);
|
|
871
990
|
setSelectingTarget("start");
|
|
@@ -873,18 +992,18 @@ function RangePickerRoot({
|
|
|
873
992
|
setIsOpen(false);
|
|
874
993
|
}
|
|
875
994
|
},
|
|
876
|
-
[isDisabled, readOnly, selectingTarget, currentValue.start, adapter, setRange]
|
|
995
|
+
[isDisabled, readOnly, selectingTarget, currentValue.start, adapter, setRange, displayTimezone]
|
|
877
996
|
);
|
|
878
997
|
const open = useCallback(() => {
|
|
879
998
|
if (isDisabled || readOnly) return;
|
|
880
999
|
setIsOpen(true);
|
|
881
|
-
const target = currentValue.start ?? adapter.today();
|
|
1000
|
+
const target = currentValue.start ?? adapter.today(displayTimezone);
|
|
882
1001
|
setViewMonth(target);
|
|
883
1002
|
setFocusedDate(target);
|
|
884
1003
|
if (currentValue.start && currentValue.end) {
|
|
885
1004
|
setSelectingTarget("start");
|
|
886
1005
|
}
|
|
887
|
-
}, [isDisabled, readOnly, currentValue, adapter]);
|
|
1006
|
+
}, [isDisabled, readOnly, currentValue, adapter, displayTimezone]);
|
|
888
1007
|
const close = useCallback(() => {
|
|
889
1008
|
setIsOpen(false);
|
|
890
1009
|
setHoverDate(null);
|
|
@@ -915,6 +1034,7 @@ function RangePickerRoot({
|
|
|
915
1034
|
weekStartsOn,
|
|
916
1035
|
displayFormat,
|
|
917
1036
|
locale,
|
|
1037
|
+
displayTimezone,
|
|
918
1038
|
isDisabled,
|
|
919
1039
|
isReadOnly: readOnly,
|
|
920
1040
|
pickerId,
|
|
@@ -937,6 +1057,7 @@ function RangePickerRoot({
|
|
|
937
1057
|
weekStartsOn,
|
|
938
1058
|
displayFormat,
|
|
939
1059
|
locale,
|
|
1060
|
+
displayTimezone,
|
|
940
1061
|
isDisabled,
|
|
941
1062
|
readOnly,
|
|
942
1063
|
pickerId,
|
|
@@ -953,7 +1074,7 @@ var RangePickerInput = forwardRef(
|
|
|
953
1074
|
let displayValue = "";
|
|
954
1075
|
if (value) {
|
|
955
1076
|
try {
|
|
956
|
-
displayValue = ctx.adapter.format(value, displayFormat);
|
|
1077
|
+
displayValue = ctx.adapter.format(value, displayFormat, ctx.displayTimezone);
|
|
957
1078
|
} catch {
|
|
958
1079
|
displayValue = value;
|
|
959
1080
|
}
|
|
@@ -1046,7 +1167,11 @@ var srOnly2 = {
|
|
|
1046
1167
|
whiteSpace: "nowrap",
|
|
1047
1168
|
border: 0
|
|
1048
1169
|
};
|
|
1049
|
-
function RangePickerCalendar({
|
|
1170
|
+
function RangePickerCalendar({
|
|
1171
|
+
classNames,
|
|
1172
|
+
selectionMode = "range",
|
|
1173
|
+
...props
|
|
1174
|
+
}) {
|
|
1050
1175
|
const ctx = useRangePickerContext("RangePicker.Calendar");
|
|
1051
1176
|
const gridRef = useRef(null);
|
|
1052
1177
|
const [announcement, setAnnouncement] = useState("");
|
|
@@ -1058,7 +1183,8 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1058
1183
|
disabled,
|
|
1059
1184
|
value,
|
|
1060
1185
|
hoverDate,
|
|
1061
|
-
selectingTarget
|
|
1186
|
+
selectingTarget,
|
|
1187
|
+
displayTimezone
|
|
1062
1188
|
} = ctx;
|
|
1063
1189
|
const { locale } = ctx;
|
|
1064
1190
|
const weekdays = getWeekdayNames(locale, weekStartsOn);
|
|
@@ -1067,7 +1193,8 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1067
1193
|
focusedDate,
|
|
1068
1194
|
disabled,
|
|
1069
1195
|
range: value,
|
|
1070
|
-
rangeHover: hoverDate
|
|
1196
|
+
rangeHover: hoverDate,
|
|
1197
|
+
timezone: displayTimezone
|
|
1071
1198
|
});
|
|
1072
1199
|
const year = adapter.getYear(viewMonth);
|
|
1073
1200
|
const month = adapter.getMonth(viewMonth);
|
|
@@ -1090,21 +1217,39 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1090
1217
|
},
|
|
1091
1218
|
[adapter, viewMonth, ctx, locale]
|
|
1092
1219
|
);
|
|
1220
|
+
const commitDay = useCallback(
|
|
1221
|
+
(iso) => {
|
|
1222
|
+
if (selectionMode === "week") {
|
|
1223
|
+
const weekStart = adapter.startOfWeek(iso, weekStartsOn);
|
|
1224
|
+
const weekEnd = adapter.startOfDay(adapter.endOfWeek(iso, weekStartsOn));
|
|
1225
|
+
const range = { start: weekStart, end: weekEnd };
|
|
1226
|
+
ctx.setRange(range);
|
|
1227
|
+
ctx.close();
|
|
1228
|
+
setAnnouncement(
|
|
1229
|
+
`${safeFormatFullDate2(weekStart, locale)} \u2013 ${safeFormatFullDate2(weekEnd, locale)}`
|
|
1230
|
+
);
|
|
1231
|
+
} else {
|
|
1232
|
+
ctx.selectDate(iso);
|
|
1233
|
+
setAnnouncement(safeFormatFullDate2(iso, locale));
|
|
1234
|
+
}
|
|
1235
|
+
},
|
|
1236
|
+
[selectionMode, adapter, weekStartsOn, ctx, locale]
|
|
1237
|
+
);
|
|
1093
1238
|
const handleDayClick = useCallback(
|
|
1094
1239
|
(day) => {
|
|
1095
1240
|
if (day.isDisabled) return;
|
|
1096
|
-
|
|
1097
|
-
setAnnouncement(safeFormatFullDate2(day.isoString, locale));
|
|
1241
|
+
commitDay(day.isoString);
|
|
1098
1242
|
},
|
|
1099
|
-
[
|
|
1243
|
+
[commitDay]
|
|
1100
1244
|
);
|
|
1101
1245
|
const handleDayMouseEnter = useCallback(
|
|
1102
1246
|
(day) => {
|
|
1247
|
+
if (selectionMode === "week") return;
|
|
1103
1248
|
if (selectingTarget === "end" && value.start && !day.isDisabled) {
|
|
1104
1249
|
ctx.setHoverDate(day.isoString);
|
|
1105
1250
|
}
|
|
1106
1251
|
},
|
|
1107
|
-
[selectingTarget, value.start, ctx]
|
|
1252
|
+
[selectionMode, selectingTarget, value.start, ctx]
|
|
1108
1253
|
);
|
|
1109
1254
|
const handleMouseLeave = useCallback(() => {
|
|
1110
1255
|
ctx.setHoverDate(null);
|
|
@@ -1141,7 +1286,7 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1141
1286
|
case " ":
|
|
1142
1287
|
e.preventDefault();
|
|
1143
1288
|
if (!isDateDisabled(focusedDate, disabled, adapter)) {
|
|
1144
|
-
|
|
1289
|
+
commitDay(focusedDate);
|
|
1145
1290
|
}
|
|
1146
1291
|
return;
|
|
1147
1292
|
case "Escape":
|
|
@@ -1156,12 +1301,12 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1156
1301
|
if (!adapter.isSameMonth(newFocused, viewMonth)) {
|
|
1157
1302
|
ctx.setViewMonth(newFocused);
|
|
1158
1303
|
}
|
|
1159
|
-
if (selectingTarget === "end" && value.start) {
|
|
1304
|
+
if (selectionMode === "range" && selectingTarget === "end" && value.start) {
|
|
1160
1305
|
ctx.setHoverDate(newFocused);
|
|
1161
1306
|
}
|
|
1162
1307
|
}
|
|
1163
1308
|
},
|
|
1164
|
-
[adapter, focusedDate, viewMonth, weekStartsOn, disabled, ctx, selectingTarget, value.start]
|
|
1309
|
+
[adapter, focusedDate, viewMonth, weekStartsOn, disabled, ctx, selectionMode, selectingTarget, value.start, commitDay]
|
|
1165
1310
|
);
|
|
1166
1311
|
return /* @__PURE__ */ jsxs("div", { className: classNames?.root, ...props, onMouseLeave: handleMouseLeave, children: [
|
|
1167
1312
|
/* @__PURE__ */ jsxs("div", { className: classNames?.header, children: [
|
|
@@ -1218,7 +1363,7 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1218
1363
|
day.isDisabled && classNames?.dayDisabled,
|
|
1219
1364
|
!day.isCurrentMonth && classNames?.dayOutsideMonth
|
|
1220
1365
|
].filter(Boolean).join(" ") || void 0;
|
|
1221
|
-
const isSelected = day.isRangeStart || day.isRangeEnd;
|
|
1366
|
+
const isSelected = selectionMode === "week" ? day.isRangeStart || day.isRangeEnd || day.isInRange : day.isRangeStart || day.isRangeEnd;
|
|
1222
1367
|
return /* @__PURE__ */ jsx(
|
|
1223
1368
|
"td",
|
|
1224
1369
|
{
|
|
@@ -1390,6 +1535,7 @@ function TimePickerRoot({
|
|
|
1390
1535
|
format = "24h",
|
|
1391
1536
|
step = 1,
|
|
1392
1537
|
withSeconds = false,
|
|
1538
|
+
displayTimezone,
|
|
1393
1539
|
disabled = false,
|
|
1394
1540
|
readOnly = false,
|
|
1395
1541
|
labels: labelsProp,
|
|
@@ -1406,17 +1552,20 @@ function TimePickerRoot({
|
|
|
1406
1552
|
);
|
|
1407
1553
|
const currentValue = isControlled ? controlledValue ?? null : uncontrolledValue;
|
|
1408
1554
|
const baseIso = currentValue ?? getDefaultIso();
|
|
1409
|
-
const currentTime = useMemo(
|
|
1555
|
+
const currentTime = useMemo(
|
|
1556
|
+
() => displayTimezone ? getTimeInTimezone(baseIso, displayTimezone) : getTime(baseIso),
|
|
1557
|
+
[baseIso, displayTimezone]
|
|
1558
|
+
);
|
|
1410
1559
|
const setTime$1 = useCallback(
|
|
1411
1560
|
(partial) => {
|
|
1412
1561
|
if (disabled || readOnly) return;
|
|
1413
|
-
const newIso = setTime(baseIso, partial);
|
|
1562
|
+
const newIso = displayTimezone ? setTimeInTimezone(baseIso, partial, displayTimezone) : setTime(baseIso, partial);
|
|
1414
1563
|
if (!isControlled) {
|
|
1415
1564
|
setUncontrolledValue(newIso);
|
|
1416
1565
|
}
|
|
1417
1566
|
onChange?.(newIso);
|
|
1418
1567
|
},
|
|
1419
|
-
[disabled, readOnly, baseIso, isControlled, onChange]
|
|
1568
|
+
[disabled, readOnly, baseIso, isControlled, onChange, displayTimezone]
|
|
1420
1569
|
);
|
|
1421
1570
|
const contextValue = useMemo(
|
|
1422
1571
|
() => ({
|
|
@@ -1425,13 +1574,14 @@ function TimePickerRoot({
|
|
|
1425
1574
|
format,
|
|
1426
1575
|
step,
|
|
1427
1576
|
withSeconds,
|
|
1577
|
+
displayTimezone,
|
|
1428
1578
|
isDisabled: disabled,
|
|
1429
1579
|
isReadOnly: readOnly,
|
|
1430
1580
|
currentTime,
|
|
1431
1581
|
pickerId,
|
|
1432
1582
|
labels: mergedLabels
|
|
1433
1583
|
}),
|
|
1434
|
-
[currentValue, setTime$1, format, step, withSeconds, disabled, readOnly, currentTime, pickerId, mergedLabels]
|
|
1584
|
+
[currentValue, setTime$1, format, step, withSeconds, displayTimezone, disabled, readOnly, currentTime, pickerId, mergedLabels]
|
|
1435
1585
|
);
|
|
1436
1586
|
return /* @__PURE__ */ jsx(TimePickerContext.Provider, { value: contextValue, children });
|
|
1437
1587
|
}
|
|
@@ -1685,6 +1835,8 @@ function DateTimePickerRoot({
|
|
|
1685
1835
|
value: controlledValue,
|
|
1686
1836
|
defaultValue,
|
|
1687
1837
|
onChange,
|
|
1838
|
+
onOpenChange,
|
|
1839
|
+
onCalendarNavigate,
|
|
1688
1840
|
format = "24h",
|
|
1689
1841
|
step = 1,
|
|
1690
1842
|
disabled = false,
|
|
@@ -1692,6 +1844,7 @@ function DateTimePickerRoot({
|
|
|
1692
1844
|
weekStartsOn = 0,
|
|
1693
1845
|
displayFormat = "yyyy-MM-dd HH:mm",
|
|
1694
1846
|
locale = "en-US",
|
|
1847
|
+
displayTimezone,
|
|
1695
1848
|
adapter = DateFnsAdapter,
|
|
1696
1849
|
labels: labelsProp,
|
|
1697
1850
|
children
|
|
@@ -1713,18 +1866,24 @@ function DateTimePickerRoot({
|
|
|
1713
1866
|
const currentValue = isControlled ? controlledValue ?? null : uncontrolledValue;
|
|
1714
1867
|
const [isOpen, setIsOpen] = useState(false);
|
|
1715
1868
|
const [viewMonth, setViewMonth] = useState(
|
|
1716
|
-
currentValue ?? adapter.today()
|
|
1869
|
+
currentValue ?? adapter.today(displayTimezone)
|
|
1717
1870
|
);
|
|
1718
1871
|
const [focusedDate, setFocusedDate] = useState(
|
|
1719
|
-
currentValue ?? adapter.today()
|
|
1872
|
+
currentValue ?? adapter.today(displayTimezone)
|
|
1720
1873
|
);
|
|
1874
|
+
useChangeEffect(isOpen, onOpenChange);
|
|
1875
|
+
const viewMonthStart = useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
|
|
1876
|
+
useChangeEffect(viewMonthStart, onCalendarNavigate);
|
|
1721
1877
|
const isDisabled = typeof disabled === "boolean" ? disabled : false;
|
|
1722
1878
|
const disabledRules = useMemo(
|
|
1723
1879
|
() => Array.isArray(disabled) ? disabled : [],
|
|
1724
1880
|
[disabled]
|
|
1725
1881
|
);
|
|
1726
1882
|
const baseIso = currentValue ?? getDefaultIso2();
|
|
1727
|
-
const currentTime = useMemo(
|
|
1883
|
+
const currentTime = useMemo(
|
|
1884
|
+
() => displayTimezone ? getTimeInTimezone(baseIso, displayTimezone) : getTime(baseIso),
|
|
1885
|
+
[baseIso, displayTimezone]
|
|
1886
|
+
);
|
|
1728
1887
|
const updateValue = useCallback(
|
|
1729
1888
|
(next) => {
|
|
1730
1889
|
if (isDisabled || readOnly) return;
|
|
@@ -1741,27 +1900,28 @@ function DateTimePickerRoot({
|
|
|
1741
1900
|
updateValue(null);
|
|
1742
1901
|
return;
|
|
1743
1902
|
}
|
|
1744
|
-
const
|
|
1745
|
-
const
|
|
1903
|
+
const normalizedDate = displayTimezone ? civilMidnightFromUtcDay(newDateIso, displayTimezone) : newDateIso;
|
|
1904
|
+
const time = currentValue ? displayTimezone ? getTimeInTimezone(currentValue, displayTimezone) : getTime(currentValue) : currentTime;
|
|
1905
|
+
const merged = displayTimezone ? setTimeInTimezone(normalizedDate, time, displayTimezone) : setTime(normalizedDate, time);
|
|
1746
1906
|
updateValue(merged);
|
|
1747
1907
|
},
|
|
1748
|
-
[currentValue, currentTime, updateValue]
|
|
1908
|
+
[currentValue, currentTime, updateValue, displayTimezone]
|
|
1749
1909
|
);
|
|
1750
1910
|
const setTime$1 = useCallback(
|
|
1751
1911
|
(partial) => {
|
|
1752
1912
|
const base = currentValue ?? getDefaultIso2();
|
|
1753
|
-
const merged = setTime(base, partial);
|
|
1913
|
+
const merged = displayTimezone ? setTimeInTimezone(base, partial, displayTimezone) : setTime(base, partial);
|
|
1754
1914
|
updateValue(merged);
|
|
1755
1915
|
},
|
|
1756
|
-
[currentValue, updateValue]
|
|
1916
|
+
[currentValue, updateValue, displayTimezone]
|
|
1757
1917
|
);
|
|
1758
1918
|
const open = useCallback(() => {
|
|
1759
1919
|
if (isDisabled || readOnly) return;
|
|
1760
1920
|
setIsOpen(true);
|
|
1761
|
-
const target = currentValue ?? adapter.today();
|
|
1921
|
+
const target = currentValue ?? adapter.today(displayTimezone);
|
|
1762
1922
|
setViewMonth(target);
|
|
1763
1923
|
setFocusedDate(target);
|
|
1764
|
-
}, [isDisabled, readOnly, currentValue, adapter]);
|
|
1924
|
+
}, [isDisabled, readOnly, currentValue, adapter, displayTimezone]);
|
|
1765
1925
|
const close = useCallback(() => {
|
|
1766
1926
|
setIsOpen(false);
|
|
1767
1927
|
}, []);
|
|
@@ -1787,6 +1947,7 @@ function DateTimePickerRoot({
|
|
|
1787
1947
|
weekStartsOn,
|
|
1788
1948
|
displayFormat,
|
|
1789
1949
|
locale,
|
|
1950
|
+
displayTimezone,
|
|
1790
1951
|
isDisabled,
|
|
1791
1952
|
isReadOnly: readOnly,
|
|
1792
1953
|
pickerId,
|
|
@@ -1806,6 +1967,7 @@ function DateTimePickerRoot({
|
|
|
1806
1967
|
weekStartsOn,
|
|
1807
1968
|
displayFormat,
|
|
1808
1969
|
locale,
|
|
1970
|
+
displayTimezone,
|
|
1809
1971
|
isDisabled,
|
|
1810
1972
|
readOnly,
|
|
1811
1973
|
pickerId,
|
|
@@ -1819,13 +1981,14 @@ function DateTimePickerRoot({
|
|
|
1819
1981
|
format,
|
|
1820
1982
|
step,
|
|
1821
1983
|
withSeconds: false,
|
|
1984
|
+
displayTimezone,
|
|
1822
1985
|
isDisabled,
|
|
1823
1986
|
isReadOnly: readOnly,
|
|
1824
1987
|
currentTime,
|
|
1825
1988
|
pickerId,
|
|
1826
1989
|
labels: mergedTimeLabels
|
|
1827
1990
|
}),
|
|
1828
|
-
[currentValue, setTime$1, format, step, isDisabled, readOnly, currentTime, pickerId, mergedTimeLabels]
|
|
1991
|
+
[currentValue, setTime$1, format, step, displayTimezone, isDisabled, readOnly, currentTime, pickerId, mergedTimeLabels]
|
|
1829
1992
|
);
|
|
1830
1993
|
return /* @__PURE__ */ jsx(DatePickerContext.Provider, { value: dateContext, children: /* @__PURE__ */ jsx(TimePickerContext.Provider, { value: timeContext, children }) });
|
|
1831
1994
|
}
|
|
@@ -1835,7 +1998,9 @@ var DateTimePickerInput = forwardRef(
|
|
|
1835
1998
|
let displayValue = "";
|
|
1836
1999
|
if (ctx.value) {
|
|
1837
2000
|
try {
|
|
1838
|
-
|
|
2001
|
+
const datePart = ctx.adapter.format(ctx.value, "yyyy-MM-dd", ctx.displayTimezone);
|
|
2002
|
+
const time = ctx.displayTimezone ? getTimeInTimezone(ctx.value, ctx.displayTimezone) : getTime(ctx.value);
|
|
2003
|
+
displayValue = `${datePart} ${formatTimeString(time)}`;
|
|
1839
2004
|
} catch {
|
|
1840
2005
|
displayValue = ctx.value;
|
|
1841
2006
|
}
|
|
@@ -1898,6 +2063,249 @@ var DateTimePicker = Object.assign(DateTimePickerRoot, {
|
|
|
1898
2063
|
MinuteList: TimePickerMinuteList,
|
|
1899
2064
|
AmPmToggle: TimePickerAmPmToggle
|
|
1900
2065
|
});
|
|
2066
|
+
function MonthPickerRoot(props) {
|
|
2067
|
+
const displayFormat = props.displayFormat ?? "yyyy-MM";
|
|
2068
|
+
return /* @__PURE__ */ jsx(DatePickerRoot, { ...props, displayFormat });
|
|
2069
|
+
}
|
|
2070
|
+
function MonthPickerGrid({
|
|
2071
|
+
classNames,
|
|
2072
|
+
...props
|
|
2073
|
+
}) {
|
|
2074
|
+
const ctx = useDatePickerContext("MonthPicker.Grid");
|
|
2075
|
+
const { adapter, viewMonth, locale, value, displayTimezone, labels } = ctx;
|
|
2076
|
+
const currentYear = adapter.getYear(viewMonth);
|
|
2077
|
+
const [valueYear, valueMonthZeroBased] = useMemo(() => {
|
|
2078
|
+
if (!value) return [null, null];
|
|
2079
|
+
try {
|
|
2080
|
+
const [y, m] = adapter.format(value, "yyyy-MM", displayTimezone).split("-").map(Number);
|
|
2081
|
+
return [y, m - 1];
|
|
2082
|
+
} catch {
|
|
2083
|
+
return [null, null];
|
|
2084
|
+
}
|
|
2085
|
+
}, [value, adapter, displayTimezone]);
|
|
2086
|
+
const today = adapter.today(displayTimezone);
|
|
2087
|
+
const todayYear = adapter.getYear(today);
|
|
2088
|
+
const todayMonth = adapter.getMonth(today);
|
|
2089
|
+
const navigateYear = useCallback(
|
|
2090
|
+
(direction) => {
|
|
2091
|
+
ctx.setViewMonth(adapter.addYears(viewMonth, direction));
|
|
2092
|
+
},
|
|
2093
|
+
[adapter, viewMonth, ctx]
|
|
2094
|
+
);
|
|
2095
|
+
const handleMonthSelect = useCallback(
|
|
2096
|
+
(monthIndex) => {
|
|
2097
|
+
const target = new Date(
|
|
2098
|
+
Date.UTC(currentYear, monthIndex, 1)
|
|
2099
|
+
).toISOString();
|
|
2100
|
+
ctx.selectDate(target);
|
|
2101
|
+
},
|
|
2102
|
+
[currentYear, ctx]
|
|
2103
|
+
);
|
|
2104
|
+
const months = Array.from({ length: 12 }, (_, i) => ({
|
|
2105
|
+
index: i,
|
|
2106
|
+
name: getMonthName(i, locale),
|
|
2107
|
+
isSelected: valueYear === currentYear && valueMonthZeroBased === i,
|
|
2108
|
+
isCurrent: todayYear === currentYear && todayMonth === i
|
|
2109
|
+
}));
|
|
2110
|
+
return /* @__PURE__ */ jsxs("div", { className: classNames?.root, ...props, children: [
|
|
2111
|
+
/* @__PURE__ */ jsxs("div", { className: classNames?.header, children: [
|
|
2112
|
+
/* @__PURE__ */ jsx(
|
|
2113
|
+
"button",
|
|
2114
|
+
{
|
|
2115
|
+
type: "button",
|
|
2116
|
+
className: classNames?.navButton,
|
|
2117
|
+
onClick: () => navigateYear(-1),
|
|
2118
|
+
"aria-label": labels.prevYear,
|
|
2119
|
+
children: "<"
|
|
2120
|
+
}
|
|
2121
|
+
),
|
|
2122
|
+
/* @__PURE__ */ jsx("span", { className: classNames?.title, children: currentYear }),
|
|
2123
|
+
/* @__PURE__ */ jsx(
|
|
2124
|
+
"button",
|
|
2125
|
+
{
|
|
2126
|
+
type: "button",
|
|
2127
|
+
className: classNames?.navButton,
|
|
2128
|
+
onClick: () => navigateYear(1),
|
|
2129
|
+
"aria-label": labels.nextYear,
|
|
2130
|
+
children: ">"
|
|
2131
|
+
}
|
|
2132
|
+
)
|
|
2133
|
+
] }),
|
|
2134
|
+
/* @__PURE__ */ jsx(
|
|
2135
|
+
"div",
|
|
2136
|
+
{
|
|
2137
|
+
role: "grid",
|
|
2138
|
+
"aria-label": `${currentYear} months`,
|
|
2139
|
+
className: classNames?.grid,
|
|
2140
|
+
children: Array.from({ length: 4 }, (_, rowIndex) => /* @__PURE__ */ jsx(
|
|
2141
|
+
"div",
|
|
2142
|
+
{
|
|
2143
|
+
role: "row",
|
|
2144
|
+
className: classNames?.gridRow,
|
|
2145
|
+
style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)" },
|
|
2146
|
+
children: months.slice(rowIndex * 3, rowIndex * 3 + 3).map((m) => {
|
|
2147
|
+
const monthClass = [
|
|
2148
|
+
classNames?.month,
|
|
2149
|
+
m.isSelected && classNames?.monthSelected,
|
|
2150
|
+
m.isCurrent && classNames?.monthCurrent
|
|
2151
|
+
].filter(Boolean).join(" ") || void 0;
|
|
2152
|
+
return /* @__PURE__ */ jsx(
|
|
2153
|
+
"button",
|
|
2154
|
+
{
|
|
2155
|
+
type: "button",
|
|
2156
|
+
role: "gridcell",
|
|
2157
|
+
"aria-selected": m.isSelected || void 0,
|
|
2158
|
+
"aria-current": m.isCurrent ? "date" : void 0,
|
|
2159
|
+
"data-selected": m.isSelected || void 0,
|
|
2160
|
+
"data-current": m.isCurrent || void 0,
|
|
2161
|
+
className: monthClass,
|
|
2162
|
+
onClick: () => handleMonthSelect(m.index),
|
|
2163
|
+
children: m.name
|
|
2164
|
+
},
|
|
2165
|
+
m.index
|
|
2166
|
+
);
|
|
2167
|
+
})
|
|
2168
|
+
},
|
|
2169
|
+
rowIndex
|
|
2170
|
+
))
|
|
2171
|
+
}
|
|
2172
|
+
)
|
|
2173
|
+
] });
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
// src/components/MonthPicker/index.ts
|
|
2177
|
+
var MonthPicker = Object.assign(MonthPickerRoot, {
|
|
2178
|
+
Input: DatePickerInput,
|
|
2179
|
+
Trigger: DatePickerTrigger,
|
|
2180
|
+
Popover: DatePickerPopover,
|
|
2181
|
+
Grid: MonthPickerGrid
|
|
2182
|
+
});
|
|
2183
|
+
function YearPickerRoot(props) {
|
|
2184
|
+
const displayFormat = props.displayFormat ?? "yyyy";
|
|
2185
|
+
return /* @__PURE__ */ jsx(DatePickerRoot, { ...props, displayFormat });
|
|
2186
|
+
}
|
|
2187
|
+
function YearPickerGrid({ classNames, ...props }) {
|
|
2188
|
+
const ctx = useDatePickerContext("YearPicker.Grid");
|
|
2189
|
+
const { adapter, viewMonth, value, displayTimezone, labels } = ctx;
|
|
2190
|
+
const currentYear = adapter.getYear(viewMonth);
|
|
2191
|
+
const decadeStart = currentYear - currentYear % 12;
|
|
2192
|
+
const valueYear = useMemo(() => {
|
|
2193
|
+
if (!value) return null;
|
|
2194
|
+
try {
|
|
2195
|
+
return Number(adapter.format(value, "yyyy", displayTimezone));
|
|
2196
|
+
} catch {
|
|
2197
|
+
return null;
|
|
2198
|
+
}
|
|
2199
|
+
}, [value, adapter, displayTimezone]);
|
|
2200
|
+
const todayYear = adapter.getYear(adapter.today(displayTimezone));
|
|
2201
|
+
const navigateDecade = useCallback(
|
|
2202
|
+
(direction) => {
|
|
2203
|
+
ctx.setViewMonth(adapter.addYears(viewMonth, direction * 12));
|
|
2204
|
+
},
|
|
2205
|
+
[adapter, viewMonth, ctx]
|
|
2206
|
+
);
|
|
2207
|
+
const handleYearSelect = useCallback(
|
|
2208
|
+
(year) => {
|
|
2209
|
+
const target = new Date(Date.UTC(year, 0, 1)).toISOString();
|
|
2210
|
+
ctx.selectDate(target);
|
|
2211
|
+
},
|
|
2212
|
+
[ctx]
|
|
2213
|
+
);
|
|
2214
|
+
const years = Array.from({ length: 12 }, (_, i) => {
|
|
2215
|
+
const year = decadeStart + i;
|
|
2216
|
+
return {
|
|
2217
|
+
value: year,
|
|
2218
|
+
isSelected: year === valueYear,
|
|
2219
|
+
isCurrent: year === todayYear
|
|
2220
|
+
};
|
|
2221
|
+
});
|
|
2222
|
+
const rangeLabel = `${decadeStart}\u2013${decadeStart + 11}`;
|
|
2223
|
+
return /* @__PURE__ */ jsxs("div", { className: classNames?.root, ...props, children: [
|
|
2224
|
+
/* @__PURE__ */ jsxs("div", { className: classNames?.header, children: [
|
|
2225
|
+
/* @__PURE__ */ jsx(
|
|
2226
|
+
"button",
|
|
2227
|
+
{
|
|
2228
|
+
type: "button",
|
|
2229
|
+
className: classNames?.navButton,
|
|
2230
|
+
onClick: () => navigateDecade(-1),
|
|
2231
|
+
"aria-label": labels.prevDecade,
|
|
2232
|
+
children: "<"
|
|
2233
|
+
}
|
|
2234
|
+
),
|
|
2235
|
+
/* @__PURE__ */ jsx("span", { className: classNames?.title, children: rangeLabel }),
|
|
2236
|
+
/* @__PURE__ */ jsx(
|
|
2237
|
+
"button",
|
|
2238
|
+
{
|
|
2239
|
+
type: "button",
|
|
2240
|
+
className: classNames?.navButton,
|
|
2241
|
+
onClick: () => navigateDecade(1),
|
|
2242
|
+
"aria-label": labels.nextDecade,
|
|
2243
|
+
children: ">"
|
|
2244
|
+
}
|
|
2245
|
+
)
|
|
2246
|
+
] }),
|
|
2247
|
+
/* @__PURE__ */ jsx(
|
|
2248
|
+
"div",
|
|
2249
|
+
{
|
|
2250
|
+
role: "grid",
|
|
2251
|
+
"aria-label": rangeLabel,
|
|
2252
|
+
className: classNames?.grid,
|
|
2253
|
+
children: Array.from({ length: 4 }, (_, rowIndex) => /* @__PURE__ */ jsx(
|
|
2254
|
+
"div",
|
|
2255
|
+
{
|
|
2256
|
+
role: "row",
|
|
2257
|
+
className: classNames?.gridRow,
|
|
2258
|
+
style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)" },
|
|
2259
|
+
children: years.slice(rowIndex * 3, rowIndex * 3 + 3).map((y) => {
|
|
2260
|
+
const yearClass = [
|
|
2261
|
+
classNames?.year,
|
|
2262
|
+
y.isSelected && classNames?.yearSelected,
|
|
2263
|
+
y.isCurrent && classNames?.yearCurrent
|
|
2264
|
+
].filter(Boolean).join(" ") || void 0;
|
|
2265
|
+
return /* @__PURE__ */ jsx(
|
|
2266
|
+
"button",
|
|
2267
|
+
{
|
|
2268
|
+
type: "button",
|
|
2269
|
+
role: "gridcell",
|
|
2270
|
+
"aria-selected": y.isSelected || void 0,
|
|
2271
|
+
"aria-current": y.isCurrent ? "date" : void 0,
|
|
2272
|
+
"data-selected": y.isSelected || void 0,
|
|
2273
|
+
"data-current": y.isCurrent || void 0,
|
|
2274
|
+
className: yearClass,
|
|
2275
|
+
onClick: () => handleYearSelect(y.value),
|
|
2276
|
+
children: y.value
|
|
2277
|
+
},
|
|
2278
|
+
y.value
|
|
2279
|
+
);
|
|
2280
|
+
})
|
|
2281
|
+
},
|
|
2282
|
+
rowIndex
|
|
2283
|
+
))
|
|
2284
|
+
}
|
|
2285
|
+
)
|
|
2286
|
+
] });
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
// src/components/YearPicker/index.ts
|
|
2290
|
+
var YearPicker = Object.assign(YearPickerRoot, {
|
|
2291
|
+
Input: DatePickerInput,
|
|
2292
|
+
Trigger: DatePickerTrigger,
|
|
2293
|
+
Popover: DatePickerPopover,
|
|
2294
|
+
Grid: YearPickerGrid
|
|
2295
|
+
});
|
|
2296
|
+
function WeekPickerRoot(props) {
|
|
2297
|
+
return /* @__PURE__ */ jsx(RangePickerRoot, { ...props });
|
|
2298
|
+
}
|
|
2299
|
+
function WeekPickerCalendar(props) {
|
|
2300
|
+
return /* @__PURE__ */ jsx(RangePickerCalendar, { ...props, selectionMode: "week" });
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
// src/components/WeekPicker/index.ts
|
|
2304
|
+
var WeekPicker = Object.assign(WeekPickerRoot, {
|
|
2305
|
+
Input: RangePickerInput,
|
|
2306
|
+
Popover: RangePickerPopover,
|
|
2307
|
+
Calendar: WeekPickerCalendar
|
|
2308
|
+
});
|
|
1901
2309
|
function useDatePicker(options = {}) {
|
|
1902
2310
|
const {
|
|
1903
2311
|
value: controlledValue,
|
|
@@ -1905,7 +2313,8 @@ function useDatePicker(options = {}) {
|
|
|
1905
2313
|
onChange,
|
|
1906
2314
|
disabled = [],
|
|
1907
2315
|
weekStartsOn = 0,
|
|
1908
|
-
adapter = DateFnsAdapter
|
|
2316
|
+
adapter = DateFnsAdapter,
|
|
2317
|
+
displayTimezone
|
|
1909
2318
|
} = options;
|
|
1910
2319
|
const pickerId = useId();
|
|
1911
2320
|
const isControlled = useRef(controlledValue !== void 0).current;
|
|
@@ -1914,24 +2323,29 @@ function useDatePicker(options = {}) {
|
|
|
1914
2323
|
);
|
|
1915
2324
|
const currentValue = isControlled ? controlledValue ?? null : uncontrolledValue;
|
|
1916
2325
|
const [isOpen, setIsOpen] = useState(false);
|
|
1917
|
-
const [viewMonth, setViewMonth] = useState(
|
|
1918
|
-
|
|
2326
|
+
const [viewMonth, setViewMonth] = useState(
|
|
2327
|
+
currentValue ?? adapter.today(displayTimezone)
|
|
2328
|
+
);
|
|
2329
|
+
const [focusedDate, setFocusedDate] = useState(
|
|
2330
|
+
currentValue ?? adapter.today(displayTimezone)
|
|
2331
|
+
);
|
|
1919
2332
|
const selectDate = useCallback(
|
|
1920
2333
|
(iso) => {
|
|
2334
|
+
const normalized = iso && displayTimezone ? civilMidnightFromUtcDay(iso, displayTimezone) : iso;
|
|
1921
2335
|
if (!isControlled) {
|
|
1922
|
-
setUncontrolledValue(
|
|
2336
|
+
setUncontrolledValue(normalized);
|
|
1923
2337
|
}
|
|
1924
|
-
onChange?.(
|
|
2338
|
+
onChange?.(normalized);
|
|
1925
2339
|
setIsOpen(false);
|
|
1926
2340
|
},
|
|
1927
|
-
[isControlled, onChange]
|
|
2341
|
+
[isControlled, onChange, displayTimezone]
|
|
1928
2342
|
);
|
|
1929
2343
|
const open = useCallback(() => {
|
|
1930
2344
|
setIsOpen(true);
|
|
1931
|
-
const target = currentValue ?? adapter.today();
|
|
2345
|
+
const target = currentValue ?? adapter.today(displayTimezone);
|
|
1932
2346
|
setViewMonth(target);
|
|
1933
2347
|
setFocusedDate(target);
|
|
1934
|
-
}, [currentValue, adapter]);
|
|
2348
|
+
}, [currentValue, adapter, displayTimezone]);
|
|
1935
2349
|
const close = useCallback(() => {
|
|
1936
2350
|
setIsOpen(false);
|
|
1937
2351
|
}, []);
|
|
@@ -1953,7 +2367,8 @@ function useDatePicker(options = {}) {
|
|
|
1953
2367
|
weekStartsOn,
|
|
1954
2368
|
selected: currentValue,
|
|
1955
2369
|
focusedDate,
|
|
1956
|
-
disabled
|
|
2370
|
+
disabled,
|
|
2371
|
+
timezone: displayTimezone
|
|
1957
2372
|
});
|
|
1958
2373
|
return {
|
|
1959
2374
|
value: currentValue,
|
|
@@ -1981,7 +2396,8 @@ function useRangePicker(options = {}) {
|
|
|
1981
2396
|
onChange,
|
|
1982
2397
|
disabled = [],
|
|
1983
2398
|
weekStartsOn = 0,
|
|
1984
|
-
adapter = DateFnsAdapter
|
|
2399
|
+
adapter = DateFnsAdapter,
|
|
2400
|
+
displayTimezone
|
|
1985
2401
|
} = options;
|
|
1986
2402
|
const pickerId = useId();
|
|
1987
2403
|
const isControlled = useRef(controlledValue !== void 0).current;
|
|
@@ -1993,10 +2409,10 @@ function useRangePicker(options = {}) {
|
|
|
1993
2409
|
const [selectingTarget, setSelectingTarget] = useState("start");
|
|
1994
2410
|
const [hoverDate, setHoverDate] = useState(null);
|
|
1995
2411
|
const [viewMonth, setViewMonth] = useState(
|
|
1996
|
-
currentValue.start ?? adapter.today()
|
|
2412
|
+
currentValue.start ?? adapter.today(displayTimezone)
|
|
1997
2413
|
);
|
|
1998
2414
|
const [focusedDate, setFocusedDate] = useState(
|
|
1999
|
-
currentValue.start ?? adapter.today()
|
|
2415
|
+
currentValue.start ?? adapter.today(displayTimezone)
|
|
2000
2416
|
);
|
|
2001
2417
|
const setRange = useCallback(
|
|
2002
2418
|
(range) => {
|
|
@@ -2009,35 +2425,36 @@ function useRangePicker(options = {}) {
|
|
|
2009
2425
|
);
|
|
2010
2426
|
const selectDate = useCallback(
|
|
2011
2427
|
(iso) => {
|
|
2428
|
+
const normalized = displayTimezone ? civilMidnightFromUtcDay(iso, displayTimezone) : iso;
|
|
2012
2429
|
if (selectingTarget === "start") {
|
|
2013
|
-
setRange({ start:
|
|
2430
|
+
setRange({ start: normalized, end: null });
|
|
2014
2431
|
setSelectingTarget("end");
|
|
2015
2432
|
setHoverDate(null);
|
|
2016
2433
|
} else {
|
|
2017
2434
|
const start = currentValue.start;
|
|
2018
2435
|
if (!start) {
|
|
2019
|
-
setRange({ start:
|
|
2436
|
+
setRange({ start: normalized, end: null });
|
|
2020
2437
|
setSelectingTarget("end");
|
|
2021
2438
|
return;
|
|
2022
2439
|
}
|
|
2023
|
-
const newRange = adapter.isBefore(
|
|
2440
|
+
const newRange = adapter.isBefore(normalized, start) ? { start: normalized, end: start } : { start, end: normalized };
|
|
2024
2441
|
setRange(newRange);
|
|
2025
2442
|
setSelectingTarget("start");
|
|
2026
2443
|
setHoverDate(null);
|
|
2027
2444
|
setIsOpen(false);
|
|
2028
2445
|
}
|
|
2029
2446
|
},
|
|
2030
|
-
[selectingTarget, currentValue.start, adapter, setRange]
|
|
2447
|
+
[selectingTarget, currentValue.start, adapter, setRange, displayTimezone]
|
|
2031
2448
|
);
|
|
2032
2449
|
const open = useCallback(() => {
|
|
2033
2450
|
setIsOpen(true);
|
|
2034
|
-
const target = currentValue.start ?? adapter.today();
|
|
2451
|
+
const target = currentValue.start ?? adapter.today(displayTimezone);
|
|
2035
2452
|
setViewMonth(target);
|
|
2036
2453
|
setFocusedDate(target);
|
|
2037
2454
|
if (currentValue.start && currentValue.end) {
|
|
2038
2455
|
setSelectingTarget("start");
|
|
2039
2456
|
}
|
|
2040
|
-
}, [currentValue, adapter]);
|
|
2457
|
+
}, [currentValue, adapter, displayTimezone]);
|
|
2041
2458
|
const close = useCallback(() => {
|
|
2042
2459
|
setIsOpen(false);
|
|
2043
2460
|
setHoverDate(null);
|
|
@@ -2061,7 +2478,8 @@ function useRangePicker(options = {}) {
|
|
|
2061
2478
|
focusedDate,
|
|
2062
2479
|
disabled,
|
|
2063
2480
|
range: currentValue,
|
|
2064
|
-
rangeHover: hoverDate
|
|
2481
|
+
rangeHover: hoverDate,
|
|
2482
|
+
timezone: displayTimezone
|
|
2065
2483
|
});
|
|
2066
2484
|
return {
|
|
2067
2485
|
value: currentValue,
|
|
@@ -2094,7 +2512,8 @@ function useTimePicker(options = {}) {
|
|
|
2094
2512
|
defaultValue,
|
|
2095
2513
|
onChange,
|
|
2096
2514
|
format = "24h",
|
|
2097
|
-
step = 1
|
|
2515
|
+
step = 1,
|
|
2516
|
+
displayTimezone
|
|
2098
2517
|
} = options;
|
|
2099
2518
|
const pickerId = useId();
|
|
2100
2519
|
const isControlled = useRef(controlledValue !== void 0).current;
|
|
@@ -2103,16 +2522,19 @@ function useTimePicker(options = {}) {
|
|
|
2103
2522
|
);
|
|
2104
2523
|
const currentValue = isControlled ? controlledValue ?? null : uncontrolledValue;
|
|
2105
2524
|
const baseIso = currentValue ?? getDefaultIso3();
|
|
2106
|
-
const currentTime = useMemo(
|
|
2525
|
+
const currentTime = useMemo(
|
|
2526
|
+
() => displayTimezone ? getTimeInTimezone(baseIso, displayTimezone) : getTime(baseIso),
|
|
2527
|
+
[baseIso, displayTimezone]
|
|
2528
|
+
);
|
|
2107
2529
|
const setTime$1 = useCallback(
|
|
2108
2530
|
(partial) => {
|
|
2109
|
-
const newIso = setTime(baseIso, partial);
|
|
2531
|
+
const newIso = displayTimezone ? setTimeInTimezone(baseIso, partial, displayTimezone) : setTime(baseIso, partial);
|
|
2110
2532
|
if (!isControlled) {
|
|
2111
2533
|
setUncontrolledValue(newIso);
|
|
2112
2534
|
}
|
|
2113
2535
|
onChange?.(newIso);
|
|
2114
2536
|
},
|
|
2115
|
-
[baseIso, isControlled, onChange]
|
|
2537
|
+
[baseIso, isControlled, onChange, displayTimezone]
|
|
2116
2538
|
);
|
|
2117
2539
|
const period = format === "12h" ? to12Hour(currentTime.hours).period : null;
|
|
2118
2540
|
const displayHour = format === "12h" ? to12Hour(currentTime.hours).hours12 : currentTime.hours;
|
|
@@ -2156,6 +2578,6 @@ function useTimePicker(options = {}) {
|
|
|
2156
2578
|
};
|
|
2157
2579
|
}
|
|
2158
2580
|
|
|
2159
|
-
export { DatePicker, DateTimePicker, RangePicker, TimePicker, useDatePicker, useRangePicker, useTimePicker };
|
|
2581
|
+
export { DatePicker, DateTimePicker, MonthPicker, RangePicker, TimePicker, WeekPicker, YearPicker, useDatePicker, useRangePicker, useTimePicker };
|
|
2160
2582
|
//# sourceMappingURL=index.js.map
|
|
2161
2583
|
//# sourceMappingURL=index.js.map
|