@xsolla/xui-date-picker 0.225.0 → 0.227.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 +6 -0
- package/native/index.js +83 -33
- package/native/index.js.map +1 -1
- package/native/index.mjs +83 -33
- package/native/index.mjs.map +1 -1
- package/package.json +6 -6
- package/web/index.js +83 -33
- package/web/index.js.map +1 -1
- package/web/index.mjs +83 -33
- package/web/index.mjs.map +1 -1
package/web/index.mjs
CHANGED
|
@@ -622,6 +622,7 @@ var getFixedPlacementStyle = (side, align, container, panel, viewport, offset) =
|
|
|
622
622
|
const vertical = align === "center" ? { top: (container.top + container.bottom) / 2 - panel.height / 2 } : align === "end" ? { bottom: viewport.height - container.bottom } : { top: container.top };
|
|
623
623
|
return { position: "fixed", ...horizontal, ...vertical };
|
|
624
624
|
};
|
|
625
|
+
var isSegmentKey = (key) => /^[0-9]$/.test(key) || key === "Backspace" || key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight";
|
|
625
626
|
var DatePicker = forwardRef(
|
|
626
627
|
({
|
|
627
628
|
onChange,
|
|
@@ -686,6 +687,7 @@ var DatePicker = forwardRef(
|
|
|
686
687
|
const [activeSegment, setActiveSegment] = useState2(null);
|
|
687
688
|
const [internalChip, setInternalChip] = useState2(null);
|
|
688
689
|
const [parseError, setParseError] = useState2(null);
|
|
690
|
+
const [rawText, setRawText] = useState2(null);
|
|
689
691
|
const [fixedPosition, setFixedPosition] = useState2(
|
|
690
692
|
null
|
|
691
693
|
);
|
|
@@ -762,7 +764,7 @@ var DatePicker = forwardRef(
|
|
|
762
764
|
(g) => g.day != null || g.month != null || g.year != null
|
|
763
765
|
);
|
|
764
766
|
const showMask = hasAnyFilled || focused && isWeb;
|
|
765
|
-
const inputValue = chipLabel ?? (showMask ? composed.text : "");
|
|
767
|
+
const inputValue = rawText ?? chipLabel ?? (showMask ? composed.text : "");
|
|
766
768
|
const showClear = clearable && editable && (hasAnyFilled || !!chipLabel);
|
|
767
769
|
const orderedSegments = () => composeField().segments;
|
|
768
770
|
const firstSegmentKey = () => {
|
|
@@ -831,6 +833,60 @@ var DatePicker = forwardRef(
|
|
|
831
833
|
commitPart(edit.group, edit.type, Number(edit.buffer));
|
|
832
834
|
setEdit(null);
|
|
833
835
|
};
|
|
836
|
+
const parseOne = (token) => {
|
|
837
|
+
const trimmed = token.trim();
|
|
838
|
+
if (!trimmed) return null;
|
|
839
|
+
const parsed = parse(trimmed, resolvedFormat, /* @__PURE__ */ new Date());
|
|
840
|
+
return isValid(parsed) ? parsed : null;
|
|
841
|
+
};
|
|
842
|
+
const parseFieldText = (text) => {
|
|
843
|
+
if (isRange) {
|
|
844
|
+
const [startText, endText] = text.split(RANGE_SEPARATOR);
|
|
845
|
+
const start = parseOne(startText ?? "");
|
|
846
|
+
const end = parseOne(endText ?? "");
|
|
847
|
+
if (!start || endText?.trim() && !end) {
|
|
848
|
+
return {
|
|
849
|
+
error: `Enter a valid date range (${resolvedFormat} - ${resolvedFormat})`
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
return { parts: [datePartsFromDate(start), datePartsFromDate(end)] };
|
|
853
|
+
}
|
|
854
|
+
const date = parseOne(text);
|
|
855
|
+
if (!date) return { error: `Enter a valid date (${resolvedFormat})` };
|
|
856
|
+
return { parts: [datePartsFromDate(date)] };
|
|
857
|
+
};
|
|
858
|
+
const isOutOfBounds = (parts) => parts.map(datePartsToDate).some((d) => d instanceof Date && !isWithinBounds(d));
|
|
859
|
+
const commitRawText = (text) => {
|
|
860
|
+
setEdit(null);
|
|
861
|
+
if (!text.trim()) {
|
|
862
|
+
setRawText(null);
|
|
863
|
+
setParseError(null);
|
|
864
|
+
setGroups(propGroups());
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const result = parseFieldText(text);
|
|
868
|
+
if ("error" in result) {
|
|
869
|
+
setParseError(result.error);
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
if (isOutOfBounds(result.parts)) {
|
|
873
|
+
setParseError("Date must be within the allowed range");
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
setRawText(null);
|
|
877
|
+
setParseError(null);
|
|
878
|
+
setGroups(result.parts);
|
|
879
|
+
emit(result.parts);
|
|
880
|
+
};
|
|
881
|
+
const handleChangeText = (text) => {
|
|
882
|
+
rest.onChangeText?.(text);
|
|
883
|
+
if (!editable) return;
|
|
884
|
+
markDirty();
|
|
885
|
+
setEdit(null);
|
|
886
|
+
setParseError(null);
|
|
887
|
+
setActiveSegment(null);
|
|
888
|
+
setRawText(text);
|
|
889
|
+
};
|
|
834
890
|
const defaultPart = (type) => {
|
|
835
891
|
const now = /* @__PURE__ */ new Date();
|
|
836
892
|
if (type === "day") return now.getDate();
|
|
@@ -923,10 +979,12 @@ var DatePicker = forwardRef(
|
|
|
923
979
|
}
|
|
924
980
|
if (!isWeb || !editable) return;
|
|
925
981
|
if (e.key === "Enter") {
|
|
926
|
-
|
|
982
|
+
if (rawText !== null) commitRawText(rawText);
|
|
983
|
+
else commitBuffer();
|
|
927
984
|
setOpen(false);
|
|
928
985
|
return;
|
|
929
986
|
}
|
|
987
|
+
if (rawText !== null && isSegmentKey(e.key)) setRawText(null);
|
|
930
988
|
if (e.key === "ArrowUp") return handleArrowStep(e, 1);
|
|
931
989
|
if (e.key === "ArrowDown") return handleArrowStep(e, -1);
|
|
932
990
|
if (e.key === "ArrowLeft") return handleArrowMove(e, -1);
|
|
@@ -979,30 +1037,33 @@ var DatePicker = forwardRef(
|
|
|
979
1037
|
setParseError(null);
|
|
980
1038
|
return;
|
|
981
1039
|
}
|
|
1040
|
+
if (rawText !== null) {
|
|
1041
|
+
commitRawText(rawText);
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
982
1044
|
let next = groups;
|
|
1045
|
+
let rejected = false;
|
|
983
1046
|
if (edit) {
|
|
984
1047
|
const clamped = clampDatePart(
|
|
985
1048
|
edit.type,
|
|
986
1049
|
Number(edit.buffer),
|
|
987
1050
|
groups[edit.group]
|
|
988
1051
|
);
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
)
|
|
1052
|
+
const edited = { ...groups[edit.group], [edit.type]: clamped };
|
|
1053
|
+
const assembled = datePartsToDate(edited);
|
|
1054
|
+
if (assembled && !isWithinBounds(assembled)) {
|
|
1055
|
+
rejected = true;
|
|
1056
|
+
} else {
|
|
1057
|
+
next = groups.map((g, i) => i === edit.group ? edited : g);
|
|
1058
|
+
}
|
|
992
1059
|
}
|
|
993
1060
|
const props = propGroups();
|
|
994
1061
|
next = next.map((g, i) => isDatePartsComplete(g) ? g : props[i]);
|
|
995
1062
|
setEdit(null);
|
|
996
|
-
setParseError(null);
|
|
1063
|
+
setParseError(rejected ? "Date must be within the allowed range" : null);
|
|
997
1064
|
setGroups(next);
|
|
998
1065
|
emit(next);
|
|
999
1066
|
};
|
|
1000
|
-
const parseOne = (token) => {
|
|
1001
|
-
const trimmed = token.trim();
|
|
1002
|
-
if (!trimmed) return null;
|
|
1003
|
-
const parsed = parse(trimmed, resolvedFormat, /* @__PURE__ */ new Date());
|
|
1004
|
-
return isValid(parsed) ? parsed : null;
|
|
1005
|
-
};
|
|
1006
1067
|
const handlePaste = (e) => {
|
|
1007
1068
|
onPasteProp?.(e);
|
|
1008
1069
|
if (e.defaultPrevented) return;
|
|
@@ -1010,34 +1071,20 @@ var DatePicker = forwardRef(
|
|
|
1010
1071
|
const text = e.clipboardData?.getData("text") ?? "";
|
|
1011
1072
|
if (!text.trim()) return;
|
|
1012
1073
|
e.preventDefault();
|
|
1013
|
-
|
|
1014
|
-
if (
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
const end = parseOne(endText ?? "");
|
|
1018
|
-
if (!start) {
|
|
1019
|
-
setParseError(
|
|
1020
|
-
`Enter a valid date range (${resolvedFormat} - ${resolvedFormat})`
|
|
1021
|
-
);
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
1024
|
-
next = [datePartsFromDate(start), datePartsFromDate(end)];
|
|
1025
|
-
} else {
|
|
1026
|
-
const date = parseOne(text);
|
|
1027
|
-
if (!date) {
|
|
1028
|
-
setParseError(`Enter a valid date (${resolvedFormat})`);
|
|
1029
|
-
return;
|
|
1030
|
-
}
|
|
1031
|
-
next = [datePartsFromDate(date)];
|
|
1074
|
+
const result = parseFieldText(text);
|
|
1075
|
+
if ("error" in result) {
|
|
1076
|
+
setParseError(result.error);
|
|
1077
|
+
return;
|
|
1032
1078
|
}
|
|
1033
|
-
const
|
|
1034
|
-
if (
|
|
1079
|
+
const next = result.parts;
|
|
1080
|
+
if (isOutOfBounds(next)) {
|
|
1035
1081
|
setParseError("Date must be within the allowed range");
|
|
1036
1082
|
return;
|
|
1037
1083
|
}
|
|
1038
1084
|
markDirty();
|
|
1039
1085
|
setParseError(null);
|
|
1040
1086
|
setEdit(null);
|
|
1087
|
+
setRawText(null);
|
|
1041
1088
|
setGroups(next);
|
|
1042
1089
|
emit(next);
|
|
1043
1090
|
};
|
|
@@ -1052,6 +1099,7 @@ var DatePicker = forwardRef(
|
|
|
1052
1099
|
sessionRef.current.cleared = true;
|
|
1053
1100
|
setGroups(next);
|
|
1054
1101
|
setEdit(null);
|
|
1102
|
+
setRawText(null);
|
|
1055
1103
|
setParseError(null);
|
|
1056
1104
|
setInternalChip(null);
|
|
1057
1105
|
onChipSelect?.(null);
|
|
@@ -1071,6 +1119,7 @@ var DatePicker = forwardRef(
|
|
|
1071
1119
|
sessionRef.current = { dirty: false, cleared: false, propKey };
|
|
1072
1120
|
setGroups(propGroups());
|
|
1073
1121
|
setEdit(null);
|
|
1122
|
+
setRawText(null);
|
|
1074
1123
|
setParseError(null);
|
|
1075
1124
|
}, [propKey]);
|
|
1076
1125
|
useEffect2(() => {
|
|
@@ -1268,6 +1317,7 @@ var DatePicker = forwardRef(
|
|
|
1268
1317
|
onKeyDown: handleKeyDown,
|
|
1269
1318
|
onClick: handleFieldClick,
|
|
1270
1319
|
onPaste: handlePaste,
|
|
1320
|
+
onChangeText: handleChangeText,
|
|
1271
1321
|
iconRight,
|
|
1272
1322
|
iconLeft,
|
|
1273
1323
|
extraClear: showClear,
|