@marcoschwartz/lite-ui 0.7.1 → 0.10.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 +51 -5
- package/dist/index.d.ts +51 -5
- package/dist/index.js +1127 -282
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1115 -272
- 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,
|
|
@@ -65,6 +66,7 @@ __export(index_exports, {
|
|
|
65
66
|
MenuIcon: () => MenuIcon,
|
|
66
67
|
Modal: () => Modal,
|
|
67
68
|
Navbar: () => Navbar,
|
|
69
|
+
NumberInput: () => NumberInput,
|
|
68
70
|
Pagination: () => Pagination,
|
|
69
71
|
PlusIcon: () => PlusIcon,
|
|
70
72
|
ProgressBar: () => ProgressBar,
|
|
@@ -300,6 +302,9 @@ var Select = ({
|
|
|
300
302
|
value: controlledValue,
|
|
301
303
|
defaultValue,
|
|
302
304
|
onChange,
|
|
305
|
+
label,
|
|
306
|
+
error,
|
|
307
|
+
helperText,
|
|
303
308
|
...props
|
|
304
309
|
}) => {
|
|
305
310
|
const { theme, themeName } = useTheme();
|
|
@@ -334,7 +339,8 @@ var Select = ({
|
|
|
334
339
|
const baseStyles = theme.select.base;
|
|
335
340
|
const sizeStyles2 = theme.select.sizes[size];
|
|
336
341
|
const disabledStyles = disabled ? theme.select.disabled : "";
|
|
337
|
-
const
|
|
342
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
343
|
+
const buttonClasses = `${baseStyles} ${sizeStyles2} ${disabledStyles} ${errorStyles}`.trim();
|
|
338
344
|
const iconColor = themeName === "minimalistic" ? disabled ? "text-gray-600" : "text-white" : disabled ? "text-gray-400" : "text-gray-500";
|
|
339
345
|
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
346
|
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 +350,56 @@ var Select = ({
|
|
|
344
350
|
lg: "px-4 py-3 text-lg",
|
|
345
351
|
xl: "px-5 py-4 text-xl"
|
|
346
352
|
}[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
|
-
|
|
353
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
354
|
+
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 }),
|
|
355
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative inline-block w-full", ref: dropdownRef, ...props, children: [
|
|
356
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
357
|
+
"button",
|
|
358
|
+
{
|
|
359
|
+
type: "button",
|
|
360
|
+
className: buttonClasses,
|
|
361
|
+
onClick: handleToggle,
|
|
362
|
+
disabled,
|
|
363
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: !selectedOption && placeholder ? "opacity-50" : "", children: displayText })
|
|
364
|
+
}
|
|
365
|
+
),
|
|
366
|
+
/* @__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)(
|
|
367
|
+
"svg",
|
|
368
|
+
{
|
|
369
|
+
className: `h-5 w-5 transition-transform duration-200 ${iconColor} ${isOpen ? "rotate-180" : ""}`,
|
|
370
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
371
|
+
viewBox: "0 0 20 20",
|
|
372
|
+
fill: "currentColor",
|
|
373
|
+
"aria-hidden": "true",
|
|
374
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
375
|
+
"path",
|
|
376
|
+
{
|
|
377
|
+
fillRule: "evenodd",
|
|
378
|
+
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",
|
|
379
|
+
clipRule: "evenodd"
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
}
|
|
383
|
+
) }),
|
|
384
|
+
isOpen && !disabled && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
385
|
+
"div",
|
|
386
|
+
{
|
|
387
|
+
className: `absolute z-50 w-full mt-1 ${dropdownBaseStyles} rounded-lg overflow-hidden`,
|
|
388
|
+
style: { maxHeight: "300px", overflowY: "auto" },
|
|
389
|
+
children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
390
|
+
"div",
|
|
391
|
+
{
|
|
392
|
+
className: `${optionBaseStyles} ${optionSizeStyles} cursor-pointer ${value === option.value ? themeName === "minimalistic" ? "bg-white text-black" : "bg-blue-50 dark:bg-gray-700" : ""}`,
|
|
393
|
+
onClick: () => handleSelect(option.value),
|
|
394
|
+
children: option.label
|
|
395
|
+
},
|
|
396
|
+
option.value
|
|
397
|
+
))
|
|
398
|
+
}
|
|
399
|
+
)
|
|
400
|
+
] }),
|
|
401
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
402
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
392
403
|
] });
|
|
393
404
|
};
|
|
394
405
|
|
|
@@ -808,6 +819,7 @@ var AppShell = ({
|
|
|
808
819
|
const [isMobileNavbarOpen, setIsMobileNavbarOpen] = (0, import_react5.useState)(defaultNavbarOpen);
|
|
809
820
|
const navbarWidth = navbar?.width || "md";
|
|
810
821
|
const navbarBreakpoint = navbar?.breakpoint || "md";
|
|
822
|
+
const navbarPosition = navbar?.position || "side";
|
|
811
823
|
const widthClass = widthClasses2[navbarWidth];
|
|
812
824
|
const breakpoint = breakpointClasses[navbarBreakpoint];
|
|
813
825
|
if (!responsive && navbar) {
|
|
@@ -825,6 +837,51 @@ var AppShell = ({
|
|
|
825
837
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("main", { className: "flex-1 overflow-y-auto", children })
|
|
826
838
|
] });
|
|
827
839
|
}
|
|
840
|
+
if (navbar && navbarPosition === "top") {
|
|
841
|
+
const mobileMenuClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
|
|
842
|
+
const desktopNavClass = navbarBreakpoint === "sm" ? "sm:flex" : navbarBreakpoint === "md" ? "md:flex" : navbarBreakpoint === "lg" ? "lg:flex" : "xl:flex";
|
|
843
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: `min-h-screen flex flex-col bg-gray-50 dark:bg-gray-900 ${className}`, children: [
|
|
844
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("nav", { className: "sticky top-0 z-30 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex justify-between items-center h-16", children: [
|
|
845
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "flex items-center", children: navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: navbarTitle }) : null }),
|
|
846
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: `hidden ${desktopNavClass} items-center gap-6`, children: navbar.content }),
|
|
847
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
848
|
+
"button",
|
|
849
|
+
{
|
|
850
|
+
className: `${mobileMenuClass} p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors`,
|
|
851
|
+
onClick: () => setIsMobileNavbarOpen(!isMobileNavbarOpen),
|
|
852
|
+
"aria-label": "Toggle menu",
|
|
853
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(MenuIcon, { size: "md" })
|
|
854
|
+
}
|
|
855
|
+
)
|
|
856
|
+
] }) }) }),
|
|
857
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "w-full", children: header }),
|
|
858
|
+
isMobileNavbarOpen && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
|
|
859
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
860
|
+
"div",
|
|
861
|
+
{
|
|
862
|
+
className: `${mobileMenuClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
|
|
863
|
+
onClick: () => setIsMobileNavbarOpen(false)
|
|
864
|
+
}
|
|
865
|
+
),
|
|
866
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: `${mobileMenuClass} fixed left-0 top-0 bottom-0 z-50 w-64 bg-white dark:bg-gray-800 shadow-2xl animate-in slide-in-from-left duration-300`, children: [
|
|
867
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between", children: [
|
|
868
|
+
navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: navbarTitle }) : null,
|
|
869
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
870
|
+
"button",
|
|
871
|
+
{
|
|
872
|
+
className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
|
|
873
|
+
onClick: () => setIsMobileNavbarOpen(false),
|
|
874
|
+
"aria-label": "Close menu",
|
|
875
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
876
|
+
}
|
|
877
|
+
)
|
|
878
|
+
] }),
|
|
879
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "p-4 flex flex-col gap-4", children: navbar.content })
|
|
880
|
+
] })
|
|
881
|
+
] }),
|
|
882
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("main", { className: "flex-1 overflow-y-auto", children })
|
|
883
|
+
] });
|
|
884
|
+
}
|
|
828
885
|
if (navbar) {
|
|
829
886
|
const mobileHeaderClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
|
|
830
887
|
const desktopNavbarClass = navbarBreakpoint === "sm" ? "sm:block" : navbarBreakpoint === "md" ? "md:block" : navbarBreakpoint === "lg" ? "lg:block" : "xl:block";
|
|
@@ -1027,25 +1084,154 @@ var TextInput = (0, import_react7.forwardRef)(
|
|
|
1027
1084
|
);
|
|
1028
1085
|
TextInput.displayName = "TextInput";
|
|
1029
1086
|
|
|
1030
|
-
// src/components/
|
|
1087
|
+
// src/components/NumberInput.tsx
|
|
1031
1088
|
var import_react8 = require("react");
|
|
1032
|
-
var import_react_dom = require("react-dom");
|
|
1033
1089
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
1090
|
+
var sizeClasses5 = {
|
|
1091
|
+
sm: "px-3 py-1.5 text-sm",
|
|
1092
|
+
md: "px-4 py-2.5 text-base",
|
|
1093
|
+
lg: "px-4 py-3 text-lg"
|
|
1094
|
+
};
|
|
1095
|
+
var NumberInput = ({
|
|
1096
|
+
label,
|
|
1097
|
+
error,
|
|
1098
|
+
helperText,
|
|
1099
|
+
value,
|
|
1100
|
+
onChange,
|
|
1101
|
+
min,
|
|
1102
|
+
max,
|
|
1103
|
+
step = 1,
|
|
1104
|
+
precision,
|
|
1105
|
+
disabled = false,
|
|
1106
|
+
hideControls = false,
|
|
1107
|
+
size = "md",
|
|
1108
|
+
fullWidth = false,
|
|
1109
|
+
placeholder,
|
|
1110
|
+
className = ""
|
|
1111
|
+
}) => {
|
|
1112
|
+
const { theme } = useTheme();
|
|
1113
|
+
const inputRef = (0, import_react8.useRef)(null);
|
|
1114
|
+
const [isFocused, setIsFocused] = (0, import_react8.useState)(false);
|
|
1115
|
+
const clampValue = (val) => {
|
|
1116
|
+
let clamped = val;
|
|
1117
|
+
if (min !== void 0 && clamped < min) clamped = min;
|
|
1118
|
+
if (max !== void 0 && clamped > max) clamped = max;
|
|
1119
|
+
if (precision !== void 0) {
|
|
1120
|
+
clamped = parseFloat(clamped.toFixed(precision));
|
|
1121
|
+
}
|
|
1122
|
+
return clamped;
|
|
1123
|
+
};
|
|
1124
|
+
const handleIncrement = () => {
|
|
1125
|
+
if (disabled) return;
|
|
1126
|
+
const currentValue = value ?? 0;
|
|
1127
|
+
const newValue = clampValue(currentValue + step);
|
|
1128
|
+
onChange?.(newValue);
|
|
1129
|
+
};
|
|
1130
|
+
const handleDecrement = () => {
|
|
1131
|
+
if (disabled) return;
|
|
1132
|
+
const currentValue = value ?? 0;
|
|
1133
|
+
const newValue = clampValue(currentValue - step);
|
|
1134
|
+
onChange?.(newValue);
|
|
1135
|
+
};
|
|
1136
|
+
const handleInputChange = (e) => {
|
|
1137
|
+
const inputValue = e.target.value;
|
|
1138
|
+
if (inputValue === "" || inputValue === "-") {
|
|
1139
|
+
onChange?.(void 0);
|
|
1140
|
+
return;
|
|
1141
|
+
}
|
|
1142
|
+
const numValue = parseFloat(inputValue);
|
|
1143
|
+
if (!isNaN(numValue)) {
|
|
1144
|
+
const clamped = clampValue(numValue);
|
|
1145
|
+
onChange?.(clamped);
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
const handleKeyDown = (e) => {
|
|
1149
|
+
if (e.key === "ArrowUp") {
|
|
1150
|
+
e.preventDefault();
|
|
1151
|
+
handleIncrement();
|
|
1152
|
+
} else if (e.key === "ArrowDown") {
|
|
1153
|
+
e.preventDefault();
|
|
1154
|
+
handleDecrement();
|
|
1155
|
+
}
|
|
1156
|
+
};
|
|
1157
|
+
const baseStyles = "w-full appearance-none rounded-lg border border-gray-300 bg-white text-gray-900 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";
|
|
1158
|
+
const sizeStyle = sizeClasses5[size];
|
|
1159
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
1160
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
1161
|
+
const widthStyle = fullWidth ? "w-full" : "";
|
|
1162
|
+
const paddingWithControls = !hideControls ? "pr-8" : "";
|
|
1163
|
+
const displayValue = value !== void 0 ? value.toString() : "";
|
|
1164
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: `${widthStyle} ${className}`, children: [
|
|
1165
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
1166
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "relative", children: [
|
|
1167
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1168
|
+
"input",
|
|
1169
|
+
{
|
|
1170
|
+
ref: inputRef,
|
|
1171
|
+
type: "number",
|
|
1172
|
+
value: displayValue,
|
|
1173
|
+
onChange: handleInputChange,
|
|
1174
|
+
onKeyDown: handleKeyDown,
|
|
1175
|
+
onFocus: () => setIsFocused(true),
|
|
1176
|
+
onBlur: () => setIsFocused(false),
|
|
1177
|
+
disabled,
|
|
1178
|
+
placeholder,
|
|
1179
|
+
min,
|
|
1180
|
+
max,
|
|
1181
|
+
step,
|
|
1182
|
+
className: `${baseStyles} ${sizeStyle} ${errorStyles} ${disabledStyles} ${paddingWithControls} [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none`.trim()
|
|
1183
|
+
}
|
|
1184
|
+
),
|
|
1185
|
+
!hideControls && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "absolute right-1 top-1/2 -translate-y-1/2 flex flex-col", children: [
|
|
1186
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1187
|
+
"button",
|
|
1188
|
+
{
|
|
1189
|
+
type: "button",
|
|
1190
|
+
onClick: handleIncrement,
|
|
1191
|
+
disabled: disabled || max !== void 0 && value !== void 0 && value >= max,
|
|
1192
|
+
className: "px-2 py-0.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
1193
|
+
tabIndex: -1,
|
|
1194
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("svg", { className: "w-3 h-3 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M5 15l7-7 7 7" }) })
|
|
1195
|
+
}
|
|
1196
|
+
),
|
|
1197
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
1198
|
+
"button",
|
|
1199
|
+
{
|
|
1200
|
+
type: "button",
|
|
1201
|
+
onClick: handleDecrement,
|
|
1202
|
+
disabled: disabled || min !== void 0 && value !== void 0 && value <= min,
|
|
1203
|
+
className: "px-2 py-0.5 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
1204
|
+
tabIndex: -1,
|
|
1205
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("svg", { className: "w-3 h-3 text-gray-600 dark:text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M19 9l-7 7-7-7" }) })
|
|
1206
|
+
}
|
|
1207
|
+
)
|
|
1208
|
+
] })
|
|
1209
|
+
] }),
|
|
1210
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
1211
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
1212
|
+
] });
|
|
1213
|
+
};
|
|
1214
|
+
NumberInput.displayName = "NumberInput";
|
|
1215
|
+
|
|
1216
|
+
// src/components/ActionMenu.tsx
|
|
1217
|
+
var import_react9 = require("react");
|
|
1218
|
+
var import_react_dom = require("react-dom");
|
|
1219
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
1034
1220
|
var ActionMenu = ({
|
|
1035
1221
|
items,
|
|
1036
1222
|
trigger,
|
|
1037
1223
|
position = "right"
|
|
1038
1224
|
}) => {
|
|
1039
1225
|
const { themeName } = useTheme();
|
|
1040
|
-
const [isOpen, setIsOpen] = (0,
|
|
1041
|
-
const [menuPosition, setMenuPosition] = (0,
|
|
1042
|
-
const [mounted, setMounted] = (0,
|
|
1043
|
-
const menuRef = (0,
|
|
1044
|
-
const triggerRef = (0,
|
|
1045
|
-
(0,
|
|
1226
|
+
const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
|
|
1227
|
+
const [menuPosition, setMenuPosition] = (0, import_react9.useState)(null);
|
|
1228
|
+
const [mounted, setMounted] = (0, import_react9.useState)(false);
|
|
1229
|
+
const menuRef = (0, import_react9.useRef)(null);
|
|
1230
|
+
const triggerRef = (0, import_react9.useRef)(null);
|
|
1231
|
+
(0, import_react9.useEffect)(() => {
|
|
1046
1232
|
setMounted(true);
|
|
1047
1233
|
}, []);
|
|
1048
|
-
(0,
|
|
1234
|
+
(0, import_react9.useEffect)(() => {
|
|
1049
1235
|
const handleClickOutside = (event) => {
|
|
1050
1236
|
if (menuRef.current && !menuRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
1051
1237
|
setIsOpen(false);
|
|
@@ -1056,7 +1242,7 @@ var ActionMenu = ({
|
|
|
1056
1242
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1057
1243
|
}
|
|
1058
1244
|
}, [isOpen]);
|
|
1059
|
-
(0,
|
|
1245
|
+
(0, import_react9.useEffect)(() => {
|
|
1060
1246
|
if (isOpen && triggerRef.current) {
|
|
1061
1247
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
1062
1248
|
const menuWidth = 224;
|
|
@@ -1075,17 +1261,17 @@ var ActionMenu = ({
|
|
|
1075
1261
|
setIsOpen(false);
|
|
1076
1262
|
}
|
|
1077
1263
|
};
|
|
1078
|
-
const defaultTrigger = /* @__PURE__ */ (0,
|
|
1264
|
+
const defaultTrigger = /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1079
1265
|
"button",
|
|
1080
1266
|
{
|
|
1081
1267
|
className: "p-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
|
|
1082
1268
|
"aria-label": "Open menu",
|
|
1083
|
-
children: /* @__PURE__ */ (0,
|
|
1269
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("svg", { className: "w-5 h-5 text-gray-600 dark:text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" }) })
|
|
1084
1270
|
}
|
|
1085
1271
|
);
|
|
1086
1272
|
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";
|
|
1087
1273
|
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";
|
|
1088
|
-
const menu = isOpen && mounted && menuPosition ? /* @__PURE__ */ (0,
|
|
1274
|
+
const menu = isOpen && mounted && menuPosition ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1089
1275
|
"div",
|
|
1090
1276
|
{
|
|
1091
1277
|
ref: menuRef,
|
|
@@ -1097,7 +1283,7 @@ var ActionMenu = ({
|
|
|
1097
1283
|
},
|
|
1098
1284
|
children: items.map((item, index) => {
|
|
1099
1285
|
if (item.type === "divider") {
|
|
1100
|
-
return /* @__PURE__ */ (0,
|
|
1286
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
1101
1287
|
"div",
|
|
1102
1288
|
{
|
|
1103
1289
|
className: "my-1 border-t border-gray-200 dark:border-gray-700"
|
|
@@ -1105,15 +1291,15 @@ var ActionMenu = ({
|
|
|
1105
1291
|
index
|
|
1106
1292
|
);
|
|
1107
1293
|
}
|
|
1108
|
-
return /* @__PURE__ */ (0,
|
|
1294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
1109
1295
|
"button",
|
|
1110
1296
|
{
|
|
1111
1297
|
onClick: () => handleItemClick(item),
|
|
1112
1298
|
disabled: item.disabled,
|
|
1113
1299
|
className: `w-full text-left px-4 py-3 flex items-center gap-3 ${itemBaseStyles} ${item.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"} ${item.variant === "danger" ? "text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20" : ""}`,
|
|
1114
1300
|
children: [
|
|
1115
|
-
item.icon && /* @__PURE__ */ (0,
|
|
1116
|
-
/* @__PURE__ */ (0,
|
|
1301
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "flex-shrink-0", children: item.icon }),
|
|
1302
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "flex-1", children: item.label })
|
|
1117
1303
|
]
|
|
1118
1304
|
},
|
|
1119
1305
|
index
|
|
@@ -1121,14 +1307,14 @@ var ActionMenu = ({
|
|
|
1121
1307
|
})
|
|
1122
1308
|
}
|
|
1123
1309
|
) : null;
|
|
1124
|
-
return /* @__PURE__ */ (0,
|
|
1125
|
-
/* @__PURE__ */ (0,
|
|
1310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
|
|
1311
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "relative inline-block", ref: triggerRef, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { onClick: () => setIsOpen(!isOpen), children: trigger || defaultTrigger }) }),
|
|
1126
1312
|
mounted && (0, import_react_dom.createPortal)(menu, document.body)
|
|
1127
1313
|
] });
|
|
1128
1314
|
};
|
|
1129
1315
|
|
|
1130
1316
|
// src/components/Card.tsx
|
|
1131
|
-
var
|
|
1317
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
1132
1318
|
var paddingClasses = {
|
|
1133
1319
|
none: "",
|
|
1134
1320
|
sm: "p-4",
|
|
@@ -1143,8 +1329,8 @@ var Card = ({
|
|
|
1143
1329
|
}) => {
|
|
1144
1330
|
const { theme } = useTheme();
|
|
1145
1331
|
const paddingClass = paddingClasses[padding];
|
|
1146
|
-
const hoverClass = hover ? "hover:shadow-
|
|
1147
|
-
return /* @__PURE__ */ (0,
|
|
1332
|
+
const hoverClass = hover ? "hover:shadow-xl hover:scale-[1.02] hover:border-blue-400 dark:hover:border-blue-500 cursor-pointer transition-all duration-200 ease-in-out" : "";
|
|
1333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
1148
1334
|
"div",
|
|
1149
1335
|
{
|
|
1150
1336
|
className: `bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 ${paddingClass} ${hoverClass} ${className}`,
|
|
@@ -1154,7 +1340,7 @@ var Card = ({
|
|
|
1154
1340
|
};
|
|
1155
1341
|
|
|
1156
1342
|
// src/components/Alert.tsx
|
|
1157
|
-
var
|
|
1343
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
1158
1344
|
var variantStyles = {
|
|
1159
1345
|
info: "bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 text-blue-900 dark:text-blue-100",
|
|
1160
1346
|
success: "bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800 text-green-900 dark:text-green-100",
|
|
@@ -1177,38 +1363,38 @@ var Alert = ({
|
|
|
1177
1363
|
const { theme } = useTheme();
|
|
1178
1364
|
const variantClass = variantStyles[variant];
|
|
1179
1365
|
const iconClass = iconStyles[variant];
|
|
1180
|
-
return /* @__PURE__ */ (0,
|
|
1181
|
-
/* @__PURE__ */ (0,
|
|
1182
|
-
variant === "info" && /* @__PURE__ */ (0,
|
|
1183
|
-
variant === "success" && /* @__PURE__ */ (0,
|
|
1184
|
-
variant === "warning" && /* @__PURE__ */ (0,
|
|
1185
|
-
variant === "error" && /* @__PURE__ */ (0,
|
|
1366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: `rounded-lg border p-4 ${variantClass} ${className}`, role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
1367
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: `flex-shrink-0 ${iconClass}`, children: [
|
|
1368
|
+
variant === "info" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime44.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" }) }),
|
|
1369
|
+
variant === "success" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z", clipRule: "evenodd" }) }),
|
|
1370
|
+
variant === "warning" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime44.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" }) }),
|
|
1371
|
+
variant === "error" && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z", clipRule: "evenodd" }) })
|
|
1186
1372
|
] }),
|
|
1187
|
-
/* @__PURE__ */ (0,
|
|
1188
|
-
title && /* @__PURE__ */ (0,
|
|
1189
|
-
/* @__PURE__ */ (0,
|
|
1373
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex-1", children: [
|
|
1374
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h3", { className: "font-semibold mb-1", children: title }),
|
|
1375
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "text-sm", children })
|
|
1190
1376
|
] }),
|
|
1191
|
-
onClose && /* @__PURE__ */ (0,
|
|
1377
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
1192
1378
|
"button",
|
|
1193
1379
|
{
|
|
1194
1380
|
onClick: onClose,
|
|
1195
1381
|
className: `flex-shrink-0 ${iconClass} hover:opacity-70 transition-opacity`,
|
|
1196
1382
|
"aria-label": "Close alert",
|
|
1197
|
-
children: /* @__PURE__ */ (0,
|
|
1383
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
1198
1384
|
}
|
|
1199
1385
|
)
|
|
1200
1386
|
] }) });
|
|
1201
1387
|
};
|
|
1202
1388
|
|
|
1203
1389
|
// src/components/Checkbox.tsx
|
|
1204
|
-
var
|
|
1205
|
-
var
|
|
1206
|
-
var Checkbox = (0,
|
|
1390
|
+
var import_react10 = require("react");
|
|
1391
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
1392
|
+
var Checkbox = (0, import_react10.forwardRef)(
|
|
1207
1393
|
({ label, error, className = "", disabled, ...props }, ref) => {
|
|
1208
1394
|
const { theme } = useTheme();
|
|
1209
|
-
return /* @__PURE__ */ (0,
|
|
1210
|
-
/* @__PURE__ */ (0,
|
|
1211
|
-
/* @__PURE__ */ (0,
|
|
1395
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className, children: [
|
|
1396
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer group", children: [
|
|
1397
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
1212
1398
|
"input",
|
|
1213
1399
|
{
|
|
1214
1400
|
ref,
|
|
@@ -1218,18 +1404,18 @@ var Checkbox = (0, import_react9.forwardRef)(
|
|
|
1218
1404
|
...props
|
|
1219
1405
|
}
|
|
1220
1406
|
),
|
|
1221
|
-
label && /* @__PURE__ */ (0,
|
|
1407
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: `text-sm text-gray-700 dark:text-gray-300 ${disabled ? "opacity-50 cursor-not-allowed" : "group-hover:text-gray-900 dark:group-hover:text-gray-100"}`, children: label })
|
|
1222
1408
|
] }),
|
|
1223
|
-
error && /* @__PURE__ */ (0,
|
|
1409
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error })
|
|
1224
1410
|
] });
|
|
1225
1411
|
}
|
|
1226
1412
|
);
|
|
1227
1413
|
Checkbox.displayName = "Checkbox";
|
|
1228
1414
|
|
|
1229
1415
|
// src/components/Toggle.tsx
|
|
1230
|
-
var
|
|
1231
|
-
var
|
|
1232
|
-
var Toggle = (0,
|
|
1416
|
+
var import_react11 = require("react");
|
|
1417
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
1418
|
+
var Toggle = (0, import_react11.forwardRef)(
|
|
1233
1419
|
({ label, size = "md", className = "", disabled, checked, ...props }, ref) => {
|
|
1234
1420
|
const { theme } = useTheme();
|
|
1235
1421
|
const toggleClasses = {
|
|
@@ -1247,9 +1433,9 @@ var Toggle = (0, import_react10.forwardRef)(
|
|
|
1247
1433
|
}
|
|
1248
1434
|
};
|
|
1249
1435
|
const currentSize = toggleClasses[size];
|
|
1250
|
-
return /* @__PURE__ */ (0,
|
|
1251
|
-
/* @__PURE__ */ (0,
|
|
1252
|
-
/* @__PURE__ */ (0,
|
|
1436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("label", { className: `inline-flex items-center gap-3 cursor-pointer ${disabled ? "opacity-50 cursor-not-allowed" : ""} ${className}`, children: [
|
|
1437
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "relative", children: [
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
1253
1439
|
"input",
|
|
1254
1440
|
{
|
|
1255
1441
|
ref,
|
|
@@ -1260,27 +1446,27 @@ var Toggle = (0, import_react10.forwardRef)(
|
|
|
1260
1446
|
...props
|
|
1261
1447
|
}
|
|
1262
1448
|
),
|
|
1263
|
-
/* @__PURE__ */ (0,
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
1264
1450
|
"div",
|
|
1265
1451
|
{
|
|
1266
1452
|
className: `${currentSize.switch} bg-gray-300 dark:bg-gray-700 peer-focus:ring-2 peer-focus:ring-blue-500 rounded-full peer peer-checked:bg-blue-600 dark:peer-checked:bg-blue-500 transition-colors`
|
|
1267
1453
|
}
|
|
1268
1454
|
),
|
|
1269
|
-
/* @__PURE__ */ (0,
|
|
1455
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
1270
1456
|
"div",
|
|
1271
1457
|
{
|
|
1272
1458
|
className: `${currentSize.thumb} bg-white rounded-full shadow-md absolute top-0.5 left-0.5 transition-transform`
|
|
1273
1459
|
}
|
|
1274
1460
|
)
|
|
1275
1461
|
] }),
|
|
1276
|
-
label && /* @__PURE__ */ (0,
|
|
1462
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label })
|
|
1277
1463
|
] });
|
|
1278
1464
|
}
|
|
1279
1465
|
);
|
|
1280
1466
|
Toggle.displayName = "Toggle";
|
|
1281
1467
|
|
|
1282
1468
|
// src/components/Badge.tsx
|
|
1283
|
-
var
|
|
1469
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
1284
1470
|
var variantStyles2 = {
|
|
1285
1471
|
default: "bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200",
|
|
1286
1472
|
primary: "bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200",
|
|
@@ -1303,12 +1489,12 @@ var Badge = ({
|
|
|
1303
1489
|
const { theme } = useTheme();
|
|
1304
1490
|
const variantClass = variantStyles2[variant];
|
|
1305
1491
|
const sizeClass = sizeStyles[size];
|
|
1306
|
-
return /* @__PURE__ */ (0,
|
|
1492
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: `inline-flex items-center font-medium rounded-full ${variantClass} ${sizeClass} ${className}`, children });
|
|
1307
1493
|
};
|
|
1308
1494
|
|
|
1309
1495
|
// src/components/Spinner.tsx
|
|
1310
|
-
var
|
|
1311
|
-
var
|
|
1496
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
1497
|
+
var sizeClasses6 = {
|
|
1312
1498
|
sm: "w-4 h-4 border-2",
|
|
1313
1499
|
md: "w-8 h-8 border-2",
|
|
1314
1500
|
lg: "w-12 h-12 border-3",
|
|
@@ -1325,22 +1511,22 @@ var Spinner = ({
|
|
|
1325
1511
|
className = ""
|
|
1326
1512
|
}) => {
|
|
1327
1513
|
const { theme } = useTheme();
|
|
1328
|
-
const sizeClass =
|
|
1514
|
+
const sizeClass = sizeClasses6[size];
|
|
1329
1515
|
const colorClass = colorClasses[color];
|
|
1330
|
-
return /* @__PURE__ */ (0,
|
|
1516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
1331
1517
|
"div",
|
|
1332
1518
|
{
|
|
1333
1519
|
className: `inline-block rounded-full animate-spin ${sizeClass} ${colorClass} ${className}`,
|
|
1334
1520
|
role: "status",
|
|
1335
1521
|
"aria-label": "Loading",
|
|
1336
|
-
children: /* @__PURE__ */ (0,
|
|
1522
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "sr-only", children: "Loading..." })
|
|
1337
1523
|
}
|
|
1338
1524
|
);
|
|
1339
1525
|
};
|
|
1340
1526
|
|
|
1341
1527
|
// src/components/Tabs.tsx
|
|
1342
|
-
var
|
|
1343
|
-
var
|
|
1528
|
+
var import_react12 = require("react");
|
|
1529
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
1344
1530
|
var Tabs = ({
|
|
1345
1531
|
tabs,
|
|
1346
1532
|
defaultIndex = 0,
|
|
@@ -1348,14 +1534,14 @@ var Tabs = ({
|
|
|
1348
1534
|
className = ""
|
|
1349
1535
|
}) => {
|
|
1350
1536
|
const { theme } = useTheme();
|
|
1351
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
1537
|
+
const [activeIndex, setActiveIndex] = (0, import_react12.useState)(defaultIndex);
|
|
1352
1538
|
const handleTabClick = (index) => {
|
|
1353
1539
|
if (tabs[index].disabled) return;
|
|
1354
1540
|
setActiveIndex(index);
|
|
1355
1541
|
onChange?.(index);
|
|
1356
1542
|
};
|
|
1357
|
-
return /* @__PURE__ */ (0,
|
|
1358
|
-
/* @__PURE__ */ (0,
|
|
1543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className, children: [
|
|
1544
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("nav", { className: "flex gap-8 px-6", "aria-label": "Tabs", children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
1359
1545
|
"button",
|
|
1360
1546
|
{
|
|
1361
1547
|
onClick: () => handleTabClick(index),
|
|
@@ -1366,12 +1552,12 @@ var Tabs = ({
|
|
|
1366
1552
|
},
|
|
1367
1553
|
index
|
|
1368
1554
|
)) }) }),
|
|
1369
|
-
/* @__PURE__ */ (0,
|
|
1555
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { children: tabs[activeIndex]?.content })
|
|
1370
1556
|
] });
|
|
1371
1557
|
};
|
|
1372
1558
|
|
|
1373
1559
|
// src/components/Table.tsx
|
|
1374
|
-
var
|
|
1560
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
1375
1561
|
function Table({
|
|
1376
1562
|
columns,
|
|
1377
1563
|
data,
|
|
@@ -1381,11 +1567,11 @@ function Table({
|
|
|
1381
1567
|
className = ""
|
|
1382
1568
|
}) {
|
|
1383
1569
|
const { theme } = useTheme();
|
|
1384
|
-
return /* @__PURE__ */ (0,
|
|
1385
|
-
/* @__PURE__ */ (0,
|
|
1386
|
-
/* @__PURE__ */ (0,
|
|
1570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: `overflow-x-auto ${className}`, children: [
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("table", { className: "w-full text-left", children: [
|
|
1572
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("thead", { className: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("tr", { children: columns.map((column, colIndex) => {
|
|
1387
1573
|
const isLast = colIndex === columns.length - 1;
|
|
1388
|
-
return /* @__PURE__ */ (0,
|
|
1574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
1389
1575
|
"th",
|
|
1390
1576
|
{
|
|
1391
1577
|
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",
|
|
@@ -1395,18 +1581,18 @@ function Table({
|
|
|
1395
1581
|
column.key
|
|
1396
1582
|
);
|
|
1397
1583
|
}) }) }),
|
|
1398
|
-
/* @__PURE__ */ (0,
|
|
1584
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700", children: data.map((row, rowIndex) => {
|
|
1399
1585
|
const rowClasses = [
|
|
1400
1586
|
striped && rowIndex % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : "",
|
|
1401
1587
|
hoverable ? "hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" : ""
|
|
1402
1588
|
].filter(Boolean).join(" ");
|
|
1403
|
-
return /* @__PURE__ */ (0,
|
|
1589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
1404
1590
|
"tr",
|
|
1405
1591
|
{
|
|
1406
1592
|
className: rowClasses,
|
|
1407
1593
|
children: columns.map((column, colIndex) => {
|
|
1408
1594
|
const isLast = colIndex === columns.length - 1;
|
|
1409
|
-
return /* @__PURE__ */ (0,
|
|
1595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
1410
1596
|
"td",
|
|
1411
1597
|
{
|
|
1412
1598
|
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",
|
|
@@ -1420,12 +1606,12 @@ function Table({
|
|
|
1420
1606
|
);
|
|
1421
1607
|
}) })
|
|
1422
1608
|
] }),
|
|
1423
|
-
data.length === 0 && /* @__PURE__ */ (0,
|
|
1609
|
+
data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "text-center py-8 text-gray-500 dark:text-gray-400", children: "No data available" })
|
|
1424
1610
|
] });
|
|
1425
1611
|
}
|
|
1426
1612
|
|
|
1427
1613
|
// src/components/Pagination.tsx
|
|
1428
|
-
var
|
|
1614
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
1429
1615
|
var Pagination = ({
|
|
1430
1616
|
currentPage,
|
|
1431
1617
|
totalPages,
|
|
@@ -1466,8 +1652,8 @@ var Pagination = ({
|
|
|
1466
1652
|
return range(1, totalPages);
|
|
1467
1653
|
};
|
|
1468
1654
|
const pages = paginationRange();
|
|
1469
|
-
return /* @__PURE__ */ (0,
|
|
1470
|
-
/* @__PURE__ */ (0,
|
|
1655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("nav", { className: `flex items-center gap-1 ${className}`, "aria-label": "Pagination", children: [
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1471
1657
|
"button",
|
|
1472
1658
|
{
|
|
1473
1659
|
onClick: () => onPageChange(currentPage - 1),
|
|
@@ -1479,7 +1665,7 @@ var Pagination = ({
|
|
|
1479
1665
|
),
|
|
1480
1666
|
pages.map((page, index) => {
|
|
1481
1667
|
if (page === "...") {
|
|
1482
|
-
return /* @__PURE__ */ (0,
|
|
1668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1483
1669
|
"span",
|
|
1484
1670
|
{
|
|
1485
1671
|
className: "px-3 py-2 text-gray-700 dark:text-gray-300",
|
|
@@ -1488,7 +1674,7 @@ var Pagination = ({
|
|
|
1488
1674
|
`dots-${index}`
|
|
1489
1675
|
);
|
|
1490
1676
|
}
|
|
1491
|
-
return /* @__PURE__ */ (0,
|
|
1677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1492
1678
|
"button",
|
|
1493
1679
|
{
|
|
1494
1680
|
onClick: () => onPageChange(page),
|
|
@@ -1500,7 +1686,7 @@ var Pagination = ({
|
|
|
1500
1686
|
page
|
|
1501
1687
|
);
|
|
1502
1688
|
}),
|
|
1503
|
-
/* @__PURE__ */ (0,
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1504
1690
|
"button",
|
|
1505
1691
|
{
|
|
1506
1692
|
onClick: () => onPageChange(currentPage + 1),
|
|
@@ -1514,65 +1700,227 @@ var Pagination = ({
|
|
|
1514
1700
|
};
|
|
1515
1701
|
|
|
1516
1702
|
// src/components/DatePicker.tsx
|
|
1517
|
-
var import_react12 = require("react");
|
|
1518
|
-
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
1519
|
-
var DatePicker = (0, import_react12.forwardRef)(
|
|
1520
|
-
({ label, error, helperText, className = "", disabled, ...props }, ref) => {
|
|
1521
|
-
const { theme } = useTheme();
|
|
1522
|
-
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";
|
|
1523
|
-
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
1524
|
-
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
1525
|
-
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className, children: [
|
|
1526
|
-
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 }),
|
|
1527
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
1528
|
-
"input",
|
|
1529
|
-
{
|
|
1530
|
-
ref,
|
|
1531
|
-
type: "date",
|
|
1532
|
-
disabled,
|
|
1533
|
-
className: `${baseStyles} ${errorStyles} ${disabledStyles}`.trim(),
|
|
1534
|
-
...props
|
|
1535
|
-
}
|
|
1536
|
-
),
|
|
1537
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
1538
|
-
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
1539
|
-
] });
|
|
1540
|
-
}
|
|
1541
|
-
);
|
|
1542
|
-
DatePicker.displayName = "DatePicker";
|
|
1543
|
-
|
|
1544
|
-
// src/components/TimePicker.tsx
|
|
1545
1703
|
var import_react13 = require("react");
|
|
1704
|
+
var import_react_dom2 = require("react-dom");
|
|
1546
1705
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
1547
|
-
var
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1706
|
+
var DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
1707
|
+
var MONTHS = [
|
|
1708
|
+
"January",
|
|
1709
|
+
"February",
|
|
1710
|
+
"March",
|
|
1711
|
+
"April",
|
|
1712
|
+
"May",
|
|
1713
|
+
"June",
|
|
1714
|
+
"July",
|
|
1715
|
+
"August",
|
|
1716
|
+
"September",
|
|
1717
|
+
"October",
|
|
1718
|
+
"November",
|
|
1719
|
+
"December"
|
|
1720
|
+
];
|
|
1721
|
+
var DatePicker = ({
|
|
1722
|
+
label,
|
|
1723
|
+
error,
|
|
1724
|
+
helperText,
|
|
1725
|
+
value,
|
|
1726
|
+
onChange,
|
|
1727
|
+
minDate,
|
|
1728
|
+
maxDate,
|
|
1729
|
+
disabled,
|
|
1730
|
+
className = "",
|
|
1731
|
+
placeholder = "Select date..."
|
|
1732
|
+
}) => {
|
|
1733
|
+
const { theme } = useTheme();
|
|
1734
|
+
const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
|
|
1735
|
+
const [viewDate, setViewDate] = (0, import_react13.useState)(value || /* @__PURE__ */ new Date());
|
|
1736
|
+
const [mounted, setMounted] = (0, import_react13.useState)(false);
|
|
1737
|
+
const [calendarPosition, setCalendarPosition] = (0, import_react13.useState)(null);
|
|
1738
|
+
const inputRef = (0, import_react13.useRef)(null);
|
|
1739
|
+
const calendarRef = (0, import_react13.useRef)(null);
|
|
1740
|
+
(0, import_react13.useEffect)(() => {
|
|
1741
|
+
setMounted(true);
|
|
1742
|
+
}, []);
|
|
1743
|
+
(0, import_react13.useEffect)(() => {
|
|
1744
|
+
const handleClickOutside = (event) => {
|
|
1745
|
+
if (calendarRef.current && !calendarRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
|
|
1746
|
+
setIsOpen(false);
|
|
1747
|
+
}
|
|
1748
|
+
};
|
|
1749
|
+
if (isOpen) {
|
|
1750
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1751
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1752
|
+
}
|
|
1753
|
+
}, [isOpen]);
|
|
1754
|
+
(0, import_react13.useEffect)(() => {
|
|
1755
|
+
if (isOpen && inputRef.current) {
|
|
1756
|
+
const rect = inputRef.current.getBoundingClientRect();
|
|
1757
|
+
setCalendarPosition({
|
|
1758
|
+
top: rect.bottom + 8,
|
|
1759
|
+
left: rect.left
|
|
1760
|
+
});
|
|
1761
|
+
} else {
|
|
1762
|
+
setCalendarPosition(null);
|
|
1763
|
+
}
|
|
1764
|
+
}, [isOpen]);
|
|
1765
|
+
const year = viewDate.getFullYear();
|
|
1766
|
+
const month = viewDate.getMonth();
|
|
1767
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
1768
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
1769
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
1770
|
+
const calendarDays = [];
|
|
1771
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
1772
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
1568
1773
|
}
|
|
1569
|
-
)
|
|
1570
|
-
|
|
1774
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
1775
|
+
calendarDays.push(new Date(year, month, i));
|
|
1776
|
+
}
|
|
1777
|
+
const remainingDays = 42 - calendarDays.length;
|
|
1778
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
1779
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
1780
|
+
}
|
|
1781
|
+
const isSameDay = (date1, date2) => {
|
|
1782
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
1783
|
+
};
|
|
1784
|
+
const isToday = (date) => {
|
|
1785
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
1786
|
+
};
|
|
1787
|
+
const isSelected = (date) => {
|
|
1788
|
+
return value && isSameDay(date, value);
|
|
1789
|
+
};
|
|
1790
|
+
const isCurrentMonth = (date) => {
|
|
1791
|
+
return date.getMonth() === month;
|
|
1792
|
+
};
|
|
1793
|
+
const isDisabled = (date) => {
|
|
1794
|
+
if (minDate && date < minDate) return true;
|
|
1795
|
+
if (maxDate && date > maxDate) return true;
|
|
1796
|
+
return false;
|
|
1797
|
+
};
|
|
1798
|
+
const handleDateClick = (date) => {
|
|
1799
|
+
if (isDisabled(date)) return;
|
|
1800
|
+
onChange?.(date);
|
|
1801
|
+
setIsOpen(false);
|
|
1802
|
+
};
|
|
1803
|
+
const handlePrevMonth = () => {
|
|
1804
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
1805
|
+
};
|
|
1806
|
+
const handleNextMonth = () => {
|
|
1807
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
1808
|
+
};
|
|
1809
|
+
const handleToday = () => {
|
|
1810
|
+
const today = /* @__PURE__ */ new Date();
|
|
1811
|
+
setViewDate(today);
|
|
1812
|
+
onChange?.(today);
|
|
1813
|
+
setIsOpen(false);
|
|
1814
|
+
};
|
|
1815
|
+
const formatDate = (date) => {
|
|
1816
|
+
if (!date) return "";
|
|
1817
|
+
return date.toLocaleDateString("en-US", {
|
|
1818
|
+
month: "short",
|
|
1819
|
+
day: "numeric",
|
|
1820
|
+
year: "numeric"
|
|
1821
|
+
});
|
|
1822
|
+
};
|
|
1823
|
+
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";
|
|
1824
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
1825
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
1826
|
+
const calendar = isOpen && mounted && calendarPosition ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
1827
|
+
"div",
|
|
1828
|
+
{
|
|
1829
|
+
ref: calendarRef,
|
|
1830
|
+
className: "fixed z-[9999] bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-xl p-4",
|
|
1831
|
+
style: {
|
|
1832
|
+
top: `${calendarPosition.top}px`,
|
|
1833
|
+
left: `${calendarPosition.left}px`,
|
|
1834
|
+
minWidth: "320px"
|
|
1835
|
+
},
|
|
1836
|
+
children: [
|
|
1837
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
1838
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
1839
|
+
"button",
|
|
1840
|
+
{
|
|
1841
|
+
onClick: handlePrevMonth,
|
|
1842
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
1843
|
+
"aria-label": "Previous month",
|
|
1844
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.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_runtime52.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
1845
|
+
}
|
|
1846
|
+
),
|
|
1847
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1848
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("h2", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
1849
|
+
MONTHS[month],
|
|
1850
|
+
" ",
|
|
1851
|
+
year
|
|
1852
|
+
] }),
|
|
1853
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
1854
|
+
"button",
|
|
1855
|
+
{
|
|
1856
|
+
onClick: handleToday,
|
|
1857
|
+
className: "px-2 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
1858
|
+
children: "Today"
|
|
1859
|
+
}
|
|
1860
|
+
)
|
|
1861
|
+
] }),
|
|
1862
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
1863
|
+
"button",
|
|
1864
|
+
{
|
|
1865
|
+
onClick: handleNextMonth,
|
|
1866
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
1867
|
+
"aria-label": "Next month",
|
|
1868
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.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_runtime52.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
1869
|
+
}
|
|
1870
|
+
)
|
|
1871
|
+
] }),
|
|
1872
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-1", children: day }, day)) }),
|
|
1873
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
|
|
1874
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
1875
|
+
const isTodayDay = isToday(date);
|
|
1876
|
+
const isSelectedDay = isSelected(date);
|
|
1877
|
+
const isDisabledDay = isDisabled(date);
|
|
1878
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
1879
|
+
"button",
|
|
1880
|
+
{
|
|
1881
|
+
onClick: () => handleDateClick(date),
|
|
1882
|
+
disabled: isDisabledDay,
|
|
1883
|
+
className: `
|
|
1884
|
+
aspect-square p-1 rounded-lg text-sm font-medium transition-all
|
|
1885
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
1886
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
1887
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
1888
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
1889
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
1890
|
+
`,
|
|
1891
|
+
children: date.getDate()
|
|
1892
|
+
},
|
|
1893
|
+
index
|
|
1894
|
+
);
|
|
1895
|
+
}) })
|
|
1896
|
+
]
|
|
1897
|
+
}
|
|
1898
|
+
) : null;
|
|
1899
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className, children: [
|
|
1900
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
1901
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
1902
|
+
"div",
|
|
1903
|
+
{
|
|
1904
|
+
ref: inputRef,
|
|
1905
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
1906
|
+
className: `${baseStyles} ${errorStyles} ${disabledStyles} flex items-center justify-between`.trim(),
|
|
1907
|
+
children: [
|
|
1908
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: !value ? "text-gray-500 dark:text-gray-400" : "", children: value ? formatDate(value) : placeholder }),
|
|
1909
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("svg", { className: "w-5 h-5 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime52.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" }) })
|
|
1910
|
+
]
|
|
1911
|
+
}
|
|
1912
|
+
),
|
|
1913
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
1914
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
1915
|
+
mounted && (0, import_react_dom2.createPortal)(calendar, document.body)
|
|
1916
|
+
] });
|
|
1917
|
+
};
|
|
1918
|
+
DatePicker.displayName = "DatePicker";
|
|
1571
1919
|
|
|
1572
|
-
// src/components/
|
|
1920
|
+
// src/components/TimePicker.tsx
|
|
1573
1921
|
var import_react14 = require("react");
|
|
1574
1922
|
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
1575
|
-
var
|
|
1923
|
+
var TimePicker = (0, import_react14.forwardRef)(
|
|
1576
1924
|
({ label, error, helperText, className = "", disabled, ...props }, ref) => {
|
|
1577
1925
|
const { theme } = useTheme();
|
|
1578
1926
|
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";
|
|
@@ -1584,7 +1932,7 @@ var DateTimePicker = (0, import_react14.forwardRef)(
|
|
|
1584
1932
|
"input",
|
|
1585
1933
|
{
|
|
1586
1934
|
ref,
|
|
1587
|
-
type: "
|
|
1935
|
+
type: "time",
|
|
1588
1936
|
disabled,
|
|
1589
1937
|
className: `${baseStyles} ${errorStyles} ${disabledStyles}`.trim(),
|
|
1590
1938
|
...props
|
|
@@ -1595,11 +1943,506 @@ var DateTimePicker = (0, import_react14.forwardRef)(
|
|
|
1595
1943
|
] });
|
|
1596
1944
|
}
|
|
1597
1945
|
);
|
|
1946
|
+
TimePicker.displayName = "TimePicker";
|
|
1947
|
+
|
|
1948
|
+
// src/components/DateTimePicker.tsx
|
|
1949
|
+
var import_react15 = require("react");
|
|
1950
|
+
var import_react_dom3 = require("react-dom");
|
|
1951
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
1952
|
+
var DAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
1953
|
+
var MONTHS2 = [
|
|
1954
|
+
"January",
|
|
1955
|
+
"February",
|
|
1956
|
+
"March",
|
|
1957
|
+
"April",
|
|
1958
|
+
"May",
|
|
1959
|
+
"June",
|
|
1960
|
+
"July",
|
|
1961
|
+
"August",
|
|
1962
|
+
"September",
|
|
1963
|
+
"October",
|
|
1964
|
+
"November",
|
|
1965
|
+
"December"
|
|
1966
|
+
];
|
|
1967
|
+
var DateTimePicker = ({
|
|
1968
|
+
label,
|
|
1969
|
+
error,
|
|
1970
|
+
helperText,
|
|
1971
|
+
value,
|
|
1972
|
+
onChange,
|
|
1973
|
+
minDate,
|
|
1974
|
+
maxDate,
|
|
1975
|
+
disabled,
|
|
1976
|
+
className = "",
|
|
1977
|
+
placeholder = "Select date and time..."
|
|
1978
|
+
}) => {
|
|
1979
|
+
const { theme } = useTheme();
|
|
1980
|
+
const [isOpen, setIsOpen] = (0, import_react15.useState)(false);
|
|
1981
|
+
const [viewDate, setViewDate] = (0, import_react15.useState)(value || /* @__PURE__ */ new Date());
|
|
1982
|
+
const [selectedTime, setSelectedTime] = (0, import_react15.useState)(
|
|
1983
|
+
value ? { hours: value.getHours(), minutes: value.getMinutes() } : { hours: 12, minutes: 0 }
|
|
1984
|
+
);
|
|
1985
|
+
const [mounted, setMounted] = (0, import_react15.useState)(false);
|
|
1986
|
+
const [pickerPosition, setPickerPosition] = (0, import_react15.useState)(null);
|
|
1987
|
+
const inputRef = (0, import_react15.useRef)(null);
|
|
1988
|
+
const pickerRef = (0, import_react15.useRef)(null);
|
|
1989
|
+
(0, import_react15.useEffect)(() => {
|
|
1990
|
+
setMounted(true);
|
|
1991
|
+
}, []);
|
|
1992
|
+
(0, import_react15.useEffect)(() => {
|
|
1993
|
+
const handleClickOutside = (event) => {
|
|
1994
|
+
if (pickerRef.current && !pickerRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
|
|
1995
|
+
setIsOpen(false);
|
|
1996
|
+
}
|
|
1997
|
+
};
|
|
1998
|
+
if (isOpen) {
|
|
1999
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2000
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2001
|
+
}
|
|
2002
|
+
}, [isOpen]);
|
|
2003
|
+
(0, import_react15.useEffect)(() => {
|
|
2004
|
+
if (isOpen && inputRef.current) {
|
|
2005
|
+
const rect = inputRef.current.getBoundingClientRect();
|
|
2006
|
+
setPickerPosition({
|
|
2007
|
+
top: rect.bottom + 8,
|
|
2008
|
+
left: rect.left
|
|
2009
|
+
});
|
|
2010
|
+
} else {
|
|
2011
|
+
setPickerPosition(null);
|
|
2012
|
+
}
|
|
2013
|
+
}, [isOpen]);
|
|
2014
|
+
const year = viewDate.getFullYear();
|
|
2015
|
+
const month = viewDate.getMonth();
|
|
2016
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
2017
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
2018
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
2019
|
+
const calendarDays = [];
|
|
2020
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
2021
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
2022
|
+
}
|
|
2023
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
2024
|
+
calendarDays.push(new Date(year, month, i));
|
|
2025
|
+
}
|
|
2026
|
+
const remainingDays = 42 - calendarDays.length;
|
|
2027
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
2028
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
2029
|
+
}
|
|
2030
|
+
const isSameDay = (date1, date2) => {
|
|
2031
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
2032
|
+
};
|
|
2033
|
+
const isToday = (date) => {
|
|
2034
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
2035
|
+
};
|
|
2036
|
+
const isSelected = (date) => {
|
|
2037
|
+
return value && isSameDay(date, value);
|
|
2038
|
+
};
|
|
2039
|
+
const isCurrentMonth = (date) => {
|
|
2040
|
+
return date.getMonth() === month;
|
|
2041
|
+
};
|
|
2042
|
+
const isDisabled = (date) => {
|
|
2043
|
+
if (minDate && date < minDate) return true;
|
|
2044
|
+
if (maxDate && date > maxDate) return true;
|
|
2045
|
+
return false;
|
|
2046
|
+
};
|
|
2047
|
+
const handleDateClick = (date) => {
|
|
2048
|
+
if (isDisabled(date)) return;
|
|
2049
|
+
const newDateTime = new Date(
|
|
2050
|
+
date.getFullYear(),
|
|
2051
|
+
date.getMonth(),
|
|
2052
|
+
date.getDate(),
|
|
2053
|
+
selectedTime.hours,
|
|
2054
|
+
selectedTime.minutes
|
|
2055
|
+
);
|
|
2056
|
+
onChange?.(newDateTime);
|
|
2057
|
+
};
|
|
2058
|
+
const handleTimeChange = (hours, minutes) => {
|
|
2059
|
+
setSelectedTime({ hours, minutes });
|
|
2060
|
+
if (value) {
|
|
2061
|
+
const newDateTime = new Date(
|
|
2062
|
+
value.getFullYear(),
|
|
2063
|
+
value.getMonth(),
|
|
2064
|
+
value.getDate(),
|
|
2065
|
+
hours,
|
|
2066
|
+
minutes
|
|
2067
|
+
);
|
|
2068
|
+
onChange?.(newDateTime);
|
|
2069
|
+
}
|
|
2070
|
+
};
|
|
2071
|
+
const handleDone = () => {
|
|
2072
|
+
if (value) {
|
|
2073
|
+
setIsOpen(false);
|
|
2074
|
+
}
|
|
2075
|
+
};
|
|
2076
|
+
const handlePrevMonth = () => {
|
|
2077
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
2078
|
+
};
|
|
2079
|
+
const handleNextMonth = () => {
|
|
2080
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
2081
|
+
};
|
|
2082
|
+
const handleToday = () => {
|
|
2083
|
+
const now = /* @__PURE__ */ new Date();
|
|
2084
|
+
setViewDate(now);
|
|
2085
|
+
setSelectedTime({ hours: now.getHours(), minutes: now.getMinutes() });
|
|
2086
|
+
onChange?.(now);
|
|
2087
|
+
};
|
|
2088
|
+
const formatDateTime = (date) => {
|
|
2089
|
+
if (!date) return "";
|
|
2090
|
+
return date.toLocaleString("en-US", {
|
|
2091
|
+
month: "short",
|
|
2092
|
+
day: "numeric",
|
|
2093
|
+
year: "numeric",
|
|
2094
|
+
hour: "numeric",
|
|
2095
|
+
minute: "2-digit",
|
|
2096
|
+
hour12: true
|
|
2097
|
+
});
|
|
2098
|
+
};
|
|
2099
|
+
const formatTime = (hours, minutes) => {
|
|
2100
|
+
const period = hours >= 12 ? "PM" : "AM";
|
|
2101
|
+
const displayHours = hours % 12 || 12;
|
|
2102
|
+
const displayMinutes = minutes.toString().padStart(2, "0");
|
|
2103
|
+
return `${displayHours}:${displayMinutes} ${period}`;
|
|
2104
|
+
};
|
|
2105
|
+
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";
|
|
2106
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
2107
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
2108
|
+
const picker = isOpen && mounted && pickerPosition ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
2109
|
+
"div",
|
|
2110
|
+
{
|
|
2111
|
+
ref: pickerRef,
|
|
2112
|
+
className: "fixed z-[9999] bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-xl p-4",
|
|
2113
|
+
style: {
|
|
2114
|
+
top: `${pickerPosition.top}px`,
|
|
2115
|
+
left: `${pickerPosition.left}px`,
|
|
2116
|
+
minWidth: "360px"
|
|
2117
|
+
},
|
|
2118
|
+
children: [
|
|
2119
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2120
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2121
|
+
"button",
|
|
2122
|
+
{
|
|
2123
|
+
onClick: handlePrevMonth,
|
|
2124
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2125
|
+
"aria-label": "Previous month",
|
|
2126
|
+
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" }) })
|
|
2127
|
+
}
|
|
2128
|
+
),
|
|
2129
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2130
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("h2", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
2131
|
+
MONTHS2[month],
|
|
2132
|
+
" ",
|
|
2133
|
+
year
|
|
2134
|
+
] }),
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2136
|
+
"button",
|
|
2137
|
+
{
|
|
2138
|
+
onClick: handleToday,
|
|
2139
|
+
className: "px-2 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
2140
|
+
children: "Now"
|
|
2141
|
+
}
|
|
2142
|
+
)
|
|
2143
|
+
] }),
|
|
2144
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2145
|
+
"button",
|
|
2146
|
+
{
|
|
2147
|
+
onClick: handleNextMonth,
|
|
2148
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2149
|
+
"aria-label": "Next month",
|
|
2150
|
+
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" }) })
|
|
2151
|
+
}
|
|
2152
|
+
)
|
|
2153
|
+
] }),
|
|
2154
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS2.map((day) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-1", children: day }, day)) }),
|
|
2155
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-4", children: calendarDays.map((date, index) => {
|
|
2156
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
2157
|
+
const isTodayDay = isToday(date);
|
|
2158
|
+
const isSelectedDay = isSelected(date);
|
|
2159
|
+
const isDisabledDay = isDisabled(date);
|
|
2160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2161
|
+
"button",
|
|
2162
|
+
{
|
|
2163
|
+
onClick: () => handleDateClick(date),
|
|
2164
|
+
disabled: isDisabledDay,
|
|
2165
|
+
className: `
|
|
2166
|
+
aspect-square p-1 rounded-lg text-sm font-medium transition-all
|
|
2167
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
2168
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
2169
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
2170
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
2171
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
2172
|
+
`,
|
|
2173
|
+
children: date.getDate()
|
|
2174
|
+
},
|
|
2175
|
+
index
|
|
2176
|
+
);
|
|
2177
|
+
}) }),
|
|
2178
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-4", children: [
|
|
2179
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex items-center justify-center gap-4 mb-4", children: [
|
|
2180
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
2181
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("label", { className: "text-xs font-semibold text-gray-600 dark:text-gray-400 mb-2", children: "Hour" }),
|
|
2182
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2184
|
+
"button",
|
|
2185
|
+
{
|
|
2186
|
+
type: "button",
|
|
2187
|
+
onClick: () => handleTimeChange((selectedTime.hours + 1) % 24, selectedTime.minutes),
|
|
2188
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2189
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.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_runtime54.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) })
|
|
2190
|
+
}
|
|
2191
|
+
),
|
|
2192
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2193
|
+
"input",
|
|
2194
|
+
{
|
|
2195
|
+
type: "number",
|
|
2196
|
+
min: "0",
|
|
2197
|
+
max: "23",
|
|
2198
|
+
value: selectedTime.hours,
|
|
2199
|
+
onChange: (e) => {
|
|
2200
|
+
const val = parseInt(e.target.value);
|
|
2201
|
+
if (!isNaN(val) && val >= 0 && val <= 23) {
|
|
2202
|
+
handleTimeChange(val, selectedTime.minutes);
|
|
2203
|
+
}
|
|
2204
|
+
},
|
|
2205
|
+
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"
|
|
2206
|
+
}
|
|
2207
|
+
),
|
|
2208
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2209
|
+
"button",
|
|
2210
|
+
{
|
|
2211
|
+
type: "button",
|
|
2212
|
+
onClick: () => handleTimeChange((selectedTime.hours - 1 + 24) % 24, selectedTime.minutes),
|
|
2213
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2214
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.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_runtime54.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
2215
|
+
}
|
|
2216
|
+
)
|
|
2217
|
+
] })
|
|
2218
|
+
] }),
|
|
2219
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "text-2xl font-bold text-gray-600 dark:text-gray-400 mt-8", children: ":" }),
|
|
2220
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
2221
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("label", { className: "text-xs font-semibold text-gray-600 dark:text-gray-400 mb-2", children: "Minute" }),
|
|
2222
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2223
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2224
|
+
"button",
|
|
2225
|
+
{
|
|
2226
|
+
type: "button",
|
|
2227
|
+
onClick: () => handleTimeChange(selectedTime.hours, (selectedTime.minutes + 1) % 60),
|
|
2228
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2229
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.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_runtime54.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) })
|
|
2230
|
+
}
|
|
2231
|
+
),
|
|
2232
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2233
|
+
"input",
|
|
2234
|
+
{
|
|
2235
|
+
type: "number",
|
|
2236
|
+
min: "0",
|
|
2237
|
+
max: "59",
|
|
2238
|
+
value: selectedTime.minutes,
|
|
2239
|
+
onChange: (e) => {
|
|
2240
|
+
const val = parseInt(e.target.value);
|
|
2241
|
+
if (!isNaN(val) && val >= 0 && val <= 59) {
|
|
2242
|
+
handleTimeChange(selectedTime.hours, val);
|
|
2243
|
+
}
|
|
2244
|
+
},
|
|
2245
|
+
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"
|
|
2246
|
+
}
|
|
2247
|
+
),
|
|
2248
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2249
|
+
"button",
|
|
2250
|
+
{
|
|
2251
|
+
type: "button",
|
|
2252
|
+
onClick: () => handleTimeChange(selectedTime.hours, (selectedTime.minutes - 1 + 60) % 60),
|
|
2253
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2254
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.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_runtime54.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
2255
|
+
}
|
|
2256
|
+
)
|
|
2257
|
+
] })
|
|
2258
|
+
] })
|
|
2259
|
+
] }),
|
|
2260
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "text-center text-sm text-gray-600 dark:text-gray-400 mb-4", children: formatTime(selectedTime.hours, selectedTime.minutes) }),
|
|
2261
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
2262
|
+
"button",
|
|
2263
|
+
{
|
|
2264
|
+
onClick: handleDone,
|
|
2265
|
+
className: "w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium",
|
|
2266
|
+
children: "Done"
|
|
2267
|
+
}
|
|
2268
|
+
)
|
|
2269
|
+
] })
|
|
2270
|
+
]
|
|
2271
|
+
}
|
|
2272
|
+
) : null;
|
|
2273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className, children: [
|
|
2274
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
2275
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
2276
|
+
"div",
|
|
2277
|
+
{
|
|
2278
|
+
ref: inputRef,
|
|
2279
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
2280
|
+
className: `${baseStyles} ${errorStyles} ${disabledStyles} flex items-center justify-between`.trim(),
|
|
2281
|
+
children: [
|
|
2282
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: !value ? "text-gray-500 dark:text-gray-400" : "", children: value ? formatDateTime(value) : placeholder }),
|
|
2283
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("svg", { className: "w-5 h-5 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: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
|
|
2284
|
+
]
|
|
2285
|
+
}
|
|
2286
|
+
),
|
|
2287
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
2288
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
2289
|
+
mounted && (0, import_react_dom3.createPortal)(picker, document.body)
|
|
2290
|
+
] });
|
|
2291
|
+
};
|
|
1598
2292
|
DateTimePicker.displayName = "DateTimePicker";
|
|
1599
2293
|
|
|
2294
|
+
// src/components/Calendar.tsx
|
|
2295
|
+
var import_react16 = require("react");
|
|
2296
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
2297
|
+
var DAYS3 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2298
|
+
var MONTHS3 = [
|
|
2299
|
+
"January",
|
|
2300
|
+
"February",
|
|
2301
|
+
"March",
|
|
2302
|
+
"April",
|
|
2303
|
+
"May",
|
|
2304
|
+
"June",
|
|
2305
|
+
"July",
|
|
2306
|
+
"August",
|
|
2307
|
+
"September",
|
|
2308
|
+
"October",
|
|
2309
|
+
"November",
|
|
2310
|
+
"December"
|
|
2311
|
+
];
|
|
2312
|
+
var Calendar = ({
|
|
2313
|
+
value,
|
|
2314
|
+
onChange,
|
|
2315
|
+
minDate,
|
|
2316
|
+
maxDate,
|
|
2317
|
+
className = ""
|
|
2318
|
+
}) => {
|
|
2319
|
+
const { theme } = useTheme();
|
|
2320
|
+
const [currentDate, setCurrentDate] = (0, import_react16.useState)(value || /* @__PURE__ */ new Date());
|
|
2321
|
+
const [viewDate, setViewDate] = (0, import_react16.useState)(value || /* @__PURE__ */ new Date());
|
|
2322
|
+
const year = viewDate.getFullYear();
|
|
2323
|
+
const month = viewDate.getMonth();
|
|
2324
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
2325
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
2326
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
2327
|
+
const calendarDays = [];
|
|
2328
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
2329
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
2330
|
+
}
|
|
2331
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
2332
|
+
calendarDays.push(new Date(year, month, i));
|
|
2333
|
+
}
|
|
2334
|
+
const remainingDays = 42 - calendarDays.length;
|
|
2335
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
2336
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
2337
|
+
}
|
|
2338
|
+
const isSameDay = (date1, date2) => {
|
|
2339
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
2340
|
+
};
|
|
2341
|
+
const isToday = (date) => {
|
|
2342
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
2343
|
+
};
|
|
2344
|
+
const isSelected = (date) => {
|
|
2345
|
+
return value && isSameDay(date, value);
|
|
2346
|
+
};
|
|
2347
|
+
const isCurrentMonth = (date) => {
|
|
2348
|
+
return date.getMonth() === month;
|
|
2349
|
+
};
|
|
2350
|
+
const isDisabled = (date) => {
|
|
2351
|
+
if (minDate && date < minDate) return true;
|
|
2352
|
+
if (maxDate && date > maxDate) return true;
|
|
2353
|
+
return false;
|
|
2354
|
+
};
|
|
2355
|
+
const handleDateClick = (date) => {
|
|
2356
|
+
if (isDisabled(date)) return;
|
|
2357
|
+
setCurrentDate(date);
|
|
2358
|
+
onChange?.(date);
|
|
2359
|
+
};
|
|
2360
|
+
const handlePrevMonth = () => {
|
|
2361
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
2362
|
+
};
|
|
2363
|
+
const handleNextMonth = () => {
|
|
2364
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
2365
|
+
};
|
|
2366
|
+
const handleToday = () => {
|
|
2367
|
+
const today = /* @__PURE__ */ new Date();
|
|
2368
|
+
setViewDate(today);
|
|
2369
|
+
setCurrentDate(today);
|
|
2370
|
+
onChange?.(today);
|
|
2371
|
+
};
|
|
2372
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: `bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4 ${className}`, children: [
|
|
2373
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2374
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
2375
|
+
"button",
|
|
2376
|
+
{
|
|
2377
|
+
onClick: handlePrevMonth,
|
|
2378
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2379
|
+
"aria-label": "Previous month",
|
|
2380
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.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_runtime55.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
2381
|
+
}
|
|
2382
|
+
),
|
|
2383
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2384
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("h2", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
2385
|
+
MONTHS3[month],
|
|
2386
|
+
" ",
|
|
2387
|
+
year
|
|
2388
|
+
] }),
|
|
2389
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
2390
|
+
"button",
|
|
2391
|
+
{
|
|
2392
|
+
onClick: handleToday,
|
|
2393
|
+
className: "px-3 py-1 text-sm bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
2394
|
+
children: "Today"
|
|
2395
|
+
}
|
|
2396
|
+
)
|
|
2397
|
+
] }),
|
|
2398
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
2399
|
+
"button",
|
|
2400
|
+
{
|
|
2401
|
+
onClick: handleNextMonth,
|
|
2402
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2403
|
+
"aria-label": "Next month",
|
|
2404
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.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_runtime55.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
2405
|
+
}
|
|
2406
|
+
)
|
|
2407
|
+
] }),
|
|
2408
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS3.map((day) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
2409
|
+
"div",
|
|
2410
|
+
{
|
|
2411
|
+
className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-2",
|
|
2412
|
+
children: day
|
|
2413
|
+
},
|
|
2414
|
+
day
|
|
2415
|
+
)) }),
|
|
2416
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
|
|
2417
|
+
if (!date) return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", {}, index);
|
|
2418
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
2419
|
+
const isTodayDay = isToday(date);
|
|
2420
|
+
const isSelectedDay = isSelected(date);
|
|
2421
|
+
const isDisabledDay = isDisabled(date);
|
|
2422
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
2423
|
+
"button",
|
|
2424
|
+
{
|
|
2425
|
+
onClick: () => handleDateClick(date),
|
|
2426
|
+
disabled: isDisabledDay,
|
|
2427
|
+
className: `
|
|
2428
|
+
aspect-square p-2 rounded-lg text-sm font-medium transition-all
|
|
2429
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
2430
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
2431
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
2432
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
2433
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
2434
|
+
`,
|
|
2435
|
+
children: date.getDate()
|
|
2436
|
+
},
|
|
2437
|
+
index
|
|
2438
|
+
);
|
|
2439
|
+
}) })
|
|
2440
|
+
] });
|
|
2441
|
+
};
|
|
2442
|
+
|
|
1600
2443
|
// src/components/Radio.tsx
|
|
1601
|
-
var
|
|
1602
|
-
var
|
|
2444
|
+
var import_react17 = __toESM(require("react"));
|
|
2445
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
1603
2446
|
var Radio = ({
|
|
1604
2447
|
name,
|
|
1605
2448
|
options,
|
|
@@ -1610,7 +2453,7 @@ var Radio = ({
|
|
|
1610
2453
|
orientation = "vertical",
|
|
1611
2454
|
className = ""
|
|
1612
2455
|
}) => {
|
|
1613
|
-
const [internalValue, setInternalValue] =
|
|
2456
|
+
const [internalValue, setInternalValue] = import_react17.default.useState(defaultValue || "");
|
|
1614
2457
|
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
1615
2458
|
const handleChange = (optionValue) => {
|
|
1616
2459
|
if (disabled) return;
|
|
@@ -1618,17 +2461,17 @@ var Radio = ({
|
|
|
1618
2461
|
onChange?.(optionValue);
|
|
1619
2462
|
};
|
|
1620
2463
|
const containerClass = orientation === "horizontal" ? "flex flex-wrap gap-4" : "flex flex-col gap-2";
|
|
1621
|
-
return /* @__PURE__ */ (0,
|
|
2464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: `${containerClass} ${className}`, role: "radiogroup", children: options.map((option) => {
|
|
1622
2465
|
const isDisabled = disabled || option.disabled;
|
|
1623
2466
|
const isChecked = value === option.value;
|
|
1624
2467
|
const id = `${name}-${option.value}`;
|
|
1625
|
-
return /* @__PURE__ */ (0,
|
|
2468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
1626
2469
|
"label",
|
|
1627
2470
|
{
|
|
1628
2471
|
htmlFor: id,
|
|
1629
2472
|
className: `flex items-center gap-2 cursor-pointer ${isDisabled ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
1630
2473
|
children: [
|
|
1631
|
-
/* @__PURE__ */ (0,
|
|
2474
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
1632
2475
|
"input",
|
|
1633
2476
|
{
|
|
1634
2477
|
type: "radio",
|
|
@@ -1641,7 +2484,7 @@ var Radio = ({
|
|
|
1641
2484
|
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"
|
|
1642
2485
|
}
|
|
1643
2486
|
),
|
|
1644
|
-
/* @__PURE__ */ (0,
|
|
2487
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-300", children: option.label })
|
|
1645
2488
|
]
|
|
1646
2489
|
},
|
|
1647
2490
|
option.value
|
|
@@ -1650,7 +2493,7 @@ var Radio = ({
|
|
|
1650
2493
|
};
|
|
1651
2494
|
|
|
1652
2495
|
// src/components/ProgressBar.tsx
|
|
1653
|
-
var
|
|
2496
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
1654
2497
|
var ProgressBar = ({
|
|
1655
2498
|
value,
|
|
1656
2499
|
max = 100,
|
|
@@ -1661,7 +2504,7 @@ var ProgressBar = ({
|
|
|
1661
2504
|
className = ""
|
|
1662
2505
|
}) => {
|
|
1663
2506
|
const percentage = Math.min(Math.max(value / max * 100, 0), 100);
|
|
1664
|
-
const
|
|
2507
|
+
const sizeClasses7 = {
|
|
1665
2508
|
sm: "h-1",
|
|
1666
2509
|
md: "h-2",
|
|
1667
2510
|
lg: "h-3"
|
|
@@ -1672,26 +2515,26 @@ var ProgressBar = ({
|
|
|
1672
2515
|
warning: "bg-yellow-500 dark:bg-yellow-400",
|
|
1673
2516
|
danger: "bg-red-600 dark:bg-red-500"
|
|
1674
2517
|
};
|
|
1675
|
-
return /* @__PURE__ */ (0,
|
|
1676
|
-
(showLabel || label) && /* @__PURE__ */ (0,
|
|
1677
|
-
label && /* @__PURE__ */ (0,
|
|
1678
|
-
showLabel && /* @__PURE__ */ (0,
|
|
2518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2519
|
+
(showLabel || label) && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex justify-between items-center mb-1", children: [
|
|
2520
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label }),
|
|
2521
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
|
|
1679
2522
|
Math.round(percentage),
|
|
1680
2523
|
"%"
|
|
1681
2524
|
] })
|
|
1682
2525
|
] }),
|
|
1683
|
-
/* @__PURE__ */ (0,
|
|
2526
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
1684
2527
|
"div",
|
|
1685
2528
|
{
|
|
1686
|
-
className: `w-full bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden ${
|
|
2529
|
+
className: `w-full bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden ${sizeClasses7[size]}`,
|
|
1687
2530
|
role: "progressbar",
|
|
1688
2531
|
"aria-valuenow": value,
|
|
1689
2532
|
"aria-valuemin": 0,
|
|
1690
2533
|
"aria-valuemax": max,
|
|
1691
|
-
children: /* @__PURE__ */ (0,
|
|
2534
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
1692
2535
|
"div",
|
|
1693
2536
|
{
|
|
1694
|
-
className: `${
|
|
2537
|
+
className: `${sizeClasses7[size]} ${variantClasses[variant]} rounded-full transition-all duration-300 ease-out`,
|
|
1695
2538
|
style: { width: `${percentage}%` }
|
|
1696
2539
|
}
|
|
1697
2540
|
)
|
|
@@ -1701,8 +2544,8 @@ var ProgressBar = ({
|
|
|
1701
2544
|
};
|
|
1702
2545
|
|
|
1703
2546
|
// src/components/Slider.tsx
|
|
1704
|
-
var
|
|
1705
|
-
var
|
|
2547
|
+
var import_react18 = __toESM(require("react"));
|
|
2548
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
1706
2549
|
var Slider = ({
|
|
1707
2550
|
value: controlledValue,
|
|
1708
2551
|
defaultValue = 50,
|
|
@@ -1715,7 +2558,7 @@ var Slider = ({
|
|
|
1715
2558
|
label,
|
|
1716
2559
|
className = ""
|
|
1717
2560
|
}) => {
|
|
1718
|
-
const [internalValue, setInternalValue] =
|
|
2561
|
+
const [internalValue, setInternalValue] = import_react18.default.useState(defaultValue);
|
|
1719
2562
|
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
1720
2563
|
const handleChange = (e) => {
|
|
1721
2564
|
const newValue = Number(e.target.value);
|
|
@@ -1723,21 +2566,21 @@ var Slider = ({
|
|
|
1723
2566
|
onChange?.(newValue);
|
|
1724
2567
|
};
|
|
1725
2568
|
const percentage = (value - min) / (max - min) * 100;
|
|
1726
|
-
return /* @__PURE__ */ (0,
|
|
1727
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
1728
|
-
label && /* @__PURE__ */ (0,
|
|
1729
|
-
showValue && /* @__PURE__ */ (0,
|
|
2569
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2570
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [
|
|
2571
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label }),
|
|
2572
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: value })
|
|
1730
2573
|
] }),
|
|
1731
|
-
/* @__PURE__ */ (0,
|
|
1732
|
-
/* @__PURE__ */ (0,
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
2574
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "relative", children: [
|
|
2575
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "absolute inset-0 h-2 bg-gray-200 dark:bg-gray-700 rounded-full top-1/2 -translate-y-1/2" }),
|
|
2576
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
1734
2577
|
"div",
|
|
1735
2578
|
{
|
|
1736
2579
|
className: "absolute h-2 bg-blue-600 dark:bg-blue-500 rounded-full top-1/2 -translate-y-1/2 pointer-events-none",
|
|
1737
2580
|
style: { width: `${percentage}%` }
|
|
1738
2581
|
}
|
|
1739
2582
|
),
|
|
1740
|
-
/* @__PURE__ */ (0,
|
|
2583
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
1741
2584
|
"input",
|
|
1742
2585
|
{
|
|
1743
2586
|
type: "range",
|
|
@@ -1759,8 +2602,8 @@ var Slider = ({
|
|
|
1759
2602
|
};
|
|
1760
2603
|
|
|
1761
2604
|
// src/components/Avatar.tsx
|
|
1762
|
-
var
|
|
1763
|
-
var
|
|
2605
|
+
var import_react19 = __toESM(require("react"));
|
|
2606
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
1764
2607
|
var Avatar = ({
|
|
1765
2608
|
src,
|
|
1766
2609
|
alt,
|
|
@@ -1770,8 +2613,8 @@ var Avatar = ({
|
|
|
1770
2613
|
className = "",
|
|
1771
2614
|
fallbackColor = "bg-blue-600"
|
|
1772
2615
|
}) => {
|
|
1773
|
-
const [imageError, setImageError] =
|
|
1774
|
-
const
|
|
2616
|
+
const [imageError, setImageError] = import_react19.default.useState(false);
|
|
2617
|
+
const sizeClasses7 = {
|
|
1775
2618
|
xs: "w-6 h-6 text-xs",
|
|
1776
2619
|
sm: "w-8 h-8 text-sm",
|
|
1777
2620
|
md: "w-10 h-10 text-base",
|
|
@@ -1788,11 +2631,11 @@ var Avatar = ({
|
|
|
1788
2631
|
};
|
|
1789
2632
|
const showImage = src && !imageError;
|
|
1790
2633
|
const showInitials = !showImage && name;
|
|
1791
|
-
return /* @__PURE__ */ (0,
|
|
2634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
1792
2635
|
"div",
|
|
1793
2636
|
{
|
|
1794
|
-
className: `${
|
|
1795
|
-
children: showImage ? /* @__PURE__ */ (0,
|
|
2637
|
+
className: `${sizeClasses7[size]} ${shapeClass} flex items-center justify-center overflow-hidden ${showImage ? "bg-gray-200 dark:bg-gray-700" : `${fallbackColor} text-white`} ${className}`,
|
|
2638
|
+
children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
1796
2639
|
"img",
|
|
1797
2640
|
{
|
|
1798
2641
|
src,
|
|
@@ -1800,13 +2643,13 @@ var Avatar = ({
|
|
|
1800
2643
|
className: "w-full h-full object-cover",
|
|
1801
2644
|
onError: () => setImageError(true)
|
|
1802
2645
|
}
|
|
1803
|
-
) : showInitials ? /* @__PURE__ */ (0,
|
|
2646
|
+
) : showInitials ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "font-semibold select-none", children: getInitials(name) }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
1804
2647
|
"svg",
|
|
1805
2648
|
{
|
|
1806
2649
|
className: "w-full h-full text-gray-400 dark:text-gray-600",
|
|
1807
2650
|
fill: "currentColor",
|
|
1808
2651
|
viewBox: "0 0 24 24",
|
|
1809
|
-
children: /* @__PURE__ */ (0,
|
|
2652
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime59.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" })
|
|
1810
2653
|
}
|
|
1811
2654
|
)
|
|
1812
2655
|
}
|
|
@@ -1814,7 +2657,7 @@ var Avatar = ({
|
|
|
1814
2657
|
};
|
|
1815
2658
|
|
|
1816
2659
|
// src/components/Textarea.tsx
|
|
1817
|
-
var
|
|
2660
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
1818
2661
|
var Textarea = ({
|
|
1819
2662
|
label,
|
|
1820
2663
|
error,
|
|
@@ -1825,7 +2668,7 @@ var Textarea = ({
|
|
|
1825
2668
|
disabled,
|
|
1826
2669
|
...props
|
|
1827
2670
|
}) => {
|
|
1828
|
-
const
|
|
2671
|
+
const sizeClasses7 = {
|
|
1829
2672
|
sm: "px-3 py-1.5 text-sm min-h-[80px]",
|
|
1830
2673
|
md: "px-4 py-2 text-base min-h-[100px]",
|
|
1831
2674
|
lg: "px-4 py-3 text-lg min-h-[120px]"
|
|
@@ -1841,35 +2684,35 @@ var Textarea = ({
|
|
|
1841
2684
|
bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100
|
|
1842
2685
|
placeholder:text-gray-500 dark:placeholder:text-gray-400
|
|
1843
2686
|
disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-gray-50 dark:disabled:bg-gray-900`;
|
|
1844
|
-
return /* @__PURE__ */ (0,
|
|
1845
|
-
label && /* @__PURE__ */ (0,
|
|
1846
|
-
/* @__PURE__ */ (0,
|
|
2687
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2688
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
2689
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
1847
2690
|
"textarea",
|
|
1848
2691
|
{
|
|
1849
|
-
className: `${baseClasses} ${
|
|
2692
|
+
className: `${baseClasses} ${sizeClasses7[size]} ${resizeClasses[resize]}`,
|
|
1850
2693
|
disabled,
|
|
1851
2694
|
...props
|
|
1852
2695
|
}
|
|
1853
2696
|
),
|
|
1854
|
-
error && /* @__PURE__ */ (0,
|
|
1855
|
-
helperText && !error && /* @__PURE__ */ (0,
|
|
2697
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
2698
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
1856
2699
|
] });
|
|
1857
2700
|
};
|
|
1858
2701
|
|
|
1859
2702
|
// src/components/Toast.tsx
|
|
1860
|
-
var
|
|
1861
|
-
var
|
|
1862
|
-
var ToastContext = (0,
|
|
2703
|
+
var import_react20 = require("react");
|
|
2704
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
2705
|
+
var ToastContext = (0, import_react20.createContext)(void 0);
|
|
1863
2706
|
var useToast = () => {
|
|
1864
|
-
const context = (0,
|
|
2707
|
+
const context = (0, import_react20.useContext)(ToastContext);
|
|
1865
2708
|
if (!context) {
|
|
1866
2709
|
throw new Error("useToast must be used within a ToastProvider");
|
|
1867
2710
|
}
|
|
1868
2711
|
return context;
|
|
1869
2712
|
};
|
|
1870
2713
|
var ToastProvider = ({ children, position = "top-right" }) => {
|
|
1871
|
-
const [toasts, setToasts] = (0,
|
|
1872
|
-
const addToast = (0,
|
|
2714
|
+
const [toasts, setToasts] = (0, import_react20.useState)([]);
|
|
2715
|
+
const addToast = (0, import_react20.useCallback)((toast2) => {
|
|
1873
2716
|
const id = Math.random().toString(36).substring(7);
|
|
1874
2717
|
const newToast = { ...toast2, id };
|
|
1875
2718
|
setToasts((prev) => [...prev, newToast]);
|
|
@@ -1878,7 +2721,7 @@ var ToastProvider = ({ children, position = "top-right" }) => {
|
|
|
1878
2721
|
removeToast(id);
|
|
1879
2722
|
}, duration);
|
|
1880
2723
|
}, []);
|
|
1881
|
-
const removeToast = (0,
|
|
2724
|
+
const removeToast = (0, import_react20.useCallback)((id) => {
|
|
1882
2725
|
setToasts((prev) => prev.filter((toast2) => toast2.id !== id));
|
|
1883
2726
|
}, []);
|
|
1884
2727
|
const positionClasses2 = {
|
|
@@ -1889,9 +2732,9 @@ var ToastProvider = ({ children, position = "top-right" }) => {
|
|
|
1889
2732
|
"top-center": "top-4 left-1/2 -translate-x-1/2",
|
|
1890
2733
|
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
1891
2734
|
};
|
|
1892
|
-
return /* @__PURE__ */ (0,
|
|
2735
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(ToastContext.Provider, { value: { toasts, addToast, removeToast }, children: [
|
|
1893
2736
|
children,
|
|
1894
|
-
/* @__PURE__ */ (0,
|
|
2737
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: `fixed ${positionClasses2[position]} z-50 flex flex-col gap-2 max-w-md`, children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(ToastItem, { toast: toast2, onClose: () => removeToast(toast2.id) }, toast2.id)) })
|
|
1895
2738
|
] });
|
|
1896
2739
|
};
|
|
1897
2740
|
var ToastItem = ({ toast: toast2, onClose }) => {
|
|
@@ -1902,27 +2745,27 @@ var ToastItem = ({ toast: toast2, onClose }) => {
|
|
|
1902
2745
|
info: "bg-blue-50 dark:bg-blue-900/30 border-blue-500 text-blue-800 dark:text-blue-200"
|
|
1903
2746
|
};
|
|
1904
2747
|
const typeIcons = {
|
|
1905
|
-
success: /* @__PURE__ */ (0,
|
|
1906
|
-
error: /* @__PURE__ */ (0,
|
|
1907
|
-
warning: /* @__PURE__ */ (0,
|
|
1908
|
-
info: /* @__PURE__ */ (0,
|
|
2748
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(CheckIcon, { size: "sm", className: "text-green-600 dark:text-green-400" }),
|
|
2749
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(CloseIcon, { size: "sm", className: "text-red-600 dark:text-red-400" }),
|
|
2750
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime61.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_runtime61.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" }) }),
|
|
2751
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime61.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_runtime61.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" }) })
|
|
1909
2752
|
};
|
|
1910
2753
|
const type = toast2.type || "info";
|
|
1911
|
-
return /* @__PURE__ */ (0,
|
|
2754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
1912
2755
|
"div",
|
|
1913
2756
|
{
|
|
1914
2757
|
className: `flex items-start gap-3 p-4 rounded-lg border-l-4 shadow-lg backdrop-blur-sm ${typeStyles[type]} animate-slide-in`,
|
|
1915
2758
|
role: "alert",
|
|
1916
2759
|
children: [
|
|
1917
|
-
/* @__PURE__ */ (0,
|
|
1918
|
-
/* @__PURE__ */ (0,
|
|
1919
|
-
/* @__PURE__ */ (0,
|
|
2760
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "flex-shrink-0 mt-0.5", children: typeIcons[type] }),
|
|
2761
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "flex-1 text-sm font-medium", children: toast2.message }),
|
|
2762
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
1920
2763
|
"button",
|
|
1921
2764
|
{
|
|
1922
2765
|
onClick: onClose,
|
|
1923
2766
|
className: "flex-shrink-0 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors",
|
|
1924
2767
|
"aria-label": "Close",
|
|
1925
|
-
children: /* @__PURE__ */ (0,
|
|
2768
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(CloseIcon, { size: "sm" })
|
|
1926
2769
|
}
|
|
1927
2770
|
)
|
|
1928
2771
|
]
|
|
@@ -1953,8 +2796,8 @@ var toast = {
|
|
|
1953
2796
|
};
|
|
1954
2797
|
|
|
1955
2798
|
// src/components/Stepper.tsx
|
|
1956
|
-
var
|
|
1957
|
-
var
|
|
2799
|
+
var import_react21 = __toESM(require("react"));
|
|
2800
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
1958
2801
|
var Stepper = ({
|
|
1959
2802
|
steps,
|
|
1960
2803
|
currentStep,
|
|
@@ -1962,18 +2805,18 @@ var Stepper = ({
|
|
|
1962
2805
|
className = ""
|
|
1963
2806
|
}) => {
|
|
1964
2807
|
const isHorizontal = orientation === "horizontal";
|
|
1965
|
-
return /* @__PURE__ */ (0,
|
|
2808
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: `${isHorizontal ? "flex items-center" : "flex flex-col"} ${className}`, children: steps.map((step, index) => {
|
|
1966
2809
|
const stepNumber = index + 1;
|
|
1967
2810
|
const isActive = stepNumber === currentStep;
|
|
1968
2811
|
const isCompleted = stepNumber < currentStep;
|
|
1969
2812
|
const isLast = index === steps.length - 1;
|
|
1970
|
-
return /* @__PURE__ */ (0,
|
|
1971
|
-
/* @__PURE__ */ (0,
|
|
1972
|
-
/* @__PURE__ */ (0,
|
|
2813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_react21.default.Fragment, { children: [
|
|
2814
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: `flex ${isHorizontal ? "flex-col items-center" : "flex-row items-start"} ${isHorizontal ? "" : "flex-1"}`, children: [
|
|
2815
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
1973
2816
|
"div",
|
|
1974
2817
|
{
|
|
1975
2818
|
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"}`,
|
|
1976
|
-
children: isCompleted ? /* @__PURE__ */ (0,
|
|
2819
|
+
children: isCompleted ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(CheckIcon, { size: "sm", className: "text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
1977
2820
|
"span",
|
|
1978
2821
|
{
|
|
1979
2822
|
className: `text-sm font-semibold ${isActive ? "text-blue-600 dark:text-blue-400" : "text-gray-500 dark:text-gray-400"}`,
|
|
@@ -1982,18 +2825,18 @@ var Stepper = ({
|
|
|
1982
2825
|
)
|
|
1983
2826
|
}
|
|
1984
2827
|
) }),
|
|
1985
|
-
/* @__PURE__ */ (0,
|
|
1986
|
-
/* @__PURE__ */ (0,
|
|
2828
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: `${isHorizontal ? "mt-2 text-center" : "ml-4 pb-8"} ${isLast && !isHorizontal ? "pb-0" : ""}`, children: [
|
|
2829
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
1987
2830
|
"p",
|
|
1988
2831
|
{
|
|
1989
2832
|
className: `text-sm font-medium ${isActive || isCompleted ? "text-gray-900 dark:text-gray-100" : "text-gray-500 dark:text-gray-400"}`,
|
|
1990
2833
|
children: step.label
|
|
1991
2834
|
}
|
|
1992
2835
|
),
|
|
1993
|
-
step.description && /* @__PURE__ */ (0,
|
|
2836
|
+
step.description && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: step.description })
|
|
1994
2837
|
] })
|
|
1995
2838
|
] }),
|
|
1996
|
-
!isLast && /* @__PURE__ */ (0,
|
|
2839
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
1997
2840
|
"div",
|
|
1998
2841
|
{
|
|
1999
2842
|
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"}`
|
|
@@ -2004,7 +2847,7 @@ var Stepper = ({
|
|
|
2004
2847
|
};
|
|
2005
2848
|
|
|
2006
2849
|
// src/components/Divider.tsx
|
|
2007
|
-
var
|
|
2850
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
2008
2851
|
var Divider = ({
|
|
2009
2852
|
orientation = "horizontal",
|
|
2010
2853
|
variant = "solid",
|
|
@@ -2023,14 +2866,14 @@ var Divider = ({
|
|
|
2023
2866
|
center: "justify-center",
|
|
2024
2867
|
right: "justify-end"
|
|
2025
2868
|
};
|
|
2026
|
-
return /* @__PURE__ */ (0,
|
|
2027
|
-
labelPosition !== "left" && /* @__PURE__ */ (0,
|
|
2028
|
-
/* @__PURE__ */ (0,
|
|
2029
|
-
labelPosition !== "right" && /* @__PURE__ */ (0,
|
|
2869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: `flex items-center ${alignmentClasses[labelPosition]} ${className}`, role: "separator", children: [
|
|
2870
|
+
labelPosition !== "left" && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: `flex-1 border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600` }),
|
|
2871
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "px-4 text-sm text-gray-500 dark:text-gray-400", children: label }),
|
|
2872
|
+
labelPosition !== "right" && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: `flex-1 border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600` })
|
|
2030
2873
|
] });
|
|
2031
2874
|
}
|
|
2032
2875
|
if (orientation === "vertical") {
|
|
2033
|
-
return /* @__PURE__ */ (0,
|
|
2876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
2034
2877
|
"div",
|
|
2035
2878
|
{
|
|
2036
2879
|
className: `inline-block h-full border-l ${variantClasses[variant]} border-gray-300 dark:border-gray-600 ${className}`,
|
|
@@ -2039,7 +2882,7 @@ var Divider = ({
|
|
|
2039
2882
|
}
|
|
2040
2883
|
);
|
|
2041
2884
|
}
|
|
2042
|
-
return /* @__PURE__ */ (0,
|
|
2885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
2043
2886
|
"hr",
|
|
2044
2887
|
{
|
|
2045
2888
|
className: `border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600 ${className}`,
|
|
@@ -2049,8 +2892,8 @@ var Divider = ({
|
|
|
2049
2892
|
};
|
|
2050
2893
|
|
|
2051
2894
|
// src/components/FileUpload.tsx
|
|
2052
|
-
var
|
|
2053
|
-
var
|
|
2895
|
+
var import_react22 = require("react");
|
|
2896
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
2054
2897
|
var FileUpload = ({
|
|
2055
2898
|
accept,
|
|
2056
2899
|
multiple = false,
|
|
@@ -2063,9 +2906,9 @@ var FileUpload = ({
|
|
|
2063
2906
|
label,
|
|
2064
2907
|
helperText
|
|
2065
2908
|
}) => {
|
|
2066
|
-
const [files, setFiles] = (0,
|
|
2067
|
-
const [isDragging, setIsDragging] = (0,
|
|
2068
|
-
const fileInputRef = (0,
|
|
2909
|
+
const [files, setFiles] = (0, import_react22.useState)([]);
|
|
2910
|
+
const [isDragging, setIsDragging] = (0, import_react22.useState)(false);
|
|
2911
|
+
const fileInputRef = (0, import_react22.useRef)(null);
|
|
2069
2912
|
const formatFileSize = (bytes) => {
|
|
2070
2913
|
if (bytes === 0) return "0 Bytes";
|
|
2071
2914
|
const k = 1024;
|
|
@@ -2123,9 +2966,9 @@ var FileUpload = ({
|
|
|
2123
2966
|
setFiles(newFiles);
|
|
2124
2967
|
onChange?.(newFiles);
|
|
2125
2968
|
};
|
|
2126
|
-
return /* @__PURE__ */ (0,
|
|
2127
|
-
label && /* @__PURE__ */ (0,
|
|
2128
|
-
/* @__PURE__ */ (0,
|
|
2969
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2970
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: label }),
|
|
2971
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
|
|
2129
2972
|
"div",
|
|
2130
2973
|
{
|
|
2131
2974
|
onDrop: handleDrop,
|
|
@@ -2134,7 +2977,7 @@ var FileUpload = ({
|
|
|
2134
2977
|
onClick: handleClick,
|
|
2135
2978
|
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" : ""}`,
|
|
2136
2979
|
children: [
|
|
2137
|
-
/* @__PURE__ */ (0,
|
|
2980
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
2138
2981
|
"input",
|
|
2139
2982
|
{
|
|
2140
2983
|
ref: fileInputRef,
|
|
@@ -2146,14 +2989,14 @@ var FileUpload = ({
|
|
|
2146
2989
|
className: "hidden"
|
|
2147
2990
|
}
|
|
2148
2991
|
),
|
|
2149
|
-
/* @__PURE__ */ (0,
|
|
2150
|
-
/* @__PURE__ */ (0,
|
|
2151
|
-
/* @__PURE__ */ (0,
|
|
2152
|
-
/* @__PURE__ */ (0,
|
|
2153
|
-
/* @__PURE__ */ (0,
|
|
2992
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "flex flex-col items-center gap-2", children: [
|
|
2993
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.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_runtime64.jsx)(UploadIcon, { size: "lg", className: "text-gray-400 dark:text-gray-500" }) }),
|
|
2994
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { children: [
|
|
2995
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
|
|
2996
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "text-blue-600 dark:text-blue-400", children: "Click to upload" }),
|
|
2154
2997
|
" or drag and drop"
|
|
2155
2998
|
] }),
|
|
2156
|
-
/* @__PURE__ */ (0,
|
|
2999
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: [
|
|
2157
3000
|
accept ? `Accepted: ${accept}` : "Any file type",
|
|
2158
3001
|
maxSize && ` \u2022 Max size: ${formatFileSize(maxSize)}`
|
|
2159
3002
|
] })
|
|
@@ -2162,17 +3005,17 @@ var FileUpload = ({
|
|
|
2162
3005
|
]
|
|
2163
3006
|
}
|
|
2164
3007
|
),
|
|
2165
|
-
helperText && /* @__PURE__ */ (0,
|
|
2166
|
-
files.length > 0 && /* @__PURE__ */ (0,
|
|
3008
|
+
helperText && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "mt-2 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
3009
|
+
files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: "mt-4 space-y-2", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
|
|
2167
3010
|
"div",
|
|
2168
3011
|
{
|
|
2169
3012
|
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",
|
|
2170
3013
|
children: [
|
|
2171
|
-
/* @__PURE__ */ (0,
|
|
2172
|
-
/* @__PURE__ */ (0,
|
|
2173
|
-
/* @__PURE__ */ (0,
|
|
3014
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
3015
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 truncate", children: file.name }),
|
|
3016
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: formatFileSize(file.size) })
|
|
2174
3017
|
] }),
|
|
2175
|
-
/* @__PURE__ */ (0,
|
|
3018
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
2176
3019
|
"button",
|
|
2177
3020
|
{
|
|
2178
3021
|
onClick: (e) => {
|
|
@@ -2181,7 +3024,7 @@ var FileUpload = ({
|
|
|
2181
3024
|
},
|
|
2182
3025
|
className: "ml-4 text-gray-400 hover:text-red-600 dark:hover:text-red-400 transition-colors",
|
|
2183
3026
|
"aria-label": "Remove file",
|
|
2184
|
-
children: /* @__PURE__ */ (0,
|
|
3027
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(CloseIcon, { size: "sm" })
|
|
2185
3028
|
}
|
|
2186
3029
|
)
|
|
2187
3030
|
]
|
|
@@ -2233,6 +3076,7 @@ function getThemeScript() {
|
|
|
2233
3076
|
Badge,
|
|
2234
3077
|
BellIcon,
|
|
2235
3078
|
Button,
|
|
3079
|
+
Calendar,
|
|
2236
3080
|
CalendarIcon,
|
|
2237
3081
|
CameraIcon,
|
|
2238
3082
|
Card,
|
|
@@ -2259,6 +3103,7 @@ function getThemeScript() {
|
|
|
2259
3103
|
MenuIcon,
|
|
2260
3104
|
Modal,
|
|
2261
3105
|
Navbar,
|
|
3106
|
+
NumberInput,
|
|
2262
3107
|
Pagination,
|
|
2263
3108
|
PlusIcon,
|
|
2264
3109
|
ProgressBar,
|