@kalyx/react 0.4.0 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +132 -3
- package/README.md +6 -1
- package/dist/index.cjs +460 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +257 -5
- package/dist/index.d.ts +257 -5
- package/dist/index.js +458 -71
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -20,10 +20,23 @@ 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,
|
|
@@ -48,6 +61,9 @@ function DatePickerRoot({
|
|
|
48
61
|
const [focusedDate, setFocusedDate] = useState(
|
|
49
62
|
currentValue ?? adapter.today(displayTimezone)
|
|
50
63
|
);
|
|
64
|
+
useChangeEffect(isOpen, onOpenChange);
|
|
65
|
+
const viewMonthStart = useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
|
|
66
|
+
useChangeEffect(viewMonthStart, onCalendarNavigate);
|
|
51
67
|
const mergedLabels = useMemo(
|
|
52
68
|
() => ({ ...DEFAULT_DATEPICKER_LABELS, ...labelsProp }),
|
|
53
69
|
[labelsProp]
|
|
@@ -285,10 +301,15 @@ var DatePickerTrigger = forwardRef(
|
|
|
285
301
|
);
|
|
286
302
|
}
|
|
287
303
|
);
|
|
288
|
-
function usePopover({
|
|
304
|
+
function usePopover({
|
|
305
|
+
isOpen,
|
|
306
|
+
close,
|
|
307
|
+
referenceRef,
|
|
308
|
+
placement = "bottom-start"
|
|
309
|
+
}) {
|
|
289
310
|
const floatingRef = useRef(null);
|
|
290
311
|
const previousFocusRef = useRef(null);
|
|
291
|
-
const { refs, floatingStyles } = useFloating({
|
|
312
|
+
const { refs, floatingStyles, isPositioned } = useFloating({
|
|
292
313
|
open: isOpen,
|
|
293
314
|
placement,
|
|
294
315
|
middleware: [offset(4), flip(), shift({ padding: 8 })],
|
|
@@ -338,21 +359,28 @@ function usePopover({ isOpen, close, referenceRef, placement = "bottom-start" })
|
|
|
338
359
|
document.addEventListener("keydown", handleKeyDown);
|
|
339
360
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
340
361
|
}, [isOpen, close]);
|
|
341
|
-
const setFloatingRef = (
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
362
|
+
const setFloatingRef = useCallback(
|
|
363
|
+
(node) => {
|
|
364
|
+
floatingRef.current = node;
|
|
365
|
+
refs.setFloating(node);
|
|
366
|
+
if (node && referenceRef.current) {
|
|
367
|
+
refs.setReference(referenceRef.current);
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
[refs, referenceRef]
|
|
371
|
+
);
|
|
372
|
+
return { floatingStyles, setFloatingRef, isPositioned };
|
|
346
373
|
}
|
|
347
374
|
function DatePickerPopover({ children, ...props }) {
|
|
348
375
|
const ctx = useDatePickerContext("DatePicker.Popover");
|
|
349
376
|
const calendarId = `${ctx.pickerId}-calendar`;
|
|
350
|
-
const { floatingStyles, setFloatingRef } = usePopover({
|
|
377
|
+
const { floatingStyles, setFloatingRef, isPositioned } = usePopover({
|
|
351
378
|
isOpen: ctx.isOpen,
|
|
352
379
|
close: ctx.close,
|
|
353
380
|
referenceRef: ctx.referenceRef
|
|
354
381
|
});
|
|
355
382
|
if (!ctx.isOpen) return null;
|
|
383
|
+
const { style: userStyle, ...rest } = props;
|
|
356
384
|
return /* @__PURE__ */ jsx(
|
|
357
385
|
"div",
|
|
358
386
|
{
|
|
@@ -361,8 +389,12 @@ function DatePickerPopover({ children, ...props }) {
|
|
|
361
389
|
role: "dialog",
|
|
362
390
|
"aria-label": ctx.labels.popoverLabel,
|
|
363
391
|
"aria-modal": "false",
|
|
364
|
-
|
|
365
|
-
|
|
392
|
+
...rest,
|
|
393
|
+
style: {
|
|
394
|
+
...userStyle,
|
|
395
|
+
...floatingStyles,
|
|
396
|
+
visibility: isPositioned ? void 0 : "hidden"
|
|
397
|
+
},
|
|
366
398
|
children
|
|
367
399
|
}
|
|
368
400
|
);
|
|
@@ -385,7 +417,11 @@ var srOnly = {
|
|
|
385
417
|
whiteSpace: "nowrap",
|
|
386
418
|
border: 0
|
|
387
419
|
};
|
|
388
|
-
function DatePickerCalendar({
|
|
420
|
+
function DatePickerCalendar({
|
|
421
|
+
classNames,
|
|
422
|
+
onTitleClick,
|
|
423
|
+
...props
|
|
424
|
+
}) {
|
|
389
425
|
const ctx = useDatePickerContext("DatePicker.Calendar");
|
|
390
426
|
const gridRef = useRef(null);
|
|
391
427
|
const [announcement, setAnnouncement] = useState("");
|
|
@@ -403,9 +439,7 @@ function DatePickerCalendar({ classNames, onTitleClick, ...props }) {
|
|
|
403
439
|
const title = formatMonthYear(year, month, locale);
|
|
404
440
|
useEffect(() => {
|
|
405
441
|
if (!ctx.isOpen || !gridRef.current) return;
|
|
406
|
-
const focusedButton = gridRef.current.querySelector(
|
|
407
|
-
'[data-focused="true"]'
|
|
408
|
-
);
|
|
442
|
+
const focusedButton = gridRef.current.querySelector('[data-focused="true"]');
|
|
409
443
|
focusedButton?.focus({ preventScroll: true });
|
|
410
444
|
}, [focusedDate, ctx.isOpen]);
|
|
411
445
|
const navigateMonth = useCallback(
|
|
@@ -628,15 +662,7 @@ function DatePickerMonthGrid({
|
|
|
628
662
|
children: "<"
|
|
629
663
|
}
|
|
630
664
|
),
|
|
631
|
-
onTitleClick ? /* @__PURE__ */ jsx(
|
|
632
|
-
"button",
|
|
633
|
-
{
|
|
634
|
-
type: "button",
|
|
635
|
-
className: classNames?.title,
|
|
636
|
-
onClick: onTitleClick,
|
|
637
|
-
children: currentYear
|
|
638
|
-
}
|
|
639
|
-
) : /* @__PURE__ */ jsx("span", { className: classNames?.title, children: currentYear }),
|
|
665
|
+
onTitleClick ? /* @__PURE__ */ jsx("button", { type: "button", className: classNames?.title, onClick: onTitleClick, children: currentYear }) : /* @__PURE__ */ jsx("span", { className: classNames?.title, children: currentYear }),
|
|
640
666
|
/* @__PURE__ */ jsx(
|
|
641
667
|
"button",
|
|
642
668
|
{
|
|
@@ -681,11 +707,7 @@ function DatePickerMonthGrid({
|
|
|
681
707
|
)
|
|
682
708
|
] });
|
|
683
709
|
}
|
|
684
|
-
function DatePickerYearGrid({
|
|
685
|
-
classNames,
|
|
686
|
-
onSelect,
|
|
687
|
-
...props
|
|
688
|
-
}) {
|
|
710
|
+
function DatePickerYearGrid({ classNames, onSelect, ...props }) {
|
|
689
711
|
const ctx = useDatePickerContext("DatePicker.YearGrid");
|
|
690
712
|
const { adapter, viewMonth } = ctx;
|
|
691
713
|
const currentYear = adapter.getYear(viewMonth);
|
|
@@ -777,6 +799,82 @@ function DatePickerYearGrid({
|
|
|
777
799
|
)
|
|
778
800
|
] });
|
|
779
801
|
}
|
|
802
|
+
function DatePickerPresets({ classNames, children, ...props }) {
|
|
803
|
+
const ctx = useDatePickerContext("DatePicker.Presets");
|
|
804
|
+
return /* @__PURE__ */ jsx("div", { role: "group", "aria-label": ctx.labels.popoverLabel, className: classNames?.root, ...props, children });
|
|
805
|
+
}
|
|
806
|
+
function resolveDatePreset(key, today, adapter) {
|
|
807
|
+
switch (key) {
|
|
808
|
+
case "today":
|
|
809
|
+
return today;
|
|
810
|
+
case "tomorrow":
|
|
811
|
+
return adapter.addDays(today, 1);
|
|
812
|
+
case "yesterday":
|
|
813
|
+
return adapter.addDays(today, -1);
|
|
814
|
+
case "startOfMonth":
|
|
815
|
+
return adapter.startOfMonth(today);
|
|
816
|
+
case "endOfMonth":
|
|
817
|
+
return adapter.startOfDay(adapter.endOfMonth(today));
|
|
818
|
+
case "startOfYear": {
|
|
819
|
+
const currentMonth = adapter.getMonth(today);
|
|
820
|
+
return adapter.startOfMonth(adapter.addMonths(today, -currentMonth));
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
function DatePickerPreset({
|
|
825
|
+
value: presetKey,
|
|
826
|
+
date: directDate,
|
|
827
|
+
children,
|
|
828
|
+
onClick,
|
|
829
|
+
...props
|
|
830
|
+
}) {
|
|
831
|
+
const ctx = useDatePickerContext("DatePicker.Preset");
|
|
832
|
+
const handleClick = useCallback(
|
|
833
|
+
(e) => {
|
|
834
|
+
if (ctx.isDisabled || ctx.isReadOnly) return;
|
|
835
|
+
let resolved;
|
|
836
|
+
if (directDate) {
|
|
837
|
+
resolved = directDate;
|
|
838
|
+
} else if (presetKey) {
|
|
839
|
+
resolved = resolveDatePreset(
|
|
840
|
+
presetKey,
|
|
841
|
+
ctx.adapter.today(ctx.displayTimezone),
|
|
842
|
+
ctx.adapter
|
|
843
|
+
);
|
|
844
|
+
} else {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
ctx.selectDate(resolved);
|
|
848
|
+
onClick?.(e);
|
|
849
|
+
},
|
|
850
|
+
[ctx, presetKey, directDate, onClick]
|
|
851
|
+
);
|
|
852
|
+
const isActive = (() => {
|
|
853
|
+
if (!ctx.value) return false;
|
|
854
|
+
let target;
|
|
855
|
+
if (directDate) {
|
|
856
|
+
target = directDate;
|
|
857
|
+
} else if (presetKey) {
|
|
858
|
+
target = resolveDatePreset(presetKey, ctx.adapter.today(ctx.displayTimezone), ctx.adapter);
|
|
859
|
+
} else {
|
|
860
|
+
return false;
|
|
861
|
+
}
|
|
862
|
+
return ctx.adapter.isSameDay(ctx.value, target, ctx.displayTimezone);
|
|
863
|
+
})();
|
|
864
|
+
return /* @__PURE__ */ jsx(
|
|
865
|
+
"button",
|
|
866
|
+
{
|
|
867
|
+
type: "button",
|
|
868
|
+
role: "option",
|
|
869
|
+
"aria-selected": isActive,
|
|
870
|
+
"data-active": isActive || void 0,
|
|
871
|
+
disabled: ctx.isDisabled,
|
|
872
|
+
onClick: handleClick,
|
|
873
|
+
...props,
|
|
874
|
+
children
|
|
875
|
+
}
|
|
876
|
+
);
|
|
877
|
+
}
|
|
780
878
|
|
|
781
879
|
// src/components/DatePicker/index.ts
|
|
782
880
|
var DatePicker = Object.assign(DatePickerRoot, {
|
|
@@ -785,7 +883,9 @@ var DatePicker = Object.assign(DatePickerRoot, {
|
|
|
785
883
|
Popover: DatePickerPopover,
|
|
786
884
|
Calendar: DatePickerCalendar,
|
|
787
885
|
MonthGrid: DatePickerMonthGrid,
|
|
788
|
-
YearGrid: DatePickerYearGrid
|
|
886
|
+
YearGrid: DatePickerYearGrid,
|
|
887
|
+
Presets: DatePickerPresets,
|
|
888
|
+
Preset: DatePickerPreset
|
|
789
889
|
});
|
|
790
890
|
var RangePickerContext = createContext(null);
|
|
791
891
|
function useRangePickerContext(componentName) {
|
|
@@ -807,6 +907,8 @@ function RangePickerRoot({
|
|
|
807
907
|
value: controlledValue,
|
|
808
908
|
defaultValue,
|
|
809
909
|
onChange,
|
|
910
|
+
onOpenChange,
|
|
911
|
+
onCalendarNavigate,
|
|
810
912
|
disabled = false,
|
|
811
913
|
readOnly = false,
|
|
812
914
|
weekStartsOn = 0,
|
|
@@ -833,6 +935,9 @@ function RangePickerRoot({
|
|
|
833
935
|
const [focusedDate, setFocusedDate] = useState(
|
|
834
936
|
currentValue.start ?? adapter.today(displayTimezone)
|
|
835
937
|
);
|
|
938
|
+
useChangeEffect(isOpen, onOpenChange);
|
|
939
|
+
const viewMonthStart = useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
|
|
940
|
+
useChangeEffect(viewMonthStart, onCalendarNavigate);
|
|
836
941
|
const mergedLabels = useMemo(
|
|
837
942
|
() => ({ ...DEFAULT_RANGEPICKER_LABELS, ...labelsProp }),
|
|
838
943
|
[labelsProp]
|
|
@@ -1017,12 +1122,13 @@ var RangePickerInput = forwardRef(
|
|
|
1017
1122
|
function RangePickerPopover({ children, ...props }) {
|
|
1018
1123
|
const ctx = useRangePickerContext("RangePicker.Popover");
|
|
1019
1124
|
const calendarId = `${ctx.pickerId}-calendar`;
|
|
1020
|
-
const { floatingStyles, setFloatingRef } = usePopover({
|
|
1125
|
+
const { floatingStyles, setFloatingRef, isPositioned } = usePopover({
|
|
1021
1126
|
isOpen: ctx.isOpen,
|
|
1022
1127
|
close: ctx.close,
|
|
1023
1128
|
referenceRef: ctx.referenceRef
|
|
1024
1129
|
});
|
|
1025
1130
|
if (!ctx.isOpen) return null;
|
|
1131
|
+
const { style: userStyle, ...rest } = props;
|
|
1026
1132
|
return /* @__PURE__ */ jsx(
|
|
1027
1133
|
"div",
|
|
1028
1134
|
{
|
|
@@ -1031,8 +1137,12 @@ function RangePickerPopover({ children, ...props }) {
|
|
|
1031
1137
|
role: "dialog",
|
|
1032
1138
|
"aria-label": ctx.labels.popoverLabel,
|
|
1033
1139
|
"aria-modal": "false",
|
|
1034
|
-
|
|
1035
|
-
|
|
1140
|
+
...rest,
|
|
1141
|
+
style: {
|
|
1142
|
+
...userStyle,
|
|
1143
|
+
...floatingStyles,
|
|
1144
|
+
visibility: isPositioned ? void 0 : "hidden"
|
|
1145
|
+
},
|
|
1036
1146
|
children
|
|
1037
1147
|
}
|
|
1038
1148
|
);
|
|
@@ -1055,7 +1165,11 @@ var srOnly2 = {
|
|
|
1055
1165
|
whiteSpace: "nowrap",
|
|
1056
1166
|
border: 0
|
|
1057
1167
|
};
|
|
1058
|
-
function RangePickerCalendar({
|
|
1168
|
+
function RangePickerCalendar({
|
|
1169
|
+
classNames,
|
|
1170
|
+
selectionMode = "range",
|
|
1171
|
+
...props
|
|
1172
|
+
}) {
|
|
1059
1173
|
const ctx = useRangePickerContext("RangePicker.Calendar");
|
|
1060
1174
|
const gridRef = useRef(null);
|
|
1061
1175
|
const [announcement, setAnnouncement] = useState("");
|
|
@@ -1085,9 +1199,7 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1085
1199
|
const title = formatMonthYear(year, month, locale);
|
|
1086
1200
|
useEffect(() => {
|
|
1087
1201
|
if (!ctx.isOpen || !gridRef.current) return;
|
|
1088
|
-
const focusedButton = gridRef.current.querySelector(
|
|
1089
|
-
'[data-focused="true"]'
|
|
1090
|
-
);
|
|
1202
|
+
const focusedButton = gridRef.current.querySelector('[data-focused="true"]');
|
|
1091
1203
|
focusedButton?.focus({ preventScroll: true });
|
|
1092
1204
|
}, [focusedDate, ctx.isOpen]);
|
|
1093
1205
|
const navigateMonth = useCallback(
|
|
@@ -1101,21 +1213,39 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1101
1213
|
},
|
|
1102
1214
|
[adapter, viewMonth, ctx, locale]
|
|
1103
1215
|
);
|
|
1216
|
+
const commitDay = useCallback(
|
|
1217
|
+
(iso) => {
|
|
1218
|
+
if (selectionMode === "week") {
|
|
1219
|
+
const weekStart = adapter.startOfWeek(iso, weekStartsOn);
|
|
1220
|
+
const weekEnd = adapter.startOfDay(adapter.endOfWeek(iso, weekStartsOn));
|
|
1221
|
+
const range = { start: weekStart, end: weekEnd };
|
|
1222
|
+
ctx.setRange(range);
|
|
1223
|
+
ctx.close();
|
|
1224
|
+
setAnnouncement(
|
|
1225
|
+
`${safeFormatFullDate2(weekStart, locale)} \u2013 ${safeFormatFullDate2(weekEnd, locale)}`
|
|
1226
|
+
);
|
|
1227
|
+
} else {
|
|
1228
|
+
ctx.selectDate(iso);
|
|
1229
|
+
setAnnouncement(safeFormatFullDate2(iso, locale));
|
|
1230
|
+
}
|
|
1231
|
+
},
|
|
1232
|
+
[selectionMode, adapter, weekStartsOn, ctx, locale]
|
|
1233
|
+
);
|
|
1104
1234
|
const handleDayClick = useCallback(
|
|
1105
1235
|
(day) => {
|
|
1106
1236
|
if (day.isDisabled) return;
|
|
1107
|
-
|
|
1108
|
-
setAnnouncement(safeFormatFullDate2(day.isoString, locale));
|
|
1237
|
+
commitDay(day.isoString);
|
|
1109
1238
|
},
|
|
1110
|
-
[
|
|
1239
|
+
[commitDay]
|
|
1111
1240
|
);
|
|
1112
1241
|
const handleDayMouseEnter = useCallback(
|
|
1113
1242
|
(day) => {
|
|
1243
|
+
if (selectionMode === "week") return;
|
|
1114
1244
|
if (selectingTarget === "end" && value.start && !day.isDisabled) {
|
|
1115
1245
|
ctx.setHoverDate(day.isoString);
|
|
1116
1246
|
}
|
|
1117
1247
|
},
|
|
1118
|
-
[selectingTarget, value.start, ctx]
|
|
1248
|
+
[selectionMode, selectingTarget, value.start, ctx]
|
|
1119
1249
|
);
|
|
1120
1250
|
const handleMouseLeave = useCallback(() => {
|
|
1121
1251
|
ctx.setHoverDate(null);
|
|
@@ -1152,7 +1282,7 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1152
1282
|
case " ":
|
|
1153
1283
|
e.preventDefault();
|
|
1154
1284
|
if (!isDateDisabled(focusedDate, disabled, adapter)) {
|
|
1155
|
-
|
|
1285
|
+
commitDay(focusedDate);
|
|
1156
1286
|
}
|
|
1157
1287
|
return;
|
|
1158
1288
|
case "Escape":
|
|
@@ -1167,12 +1297,23 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1167
1297
|
if (!adapter.isSameMonth(newFocused, viewMonth)) {
|
|
1168
1298
|
ctx.setViewMonth(newFocused);
|
|
1169
1299
|
}
|
|
1170
|
-
if (selectingTarget === "end" && value.start) {
|
|
1300
|
+
if (selectionMode === "range" && selectingTarget === "end" && value.start) {
|
|
1171
1301
|
ctx.setHoverDate(newFocused);
|
|
1172
1302
|
}
|
|
1173
1303
|
}
|
|
1174
1304
|
},
|
|
1175
|
-
[
|
|
1305
|
+
[
|
|
1306
|
+
adapter,
|
|
1307
|
+
focusedDate,
|
|
1308
|
+
viewMonth,
|
|
1309
|
+
weekStartsOn,
|
|
1310
|
+
disabled,
|
|
1311
|
+
ctx,
|
|
1312
|
+
selectionMode,
|
|
1313
|
+
selectingTarget,
|
|
1314
|
+
value.start,
|
|
1315
|
+
commitDay
|
|
1316
|
+
]
|
|
1176
1317
|
);
|
|
1177
1318
|
return /* @__PURE__ */ jsxs("div", { className: classNames?.root, ...props, onMouseLeave: handleMouseLeave, children: [
|
|
1178
1319
|
/* @__PURE__ */ jsxs("div", { className: classNames?.header, children: [
|
|
@@ -1229,7 +1370,7 @@ function RangePickerCalendar({ classNames, ...props }) {
|
|
|
1229
1370
|
day.isDisabled && classNames?.dayDisabled,
|
|
1230
1371
|
!day.isCurrentMonth && classNames?.dayOutsideMonth
|
|
1231
1372
|
].filter(Boolean).join(" ") || void 0;
|
|
1232
|
-
const isSelected = day.isRangeStart || day.isRangeEnd;
|
|
1373
|
+
const isSelected = selectionMode === "week" ? day.isRangeStart || day.isRangeEnd || day.isInRange : day.isRangeStart || day.isRangeEnd;
|
|
1233
1374
|
return /* @__PURE__ */ jsx(
|
|
1234
1375
|
"td",
|
|
1235
1376
|
{
|
|
@@ -1309,9 +1450,7 @@ function resolvePreset(key, today, adapter) {
|
|
|
1309
1450
|
}
|
|
1310
1451
|
case "thisYear": {
|
|
1311
1452
|
const currentMonth = new Date(today).getUTCMonth();
|
|
1312
|
-
const yearStart = adapter.startOfMonth(
|
|
1313
|
-
adapter.addMonths(today, -currentMonth)
|
|
1314
|
-
);
|
|
1453
|
+
const yearStart = adapter.startOfMonth(adapter.addMonths(today, -currentMonth));
|
|
1315
1454
|
return { start: yearStart, end: today };
|
|
1316
1455
|
}
|
|
1317
1456
|
}
|
|
@@ -1447,7 +1586,19 @@ function TimePickerRoot({
|
|
|
1447
1586
|
pickerId,
|
|
1448
1587
|
labels: mergedLabels
|
|
1449
1588
|
}),
|
|
1450
|
-
[
|
|
1589
|
+
[
|
|
1590
|
+
currentValue,
|
|
1591
|
+
setTime$1,
|
|
1592
|
+
format,
|
|
1593
|
+
step,
|
|
1594
|
+
withSeconds,
|
|
1595
|
+
displayTimezone,
|
|
1596
|
+
disabled,
|
|
1597
|
+
readOnly,
|
|
1598
|
+
currentTime,
|
|
1599
|
+
pickerId,
|
|
1600
|
+
mergedLabels
|
|
1601
|
+
]
|
|
1451
1602
|
);
|
|
1452
1603
|
return /* @__PURE__ */ jsx(TimePickerContext.Provider, { value: contextValue, children });
|
|
1453
1604
|
}
|
|
@@ -1464,12 +1615,9 @@ var TimePickerInput = forwardRef(
|
|
|
1464
1615
|
}
|
|
1465
1616
|
setInputText(null);
|
|
1466
1617
|
}, [inputText, ctx]);
|
|
1467
|
-
const handleChange = useCallback(
|
|
1468
|
-
(e)
|
|
1469
|
-
|
|
1470
|
-
},
|
|
1471
|
-
[]
|
|
1472
|
-
);
|
|
1618
|
+
const handleChange = useCallback((e) => {
|
|
1619
|
+
setInputText(e.target.value);
|
|
1620
|
+
}, []);
|
|
1473
1621
|
const handleBlur = useCallback(
|
|
1474
1622
|
(e) => {
|
|
1475
1623
|
commitInput();
|
|
@@ -1542,9 +1690,7 @@ function useListboxNavigation({
|
|
|
1542
1690
|
onSelect(target);
|
|
1543
1691
|
cancelAnimationFrame(rafIdRef.current);
|
|
1544
1692
|
rafIdRef.current = requestAnimationFrame(() => {
|
|
1545
|
-
const next = listRef.current?.querySelector(
|
|
1546
|
-
'[data-selected="true"]'
|
|
1547
|
-
);
|
|
1693
|
+
const next = listRef.current?.querySelector('[data-selected="true"]');
|
|
1548
1694
|
next?.focus();
|
|
1549
1695
|
});
|
|
1550
1696
|
}
|
|
@@ -1681,10 +1827,19 @@ function TimePickerAmPmToggle({ classNames, ...props }) {
|
|
|
1681
1827
|
}
|
|
1682
1828
|
);
|
|
1683
1829
|
};
|
|
1684
|
-
return /* @__PURE__ */ jsxs(
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1830
|
+
return /* @__PURE__ */ jsxs(
|
|
1831
|
+
"div",
|
|
1832
|
+
{
|
|
1833
|
+
role: "radiogroup",
|
|
1834
|
+
"aria-label": ctx.labels.amPmToggle,
|
|
1835
|
+
className: classNames?.root,
|
|
1836
|
+
...props,
|
|
1837
|
+
children: [
|
|
1838
|
+
renderButton("AM"),
|
|
1839
|
+
renderButton("PM")
|
|
1840
|
+
]
|
|
1841
|
+
}
|
|
1842
|
+
);
|
|
1688
1843
|
}
|
|
1689
1844
|
|
|
1690
1845
|
// src/components/TimePicker/index.ts
|
|
@@ -1701,6 +1856,8 @@ function DateTimePickerRoot({
|
|
|
1701
1856
|
value: controlledValue,
|
|
1702
1857
|
defaultValue,
|
|
1703
1858
|
onChange,
|
|
1859
|
+
onOpenChange,
|
|
1860
|
+
onCalendarNavigate,
|
|
1704
1861
|
format = "24h",
|
|
1705
1862
|
step = 1,
|
|
1706
1863
|
disabled = false,
|
|
@@ -1735,6 +1892,9 @@ function DateTimePickerRoot({
|
|
|
1735
1892
|
const [focusedDate, setFocusedDate] = useState(
|
|
1736
1893
|
currentValue ?? adapter.today(displayTimezone)
|
|
1737
1894
|
);
|
|
1895
|
+
useChangeEffect(isOpen, onOpenChange);
|
|
1896
|
+
const viewMonthStart = useMemo(() => adapter.startOfMonth(viewMonth), [viewMonth, adapter]);
|
|
1897
|
+
useChangeEffect(viewMonthStart, onCalendarNavigate);
|
|
1738
1898
|
const isDisabled = typeof disabled === "boolean" ? disabled : false;
|
|
1739
1899
|
const disabledRules = useMemo(
|
|
1740
1900
|
() => Array.isArray(disabled) ? disabled : [],
|
|
@@ -1849,7 +2009,18 @@ function DateTimePickerRoot({
|
|
|
1849
2009
|
pickerId,
|
|
1850
2010
|
labels: mergedTimeLabels
|
|
1851
2011
|
}),
|
|
1852
|
-
[
|
|
2012
|
+
[
|
|
2013
|
+
currentValue,
|
|
2014
|
+
setTime$1,
|
|
2015
|
+
format,
|
|
2016
|
+
step,
|
|
2017
|
+
displayTimezone,
|
|
2018
|
+
isDisabled,
|
|
2019
|
+
readOnly,
|
|
2020
|
+
currentTime,
|
|
2021
|
+
pickerId,
|
|
2022
|
+
mergedTimeLabels
|
|
2023
|
+
]
|
|
1853
2024
|
);
|
|
1854
2025
|
return /* @__PURE__ */ jsx(DatePickerContext.Provider, { value: dateContext, children: /* @__PURE__ */ jsx(TimePickerContext.Provider, { value: timeContext, children }) });
|
|
1855
2026
|
}
|
|
@@ -1924,6 +2095,228 @@ var DateTimePicker = Object.assign(DateTimePickerRoot, {
|
|
|
1924
2095
|
MinuteList: TimePickerMinuteList,
|
|
1925
2096
|
AmPmToggle: TimePickerAmPmToggle
|
|
1926
2097
|
});
|
|
2098
|
+
function MonthPickerRoot(props) {
|
|
2099
|
+
const displayFormat = props.displayFormat ?? "yyyy-MM";
|
|
2100
|
+
return /* @__PURE__ */ jsx(DatePickerRoot, { ...props, displayFormat });
|
|
2101
|
+
}
|
|
2102
|
+
function MonthPickerGrid({ classNames, ...props }) {
|
|
2103
|
+
const ctx = useDatePickerContext("MonthPicker.Grid");
|
|
2104
|
+
const { adapter, viewMonth, locale, value, displayTimezone, labels } = ctx;
|
|
2105
|
+
const currentYear = adapter.getYear(viewMonth);
|
|
2106
|
+
const [valueYear, valueMonthZeroBased] = useMemo(() => {
|
|
2107
|
+
if (!value) return [null, null];
|
|
2108
|
+
try {
|
|
2109
|
+
const [y, m] = adapter.format(value, "yyyy-MM", displayTimezone).split("-").map(Number);
|
|
2110
|
+
return [y, m - 1];
|
|
2111
|
+
} catch {
|
|
2112
|
+
return [null, null];
|
|
2113
|
+
}
|
|
2114
|
+
}, [value, adapter, displayTimezone]);
|
|
2115
|
+
const today = adapter.today(displayTimezone);
|
|
2116
|
+
const todayYear = adapter.getYear(today);
|
|
2117
|
+
const todayMonth = adapter.getMonth(today);
|
|
2118
|
+
const navigateYear = useCallback(
|
|
2119
|
+
(direction) => {
|
|
2120
|
+
ctx.setViewMonth(adapter.addYears(viewMonth, direction));
|
|
2121
|
+
},
|
|
2122
|
+
[adapter, viewMonth, ctx]
|
|
2123
|
+
);
|
|
2124
|
+
const handleMonthSelect = useCallback(
|
|
2125
|
+
(monthIndex) => {
|
|
2126
|
+
const target = new Date(Date.UTC(currentYear, monthIndex, 1)).toISOString();
|
|
2127
|
+
ctx.selectDate(target);
|
|
2128
|
+
},
|
|
2129
|
+
[currentYear, ctx]
|
|
2130
|
+
);
|
|
2131
|
+
const months = Array.from({ length: 12 }, (_, i) => ({
|
|
2132
|
+
index: i,
|
|
2133
|
+
name: getMonthName(i, locale),
|
|
2134
|
+
isSelected: valueYear === currentYear && valueMonthZeroBased === i,
|
|
2135
|
+
isCurrent: todayYear === currentYear && todayMonth === i
|
|
2136
|
+
}));
|
|
2137
|
+
return /* @__PURE__ */ jsxs("div", { className: classNames?.root, ...props, children: [
|
|
2138
|
+
/* @__PURE__ */ jsxs("div", { className: classNames?.header, children: [
|
|
2139
|
+
/* @__PURE__ */ jsx(
|
|
2140
|
+
"button",
|
|
2141
|
+
{
|
|
2142
|
+
type: "button",
|
|
2143
|
+
className: classNames?.navButton,
|
|
2144
|
+
onClick: () => navigateYear(-1),
|
|
2145
|
+
"aria-label": labels.prevYear,
|
|
2146
|
+
children: "<"
|
|
2147
|
+
}
|
|
2148
|
+
),
|
|
2149
|
+
/* @__PURE__ */ jsx("span", { className: classNames?.title, children: currentYear }),
|
|
2150
|
+
/* @__PURE__ */ jsx(
|
|
2151
|
+
"button",
|
|
2152
|
+
{
|
|
2153
|
+
type: "button",
|
|
2154
|
+
className: classNames?.navButton,
|
|
2155
|
+
onClick: () => navigateYear(1),
|
|
2156
|
+
"aria-label": labels.nextYear,
|
|
2157
|
+
children: ">"
|
|
2158
|
+
}
|
|
2159
|
+
)
|
|
2160
|
+
] }),
|
|
2161
|
+
/* @__PURE__ */ jsx("div", { role: "grid", "aria-label": `${currentYear} months`, className: classNames?.grid, children: Array.from({ length: 4 }, (_, rowIndex) => /* @__PURE__ */ jsx(
|
|
2162
|
+
"div",
|
|
2163
|
+
{
|
|
2164
|
+
role: "row",
|
|
2165
|
+
className: classNames?.gridRow,
|
|
2166
|
+
style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)" },
|
|
2167
|
+
children: months.slice(rowIndex * 3, rowIndex * 3 + 3).map((m) => {
|
|
2168
|
+
const monthClass = [
|
|
2169
|
+
classNames?.month,
|
|
2170
|
+
m.isSelected && classNames?.monthSelected,
|
|
2171
|
+
m.isCurrent && classNames?.monthCurrent
|
|
2172
|
+
].filter(Boolean).join(" ") || void 0;
|
|
2173
|
+
return /* @__PURE__ */ jsx(
|
|
2174
|
+
"button",
|
|
2175
|
+
{
|
|
2176
|
+
type: "button",
|
|
2177
|
+
role: "gridcell",
|
|
2178
|
+
"aria-selected": m.isSelected || void 0,
|
|
2179
|
+
"aria-current": m.isCurrent ? "date" : void 0,
|
|
2180
|
+
"data-selected": m.isSelected || void 0,
|
|
2181
|
+
"data-current": m.isCurrent || void 0,
|
|
2182
|
+
className: monthClass,
|
|
2183
|
+
onClick: () => handleMonthSelect(m.index),
|
|
2184
|
+
children: m.name
|
|
2185
|
+
},
|
|
2186
|
+
m.index
|
|
2187
|
+
);
|
|
2188
|
+
})
|
|
2189
|
+
},
|
|
2190
|
+
rowIndex
|
|
2191
|
+
)) })
|
|
2192
|
+
] });
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2195
|
+
// src/components/MonthPicker/index.ts
|
|
2196
|
+
var MonthPicker = Object.assign(MonthPickerRoot, {
|
|
2197
|
+
Input: DatePickerInput,
|
|
2198
|
+
Trigger: DatePickerTrigger,
|
|
2199
|
+
Popover: DatePickerPopover,
|
|
2200
|
+
Grid: MonthPickerGrid
|
|
2201
|
+
});
|
|
2202
|
+
function YearPickerRoot(props) {
|
|
2203
|
+
const displayFormat = props.displayFormat ?? "yyyy";
|
|
2204
|
+
return /* @__PURE__ */ jsx(DatePickerRoot, { ...props, displayFormat });
|
|
2205
|
+
}
|
|
2206
|
+
function YearPickerGrid({ classNames, ...props }) {
|
|
2207
|
+
const ctx = useDatePickerContext("YearPicker.Grid");
|
|
2208
|
+
const { adapter, viewMonth, value, displayTimezone, labels } = ctx;
|
|
2209
|
+
const currentYear = adapter.getYear(viewMonth);
|
|
2210
|
+
const decadeStart = currentYear - currentYear % 12;
|
|
2211
|
+
const valueYear = useMemo(() => {
|
|
2212
|
+
if (!value) return null;
|
|
2213
|
+
try {
|
|
2214
|
+
return Number(adapter.format(value, "yyyy", displayTimezone));
|
|
2215
|
+
} catch {
|
|
2216
|
+
return null;
|
|
2217
|
+
}
|
|
2218
|
+
}, [value, adapter, displayTimezone]);
|
|
2219
|
+
const todayYear = adapter.getYear(adapter.today(displayTimezone));
|
|
2220
|
+
const navigateDecade = useCallback(
|
|
2221
|
+
(direction) => {
|
|
2222
|
+
ctx.setViewMonth(adapter.addYears(viewMonth, direction * 12));
|
|
2223
|
+
},
|
|
2224
|
+
[adapter, viewMonth, ctx]
|
|
2225
|
+
);
|
|
2226
|
+
const handleYearSelect = useCallback(
|
|
2227
|
+
(year) => {
|
|
2228
|
+
const target = new Date(Date.UTC(year, 0, 1)).toISOString();
|
|
2229
|
+
ctx.selectDate(target);
|
|
2230
|
+
},
|
|
2231
|
+
[ctx]
|
|
2232
|
+
);
|
|
2233
|
+
const years = Array.from({ length: 12 }, (_, i) => {
|
|
2234
|
+
const year = decadeStart + i;
|
|
2235
|
+
return {
|
|
2236
|
+
value: year,
|
|
2237
|
+
isSelected: year === valueYear,
|
|
2238
|
+
isCurrent: year === todayYear
|
|
2239
|
+
};
|
|
2240
|
+
});
|
|
2241
|
+
const rangeLabel = `${decadeStart}\u2013${decadeStart + 11}`;
|
|
2242
|
+
return /* @__PURE__ */ jsxs("div", { className: classNames?.root, ...props, children: [
|
|
2243
|
+
/* @__PURE__ */ jsxs("div", { className: classNames?.header, children: [
|
|
2244
|
+
/* @__PURE__ */ jsx(
|
|
2245
|
+
"button",
|
|
2246
|
+
{
|
|
2247
|
+
type: "button",
|
|
2248
|
+
className: classNames?.navButton,
|
|
2249
|
+
onClick: () => navigateDecade(-1),
|
|
2250
|
+
"aria-label": labels.prevDecade,
|
|
2251
|
+
children: "<"
|
|
2252
|
+
}
|
|
2253
|
+
),
|
|
2254
|
+
/* @__PURE__ */ jsx("span", { className: classNames?.title, children: rangeLabel }),
|
|
2255
|
+
/* @__PURE__ */ jsx(
|
|
2256
|
+
"button",
|
|
2257
|
+
{
|
|
2258
|
+
type: "button",
|
|
2259
|
+
className: classNames?.navButton,
|
|
2260
|
+
onClick: () => navigateDecade(1),
|
|
2261
|
+
"aria-label": labels.nextDecade,
|
|
2262
|
+
children: ">"
|
|
2263
|
+
}
|
|
2264
|
+
)
|
|
2265
|
+
] }),
|
|
2266
|
+
/* @__PURE__ */ jsx("div", { role: "grid", "aria-label": rangeLabel, className: classNames?.grid, children: Array.from({ length: 4 }, (_, rowIndex) => /* @__PURE__ */ jsx(
|
|
2267
|
+
"div",
|
|
2268
|
+
{
|
|
2269
|
+
role: "row",
|
|
2270
|
+
className: classNames?.gridRow,
|
|
2271
|
+
style: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)" },
|
|
2272
|
+
children: years.slice(rowIndex * 3, rowIndex * 3 + 3).map((y) => {
|
|
2273
|
+
const yearClass = [
|
|
2274
|
+
classNames?.year,
|
|
2275
|
+
y.isSelected && classNames?.yearSelected,
|
|
2276
|
+
y.isCurrent && classNames?.yearCurrent
|
|
2277
|
+
].filter(Boolean).join(" ") || void 0;
|
|
2278
|
+
return /* @__PURE__ */ jsx(
|
|
2279
|
+
"button",
|
|
2280
|
+
{
|
|
2281
|
+
type: "button",
|
|
2282
|
+
role: "gridcell",
|
|
2283
|
+
"aria-selected": y.isSelected || void 0,
|
|
2284
|
+
"aria-current": y.isCurrent ? "date" : void 0,
|
|
2285
|
+
"data-selected": y.isSelected || void 0,
|
|
2286
|
+
"data-current": y.isCurrent || void 0,
|
|
2287
|
+
className: yearClass,
|
|
2288
|
+
onClick: () => handleYearSelect(y.value),
|
|
2289
|
+
children: y.value
|
|
2290
|
+
},
|
|
2291
|
+
y.value
|
|
2292
|
+
);
|
|
2293
|
+
})
|
|
2294
|
+
},
|
|
2295
|
+
rowIndex
|
|
2296
|
+
)) })
|
|
2297
|
+
] });
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
// src/components/YearPicker/index.ts
|
|
2301
|
+
var YearPicker = Object.assign(YearPickerRoot, {
|
|
2302
|
+
Input: DatePickerInput,
|
|
2303
|
+
Trigger: DatePickerTrigger,
|
|
2304
|
+
Popover: DatePickerPopover,
|
|
2305
|
+
Grid: YearPickerGrid
|
|
2306
|
+
});
|
|
2307
|
+
function WeekPickerRoot(props) {
|
|
2308
|
+
return /* @__PURE__ */ jsx(RangePickerRoot, { ...props });
|
|
2309
|
+
}
|
|
2310
|
+
function WeekPickerCalendar(props) {
|
|
2311
|
+
return /* @__PURE__ */ jsx(RangePickerCalendar, { ...props, selectionMode: "week" });
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
// src/components/WeekPicker/index.ts
|
|
2315
|
+
var WeekPicker = Object.assign(WeekPickerRoot, {
|
|
2316
|
+
Input: RangePickerInput,
|
|
2317
|
+
Popover: RangePickerPopover,
|
|
2318
|
+
Calendar: WeekPickerCalendar
|
|
2319
|
+
});
|
|
1927
2320
|
function useDatePicker(options = {}) {
|
|
1928
2321
|
const {
|
|
1929
2322
|
value: controlledValue,
|
|
@@ -2163,14 +2556,8 @@ function useTimePicker(options = {}) {
|
|
|
2163
2556
|
},
|
|
2164
2557
|
[format, period, setTime$1]
|
|
2165
2558
|
);
|
|
2166
|
-
const setMinute = useCallback(
|
|
2167
|
-
|
|
2168
|
-
[setTime$1]
|
|
2169
|
-
);
|
|
2170
|
-
const setSecond = useCallback(
|
|
2171
|
-
(second) => setTime$1({ seconds: second }),
|
|
2172
|
-
[setTime$1]
|
|
2173
|
-
);
|
|
2559
|
+
const setMinute = useCallback((minute) => setTime$1({ minutes: minute }), [setTime$1]);
|
|
2560
|
+
const setSecond = useCallback((second) => setTime$1({ seconds: second }), [setTime$1]);
|
|
2174
2561
|
const setPeriod = useCallback(
|
|
2175
2562
|
(newPeriod) => {
|
|
2176
2563
|
if (format !== "12h") return;
|
|
@@ -2196,6 +2583,6 @@ function useTimePicker(options = {}) {
|
|
|
2196
2583
|
};
|
|
2197
2584
|
}
|
|
2198
2585
|
|
|
2199
|
-
export { DatePicker, DateTimePicker, RangePicker, TimePicker, useDatePicker, useRangePicker, useTimePicker };
|
|
2586
|
+
export { DatePicker, DateTimePicker, MonthPicker, RangePicker, TimePicker, WeekPicker, YearPicker, useDatePicker, useRangePicker, useTimePicker };
|
|
2200
2587
|
//# sourceMappingURL=index.js.map
|
|
2201
2588
|
//# sourceMappingURL=index.js.map
|