@dmsi/wedgekit-react 0.0.28 → 0.0.30
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/dist/{chunk-57WRM337.js → chunk-5POWRPIO.js} +3 -2
- package/dist/{chunk-S5KPS4IQ.js → chunk-HXEPUO5W.js} +189 -95
- package/dist/chunk-KHQX42T7.js +127 -0
- package/dist/{chunk-OUSNH76S.js → chunk-PCCJ7L3N.js} +29 -6
- package/dist/{chunk-PDDZ5PMY.js → chunk-S46RZBT4.js} +3 -2
- package/dist/components/CalendarRange.cjs +28 -5
- package/dist/components/CalendarRange.js +1 -1
- package/dist/components/DataGrid.cjs +490 -217
- package/dist/components/DataGrid.js +303 -122
- package/dist/components/DataGridCell.cjs +192 -96
- package/dist/components/DataGridCell.js +4 -2
- package/dist/components/DateInput.cjs +231 -30
- package/dist/components/DateInput.js +101 -27
- package/dist/components/DateRangeInput.cjs +550 -37
- package/dist/components/DateRangeInput.js +413 -34
- package/dist/components/MenuOption.cjs +3 -2
- package/dist/components/MenuOption.js +1 -1
- package/dist/components/MobileDataGrid.cjs +3 -2
- package/dist/components/MobileDataGrid.js +1 -1
- package/dist/components/NestedMenu.cjs +3 -2
- package/dist/components/NestedMenu.js +1 -1
- package/dist/components/Notification.cjs +3 -2
- package/dist/components/Notification.js +1 -1
- package/dist/components/SideMenuGroup.cjs +3 -2
- package/dist/components/SideMenuGroup.js +1 -1
- package/dist/components/SideMenuItem.cjs +3 -2
- package/dist/components/SideMenuItem.js +1 -1
- package/dist/components/Stack.cjs +3 -2
- package/dist/components/Stack.js +1 -1
- package/dist/components/Swatch.cjs +3 -2
- package/dist/components/Swatch.js +1 -1
- package/dist/components/Time.cjs +3 -2
- package/dist/components/Time.js +1 -1
- package/dist/index.css +9 -0
- package/package.json +1 -1
- package/src/components/CalendarRange.tsx +37 -6
- package/src/components/DataGrid.tsx +284 -48
- package/src/components/DataGridCell.tsx +122 -35
- package/src/components/DateInput.tsx +118 -25
- package/src/components/DateRangeInput.tsx +544 -30
- package/src/components/MenuOption.tsx +18 -14
- package/src/components/Stack.tsx +4 -2
- package/src/utils/date.ts +206 -0
|
@@ -774,11 +774,20 @@ function CalendarRange({
|
|
|
774
774
|
}) {
|
|
775
775
|
const weekDays = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
776
776
|
const parseDate = (d) => {
|
|
777
|
-
if (!d)
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
777
|
+
if (!d) {
|
|
778
|
+
return void 0;
|
|
779
|
+
}
|
|
780
|
+
try {
|
|
781
|
+
if (typeof d === "number") {
|
|
782
|
+
return import_polyfill.Temporal.PlainDate.from(new Date(d).toISOString().slice(0, 10));
|
|
783
|
+
}
|
|
784
|
+
if (typeof d === "string") {
|
|
785
|
+
return import_polyfill.Temporal.PlainDate.from(d);
|
|
786
|
+
}
|
|
787
|
+
return void 0;
|
|
788
|
+
} catch (error) {
|
|
789
|
+
return import_polyfill.Temporal.Now.plainDateISO();
|
|
790
|
+
}
|
|
782
791
|
};
|
|
783
792
|
const fromDate = parseDate(from);
|
|
784
793
|
const toDate = parseDate(to);
|
|
@@ -789,6 +798,20 @@ function CalendarRange({
|
|
|
789
798
|
const [selecting, setSelecting] = (0, import_react2.useState)("from");
|
|
790
799
|
const [pendingFrom, setPendingFrom] = (0, import_react2.useState)(void 0);
|
|
791
800
|
const [hoveredDate, setHoveredDate] = (0, import_react2.useState)(void 0);
|
|
801
|
+
(0, import_react2.useEffect)(() => {
|
|
802
|
+
if (fromDate) {
|
|
803
|
+
setBaseMonth(fromDate.with({ day: 1 }));
|
|
804
|
+
} else if (toDate) {
|
|
805
|
+
setBaseMonth(toDate.with({ day: 1 }));
|
|
806
|
+
}
|
|
807
|
+
}, [from, to]);
|
|
808
|
+
(0, import_react2.useEffect)(() => {
|
|
809
|
+
if (fromDate && toDate) {
|
|
810
|
+
setSelecting("from");
|
|
811
|
+
setPendingFrom(void 0);
|
|
812
|
+
setHoveredDate(void 0);
|
|
813
|
+
}
|
|
814
|
+
}, [from, to]);
|
|
792
815
|
function getMonthData(monthOffset) {
|
|
793
816
|
const monthDate = baseMonth.add({ months: monthOffset }).with({ day: 1 });
|
|
794
817
|
const days = monthDate.daysInMonth;
|
|
@@ -1002,6 +1025,117 @@ function findDocumentRoot(element) {
|
|
|
1002
1025
|
return window.document.body;
|
|
1003
1026
|
}
|
|
1004
1027
|
|
|
1028
|
+
// src/utils/date.ts
|
|
1029
|
+
function parseInputDate(input) {
|
|
1030
|
+
const match = input.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
|
|
1031
|
+
if (!match) {
|
|
1032
|
+
return null;
|
|
1033
|
+
}
|
|
1034
|
+
const [, month, day, year] = match;
|
|
1035
|
+
const paddedMonth = month.padStart(2, "0");
|
|
1036
|
+
const paddedDay = day.padStart(2, "0");
|
|
1037
|
+
return `${year}-${paddedMonth}-${paddedDay}`;
|
|
1038
|
+
}
|
|
1039
|
+
function isValidDate(dateString) {
|
|
1040
|
+
const date = new Date(dateString);
|
|
1041
|
+
return date instanceof Date && !isNaN(date.getTime()) && dateString === date.toISOString().split("T")[0];
|
|
1042
|
+
}
|
|
1043
|
+
function formatInputValue(value) {
|
|
1044
|
+
const digits = value.replace(/\D/g, "");
|
|
1045
|
+
if (digits.length < 2) {
|
|
1046
|
+
return digits;
|
|
1047
|
+
}
|
|
1048
|
+
if (digits.length >= 4) {
|
|
1049
|
+
return `${digits.slice(0, 2)}/${digits.slice(2, 4)}/${digits.slice(4, 8)}`;
|
|
1050
|
+
}
|
|
1051
|
+
return `${digits.slice(0, 2)}/${digits.slice(2)}`;
|
|
1052
|
+
}
|
|
1053
|
+
function isDigit(character) {
|
|
1054
|
+
return /\d/.test(character);
|
|
1055
|
+
}
|
|
1056
|
+
function isSlash(character) {
|
|
1057
|
+
return character === "/";
|
|
1058
|
+
}
|
|
1059
|
+
function countDigitsUpToCursor(value, cursorPosition) {
|
|
1060
|
+
let digitCount = 0;
|
|
1061
|
+
for (let i = 0; i < cursorPosition && i < value.length; i++) {
|
|
1062
|
+
if (!isDigit(value[i])) {
|
|
1063
|
+
continue;
|
|
1064
|
+
}
|
|
1065
|
+
digitCount++;
|
|
1066
|
+
}
|
|
1067
|
+
return digitCount;
|
|
1068
|
+
}
|
|
1069
|
+
function findPositionAfterDigitCount(formattedValue, targetDigitCount) {
|
|
1070
|
+
let currentDigitCount = 0;
|
|
1071
|
+
for (let i = 0; i < formattedValue.length; i++) {
|
|
1072
|
+
if (!isDigit(formattedValue[i])) {
|
|
1073
|
+
continue;
|
|
1074
|
+
}
|
|
1075
|
+
currentDigitCount++;
|
|
1076
|
+
if (currentDigitCount !== targetDigitCount) {
|
|
1077
|
+
continue;
|
|
1078
|
+
}
|
|
1079
|
+
const positionAfterDigit = i + 1;
|
|
1080
|
+
const nextCharacter = formattedValue[positionAfterDigit];
|
|
1081
|
+
if (nextCharacter && isSlash(nextCharacter)) {
|
|
1082
|
+
return positionAfterDigit + 1;
|
|
1083
|
+
}
|
|
1084
|
+
return positionAfterDigit;
|
|
1085
|
+
}
|
|
1086
|
+
return formattedValue.length;
|
|
1087
|
+
}
|
|
1088
|
+
function calculateCursorPosition(originalValue, formattedValue, originalPosition) {
|
|
1089
|
+
const targetDigitCount = countDigitsUpToCursor(originalValue, originalPosition);
|
|
1090
|
+
const newPosition = findPositionAfterDigitCount(formattedValue, targetDigitCount);
|
|
1091
|
+
return Math.min(newPosition, formattedValue.length);
|
|
1092
|
+
}
|
|
1093
|
+
function parseDateParts(dateString) {
|
|
1094
|
+
const [yearStr, monthStr, dayStr] = dateString.split("-");
|
|
1095
|
+
if (!yearStr || !monthStr || !dayStr) {
|
|
1096
|
+
return null;
|
|
1097
|
+
}
|
|
1098
|
+
const year = parseInt(yearStr, 10);
|
|
1099
|
+
const month = parseInt(monthStr, 10);
|
|
1100
|
+
const day = parseInt(dayStr, 10);
|
|
1101
|
+
if (isNaN(year) || isNaN(month) || isNaN(day)) {
|
|
1102
|
+
return null;
|
|
1103
|
+
}
|
|
1104
|
+
return { year, month, day };
|
|
1105
|
+
}
|
|
1106
|
+
function isValidDateRange(month, day) {
|
|
1107
|
+
if (month < 1 || month > 12) {
|
|
1108
|
+
return false;
|
|
1109
|
+
}
|
|
1110
|
+
if (day < 1 || day > 31) {
|
|
1111
|
+
return false;
|
|
1112
|
+
}
|
|
1113
|
+
return true;
|
|
1114
|
+
}
|
|
1115
|
+
function formatDatePartsToDisplay(year, month, day) {
|
|
1116
|
+
const paddedMonth = month.toString().padStart(2, "0");
|
|
1117
|
+
const paddedDay = day.toString().padStart(2, "0");
|
|
1118
|
+
return `${paddedMonth}/${paddedDay}/${year}`;
|
|
1119
|
+
}
|
|
1120
|
+
function formatDate(date) {
|
|
1121
|
+
if (!date) {
|
|
1122
|
+
return "";
|
|
1123
|
+
}
|
|
1124
|
+
try {
|
|
1125
|
+
const dateParts = parseDateParts(date);
|
|
1126
|
+
if (!dateParts) {
|
|
1127
|
+
return "";
|
|
1128
|
+
}
|
|
1129
|
+
const { year, month, day } = dateParts;
|
|
1130
|
+
if (!isValidDateRange(month, day)) {
|
|
1131
|
+
return "";
|
|
1132
|
+
}
|
|
1133
|
+
return formatDatePartsToDisplay(year, month, day);
|
|
1134
|
+
} catch (error) {
|
|
1135
|
+
return "";
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1005
1139
|
// src/components/DateInput.tsx
|
|
1006
1140
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1007
1141
|
var DateInput = (_a) => {
|
|
@@ -1023,6 +1157,8 @@ var DateInput = (_a) => {
|
|
|
1023
1157
|
"label"
|
|
1024
1158
|
]);
|
|
1025
1159
|
const [visible, setVisible] = (0, import_react3.useState)(false);
|
|
1160
|
+
const [inputValue, setInputValue] = (0, import_react3.useState)("");
|
|
1161
|
+
const [isTyping, setIsTyping] = (0, import_react3.useState)(false);
|
|
1026
1162
|
const popoverRef = (0, import_react3.useRef)(null);
|
|
1027
1163
|
const triggerRef = (0, import_react3.useRef)(null);
|
|
1028
1164
|
const [calendarPosition, setCalendarPosition] = (0, import_react3.useState)({
|
|
@@ -1031,17 +1167,23 @@ var DateInput = (_a) => {
|
|
|
1031
1167
|
width: 0
|
|
1032
1168
|
});
|
|
1033
1169
|
const [from, to] = [value, ""];
|
|
1170
|
+
(0, import_react3.useEffect)(() => {
|
|
1171
|
+
if (!isTyping) {
|
|
1172
|
+
setInputValue(formatDisplayValue(from));
|
|
1173
|
+
}
|
|
1174
|
+
}, [from, isTyping]);
|
|
1175
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
1176
|
+
if (visible) {
|
|
1177
|
+
updatePosition();
|
|
1178
|
+
}
|
|
1179
|
+
}, [visible]);
|
|
1034
1180
|
const updatePosition = () => {
|
|
1035
1181
|
if (triggerRef.current) {
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
left: rect.left + window.scrollX,
|
|
1042
|
-
width: rect.width
|
|
1043
|
-
});
|
|
1044
|
-
}
|
|
1182
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
1183
|
+
setCalendarPosition({
|
|
1184
|
+
top: rect.bottom + window.scrollY,
|
|
1185
|
+
left: rect.left + window.scrollX,
|
|
1186
|
+
width: rect.width
|
|
1045
1187
|
});
|
|
1046
1188
|
}
|
|
1047
1189
|
};
|
|
@@ -1058,16 +1200,16 @@ var DateInput = (_a) => {
|
|
|
1058
1200
|
};
|
|
1059
1201
|
}, []);
|
|
1060
1202
|
(0, import_react3.useEffect)(() => {
|
|
1061
|
-
const
|
|
1203
|
+
const handleKeyDown2 = (event) => {
|
|
1062
1204
|
var _a2;
|
|
1063
1205
|
if (event.key === "Escape" && popoverRef.current) {
|
|
1064
1206
|
setVisible(false);
|
|
1065
1207
|
(_a2 = triggerRef.current) == null ? void 0 : _a2.blur();
|
|
1066
1208
|
}
|
|
1067
1209
|
};
|
|
1068
|
-
document.addEventListener("keydown",
|
|
1210
|
+
document.addEventListener("keydown", handleKeyDown2);
|
|
1069
1211
|
return () => {
|
|
1070
|
-
document.removeEventListener("keydown",
|
|
1212
|
+
document.removeEventListener("keydown", handleKeyDown2);
|
|
1071
1213
|
};
|
|
1072
1214
|
});
|
|
1073
1215
|
(0, import_react3.useEffect)(() => {
|
|
@@ -1084,21 +1226,69 @@ var DateInput = (_a) => {
|
|
|
1084
1226
|
function handleDateChange(fromValue) {
|
|
1085
1227
|
onChange(fromValue);
|
|
1086
1228
|
setVisible(false);
|
|
1229
|
+
setIsTyping(false);
|
|
1087
1230
|
}
|
|
1088
1231
|
const handleFocus = () => {
|
|
1089
1232
|
if (readOnly) return;
|
|
1090
1233
|
setVisible(true);
|
|
1091
|
-
updatePosition();
|
|
1092
1234
|
};
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1101
|
-
|
|
1235
|
+
const handleClick = () => {
|
|
1236
|
+
handleFocus();
|
|
1237
|
+
};
|
|
1238
|
+
const handleInputChange = (event) => {
|
|
1239
|
+
if (readOnly) return;
|
|
1240
|
+
const rawValue = event.target.value;
|
|
1241
|
+
const cursorPosition = event.target.selectionStart || 0;
|
|
1242
|
+
setIsTyping(true);
|
|
1243
|
+
const formattedValue = formatInputValue(rawValue);
|
|
1244
|
+
setInputValue(formattedValue);
|
|
1245
|
+
requestAnimationFrame(() => {
|
|
1246
|
+
if (triggerRef.current) {
|
|
1247
|
+
const newPosition = calculateCursorPosition(rawValue, formattedValue, cursorPosition);
|
|
1248
|
+
triggerRef.current.setSelectionRange(newPosition, newPosition);
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1251
|
+
const parsedDate = parseInputDate(formattedValue);
|
|
1252
|
+
if (parsedDate && isValidDate(parsedDate)) {
|
|
1253
|
+
onChange(parsedDate);
|
|
1254
|
+
}
|
|
1255
|
+
};
|
|
1256
|
+
const handleBlur = () => {
|
|
1257
|
+
setIsTyping(false);
|
|
1258
|
+
const parsedDate = parseInputDate(inputValue);
|
|
1259
|
+
if (!parsedDate || !isValidDate(parsedDate)) {
|
|
1260
|
+
setInputValue(formatDisplayValue(from));
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
const handleKeyDown = (event) => {
|
|
1264
|
+
if (event.key === "Backspace") {
|
|
1265
|
+
const input = event.target;
|
|
1266
|
+
const cursorPosition = input.selectionStart || 0;
|
|
1267
|
+
const value2 = input.value;
|
|
1268
|
+
if (cursorPosition > 0 && value2[cursorPosition - 1] === "/") {
|
|
1269
|
+
event.preventDefault();
|
|
1270
|
+
const newValue = value2.slice(0, cursorPosition - 2) + value2.slice(cursorPosition);
|
|
1271
|
+
const formattedValue = formatInputValue(newValue);
|
|
1272
|
+
setInputValue(formattedValue);
|
|
1273
|
+
requestAnimationFrame(() => {
|
|
1274
|
+
if (triggerRef.current) {
|
|
1275
|
+
const newPosition = Math.max(0, cursorPosition - 2);
|
|
1276
|
+
triggerRef.current.setSelectionRange(newPosition, newPosition);
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1279
|
+
setIsTyping(true);
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
if (event.key === "Enter") {
|
|
1284
|
+
const parsedDate = parseInputDate(inputValue);
|
|
1285
|
+
if (parsedDate && isValidDate(parsedDate)) {
|
|
1286
|
+
onChange(parsedDate);
|
|
1287
|
+
setVisible(false);
|
|
1288
|
+
setIsTyping(false);
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
};
|
|
1102
1292
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative", children: [
|
|
1103
1293
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1104
1294
|
InputBase,
|
|
@@ -1108,14 +1298,16 @@ var DateInput = (_a) => {
|
|
|
1108
1298
|
triggerRef.current = el;
|
|
1109
1299
|
}
|
|
1110
1300
|
}, props), {
|
|
1111
|
-
value:
|
|
1301
|
+
value: inputValue,
|
|
1112
1302
|
placeholder,
|
|
1113
1303
|
disabled,
|
|
1114
1304
|
readOnly,
|
|
1115
1305
|
after: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "calendar_month" }),
|
|
1116
1306
|
onFocus: handleFocus,
|
|
1117
|
-
|
|
1118
|
-
|
|
1307
|
+
onClick: handleClick,
|
|
1308
|
+
onChange: handleInputChange,
|
|
1309
|
+
onBlur: handleBlur,
|
|
1310
|
+
onKeyDown: handleKeyDown,
|
|
1119
1311
|
label
|
|
1120
1312
|
})
|
|
1121
1313
|
),
|
|
@@ -1151,6 +1343,15 @@ var DateInput = (_a) => {
|
|
|
1151
1343
|
] });
|
|
1152
1344
|
};
|
|
1153
1345
|
DateInput.displayName = "DateInput";
|
|
1346
|
+
function formatDisplayValue(from) {
|
|
1347
|
+
if (!from) {
|
|
1348
|
+
return "";
|
|
1349
|
+
}
|
|
1350
|
+
if (!isValidDate(from)) {
|
|
1351
|
+
return "";
|
|
1352
|
+
}
|
|
1353
|
+
return formatDate(from);
|
|
1354
|
+
}
|
|
1154
1355
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1155
1356
|
0 && (module.exports = {
|
|
1156
1357
|
DateInput
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
calculateCursorPosition,
|
|
3
|
+
formatDate,
|
|
4
|
+
formatInputValue,
|
|
5
|
+
isValidDate,
|
|
6
|
+
parseInputDate
|
|
7
|
+
} from "../chunk-KHQX42T7.js";
|
|
1
8
|
import {
|
|
2
9
|
findDocumentRoot
|
|
3
10
|
} from "../chunk-4T7F5BZZ.js";
|
|
@@ -7,7 +14,7 @@ import {
|
|
|
7
14
|
import "../chunk-S5K22XTH.js";
|
|
8
15
|
import {
|
|
9
16
|
CalendarRange
|
|
10
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-PCCJ7L3N.js";
|
|
11
18
|
import {
|
|
12
19
|
Icon
|
|
13
20
|
} from "../chunk-IGQVA7SC.js";
|
|
@@ -19,7 +26,7 @@ import {
|
|
|
19
26
|
} from "../chunk-ORMEWXMH.js";
|
|
20
27
|
|
|
21
28
|
// src/components/DateInput.tsx
|
|
22
|
-
import { useRef, useEffect, useState } from "react";
|
|
29
|
+
import { useRef, useEffect, useState, useLayoutEffect } from "react";
|
|
23
30
|
import { createPortal } from "react-dom";
|
|
24
31
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
25
32
|
var DateInput = (_a) => {
|
|
@@ -41,6 +48,8 @@ var DateInput = (_a) => {
|
|
|
41
48
|
"label"
|
|
42
49
|
]);
|
|
43
50
|
const [visible, setVisible] = useState(false);
|
|
51
|
+
const [inputValue, setInputValue] = useState("");
|
|
52
|
+
const [isTyping, setIsTyping] = useState(false);
|
|
44
53
|
const popoverRef = useRef(null);
|
|
45
54
|
const triggerRef = useRef(null);
|
|
46
55
|
const [calendarPosition, setCalendarPosition] = useState({
|
|
@@ -49,17 +58,23 @@ var DateInput = (_a) => {
|
|
|
49
58
|
width: 0
|
|
50
59
|
});
|
|
51
60
|
const [from, to] = [value, ""];
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!isTyping) {
|
|
63
|
+
setInputValue(formatDisplayValue(from));
|
|
64
|
+
}
|
|
65
|
+
}, [from, isTyping]);
|
|
66
|
+
useLayoutEffect(() => {
|
|
67
|
+
if (visible) {
|
|
68
|
+
updatePosition();
|
|
69
|
+
}
|
|
70
|
+
}, [visible]);
|
|
52
71
|
const updatePosition = () => {
|
|
53
72
|
if (triggerRef.current) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
left: rect.left + window.scrollX,
|
|
60
|
-
width: rect.width
|
|
61
|
-
});
|
|
62
|
-
}
|
|
73
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
74
|
+
setCalendarPosition({
|
|
75
|
+
top: rect.bottom + window.scrollY,
|
|
76
|
+
left: rect.left + window.scrollX,
|
|
77
|
+
width: rect.width
|
|
63
78
|
});
|
|
64
79
|
}
|
|
65
80
|
};
|
|
@@ -76,16 +91,16 @@ var DateInput = (_a) => {
|
|
|
76
91
|
};
|
|
77
92
|
}, []);
|
|
78
93
|
useEffect(() => {
|
|
79
|
-
const
|
|
94
|
+
const handleKeyDown2 = (event) => {
|
|
80
95
|
var _a2;
|
|
81
96
|
if (event.key === "Escape" && popoverRef.current) {
|
|
82
97
|
setVisible(false);
|
|
83
98
|
(_a2 = triggerRef.current) == null ? void 0 : _a2.blur();
|
|
84
99
|
}
|
|
85
100
|
};
|
|
86
|
-
document.addEventListener("keydown",
|
|
101
|
+
document.addEventListener("keydown", handleKeyDown2);
|
|
87
102
|
return () => {
|
|
88
|
-
document.removeEventListener("keydown",
|
|
103
|
+
document.removeEventListener("keydown", handleKeyDown2);
|
|
89
104
|
};
|
|
90
105
|
});
|
|
91
106
|
useEffect(() => {
|
|
@@ -102,21 +117,69 @@ var DateInput = (_a) => {
|
|
|
102
117
|
function handleDateChange(fromValue) {
|
|
103
118
|
onChange(fromValue);
|
|
104
119
|
setVisible(false);
|
|
120
|
+
setIsTyping(false);
|
|
105
121
|
}
|
|
106
122
|
const handleFocus = () => {
|
|
107
123
|
if (readOnly) return;
|
|
108
124
|
setVisible(true);
|
|
109
|
-
updatePosition();
|
|
110
125
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
const handleClick = () => {
|
|
127
|
+
handleFocus();
|
|
128
|
+
};
|
|
129
|
+
const handleInputChange = (event) => {
|
|
130
|
+
if (readOnly) return;
|
|
131
|
+
const rawValue = event.target.value;
|
|
132
|
+
const cursorPosition = event.target.selectionStart || 0;
|
|
133
|
+
setIsTyping(true);
|
|
134
|
+
const formattedValue = formatInputValue(rawValue);
|
|
135
|
+
setInputValue(formattedValue);
|
|
136
|
+
requestAnimationFrame(() => {
|
|
137
|
+
if (triggerRef.current) {
|
|
138
|
+
const newPosition = calculateCursorPosition(rawValue, formattedValue, cursorPosition);
|
|
139
|
+
triggerRef.current.setSelectionRange(newPosition, newPosition);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
const parsedDate = parseInputDate(formattedValue);
|
|
143
|
+
if (parsedDate && isValidDate(parsedDate)) {
|
|
144
|
+
onChange(parsedDate);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
const handleBlur = () => {
|
|
148
|
+
setIsTyping(false);
|
|
149
|
+
const parsedDate = parseInputDate(inputValue);
|
|
150
|
+
if (!parsedDate || !isValidDate(parsedDate)) {
|
|
151
|
+
setInputValue(formatDisplayValue(from));
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const handleKeyDown = (event) => {
|
|
155
|
+
if (event.key === "Backspace") {
|
|
156
|
+
const input = event.target;
|
|
157
|
+
const cursorPosition = input.selectionStart || 0;
|
|
158
|
+
const value2 = input.value;
|
|
159
|
+
if (cursorPosition > 0 && value2[cursorPosition - 1] === "/") {
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
const newValue = value2.slice(0, cursorPosition - 2) + value2.slice(cursorPosition);
|
|
162
|
+
const formattedValue = formatInputValue(newValue);
|
|
163
|
+
setInputValue(formattedValue);
|
|
164
|
+
requestAnimationFrame(() => {
|
|
165
|
+
if (triggerRef.current) {
|
|
166
|
+
const newPosition = Math.max(0, cursorPosition - 2);
|
|
167
|
+
triggerRef.current.setSelectionRange(newPosition, newPosition);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
setIsTyping(true);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (event.key === "Enter") {
|
|
175
|
+
const parsedDate = parseInputDate(inputValue);
|
|
176
|
+
if (parsedDate && isValidDate(parsedDate)) {
|
|
177
|
+
onChange(parsedDate);
|
|
178
|
+
setVisible(false);
|
|
179
|
+
setIsTyping(false);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
120
183
|
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
121
184
|
/* @__PURE__ */ jsx(
|
|
122
185
|
InputBase,
|
|
@@ -126,14 +189,16 @@ var DateInput = (_a) => {
|
|
|
126
189
|
triggerRef.current = el;
|
|
127
190
|
}
|
|
128
191
|
}, props), {
|
|
129
|
-
value:
|
|
192
|
+
value: inputValue,
|
|
130
193
|
placeholder,
|
|
131
194
|
disabled,
|
|
132
195
|
readOnly,
|
|
133
196
|
after: /* @__PURE__ */ jsx(Icon, { name: "calendar_month" }),
|
|
134
197
|
onFocus: handleFocus,
|
|
135
|
-
|
|
136
|
-
|
|
198
|
+
onClick: handleClick,
|
|
199
|
+
onChange: handleInputChange,
|
|
200
|
+
onBlur: handleBlur,
|
|
201
|
+
onKeyDown: handleKeyDown,
|
|
137
202
|
label
|
|
138
203
|
})
|
|
139
204
|
),
|
|
@@ -169,6 +234,15 @@ var DateInput = (_a) => {
|
|
|
169
234
|
] });
|
|
170
235
|
};
|
|
171
236
|
DateInput.displayName = "DateInput";
|
|
237
|
+
function formatDisplayValue(from) {
|
|
238
|
+
if (!from) {
|
|
239
|
+
return "";
|
|
240
|
+
}
|
|
241
|
+
if (!isValidDate(from)) {
|
|
242
|
+
return "";
|
|
243
|
+
}
|
|
244
|
+
return formatDate(from);
|
|
245
|
+
}
|
|
172
246
|
export {
|
|
173
247
|
DateInput
|
|
174
248
|
};
|