@xsolla/xui-calendar 0.226.0 → 0.228.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/README.md +33 -16
- package/native/index.d.mts +6 -0
- package/native/index.d.ts +6 -0
- package/native/index.js +125 -11
- package/native/index.js.map +1 -1
- package/native/index.mjs +145 -24
- package/native/index.mjs.map +1 -1
- package/package.json +7 -7
- package/web/index.d.mts +6 -0
- package/web/index.d.ts +6 -0
- package/web/index.js +125 -11
- package/web/index.js.map +1 -1
- package/web/index.mjs +145 -24
- package/web/index.mjs.map +1 -1
package/web/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/Calendar.tsx
|
|
2
|
-
import { forwardRef, useCallback as useCallback3, useEffect, useState as useState2 } from "react";
|
|
2
|
+
import { forwardRef, useCallback as useCallback3, useEffect as useEffect2, useState as useState2 } from "react";
|
|
3
3
|
|
|
4
4
|
// ../../foundation/primitives-web/src/Box.tsx
|
|
5
5
|
import React2 from "react";
|
|
@@ -336,9 +336,12 @@ var Text = ({
|
|
|
336
336
|
);
|
|
337
337
|
};
|
|
338
338
|
|
|
339
|
+
// ../../foundation/primitives-web/src/index.tsx
|
|
340
|
+
var isWeb = true;
|
|
341
|
+
|
|
339
342
|
// src/Calendar.tsx
|
|
340
343
|
import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
|
|
341
|
-
import { addMonths, subDays, subMonths, startOfDay as startOfDay2 } from "date-fns";
|
|
344
|
+
import { addMonths as addMonths2, subDays, subMonths, startOfDay as startOfDay2 } from "date-fns";
|
|
342
345
|
|
|
343
346
|
// src/CalendarHeader.tsx
|
|
344
347
|
import { useCallback, useMemo } from "react";
|
|
@@ -490,10 +493,17 @@ var CalendarHeader = ({
|
|
|
490
493
|
};
|
|
491
494
|
|
|
492
495
|
// src/CalendarGrid.tsx
|
|
493
|
-
import {
|
|
496
|
+
import {
|
|
497
|
+
useMemo as useMemo2,
|
|
498
|
+
useCallback as useCallback2,
|
|
499
|
+
useEffect,
|
|
500
|
+
useRef,
|
|
501
|
+
useState
|
|
502
|
+
} from "react";
|
|
494
503
|
import { useResolvedTheme } from "@xsolla/xui-core";
|
|
495
504
|
import {
|
|
496
505
|
addDays,
|
|
506
|
+
addMonths,
|
|
497
507
|
eachDayOfInterval,
|
|
498
508
|
endOfDay,
|
|
499
509
|
endOfMonth,
|
|
@@ -513,6 +523,7 @@ import * as locales2 from "date-fns/locale";
|
|
|
513
523
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
514
524
|
var DAY_CELL_WIDTH = 40;
|
|
515
525
|
var GRID_WIDTH = DAY_CELL_WIDTH * 7;
|
|
526
|
+
var dayKeyOf = (date) => format2(date, "yyyy-MM-dd");
|
|
516
527
|
var CalendarGrid = ({
|
|
517
528
|
currentMonth,
|
|
518
529
|
locale = "enUS",
|
|
@@ -525,6 +536,7 @@ var CalendarGrid = ({
|
|
|
525
536
|
selectedDate,
|
|
526
537
|
selectingRange,
|
|
527
538
|
onDayPress,
|
|
539
|
+
onMonthChange,
|
|
528
540
|
testID,
|
|
529
541
|
themeMode,
|
|
530
542
|
themeProductContext
|
|
@@ -573,33 +585,122 @@ var CalendarGrid = ({
|
|
|
573
585
|
},
|
|
574
586
|
[selectsRange, startDate, endDate, selectingRange]
|
|
575
587
|
);
|
|
576
|
-
|
|
588
|
+
const [focusedDate, setFocusedDate] = useState(null);
|
|
589
|
+
const dayRefs = useRef(/* @__PURE__ */ new Map());
|
|
590
|
+
const shouldMoveFocus = useRef(false);
|
|
591
|
+
const tabStopDate = useMemo2(() => {
|
|
592
|
+
if (focusedDate && isSameMonth(focusedDate, currentMonth)) {
|
|
593
|
+
return focusedDate;
|
|
594
|
+
}
|
|
595
|
+
const preferred = selectsRange ? startDate : selectedDate;
|
|
596
|
+
if (preferred && isSameMonth(preferred, currentMonth)) return preferred;
|
|
597
|
+
const today = /* @__PURE__ */ new Date();
|
|
598
|
+
if (isSameMonth(today, currentMonth)) return today;
|
|
599
|
+
return monthStart;
|
|
600
|
+
}, [
|
|
601
|
+
focusedDate,
|
|
602
|
+
currentMonth,
|
|
603
|
+
selectsRange,
|
|
604
|
+
startDate,
|
|
605
|
+
selectedDate,
|
|
606
|
+
monthStart
|
|
607
|
+
]);
|
|
608
|
+
const tabStopKey = dayKeyOf(tabStopDate);
|
|
609
|
+
useEffect(() => {
|
|
610
|
+
if (!shouldMoveFocus.current) return;
|
|
611
|
+
shouldMoveFocus.current = false;
|
|
612
|
+
dayRefs.current.get(tabStopKey)?.focus();
|
|
613
|
+
}, [tabStopKey, currentMonth]);
|
|
614
|
+
const moveFocus = useCallback2(
|
|
615
|
+
(target) => {
|
|
616
|
+
if (!isSameMonth(target, currentMonth)) {
|
|
617
|
+
if (!onMonthChange) return;
|
|
618
|
+
onMonthChange(startOfMonth(target));
|
|
619
|
+
}
|
|
620
|
+
shouldMoveFocus.current = true;
|
|
621
|
+
setFocusedDate(target);
|
|
622
|
+
},
|
|
623
|
+
[currentMonth, onMonthChange]
|
|
624
|
+
);
|
|
625
|
+
const handleDayKeyDown = useCallback2(
|
|
626
|
+
(event, day) => {
|
|
627
|
+
let target = null;
|
|
628
|
+
switch (event.key) {
|
|
629
|
+
case "ArrowLeft":
|
|
630
|
+
target = addDays(day, -1);
|
|
631
|
+
break;
|
|
632
|
+
case "ArrowRight":
|
|
633
|
+
target = addDays(day, 1);
|
|
634
|
+
break;
|
|
635
|
+
case "ArrowUp":
|
|
636
|
+
target = addDays(day, -7);
|
|
637
|
+
break;
|
|
638
|
+
case "ArrowDown":
|
|
639
|
+
target = addDays(day, 7);
|
|
640
|
+
break;
|
|
641
|
+
case "Home":
|
|
642
|
+
target = startOfWeek(day, { weekStartsOn });
|
|
643
|
+
break;
|
|
644
|
+
case "End":
|
|
645
|
+
target = endOfWeek(day, { weekStartsOn });
|
|
646
|
+
break;
|
|
647
|
+
case "PageUp":
|
|
648
|
+
target = addMonths(day, -1);
|
|
649
|
+
break;
|
|
650
|
+
case "PageDown":
|
|
651
|
+
target = addMonths(day, 1);
|
|
652
|
+
break;
|
|
653
|
+
case "Enter":
|
|
654
|
+
case " ":
|
|
655
|
+
event.preventDefault();
|
|
656
|
+
if (!isDateDisabled(day)) onDayPress?.(day);
|
|
657
|
+
return;
|
|
658
|
+
default:
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
event.preventDefault();
|
|
662
|
+
moveFocus(target);
|
|
663
|
+
},
|
|
664
|
+
[isDateDisabled, moveFocus, onDayPress, weekStartsOn]
|
|
665
|
+
);
|
|
666
|
+
return /* @__PURE__ */ jsxs2(Box, { testID, role: "grid", children: [
|
|
577
667
|
/* @__PURE__ */ jsx4(
|
|
578
668
|
Box,
|
|
579
669
|
{
|
|
670
|
+
role: "row",
|
|
580
671
|
flexDirection: "row",
|
|
581
672
|
justifyContent: "flex-start",
|
|
582
673
|
width: GRID_WIDTH,
|
|
583
674
|
marginBottom: 8,
|
|
584
|
-
children: weekDays.map((day, i) => /* @__PURE__ */ jsx4(
|
|
585
|
-
|
|
675
|
+
children: weekDays.map((day, i) => /* @__PURE__ */ jsx4(
|
|
676
|
+
Box,
|
|
586
677
|
{
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
children:
|
|
591
|
-
|
|
592
|
-
|
|
678
|
+
role: "columnheader",
|
|
679
|
+
width: DAY_CELL_WIDTH,
|
|
680
|
+
alignItems: "center",
|
|
681
|
+
children: /* @__PURE__ */ jsx4(
|
|
682
|
+
Text,
|
|
683
|
+
{
|
|
684
|
+
fontSize: 12,
|
|
685
|
+
fontWeight: "600",
|
|
686
|
+
color: theme.colors.content.tertiary,
|
|
687
|
+
children: day.toUpperCase()
|
|
688
|
+
}
|
|
689
|
+
)
|
|
690
|
+
},
|
|
691
|
+
i
|
|
692
|
+
))
|
|
593
693
|
}
|
|
594
694
|
),
|
|
595
695
|
/* @__PURE__ */ jsx4(Box, { gap: 2, children: weeks.map((week, i) => /* @__PURE__ */ jsx4(
|
|
596
696
|
Box,
|
|
597
697
|
{
|
|
698
|
+
role: "row",
|
|
598
699
|
flexDirection: "row",
|
|
599
700
|
justifyContent: "flex-start",
|
|
600
701
|
width: GRID_WIDTH,
|
|
601
702
|
children: week.map((day, j) => {
|
|
602
|
-
const dayKey =
|
|
703
|
+
const dayKey = dayKeyOf(day);
|
|
603
704
|
const isOutsideMonth = !isSameMonth(day, currentMonth);
|
|
604
705
|
const isSelected = !selectsRange && selectedDate && isSameDay(day, selectedDate) || selectsRange && startDate && endDate && isSameDay(day, startDate) && isSameDay(day, endDate);
|
|
605
706
|
const isRangeStart = selectsRange && startDate && isSameDay(day, startDate);
|
|
@@ -609,6 +710,7 @@ var CalendarGrid = ({
|
|
|
609
710
|
const disabled = isDateDisabled(day);
|
|
610
711
|
const isHoverable = !disabled && !isOutsideMonth && !isSelected && !isRangeStart && !isRangeEnd;
|
|
611
712
|
const isHovered = isHoverable && hoveredKey === dayKey;
|
|
713
|
+
const isTabStop = !isOutsideMonth && dayKey === tabStopKey;
|
|
612
714
|
let bgColor = "transparent";
|
|
613
715
|
let textColor = theme.colors.content.primary;
|
|
614
716
|
if (isSelected || isRangeStart || isRangeEnd || inRange) {
|
|
@@ -620,9 +722,23 @@ var CalendarGrid = ({
|
|
|
620
722
|
} else if (isOutsideMonth || disabled) {
|
|
621
723
|
textColor = theme.colors.control.text.disable;
|
|
622
724
|
}
|
|
725
|
+
const keyboardProps = isWeb && !isOutsideMonth ? {
|
|
726
|
+
ref: (node) => {
|
|
727
|
+
if (node) dayRefs.current.set(dayKey, node);
|
|
728
|
+
else dayRefs.current.delete(dayKey);
|
|
729
|
+
},
|
|
730
|
+
tabIndex: isTabStop ? 0 : -1,
|
|
731
|
+
onKeyDown: (event) => handleDayKeyDown(event, day)
|
|
732
|
+
} : {};
|
|
623
733
|
return /* @__PURE__ */ jsx4(
|
|
624
734
|
Box,
|
|
625
735
|
{
|
|
736
|
+
...keyboardProps,
|
|
737
|
+
role: "gridcell",
|
|
738
|
+
"aria-label": isOutsideMonth ? void 0 : format2(day, "EEEE, d MMMM yyyy", { locale: localeObj }),
|
|
739
|
+
"aria-selected": isOutsideMonth ? void 0 : Boolean(isSelected || isRangeStart || isRangeEnd),
|
|
740
|
+
"aria-disabled": disabled || isOutsideMonth || void 0,
|
|
741
|
+
"aria-current": today ? "date" : void 0,
|
|
626
742
|
width: DAY_CELL_WIDTH,
|
|
627
743
|
height: 32,
|
|
628
744
|
alignItems: "center",
|
|
@@ -633,7 +749,11 @@ var CalendarGrid = ({
|
|
|
633
749
|
borderBottomRightRadius: isSelected || isRangeEnd ? 4 : 0,
|
|
634
750
|
backgroundColor: bgColor,
|
|
635
751
|
cursor: disabled || isOutsideMonth ? "default" : "pointer",
|
|
636
|
-
onPress: () =>
|
|
752
|
+
onPress: () => {
|
|
753
|
+
if (disabled || isOutsideMonth) return;
|
|
754
|
+
setFocusedDate(day);
|
|
755
|
+
onDayPress?.(day);
|
|
756
|
+
},
|
|
637
757
|
onMouseEnter: () => isHoverable && setHoveredKey(dayKey),
|
|
638
758
|
onMouseLeave: () => setHoveredKey(
|
|
639
759
|
(current) => current === dayKey ? null : current
|
|
@@ -760,7 +880,7 @@ var Calendar = forwardRef(
|
|
|
760
880
|
const [selectedEndDate, setSelectedEndDate] = useState2(endDate);
|
|
761
881
|
const [locSelectedDate, setLocSelectedDate] = useState2(selectedDate);
|
|
762
882
|
const [selectingRange, setSelectingRange] = useState2(null);
|
|
763
|
-
|
|
883
|
+
useEffect2(() => {
|
|
764
884
|
setSelectedStartDate(startDate);
|
|
765
885
|
setSelectedEndDate(endDate);
|
|
766
886
|
setLocSelectedDate(selectedDate);
|
|
@@ -801,7 +921,7 @@ var Calendar = forwardRef(
|
|
|
801
921
|
[]
|
|
802
922
|
);
|
|
803
923
|
const increaseMonth = useCallback3(
|
|
804
|
-
() => setCurrentMonth((prev) =>
|
|
924
|
+
() => setCurrentMonth((prev) => addMonths2(prev, 1)),
|
|
805
925
|
[]
|
|
806
926
|
);
|
|
807
927
|
const changeMonth = useCallback3(
|
|
@@ -901,6 +1021,7 @@ var Calendar = forwardRef(
|
|
|
901
1021
|
selectedDate: locSelectedDate,
|
|
902
1022
|
selectingRange,
|
|
903
1023
|
onDayPress: handleChange,
|
|
1024
|
+
onMonthChange: setCurrentMonth,
|
|
904
1025
|
themeMode,
|
|
905
1026
|
themeProductContext
|
|
906
1027
|
}
|
|
@@ -915,10 +1036,10 @@ var Calendar = forwardRef(
|
|
|
915
1036
|
Calendar.displayName = "Calendar";
|
|
916
1037
|
|
|
917
1038
|
// src/DualCalendar.tsx
|
|
918
|
-
import { forwardRef as forwardRef2, useCallback as useCallback4, useEffect as
|
|
1039
|
+
import { forwardRef as forwardRef2, useCallback as useCallback4, useEffect as useEffect3, useState as useState3 } from "react";
|
|
919
1040
|
import { useResolvedTheme as useResolvedTheme4 } from "@xsolla/xui-core";
|
|
920
1041
|
import {
|
|
921
|
-
addMonths as
|
|
1042
|
+
addMonths as addMonths3,
|
|
922
1043
|
isSameMonth as isSameMonth2,
|
|
923
1044
|
subDays as subDays2,
|
|
924
1045
|
subMonths as subMonths2,
|
|
@@ -951,21 +1072,21 @@ var DualCalendar = forwardRef2(
|
|
|
951
1072
|
month || initialMonth || startDate || /* @__PURE__ */ new Date()
|
|
952
1073
|
);
|
|
953
1074
|
const [rightMonth, setRightMonth] = useState3(
|
|
954
|
-
() =>
|
|
1075
|
+
() => addMonths3(month || initialMonth || startDate || /* @__PURE__ */ new Date(), 1)
|
|
955
1076
|
);
|
|
956
1077
|
const [selectedStartDate, setSelectedStartDate] = useState3(startDate);
|
|
957
1078
|
const [selectedEndDate, setSelectedEndDate] = useState3(endDate);
|
|
958
1079
|
const [selectingRange, setSelectingRange] = useState3(null);
|
|
959
1080
|
const showFrom = useCallback4((date) => {
|
|
960
1081
|
setLeftMonth(date);
|
|
961
|
-
setRightMonth(
|
|
1082
|
+
setRightMonth(addMonths3(date, 1));
|
|
962
1083
|
}, []);
|
|
963
|
-
|
|
1084
|
+
useEffect3(() => {
|
|
964
1085
|
setSelectedStartDate(startDate);
|
|
965
1086
|
setSelectedEndDate(endDate);
|
|
966
1087
|
}, [startDate, endDate]);
|
|
967
1088
|
const monthKey = month ? month.getFullYear() * 12 + month.getMonth() : null;
|
|
968
|
-
|
|
1089
|
+
useEffect3(() => {
|
|
969
1090
|
if (!month) return;
|
|
970
1091
|
if (isSameMonth2(month, leftMonth) || isSameMonth2(month, rightMonth)) {
|
|
971
1092
|
return;
|
|
@@ -1028,7 +1149,7 @@ var DualCalendar = forwardRef2(
|
|
|
1028
1149
|
[]
|
|
1029
1150
|
);
|
|
1030
1151
|
const increaseLeftMonth = useCallback4(
|
|
1031
|
-
() => setLeftMonth((prev) =>
|
|
1152
|
+
() => setLeftMonth((prev) => addMonths3(prev, 1)),
|
|
1032
1153
|
[]
|
|
1033
1154
|
);
|
|
1034
1155
|
const changeLeftMonth = useCallback4(
|
|
@@ -1044,7 +1165,7 @@ var DualCalendar = forwardRef2(
|
|
|
1044
1165
|
[]
|
|
1045
1166
|
);
|
|
1046
1167
|
const increaseRightMonth = useCallback4(
|
|
1047
|
-
() => setRightMonth((prev) =>
|
|
1168
|
+
() => setRightMonth((prev) => addMonths3(prev, 1)),
|
|
1048
1169
|
[]
|
|
1049
1170
|
);
|
|
1050
1171
|
const changeRightMonth = useCallback4(
|