@xsolla/xui-date-picker 0.225.0 → 0.226.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.js
CHANGED
|
@@ -663,6 +663,7 @@ var getFixedPlacementStyle = (side, align, container, panel, viewport, offset) =
|
|
|
663
663
|
const vertical = align === "center" ? { top: (container.top + container.bottom) / 2 - panel.height / 2 } : align === "end" ? { bottom: viewport.height - container.bottom } : { top: container.top };
|
|
664
664
|
return { position: "fixed", ...horizontal, ...vertical };
|
|
665
665
|
};
|
|
666
|
+
var isSegmentKey = (key) => /^[0-9]$/.test(key) || key === "Backspace" || key === "ArrowUp" || key === "ArrowDown" || key === "ArrowLeft" || key === "ArrowRight";
|
|
666
667
|
var DatePicker = (0, import_react4.forwardRef)(
|
|
667
668
|
({
|
|
668
669
|
onChange,
|
|
@@ -727,6 +728,7 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
727
728
|
const [activeSegment, setActiveSegment] = (0, import_react4.useState)(null);
|
|
728
729
|
const [internalChip, setInternalChip] = (0, import_react4.useState)(null);
|
|
729
730
|
const [parseError, setParseError] = (0, import_react4.useState)(null);
|
|
731
|
+
const [rawText, setRawText] = (0, import_react4.useState)(null);
|
|
730
732
|
const [fixedPosition, setFixedPosition] = (0, import_react4.useState)(
|
|
731
733
|
null
|
|
732
734
|
);
|
|
@@ -803,7 +805,7 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
803
805
|
(g) => g.day != null || g.month != null || g.year != null
|
|
804
806
|
);
|
|
805
807
|
const showMask = hasAnyFilled || focused && isWeb;
|
|
806
|
-
const inputValue = chipLabel ?? (showMask ? composed.text : "");
|
|
808
|
+
const inputValue = rawText ?? chipLabel ?? (showMask ? composed.text : "");
|
|
807
809
|
const showClear = clearable && editable && (hasAnyFilled || !!chipLabel);
|
|
808
810
|
const orderedSegments = () => composeField().segments;
|
|
809
811
|
const firstSegmentKey = () => {
|
|
@@ -872,6 +874,60 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
872
874
|
commitPart(edit.group, edit.type, Number(edit.buffer));
|
|
873
875
|
setEdit(null);
|
|
874
876
|
};
|
|
877
|
+
const parseOne = (token) => {
|
|
878
|
+
const trimmed = token.trim();
|
|
879
|
+
if (!trimmed) return null;
|
|
880
|
+
const parsed = (0, import_date_fns.parse)(trimmed, resolvedFormat, /* @__PURE__ */ new Date());
|
|
881
|
+
return (0, import_date_fns.isValid)(parsed) ? parsed : null;
|
|
882
|
+
};
|
|
883
|
+
const parseFieldText = (text) => {
|
|
884
|
+
if (isRange) {
|
|
885
|
+
const [startText, endText] = text.split(RANGE_SEPARATOR);
|
|
886
|
+
const start = parseOne(startText ?? "");
|
|
887
|
+
const end = parseOne(endText ?? "");
|
|
888
|
+
if (!start || endText?.trim() && !end) {
|
|
889
|
+
return {
|
|
890
|
+
error: `Enter a valid date range (${resolvedFormat} - ${resolvedFormat})`
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
return { parts: [datePartsFromDate(start), datePartsFromDate(end)] };
|
|
894
|
+
}
|
|
895
|
+
const date = parseOne(text);
|
|
896
|
+
if (!date) return { error: `Enter a valid date (${resolvedFormat})` };
|
|
897
|
+
return { parts: [datePartsFromDate(date)] };
|
|
898
|
+
};
|
|
899
|
+
const isOutOfBounds = (parts) => parts.map(datePartsToDate).some((d) => d instanceof Date && !isWithinBounds(d));
|
|
900
|
+
const commitRawText = (text) => {
|
|
901
|
+
setEdit(null);
|
|
902
|
+
if (!text.trim()) {
|
|
903
|
+
setRawText(null);
|
|
904
|
+
setParseError(null);
|
|
905
|
+
setGroups(propGroups());
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
const result = parseFieldText(text);
|
|
909
|
+
if ("error" in result) {
|
|
910
|
+
setParseError(result.error);
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
if (isOutOfBounds(result.parts)) {
|
|
914
|
+
setParseError("Date must be within the allowed range");
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
setRawText(null);
|
|
918
|
+
setParseError(null);
|
|
919
|
+
setGroups(result.parts);
|
|
920
|
+
emit(result.parts);
|
|
921
|
+
};
|
|
922
|
+
const handleChangeText = (text) => {
|
|
923
|
+
rest.onChangeText?.(text);
|
|
924
|
+
if (!editable) return;
|
|
925
|
+
markDirty();
|
|
926
|
+
setEdit(null);
|
|
927
|
+
setParseError(null);
|
|
928
|
+
setActiveSegment(null);
|
|
929
|
+
setRawText(text);
|
|
930
|
+
};
|
|
875
931
|
const defaultPart = (type) => {
|
|
876
932
|
const now = /* @__PURE__ */ new Date();
|
|
877
933
|
if (type === "day") return now.getDate();
|
|
@@ -964,10 +1020,12 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
964
1020
|
}
|
|
965
1021
|
if (!isWeb || !editable) return;
|
|
966
1022
|
if (e.key === "Enter") {
|
|
967
|
-
|
|
1023
|
+
if (rawText !== null) commitRawText(rawText);
|
|
1024
|
+
else commitBuffer();
|
|
968
1025
|
setOpen(false);
|
|
969
1026
|
return;
|
|
970
1027
|
}
|
|
1028
|
+
if (rawText !== null && isSegmentKey(e.key)) setRawText(null);
|
|
971
1029
|
if (e.key === "ArrowUp") return handleArrowStep(e, 1);
|
|
972
1030
|
if (e.key === "ArrowDown") return handleArrowStep(e, -1);
|
|
973
1031
|
if (e.key === "ArrowLeft") return handleArrowMove(e, -1);
|
|
@@ -1020,30 +1078,33 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
1020
1078
|
setParseError(null);
|
|
1021
1079
|
return;
|
|
1022
1080
|
}
|
|
1081
|
+
if (rawText !== null) {
|
|
1082
|
+
commitRawText(rawText);
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1023
1085
|
let next = groups;
|
|
1086
|
+
let rejected = false;
|
|
1024
1087
|
if (edit) {
|
|
1025
1088
|
const clamped = clampDatePart(
|
|
1026
1089
|
edit.type,
|
|
1027
1090
|
Number(edit.buffer),
|
|
1028
1091
|
groups[edit.group]
|
|
1029
1092
|
);
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
)
|
|
1093
|
+
const edited = { ...groups[edit.group], [edit.type]: clamped };
|
|
1094
|
+
const assembled = datePartsToDate(edited);
|
|
1095
|
+
if (assembled && !isWithinBounds(assembled)) {
|
|
1096
|
+
rejected = true;
|
|
1097
|
+
} else {
|
|
1098
|
+
next = groups.map((g, i) => i === edit.group ? edited : g);
|
|
1099
|
+
}
|
|
1033
1100
|
}
|
|
1034
1101
|
const props = propGroups();
|
|
1035
1102
|
next = next.map((g, i) => isDatePartsComplete(g) ? g : props[i]);
|
|
1036
1103
|
setEdit(null);
|
|
1037
|
-
setParseError(null);
|
|
1104
|
+
setParseError(rejected ? "Date must be within the allowed range" : null);
|
|
1038
1105
|
setGroups(next);
|
|
1039
1106
|
emit(next);
|
|
1040
1107
|
};
|
|
1041
|
-
const parseOne = (token) => {
|
|
1042
|
-
const trimmed = token.trim();
|
|
1043
|
-
if (!trimmed) return null;
|
|
1044
|
-
const parsed = (0, import_date_fns.parse)(trimmed, resolvedFormat, /* @__PURE__ */ new Date());
|
|
1045
|
-
return (0, import_date_fns.isValid)(parsed) ? parsed : null;
|
|
1046
|
-
};
|
|
1047
1108
|
const handlePaste = (e) => {
|
|
1048
1109
|
onPasteProp?.(e);
|
|
1049
1110
|
if (e.defaultPrevented) return;
|
|
@@ -1051,34 +1112,20 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
1051
1112
|
const text = e.clipboardData?.getData("text") ?? "";
|
|
1052
1113
|
if (!text.trim()) return;
|
|
1053
1114
|
e.preventDefault();
|
|
1054
|
-
|
|
1055
|
-
if (
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
const end = parseOne(endText ?? "");
|
|
1059
|
-
if (!start) {
|
|
1060
|
-
setParseError(
|
|
1061
|
-
`Enter a valid date range (${resolvedFormat} - ${resolvedFormat})`
|
|
1062
|
-
);
|
|
1063
|
-
return;
|
|
1064
|
-
}
|
|
1065
|
-
next = [datePartsFromDate(start), datePartsFromDate(end)];
|
|
1066
|
-
} else {
|
|
1067
|
-
const date = parseOne(text);
|
|
1068
|
-
if (!date) {
|
|
1069
|
-
setParseError(`Enter a valid date (${resolvedFormat})`);
|
|
1070
|
-
return;
|
|
1071
|
-
}
|
|
1072
|
-
next = [datePartsFromDate(date)];
|
|
1115
|
+
const result = parseFieldText(text);
|
|
1116
|
+
if ("error" in result) {
|
|
1117
|
+
setParseError(result.error);
|
|
1118
|
+
return;
|
|
1073
1119
|
}
|
|
1074
|
-
const
|
|
1075
|
-
if (
|
|
1120
|
+
const next = result.parts;
|
|
1121
|
+
if (isOutOfBounds(next)) {
|
|
1076
1122
|
setParseError("Date must be within the allowed range");
|
|
1077
1123
|
return;
|
|
1078
1124
|
}
|
|
1079
1125
|
markDirty();
|
|
1080
1126
|
setParseError(null);
|
|
1081
1127
|
setEdit(null);
|
|
1128
|
+
setRawText(null);
|
|
1082
1129
|
setGroups(next);
|
|
1083
1130
|
emit(next);
|
|
1084
1131
|
};
|
|
@@ -1093,6 +1140,7 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
1093
1140
|
sessionRef.current.cleared = true;
|
|
1094
1141
|
setGroups(next);
|
|
1095
1142
|
setEdit(null);
|
|
1143
|
+
setRawText(null);
|
|
1096
1144
|
setParseError(null);
|
|
1097
1145
|
setInternalChip(null);
|
|
1098
1146
|
onChipSelect?.(null);
|
|
@@ -1112,6 +1160,7 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
1112
1160
|
sessionRef.current = { dirty: false, cleared: false, propKey };
|
|
1113
1161
|
setGroups(propGroups());
|
|
1114
1162
|
setEdit(null);
|
|
1163
|
+
setRawText(null);
|
|
1115
1164
|
setParseError(null);
|
|
1116
1165
|
}, [propKey]);
|
|
1117
1166
|
(0, import_react4.useEffect)(() => {
|
|
@@ -1309,6 +1358,7 @@ var DatePicker = (0, import_react4.forwardRef)(
|
|
|
1309
1358
|
onKeyDown: handleKeyDown,
|
|
1310
1359
|
onClick: handleFieldClick,
|
|
1311
1360
|
onPaste: handlePaste,
|
|
1361
|
+
onChangeText: handleChangeText,
|
|
1312
1362
|
iconRight,
|
|
1313
1363
|
iconLeft,
|
|
1314
1364
|
extraClear: showClear,
|