@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.mjs
CHANGED
|
@@ -66,6 +66,10 @@ var ADDITIONAL_BLOCKED_PROPS = /* @__PURE__ */ new Set([
|
|
|
66
66
|
"fontWeight",
|
|
67
67
|
"fontFamily",
|
|
68
68
|
"textDecoration",
|
|
69
|
+
// `display` is a presentation attribute on SVG, so isPropValid lets it
|
|
70
|
+
// through — but Box consumes it purely as CSS. Without this it lands on the
|
|
71
|
+
// DOM node as a bogus `display="inline-flex"` attribute.
|
|
72
|
+
"display",
|
|
69
73
|
// Cross-platform layout prop that Text consumes as CSS, never as an
|
|
70
74
|
// attribute. Pinned explicitly because it is now spread into the styled
|
|
71
75
|
// component rather than destructured away before it can reach the DOM.
|
|
@@ -100,7 +104,7 @@ function createFilteredElement(defaultTag) {
|
|
|
100
104
|
import { jsx } from "react/jsx-runtime";
|
|
101
105
|
var FilteredDiv = createFilteredElement("div");
|
|
102
106
|
var StyledBox = styled(FilteredDiv)`
|
|
103
|
-
display: flex;
|
|
107
|
+
display: ${(props) => props.display || "flex"};
|
|
104
108
|
box-sizing: border-box;
|
|
105
109
|
background-color: ${(props) => props.backgroundColor || "transparent"};
|
|
106
110
|
border-color: ${(props) => props.borderColor || "transparent"};
|
|
@@ -236,7 +240,7 @@ var Box = React2.forwardRef(
|
|
|
236
240
|
onLoad,
|
|
237
241
|
"data-testid": dataTestId || testID,
|
|
238
242
|
style: {
|
|
239
|
-
display: "block",
|
|
243
|
+
display: props.display || "block",
|
|
240
244
|
objectFit: "cover",
|
|
241
245
|
width: typeof props.width === "number" ? `${props.width}px` : props.width,
|
|
242
246
|
height: typeof props.height === "number" ? `${props.height}px` : props.height,
|
|
@@ -636,6 +640,9 @@ var DatePicker = forwardRef(
|
|
|
636
640
|
overlayThemeProductContext,
|
|
637
641
|
iconRight = /* @__PURE__ */ jsx2(CalendarFieldIcon, {}),
|
|
638
642
|
iconLeft,
|
|
643
|
+
label,
|
|
644
|
+
clearable = false,
|
|
645
|
+
onClear,
|
|
639
646
|
error,
|
|
640
647
|
errorMessage,
|
|
641
648
|
readOnly,
|
|
@@ -657,6 +664,7 @@ var DatePicker = forwardRef(
|
|
|
657
664
|
() => isRange ? [datePartsFromDate(startDate), datePartsFromDate(endDate)] : [datePartsFromDate(selectedDate)],
|
|
658
665
|
[isRange, startDate, endDate, selectedDate]
|
|
659
666
|
);
|
|
667
|
+
const propKey = `${selectedDate?.getTime() ?? ""}|${startDate?.getTime() ?? ""}|${endDate?.getTime() ?? ""}|${isRange}`;
|
|
660
668
|
const [open, setOpen] = useState(false);
|
|
661
669
|
const [groups, setGroups] = useState(propGroups);
|
|
662
670
|
const [edit, setEdit] = useState(null);
|
|
@@ -672,6 +680,15 @@ var DatePicker = forwardRef(
|
|
|
672
680
|
const inputRef = useRef(null);
|
|
673
681
|
const chipSelectionRef = useRef(false);
|
|
674
682
|
const suppressReopenRef = useRef(false);
|
|
683
|
+
const sessionRef = useRef({
|
|
684
|
+
dirty: false,
|
|
685
|
+
cleared: false,
|
|
686
|
+
propKey
|
|
687
|
+
});
|
|
688
|
+
const markDirty = () => {
|
|
689
|
+
sessionRef.current.dirty = true;
|
|
690
|
+
sessionRef.current.cleared = false;
|
|
691
|
+
};
|
|
675
692
|
const activeChipValue = activeChip !== void 0 ? activeChip : internalChip;
|
|
676
693
|
const chipLabel = showChipLabel && activeChipValue && chips ? chips.find((c) => c.value === activeChipValue)?.label : void 0;
|
|
677
694
|
const isWithinBounds = (date) => {
|
|
@@ -731,6 +748,7 @@ var DatePicker = forwardRef(
|
|
|
731
748
|
);
|
|
732
749
|
const showMask = hasAnyFilled || focused && isWeb;
|
|
733
750
|
const inputValue = chipLabel ?? (showMask ? composed.text : "");
|
|
751
|
+
const showClear = clearable && editable && (hasAnyFilled || !!chipLabel);
|
|
734
752
|
const orderedSegments = () => composeField().segments;
|
|
735
753
|
const firstSegmentKey = () => {
|
|
736
754
|
const first = orderedSegments()[0];
|
|
@@ -773,6 +791,7 @@ var DatePicker = forwardRef(
|
|
|
773
791
|
if (start || end) applySelection([start, end], false);
|
|
774
792
|
};
|
|
775
793
|
const commitPart = (group, type, rawValue) => {
|
|
794
|
+
markDirty();
|
|
776
795
|
const clamped = clampDatePart(type, rawValue, groups[group]);
|
|
777
796
|
const next = groups.map((g, i) => {
|
|
778
797
|
if (i !== group) return g;
|
|
@@ -821,6 +840,7 @@ var DatePicker = forwardRef(
|
|
|
821
840
|
setEdit(null);
|
|
822
841
|
if (committed !== null) advance(active);
|
|
823
842
|
} else {
|
|
843
|
+
markDirty();
|
|
824
844
|
setEdit({ group: active.group, type: active.type, buffer });
|
|
825
845
|
}
|
|
826
846
|
};
|
|
@@ -858,6 +878,7 @@ var DatePicker = forwardRef(
|
|
|
858
878
|
e.preventDefault();
|
|
859
879
|
const active = activeSegment ?? firstSegmentKey();
|
|
860
880
|
if (!active) return;
|
|
881
|
+
markDirty();
|
|
861
882
|
const sameActive = edit && edit.group === active.group && edit.type === active.type;
|
|
862
883
|
if (sameActive && edit.buffer.length > 0) {
|
|
863
884
|
const buffer = edit.buffer.slice(0, -1);
|
|
@@ -909,6 +930,11 @@ var DatePicker = forwardRef(
|
|
|
909
930
|
suppressReopenRef.current = false;
|
|
910
931
|
return;
|
|
911
932
|
}
|
|
933
|
+
sessionRef.current = {
|
|
934
|
+
dirty: false,
|
|
935
|
+
cleared: sessionRef.current.cleared,
|
|
936
|
+
propKey
|
|
937
|
+
};
|
|
912
938
|
setFocused(true);
|
|
913
939
|
setOpen(true);
|
|
914
940
|
if (isWeb && editable) setActiveSegment(firstSegmentKey());
|
|
@@ -925,7 +951,19 @@ var DatePicker = forwardRef(
|
|
|
925
951
|
onBlurProp?.(e);
|
|
926
952
|
setFocused(false);
|
|
927
953
|
setActiveSegment(null);
|
|
954
|
+
if (sessionRef.current.propKey !== propKey && !sessionRef.current.dirty) {
|
|
955
|
+
sessionRef.current = { dirty: false, cleared: false, propKey };
|
|
956
|
+
setEdit(null);
|
|
957
|
+
setParseError(null);
|
|
958
|
+
setGroups(propGroups());
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
928
961
|
if (!editable) return;
|
|
962
|
+
if (sessionRef.current.cleared && !sessionRef.current.dirty) {
|
|
963
|
+
setEdit(null);
|
|
964
|
+
setParseError(null);
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
929
967
|
let next = groups;
|
|
930
968
|
if (edit) {
|
|
931
969
|
const clamped = clampDatePart(
|
|
@@ -982,6 +1020,7 @@ var DatePicker = forwardRef(
|
|
|
982
1020
|
setParseError("Date must be within the allowed range");
|
|
983
1021
|
return;
|
|
984
1022
|
}
|
|
1023
|
+
markDirty();
|
|
985
1024
|
setParseError(null);
|
|
986
1025
|
setEdit(null);
|
|
987
1026
|
setGroups(next);
|
|
@@ -992,13 +1031,29 @@ var DatePicker = forwardRef(
|
|
|
992
1031
|
setInternalChip(value);
|
|
993
1032
|
onChipSelect?.(value);
|
|
994
1033
|
};
|
|
1034
|
+
const handleClear = () => {
|
|
1035
|
+
const next = isRange ? [datePartsFromDate(null), datePartsFromDate(null)] : [datePartsFromDate(null)];
|
|
1036
|
+
sessionRef.current.dirty = false;
|
|
1037
|
+
sessionRef.current.cleared = true;
|
|
1038
|
+
setGroups(next);
|
|
1039
|
+
setEdit(null);
|
|
1040
|
+
setParseError(null);
|
|
1041
|
+
setInternalChip(null);
|
|
1042
|
+
onChipSelect?.(null);
|
|
1043
|
+
if (isWeb && editable) setActiveSegment(firstSegmentKey());
|
|
1044
|
+
onClear?.();
|
|
1045
|
+
if (isRange) {
|
|
1046
|
+
const emptyRange = [null, null];
|
|
1047
|
+
onChange?.(emptyRange);
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
995
1050
|
const handleDateChange = (date) => applySelection(date, closeOnComplete);
|
|
996
1051
|
const closePanel = useCallback(() => setOpen(false), []);
|
|
997
1052
|
const renderTopContent = topContent ? () => topContent({ close: closePanel }) : void 0;
|
|
998
1053
|
const renderBottomContent = bottomContent ? () => bottomContent({ close: closePanel }) : void 0;
|
|
999
|
-
const propKey = `${selectedDate?.getTime() ?? ""}|${startDate?.getTime() ?? ""}|${endDate?.getTime() ?? ""}|${isRange}`;
|
|
1000
1054
|
useEffect(() => {
|
|
1001
1055
|
if (focused) return;
|
|
1056
|
+
sessionRef.current = { dirty: false, cleared: false, propKey };
|
|
1002
1057
|
setGroups(propGroups());
|
|
1003
1058
|
setEdit(null);
|
|
1004
1059
|
setParseError(null);
|
|
@@ -1175,6 +1230,7 @@ var DatePicker = forwardRef(
|
|
|
1175
1230
|
...rest,
|
|
1176
1231
|
ref: inputRef,
|
|
1177
1232
|
size,
|
|
1233
|
+
label,
|
|
1178
1234
|
placeholder: placeholder || (isRange ? "Choose a date range" : "Choose a date"),
|
|
1179
1235
|
value: inputValue,
|
|
1180
1236
|
readOnly,
|
|
@@ -1185,6 +1241,8 @@ var DatePicker = forwardRef(
|
|
|
1185
1241
|
onPaste: handlePaste,
|
|
1186
1242
|
iconRight,
|
|
1187
1243
|
iconLeft,
|
|
1244
|
+
extraClear: showClear,
|
|
1245
|
+
onRemove: handleClear,
|
|
1188
1246
|
error: error || !!parseError,
|
|
1189
1247
|
errorMessage: parseError ?? errorMessage,
|
|
1190
1248
|
backgroundColor,
|