@marcoschwartz/lite-ui 0.7.0 → 0.8.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/dist/index.d.mts +36 -7
- package/dist/index.d.ts +36 -7
- package/dist/index.js +938 -225
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +938 -226
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -39,6 +39,7 @@ __export(index_exports, {
|
|
|
39
39
|
Badge: () => Badge,
|
|
40
40
|
BellIcon: () => BellIcon,
|
|
41
41
|
Button: () => Button,
|
|
42
|
+
Calendar: () => Calendar,
|
|
42
43
|
CalendarIcon: () => CalendarIcon,
|
|
43
44
|
CameraIcon: () => CameraIcon,
|
|
44
45
|
Card: () => Card,
|
|
@@ -300,6 +301,9 @@ var Select = ({
|
|
|
300
301
|
value: controlledValue,
|
|
301
302
|
defaultValue,
|
|
302
303
|
onChange,
|
|
304
|
+
label,
|
|
305
|
+
error,
|
|
306
|
+
helperText,
|
|
303
307
|
...props
|
|
304
308
|
}) => {
|
|
305
309
|
const { theme, themeName } = useTheme();
|
|
@@ -334,7 +338,8 @@ var Select = ({
|
|
|
334
338
|
const baseStyles = theme.select.base;
|
|
335
339
|
const sizeStyles2 = theme.select.sizes[size];
|
|
336
340
|
const disabledStyles = disabled ? theme.select.disabled : "";
|
|
337
|
-
const
|
|
341
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
342
|
+
const buttonClasses = `${baseStyles} ${sizeStyles2} ${disabledStyles} ${errorStyles}`.trim();
|
|
338
343
|
const iconColor = themeName === "minimalistic" ? disabled ? "text-gray-600" : "text-white" : disabled ? "text-gray-400" : "text-gray-500";
|
|
339
344
|
const dropdownBaseStyles = themeName === "minimalistic" ? "bg-black border-2 border-white" : "bg-white border border-gray-300 shadow-lg dark:bg-gray-800 dark:border-gray-600";
|
|
340
345
|
const optionBaseStyles = themeName === "minimalistic" ? "text-white hover:bg-white hover:text-black transition-colors duration-200" : "text-gray-900 hover:bg-blue-50 transition-colors duration-150 dark:text-gray-100 dark:hover:bg-gray-700";
|
|
@@ -344,51 +349,56 @@ var Select = ({
|
|
|
344
349
|
lg: "px-4 py-3 text-lg",
|
|
345
350
|
xl: "px-5 py-4 text-xl"
|
|
346
351
|
}[size];
|
|
347
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className:
|
|
348
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
{
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
"
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
"
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
353
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
354
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative inline-block w-full", ref: dropdownRef, ...props, children: [
|
|
355
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
356
|
+
"button",
|
|
357
|
+
{
|
|
358
|
+
type: "button",
|
|
359
|
+
className: buttonClasses,
|
|
360
|
+
onClick: handleToggle,
|
|
361
|
+
disabled,
|
|
362
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: !selectedOption && placeholder ? "opacity-50" : "", children: displayText })
|
|
363
|
+
}
|
|
364
|
+
),
|
|
365
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
366
|
+
"svg",
|
|
367
|
+
{
|
|
368
|
+
className: `h-5 w-5 transition-transform duration-200 ${iconColor} ${isOpen ? "rotate-180" : ""}`,
|
|
369
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
370
|
+
viewBox: "0 0 20 20",
|
|
371
|
+
fill: "currentColor",
|
|
372
|
+
"aria-hidden": "true",
|
|
373
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
374
|
+
"path",
|
|
375
|
+
{
|
|
376
|
+
fillRule: "evenodd",
|
|
377
|
+
d: "M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z",
|
|
378
|
+
clipRule: "evenodd"
|
|
379
|
+
}
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
) }),
|
|
383
|
+
isOpen && !disabled && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
384
|
+
"div",
|
|
385
|
+
{
|
|
386
|
+
className: `absolute z-50 w-full mt-1 ${dropdownBaseStyles} rounded-lg overflow-hidden`,
|
|
387
|
+
style: { maxHeight: "300px", overflowY: "auto" },
|
|
388
|
+
children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
389
|
+
"div",
|
|
390
|
+
{
|
|
391
|
+
className: `${optionBaseStyles} ${optionSizeStyles} cursor-pointer ${value === option.value ? themeName === "minimalistic" ? "bg-white text-black" : "bg-blue-50 dark:bg-gray-700" : ""}`,
|
|
392
|
+
onClick: () => handleSelect(option.value),
|
|
393
|
+
children: option.label
|
|
394
|
+
},
|
|
395
|
+
option.value
|
|
396
|
+
))
|
|
397
|
+
}
|
|
398
|
+
)
|
|
399
|
+
] }),
|
|
400
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
401
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
392
402
|
] });
|
|
393
403
|
};
|
|
394
404
|
|
|
@@ -1029,6 +1039,7 @@ TextInput.displayName = "TextInput";
|
|
|
1029
1039
|
|
|
1030
1040
|
// src/components/ActionMenu.tsx
|
|
1031
1041
|
var import_react8 = require("react");
|
|
1042
|
+
var import_react_dom = require("react-dom");
|
|
1032
1043
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
1033
1044
|
var ActionMenu = ({
|
|
1034
1045
|
items,
|
|
@@ -1037,10 +1048,16 @@ var ActionMenu = ({
|
|
|
1037
1048
|
}) => {
|
|
1038
1049
|
const { themeName } = useTheme();
|
|
1039
1050
|
const [isOpen, setIsOpen] = (0, import_react8.useState)(false);
|
|
1051
|
+
const [menuPosition, setMenuPosition] = (0, import_react8.useState)(null);
|
|
1052
|
+
const [mounted, setMounted] = (0, import_react8.useState)(false);
|
|
1040
1053
|
const menuRef = (0, import_react8.useRef)(null);
|
|
1054
|
+
const triggerRef = (0, import_react8.useRef)(null);
|
|
1055
|
+
(0, import_react8.useEffect)(() => {
|
|
1056
|
+
setMounted(true);
|
|
1057
|
+
}, []);
|
|
1041
1058
|
(0, import_react8.useEffect)(() => {
|
|
1042
1059
|
const handleClickOutside = (event) => {
|
|
1043
|
-
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
|
1060
|
+
if (menuRef.current && !menuRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
1044
1061
|
setIsOpen(false);
|
|
1045
1062
|
}
|
|
1046
1063
|
};
|
|
@@ -1049,7 +1066,20 @@ var ActionMenu = ({
|
|
|
1049
1066
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1050
1067
|
}
|
|
1051
1068
|
}, [isOpen]);
|
|
1069
|
+
(0, import_react8.useEffect)(() => {
|
|
1070
|
+
if (isOpen && triggerRef.current) {
|
|
1071
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
1072
|
+
const menuWidth = 224;
|
|
1073
|
+
setMenuPosition({
|
|
1074
|
+
top: rect.bottom + 8,
|
|
1075
|
+
left: position === "left" ? rect.left : rect.right - menuWidth
|
|
1076
|
+
});
|
|
1077
|
+
} else {
|
|
1078
|
+
setMenuPosition(null);
|
|
1079
|
+
}
|
|
1080
|
+
}, [isOpen, position]);
|
|
1052
1081
|
const handleItemClick = (item) => {
|
|
1082
|
+
if (item.type === "divider") return;
|
|
1053
1083
|
if (!item.disabled) {
|
|
1054
1084
|
item.onClick();
|
|
1055
1085
|
setIsOpen(false);
|
|
@@ -1065,15 +1095,27 @@ var ActionMenu = ({
|
|
|
1065
1095
|
);
|
|
1066
1096
|
const menuBaseStyles = themeName === "minimalistic" ? "bg-black border-2 border-white" : "bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-lg";
|
|
1067
1097
|
const itemBaseStyles = themeName === "minimalistic" ? "text-white hover:bg-white hover:text-black transition-colors duration-200" : "text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors";
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
{
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1098
|
+
const menu = isOpen && mounted && menuPosition ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1099
|
+
"div",
|
|
1100
|
+
{
|
|
1101
|
+
ref: menuRef,
|
|
1102
|
+
className: `fixed w-56 rounded-lg ${menuBaseStyles} z-[9999] max-h-[80vh] overflow-auto`,
|
|
1103
|
+
style: {
|
|
1104
|
+
minWidth: "14rem",
|
|
1105
|
+
top: `${menuPosition.top}px`,
|
|
1106
|
+
left: `${menuPosition.left}px`
|
|
1107
|
+
},
|
|
1108
|
+
children: items.map((item, index) => {
|
|
1109
|
+
if (item.type === "divider") {
|
|
1110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1111
|
+
"div",
|
|
1112
|
+
{
|
|
1113
|
+
className: "my-1 border-t border-gray-200 dark:border-gray-700"
|
|
1114
|
+
},
|
|
1115
|
+
index
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
1077
1119
|
"button",
|
|
1078
1120
|
{
|
|
1079
1121
|
onClick: () => handleItemClick(item),
|
|
@@ -1085,9 +1127,13 @@ var ActionMenu = ({
|
|
|
1085
1127
|
]
|
|
1086
1128
|
},
|
|
1087
1129
|
index
|
|
1088
|
-
)
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1130
|
+
);
|
|
1131
|
+
})
|
|
1132
|
+
}
|
|
1133
|
+
) : null;
|
|
1134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
|
|
1135
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "relative inline-block", ref: triggerRef, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { onClick: () => setIsOpen(!isOpen), children: trigger || defaultTrigger }) }),
|
|
1136
|
+
mounted && (0, import_react_dom.createPortal)(menu, document.body)
|
|
1091
1137
|
] });
|
|
1092
1138
|
};
|
|
1093
1139
|
|
|
@@ -1347,33 +1393,42 @@ function Table({
|
|
|
1347
1393
|
const { theme } = useTheme();
|
|
1348
1394
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: `overflow-x-auto ${className}`, children: [
|
|
1349
1395
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("table", { className: "w-full text-left", children: [
|
|
1350
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("thead", { className: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("tr", { children: columns.map((column) =>
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("thead", { className: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("tr", { children: columns.map((column, colIndex) => {
|
|
1397
|
+
const isLast = colIndex === columns.length - 1;
|
|
1398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
1399
|
+
"th",
|
|
1400
|
+
{
|
|
1401
|
+
className: isLast ? "px-6 py-3 text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider relative" : "px-6 py-3 text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider",
|
|
1402
|
+
style: { width: column.width },
|
|
1403
|
+
children: column.title
|
|
1404
|
+
},
|
|
1405
|
+
column.key
|
|
1406
|
+
);
|
|
1407
|
+
}) }) }),
|
|
1408
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700", children: data.map((row, rowIndex) => {
|
|
1409
|
+
const rowClasses = [
|
|
1410
|
+
striped && rowIndex % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : "",
|
|
1411
|
+
hoverable ? "hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" : ""
|
|
1412
|
+
].filter(Boolean).join(" ");
|
|
1413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
1414
|
+
"tr",
|
|
1415
|
+
{
|
|
1416
|
+
className: rowClasses,
|
|
1417
|
+
children: columns.map((column, colIndex) => {
|
|
1418
|
+
const isLast = colIndex === columns.length - 1;
|
|
1419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
1420
|
+
"td",
|
|
1421
|
+
{
|
|
1422
|
+
className: isLast ? "px-6 py-4 text-sm text-gray-900 dark:text-gray-100 overflow-visible" : "px-6 py-4 text-sm text-gray-900 dark:text-gray-100",
|
|
1423
|
+
children: column.render ? column.render(row[column.key], row, rowIndex) : row[column.key]
|
|
1424
|
+
},
|
|
1425
|
+
column.key
|
|
1426
|
+
);
|
|
1427
|
+
})
|
|
1428
|
+
},
|
|
1429
|
+
row[keyField] || rowIndex
|
|
1430
|
+
);
|
|
1431
|
+
}) })
|
|
1377
1432
|
] }),
|
|
1378
1433
|
data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "text-center py-8 text-gray-500 dark:text-gray-400", children: "No data available" })
|
|
1379
1434
|
] });
|
|
@@ -1470,30 +1525,220 @@ var Pagination = ({
|
|
|
1470
1525
|
|
|
1471
1526
|
// src/components/DatePicker.tsx
|
|
1472
1527
|
var import_react12 = require("react");
|
|
1528
|
+
var import_react_dom2 = require("react-dom");
|
|
1473
1529
|
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
1474
|
-
var
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1530
|
+
var DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
1531
|
+
var MONTHS = [
|
|
1532
|
+
"January",
|
|
1533
|
+
"February",
|
|
1534
|
+
"March",
|
|
1535
|
+
"April",
|
|
1536
|
+
"May",
|
|
1537
|
+
"June",
|
|
1538
|
+
"July",
|
|
1539
|
+
"August",
|
|
1540
|
+
"September",
|
|
1541
|
+
"October",
|
|
1542
|
+
"November",
|
|
1543
|
+
"December"
|
|
1544
|
+
];
|
|
1545
|
+
var DatePicker = ({
|
|
1546
|
+
label,
|
|
1547
|
+
error,
|
|
1548
|
+
helperText,
|
|
1549
|
+
value,
|
|
1550
|
+
onChange,
|
|
1551
|
+
minDate,
|
|
1552
|
+
maxDate,
|
|
1553
|
+
disabled,
|
|
1554
|
+
className = "",
|
|
1555
|
+
placeholder = "Select date..."
|
|
1556
|
+
}) => {
|
|
1557
|
+
const { theme } = useTheme();
|
|
1558
|
+
const [isOpen, setIsOpen] = (0, import_react12.useState)(false);
|
|
1559
|
+
const [viewDate, setViewDate] = (0, import_react12.useState)(value || /* @__PURE__ */ new Date());
|
|
1560
|
+
const [mounted, setMounted] = (0, import_react12.useState)(false);
|
|
1561
|
+
const [calendarPosition, setCalendarPosition] = (0, import_react12.useState)(null);
|
|
1562
|
+
const inputRef = (0, import_react12.useRef)(null);
|
|
1563
|
+
const calendarRef = (0, import_react12.useRef)(null);
|
|
1564
|
+
(0, import_react12.useEffect)(() => {
|
|
1565
|
+
setMounted(true);
|
|
1566
|
+
}, []);
|
|
1567
|
+
(0, import_react12.useEffect)(() => {
|
|
1568
|
+
const handleClickOutside = (event) => {
|
|
1569
|
+
if (calendarRef.current && !calendarRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
|
|
1570
|
+
setIsOpen(false);
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
if (isOpen) {
|
|
1574
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1575
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1576
|
+
}
|
|
1577
|
+
}, [isOpen]);
|
|
1578
|
+
(0, import_react12.useEffect)(() => {
|
|
1579
|
+
if (isOpen && inputRef.current) {
|
|
1580
|
+
const rect = inputRef.current.getBoundingClientRect();
|
|
1581
|
+
setCalendarPosition({
|
|
1582
|
+
top: rect.bottom + 8,
|
|
1583
|
+
left: rect.left
|
|
1584
|
+
});
|
|
1585
|
+
} else {
|
|
1586
|
+
setCalendarPosition(null);
|
|
1587
|
+
}
|
|
1588
|
+
}, [isOpen]);
|
|
1589
|
+
const year = viewDate.getFullYear();
|
|
1590
|
+
const month = viewDate.getMonth();
|
|
1591
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
1592
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
1593
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
1594
|
+
const calendarDays = [];
|
|
1595
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
1596
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
1495
1597
|
}
|
|
1496
|
-
)
|
|
1598
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
1599
|
+
calendarDays.push(new Date(year, month, i));
|
|
1600
|
+
}
|
|
1601
|
+
const remainingDays = 42 - calendarDays.length;
|
|
1602
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
1603
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
1604
|
+
}
|
|
1605
|
+
const isSameDay = (date1, date2) => {
|
|
1606
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
1607
|
+
};
|
|
1608
|
+
const isToday = (date) => {
|
|
1609
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
1610
|
+
};
|
|
1611
|
+
const isSelected = (date) => {
|
|
1612
|
+
return value && isSameDay(date, value);
|
|
1613
|
+
};
|
|
1614
|
+
const isCurrentMonth = (date) => {
|
|
1615
|
+
return date.getMonth() === month;
|
|
1616
|
+
};
|
|
1617
|
+
const isDisabled = (date) => {
|
|
1618
|
+
if (minDate && date < minDate) return true;
|
|
1619
|
+
if (maxDate && date > maxDate) return true;
|
|
1620
|
+
return false;
|
|
1621
|
+
};
|
|
1622
|
+
const handleDateClick = (date) => {
|
|
1623
|
+
if (isDisabled(date)) return;
|
|
1624
|
+
onChange?.(date);
|
|
1625
|
+
setIsOpen(false);
|
|
1626
|
+
};
|
|
1627
|
+
const handlePrevMonth = () => {
|
|
1628
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
1629
|
+
};
|
|
1630
|
+
const handleNextMonth = () => {
|
|
1631
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
1632
|
+
};
|
|
1633
|
+
const handleToday = () => {
|
|
1634
|
+
const today = /* @__PURE__ */ new Date();
|
|
1635
|
+
setViewDate(today);
|
|
1636
|
+
onChange?.(today);
|
|
1637
|
+
setIsOpen(false);
|
|
1638
|
+
};
|
|
1639
|
+
const formatDate = (date) => {
|
|
1640
|
+
if (!date) return "";
|
|
1641
|
+
return date.toLocaleDateString("en-US", {
|
|
1642
|
+
month: "short",
|
|
1643
|
+
day: "numeric",
|
|
1644
|
+
year: "numeric"
|
|
1645
|
+
});
|
|
1646
|
+
};
|
|
1647
|
+
const baseStyles = "w-full appearance-none rounded-lg border border-gray-300 bg-white text-gray-900 px-4 py-2.5 text-base transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent shadow-sm hover:border-gray-400 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-100 dark:hover:border-gray-500 cursor-pointer";
|
|
1648
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
1649
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
1650
|
+
const calendar = isOpen && mounted && calendarPosition ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
1651
|
+
"div",
|
|
1652
|
+
{
|
|
1653
|
+
ref: calendarRef,
|
|
1654
|
+
className: "fixed z-[9999] bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-xl p-4",
|
|
1655
|
+
style: {
|
|
1656
|
+
top: `${calendarPosition.top}px`,
|
|
1657
|
+
left: `${calendarPosition.left}px`,
|
|
1658
|
+
minWidth: "320px"
|
|
1659
|
+
},
|
|
1660
|
+
children: [
|
|
1661
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
1662
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1663
|
+
"button",
|
|
1664
|
+
{
|
|
1665
|
+
onClick: handlePrevMonth,
|
|
1666
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
1667
|
+
"aria-label": "Previous month",
|
|
1668
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("svg", { className: "w-5 h-5 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
1669
|
+
}
|
|
1670
|
+
),
|
|
1671
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1672
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("h2", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
1673
|
+
MONTHS[month],
|
|
1674
|
+
" ",
|
|
1675
|
+
year
|
|
1676
|
+
] }),
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1678
|
+
"button",
|
|
1679
|
+
{
|
|
1680
|
+
onClick: handleToday,
|
|
1681
|
+
className: "px-2 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
1682
|
+
children: "Today"
|
|
1683
|
+
}
|
|
1684
|
+
)
|
|
1685
|
+
] }),
|
|
1686
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1687
|
+
"button",
|
|
1688
|
+
{
|
|
1689
|
+
onClick: handleNextMonth,
|
|
1690
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
1691
|
+
"aria-label": "Next month",
|
|
1692
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("svg", { className: "w-5 h-5 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
1693
|
+
}
|
|
1694
|
+
)
|
|
1695
|
+
] }),
|
|
1696
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-1", children: day }, day)) }),
|
|
1697
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
|
|
1698
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
1699
|
+
const isTodayDay = isToday(date);
|
|
1700
|
+
const isSelectedDay = isSelected(date);
|
|
1701
|
+
const isDisabledDay = isDisabled(date);
|
|
1702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1703
|
+
"button",
|
|
1704
|
+
{
|
|
1705
|
+
onClick: () => handleDateClick(date),
|
|
1706
|
+
disabled: isDisabledDay,
|
|
1707
|
+
className: `
|
|
1708
|
+
aspect-square p-1 rounded-lg text-sm font-medium transition-all
|
|
1709
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
1710
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
1711
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
1712
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
1713
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
1714
|
+
`,
|
|
1715
|
+
children: date.getDate()
|
|
1716
|
+
},
|
|
1717
|
+
index
|
|
1718
|
+
);
|
|
1719
|
+
}) })
|
|
1720
|
+
]
|
|
1721
|
+
}
|
|
1722
|
+
) : null;
|
|
1723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className, children: [
|
|
1724
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
1725
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
1726
|
+
"div",
|
|
1727
|
+
{
|
|
1728
|
+
ref: inputRef,
|
|
1729
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
1730
|
+
className: `${baseStyles} ${errorStyles} ${disabledStyles} flex items-center justify-between`.trim(),
|
|
1731
|
+
children: [
|
|
1732
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: !value ? "text-gray-500 dark:text-gray-400" : "", children: value ? formatDate(value) : placeholder }),
|
|
1733
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("svg", { className: "w-5 h-5 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
|
|
1734
|
+
]
|
|
1735
|
+
}
|
|
1736
|
+
),
|
|
1737
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
1738
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
1739
|
+
mounted && (0, import_react_dom2.createPortal)(calendar, document.body)
|
|
1740
|
+
] });
|
|
1741
|
+
};
|
|
1497
1742
|
DatePicker.displayName = "DatePicker";
|
|
1498
1743
|
|
|
1499
1744
|
// src/components/TimePicker.tsx
|
|
@@ -1526,35 +1771,502 @@ TimePicker.displayName = "TimePicker";
|
|
|
1526
1771
|
|
|
1527
1772
|
// src/components/DateTimePicker.tsx
|
|
1528
1773
|
var import_react14 = require("react");
|
|
1774
|
+
var import_react_dom3 = require("react-dom");
|
|
1529
1775
|
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
1530
|
-
var
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1776
|
+
var DAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
1777
|
+
var MONTHS2 = [
|
|
1778
|
+
"January",
|
|
1779
|
+
"February",
|
|
1780
|
+
"March",
|
|
1781
|
+
"April",
|
|
1782
|
+
"May",
|
|
1783
|
+
"June",
|
|
1784
|
+
"July",
|
|
1785
|
+
"August",
|
|
1786
|
+
"September",
|
|
1787
|
+
"October",
|
|
1788
|
+
"November",
|
|
1789
|
+
"December"
|
|
1790
|
+
];
|
|
1791
|
+
var DateTimePicker = ({
|
|
1792
|
+
label,
|
|
1793
|
+
error,
|
|
1794
|
+
helperText,
|
|
1795
|
+
value,
|
|
1796
|
+
onChange,
|
|
1797
|
+
minDate,
|
|
1798
|
+
maxDate,
|
|
1799
|
+
disabled,
|
|
1800
|
+
className = "",
|
|
1801
|
+
placeholder = "Select date and time..."
|
|
1802
|
+
}) => {
|
|
1803
|
+
const { theme } = useTheme();
|
|
1804
|
+
const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
|
|
1805
|
+
const [viewDate, setViewDate] = (0, import_react14.useState)(value || /* @__PURE__ */ new Date());
|
|
1806
|
+
const [selectedTime, setSelectedTime] = (0, import_react14.useState)(
|
|
1807
|
+
value ? { hours: value.getHours(), minutes: value.getMinutes() } : { hours: 12, minutes: 0 }
|
|
1808
|
+
);
|
|
1809
|
+
const [mounted, setMounted] = (0, import_react14.useState)(false);
|
|
1810
|
+
const [pickerPosition, setPickerPosition] = (0, import_react14.useState)(null);
|
|
1811
|
+
const inputRef = (0, import_react14.useRef)(null);
|
|
1812
|
+
const pickerRef = (0, import_react14.useRef)(null);
|
|
1813
|
+
(0, import_react14.useEffect)(() => {
|
|
1814
|
+
setMounted(true);
|
|
1815
|
+
}, []);
|
|
1816
|
+
(0, import_react14.useEffect)(() => {
|
|
1817
|
+
const handleClickOutside = (event) => {
|
|
1818
|
+
if (pickerRef.current && !pickerRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
|
|
1819
|
+
setIsOpen(false);
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
if (isOpen) {
|
|
1823
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1824
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1825
|
+
}
|
|
1826
|
+
}, [isOpen]);
|
|
1827
|
+
(0, import_react14.useEffect)(() => {
|
|
1828
|
+
if (isOpen && inputRef.current) {
|
|
1829
|
+
const rect = inputRef.current.getBoundingClientRect();
|
|
1830
|
+
setPickerPosition({
|
|
1831
|
+
top: rect.bottom + 8,
|
|
1832
|
+
left: rect.left
|
|
1833
|
+
});
|
|
1834
|
+
} else {
|
|
1835
|
+
setPickerPosition(null);
|
|
1836
|
+
}
|
|
1837
|
+
}, [isOpen]);
|
|
1838
|
+
const year = viewDate.getFullYear();
|
|
1839
|
+
const month = viewDate.getMonth();
|
|
1840
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
1841
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
1842
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
1843
|
+
const calendarDays = [];
|
|
1844
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
1845
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
1846
|
+
}
|
|
1847
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
1848
|
+
calendarDays.push(new Date(year, month, i));
|
|
1849
|
+
}
|
|
1850
|
+
const remainingDays = 42 - calendarDays.length;
|
|
1851
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
1852
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
1853
|
+
}
|
|
1854
|
+
const isSameDay = (date1, date2) => {
|
|
1855
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
1856
|
+
};
|
|
1857
|
+
const isToday = (date) => {
|
|
1858
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
1859
|
+
};
|
|
1860
|
+
const isSelected = (date) => {
|
|
1861
|
+
return value && isSameDay(date, value);
|
|
1862
|
+
};
|
|
1863
|
+
const isCurrentMonth = (date) => {
|
|
1864
|
+
return date.getMonth() === month;
|
|
1865
|
+
};
|
|
1866
|
+
const isDisabled = (date) => {
|
|
1867
|
+
if (minDate && date < minDate) return true;
|
|
1868
|
+
if (maxDate && date > maxDate) return true;
|
|
1869
|
+
return false;
|
|
1870
|
+
};
|
|
1871
|
+
const handleDateClick = (date) => {
|
|
1872
|
+
if (isDisabled(date)) return;
|
|
1873
|
+
const newDateTime = new Date(
|
|
1874
|
+
date.getFullYear(),
|
|
1875
|
+
date.getMonth(),
|
|
1876
|
+
date.getDate(),
|
|
1877
|
+
selectedTime.hours,
|
|
1878
|
+
selectedTime.minutes
|
|
1879
|
+
);
|
|
1880
|
+
onChange?.(newDateTime);
|
|
1881
|
+
};
|
|
1882
|
+
const handleTimeChange = (hours, minutes) => {
|
|
1883
|
+
setSelectedTime({ hours, minutes });
|
|
1884
|
+
if (value) {
|
|
1885
|
+
const newDateTime = new Date(
|
|
1886
|
+
value.getFullYear(),
|
|
1887
|
+
value.getMonth(),
|
|
1888
|
+
value.getDate(),
|
|
1889
|
+
hours,
|
|
1890
|
+
minutes
|
|
1891
|
+
);
|
|
1892
|
+
onChange?.(newDateTime);
|
|
1893
|
+
}
|
|
1894
|
+
};
|
|
1895
|
+
const handleDone = () => {
|
|
1896
|
+
if (value) {
|
|
1897
|
+
setIsOpen(false);
|
|
1898
|
+
}
|
|
1899
|
+
};
|
|
1900
|
+
const handlePrevMonth = () => {
|
|
1901
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
1902
|
+
};
|
|
1903
|
+
const handleNextMonth = () => {
|
|
1904
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
1905
|
+
};
|
|
1906
|
+
const handleToday = () => {
|
|
1907
|
+
const now = /* @__PURE__ */ new Date();
|
|
1908
|
+
setViewDate(now);
|
|
1909
|
+
setSelectedTime({ hours: now.getHours(), minutes: now.getMinutes() });
|
|
1910
|
+
onChange?.(now);
|
|
1911
|
+
};
|
|
1912
|
+
const formatDateTime = (date) => {
|
|
1913
|
+
if (!date) return "";
|
|
1914
|
+
return date.toLocaleString("en-US", {
|
|
1915
|
+
month: "short",
|
|
1916
|
+
day: "numeric",
|
|
1917
|
+
year: "numeric",
|
|
1918
|
+
hour: "numeric",
|
|
1919
|
+
minute: "2-digit",
|
|
1920
|
+
hour12: true
|
|
1921
|
+
});
|
|
1922
|
+
};
|
|
1923
|
+
const formatTime = (hours, minutes) => {
|
|
1924
|
+
const period = hours >= 12 ? "PM" : "AM";
|
|
1925
|
+
const displayHours = hours % 12 || 12;
|
|
1926
|
+
const displayMinutes = minutes.toString().padStart(2, "0");
|
|
1927
|
+
return `${displayHours}:${displayMinutes} ${period}`;
|
|
1928
|
+
};
|
|
1929
|
+
const baseStyles = "w-full appearance-none rounded-lg border border-gray-300 bg-white text-gray-900 px-4 py-2.5 text-base transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent shadow-sm hover:border-gray-400 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-100 dark:hover:border-gray-500 cursor-pointer";
|
|
1930
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
1931
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
1932
|
+
const picker = isOpen && mounted && pickerPosition ? /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
1933
|
+
"div",
|
|
1934
|
+
{
|
|
1935
|
+
ref: pickerRef,
|
|
1936
|
+
className: "fixed z-[9999] bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-xl p-4",
|
|
1937
|
+
style: {
|
|
1938
|
+
top: `${pickerPosition.top}px`,
|
|
1939
|
+
left: `${pickerPosition.left}px`,
|
|
1940
|
+
minWidth: "360px"
|
|
1941
|
+
},
|
|
1942
|
+
children: [
|
|
1943
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
1944
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
1945
|
+
"button",
|
|
1946
|
+
{
|
|
1947
|
+
onClick: handlePrevMonth,
|
|
1948
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
1949
|
+
"aria-label": "Previous month",
|
|
1950
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("svg", { className: "w-5 h-5 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
1951
|
+
}
|
|
1952
|
+
),
|
|
1953
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1954
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("h2", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
1955
|
+
MONTHS2[month],
|
|
1956
|
+
" ",
|
|
1957
|
+
year
|
|
1958
|
+
] }),
|
|
1959
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
1960
|
+
"button",
|
|
1961
|
+
{
|
|
1962
|
+
onClick: handleToday,
|
|
1963
|
+
className: "px-2 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
1964
|
+
children: "Now"
|
|
1965
|
+
}
|
|
1966
|
+
)
|
|
1967
|
+
] }),
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
1969
|
+
"button",
|
|
1970
|
+
{
|
|
1971
|
+
onClick: handleNextMonth,
|
|
1972
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
1973
|
+
"aria-label": "Next month",
|
|
1974
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("svg", { className: "w-5 h-5 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
1975
|
+
}
|
|
1976
|
+
)
|
|
1977
|
+
] }),
|
|
1978
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS2.map((day) => /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-1", children: day }, day)) }),
|
|
1979
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-4", children: calendarDays.map((date, index) => {
|
|
1980
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
1981
|
+
const isTodayDay = isToday(date);
|
|
1982
|
+
const isSelectedDay = isSelected(date);
|
|
1983
|
+
const isDisabledDay = isDisabled(date);
|
|
1984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
1985
|
+
"button",
|
|
1986
|
+
{
|
|
1987
|
+
onClick: () => handleDateClick(date),
|
|
1988
|
+
disabled: isDisabledDay,
|
|
1989
|
+
className: `
|
|
1990
|
+
aspect-square p-1 rounded-lg text-sm font-medium transition-all
|
|
1991
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
1992
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
1993
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
1994
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
1995
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
1996
|
+
`,
|
|
1997
|
+
children: date.getDate()
|
|
1998
|
+
},
|
|
1999
|
+
index
|
|
2000
|
+
);
|
|
2001
|
+
}) }),
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-4", children: [
|
|
2003
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center justify-center gap-4 mb-4", children: [
|
|
2004
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
2005
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { className: "text-xs font-semibold text-gray-600 dark:text-gray-400 mb-2", children: "Hour" }),
|
|
2006
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2007
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
2008
|
+
"button",
|
|
2009
|
+
{
|
|
2010
|
+
type: "button",
|
|
2011
|
+
onClick: () => handleTimeChange((selectedTime.hours + 1) % 24, selectedTime.minutes),
|
|
2012
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2013
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("svg", { className: "w-4 h-4 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) })
|
|
2014
|
+
}
|
|
2015
|
+
),
|
|
2016
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
2017
|
+
"input",
|
|
2018
|
+
{
|
|
2019
|
+
type: "number",
|
|
2020
|
+
min: "0",
|
|
2021
|
+
max: "23",
|
|
2022
|
+
value: selectedTime.hours,
|
|
2023
|
+
onChange: (e) => {
|
|
2024
|
+
const val = parseInt(e.target.value);
|
|
2025
|
+
if (!isNaN(val) && val >= 0 && val <= 23) {
|
|
2026
|
+
handleTimeChange(val, selectedTime.minutes);
|
|
2027
|
+
}
|
|
2028
|
+
},
|
|
2029
|
+
className: "w-16 px-2 py-2 text-center border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg font-semibold [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
|
2030
|
+
}
|
|
2031
|
+
),
|
|
2032
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
2033
|
+
"button",
|
|
2034
|
+
{
|
|
2035
|
+
type: "button",
|
|
2036
|
+
onClick: () => handleTimeChange((selectedTime.hours - 1 + 24) % 24, selectedTime.minutes),
|
|
2037
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2038
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("svg", { className: "w-4 h-4 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
2039
|
+
}
|
|
2040
|
+
)
|
|
2041
|
+
] })
|
|
2042
|
+
] }),
|
|
2043
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-2xl font-bold text-gray-600 dark:text-gray-400 mt-8", children: ":" }),
|
|
2044
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
2045
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { className: "text-xs font-semibold text-gray-600 dark:text-gray-400 mb-2", children: "Minute" }),
|
|
2046
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2047
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
2048
|
+
"button",
|
|
2049
|
+
{
|
|
2050
|
+
type: "button",
|
|
2051
|
+
onClick: () => handleTimeChange(selectedTime.hours, (selectedTime.minutes + 1) % 60),
|
|
2052
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2053
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("svg", { className: "w-4 h-4 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) })
|
|
2054
|
+
}
|
|
2055
|
+
),
|
|
2056
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
2057
|
+
"input",
|
|
2058
|
+
{
|
|
2059
|
+
type: "number",
|
|
2060
|
+
min: "0",
|
|
2061
|
+
max: "59",
|
|
2062
|
+
value: selectedTime.minutes,
|
|
2063
|
+
onChange: (e) => {
|
|
2064
|
+
const val = parseInt(e.target.value);
|
|
2065
|
+
if (!isNaN(val) && val >= 0 && val <= 59) {
|
|
2066
|
+
handleTimeChange(selectedTime.hours, val);
|
|
2067
|
+
}
|
|
2068
|
+
},
|
|
2069
|
+
className: "w-16 px-2 py-2 text-center border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 text-lg font-semibold [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
|
|
2070
|
+
}
|
|
2071
|
+
),
|
|
2072
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
2073
|
+
"button",
|
|
2074
|
+
{
|
|
2075
|
+
type: "button",
|
|
2076
|
+
onClick: () => handleTimeChange(selectedTime.hours, (selectedTime.minutes - 1 + 60) % 60),
|
|
2077
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2078
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("svg", { className: "w-4 h-4 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
2079
|
+
}
|
|
2080
|
+
)
|
|
2081
|
+
] })
|
|
2082
|
+
] })
|
|
2083
|
+
] }),
|
|
2084
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "text-center text-sm text-gray-600 dark:text-gray-400 mb-4", children: formatTime(selectedTime.hours, selectedTime.minutes) }),
|
|
2085
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
2086
|
+
"button",
|
|
2087
|
+
{
|
|
2088
|
+
onClick: handleDone,
|
|
2089
|
+
className: "w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium",
|
|
2090
|
+
children: "Done"
|
|
2091
|
+
}
|
|
2092
|
+
)
|
|
2093
|
+
] })
|
|
2094
|
+
]
|
|
2095
|
+
}
|
|
2096
|
+
) : null;
|
|
2097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className, children: [
|
|
2098
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
2099
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
2100
|
+
"div",
|
|
2101
|
+
{
|
|
2102
|
+
ref: inputRef,
|
|
2103
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
2104
|
+
className: `${baseStyles} ${errorStyles} ${disabledStyles} flex items-center justify-between`.trim(),
|
|
2105
|
+
children: [
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: !value ? "text-gray-500 dark:text-gray-400" : "", children: value ? formatDateTime(value) : placeholder }),
|
|
2107
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("svg", { className: "w-5 h-5 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
|
|
2108
|
+
]
|
|
2109
|
+
}
|
|
2110
|
+
),
|
|
2111
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
2112
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
2113
|
+
mounted && (0, import_react_dom3.createPortal)(picker, document.body)
|
|
2114
|
+
] });
|
|
2115
|
+
};
|
|
2116
|
+
DateTimePicker.displayName = "DateTimePicker";
|
|
2117
|
+
|
|
2118
|
+
// src/components/Calendar.tsx
|
|
2119
|
+
var import_react15 = require("react");
|
|
2120
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
2121
|
+
var DAYS3 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2122
|
+
var MONTHS3 = [
|
|
2123
|
+
"January",
|
|
2124
|
+
"February",
|
|
2125
|
+
"March",
|
|
2126
|
+
"April",
|
|
2127
|
+
"May",
|
|
2128
|
+
"June",
|
|
2129
|
+
"July",
|
|
2130
|
+
"August",
|
|
2131
|
+
"September",
|
|
2132
|
+
"October",
|
|
2133
|
+
"November",
|
|
2134
|
+
"December"
|
|
2135
|
+
];
|
|
2136
|
+
var Calendar = ({
|
|
2137
|
+
value,
|
|
2138
|
+
onChange,
|
|
2139
|
+
minDate,
|
|
2140
|
+
maxDate,
|
|
2141
|
+
className = ""
|
|
2142
|
+
}) => {
|
|
2143
|
+
const { theme } = useTheme();
|
|
2144
|
+
const [currentDate, setCurrentDate] = (0, import_react15.useState)(value || /* @__PURE__ */ new Date());
|
|
2145
|
+
const [viewDate, setViewDate] = (0, import_react15.useState)(value || /* @__PURE__ */ new Date());
|
|
2146
|
+
const year = viewDate.getFullYear();
|
|
2147
|
+
const month = viewDate.getMonth();
|
|
2148
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
2149
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
2150
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
2151
|
+
const calendarDays = [];
|
|
2152
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
2153
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
2154
|
+
}
|
|
2155
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
2156
|
+
calendarDays.push(new Date(year, month, i));
|
|
2157
|
+
}
|
|
2158
|
+
const remainingDays = 42 - calendarDays.length;
|
|
2159
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
2160
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
2161
|
+
}
|
|
2162
|
+
const isSameDay = (date1, date2) => {
|
|
2163
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
2164
|
+
};
|
|
2165
|
+
const isToday = (date) => {
|
|
2166
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
2167
|
+
};
|
|
2168
|
+
const isSelected = (date) => {
|
|
2169
|
+
return value && isSameDay(date, value);
|
|
2170
|
+
};
|
|
2171
|
+
const isCurrentMonth = (date) => {
|
|
2172
|
+
return date.getMonth() === month;
|
|
2173
|
+
};
|
|
2174
|
+
const isDisabled = (date) => {
|
|
2175
|
+
if (minDate && date < minDate) return true;
|
|
2176
|
+
if (maxDate && date > maxDate) return true;
|
|
2177
|
+
return false;
|
|
2178
|
+
};
|
|
2179
|
+
const handleDateClick = (date) => {
|
|
2180
|
+
if (isDisabled(date)) return;
|
|
2181
|
+
setCurrentDate(date);
|
|
2182
|
+
onChange?.(date);
|
|
2183
|
+
};
|
|
2184
|
+
const handlePrevMonth = () => {
|
|
2185
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
2186
|
+
};
|
|
2187
|
+
const handleNextMonth = () => {
|
|
2188
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
2189
|
+
};
|
|
2190
|
+
const handleToday = () => {
|
|
2191
|
+
const today = /* @__PURE__ */ new Date();
|
|
2192
|
+
setViewDate(today);
|
|
2193
|
+
setCurrentDate(today);
|
|
2194
|
+
onChange?.(today);
|
|
2195
|
+
};
|
|
2196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: `bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4 ${className}`, children: [
|
|
2197
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2198
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2199
|
+
"button",
|
|
1540
2200
|
{
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
className:
|
|
1545
|
-
...props
|
|
2201
|
+
onClick: handlePrevMonth,
|
|
2202
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2203
|
+
"aria-label": "Previous month",
|
|
2204
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("svg", { className: "w-5 h-5 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
1546
2205
|
}
|
|
1547
2206
|
),
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
2207
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2208
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("h2", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
2209
|
+
MONTHS3[month],
|
|
2210
|
+
" ",
|
|
2211
|
+
year
|
|
2212
|
+
] }),
|
|
2213
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2214
|
+
"button",
|
|
2215
|
+
{
|
|
2216
|
+
onClick: handleToday,
|
|
2217
|
+
className: "px-3 py-1 text-sm bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
2218
|
+
children: "Today"
|
|
2219
|
+
}
|
|
2220
|
+
)
|
|
2221
|
+
] }),
|
|
2222
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2223
|
+
"button",
|
|
2224
|
+
{
|
|
2225
|
+
onClick: handleNextMonth,
|
|
2226
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2227
|
+
"aria-label": "Next month",
|
|
2228
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("svg", { className: "w-5 h-5 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
2229
|
+
}
|
|
2230
|
+
)
|
|
2231
|
+
] }),
|
|
2232
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS3.map((day) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2233
|
+
"div",
|
|
2234
|
+
{
|
|
2235
|
+
className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-2",
|
|
2236
|
+
children: day
|
|
2237
|
+
},
|
|
2238
|
+
day
|
|
2239
|
+
)) }),
|
|
2240
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
|
|
2241
|
+
if (!date) return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", {}, index);
|
|
2242
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
2243
|
+
const isTodayDay = isToday(date);
|
|
2244
|
+
const isSelectedDay = isSelected(date);
|
|
2245
|
+
const isDisabledDay = isDisabled(date);
|
|
2246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2247
|
+
"button",
|
|
2248
|
+
{
|
|
2249
|
+
onClick: () => handleDateClick(date),
|
|
2250
|
+
disabled: isDisabledDay,
|
|
2251
|
+
className: `
|
|
2252
|
+
aspect-square p-2 rounded-lg text-sm font-medium transition-all
|
|
2253
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
2254
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
2255
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
2256
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
2257
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
2258
|
+
`,
|
|
2259
|
+
children: date.getDate()
|
|
2260
|
+
},
|
|
2261
|
+
index
|
|
2262
|
+
);
|
|
2263
|
+
}) })
|
|
2264
|
+
] });
|
|
2265
|
+
};
|
|
1554
2266
|
|
|
1555
2267
|
// src/components/Radio.tsx
|
|
1556
|
-
var
|
|
1557
|
-
var
|
|
2268
|
+
var import_react16 = __toESM(require("react"));
|
|
2269
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
1558
2270
|
var Radio = ({
|
|
1559
2271
|
name,
|
|
1560
2272
|
options,
|
|
@@ -1565,7 +2277,7 @@ var Radio = ({
|
|
|
1565
2277
|
orientation = "vertical",
|
|
1566
2278
|
className = ""
|
|
1567
2279
|
}) => {
|
|
1568
|
-
const [internalValue, setInternalValue] =
|
|
2280
|
+
const [internalValue, setInternalValue] = import_react16.default.useState(defaultValue || "");
|
|
1569
2281
|
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
1570
2282
|
const handleChange = (optionValue) => {
|
|
1571
2283
|
if (disabled) return;
|
|
@@ -1573,17 +2285,17 @@ var Radio = ({
|
|
|
1573
2285
|
onChange?.(optionValue);
|
|
1574
2286
|
};
|
|
1575
2287
|
const containerClass = orientation === "horizontal" ? "flex flex-wrap gap-4" : "flex flex-col gap-2";
|
|
1576
|
-
return /* @__PURE__ */ (0,
|
|
2288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: `${containerClass} ${className}`, role: "radiogroup", children: options.map((option) => {
|
|
1577
2289
|
const isDisabled = disabled || option.disabled;
|
|
1578
2290
|
const isChecked = value === option.value;
|
|
1579
2291
|
const id = `${name}-${option.value}`;
|
|
1580
|
-
return /* @__PURE__ */ (0,
|
|
2292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
1581
2293
|
"label",
|
|
1582
2294
|
{
|
|
1583
2295
|
htmlFor: id,
|
|
1584
2296
|
className: `flex items-center gap-2 cursor-pointer ${isDisabled ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
1585
2297
|
children: [
|
|
1586
|
-
/* @__PURE__ */ (0,
|
|
2298
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
1587
2299
|
"input",
|
|
1588
2300
|
{
|
|
1589
2301
|
type: "radio",
|
|
@@ -1596,7 +2308,7 @@ var Radio = ({
|
|
|
1596
2308
|
className: "w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 cursor-pointer disabled:cursor-not-allowed"
|
|
1597
2309
|
}
|
|
1598
2310
|
),
|
|
1599
|
-
/* @__PURE__ */ (0,
|
|
2311
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-300", children: option.label })
|
|
1600
2312
|
]
|
|
1601
2313
|
},
|
|
1602
2314
|
option.value
|
|
@@ -1605,7 +2317,7 @@ var Radio = ({
|
|
|
1605
2317
|
};
|
|
1606
2318
|
|
|
1607
2319
|
// src/components/ProgressBar.tsx
|
|
1608
|
-
var
|
|
2320
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
1609
2321
|
var ProgressBar = ({
|
|
1610
2322
|
value,
|
|
1611
2323
|
max = 100,
|
|
@@ -1627,15 +2339,15 @@ var ProgressBar = ({
|
|
|
1627
2339
|
warning: "bg-yellow-500 dark:bg-yellow-400",
|
|
1628
2340
|
danger: "bg-red-600 dark:bg-red-500"
|
|
1629
2341
|
};
|
|
1630
|
-
return /* @__PURE__ */ (0,
|
|
1631
|
-
(showLabel || label) && /* @__PURE__ */ (0,
|
|
1632
|
-
label && /* @__PURE__ */ (0,
|
|
1633
|
-
showLabel && /* @__PURE__ */ (0,
|
|
2342
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2343
|
+
(showLabel || label) && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex justify-between items-center mb-1", children: [
|
|
2344
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label }),
|
|
2345
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
|
|
1634
2346
|
Math.round(percentage),
|
|
1635
2347
|
"%"
|
|
1636
2348
|
] })
|
|
1637
2349
|
] }),
|
|
1638
|
-
/* @__PURE__ */ (0,
|
|
2350
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
1639
2351
|
"div",
|
|
1640
2352
|
{
|
|
1641
2353
|
className: `w-full bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden ${sizeClasses6[size]}`,
|
|
@@ -1643,7 +2355,7 @@ var ProgressBar = ({
|
|
|
1643
2355
|
"aria-valuenow": value,
|
|
1644
2356
|
"aria-valuemin": 0,
|
|
1645
2357
|
"aria-valuemax": max,
|
|
1646
|
-
children: /* @__PURE__ */ (0,
|
|
2358
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
1647
2359
|
"div",
|
|
1648
2360
|
{
|
|
1649
2361
|
className: `${sizeClasses6[size]} ${variantClasses[variant]} rounded-full transition-all duration-300 ease-out`,
|
|
@@ -1656,8 +2368,8 @@ var ProgressBar = ({
|
|
|
1656
2368
|
};
|
|
1657
2369
|
|
|
1658
2370
|
// src/components/Slider.tsx
|
|
1659
|
-
var
|
|
1660
|
-
var
|
|
2371
|
+
var import_react17 = __toESM(require("react"));
|
|
2372
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
1661
2373
|
var Slider = ({
|
|
1662
2374
|
value: controlledValue,
|
|
1663
2375
|
defaultValue = 50,
|
|
@@ -1670,7 +2382,7 @@ var Slider = ({
|
|
|
1670
2382
|
label,
|
|
1671
2383
|
className = ""
|
|
1672
2384
|
}) => {
|
|
1673
|
-
const [internalValue, setInternalValue] =
|
|
2385
|
+
const [internalValue, setInternalValue] = import_react17.default.useState(defaultValue);
|
|
1674
2386
|
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
1675
2387
|
const handleChange = (e) => {
|
|
1676
2388
|
const newValue = Number(e.target.value);
|
|
@@ -1678,21 +2390,21 @@ var Slider = ({
|
|
|
1678
2390
|
onChange?.(newValue);
|
|
1679
2391
|
};
|
|
1680
2392
|
const percentage = (value - min) / (max - min) * 100;
|
|
1681
|
-
return /* @__PURE__ */ (0,
|
|
1682
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
1683
|
-
label && /* @__PURE__ */ (0,
|
|
1684
|
-
showValue && /* @__PURE__ */ (0,
|
|
2393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2394
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [
|
|
2395
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label }),
|
|
2396
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: value })
|
|
1685
2397
|
] }),
|
|
1686
|
-
/* @__PURE__ */ (0,
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
2398
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "relative", children: [
|
|
2399
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "absolute inset-0 h-2 bg-gray-200 dark:bg-gray-700 rounded-full top-1/2 -translate-y-1/2" }),
|
|
2400
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
1689
2401
|
"div",
|
|
1690
2402
|
{
|
|
1691
2403
|
className: "absolute h-2 bg-blue-600 dark:bg-blue-500 rounded-full top-1/2 -translate-y-1/2 pointer-events-none",
|
|
1692
2404
|
style: { width: `${percentage}%` }
|
|
1693
2405
|
}
|
|
1694
2406
|
),
|
|
1695
|
-
/* @__PURE__ */ (0,
|
|
2407
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
1696
2408
|
"input",
|
|
1697
2409
|
{
|
|
1698
2410
|
type: "range",
|
|
@@ -1714,8 +2426,8 @@ var Slider = ({
|
|
|
1714
2426
|
};
|
|
1715
2427
|
|
|
1716
2428
|
// src/components/Avatar.tsx
|
|
1717
|
-
var
|
|
1718
|
-
var
|
|
2429
|
+
var import_react18 = __toESM(require("react"));
|
|
2430
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
1719
2431
|
var Avatar = ({
|
|
1720
2432
|
src,
|
|
1721
2433
|
alt,
|
|
@@ -1725,7 +2437,7 @@ var Avatar = ({
|
|
|
1725
2437
|
className = "",
|
|
1726
2438
|
fallbackColor = "bg-blue-600"
|
|
1727
2439
|
}) => {
|
|
1728
|
-
const [imageError, setImageError] =
|
|
2440
|
+
const [imageError, setImageError] = import_react18.default.useState(false);
|
|
1729
2441
|
const sizeClasses6 = {
|
|
1730
2442
|
xs: "w-6 h-6 text-xs",
|
|
1731
2443
|
sm: "w-8 h-8 text-sm",
|
|
@@ -1743,11 +2455,11 @@ var Avatar = ({
|
|
|
1743
2455
|
};
|
|
1744
2456
|
const showImage = src && !imageError;
|
|
1745
2457
|
const showInitials = !showImage && name;
|
|
1746
|
-
return /* @__PURE__ */ (0,
|
|
2458
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
1747
2459
|
"div",
|
|
1748
2460
|
{
|
|
1749
2461
|
className: `${sizeClasses6[size]} ${shapeClass} flex items-center justify-center overflow-hidden ${showImage ? "bg-gray-200 dark:bg-gray-700" : `${fallbackColor} text-white`} ${className}`,
|
|
1750
|
-
children: showImage ? /* @__PURE__ */ (0,
|
|
2462
|
+
children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
1751
2463
|
"img",
|
|
1752
2464
|
{
|
|
1753
2465
|
src,
|
|
@@ -1755,13 +2467,13 @@ var Avatar = ({
|
|
|
1755
2467
|
className: "w-full h-full object-cover",
|
|
1756
2468
|
onError: () => setImageError(true)
|
|
1757
2469
|
}
|
|
1758
|
-
) : showInitials ? /* @__PURE__ */ (0,
|
|
2470
|
+
) : showInitials ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "font-semibold select-none", children: getInitials(name) }) : /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
1759
2471
|
"svg",
|
|
1760
2472
|
{
|
|
1761
2473
|
className: "w-full h-full text-gray-400 dark:text-gray-600",
|
|
1762
2474
|
fill: "currentColor",
|
|
1763
2475
|
viewBox: "0 0 24 24",
|
|
1764
|
-
children: /* @__PURE__ */ (0,
|
|
2476
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" })
|
|
1765
2477
|
}
|
|
1766
2478
|
)
|
|
1767
2479
|
}
|
|
@@ -1769,7 +2481,7 @@ var Avatar = ({
|
|
|
1769
2481
|
};
|
|
1770
2482
|
|
|
1771
2483
|
// src/components/Textarea.tsx
|
|
1772
|
-
var
|
|
2484
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
1773
2485
|
var Textarea = ({
|
|
1774
2486
|
label,
|
|
1775
2487
|
error,
|
|
@@ -1796,9 +2508,9 @@ var Textarea = ({
|
|
|
1796
2508
|
bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100
|
|
1797
2509
|
placeholder:text-gray-500 dark:placeholder:text-gray-400
|
|
1798
2510
|
disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-gray-50 dark:disabled:bg-gray-900`;
|
|
1799
|
-
return /* @__PURE__ */ (0,
|
|
1800
|
-
label && /* @__PURE__ */ (0,
|
|
1801
|
-
/* @__PURE__ */ (0,
|
|
2511
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2512
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
2513
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
1802
2514
|
"textarea",
|
|
1803
2515
|
{
|
|
1804
2516
|
className: `${baseClasses} ${sizeClasses6[size]} ${resizeClasses[resize]}`,
|
|
@@ -1806,25 +2518,25 @@ var Textarea = ({
|
|
|
1806
2518
|
...props
|
|
1807
2519
|
}
|
|
1808
2520
|
),
|
|
1809
|
-
error && /* @__PURE__ */ (0,
|
|
1810
|
-
helperText && !error && /* @__PURE__ */ (0,
|
|
2521
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
2522
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
1811
2523
|
] });
|
|
1812
2524
|
};
|
|
1813
2525
|
|
|
1814
2526
|
// src/components/Toast.tsx
|
|
1815
|
-
var
|
|
1816
|
-
var
|
|
1817
|
-
var ToastContext = (0,
|
|
2527
|
+
var import_react19 = require("react");
|
|
2528
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
2529
|
+
var ToastContext = (0, import_react19.createContext)(void 0);
|
|
1818
2530
|
var useToast = () => {
|
|
1819
|
-
const context = (0,
|
|
2531
|
+
const context = (0, import_react19.useContext)(ToastContext);
|
|
1820
2532
|
if (!context) {
|
|
1821
2533
|
throw new Error("useToast must be used within a ToastProvider");
|
|
1822
2534
|
}
|
|
1823
2535
|
return context;
|
|
1824
2536
|
};
|
|
1825
2537
|
var ToastProvider = ({ children, position = "top-right" }) => {
|
|
1826
|
-
const [toasts, setToasts] = (0,
|
|
1827
|
-
const addToast = (0,
|
|
2538
|
+
const [toasts, setToasts] = (0, import_react19.useState)([]);
|
|
2539
|
+
const addToast = (0, import_react19.useCallback)((toast2) => {
|
|
1828
2540
|
const id = Math.random().toString(36).substring(7);
|
|
1829
2541
|
const newToast = { ...toast2, id };
|
|
1830
2542
|
setToasts((prev) => [...prev, newToast]);
|
|
@@ -1833,7 +2545,7 @@ var ToastProvider = ({ children, position = "top-right" }) => {
|
|
|
1833
2545
|
removeToast(id);
|
|
1834
2546
|
}, duration);
|
|
1835
2547
|
}, []);
|
|
1836
|
-
const removeToast = (0,
|
|
2548
|
+
const removeToast = (0, import_react19.useCallback)((id) => {
|
|
1837
2549
|
setToasts((prev) => prev.filter((toast2) => toast2.id !== id));
|
|
1838
2550
|
}, []);
|
|
1839
2551
|
const positionClasses2 = {
|
|
@@ -1844,9 +2556,9 @@ var ToastProvider = ({ children, position = "top-right" }) => {
|
|
|
1844
2556
|
"top-center": "top-4 left-1/2 -translate-x-1/2",
|
|
1845
2557
|
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
1846
2558
|
};
|
|
1847
|
-
return /* @__PURE__ */ (0,
|
|
2559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(ToastContext.Provider, { value: { toasts, addToast, removeToast }, children: [
|
|
1848
2560
|
children,
|
|
1849
|
-
/* @__PURE__ */ (0,
|
|
2561
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: `fixed ${positionClasses2[position]} z-50 flex flex-col gap-2 max-w-md`, children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(ToastItem, { toast: toast2, onClose: () => removeToast(toast2.id) }, toast2.id)) })
|
|
1850
2562
|
] });
|
|
1851
2563
|
};
|
|
1852
2564
|
var ToastItem = ({ toast: toast2, onClose }) => {
|
|
@@ -1857,27 +2569,27 @@ var ToastItem = ({ toast: toast2, onClose }) => {
|
|
|
1857
2569
|
info: "bg-blue-50 dark:bg-blue-900/30 border-blue-500 text-blue-800 dark:text-blue-200"
|
|
1858
2570
|
};
|
|
1859
2571
|
const typeIcons = {
|
|
1860
|
-
success: /* @__PURE__ */ (0,
|
|
1861
|
-
error: /* @__PURE__ */ (0,
|
|
1862
|
-
warning: /* @__PURE__ */ (0,
|
|
1863
|
-
info: /* @__PURE__ */ (0,
|
|
2572
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(CheckIcon, { size: "sm", className: "text-green-600 dark:text-green-400" }),
|
|
2573
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(CloseIcon, { size: "sm", className: "text-red-600 dark:text-red-400" }),
|
|
2574
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("svg", { className: "w-4 h-4 text-yellow-600 dark:text-yellow-400", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("path", { fillRule: "evenodd", d: "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z", clipRule: "evenodd" }) }),
|
|
2575
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("svg", { className: "w-4 h-4 text-blue-600 dark:text-blue-400", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) })
|
|
1864
2576
|
};
|
|
1865
2577
|
const type = toast2.type || "info";
|
|
1866
|
-
return /* @__PURE__ */ (0,
|
|
2578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
1867
2579
|
"div",
|
|
1868
2580
|
{
|
|
1869
2581
|
className: `flex items-start gap-3 p-4 rounded-lg border-l-4 shadow-lg backdrop-blur-sm ${typeStyles[type]} animate-slide-in`,
|
|
1870
2582
|
role: "alert",
|
|
1871
2583
|
children: [
|
|
1872
|
-
/* @__PURE__ */ (0,
|
|
1873
|
-
/* @__PURE__ */ (0,
|
|
1874
|
-
/* @__PURE__ */ (0,
|
|
2584
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "flex-shrink-0 mt-0.5", children: typeIcons[type] }),
|
|
2585
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "flex-1 text-sm font-medium", children: toast2.message }),
|
|
2586
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
1875
2587
|
"button",
|
|
1876
2588
|
{
|
|
1877
2589
|
onClick: onClose,
|
|
1878
2590
|
className: "flex-shrink-0 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors",
|
|
1879
2591
|
"aria-label": "Close",
|
|
1880
|
-
children: /* @__PURE__ */ (0,
|
|
2592
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(CloseIcon, { size: "sm" })
|
|
1881
2593
|
}
|
|
1882
2594
|
)
|
|
1883
2595
|
]
|
|
@@ -1908,8 +2620,8 @@ var toast = {
|
|
|
1908
2620
|
};
|
|
1909
2621
|
|
|
1910
2622
|
// src/components/Stepper.tsx
|
|
1911
|
-
var
|
|
1912
|
-
var
|
|
2623
|
+
var import_react20 = __toESM(require("react"));
|
|
2624
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
1913
2625
|
var Stepper = ({
|
|
1914
2626
|
steps,
|
|
1915
2627
|
currentStep,
|
|
@@ -1917,18 +2629,18 @@ var Stepper = ({
|
|
|
1917
2629
|
className = ""
|
|
1918
2630
|
}) => {
|
|
1919
2631
|
const isHorizontal = orientation === "horizontal";
|
|
1920
|
-
return /* @__PURE__ */ (0,
|
|
2632
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: `${isHorizontal ? "flex items-center" : "flex flex-col"} ${className}`, children: steps.map((step, index) => {
|
|
1921
2633
|
const stepNumber = index + 1;
|
|
1922
2634
|
const isActive = stepNumber === currentStep;
|
|
1923
2635
|
const isCompleted = stepNumber < currentStep;
|
|
1924
2636
|
const isLast = index === steps.length - 1;
|
|
1925
|
-
return /* @__PURE__ */ (0,
|
|
1926
|
-
/* @__PURE__ */ (0,
|
|
1927
|
-
/* @__PURE__ */ (0,
|
|
2637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_react20.default.Fragment, { children: [
|
|
2638
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: `flex ${isHorizontal ? "flex-col items-center" : "flex-row items-start"} ${isHorizontal ? "" : "flex-1"}`, children: [
|
|
2639
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
1928
2640
|
"div",
|
|
1929
2641
|
{
|
|
1930
2642
|
className: `flex items-center justify-center w-10 h-10 rounded-full border-2 transition-all ${isCompleted ? "bg-blue-600 border-blue-600 dark:bg-blue-500 dark:border-blue-500" : isActive ? "border-blue-600 bg-white dark:border-blue-500 dark:bg-gray-800" : "border-gray-300 bg-white dark:border-gray-600 dark:bg-gray-800"}`,
|
|
1931
|
-
children: isCompleted ? /* @__PURE__ */ (0,
|
|
2643
|
+
children: isCompleted ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(CheckIcon, { size: "sm", className: "text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
1932
2644
|
"span",
|
|
1933
2645
|
{
|
|
1934
2646
|
className: `text-sm font-semibold ${isActive ? "text-blue-600 dark:text-blue-400" : "text-gray-500 dark:text-gray-400"}`,
|
|
@@ -1937,18 +2649,18 @@ var Stepper = ({
|
|
|
1937
2649
|
)
|
|
1938
2650
|
}
|
|
1939
2651
|
) }),
|
|
1940
|
-
/* @__PURE__ */ (0,
|
|
1941
|
-
/* @__PURE__ */ (0,
|
|
2652
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: `${isHorizontal ? "mt-2 text-center" : "ml-4 pb-8"} ${isLast && !isHorizontal ? "pb-0" : ""}`, children: [
|
|
2653
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
1942
2654
|
"p",
|
|
1943
2655
|
{
|
|
1944
2656
|
className: `text-sm font-medium ${isActive || isCompleted ? "text-gray-900 dark:text-gray-100" : "text-gray-500 dark:text-gray-400"}`,
|
|
1945
2657
|
children: step.label
|
|
1946
2658
|
}
|
|
1947
2659
|
),
|
|
1948
|
-
step.description && /* @__PURE__ */ (0,
|
|
2660
|
+
step.description && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: step.description })
|
|
1949
2661
|
] })
|
|
1950
2662
|
] }),
|
|
1951
|
-
!isLast && /* @__PURE__ */ (0,
|
|
2663
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
1952
2664
|
"div",
|
|
1953
2665
|
{
|
|
1954
2666
|
className: `${isHorizontal ? "flex-1 h-0.5 mx-4" : "w-0.5 h-full ml-5 -mt-8"} ${isCompleted || isActive && stepNumber < currentStep ? "bg-blue-600 dark:bg-blue-500" : "bg-gray-300 dark:bg-gray-600"}`
|
|
@@ -1959,7 +2671,7 @@ var Stepper = ({
|
|
|
1959
2671
|
};
|
|
1960
2672
|
|
|
1961
2673
|
// src/components/Divider.tsx
|
|
1962
|
-
var
|
|
2674
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
1963
2675
|
var Divider = ({
|
|
1964
2676
|
orientation = "horizontal",
|
|
1965
2677
|
variant = "solid",
|
|
@@ -1978,14 +2690,14 @@ var Divider = ({
|
|
|
1978
2690
|
center: "justify-center",
|
|
1979
2691
|
right: "justify-end"
|
|
1980
2692
|
};
|
|
1981
|
-
return /* @__PURE__ */ (0,
|
|
1982
|
-
labelPosition !== "left" && /* @__PURE__ */ (0,
|
|
1983
|
-
/* @__PURE__ */ (0,
|
|
1984
|
-
labelPosition !== "right" && /* @__PURE__ */ (0,
|
|
2693
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: `flex items-center ${alignmentClasses[labelPosition]} ${className}`, role: "separator", children: [
|
|
2694
|
+
labelPosition !== "left" && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: `flex-1 border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600` }),
|
|
2695
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "px-4 text-sm text-gray-500 dark:text-gray-400", children: label }),
|
|
2696
|
+
labelPosition !== "right" && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: `flex-1 border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600` })
|
|
1985
2697
|
] });
|
|
1986
2698
|
}
|
|
1987
2699
|
if (orientation === "vertical") {
|
|
1988
|
-
return /* @__PURE__ */ (0,
|
|
2700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
1989
2701
|
"div",
|
|
1990
2702
|
{
|
|
1991
2703
|
className: `inline-block h-full border-l ${variantClasses[variant]} border-gray-300 dark:border-gray-600 ${className}`,
|
|
@@ -1994,7 +2706,7 @@ var Divider = ({
|
|
|
1994
2706
|
}
|
|
1995
2707
|
);
|
|
1996
2708
|
}
|
|
1997
|
-
return /* @__PURE__ */ (0,
|
|
2709
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
1998
2710
|
"hr",
|
|
1999
2711
|
{
|
|
2000
2712
|
className: `border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600 ${className}`,
|
|
@@ -2004,8 +2716,8 @@ var Divider = ({
|
|
|
2004
2716
|
};
|
|
2005
2717
|
|
|
2006
2718
|
// src/components/FileUpload.tsx
|
|
2007
|
-
var
|
|
2008
|
-
var
|
|
2719
|
+
var import_react21 = require("react");
|
|
2720
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
2009
2721
|
var FileUpload = ({
|
|
2010
2722
|
accept,
|
|
2011
2723
|
multiple = false,
|
|
@@ -2018,9 +2730,9 @@ var FileUpload = ({
|
|
|
2018
2730
|
label,
|
|
2019
2731
|
helperText
|
|
2020
2732
|
}) => {
|
|
2021
|
-
const [files, setFiles] = (0,
|
|
2022
|
-
const [isDragging, setIsDragging] = (0,
|
|
2023
|
-
const fileInputRef = (0,
|
|
2733
|
+
const [files, setFiles] = (0, import_react21.useState)([]);
|
|
2734
|
+
const [isDragging, setIsDragging] = (0, import_react21.useState)(false);
|
|
2735
|
+
const fileInputRef = (0, import_react21.useRef)(null);
|
|
2024
2736
|
const formatFileSize = (bytes) => {
|
|
2025
2737
|
if (bytes === 0) return "0 Bytes";
|
|
2026
2738
|
const k = 1024;
|
|
@@ -2078,9 +2790,9 @@ var FileUpload = ({
|
|
|
2078
2790
|
setFiles(newFiles);
|
|
2079
2791
|
onChange?.(newFiles);
|
|
2080
2792
|
};
|
|
2081
|
-
return /* @__PURE__ */ (0,
|
|
2082
|
-
label && /* @__PURE__ */ (0,
|
|
2083
|
-
/* @__PURE__ */ (0,
|
|
2793
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2794
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: label }),
|
|
2795
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
2084
2796
|
"div",
|
|
2085
2797
|
{
|
|
2086
2798
|
onDrop: handleDrop,
|
|
@@ -2089,7 +2801,7 @@ var FileUpload = ({
|
|
|
2089
2801
|
onClick: handleClick,
|
|
2090
2802
|
className: `relative border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-all ${isDragging ? "border-blue-500 bg-blue-50 dark:bg-blue-900/20" : "border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500"} ${disabled ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
2091
2803
|
children: [
|
|
2092
|
-
/* @__PURE__ */ (0,
|
|
2804
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
2093
2805
|
"input",
|
|
2094
2806
|
{
|
|
2095
2807
|
ref: fileInputRef,
|
|
@@ -2101,14 +2813,14 @@ var FileUpload = ({
|
|
|
2101
2813
|
className: "hidden"
|
|
2102
2814
|
}
|
|
2103
2815
|
),
|
|
2104
|
-
/* @__PURE__ */ (0,
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2107
|
-
/* @__PURE__ */ (0,
|
|
2108
|
-
/* @__PURE__ */ (0,
|
|
2816
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex flex-col items-center gap-2", children: [
|
|
2817
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "w-12 h-12 rounded-full bg-gray-100 dark:bg-gray-800 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(UploadIcon, { size: "lg", className: "text-gray-400 dark:text-gray-500" }) }),
|
|
2818
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { children: [
|
|
2819
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
|
|
2820
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-blue-600 dark:text-blue-400", children: "Click to upload" }),
|
|
2109
2821
|
" or drag and drop"
|
|
2110
2822
|
] }),
|
|
2111
|
-
/* @__PURE__ */ (0,
|
|
2823
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: [
|
|
2112
2824
|
accept ? `Accepted: ${accept}` : "Any file type",
|
|
2113
2825
|
maxSize && ` \u2022 Max size: ${formatFileSize(maxSize)}`
|
|
2114
2826
|
] })
|
|
@@ -2117,17 +2829,17 @@ var FileUpload = ({
|
|
|
2117
2829
|
]
|
|
2118
2830
|
}
|
|
2119
2831
|
),
|
|
2120
|
-
helperText && /* @__PURE__ */ (0,
|
|
2121
|
-
files.length > 0 && /* @__PURE__ */ (0,
|
|
2832
|
+
helperText && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "mt-2 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
2833
|
+
files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "mt-4 space-y-2", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
2122
2834
|
"div",
|
|
2123
2835
|
{
|
|
2124
2836
|
className: "flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700",
|
|
2125
2837
|
children: [
|
|
2126
|
-
/* @__PURE__ */ (0,
|
|
2127
|
-
/* @__PURE__ */ (0,
|
|
2128
|
-
/* @__PURE__ */ (0,
|
|
2838
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
2839
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 truncate", children: file.name }),
|
|
2840
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: formatFileSize(file.size) })
|
|
2129
2841
|
] }),
|
|
2130
|
-
/* @__PURE__ */ (0,
|
|
2842
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
2131
2843
|
"button",
|
|
2132
2844
|
{
|
|
2133
2845
|
onClick: (e) => {
|
|
@@ -2136,7 +2848,7 @@ var FileUpload = ({
|
|
|
2136
2848
|
},
|
|
2137
2849
|
className: "ml-4 text-gray-400 hover:text-red-600 dark:hover:text-red-400 transition-colors",
|
|
2138
2850
|
"aria-label": "Remove file",
|
|
2139
|
-
children: /* @__PURE__ */ (0,
|
|
2851
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(CloseIcon, { size: "sm" })
|
|
2140
2852
|
}
|
|
2141
2853
|
)
|
|
2142
2854
|
]
|
|
@@ -2188,6 +2900,7 @@ function getThemeScript() {
|
|
|
2188
2900
|
Badge,
|
|
2189
2901
|
BellIcon,
|
|
2190
2902
|
Button,
|
|
2903
|
+
Calendar,
|
|
2191
2904
|
CalendarIcon,
|
|
2192
2905
|
CameraIcon,
|
|
2193
2906
|
Card,
|