@xsolla/xui-date-picker 0.218.1 → 0.220.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 +39 -1
- package/native/index.d.mts +29 -0
- package/native/index.d.ts +29 -0
- package/native/index.js +58 -1
- package/native/index.js.map +1 -1
- package/native/index.mjs +58 -1
- package/native/index.mjs.map +1 -1
- package/package.json +6 -6
- package/web/index.d.mts +29 -0
- package/web/index.d.ts +29 -0
- package/web/index.js +61 -3
- package/web/index.js.map +1 -1
- package/web/index.mjs +61 -3
- package/web/index.mjs.map +1 -1
package/web/index.js
CHANGED
|
@@ -107,6 +107,10 @@ var ADDITIONAL_BLOCKED_PROPS = /* @__PURE__ */ new Set([
|
|
|
107
107
|
"fontWeight",
|
|
108
108
|
"fontFamily",
|
|
109
109
|
"textDecoration",
|
|
110
|
+
// `display` is a presentation attribute on SVG, so isPropValid lets it
|
|
111
|
+
// through — but Box consumes it purely as CSS. Without this it lands on the
|
|
112
|
+
// DOM node as a bogus `display="inline-flex"` attribute.
|
|
113
|
+
"display",
|
|
110
114
|
// Cross-platform layout prop that Text consumes as CSS, never as an
|
|
111
115
|
// attribute. Pinned explicitly because it is now spread into the styled
|
|
112
116
|
// component rather than destructured away before it can reach the DOM.
|
|
@@ -141,7 +145,7 @@ function createFilteredElement(defaultTag) {
|
|
|
141
145
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
142
146
|
var FilteredDiv = createFilteredElement("div");
|
|
143
147
|
var StyledBox = (0, import_styled_components.default)(FilteredDiv)`
|
|
144
|
-
display: flex;
|
|
148
|
+
display: ${(props) => props.display || "flex"};
|
|
145
149
|
box-sizing: border-box;
|
|
146
150
|
background-color: ${(props) => props.backgroundColor || "transparent"};
|
|
147
151
|
border-color: ${(props) => props.borderColor || "transparent"};
|
|
@@ -277,7 +281,7 @@ var Box = import_react2.default.forwardRef(
|
|
|
277
281
|
onLoad,
|
|
278
282
|
"data-testid": dataTestId || testID,
|
|
279
283
|
style: {
|
|
280
|
-
display: "block",
|
|
284
|
+
display: props.display || "block",
|
|
281
285
|
objectFit: "cover",
|
|
282
286
|
width: typeof props.width === "number" ? `${props.width}px` : props.width,
|
|
283
287
|
height: typeof props.height === "number" ? `${props.height}px` : props.height,
|
|
@@ -677,6 +681,9 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
677
681
|
overlayThemeProductContext,
|
|
678
682
|
iconRight = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CalendarFieldIcon, {}),
|
|
679
683
|
iconLeft,
|
|
684
|
+
label,
|
|
685
|
+
clearable = false,
|
|
686
|
+
onClear,
|
|
680
687
|
error,
|
|
681
688
|
errorMessage,
|
|
682
689
|
readOnly,
|
|
@@ -698,6 +705,7 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
698
705
|
() => isRange ? [datePartsFromDate(startDate), datePartsFromDate(endDate)] : [datePartsFromDate(selectedDate)],
|
|
699
706
|
[isRange, startDate, endDate, selectedDate]
|
|
700
707
|
);
|
|
708
|
+
const propKey = `${selectedDate?.getTime() ?? ""}|${startDate?.getTime() ?? ""}|${endDate?.getTime() ?? ""}|${isRange}`;
|
|
701
709
|
const [open, setOpen] = (0, import_react3.useState)(false);
|
|
702
710
|
const [groups, setGroups] = (0, import_react3.useState)(propGroups);
|
|
703
711
|
const [edit, setEdit] = (0, import_react3.useState)(null);
|
|
@@ -713,6 +721,15 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
713
721
|
const inputRef = (0, import_react3.useRef)(null);
|
|
714
722
|
const chipSelectionRef = (0, import_react3.useRef)(false);
|
|
715
723
|
const suppressReopenRef = (0, import_react3.useRef)(false);
|
|
724
|
+
const sessionRef = (0, import_react3.useRef)({
|
|
725
|
+
dirty: false,
|
|
726
|
+
cleared: false,
|
|
727
|
+
propKey
|
|
728
|
+
});
|
|
729
|
+
const markDirty = () => {
|
|
730
|
+
sessionRef.current.dirty = true;
|
|
731
|
+
sessionRef.current.cleared = false;
|
|
732
|
+
};
|
|
716
733
|
const activeChipValue = activeChip !== void 0 ? activeChip : internalChip;
|
|
717
734
|
const chipLabel = showChipLabel && activeChipValue && chips ? chips.find((c) => c.value === activeChipValue)?.label : void 0;
|
|
718
735
|
const isWithinBounds = (date) => {
|
|
@@ -772,6 +789,7 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
772
789
|
);
|
|
773
790
|
const showMask = hasAnyFilled || focused && isWeb;
|
|
774
791
|
const inputValue = chipLabel ?? (showMask ? composed.text : "");
|
|
792
|
+
const showClear = clearable && editable && (hasAnyFilled || !!chipLabel);
|
|
775
793
|
const orderedSegments = () => composeField().segments;
|
|
776
794
|
const firstSegmentKey = () => {
|
|
777
795
|
const first = orderedSegments()[0];
|
|
@@ -814,6 +832,7 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
814
832
|
if (start || end) applySelection([start, end], false);
|
|
815
833
|
};
|
|
816
834
|
const commitPart = (group, type, rawValue) => {
|
|
835
|
+
markDirty();
|
|
817
836
|
const clamped = clampDatePart(type, rawValue, groups[group]);
|
|
818
837
|
const next = groups.map((g, i) => {
|
|
819
838
|
if (i !== group) return g;
|
|
@@ -862,6 +881,7 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
862
881
|
setEdit(null);
|
|
863
882
|
if (committed !== null) advance(active);
|
|
864
883
|
} else {
|
|
884
|
+
markDirty();
|
|
865
885
|
setEdit({ group: active.group, type: active.type, buffer });
|
|
866
886
|
}
|
|
867
887
|
};
|
|
@@ -899,6 +919,7 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
899
919
|
e.preventDefault();
|
|
900
920
|
const active = activeSegment ?? firstSegmentKey();
|
|
901
921
|
if (!active) return;
|
|
922
|
+
markDirty();
|
|
902
923
|
const sameActive = edit && edit.group === active.group && edit.type === active.type;
|
|
903
924
|
if (sameActive && edit.buffer.length > 0) {
|
|
904
925
|
const buffer = edit.buffer.slice(0, -1);
|
|
@@ -950,6 +971,11 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
950
971
|
suppressReopenRef.current = false;
|
|
951
972
|
return;
|
|
952
973
|
}
|
|
974
|
+
sessionRef.current = {
|
|
975
|
+
dirty: false,
|
|
976
|
+
cleared: sessionRef.current.cleared,
|
|
977
|
+
propKey
|
|
978
|
+
};
|
|
953
979
|
setFocused(true);
|
|
954
980
|
setOpen(true);
|
|
955
981
|
if (isWeb && editable) setActiveSegment(firstSegmentKey());
|
|
@@ -966,7 +992,19 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
966
992
|
onBlurProp?.(e);
|
|
967
993
|
setFocused(false);
|
|
968
994
|
setActiveSegment(null);
|
|
995
|
+
if (sessionRef.current.propKey !== propKey && !sessionRef.current.dirty) {
|
|
996
|
+
sessionRef.current = { dirty: false, cleared: false, propKey };
|
|
997
|
+
setEdit(null);
|
|
998
|
+
setParseError(null);
|
|
999
|
+
setGroups(propGroups());
|
|
1000
|
+
return;
|
|
1001
|
+
}
|
|
969
1002
|
if (!editable) return;
|
|
1003
|
+
if (sessionRef.current.cleared && !sessionRef.current.dirty) {
|
|
1004
|
+
setEdit(null);
|
|
1005
|
+
setParseError(null);
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
970
1008
|
let next = groups;
|
|
971
1009
|
if (edit) {
|
|
972
1010
|
const clamped = clampDatePart(
|
|
@@ -1023,6 +1061,7 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
1023
1061
|
setParseError("Date must be within the allowed range");
|
|
1024
1062
|
return;
|
|
1025
1063
|
}
|
|
1064
|
+
markDirty();
|
|
1026
1065
|
setParseError(null);
|
|
1027
1066
|
setEdit(null);
|
|
1028
1067
|
setGroups(next);
|
|
@@ -1033,13 +1072,29 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
1033
1072
|
setInternalChip(value);
|
|
1034
1073
|
onChipSelect?.(value);
|
|
1035
1074
|
};
|
|
1075
|
+
const handleClear = () => {
|
|
1076
|
+
const next = isRange ? [datePartsFromDate(null), datePartsFromDate(null)] : [datePartsFromDate(null)];
|
|
1077
|
+
sessionRef.current.dirty = false;
|
|
1078
|
+
sessionRef.current.cleared = true;
|
|
1079
|
+
setGroups(next);
|
|
1080
|
+
setEdit(null);
|
|
1081
|
+
setParseError(null);
|
|
1082
|
+
setInternalChip(null);
|
|
1083
|
+
onChipSelect?.(null);
|
|
1084
|
+
if (isWeb && editable) setActiveSegment(firstSegmentKey());
|
|
1085
|
+
onClear?.();
|
|
1086
|
+
if (isRange) {
|
|
1087
|
+
const emptyRange = [null, null];
|
|
1088
|
+
onChange?.(emptyRange);
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1036
1091
|
const handleDateChange = (date) => applySelection(date, closeOnComplete);
|
|
1037
1092
|
const closePanel = (0, import_react3.useCallback)(() => setOpen(false), []);
|
|
1038
1093
|
const renderTopContent = topContent ? () => topContent({ close: closePanel }) : void 0;
|
|
1039
1094
|
const renderBottomContent = bottomContent ? () => bottomContent({ close: closePanel }) : void 0;
|
|
1040
|
-
const propKey = `${selectedDate?.getTime() ?? ""}|${startDate?.getTime() ?? ""}|${endDate?.getTime() ?? ""}|${isRange}`;
|
|
1041
1095
|
(0, import_react3.useEffect)(() => {
|
|
1042
1096
|
if (focused) return;
|
|
1097
|
+
sessionRef.current = { dirty: false, cleared: false, propKey };
|
|
1043
1098
|
setGroups(propGroups());
|
|
1044
1099
|
setEdit(null);
|
|
1045
1100
|
setParseError(null);
|
|
@@ -1216,6 +1271,7 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
1216
1271
|
...rest,
|
|
1217
1272
|
ref: inputRef,
|
|
1218
1273
|
size,
|
|
1274
|
+
label,
|
|
1219
1275
|
placeholder: placeholder || (isRange ? "Choose a date range" : "Choose a date"),
|
|
1220
1276
|
value: inputValue,
|
|
1221
1277
|
readOnly,
|
|
@@ -1226,6 +1282,8 @@ var DatePicker = (0, import_react3.forwardRef)(
|
|
|
1226
1282
|
onPaste: handlePaste,
|
|
1227
1283
|
iconRight,
|
|
1228
1284
|
iconLeft,
|
|
1285
|
+
extraClear: showClear,
|
|
1286
|
+
onRemove: handleClear,
|
|
1229
1287
|
error: error || !!parseError,
|
|
1230
1288
|
errorMessage: parseError ?? errorMessage,
|
|
1231
1289
|
backgroundColor,
|