@marcoschwartz/lite-ui 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +238 -134
- package/dist/index.d.mts +569 -2
- package/dist/index.d.ts +569 -2
- package/dist/index.js +4289 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4179 -53
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +9 -2
package/dist/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __export = (target, all) => {
|
|
8
10
|
for (var name in all)
|
|
@@ -16,18 +18,127 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
}
|
|
17
19
|
return to;
|
|
18
20
|
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
19
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
30
|
|
|
21
31
|
// src/index.ts
|
|
22
32
|
var index_exports = {};
|
|
23
33
|
__export(index_exports, {
|
|
34
|
+
ActionMenu: () => ActionMenu,
|
|
35
|
+
Alert: () => Alert,
|
|
36
|
+
AlertCircleIcon: () => AlertCircleIcon,
|
|
37
|
+
AppShell: () => AppShell,
|
|
38
|
+
AppleIcon: () => AppleIcon,
|
|
39
|
+
ArrowLeftIcon: () => ArrowLeftIcon,
|
|
40
|
+
ArrowRightIcon: () => ArrowRightIcon,
|
|
41
|
+
AudioPlayer: () => AudioPlayer,
|
|
42
|
+
Avatar: () => Avatar,
|
|
43
|
+
Badge: () => Badge,
|
|
44
|
+
BeakerIcon: () => BeakerIcon,
|
|
45
|
+
BellIcon: () => BellIcon,
|
|
46
|
+
BookIcon: () => BookIcon,
|
|
47
|
+
BrainIcon: () => BrainIcon,
|
|
24
48
|
Button: () => Button,
|
|
49
|
+
Calendar: () => Calendar,
|
|
50
|
+
CalendarIcon: () => CalendarIcon,
|
|
51
|
+
CameraIcon: () => CameraIcon,
|
|
52
|
+
Card: () => Card,
|
|
53
|
+
ChatIcon: () => ChatIcon,
|
|
54
|
+
CheckCircleIcon: () => CheckCircleIcon,
|
|
55
|
+
CheckIcon: () => CheckIcon,
|
|
56
|
+
Checkbox: () => Checkbox,
|
|
57
|
+
ChevronDownIcon: () => ChevronDownIcon,
|
|
58
|
+
ChevronLeftIcon: () => ChevronLeftIcon,
|
|
59
|
+
ChevronRightIcon: () => ChevronRightIcon,
|
|
60
|
+
ChevronUpIcon: () => ChevronUpIcon,
|
|
61
|
+
CloseIcon: () => CloseIcon,
|
|
62
|
+
CloudIcon: () => CloudIcon,
|
|
63
|
+
CodeIcon: () => CodeIcon,
|
|
64
|
+
CopyIcon: () => CopyIcon,
|
|
65
|
+
DatabaseIcon: () => DatabaseIcon,
|
|
66
|
+
DatePicker: () => DatePicker,
|
|
67
|
+
DateTimePicker: () => DateTimePicker,
|
|
68
|
+
Divider: () => Divider,
|
|
69
|
+
DownloadIcon: () => DownloadIcon,
|
|
70
|
+
Drawer: () => Drawer,
|
|
71
|
+
EditIcon: () => EditIcon,
|
|
72
|
+
ExternalLinkIcon: () => ExternalLinkIcon,
|
|
73
|
+
EyeIcon: () => EyeIcon,
|
|
74
|
+
EyeOffIcon: () => EyeOffIcon,
|
|
75
|
+
FacebookIcon: () => FacebookIcon,
|
|
76
|
+
FileIcon: () => FileIcon,
|
|
77
|
+
FileUpload: () => FileUpload,
|
|
78
|
+
FolderIcon: () => FolderIcon,
|
|
79
|
+
GitHubIcon: () => GitHubIcon,
|
|
80
|
+
GlobeIcon: () => GlobeIcon,
|
|
81
|
+
GoogleIcon: () => GoogleIcon,
|
|
82
|
+
HeartIcon: () => HeartIcon,
|
|
83
|
+
HomeIcon: () => HomeIcon,
|
|
84
|
+
ImageIcon: () => ImageIcon,
|
|
85
|
+
InfoCircleIcon: () => InfoCircleIcon,
|
|
86
|
+
KeyIcon: () => KeyIcon,
|
|
87
|
+
LinkedInIcon: () => LinkedInIcon,
|
|
88
|
+
LockIcon: () => LockIcon,
|
|
89
|
+
MailIcon: () => MailIcon,
|
|
90
|
+
MenuIcon: () => MenuIcon,
|
|
91
|
+
Modal: () => Modal,
|
|
92
|
+
Navbar: () => Navbar,
|
|
93
|
+
NumberInput: () => NumberInput,
|
|
94
|
+
Pagination: () => Pagination,
|
|
95
|
+
PauseIcon: () => PauseIcon,
|
|
96
|
+
PlayIcon: () => PlayIcon,
|
|
97
|
+
PlugIcon: () => PlugIcon,
|
|
98
|
+
PlusIcon: () => PlusIcon,
|
|
99
|
+
ProgressBar: () => ProgressBar,
|
|
100
|
+
Radio: () => Radio,
|
|
101
|
+
RefreshIcon: () => RefreshIcon,
|
|
102
|
+
RichTextEditor: () => RichTextEditor,
|
|
103
|
+
SaveIcon: () => SaveIcon,
|
|
104
|
+
SearchIcon: () => SearchIcon,
|
|
25
105
|
Select: () => Select,
|
|
106
|
+
SettingsIcon: () => SettingsIcon,
|
|
107
|
+
ShieldIcon: () => ShieldIcon,
|
|
108
|
+
Sidebar: () => Sidebar,
|
|
109
|
+
SidebarProvider: () => SidebarProvider,
|
|
110
|
+
SkipBackIcon: () => SkipBackIcon,
|
|
111
|
+
SkipForwardIcon: () => SkipForwardIcon,
|
|
112
|
+
SlackIcon: () => SlackIcon,
|
|
113
|
+
Slider: () => Slider,
|
|
114
|
+
SparklesIcon: () => SparklesIcon,
|
|
115
|
+
Spinner: () => Spinner,
|
|
116
|
+
StarIcon: () => StarIcon,
|
|
117
|
+
Stepper: () => Stepper,
|
|
118
|
+
StopIcon: () => StopIcon,
|
|
119
|
+
Table: () => Table,
|
|
120
|
+
Tabs: () => Tabs,
|
|
121
|
+
TerminalIcon: () => TerminalIcon,
|
|
122
|
+
TextInput: () => TextInput,
|
|
123
|
+
Textarea: () => Textarea,
|
|
26
124
|
ThemeProvider: () => ThemeProvider,
|
|
125
|
+
TimePicker: () => TimePicker,
|
|
126
|
+
ToastProvider: () => ToastProvider,
|
|
127
|
+
Toggle: () => Toggle,
|
|
128
|
+
TrashIcon: () => TrashIcon,
|
|
129
|
+
TwitterIcon: () => TwitterIcon,
|
|
130
|
+
UploadIcon: () => UploadIcon,
|
|
131
|
+
UserIcon: () => UserIcon,
|
|
132
|
+
VolumeOffIcon: () => VolumeOffIcon,
|
|
133
|
+
VolumeUpIcon: () => VolumeUpIcon,
|
|
134
|
+
YouTubeIcon: () => YouTubeIcon,
|
|
27
135
|
getThemeScript: () => getThemeScript,
|
|
28
136
|
themeScript: () => themeScript,
|
|
29
137
|
themes: () => themes,
|
|
30
|
-
|
|
138
|
+
toast: () => toast,
|
|
139
|
+
useSidebar: () => useSidebar,
|
|
140
|
+
useTheme: () => useTheme,
|
|
141
|
+
useToast: () => useToast
|
|
31
142
|
});
|
|
32
143
|
module.exports = __toCommonJS(index_exports);
|
|
33
144
|
|
|
@@ -39,7 +150,7 @@ var themes = {
|
|
|
39
150
|
default: {
|
|
40
151
|
name: "default",
|
|
41
152
|
button: {
|
|
42
|
-
base: "font-semibold rounded-lg transition-all duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 active:scale-95",
|
|
153
|
+
base: "font-semibold rounded-lg transition-all duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 active:scale-95 gap-2",
|
|
43
154
|
variants: {
|
|
44
155
|
primary: "bg-blue-600 hover:bg-blue-700 active:bg-blue-800 text-white shadow-sm hover:shadow-md dark:bg-blue-500 dark:hover:bg-blue-600 dark:active:bg-blue-700",
|
|
45
156
|
secondary: "bg-gray-600 hover:bg-gray-700 active:bg-gray-800 text-white shadow-sm hover:shadow-md dark:bg-gray-500 dark:hover:bg-gray-600 dark:active:bg-gray-700",
|
|
@@ -49,15 +160,15 @@ var themes = {
|
|
|
49
160
|
info: "bg-cyan-600 hover:bg-cyan-700 active:bg-cyan-800 text-white shadow-sm hover:shadow-md dark:bg-cyan-500 dark:hover:bg-cyan-600 dark:active:bg-cyan-700"
|
|
50
161
|
},
|
|
51
162
|
sizes: {
|
|
52
|
-
sm: "px-3 py-1.5 text-sm",
|
|
53
|
-
md: "px-4 py-2 text-base",
|
|
54
|
-
lg: "px-6 py-3 text-lg",
|
|
55
|
-
xl: "px-8 py-4 text-xl"
|
|
163
|
+
sm: "px-3 py-1.5 text-sm min-h-[30px]",
|
|
164
|
+
md: "px-4 py-2 text-base min-h-[38px]",
|
|
165
|
+
lg: "px-6 py-3 text-lg min-h-[48px]",
|
|
166
|
+
xl: "px-8 py-4 text-xl min-h-[60px]"
|
|
56
167
|
},
|
|
57
168
|
disabled: "opacity-50 cursor-not-allowed hover:shadow-sm active:scale-100"
|
|
58
169
|
},
|
|
59
170
|
select: {
|
|
60
|
-
base: "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 pr-10 cursor-pointer dark:bg-gray-800 dark:border-gray-600 dark:text-gray-100 dark:hover:border-gray-500",
|
|
171
|
+
base: "w-full appearance-none rounded-lg border border-gray-300 bg-white text-gray-900 text-left transition-all duration-150 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent shadow-sm hover:border-gray-400 pr-10 cursor-pointer dark:bg-gray-800 dark:border-gray-600 dark:text-gray-100 dark:hover:border-gray-500",
|
|
61
172
|
sizes: {
|
|
62
173
|
sm: "px-3 py-1.5 text-sm",
|
|
63
174
|
md: "px-4 py-2.5 text-base",
|
|
@@ -70,7 +181,7 @@ var themes = {
|
|
|
70
181
|
minimalistic: {
|
|
71
182
|
name: "minimalistic",
|
|
72
183
|
button: {
|
|
73
|
-
base: "font-normal rounded-none transition-colors duration-200 focus:outline-none border-2",
|
|
184
|
+
base: "font-normal rounded-none transition-colors duration-200 focus:outline-none border-2 gap-2",
|
|
74
185
|
variants: {
|
|
75
186
|
primary: "bg-transparent border-white text-white hover:bg-white hover:text-black",
|
|
76
187
|
secondary: "bg-transparent border-gray-400 text-gray-400 hover:bg-gray-400 hover:text-black",
|
|
@@ -80,15 +191,15 @@ var themes = {
|
|
|
80
191
|
info: "bg-transparent border-blue-400 text-blue-400 hover:bg-blue-400 hover:text-black"
|
|
81
192
|
},
|
|
82
193
|
sizes: {
|
|
83
|
-
sm: "px-4 py-2 text-sm uppercase tracking-wide",
|
|
84
|
-
md: "px-6 py-3 text-base uppercase tracking-wide",
|
|
85
|
-
lg: "px-8 py-4 text-lg uppercase tracking-wider",
|
|
86
|
-
xl: "px-10 py-5 text-xl uppercase tracking-wider"
|
|
194
|
+
sm: "px-4 py-2 text-sm uppercase tracking-wide min-h-[36px]",
|
|
195
|
+
md: "px-6 py-3 text-base uppercase tracking-wide min-h-[48px]",
|
|
196
|
+
lg: "px-8 py-4 text-lg uppercase tracking-wider min-h-[60px]",
|
|
197
|
+
xl: "px-10 py-5 text-xl uppercase tracking-wider min-h-[72px]"
|
|
87
198
|
},
|
|
88
199
|
disabled: "opacity-30 cursor-not-allowed hover:bg-transparent"
|
|
89
200
|
},
|
|
90
201
|
select: {
|
|
91
|
-
base: "w-full appearance-none rounded-none border-2 border-white bg-transparent text-white transition-colors duration-200 focus:outline-none pr-10 cursor-pointer placeholder:text-gray-500",
|
|
202
|
+
base: "w-full appearance-none rounded-none border-2 border-white bg-transparent text-white text-left transition-colors duration-200 focus:outline-none pr-10 cursor-pointer placeholder:text-gray-500",
|
|
92
203
|
sizes: {
|
|
93
204
|
sm: "px-4 py-2 text-sm uppercase tracking-wide",
|
|
94
205
|
md: "px-4 py-3 text-base uppercase tracking-wide",
|
|
@@ -106,7 +217,20 @@ var ThemeContext = (0, import_react.createContext)(void 0);
|
|
|
106
217
|
function useTheme() {
|
|
107
218
|
const context = (0, import_react.useContext)(ThemeContext);
|
|
108
219
|
if (!context) {
|
|
109
|
-
|
|
220
|
+
const warnOnce = () => {
|
|
221
|
+
if (process.env.NODE_ENV === "development") {
|
|
222
|
+
console.warn("useTheme: Component used outside ThemeProvider. Using default theme. Wrap your app with <ThemeProvider> for full functionality.");
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
return {
|
|
226
|
+
theme: themes.default,
|
|
227
|
+
themeName: "default",
|
|
228
|
+
setTheme: () => warnOnce(),
|
|
229
|
+
colorMode: "light",
|
|
230
|
+
setColorMode: () => warnOnce(),
|
|
231
|
+
toggleColorMode: () => warnOnce(),
|
|
232
|
+
resolvedColorMode: "light"
|
|
233
|
+
};
|
|
110
234
|
}
|
|
111
235
|
return context;
|
|
112
236
|
}
|
|
@@ -154,6 +278,13 @@ function ThemeProvider({
|
|
|
154
278
|
document.documentElement.classList.remove("dark");
|
|
155
279
|
}
|
|
156
280
|
};
|
|
281
|
+
const toggleColorMode = () => {
|
|
282
|
+
if (colorMode === "system") {
|
|
283
|
+
setColorMode(resolvedColorMode === "dark" ? "light" : "dark");
|
|
284
|
+
} else {
|
|
285
|
+
setColorMode(colorMode === "dark" ? "light" : "dark");
|
|
286
|
+
}
|
|
287
|
+
};
|
|
157
288
|
(0, import_react.useEffect)(() => {
|
|
158
289
|
if (!mounted) return;
|
|
159
290
|
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
@@ -178,6 +309,7 @@ function ThemeProvider({
|
|
|
178
309
|
setTheme,
|
|
179
310
|
colorMode,
|
|
180
311
|
setColorMode,
|
|
312
|
+
toggleColorMode,
|
|
181
313
|
resolvedColorMode
|
|
182
314
|
}, children });
|
|
183
315
|
}
|
|
@@ -190,21 +322,29 @@ var Button = ({
|
|
|
190
322
|
className = "",
|
|
191
323
|
children,
|
|
192
324
|
disabled,
|
|
325
|
+
leftIcon,
|
|
326
|
+
rightIcon,
|
|
327
|
+
iconOnly = false,
|
|
193
328
|
...props
|
|
194
329
|
}) => {
|
|
195
330
|
const { theme } = useTheme();
|
|
196
331
|
const baseStyles = theme.button.base;
|
|
197
|
-
const
|
|
198
|
-
const
|
|
332
|
+
const variantStyles3 = theme.button.variants[variant];
|
|
333
|
+
const sizeStyles2 = theme.button.sizes[size];
|
|
199
334
|
const disabledStyles = disabled ? theme.button.disabled : "";
|
|
200
|
-
const
|
|
335
|
+
const iconOnlyStyles = iconOnly ? "!p-0 aspect-square" : "";
|
|
336
|
+
const classes = `inline-flex items-center justify-center ${baseStyles} ${variantStyles3} ${sizeStyles2} ${disabledStyles} ${iconOnlyStyles} ${className}`.trim();
|
|
201
337
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
202
338
|
"button",
|
|
203
339
|
{
|
|
204
340
|
className: classes,
|
|
205
341
|
disabled,
|
|
206
342
|
...props,
|
|
207
|
-
children
|
|
343
|
+
children: iconOnly ? children : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
344
|
+
leftIcon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "inline-flex shrink-0", children: leftIcon }),
|
|
345
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "inline-flex items-center", children }),
|
|
346
|
+
rightIcon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "inline-flex shrink-0", children: rightIcon })
|
|
347
|
+
] })
|
|
208
348
|
}
|
|
209
349
|
);
|
|
210
350
|
};
|
|
@@ -221,19 +361,30 @@ var Select = ({
|
|
|
221
361
|
value: controlledValue,
|
|
222
362
|
defaultValue,
|
|
223
363
|
onChange,
|
|
364
|
+
label,
|
|
365
|
+
error,
|
|
366
|
+
helperText,
|
|
367
|
+
searchable = false,
|
|
368
|
+
searchPlaceholder = "Search...",
|
|
224
369
|
...props
|
|
225
370
|
}) => {
|
|
226
371
|
const { theme, themeName } = useTheme();
|
|
227
372
|
const [isOpen, setIsOpen] = (0, import_react2.useState)(false);
|
|
228
373
|
const [internalValue, setInternalValue] = (0, import_react2.useState)(defaultValue || "");
|
|
374
|
+
const [searchQuery, setSearchQuery] = (0, import_react2.useState)("");
|
|
229
375
|
const dropdownRef = (0, import_react2.useRef)(null);
|
|
376
|
+
const searchInputRef = (0, import_react2.useRef)(null);
|
|
230
377
|
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
231
378
|
const selectedOption = options.find((opt) => opt.value === value);
|
|
232
379
|
const displayText = selectedOption ? selectedOption.label : placeholder || "Select...";
|
|
380
|
+
const filteredOptions = searchable && searchQuery ? options.filter(
|
|
381
|
+
(option) => option.label.toLowerCase().includes(searchQuery.toLowerCase())
|
|
382
|
+
) : options;
|
|
233
383
|
(0, import_react2.useEffect)(() => {
|
|
234
384
|
const handleClickOutside = (event) => {
|
|
235
385
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
236
386
|
setIsOpen(false);
|
|
387
|
+
setSearchQuery("");
|
|
237
388
|
}
|
|
238
389
|
};
|
|
239
390
|
if (isOpen) {
|
|
@@ -241,11 +392,17 @@ var Select = ({
|
|
|
241
392
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
242
393
|
}
|
|
243
394
|
}, [isOpen]);
|
|
395
|
+
(0, import_react2.useEffect)(() => {
|
|
396
|
+
if (isOpen && searchable && searchInputRef.current) {
|
|
397
|
+
searchInputRef.current.focus();
|
|
398
|
+
}
|
|
399
|
+
}, [isOpen, searchable]);
|
|
244
400
|
const handleSelect = (optionValue) => {
|
|
245
401
|
if (disabled) return;
|
|
246
402
|
setInternalValue(optionValue);
|
|
247
403
|
onChange?.(optionValue);
|
|
248
404
|
setIsOpen(false);
|
|
405
|
+
setSearchQuery("");
|
|
249
406
|
};
|
|
250
407
|
const handleToggle = () => {
|
|
251
408
|
if (!disabled) {
|
|
@@ -253,9 +410,10 @@ var Select = ({
|
|
|
253
410
|
}
|
|
254
411
|
};
|
|
255
412
|
const baseStyles = theme.select.base;
|
|
256
|
-
const
|
|
413
|
+
const sizeStyles2 = theme.select.sizes[size];
|
|
257
414
|
const disabledStyles = disabled ? theme.select.disabled : "";
|
|
258
|
-
const
|
|
415
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
416
|
+
const buttonClasses = `${baseStyles} ${sizeStyles2} ${disabledStyles} ${errorStyles}`.trim();
|
|
259
417
|
const iconColor = themeName === "minimalistic" ? disabled ? "text-gray-600" : "text-white" : disabled ? "text-gray-400" : "text-gray-500";
|
|
260
418
|
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";
|
|
261
419
|
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";
|
|
@@ -265,51 +423,4029 @@ var Select = ({
|
|
|
265
423
|
lg: "px-4 py-3 text-lg",
|
|
266
424
|
xl: "px-5 py-4 text-xl"
|
|
267
425
|
}[size];
|
|
268
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className:
|
|
269
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
427
|
+
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 }),
|
|
428
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative inline-block w-full", ref: dropdownRef, ...props, children: [
|
|
429
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
430
|
+
"button",
|
|
431
|
+
{
|
|
432
|
+
type: "button",
|
|
433
|
+
className: buttonClasses,
|
|
434
|
+
onClick: handleToggle,
|
|
435
|
+
disabled,
|
|
436
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: !selectedOption && placeholder ? "opacity-50" : "", children: displayText })
|
|
437
|
+
}
|
|
438
|
+
),
|
|
439
|
+
/* @__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)(
|
|
440
|
+
"svg",
|
|
441
|
+
{
|
|
442
|
+
className: `h-5 w-5 transition-transform duration-200 ${iconColor} ${isOpen ? "rotate-180" : ""}`,
|
|
443
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
444
|
+
viewBox: "0 0 20 20",
|
|
445
|
+
fill: "currentColor",
|
|
446
|
+
"aria-hidden": "true",
|
|
447
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
448
|
+
"path",
|
|
449
|
+
{
|
|
450
|
+
fillRule: "evenodd",
|
|
451
|
+
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",
|
|
452
|
+
clipRule: "evenodd"
|
|
453
|
+
}
|
|
454
|
+
)
|
|
455
|
+
}
|
|
456
|
+
) }),
|
|
457
|
+
isOpen && !disabled && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
458
|
+
"div",
|
|
459
|
+
{
|
|
460
|
+
className: `absolute z-50 w-full mt-1 ${dropdownBaseStyles} rounded-lg overflow-hidden`,
|
|
461
|
+
children: [
|
|
462
|
+
searchable && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `sticky top-0 ${themeName === "minimalistic" ? "bg-black border-b-2 border-white" : "bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700"}`, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
463
|
+
"input",
|
|
464
|
+
{
|
|
465
|
+
ref: searchInputRef,
|
|
466
|
+
type: "text",
|
|
467
|
+
className: `w-full ${optionSizeStyles} ${themeName === "minimalistic" ? "bg-black text-white placeholder-gray-600 focus:outline-none" : "bg-transparent text-gray-900 dark:text-gray-100 placeholder-gray-400 focus:outline-none"}`,
|
|
468
|
+
placeholder: searchPlaceholder,
|
|
469
|
+
value: searchQuery,
|
|
470
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
471
|
+
onClick: (e) => e.stopPropagation()
|
|
472
|
+
}
|
|
473
|
+
) }),
|
|
474
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
|
|
475
|
+
.select-dropdown-scroll {
|
|
476
|
+
scrollbar-width: thin;
|
|
477
|
+
scrollbar-color: rgba(156, 163, 175, 0.5) transparent;
|
|
478
|
+
}
|
|
479
|
+
.select-dropdown-scroll::-webkit-scrollbar {
|
|
480
|
+
width: 8px;
|
|
481
|
+
}
|
|
482
|
+
.select-dropdown-scroll::-webkit-scrollbar-track {
|
|
483
|
+
background: transparent;
|
|
484
|
+
}
|
|
485
|
+
.select-dropdown-scroll::-webkit-scrollbar-thumb {
|
|
486
|
+
background-color: rgba(156, 163, 175, 0.5);
|
|
487
|
+
border-radius: 4px;
|
|
488
|
+
border: 2px solid transparent;
|
|
489
|
+
background-clip: padding-box;
|
|
490
|
+
}
|
|
491
|
+
.select-dropdown-scroll::-webkit-scrollbar-thumb:hover {
|
|
492
|
+
background-color: rgba(156, 163, 175, 0.7);
|
|
493
|
+
}
|
|
494
|
+
.dark .select-dropdown-scroll {
|
|
495
|
+
scrollbar-color: rgba(75, 85, 99, 0.6) transparent;
|
|
496
|
+
}
|
|
497
|
+
.dark .select-dropdown-scroll::-webkit-scrollbar-thumb {
|
|
498
|
+
background-color: rgba(75, 85, 99, 0.6);
|
|
499
|
+
}
|
|
500
|
+
.dark .select-dropdown-scroll::-webkit-scrollbar-thumb:hover {
|
|
501
|
+
background-color: rgba(75, 85, 99, 0.8);
|
|
502
|
+
}
|
|
503
|
+
` }),
|
|
504
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
505
|
+
"div",
|
|
506
|
+
{
|
|
507
|
+
className: "select-dropdown-scroll",
|
|
508
|
+
style: { maxHeight: "300px", overflowY: "auto" },
|
|
509
|
+
children: filteredOptions.length > 0 ? filteredOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
510
|
+
"div",
|
|
511
|
+
{
|
|
512
|
+
className: `${optionBaseStyles} ${optionSizeStyles} cursor-pointer ${value === option.value ? themeName === "minimalistic" ? "bg-white text-black" : "bg-blue-50 dark:bg-gray-700" : ""}`,
|
|
513
|
+
onClick: () => handleSelect(option.value),
|
|
514
|
+
children: option.label
|
|
515
|
+
},
|
|
516
|
+
option.value
|
|
517
|
+
)) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `${optionSizeStyles} ${themeName === "minimalistic" ? "text-gray-500" : "text-gray-500 dark:text-gray-400"} text-center`, children: "No results found" })
|
|
518
|
+
}
|
|
519
|
+
)
|
|
520
|
+
]
|
|
521
|
+
}
|
|
522
|
+
)
|
|
523
|
+
] }),
|
|
524
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
525
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
526
|
+
] });
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
// src/components/Modal.tsx
|
|
530
|
+
var import_react3 = require("react");
|
|
531
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
532
|
+
var sizeClasses = {
|
|
533
|
+
sm: "max-w-md",
|
|
534
|
+
md: "max-w-lg",
|
|
535
|
+
lg: "max-w-2xl",
|
|
536
|
+
xl: "max-w-4xl"
|
|
537
|
+
};
|
|
538
|
+
var Modal = ({
|
|
539
|
+
isOpen,
|
|
540
|
+
onClose,
|
|
541
|
+
title,
|
|
542
|
+
children,
|
|
543
|
+
size = "md",
|
|
544
|
+
showCloseButton = true
|
|
545
|
+
}) => {
|
|
546
|
+
const { theme } = useTheme();
|
|
547
|
+
(0, import_react3.useEffect)(() => {
|
|
548
|
+
const handleEscape = (e) => {
|
|
549
|
+
if (e.key === "Escape" && isOpen) {
|
|
550
|
+
onClose();
|
|
277
551
|
}
|
|
278
|
-
|
|
279
|
-
|
|
552
|
+
};
|
|
553
|
+
if (isOpen) {
|
|
554
|
+
document.addEventListener("keydown", handleEscape);
|
|
555
|
+
document.body.style.overflow = "hidden";
|
|
556
|
+
}
|
|
557
|
+
return () => {
|
|
558
|
+
document.removeEventListener("keydown", handleEscape);
|
|
559
|
+
document.body.style.overflow = "unset";
|
|
560
|
+
};
|
|
561
|
+
}, [isOpen, onClose]);
|
|
562
|
+
if (!isOpen) return null;
|
|
563
|
+
const sizeClass = sizeClasses[size];
|
|
564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
565
|
+
"div",
|
|
566
|
+
{
|
|
567
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60 backdrop-blur-sm transition-all duration-200",
|
|
568
|
+
onClick: onClose,
|
|
569
|
+
role: "dialog",
|
|
570
|
+
"aria-modal": "true",
|
|
571
|
+
"aria-labelledby": title ? "modal-title" : void 0,
|
|
572
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
573
|
+
"div",
|
|
574
|
+
{
|
|
575
|
+
className: `relative w-full ${sizeClass} bg-white dark:bg-gray-800 rounded-lg shadow-2xl transform transition-all duration-200 scale-100 animate-in`,
|
|
576
|
+
onClick: (e) => e.stopPropagation(),
|
|
577
|
+
children: [
|
|
578
|
+
(title || showCloseButton) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700", children: [
|
|
579
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { id: "modal-title", className: "text-xl font-semibold text-gray-900 dark:text-gray-100", children: title }),
|
|
580
|
+
showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
581
|
+
"button",
|
|
582
|
+
{
|
|
583
|
+
onClick: onClose,
|
|
584
|
+
className: "ml-auto text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors",
|
|
585
|
+
"aria-label": "Close modal",
|
|
586
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
587
|
+
}
|
|
588
|
+
)
|
|
589
|
+
] }),
|
|
590
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "p-6", children })
|
|
591
|
+
]
|
|
592
|
+
}
|
|
593
|
+
)
|
|
594
|
+
}
|
|
595
|
+
);
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// src/components/Navbar.tsx
|
|
599
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
600
|
+
var Navbar = ({
|
|
601
|
+
logo,
|
|
602
|
+
children,
|
|
603
|
+
className = "",
|
|
604
|
+
sticky = false
|
|
605
|
+
}) => {
|
|
606
|
+
const { theme } = useTheme();
|
|
607
|
+
const baseClasses = sticky ? "sticky top-0 z-40" : "";
|
|
608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("nav", { className: `bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 ${baseClasses} ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex justify-between items-center h-16", children: [
|
|
609
|
+
logo && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center", children: logo }),
|
|
610
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex items-center gap-6", children })
|
|
611
|
+
] }) }) });
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
// src/components/Sidebar.tsx
|
|
615
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
616
|
+
var widthClasses = {
|
|
617
|
+
sm: "w-48",
|
|
618
|
+
md: "w-64",
|
|
619
|
+
lg: "w-80"
|
|
620
|
+
};
|
|
621
|
+
var Sidebar = ({
|
|
622
|
+
children,
|
|
623
|
+
className = "",
|
|
624
|
+
width = "md",
|
|
625
|
+
position = "left"
|
|
626
|
+
}) => {
|
|
627
|
+
const { theme } = useTheme();
|
|
628
|
+
const widthClass = widthClasses[width];
|
|
629
|
+
const borderClass = position === "left" ? "border-r" : "border-l";
|
|
630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
631
|
+
"aside",
|
|
632
|
+
{
|
|
633
|
+
className: `${widthClass} bg-white dark:bg-gray-800 ${borderClass} border-gray-200 dark:border-gray-700 h-full overflow-y-auto ${className}`,
|
|
634
|
+
children
|
|
635
|
+
}
|
|
636
|
+
);
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
// src/components/SidebarProvider.tsx
|
|
640
|
+
var import_react4 = require("react");
|
|
641
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
642
|
+
var SidebarContext = (0, import_react4.createContext)(void 0);
|
|
643
|
+
var SidebarProvider = ({
|
|
644
|
+
children,
|
|
645
|
+
defaultOpen = false
|
|
646
|
+
}) => {
|
|
647
|
+
const [isOpen, setIsOpen] = (0, import_react4.useState)(defaultOpen);
|
|
648
|
+
const [isMobile, setIsMobile] = (0, import_react4.useState)(false);
|
|
649
|
+
const open = () => setIsOpen(true);
|
|
650
|
+
const close = () => setIsOpen(false);
|
|
651
|
+
const toggle = () => setIsOpen((prev) => !prev);
|
|
652
|
+
const value = {
|
|
653
|
+
isOpen,
|
|
654
|
+
isMobile,
|
|
655
|
+
open,
|
|
656
|
+
close,
|
|
657
|
+
toggle,
|
|
658
|
+
setIsMobile
|
|
659
|
+
};
|
|
660
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SidebarContext.Provider, { value, children });
|
|
661
|
+
};
|
|
662
|
+
var useSidebar = () => {
|
|
663
|
+
const context = (0, import_react4.useContext)(SidebarContext);
|
|
664
|
+
if (!context) {
|
|
665
|
+
throw new Error("useSidebar must be used within a SidebarProvider");
|
|
666
|
+
}
|
|
667
|
+
return context;
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
// src/components/AppShell.tsx
|
|
671
|
+
var import_react5 = require("react");
|
|
672
|
+
|
|
673
|
+
// src/icons/icon-utils.tsx
|
|
674
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
675
|
+
var sizeClasses2 = {
|
|
676
|
+
xs: "w-3 h-3",
|
|
677
|
+
sm: "w-4 h-4",
|
|
678
|
+
md: "w-5 h-5",
|
|
679
|
+
lg: "w-6 h-6",
|
|
680
|
+
xl: "w-8 h-8"
|
|
681
|
+
};
|
|
682
|
+
var createIcon = (displayName, path, filled = false) => {
|
|
683
|
+
const Icon = ({ size = "md", className = "", color = "currentColor" }) => {
|
|
684
|
+
const sizeClass = sizeClasses2[size];
|
|
685
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
280
686
|
"svg",
|
|
281
687
|
{
|
|
282
|
-
className:
|
|
283
|
-
|
|
284
|
-
viewBox: "0 0
|
|
285
|
-
|
|
688
|
+
className: `${sizeClass} ${className}`,
|
|
689
|
+
fill: filled ? color : "none",
|
|
690
|
+
viewBox: "0 0 24 24",
|
|
691
|
+
stroke: filled ? "none" : color,
|
|
286
692
|
"aria-hidden": "true",
|
|
287
|
-
children:
|
|
288
|
-
|
|
693
|
+
children: path
|
|
694
|
+
}
|
|
695
|
+
);
|
|
696
|
+
};
|
|
697
|
+
Icon.displayName = displayName;
|
|
698
|
+
return Icon;
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
// src/icons/HomeIcon.tsx
|
|
702
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
703
|
+
var HomeIcon = createIcon(
|
|
704
|
+
"HomeIcon",
|
|
705
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" })
|
|
706
|
+
);
|
|
707
|
+
|
|
708
|
+
// src/icons/UserIcon.tsx
|
|
709
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
710
|
+
var UserIcon = createIcon(
|
|
711
|
+
"UserIcon",
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" })
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
// src/icons/SearchIcon.tsx
|
|
716
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
717
|
+
var SearchIcon = createIcon(
|
|
718
|
+
"SearchIcon",
|
|
719
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" })
|
|
720
|
+
);
|
|
721
|
+
|
|
722
|
+
// src/icons/BellIcon.tsx
|
|
723
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
724
|
+
var BellIcon = createIcon(
|
|
725
|
+
"BellIcon",
|
|
726
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" })
|
|
727
|
+
);
|
|
728
|
+
|
|
729
|
+
// src/icons/SettingsIcon.tsx
|
|
730
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
731
|
+
var SettingsIcon = createIcon(
|
|
732
|
+
"SettingsIcon",
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" }),
|
|
735
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z" })
|
|
736
|
+
] })
|
|
737
|
+
);
|
|
738
|
+
|
|
739
|
+
// src/icons/MenuIcon.tsx
|
|
740
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
741
|
+
var MenuIcon = createIcon(
|
|
742
|
+
"MenuIcon",
|
|
743
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h16M4 18h16" })
|
|
744
|
+
);
|
|
745
|
+
|
|
746
|
+
// src/icons/CloseIcon.tsx
|
|
747
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
748
|
+
var CloseIcon = createIcon(
|
|
749
|
+
"CloseIcon",
|
|
750
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" })
|
|
751
|
+
);
|
|
752
|
+
|
|
753
|
+
// src/icons/PlusIcon.tsx
|
|
754
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
755
|
+
var PlusIcon = createIcon(
|
|
756
|
+
"PlusIcon",
|
|
757
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" })
|
|
758
|
+
);
|
|
759
|
+
|
|
760
|
+
// src/icons/ArrowLeftIcon.tsx
|
|
761
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
762
|
+
var ArrowLeftIcon = createIcon(
|
|
763
|
+
"ArrowLeftIcon",
|
|
764
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 19l-7-7m0 0l7-7m-7 7h18" })
|
|
765
|
+
);
|
|
766
|
+
|
|
767
|
+
// src/icons/ArrowRightIcon.tsx
|
|
768
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
769
|
+
var ArrowRightIcon = createIcon(
|
|
770
|
+
"ArrowRightIcon",
|
|
771
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M14 5l7 7m0 0l-7 7m7-7H3" })
|
|
772
|
+
);
|
|
773
|
+
|
|
774
|
+
// src/icons/ChevronDownIcon.tsx
|
|
775
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
776
|
+
var ChevronDownIcon = createIcon(
|
|
777
|
+
"ChevronDownIcon",
|
|
778
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" })
|
|
779
|
+
);
|
|
780
|
+
|
|
781
|
+
// src/icons/ChevronUpIcon.tsx
|
|
782
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
783
|
+
var ChevronUpIcon = createIcon(
|
|
784
|
+
"ChevronUpIcon",
|
|
785
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" })
|
|
786
|
+
);
|
|
787
|
+
|
|
788
|
+
// src/icons/ChevronLeftIcon.tsx
|
|
789
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
790
|
+
var ChevronLeftIcon = createIcon(
|
|
791
|
+
"ChevronLeftIcon",
|
|
792
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" })
|
|
793
|
+
);
|
|
794
|
+
|
|
795
|
+
// src/icons/ChevronRightIcon.tsx
|
|
796
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
797
|
+
var ChevronRightIcon = createIcon(
|
|
798
|
+
"ChevronRightIcon",
|
|
799
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
|
|
800
|
+
);
|
|
801
|
+
|
|
802
|
+
// src/icons/ExternalLinkIcon.tsx
|
|
803
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
804
|
+
var ExternalLinkIcon = createIcon(
|
|
805
|
+
"ExternalLinkIcon",
|
|
806
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" })
|
|
807
|
+
);
|
|
808
|
+
|
|
809
|
+
// src/icons/CheckIcon.tsx
|
|
810
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
811
|
+
var CheckIcon = createIcon(
|
|
812
|
+
"CheckIcon",
|
|
813
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" })
|
|
814
|
+
);
|
|
815
|
+
|
|
816
|
+
// src/icons/CheckCircleIcon.tsx
|
|
817
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
818
|
+
var CheckCircleIcon = createIcon(
|
|
819
|
+
"CheckCircleIcon",
|
|
820
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" })
|
|
821
|
+
);
|
|
822
|
+
|
|
823
|
+
// src/icons/AlertCircleIcon.tsx
|
|
824
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
825
|
+
var AlertCircleIcon = createIcon(
|
|
826
|
+
"AlertCircleIcon",
|
|
827
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" })
|
|
828
|
+
);
|
|
829
|
+
|
|
830
|
+
// src/icons/InfoCircleIcon.tsx
|
|
831
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
832
|
+
var InfoCircleIcon = createIcon(
|
|
833
|
+
"InfoCircleIcon",
|
|
834
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" })
|
|
835
|
+
);
|
|
836
|
+
|
|
837
|
+
// src/icons/TrashIcon.tsx
|
|
838
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
839
|
+
var TrashIcon = createIcon(
|
|
840
|
+
"TrashIcon",
|
|
841
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" })
|
|
842
|
+
);
|
|
843
|
+
|
|
844
|
+
// src/icons/EditIcon.tsx
|
|
845
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
846
|
+
var EditIcon = createIcon(
|
|
847
|
+
"EditIcon",
|
|
848
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" })
|
|
849
|
+
);
|
|
850
|
+
|
|
851
|
+
// src/icons/CopyIcon.tsx
|
|
852
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
853
|
+
var CopyIcon = createIcon(
|
|
854
|
+
"CopyIcon",
|
|
855
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" })
|
|
856
|
+
);
|
|
857
|
+
|
|
858
|
+
// src/icons/SaveIcon.tsx
|
|
859
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
860
|
+
var SaveIcon = createIcon(
|
|
861
|
+
"SaveIcon",
|
|
862
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7H5a2 2 0 00-2 2v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4" })
|
|
863
|
+
);
|
|
864
|
+
|
|
865
|
+
// src/icons/DownloadIcon.tsx
|
|
866
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
867
|
+
var DownloadIcon = createIcon(
|
|
868
|
+
"DownloadIcon",
|
|
869
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" })
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
// src/icons/UploadIcon.tsx
|
|
873
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
874
|
+
var UploadIcon = createIcon(
|
|
875
|
+
"UploadIcon",
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" })
|
|
877
|
+
);
|
|
878
|
+
|
|
879
|
+
// src/icons/RefreshIcon.tsx
|
|
880
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
881
|
+
var RefreshIcon = createIcon(
|
|
882
|
+
"RefreshIcon",
|
|
883
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" })
|
|
884
|
+
);
|
|
885
|
+
|
|
886
|
+
// src/icons/EyeIcon.tsx
|
|
887
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
888
|
+
var EyeIcon = createIcon(
|
|
889
|
+
"EyeIcon",
|
|
890
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 12a3 3 0 11-6 0 3 3 0 016 0z M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" })
|
|
891
|
+
);
|
|
892
|
+
|
|
893
|
+
// src/icons/EyeOffIcon.tsx
|
|
894
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
895
|
+
var EyeOffIcon = createIcon(
|
|
896
|
+
"EyeOffIcon",
|
|
897
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" })
|
|
898
|
+
);
|
|
899
|
+
|
|
900
|
+
// src/icons/PlayIcon.tsx
|
|
901
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
902
|
+
var PlayIcon = createIcon(
|
|
903
|
+
"PlayIcon",
|
|
904
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { d: "M8 5v14l11-7z" }),
|
|
905
|
+
true
|
|
906
|
+
);
|
|
907
|
+
|
|
908
|
+
// src/icons/PauseIcon.tsx
|
|
909
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
910
|
+
var PauseIcon = createIcon(
|
|
911
|
+
"PauseIcon",
|
|
912
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
|
|
913
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1" }),
|
|
914
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1" })
|
|
915
|
+
] }),
|
|
916
|
+
true
|
|
917
|
+
);
|
|
918
|
+
|
|
919
|
+
// src/icons/StopIcon.tsx
|
|
920
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
921
|
+
var StopIcon = createIcon(
|
|
922
|
+
"StopIcon",
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 12a9 9 0 11-18 0 9 9 0 0118 0z" })
|
|
924
|
+
);
|
|
925
|
+
|
|
926
|
+
// src/icons/SkipBackIcon.tsx
|
|
927
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
928
|
+
var SkipBackIcon = createIcon(
|
|
929
|
+
"SkipBackIcon",
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_jsx_runtime40.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12.066 11.2a1 1 0 000 1.6l5.334 4A1 1 0 0019 16V8a1 1 0 00-1.6-.8l-5.333 4zM4.066 11.2a1 1 0 000 1.6l5.334 4A1 1 0 0011 16V8a1 1 0 00-1.6-.8l-5.334 4z" }) }),
|
|
931
|
+
false
|
|
932
|
+
);
|
|
933
|
+
|
|
934
|
+
// src/icons/SkipForwardIcon.tsx
|
|
935
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
936
|
+
var SkipForwardIcon = createIcon(
|
|
937
|
+
"SkipForwardIcon",
|
|
938
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_jsx_runtime41.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11.933 12.8a1 1 0 000-1.6L6.6 7.2A1 1 0 005 8v8a1 1 0 001.6.8l5.333-4zM19.933 12.8a1 1 0 000-1.6l-5.333-4A1 1 0 0013 8v8a1 1 0 001.6.8l5.333-4z" }) }),
|
|
939
|
+
false
|
|
940
|
+
);
|
|
941
|
+
|
|
942
|
+
// src/icons/VolumeUpIcon.tsx
|
|
943
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
944
|
+
var VolumeUpIcon = createIcon(
|
|
945
|
+
"VolumeUpIcon",
|
|
946
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_jsx_runtime42.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z" }) }),
|
|
947
|
+
false
|
|
948
|
+
);
|
|
949
|
+
|
|
950
|
+
// src/icons/VolumeOffIcon.tsx
|
|
951
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
952
|
+
var VolumeOffIcon = createIcon(
|
|
953
|
+
"VolumeOffIcon",
|
|
954
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
955
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z", clipRule: "evenodd" }),
|
|
956
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2" })
|
|
957
|
+
] }),
|
|
958
|
+
false
|
|
959
|
+
);
|
|
960
|
+
|
|
961
|
+
// src/icons/MailIcon.tsx
|
|
962
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
963
|
+
var MailIcon = createIcon(
|
|
964
|
+
"MailIcon",
|
|
965
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" })
|
|
966
|
+
);
|
|
967
|
+
|
|
968
|
+
// src/icons/ChatIcon.tsx
|
|
969
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
970
|
+
var ChatIcon = createIcon(
|
|
971
|
+
"ChatIcon",
|
|
972
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" })
|
|
973
|
+
);
|
|
974
|
+
|
|
975
|
+
// src/icons/StarIcon.tsx
|
|
976
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
977
|
+
var StarIcon = createIcon(
|
|
978
|
+
"StarIcon",
|
|
979
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" })
|
|
980
|
+
);
|
|
981
|
+
|
|
982
|
+
// src/icons/HeartIcon.tsx
|
|
983
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
984
|
+
var HeartIcon = createIcon(
|
|
985
|
+
"HeartIcon",
|
|
986
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" })
|
|
987
|
+
);
|
|
988
|
+
|
|
989
|
+
// src/icons/CameraIcon.tsx
|
|
990
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
991
|
+
var CameraIcon = createIcon(
|
|
992
|
+
"CameraIcon",
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
|
|
994
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" }),
|
|
995
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 13a3 3 0 11-6 0 3 3 0 016 0z" })
|
|
996
|
+
] })
|
|
997
|
+
);
|
|
998
|
+
|
|
999
|
+
// src/icons/CalendarIcon.tsx
|
|
1000
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
1001
|
+
var CalendarIcon = createIcon(
|
|
1002
|
+
"CalendarIcon",
|
|
1003
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.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" })
|
|
1004
|
+
);
|
|
1005
|
+
|
|
1006
|
+
// src/icons/BookIcon.tsx
|
|
1007
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
1008
|
+
var BookIcon = createIcon(
|
|
1009
|
+
"BookIcon",
|
|
1010
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" })
|
|
1011
|
+
);
|
|
1012
|
+
|
|
1013
|
+
// src/icons/FileIcon.tsx
|
|
1014
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
1015
|
+
var FileIcon = createIcon(
|
|
1016
|
+
"FileIcon",
|
|
1017
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" })
|
|
1018
|
+
);
|
|
1019
|
+
|
|
1020
|
+
// src/icons/FolderIcon.tsx
|
|
1021
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
1022
|
+
var FolderIcon = createIcon(
|
|
1023
|
+
"FolderIcon",
|
|
1024
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" })
|
|
1025
|
+
);
|
|
1026
|
+
|
|
1027
|
+
// src/icons/ImageIcon.tsx
|
|
1028
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
1029
|
+
var ImageIcon = createIcon(
|
|
1030
|
+
"ImageIcon",
|
|
1031
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" })
|
|
1032
|
+
);
|
|
1033
|
+
|
|
1034
|
+
// src/icons/CodeIcon.tsx
|
|
1035
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
1036
|
+
var CodeIcon = createIcon(
|
|
1037
|
+
"CodeIcon",
|
|
1038
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" })
|
|
1039
|
+
);
|
|
1040
|
+
|
|
1041
|
+
// src/icons/TerminalIcon.tsx
|
|
1042
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
1043
|
+
var TerminalIcon = createIcon(
|
|
1044
|
+
"TerminalIcon",
|
|
1045
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" })
|
|
1046
|
+
);
|
|
1047
|
+
|
|
1048
|
+
// src/icons/DatabaseIcon.tsx
|
|
1049
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
1050
|
+
var DatabaseIcon = createIcon(
|
|
1051
|
+
"DatabaseIcon",
|
|
1052
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4" })
|
|
1053
|
+
);
|
|
1054
|
+
|
|
1055
|
+
// src/icons/CloudIcon.tsx
|
|
1056
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
1057
|
+
var CloudIcon = createIcon(
|
|
1058
|
+
"CloudIcon",
|
|
1059
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" })
|
|
1060
|
+
);
|
|
1061
|
+
|
|
1062
|
+
// src/icons/PlugIcon.tsx
|
|
1063
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
1064
|
+
var PlugIcon = createIcon(
|
|
1065
|
+
"PlugIcon",
|
|
1066
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 10V3L4 14h7v7l9-11h-7z" })
|
|
1067
|
+
);
|
|
1068
|
+
|
|
1069
|
+
// src/icons/KeyIcon.tsx
|
|
1070
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
1071
|
+
var KeyIcon = createIcon(
|
|
1072
|
+
"KeyIcon",
|
|
1073
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" })
|
|
1074
|
+
);
|
|
1075
|
+
|
|
1076
|
+
// src/icons/LockIcon.tsx
|
|
1077
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
1078
|
+
var LockIcon = createIcon(
|
|
1079
|
+
"LockIcon",
|
|
1080
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" })
|
|
1081
|
+
);
|
|
1082
|
+
|
|
1083
|
+
// src/icons/ShieldIcon.tsx
|
|
1084
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
1085
|
+
var ShieldIcon = createIcon(
|
|
1086
|
+
"ShieldIcon",
|
|
1087
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" })
|
|
1088
|
+
);
|
|
1089
|
+
|
|
1090
|
+
// src/icons/SparklesIcon.tsx
|
|
1091
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
1092
|
+
var SparklesIcon = createIcon(
|
|
1093
|
+
"SparklesIcon",
|
|
1094
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" })
|
|
1095
|
+
);
|
|
1096
|
+
|
|
1097
|
+
// src/icons/BrainIcon.tsx
|
|
1098
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
1099
|
+
var BrainIcon = createIcon(
|
|
1100
|
+
"BrainIcon",
|
|
1101
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z" })
|
|
1102
|
+
);
|
|
1103
|
+
|
|
1104
|
+
// src/icons/GlobeIcon.tsx
|
|
1105
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
1106
|
+
var GlobeIcon = createIcon(
|
|
1107
|
+
"GlobeIcon",
|
|
1108
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z" })
|
|
1109
|
+
);
|
|
1110
|
+
|
|
1111
|
+
// src/icons/BeakerIcon.tsx
|
|
1112
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
1113
|
+
var BeakerIcon = createIcon(
|
|
1114
|
+
"BeakerIcon",
|
|
1115
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z" })
|
|
1116
|
+
);
|
|
1117
|
+
|
|
1118
|
+
// src/icons/GoogleIcon.tsx
|
|
1119
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
1120
|
+
var GoogleIcon = createIcon(
|
|
1121
|
+
"GoogleIcon",
|
|
1122
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" }),
|
|
1123
|
+
true
|
|
1124
|
+
);
|
|
1125
|
+
|
|
1126
|
+
// src/icons/GitHubIcon.tsx
|
|
1127
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
1128
|
+
var GitHubIcon = createIcon(
|
|
1129
|
+
"GitHubIcon",
|
|
1130
|
+
/* @__PURE__ */ (0, import_jsx_runtime67.jsx)("path", { d: "M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" }),
|
|
1131
|
+
true
|
|
1132
|
+
);
|
|
1133
|
+
|
|
1134
|
+
// src/icons/TwitterIcon.tsx
|
|
1135
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
1136
|
+
var TwitterIcon = createIcon(
|
|
1137
|
+
"TwitterIcon",
|
|
1138
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" }),
|
|
1139
|
+
true
|
|
1140
|
+
);
|
|
1141
|
+
|
|
1142
|
+
// src/icons/FacebookIcon.tsx
|
|
1143
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
1144
|
+
var FacebookIcon = createIcon(
|
|
1145
|
+
"FacebookIcon",
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("path", { d: "M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z" }),
|
|
1147
|
+
true
|
|
1148
|
+
);
|
|
1149
|
+
|
|
1150
|
+
// src/icons/AppleIcon.tsx
|
|
1151
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
1152
|
+
var AppleIcon = createIcon(
|
|
1153
|
+
"AppleIcon",
|
|
1154
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("path", { d: "M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z" }),
|
|
1155
|
+
true
|
|
1156
|
+
);
|
|
1157
|
+
|
|
1158
|
+
// src/icons/LinkedInIcon.tsx
|
|
1159
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
1160
|
+
var LinkedInIcon = createIcon(
|
|
1161
|
+
"LinkedInIcon",
|
|
1162
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("path", { d: "M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" }),
|
|
1163
|
+
true
|
|
1164
|
+
);
|
|
1165
|
+
|
|
1166
|
+
// src/icons/YouTubeIcon.tsx
|
|
1167
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
1168
|
+
var YouTubeIcon = createIcon(
|
|
1169
|
+
"YouTubeIcon",
|
|
1170
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("path", { d: "M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z" }),
|
|
1171
|
+
true
|
|
1172
|
+
);
|
|
1173
|
+
|
|
1174
|
+
// src/icons/SlackIcon.tsx
|
|
1175
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
1176
|
+
var SlackIcon = createIcon(
|
|
1177
|
+
"SlackIcon",
|
|
1178
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("path", { d: "M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zm10.122 2.521a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.268 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zm-2.523 10.122a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.268a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z" }),
|
|
1179
|
+
true
|
|
1180
|
+
);
|
|
1181
|
+
|
|
1182
|
+
// src/components/AppShell.tsx
|
|
1183
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
1184
|
+
var widthClasses2 = {
|
|
1185
|
+
sm: "w-48",
|
|
1186
|
+
md: "w-64",
|
|
1187
|
+
lg: "w-80"
|
|
1188
|
+
};
|
|
1189
|
+
var breakpointClasses = {
|
|
1190
|
+
sm: "sm",
|
|
1191
|
+
md: "md",
|
|
1192
|
+
lg: "lg",
|
|
1193
|
+
xl: "xl"
|
|
1194
|
+
};
|
|
1195
|
+
var AppShell = ({
|
|
1196
|
+
children,
|
|
1197
|
+
navbar,
|
|
1198
|
+
header,
|
|
1199
|
+
navbarTitle,
|
|
1200
|
+
navbarLogo,
|
|
1201
|
+
defaultNavbarOpen = false,
|
|
1202
|
+
responsive = true,
|
|
1203
|
+
className = ""
|
|
1204
|
+
}) => {
|
|
1205
|
+
const { theme } = useTheme();
|
|
1206
|
+
const [isMobileNavbarOpen, setIsMobileNavbarOpen] = (0, import_react5.useState)(defaultNavbarOpen);
|
|
1207
|
+
const navbarWidth = navbar?.width || "md";
|
|
1208
|
+
const navbarBreakpoint = navbar?.breakpoint || "md";
|
|
1209
|
+
const navbarPosition = navbar?.position || "side";
|
|
1210
|
+
const widthClass = widthClasses2[navbarWidth];
|
|
1211
|
+
const breakpoint = breakpointClasses[navbarBreakpoint];
|
|
1212
|
+
if (!responsive && navbar) {
|
|
1213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: `min-h-screen flex flex-col ${className}`, children: [
|
|
1214
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "w-full", children: header }),
|
|
1215
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "flex flex-1", children: [
|
|
1216
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("aside", { className: `${widthClass} bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 h-full overflow-y-auto`, children: navbar.content }),
|
|
1217
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("main", { className: "flex-1 overflow-y-auto", children })
|
|
1218
|
+
] })
|
|
1219
|
+
] });
|
|
1220
|
+
}
|
|
1221
|
+
if (!responsive) {
|
|
1222
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: `min-h-screen flex flex-col ${className}`, children: [
|
|
1223
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "w-full", children: header }),
|
|
1224
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("main", { className: "flex-1 overflow-y-auto", children })
|
|
1225
|
+
] });
|
|
1226
|
+
}
|
|
1227
|
+
if (navbar && navbarPosition === "top") {
|
|
1228
|
+
const mobileMenuClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
|
|
1229
|
+
const desktopNavClass = navbarBreakpoint === "sm" ? "sm:flex" : navbarBreakpoint === "md" ? "md:flex" : navbarBreakpoint === "lg" ? "lg:flex" : "xl:flex";
|
|
1230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: `min-h-screen flex flex-col bg-gray-50 dark:bg-gray-900 ${className}`, children: [
|
|
1231
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.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_runtime74.jsx)("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "flex justify-between items-center h-16", children: [
|
|
1232
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "flex items-center", children: navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: navbarTitle }) : null }),
|
|
1233
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: `hidden ${desktopNavClass} items-center gap-6`, children: navbar.content }),
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
1235
|
+
"button",
|
|
1236
|
+
{
|
|
1237
|
+
className: `${mobileMenuClass} p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors`,
|
|
1238
|
+
onClick: () => setIsMobileNavbarOpen(!isMobileNavbarOpen),
|
|
1239
|
+
"aria-label": "Toggle menu",
|
|
1240
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(MenuIcon, { size: "md" })
|
|
1241
|
+
}
|
|
1242
|
+
)
|
|
1243
|
+
] }) }) }),
|
|
1244
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "w-full", children: header }),
|
|
1245
|
+
isMobileNavbarOpen && /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
|
|
1246
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
1247
|
+
"div",
|
|
289
1248
|
{
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
1249
|
+
className: `${mobileMenuClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
|
|
1250
|
+
onClick: () => setIsMobileNavbarOpen(false)
|
|
1251
|
+
}
|
|
1252
|
+
),
|
|
1253
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.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: [
|
|
1254
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between", children: [
|
|
1255
|
+
navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: navbarTitle }) : null,
|
|
1256
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
1257
|
+
"button",
|
|
1258
|
+
{
|
|
1259
|
+
className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
|
|
1260
|
+
onClick: () => setIsMobileNavbarOpen(false),
|
|
1261
|
+
"aria-label": "Close menu",
|
|
1262
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
1263
|
+
}
|
|
1264
|
+
)
|
|
1265
|
+
] }),
|
|
1266
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
1267
|
+
"div",
|
|
1268
|
+
{
|
|
1269
|
+
className: "p-4 flex flex-col gap-4",
|
|
1270
|
+
onClick: () => setIsMobileNavbarOpen(false),
|
|
1271
|
+
children: navbar.content
|
|
1272
|
+
}
|
|
1273
|
+
)
|
|
1274
|
+
] })
|
|
1275
|
+
] }),
|
|
1276
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("main", { className: "flex-1 overflow-y-auto", children })
|
|
1277
|
+
] });
|
|
1278
|
+
}
|
|
1279
|
+
if (navbar) {
|
|
1280
|
+
const mobileHeaderClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
|
|
1281
|
+
const desktopNavbarClass = navbarBreakpoint === "sm" ? "sm:block" : navbarBreakpoint === "md" ? "md:block" : navbarBreakpoint === "lg" ? "lg:block" : "xl:block";
|
|
1282
|
+
const mobileDrawerClass = navbarBreakpoint === "sm" ? "sm:hidden" : navbarBreakpoint === "md" ? "md:hidden" : navbarBreakpoint === "lg" ? "lg:hidden" : "xl:hidden";
|
|
1283
|
+
const sidebarWidthClass = navbarWidth === "sm" ? "w-48" : navbarWidth === "lg" ? "w-80" : "w-64";
|
|
1284
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: `min-h-screen flex flex-col bg-gray-50 dark:bg-gray-900 ${className}`, children: [
|
|
1285
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: `${mobileHeaderClass} sticky top-0 z-30 bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 px-4 py-3 flex items-center justify-between`, children: [
|
|
1286
|
+
navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: navbarTitle }) : null,
|
|
1287
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
1288
|
+
"button",
|
|
1289
|
+
{
|
|
1290
|
+
className: "p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
|
|
1291
|
+
onClick: () => setIsMobileNavbarOpen(!isMobileNavbarOpen),
|
|
1292
|
+
"aria-label": "Toggle menu",
|
|
1293
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(MenuIcon, { size: "md" })
|
|
293
1294
|
}
|
|
294
1295
|
)
|
|
1296
|
+
] }),
|
|
1297
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "w-full", children: header }),
|
|
1298
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "flex flex-1 min-h-0", children: [
|
|
1299
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("aside", { className: `hidden ${desktopNavbarClass} ${sidebarWidthClass} bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 overflow-y-auto shrink-0`, children: navbar.content }),
|
|
1300
|
+
isMobileNavbarOpen && /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(import_jsx_runtime74.Fragment, { children: [
|
|
1301
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
1302
|
+
"div",
|
|
1303
|
+
{
|
|
1304
|
+
className: `${mobileDrawerClass} fixed inset-0 z-40 bg-black/60 backdrop-blur-sm animate-in fade-in duration-200`,
|
|
1305
|
+
onClick: () => setIsMobileNavbarOpen(false)
|
|
1306
|
+
}
|
|
1307
|
+
),
|
|
1308
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: `${mobileDrawerClass} 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: [
|
|
1309
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between", children: [
|
|
1310
|
+
navbarLogo ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { children: navbarLogo }) : navbarTitle ? /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: "text-xl font-bold text-gray-900 dark:text-gray-100", children: navbarTitle }) : null,
|
|
1311
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
1312
|
+
"button",
|
|
1313
|
+
{
|
|
1314
|
+
className: "p-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
|
|
1315
|
+
onClick: () => setIsMobileNavbarOpen(false),
|
|
1316
|
+
"aria-label": "Close menu",
|
|
1317
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("svg", { className: "w-6 h-6", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
1318
|
+
}
|
|
1319
|
+
)
|
|
1320
|
+
] }),
|
|
1321
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
|
|
1322
|
+
"div",
|
|
1323
|
+
{
|
|
1324
|
+
className: "overflow-y-auto h-[calc(100vh-73px)]",
|
|
1325
|
+
onClick: () => setIsMobileNavbarOpen(false),
|
|
1326
|
+
children: navbar.content
|
|
1327
|
+
}
|
|
1328
|
+
)
|
|
1329
|
+
] })
|
|
1330
|
+
] }),
|
|
1331
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("main", { className: "flex-1 overflow-y-auto min-h-screen", children })
|
|
1332
|
+
] })
|
|
1333
|
+
] });
|
|
1334
|
+
}
|
|
1335
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: `min-h-screen flex flex-col ${className}`, children: [
|
|
1336
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "w-full", children: header }),
|
|
1337
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("main", { className: "flex-1 overflow-y-auto", children })
|
|
1338
|
+
] });
|
|
1339
|
+
};
|
|
1340
|
+
|
|
1341
|
+
// src/components/Drawer.tsx
|
|
1342
|
+
var import_react6 = require("react");
|
|
1343
|
+
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
1344
|
+
var sizeClasses3 = {
|
|
1345
|
+
left: {
|
|
1346
|
+
sm: "w-64",
|
|
1347
|
+
md: "w-80",
|
|
1348
|
+
lg: "w-96"
|
|
1349
|
+
},
|
|
1350
|
+
right: {
|
|
1351
|
+
sm: "w-64",
|
|
1352
|
+
md: "w-80",
|
|
1353
|
+
lg: "w-96"
|
|
1354
|
+
},
|
|
1355
|
+
top: {
|
|
1356
|
+
sm: "h-48",
|
|
1357
|
+
md: "h-64",
|
|
1358
|
+
lg: "h-80"
|
|
1359
|
+
},
|
|
1360
|
+
bottom: {
|
|
1361
|
+
sm: "h-48",
|
|
1362
|
+
md: "h-64",
|
|
1363
|
+
lg: "h-80"
|
|
1364
|
+
}
|
|
1365
|
+
};
|
|
1366
|
+
var positionClasses = {
|
|
1367
|
+
left: "left-0 top-0 h-full",
|
|
1368
|
+
right: "right-0 top-0 h-full",
|
|
1369
|
+
top: "top-0 left-0 w-full",
|
|
1370
|
+
bottom: "bottom-0 left-0 w-full"
|
|
1371
|
+
};
|
|
1372
|
+
var slideClasses = {
|
|
1373
|
+
left: "transform transition-transform duration-300",
|
|
1374
|
+
right: "transform transition-transform duration-300",
|
|
1375
|
+
top: "transform transition-transform duration-300",
|
|
1376
|
+
bottom: "transform transition-transform duration-300"
|
|
1377
|
+
};
|
|
1378
|
+
var Drawer = ({
|
|
1379
|
+
isOpen,
|
|
1380
|
+
onClose,
|
|
1381
|
+
title,
|
|
1382
|
+
children,
|
|
1383
|
+
position = "right",
|
|
1384
|
+
size = "md",
|
|
1385
|
+
showCloseButton = true
|
|
1386
|
+
}) => {
|
|
1387
|
+
const { theme } = useTheme();
|
|
1388
|
+
(0, import_react6.useEffect)(() => {
|
|
1389
|
+
const handleEscape = (e) => {
|
|
1390
|
+
if (e.key === "Escape" && isOpen) {
|
|
1391
|
+
onClose();
|
|
295
1392
|
}
|
|
296
|
-
|
|
297
|
-
|
|
1393
|
+
};
|
|
1394
|
+
if (isOpen) {
|
|
1395
|
+
document.addEventListener("keydown", handleEscape);
|
|
1396
|
+
document.body.style.overflow = "hidden";
|
|
1397
|
+
}
|
|
1398
|
+
return () => {
|
|
1399
|
+
document.removeEventListener("keydown", handleEscape);
|
|
1400
|
+
document.body.style.overflow = "unset";
|
|
1401
|
+
};
|
|
1402
|
+
}, [isOpen, onClose]);
|
|
1403
|
+
if (!isOpen) return null;
|
|
1404
|
+
const sizeClass = sizeClasses3[position][size];
|
|
1405
|
+
const positionClass = positionClasses[position];
|
|
1406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
|
|
1407
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
298
1408
|
"div",
|
|
299
1409
|
{
|
|
300
|
-
className:
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
1410
|
+
className: "fixed inset-0 z-40 bg-black/60 backdrop-blur-sm transition-all duration-200",
|
|
1411
|
+
onClick: onClose
|
|
1412
|
+
}
|
|
1413
|
+
),
|
|
1414
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
|
|
1415
|
+
"div",
|
|
1416
|
+
{
|
|
1417
|
+
className: `fixed z-50 ${positionClass} ${sizeClass} bg-white dark:bg-gray-800 shadow-2xl overflow-hidden flex flex-col ${slideClasses[position]}`,
|
|
1418
|
+
children: [
|
|
1419
|
+
(title || showCloseButton) && /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-700", children: [
|
|
1420
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("h3", { className: "text-xl font-semibold text-gray-900 dark:text-gray-100", children: title }),
|
|
1421
|
+
showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
1422
|
+
"button",
|
|
1423
|
+
{
|
|
1424
|
+
onClick: onClose,
|
|
1425
|
+
className: "ml-auto text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors",
|
|
1426
|
+
"aria-label": "Close drawer",
|
|
1427
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("svg", { className: "w-6 h-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
1428
|
+
}
|
|
1429
|
+
)
|
|
1430
|
+
] }),
|
|
1431
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "flex-1 p-6 overflow-y-auto", children })
|
|
1432
|
+
]
|
|
1433
|
+
}
|
|
1434
|
+
)
|
|
1435
|
+
] });
|
|
1436
|
+
};
|
|
1437
|
+
|
|
1438
|
+
// src/components/TextInput.tsx
|
|
1439
|
+
var import_react7 = require("react");
|
|
1440
|
+
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
1441
|
+
var sizeClasses4 = {
|
|
1442
|
+
sm: "px-3 py-1.5 text-sm",
|
|
1443
|
+
md: "px-4 py-2.5 text-base",
|
|
1444
|
+
lg: "px-4 py-3 text-lg"
|
|
1445
|
+
};
|
|
1446
|
+
var TextInput = (0, import_react7.forwardRef)(
|
|
1447
|
+
({
|
|
1448
|
+
label,
|
|
1449
|
+
error,
|
|
1450
|
+
helperText,
|
|
1451
|
+
size = "md",
|
|
1452
|
+
fullWidth = false,
|
|
1453
|
+
leftIcon,
|
|
1454
|
+
rightIcon,
|
|
1455
|
+
className = "",
|
|
1456
|
+
disabled,
|
|
1457
|
+
...props
|
|
1458
|
+
}, ref) => {
|
|
1459
|
+
const { theme, themeName } = useTheme();
|
|
1460
|
+
const baseStyles = theme.select?.base || "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";
|
|
1461
|
+
const sizeStyle = sizeClasses4[size];
|
|
1462
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
1463
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
1464
|
+
const widthStyle = fullWidth ? "w-full" : "";
|
|
1465
|
+
const paddingWithIcon = leftIcon ? "pl-10" : rightIcon ? "pr-10" : "";
|
|
1466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: `${widthStyle} ${className}`, children: [
|
|
1467
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
1468
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "relative", children: [
|
|
1469
|
+
leftIcon && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 dark:text-gray-500", children: leftIcon }),
|
|
1470
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
1471
|
+
"input",
|
|
1472
|
+
{
|
|
1473
|
+
ref,
|
|
1474
|
+
className: `${baseStyles} ${sizeStyle} ${errorStyles} ${disabledStyles} ${paddingWithIcon}`.trim(),
|
|
1475
|
+
disabled,
|
|
1476
|
+
...props
|
|
1477
|
+
}
|
|
1478
|
+
),
|
|
1479
|
+
rightIcon && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 dark:text-gray-500", children: rightIcon })
|
|
1480
|
+
] }),
|
|
1481
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
1482
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
1483
|
+
] });
|
|
1484
|
+
}
|
|
1485
|
+
);
|
|
1486
|
+
TextInput.displayName = "TextInput";
|
|
1487
|
+
|
|
1488
|
+
// src/components/NumberInput.tsx
|
|
1489
|
+
var import_react8 = require("react");
|
|
1490
|
+
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
1491
|
+
var sizeClasses5 = {
|
|
1492
|
+
sm: "px-3 py-1.5 text-sm",
|
|
1493
|
+
md: "px-4 py-2.5 text-base",
|
|
1494
|
+
lg: "px-4 py-3 text-lg"
|
|
1495
|
+
};
|
|
1496
|
+
var NumberInput = ({
|
|
1497
|
+
label,
|
|
1498
|
+
error,
|
|
1499
|
+
helperText,
|
|
1500
|
+
value,
|
|
1501
|
+
onChange,
|
|
1502
|
+
min,
|
|
1503
|
+
max,
|
|
1504
|
+
step = 1,
|
|
1505
|
+
precision,
|
|
1506
|
+
disabled = false,
|
|
1507
|
+
hideControls = false,
|
|
1508
|
+
size = "md",
|
|
1509
|
+
fullWidth = false,
|
|
1510
|
+
placeholder,
|
|
1511
|
+
className = ""
|
|
1512
|
+
}) => {
|
|
1513
|
+
const { theme } = useTheme();
|
|
1514
|
+
const inputRef = (0, import_react8.useRef)(null);
|
|
1515
|
+
const [isFocused, setIsFocused] = (0, import_react8.useState)(false);
|
|
1516
|
+
const clampValue = (val) => {
|
|
1517
|
+
let clamped = val;
|
|
1518
|
+
if (min !== void 0 && clamped < min) clamped = min;
|
|
1519
|
+
if (max !== void 0 && clamped > max) clamped = max;
|
|
1520
|
+
if (precision !== void 0) {
|
|
1521
|
+
clamped = parseFloat(clamped.toFixed(precision));
|
|
1522
|
+
}
|
|
1523
|
+
return clamped;
|
|
1524
|
+
};
|
|
1525
|
+
const handleIncrement = () => {
|
|
1526
|
+
if (disabled) return;
|
|
1527
|
+
const currentValue = value ?? 0;
|
|
1528
|
+
const newValue = clampValue(currentValue + step);
|
|
1529
|
+
onChange?.(newValue);
|
|
1530
|
+
};
|
|
1531
|
+
const handleDecrement = () => {
|
|
1532
|
+
if (disabled) return;
|
|
1533
|
+
const currentValue = value ?? 0;
|
|
1534
|
+
const newValue = clampValue(currentValue - step);
|
|
1535
|
+
onChange?.(newValue);
|
|
1536
|
+
};
|
|
1537
|
+
const handleInputChange = (e) => {
|
|
1538
|
+
const inputValue = e.target.value;
|
|
1539
|
+
if (inputValue === "" || inputValue === "-") {
|
|
1540
|
+
onChange?.(void 0);
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
const numValue = parseFloat(inputValue);
|
|
1544
|
+
if (!isNaN(numValue)) {
|
|
1545
|
+
const clamped = clampValue(numValue);
|
|
1546
|
+
onChange?.(clamped);
|
|
1547
|
+
}
|
|
1548
|
+
};
|
|
1549
|
+
const handleKeyDown = (e) => {
|
|
1550
|
+
if (e.key === "ArrowUp") {
|
|
1551
|
+
e.preventDefault();
|
|
1552
|
+
handleIncrement();
|
|
1553
|
+
} else if (e.key === "ArrowDown") {
|
|
1554
|
+
e.preventDefault();
|
|
1555
|
+
handleDecrement();
|
|
1556
|
+
}
|
|
1557
|
+
};
|
|
1558
|
+
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";
|
|
1559
|
+
const sizeStyle = sizeClasses5[size];
|
|
1560
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
1561
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
1562
|
+
const widthStyle = fullWidth ? "w-full" : "";
|
|
1563
|
+
const paddingWithControls = !hideControls ? "pr-8" : "";
|
|
1564
|
+
const displayValue = value !== void 0 ? value.toString() : "";
|
|
1565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: `${widthStyle} ${className}`, children: [
|
|
1566
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
1567
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "relative", children: [
|
|
1568
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
1569
|
+
"input",
|
|
1570
|
+
{
|
|
1571
|
+
ref: inputRef,
|
|
1572
|
+
type: "number",
|
|
1573
|
+
value: displayValue,
|
|
1574
|
+
onChange: handleInputChange,
|
|
1575
|
+
onKeyDown: handleKeyDown,
|
|
1576
|
+
onFocus: () => setIsFocused(true),
|
|
1577
|
+
onBlur: () => setIsFocused(false),
|
|
1578
|
+
disabled,
|
|
1579
|
+
placeholder,
|
|
1580
|
+
min,
|
|
1581
|
+
max,
|
|
1582
|
+
step,
|
|
1583
|
+
className: `${baseStyles} ${sizeStyle} ${errorStyles} ${disabledStyles} ${paddingWithControls} [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none`.trim()
|
|
1584
|
+
}
|
|
1585
|
+
),
|
|
1586
|
+
!hideControls && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "absolute right-1 top-1/2 -translate-y-1/2 flex flex-col", children: [
|
|
1587
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
1588
|
+
"button",
|
|
1589
|
+
{
|
|
1590
|
+
type: "button",
|
|
1591
|
+
onClick: handleIncrement,
|
|
1592
|
+
disabled: disabled || max !== void 0 && value !== void 0 && value >= max,
|
|
1593
|
+
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",
|
|
1594
|
+
tabIndex: -1,
|
|
1595
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime77.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_runtime77.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M5 15l7-7 7 7" }) })
|
|
1596
|
+
}
|
|
1597
|
+
),
|
|
1598
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
|
|
1599
|
+
"button",
|
|
1600
|
+
{
|
|
1601
|
+
type: "button",
|
|
1602
|
+
onClick: handleDecrement,
|
|
1603
|
+
disabled: disabled || min !== void 0 && value !== void 0 && value <= min,
|
|
1604
|
+
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",
|
|
1605
|
+
tabIndex: -1,
|
|
1606
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime77.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_runtime77.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M19 9l-7 7-7-7" }) })
|
|
1607
|
+
}
|
|
1608
|
+
)
|
|
1609
|
+
] })
|
|
1610
|
+
] }),
|
|
1611
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
1612
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
1613
|
+
] });
|
|
1614
|
+
};
|
|
1615
|
+
NumberInput.displayName = "NumberInput";
|
|
1616
|
+
|
|
1617
|
+
// src/components/ActionMenu.tsx
|
|
1618
|
+
var import_react9 = require("react");
|
|
1619
|
+
var import_react_dom = require("react-dom");
|
|
1620
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
1621
|
+
var ActionMenu = ({
|
|
1622
|
+
items,
|
|
1623
|
+
trigger,
|
|
1624
|
+
position = "right",
|
|
1625
|
+
placement = "bottom"
|
|
1626
|
+
}) => {
|
|
1627
|
+
const { themeName } = useTheme();
|
|
1628
|
+
const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
|
|
1629
|
+
const [menuPosition, setMenuPosition] = (0, import_react9.useState)(null);
|
|
1630
|
+
const [mounted, setMounted] = (0, import_react9.useState)(false);
|
|
1631
|
+
const menuRef = (0, import_react9.useRef)(null);
|
|
1632
|
+
const triggerRef = (0, import_react9.useRef)(null);
|
|
1633
|
+
(0, import_react9.useEffect)(() => {
|
|
1634
|
+
setMounted(true);
|
|
1635
|
+
}, []);
|
|
1636
|
+
(0, import_react9.useEffect)(() => {
|
|
1637
|
+
const handleClickOutside = (event) => {
|
|
1638
|
+
if (menuRef.current && !menuRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
1639
|
+
setIsOpen(false);
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
if (isOpen) {
|
|
1643
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1644
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1645
|
+
}
|
|
1646
|
+
}, [isOpen]);
|
|
1647
|
+
(0, import_react9.useEffect)(() => {
|
|
1648
|
+
if (isOpen && triggerRef.current) {
|
|
1649
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
1650
|
+
const menuWidth = 224;
|
|
1651
|
+
const menuHeight = 300;
|
|
1652
|
+
const spacing = 8;
|
|
1653
|
+
let top = 0;
|
|
1654
|
+
let left = 0;
|
|
1655
|
+
switch (placement) {
|
|
1656
|
+
case "top":
|
|
1657
|
+
top = rect.top - menuHeight - spacing;
|
|
1658
|
+
left = position === "left" ? rect.left : rect.right - menuWidth;
|
|
1659
|
+
break;
|
|
1660
|
+
case "bottom":
|
|
1661
|
+
top = rect.bottom + spacing;
|
|
1662
|
+
left = position === "left" ? rect.left : rect.right - menuWidth;
|
|
1663
|
+
break;
|
|
1664
|
+
case "left":
|
|
1665
|
+
top = rect.top;
|
|
1666
|
+
left = rect.left - menuWidth - spacing;
|
|
1667
|
+
break;
|
|
1668
|
+
case "right":
|
|
1669
|
+
top = rect.top;
|
|
1670
|
+
left = rect.right + spacing;
|
|
1671
|
+
break;
|
|
1672
|
+
}
|
|
1673
|
+
setMenuPosition({ top, left });
|
|
1674
|
+
} else {
|
|
1675
|
+
setMenuPosition(null);
|
|
1676
|
+
}
|
|
1677
|
+
}, [isOpen, position, placement]);
|
|
1678
|
+
const handleItemClick = (item) => {
|
|
1679
|
+
if (item.type === "divider") return;
|
|
1680
|
+
if (!item.disabled) {
|
|
1681
|
+
item.onClick();
|
|
1682
|
+
setIsOpen(false);
|
|
1683
|
+
}
|
|
1684
|
+
};
|
|
1685
|
+
const defaultTrigger = /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
1686
|
+
"button",
|
|
1687
|
+
{
|
|
1688
|
+
className: "p-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
|
|
1689
|
+
"aria-label": "Open menu",
|
|
1690
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime78.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_runtime78.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" }) })
|
|
1691
|
+
}
|
|
1692
|
+
);
|
|
1693
|
+
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";
|
|
1694
|
+
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";
|
|
1695
|
+
const menu = isOpen && mounted && menuPosition ? /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
1696
|
+
"div",
|
|
1697
|
+
{
|
|
1698
|
+
ref: menuRef,
|
|
1699
|
+
className: `fixed w-56 rounded-lg ${menuBaseStyles} z-[9999] max-h-[80vh] overflow-auto`,
|
|
1700
|
+
style: {
|
|
1701
|
+
minWidth: "14rem",
|
|
1702
|
+
top: `${menuPosition.top}px`,
|
|
1703
|
+
left: `${menuPosition.left}px`
|
|
1704
|
+
},
|
|
1705
|
+
children: items.map((item, index) => {
|
|
1706
|
+
if (item.type === "divider") {
|
|
1707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
|
|
1708
|
+
"div",
|
|
1709
|
+
{
|
|
1710
|
+
className: "my-1 border-t border-gray-200 dark:border-gray-700"
|
|
1711
|
+
},
|
|
1712
|
+
index
|
|
1713
|
+
);
|
|
1714
|
+
}
|
|
1715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(
|
|
1716
|
+
"button",
|
|
304
1717
|
{
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
1718
|
+
onClick: () => handleItemClick(item),
|
|
1719
|
+
disabled: item.disabled,
|
|
1720
|
+
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" : ""}`,
|
|
1721
|
+
children: [
|
|
1722
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "flex-shrink-0", children: item.icon }),
|
|
1723
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "flex-1", children: item.label })
|
|
1724
|
+
]
|
|
308
1725
|
},
|
|
309
|
-
|
|
310
|
-
)
|
|
1726
|
+
index
|
|
1727
|
+
);
|
|
1728
|
+
})
|
|
1729
|
+
}
|
|
1730
|
+
) : null;
|
|
1731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)(import_jsx_runtime78.Fragment, { children: [
|
|
1732
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "relative inline-block", ref: triggerRef, children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { onClick: () => setIsOpen(!isOpen), children: trigger || defaultTrigger }) }),
|
|
1733
|
+
mounted && (0, import_react_dom.createPortal)(menu, document.body)
|
|
1734
|
+
] });
|
|
1735
|
+
};
|
|
1736
|
+
|
|
1737
|
+
// src/components/Card.tsx
|
|
1738
|
+
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
1739
|
+
var paddingClasses = {
|
|
1740
|
+
none: "",
|
|
1741
|
+
sm: "p-4",
|
|
1742
|
+
md: "p-6",
|
|
1743
|
+
lg: "p-8"
|
|
1744
|
+
};
|
|
1745
|
+
var Card = ({
|
|
1746
|
+
children,
|
|
1747
|
+
className = "",
|
|
1748
|
+
padding = "md",
|
|
1749
|
+
hover = false,
|
|
1750
|
+
...props
|
|
1751
|
+
}) => {
|
|
1752
|
+
const { theme } = useTheme();
|
|
1753
|
+
const paddingClass = paddingClasses[padding];
|
|
1754
|
+
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" : "";
|
|
1755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
|
|
1756
|
+
"div",
|
|
1757
|
+
{
|
|
1758
|
+
className: `bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 ${paddingClass} ${hoverClass} ${className}`,
|
|
1759
|
+
...props,
|
|
1760
|
+
children
|
|
1761
|
+
}
|
|
1762
|
+
);
|
|
1763
|
+
};
|
|
1764
|
+
|
|
1765
|
+
// src/components/Alert.tsx
|
|
1766
|
+
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
1767
|
+
var variantStyles = {
|
|
1768
|
+
info: "bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 text-blue-900 dark:text-blue-100",
|
|
1769
|
+
success: "bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800 text-green-900 dark:text-green-100",
|
|
1770
|
+
warning: "bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800 text-yellow-900 dark:text-yellow-100",
|
|
1771
|
+
error: "bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800 text-red-900 dark:text-red-100"
|
|
1772
|
+
};
|
|
1773
|
+
var iconStyles = {
|
|
1774
|
+
info: "text-blue-600 dark:text-blue-400",
|
|
1775
|
+
success: "text-green-600 dark:text-green-400",
|
|
1776
|
+
warning: "text-yellow-600 dark:text-yellow-400",
|
|
1777
|
+
error: "text-red-600 dark:text-red-400"
|
|
1778
|
+
};
|
|
1779
|
+
var Alert = ({
|
|
1780
|
+
variant = "info",
|
|
1781
|
+
title,
|
|
1782
|
+
children,
|
|
1783
|
+
onClose,
|
|
1784
|
+
className = ""
|
|
1785
|
+
}) => {
|
|
1786
|
+
const { theme } = useTheme();
|
|
1787
|
+
const variantClass = variantStyles[variant];
|
|
1788
|
+
const iconClass = iconStyles[variant];
|
|
1789
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: `rounded-lg border p-4 ${variantClass} ${className}`, role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
1790
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: `flex-shrink-0 ${iconClass}`, children: [
|
|
1791
|
+
variant === "info" && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime80.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" }) }),
|
|
1792
|
+
variant === "success" && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime80.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" }) }),
|
|
1793
|
+
variant === "warning" && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime80.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" }) }),
|
|
1794
|
+
variant === "error" && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime80.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" }) })
|
|
1795
|
+
] }),
|
|
1796
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "flex-1", children: [
|
|
1797
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("h3", { className: "font-semibold mb-1", children: title }),
|
|
1798
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "text-sm", children })
|
|
1799
|
+
] }),
|
|
1800
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
|
|
1801
|
+
"button",
|
|
1802
|
+
{
|
|
1803
|
+
onClick: onClose,
|
|
1804
|
+
className: `flex-shrink-0 ${iconClass} hover:opacity-70 transition-opacity`,
|
|
1805
|
+
"aria-label": "Close alert",
|
|
1806
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("svg", { className: "w-5 h-5", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
311
1807
|
}
|
|
312
1808
|
)
|
|
1809
|
+
] }) });
|
|
1810
|
+
};
|
|
1811
|
+
|
|
1812
|
+
// src/components/Checkbox.tsx
|
|
1813
|
+
var import_react10 = require("react");
|
|
1814
|
+
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
1815
|
+
var Checkbox = (0, import_react10.forwardRef)(
|
|
1816
|
+
({ label, error, className = "", disabled, checked, ...props }, ref) => {
|
|
1817
|
+
const { theme } = useTheme();
|
|
1818
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className, children: [
|
|
1819
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "flex items-center gap-2 cursor-pointer group", children: [
|
|
1820
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "relative inline-flex items-center", children: [
|
|
1821
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
1822
|
+
"input",
|
|
1823
|
+
{
|
|
1824
|
+
ref,
|
|
1825
|
+
type: "checkbox",
|
|
1826
|
+
disabled,
|
|
1827
|
+
checked,
|
|
1828
|
+
className: "sr-only peer",
|
|
1829
|
+
...props
|
|
1830
|
+
}
|
|
1831
|
+
),
|
|
1832
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: `w-4 h-4 border-2 rounded transition-all duration-200 flex items-center justify-center
|
|
1833
|
+
${error ? "border-red-500 dark:border-red-500" : "border-gray-300 dark:border-gray-600"}
|
|
1834
|
+
${disabled ? "opacity-50 cursor-not-allowed bg-gray-100 dark:bg-gray-800" : "peer-hover:border-gray-400 dark:peer-hover:border-gray-500"}
|
|
1835
|
+
peer-checked:bg-blue-600 peer-checked:border-blue-600
|
|
1836
|
+
peer-focus:ring-2 peer-focus:ring-blue-500 peer-focus:ring-offset-2
|
|
1837
|
+
`, children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
1838
|
+
"svg",
|
|
1839
|
+
{
|
|
1840
|
+
className: `w-3 h-3 text-white transition-opacity duration-200 ${checked ? "opacity-100" : "opacity-0"}`,
|
|
1841
|
+
viewBox: "0 0 12 12",
|
|
1842
|
+
fill: "none",
|
|
1843
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1844
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
|
1845
|
+
"path",
|
|
1846
|
+
{
|
|
1847
|
+
d: "M10 3L4.5 8.5L2 6",
|
|
1848
|
+
stroke: "currentColor",
|
|
1849
|
+
strokeWidth: "2",
|
|
1850
|
+
strokeLinecap: "round",
|
|
1851
|
+
strokeLinejoin: "round"
|
|
1852
|
+
}
|
|
1853
|
+
)
|
|
1854
|
+
}
|
|
1855
|
+
) })
|
|
1856
|
+
] }),
|
|
1857
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime81.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 })
|
|
1858
|
+
] }),
|
|
1859
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error })
|
|
1860
|
+
] });
|
|
1861
|
+
}
|
|
1862
|
+
);
|
|
1863
|
+
Checkbox.displayName = "Checkbox";
|
|
1864
|
+
|
|
1865
|
+
// src/components/Toggle.tsx
|
|
1866
|
+
var import_react11 = require("react");
|
|
1867
|
+
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
1868
|
+
var Toggle = (0, import_react11.forwardRef)(
|
|
1869
|
+
({ label, size = "md", className = "", disabled, checked, ...props }, ref) => {
|
|
1870
|
+
const { theme } = useTheme();
|
|
1871
|
+
const toggleClasses = {
|
|
1872
|
+
sm: {
|
|
1873
|
+
switch: "w-9 h-5",
|
|
1874
|
+
thumb: "w-4 h-4 peer-checked:translate-x-4"
|
|
1875
|
+
},
|
|
1876
|
+
md: {
|
|
1877
|
+
switch: "w-11 h-6",
|
|
1878
|
+
thumb: "w-5 h-5 peer-checked:translate-x-5"
|
|
1879
|
+
},
|
|
1880
|
+
lg: {
|
|
1881
|
+
switch: "w-14 h-7",
|
|
1882
|
+
thumb: "w-6 h-6 peer-checked:translate-x-7"
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
const currentSize = toggleClasses[size];
|
|
1886
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("label", { className: `inline-flex items-center gap-3 cursor-pointer ${disabled ? "opacity-50 cursor-not-allowed" : ""} ${className}`, children: [
|
|
1887
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "relative", children: [
|
|
1888
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
1889
|
+
"input",
|
|
1890
|
+
{
|
|
1891
|
+
ref,
|
|
1892
|
+
type: "checkbox",
|
|
1893
|
+
className: "sr-only peer",
|
|
1894
|
+
disabled,
|
|
1895
|
+
checked,
|
|
1896
|
+
...props
|
|
1897
|
+
}
|
|
1898
|
+
),
|
|
1899
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
1900
|
+
"div",
|
|
1901
|
+
{
|
|
1902
|
+
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`
|
|
1903
|
+
}
|
|
1904
|
+
),
|
|
1905
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
|
1906
|
+
"div",
|
|
1907
|
+
{
|
|
1908
|
+
className: `${currentSize.thumb} bg-white rounded-full shadow-md absolute top-0.5 left-0.5 transition-transform`
|
|
1909
|
+
}
|
|
1910
|
+
)
|
|
1911
|
+
] }),
|
|
1912
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label })
|
|
1913
|
+
] });
|
|
1914
|
+
}
|
|
1915
|
+
);
|
|
1916
|
+
Toggle.displayName = "Toggle";
|
|
1917
|
+
|
|
1918
|
+
// src/components/Badge.tsx
|
|
1919
|
+
var import_jsx_runtime83 = require("react/jsx-runtime");
|
|
1920
|
+
var variantStyles2 = {
|
|
1921
|
+
default: "bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-200",
|
|
1922
|
+
primary: "bg-blue-100 dark:bg-blue-900/30 text-blue-800 dark:text-blue-200",
|
|
1923
|
+
success: "bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-200",
|
|
1924
|
+
warning: "bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-200",
|
|
1925
|
+
error: "bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-200",
|
|
1926
|
+
info: "bg-cyan-100 dark:bg-cyan-900/30 text-cyan-800 dark:text-cyan-200"
|
|
1927
|
+
};
|
|
1928
|
+
var sizeStyles = {
|
|
1929
|
+
sm: "px-2 py-0.5 text-xs",
|
|
1930
|
+
md: "px-2.5 py-1 text-sm",
|
|
1931
|
+
lg: "px-3 py-1.5 text-base"
|
|
1932
|
+
};
|
|
1933
|
+
var Badge = ({
|
|
1934
|
+
children,
|
|
1935
|
+
variant = "default",
|
|
1936
|
+
size = "md",
|
|
1937
|
+
className = ""
|
|
1938
|
+
}) => {
|
|
1939
|
+
const { theme } = useTheme();
|
|
1940
|
+
const variantClass = variantStyles2[variant];
|
|
1941
|
+
const sizeClass = sizeStyles[size];
|
|
1942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { className: `inline-flex items-center font-medium rounded-full ${variantClass} ${sizeClass} ${className}`, children });
|
|
1943
|
+
};
|
|
1944
|
+
|
|
1945
|
+
// src/components/Spinner.tsx
|
|
1946
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
1947
|
+
var sizeClasses6 = {
|
|
1948
|
+
sm: "w-4 h-4 border-2",
|
|
1949
|
+
md: "w-8 h-8 border-2",
|
|
1950
|
+
lg: "w-12 h-12 border-3",
|
|
1951
|
+
xl: "w-16 h-16 border-4"
|
|
1952
|
+
};
|
|
1953
|
+
var colorClasses = {
|
|
1954
|
+
primary: "border-blue-600 border-t-transparent",
|
|
1955
|
+
secondary: "border-gray-600 border-t-transparent",
|
|
1956
|
+
white: "border-white border-t-transparent"
|
|
1957
|
+
};
|
|
1958
|
+
var Spinner = ({
|
|
1959
|
+
size = "md",
|
|
1960
|
+
color = "primary",
|
|
1961
|
+
className = ""
|
|
1962
|
+
}) => {
|
|
1963
|
+
const { theme } = useTheme();
|
|
1964
|
+
const sizeClass = sizeClasses6[size];
|
|
1965
|
+
const colorClass = colorClasses[color];
|
|
1966
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
1967
|
+
"div",
|
|
1968
|
+
{
|
|
1969
|
+
className: `inline-block rounded-full animate-spin ${sizeClass} ${colorClass} ${className}`,
|
|
1970
|
+
role: "status",
|
|
1971
|
+
"aria-label": "Loading",
|
|
1972
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "sr-only", children: "Loading..." })
|
|
1973
|
+
}
|
|
1974
|
+
);
|
|
1975
|
+
};
|
|
1976
|
+
|
|
1977
|
+
// src/components/Tabs.tsx
|
|
1978
|
+
var import_react12 = require("react");
|
|
1979
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
1980
|
+
var Tabs = ({
|
|
1981
|
+
tabs,
|
|
1982
|
+
defaultIndex = 0,
|
|
1983
|
+
onChange,
|
|
1984
|
+
className = ""
|
|
1985
|
+
}) => {
|
|
1986
|
+
const { theme } = useTheme();
|
|
1987
|
+
const [activeIndex, setActiveIndex] = (0, import_react12.useState)(defaultIndex);
|
|
1988
|
+
const handleTabClick = (index) => {
|
|
1989
|
+
if (tabs[index].disabled) return;
|
|
1990
|
+
setActiveIndex(index);
|
|
1991
|
+
onChange?.(index);
|
|
1992
|
+
};
|
|
1993
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className, children: [
|
|
1994
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("nav", { className: "flex gap-8 px-6", "aria-label": "Tabs", children: tabs.map((tab, index) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
1995
|
+
"button",
|
|
1996
|
+
{
|
|
1997
|
+
onClick: () => handleTabClick(index),
|
|
1998
|
+
disabled: tab.disabled,
|
|
1999
|
+
className: `py-4 px-1 border-b-2 font-medium text-sm transition-colors ${activeIndex === index ? "border-blue-600 text-blue-600 dark:text-blue-400" : "border-transparent text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 hover:border-gray-300 dark:hover:border-gray-600"} ${tab.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}`,
|
|
2000
|
+
"aria-current": activeIndex === index ? "page" : void 0,
|
|
2001
|
+
children: tab.label
|
|
2002
|
+
},
|
|
2003
|
+
index
|
|
2004
|
+
)) }) }),
|
|
2005
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { children: tabs[activeIndex]?.content })
|
|
2006
|
+
] });
|
|
2007
|
+
};
|
|
2008
|
+
|
|
2009
|
+
// src/components/Table.tsx
|
|
2010
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
2011
|
+
function Table({
|
|
2012
|
+
columns,
|
|
2013
|
+
data,
|
|
2014
|
+
keyField = "id",
|
|
2015
|
+
striped = false,
|
|
2016
|
+
hoverable = true,
|
|
2017
|
+
className = ""
|
|
2018
|
+
}) {
|
|
2019
|
+
const { theme } = useTheme();
|
|
2020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: `overflow-x-auto ${className}`, children: [
|
|
2021
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("table", { className: "w-full text-left", children: [
|
|
2022
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("thead", { className: "bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("tr", { children: columns.map((column, colIndex) => {
|
|
2023
|
+
const isLast = colIndex === columns.length - 1;
|
|
2024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
2025
|
+
"th",
|
|
2026
|
+
{
|
|
2027
|
+
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",
|
|
2028
|
+
style: { width: column.width },
|
|
2029
|
+
children: column.title
|
|
2030
|
+
},
|
|
2031
|
+
column.key
|
|
2032
|
+
);
|
|
2033
|
+
}) }) }),
|
|
2034
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700", children: data.map((row, rowIndex) => {
|
|
2035
|
+
const rowClasses = [
|
|
2036
|
+
striped && rowIndex % 2 === 1 ? "bg-gray-50 dark:bg-gray-800/50" : "",
|
|
2037
|
+
hoverable ? "hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" : ""
|
|
2038
|
+
].filter(Boolean).join(" ");
|
|
2039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
2040
|
+
"tr",
|
|
2041
|
+
{
|
|
2042
|
+
className: rowClasses,
|
|
2043
|
+
children: columns.map((column, colIndex) => {
|
|
2044
|
+
const isLast = colIndex === columns.length - 1;
|
|
2045
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
2046
|
+
"td",
|
|
2047
|
+
{
|
|
2048
|
+
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",
|
|
2049
|
+
children: column.render ? column.render(row[column.key], row, rowIndex) : row[column.key]
|
|
2050
|
+
},
|
|
2051
|
+
column.key
|
|
2052
|
+
);
|
|
2053
|
+
})
|
|
2054
|
+
},
|
|
2055
|
+
row[keyField] || rowIndex
|
|
2056
|
+
);
|
|
2057
|
+
}) })
|
|
2058
|
+
] }),
|
|
2059
|
+
data.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "text-center py-8 text-gray-500 dark:text-gray-400", children: "No data available" })
|
|
2060
|
+
] });
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
// src/components/Pagination.tsx
|
|
2064
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
2065
|
+
var Pagination = ({
|
|
2066
|
+
currentPage,
|
|
2067
|
+
totalPages,
|
|
2068
|
+
onPageChange,
|
|
2069
|
+
siblingCount = 1,
|
|
2070
|
+
className = ""
|
|
2071
|
+
}) => {
|
|
2072
|
+
const { theme } = useTheme();
|
|
2073
|
+
const range = (start, end) => {
|
|
2074
|
+
const length = end - start + 1;
|
|
2075
|
+
return Array.from({ length }, (_, idx) => idx + start);
|
|
2076
|
+
};
|
|
2077
|
+
const paginationRange = () => {
|
|
2078
|
+
const totalPageNumbers = siblingCount + 5;
|
|
2079
|
+
if (totalPageNumbers >= totalPages) {
|
|
2080
|
+
return range(1, totalPages);
|
|
2081
|
+
}
|
|
2082
|
+
const leftSiblingIndex = Math.max(currentPage - siblingCount, 1);
|
|
2083
|
+
const rightSiblingIndex = Math.min(currentPage + siblingCount, totalPages);
|
|
2084
|
+
const shouldShowLeftDots = leftSiblingIndex > 2;
|
|
2085
|
+
const shouldShowRightDots = rightSiblingIndex < totalPages - 2;
|
|
2086
|
+
const firstPageIndex = 1;
|
|
2087
|
+
const lastPageIndex = totalPages;
|
|
2088
|
+
if (!shouldShowLeftDots && shouldShowRightDots) {
|
|
2089
|
+
const leftItemCount = 3 + 2 * siblingCount;
|
|
2090
|
+
const leftRange = range(1, leftItemCount);
|
|
2091
|
+
return [...leftRange, "...", totalPages];
|
|
2092
|
+
}
|
|
2093
|
+
if (shouldShowLeftDots && !shouldShowRightDots) {
|
|
2094
|
+
const rightItemCount = 3 + 2 * siblingCount;
|
|
2095
|
+
const rightRange = range(totalPages - rightItemCount + 1, totalPages);
|
|
2096
|
+
return [firstPageIndex, "...", ...rightRange];
|
|
2097
|
+
}
|
|
2098
|
+
if (shouldShowLeftDots && shouldShowRightDots) {
|
|
2099
|
+
const middleRange = range(leftSiblingIndex, rightSiblingIndex);
|
|
2100
|
+
return [firstPageIndex, "...", ...middleRange, "...", lastPageIndex];
|
|
2101
|
+
}
|
|
2102
|
+
return range(1, totalPages);
|
|
2103
|
+
};
|
|
2104
|
+
const pages = paginationRange();
|
|
2105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("nav", { className: `flex items-center gap-1 ${className}`, "aria-label": "Pagination", children: [
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
2107
|
+
"button",
|
|
2108
|
+
{
|
|
2109
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
2110
|
+
disabled: currentPage === 1,
|
|
2111
|
+
className: "px-3 py-2 rounded-md text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
|
|
2112
|
+
"aria-label": "Previous page",
|
|
2113
|
+
children: "Previous"
|
|
2114
|
+
}
|
|
2115
|
+
),
|
|
2116
|
+
pages.map((page, index) => {
|
|
2117
|
+
if (page === "...") {
|
|
2118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
2119
|
+
"span",
|
|
2120
|
+
{
|
|
2121
|
+
className: "px-3 py-2 text-gray-700 dark:text-gray-300",
|
|
2122
|
+
children: "..."
|
|
2123
|
+
},
|
|
2124
|
+
`dots-${index}`
|
|
2125
|
+
);
|
|
2126
|
+
}
|
|
2127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
2128
|
+
"button",
|
|
2129
|
+
{
|
|
2130
|
+
onClick: () => onPageChange(page),
|
|
2131
|
+
className: `px-3 py-2 rounded-md text-sm font-medium transition-colors ${currentPage === page ? "bg-blue-600 text-white" : "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800"}`,
|
|
2132
|
+
"aria-label": `Page ${page}`,
|
|
2133
|
+
"aria-current": currentPage === page ? "page" : void 0,
|
|
2134
|
+
children: page
|
|
2135
|
+
},
|
|
2136
|
+
page
|
|
2137
|
+
);
|
|
2138
|
+
}),
|
|
2139
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
2140
|
+
"button",
|
|
2141
|
+
{
|
|
2142
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
2143
|
+
disabled: currentPage === totalPages,
|
|
2144
|
+
className: "px-3 py-2 rounded-md text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
|
|
2145
|
+
"aria-label": "Next page",
|
|
2146
|
+
children: "Next"
|
|
2147
|
+
}
|
|
2148
|
+
)
|
|
2149
|
+
] });
|
|
2150
|
+
};
|
|
2151
|
+
|
|
2152
|
+
// src/components/DatePicker.tsx
|
|
2153
|
+
var import_react13 = require("react");
|
|
2154
|
+
var import_react_dom2 = require("react-dom");
|
|
2155
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
2156
|
+
var DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2157
|
+
var MONTHS = [
|
|
2158
|
+
"January",
|
|
2159
|
+
"February",
|
|
2160
|
+
"March",
|
|
2161
|
+
"April",
|
|
2162
|
+
"May",
|
|
2163
|
+
"June",
|
|
2164
|
+
"July",
|
|
2165
|
+
"August",
|
|
2166
|
+
"September",
|
|
2167
|
+
"October",
|
|
2168
|
+
"November",
|
|
2169
|
+
"December"
|
|
2170
|
+
];
|
|
2171
|
+
var DatePicker = ({
|
|
2172
|
+
label,
|
|
2173
|
+
error,
|
|
2174
|
+
helperText,
|
|
2175
|
+
value,
|
|
2176
|
+
onChange,
|
|
2177
|
+
minDate,
|
|
2178
|
+
maxDate,
|
|
2179
|
+
disabled,
|
|
2180
|
+
className = "",
|
|
2181
|
+
placeholder = "Select date..."
|
|
2182
|
+
}) => {
|
|
2183
|
+
const { theme } = useTheme();
|
|
2184
|
+
const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
|
|
2185
|
+
const [viewDate, setViewDate] = (0, import_react13.useState)(value || /* @__PURE__ */ new Date());
|
|
2186
|
+
const [mounted, setMounted] = (0, import_react13.useState)(false);
|
|
2187
|
+
const [calendarPosition, setCalendarPosition] = (0, import_react13.useState)(null);
|
|
2188
|
+
const inputRef = (0, import_react13.useRef)(null);
|
|
2189
|
+
const calendarRef = (0, import_react13.useRef)(null);
|
|
2190
|
+
(0, import_react13.useEffect)(() => {
|
|
2191
|
+
setMounted(true);
|
|
2192
|
+
}, []);
|
|
2193
|
+
(0, import_react13.useEffect)(() => {
|
|
2194
|
+
const handleClickOutside = (event) => {
|
|
2195
|
+
if (calendarRef.current && !calendarRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
|
|
2196
|
+
setIsOpen(false);
|
|
2197
|
+
}
|
|
2198
|
+
};
|
|
2199
|
+
if (isOpen) {
|
|
2200
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2201
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2202
|
+
}
|
|
2203
|
+
}, [isOpen]);
|
|
2204
|
+
(0, import_react13.useEffect)(() => {
|
|
2205
|
+
if (isOpen && inputRef.current) {
|
|
2206
|
+
const rect = inputRef.current.getBoundingClientRect();
|
|
2207
|
+
setCalendarPosition({
|
|
2208
|
+
top: rect.bottom + 8,
|
|
2209
|
+
left: rect.left
|
|
2210
|
+
});
|
|
2211
|
+
} else {
|
|
2212
|
+
setCalendarPosition(null);
|
|
2213
|
+
}
|
|
2214
|
+
}, [isOpen]);
|
|
2215
|
+
const year = viewDate.getFullYear();
|
|
2216
|
+
const month = viewDate.getMonth();
|
|
2217
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
2218
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
2219
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
2220
|
+
const calendarDays = [];
|
|
2221
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
2222
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
2223
|
+
}
|
|
2224
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
2225
|
+
calendarDays.push(new Date(year, month, i));
|
|
2226
|
+
}
|
|
2227
|
+
const remainingDays = 42 - calendarDays.length;
|
|
2228
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
2229
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
2230
|
+
}
|
|
2231
|
+
const isSameDay = (date1, date2) => {
|
|
2232
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
2233
|
+
};
|
|
2234
|
+
const isToday = (date) => {
|
|
2235
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
2236
|
+
};
|
|
2237
|
+
const isSelected = (date) => {
|
|
2238
|
+
return value && isSameDay(date, value);
|
|
2239
|
+
};
|
|
2240
|
+
const isCurrentMonth = (date) => {
|
|
2241
|
+
return date.getMonth() === month;
|
|
2242
|
+
};
|
|
2243
|
+
const isDisabled = (date) => {
|
|
2244
|
+
if (minDate && date < minDate) return true;
|
|
2245
|
+
if (maxDate && date > maxDate) return true;
|
|
2246
|
+
return false;
|
|
2247
|
+
};
|
|
2248
|
+
const handleDateClick = (date) => {
|
|
2249
|
+
if (isDisabled(date)) return;
|
|
2250
|
+
onChange?.(date);
|
|
2251
|
+
setIsOpen(false);
|
|
2252
|
+
};
|
|
2253
|
+
const handlePrevMonth = () => {
|
|
2254
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
2255
|
+
};
|
|
2256
|
+
const handleNextMonth = () => {
|
|
2257
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
2258
|
+
};
|
|
2259
|
+
const handleToday = () => {
|
|
2260
|
+
const today = /* @__PURE__ */ new Date();
|
|
2261
|
+
setViewDate(today);
|
|
2262
|
+
onChange?.(today);
|
|
2263
|
+
setIsOpen(false);
|
|
2264
|
+
};
|
|
2265
|
+
const formatDate = (date) => {
|
|
2266
|
+
if (!date) return "";
|
|
2267
|
+
return date.toLocaleDateString("en-US", {
|
|
2268
|
+
month: "short",
|
|
2269
|
+
day: "numeric",
|
|
2270
|
+
year: "numeric"
|
|
2271
|
+
});
|
|
2272
|
+
};
|
|
2273
|
+
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";
|
|
2274
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
2275
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
2276
|
+
const calendar = isOpen && mounted && calendarPosition ? /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
|
|
2277
|
+
"div",
|
|
2278
|
+
{
|
|
2279
|
+
ref: calendarRef,
|
|
2280
|
+
className: "fixed z-[9999] bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-xl p-4",
|
|
2281
|
+
style: {
|
|
2282
|
+
top: `${calendarPosition.top}px`,
|
|
2283
|
+
left: `${calendarPosition.left}px`,
|
|
2284
|
+
minWidth: "320px"
|
|
2285
|
+
},
|
|
2286
|
+
children: [
|
|
2287
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2288
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
2289
|
+
"button",
|
|
2290
|
+
{
|
|
2291
|
+
onClick: handlePrevMonth,
|
|
2292
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2293
|
+
"aria-label": "Previous month",
|
|
2294
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime88.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_runtime88.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
2295
|
+
}
|
|
2296
|
+
),
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2298
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("h2", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
2299
|
+
MONTHS[month],
|
|
2300
|
+
" ",
|
|
2301
|
+
year
|
|
2302
|
+
] }),
|
|
2303
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
2304
|
+
"button",
|
|
2305
|
+
{
|
|
2306
|
+
onClick: handleToday,
|
|
2307
|
+
className: "px-2 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
2308
|
+
children: "Today"
|
|
2309
|
+
}
|
|
2310
|
+
)
|
|
2311
|
+
] }),
|
|
2312
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
2313
|
+
"button",
|
|
2314
|
+
{
|
|
2315
|
+
onClick: handleNextMonth,
|
|
2316
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2317
|
+
"aria-label": "Next month",
|
|
2318
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime88.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_runtime88.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
2319
|
+
}
|
|
2320
|
+
)
|
|
2321
|
+
] }),
|
|
2322
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", { className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-1", children: day }, day)) }),
|
|
2323
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
|
|
2324
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
2325
|
+
const isTodayDay = isToday(date);
|
|
2326
|
+
const isSelectedDay = isSelected(date);
|
|
2327
|
+
const isDisabledDay = isDisabled(date);
|
|
2328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
2329
|
+
"button",
|
|
2330
|
+
{
|
|
2331
|
+
onClick: () => handleDateClick(date),
|
|
2332
|
+
disabled: isDisabledDay,
|
|
2333
|
+
className: `
|
|
2334
|
+
aspect-square p-1 rounded-lg text-sm font-medium transition-all
|
|
2335
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
2336
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
2337
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
2338
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
2339
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
2340
|
+
`,
|
|
2341
|
+
children: date.getDate()
|
|
2342
|
+
},
|
|
2343
|
+
index
|
|
2344
|
+
);
|
|
2345
|
+
}) })
|
|
2346
|
+
]
|
|
2347
|
+
}
|
|
2348
|
+
) : null;
|
|
2349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className, children: [
|
|
2350
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
2351
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
|
|
2352
|
+
"div",
|
|
2353
|
+
{
|
|
2354
|
+
ref: inputRef,
|
|
2355
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
2356
|
+
className: `${baseStyles} ${errorStyles} ${disabledStyles} flex items-center justify-between`.trim(),
|
|
2357
|
+
children: [
|
|
2358
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { className: !value ? "text-gray-500 dark:text-gray-400" : "", children: value ? formatDate(value) : placeholder }),
|
|
2359
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("svg", { className: "w-5 h-5 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime88.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" }) })
|
|
2360
|
+
]
|
|
2361
|
+
}
|
|
2362
|
+
),
|
|
2363
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
2364
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
2365
|
+
mounted && (0, import_react_dom2.createPortal)(calendar, document.body)
|
|
2366
|
+
] });
|
|
2367
|
+
};
|
|
2368
|
+
DatePicker.displayName = "DatePicker";
|
|
2369
|
+
|
|
2370
|
+
// src/components/TimePicker.tsx
|
|
2371
|
+
var import_react14 = require("react");
|
|
2372
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
2373
|
+
var TimePicker = (0, import_react14.forwardRef)(
|
|
2374
|
+
({ label, error, helperText, className = "", disabled, ...props }, ref) => {
|
|
2375
|
+
const { theme } = useTheme();
|
|
2376
|
+
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";
|
|
2377
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
2378
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
2379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className, children: [
|
|
2380
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
2381
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
2382
|
+
"input",
|
|
2383
|
+
{
|
|
2384
|
+
ref,
|
|
2385
|
+
type: "time",
|
|
2386
|
+
disabled,
|
|
2387
|
+
className: `${baseStyles} ${errorStyles} ${disabledStyles}`.trim(),
|
|
2388
|
+
...props
|
|
2389
|
+
}
|
|
2390
|
+
),
|
|
2391
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
2392
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
2393
|
+
] });
|
|
2394
|
+
}
|
|
2395
|
+
);
|
|
2396
|
+
TimePicker.displayName = "TimePicker";
|
|
2397
|
+
|
|
2398
|
+
// src/components/DateTimePicker.tsx
|
|
2399
|
+
var import_react15 = require("react");
|
|
2400
|
+
var import_react_dom3 = require("react-dom");
|
|
2401
|
+
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
2402
|
+
var DAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2403
|
+
var MONTHS2 = [
|
|
2404
|
+
"January",
|
|
2405
|
+
"February",
|
|
2406
|
+
"March",
|
|
2407
|
+
"April",
|
|
2408
|
+
"May",
|
|
2409
|
+
"June",
|
|
2410
|
+
"July",
|
|
2411
|
+
"August",
|
|
2412
|
+
"September",
|
|
2413
|
+
"October",
|
|
2414
|
+
"November",
|
|
2415
|
+
"December"
|
|
2416
|
+
];
|
|
2417
|
+
var DateTimePicker = ({
|
|
2418
|
+
label,
|
|
2419
|
+
error,
|
|
2420
|
+
helperText,
|
|
2421
|
+
value,
|
|
2422
|
+
onChange,
|
|
2423
|
+
minDate,
|
|
2424
|
+
maxDate,
|
|
2425
|
+
disabled,
|
|
2426
|
+
className = "",
|
|
2427
|
+
placeholder = "Select date and time..."
|
|
2428
|
+
}) => {
|
|
2429
|
+
const { theme } = useTheme();
|
|
2430
|
+
const [isOpen, setIsOpen] = (0, import_react15.useState)(false);
|
|
2431
|
+
const [viewDate, setViewDate] = (0, import_react15.useState)(value || /* @__PURE__ */ new Date());
|
|
2432
|
+
const [selectedTime, setSelectedTime] = (0, import_react15.useState)(
|
|
2433
|
+
value ? { hours: value.getHours(), minutes: value.getMinutes() } : { hours: 12, minutes: 0 }
|
|
2434
|
+
);
|
|
2435
|
+
const [mounted, setMounted] = (0, import_react15.useState)(false);
|
|
2436
|
+
const [pickerPosition, setPickerPosition] = (0, import_react15.useState)(null);
|
|
2437
|
+
const inputRef = (0, import_react15.useRef)(null);
|
|
2438
|
+
const pickerRef = (0, import_react15.useRef)(null);
|
|
2439
|
+
(0, import_react15.useEffect)(() => {
|
|
2440
|
+
setMounted(true);
|
|
2441
|
+
}, []);
|
|
2442
|
+
(0, import_react15.useEffect)(() => {
|
|
2443
|
+
const handleClickOutside = (event) => {
|
|
2444
|
+
if (pickerRef.current && !pickerRef.current.contains(event.target) && inputRef.current && !inputRef.current.contains(event.target)) {
|
|
2445
|
+
setIsOpen(false);
|
|
2446
|
+
}
|
|
2447
|
+
};
|
|
2448
|
+
if (isOpen) {
|
|
2449
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2450
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2451
|
+
}
|
|
2452
|
+
}, [isOpen]);
|
|
2453
|
+
(0, import_react15.useEffect)(() => {
|
|
2454
|
+
if (isOpen && inputRef.current) {
|
|
2455
|
+
const rect = inputRef.current.getBoundingClientRect();
|
|
2456
|
+
setPickerPosition({
|
|
2457
|
+
top: rect.bottom + 8,
|
|
2458
|
+
left: rect.left
|
|
2459
|
+
});
|
|
2460
|
+
} else {
|
|
2461
|
+
setPickerPosition(null);
|
|
2462
|
+
}
|
|
2463
|
+
}, [isOpen]);
|
|
2464
|
+
const year = viewDate.getFullYear();
|
|
2465
|
+
const month = viewDate.getMonth();
|
|
2466
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
2467
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
2468
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
2469
|
+
const calendarDays = [];
|
|
2470
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
2471
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
2472
|
+
}
|
|
2473
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
2474
|
+
calendarDays.push(new Date(year, month, i));
|
|
2475
|
+
}
|
|
2476
|
+
const remainingDays = 42 - calendarDays.length;
|
|
2477
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
2478
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
2479
|
+
}
|
|
2480
|
+
const isSameDay = (date1, date2) => {
|
|
2481
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
2482
|
+
};
|
|
2483
|
+
const isToday = (date) => {
|
|
2484
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
2485
|
+
};
|
|
2486
|
+
const isSelected = (date) => {
|
|
2487
|
+
return value && isSameDay(date, value);
|
|
2488
|
+
};
|
|
2489
|
+
const isCurrentMonth = (date) => {
|
|
2490
|
+
return date.getMonth() === month;
|
|
2491
|
+
};
|
|
2492
|
+
const isDisabled = (date) => {
|
|
2493
|
+
if (minDate && date < minDate) return true;
|
|
2494
|
+
if (maxDate && date > maxDate) return true;
|
|
2495
|
+
return false;
|
|
2496
|
+
};
|
|
2497
|
+
const handleDateClick = (date) => {
|
|
2498
|
+
if (isDisabled(date)) return;
|
|
2499
|
+
const newDateTime = new Date(
|
|
2500
|
+
date.getFullYear(),
|
|
2501
|
+
date.getMonth(),
|
|
2502
|
+
date.getDate(),
|
|
2503
|
+
selectedTime.hours,
|
|
2504
|
+
selectedTime.minutes
|
|
2505
|
+
);
|
|
2506
|
+
onChange?.(newDateTime);
|
|
2507
|
+
};
|
|
2508
|
+
const handleTimeChange = (hours, minutes) => {
|
|
2509
|
+
setSelectedTime({ hours, minutes });
|
|
2510
|
+
if (value) {
|
|
2511
|
+
const newDateTime = new Date(
|
|
2512
|
+
value.getFullYear(),
|
|
2513
|
+
value.getMonth(),
|
|
2514
|
+
value.getDate(),
|
|
2515
|
+
hours,
|
|
2516
|
+
minutes
|
|
2517
|
+
);
|
|
2518
|
+
onChange?.(newDateTime);
|
|
2519
|
+
}
|
|
2520
|
+
};
|
|
2521
|
+
const handleDone = () => {
|
|
2522
|
+
if (value) {
|
|
2523
|
+
setIsOpen(false);
|
|
2524
|
+
}
|
|
2525
|
+
};
|
|
2526
|
+
const handlePrevMonth = () => {
|
|
2527
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
2528
|
+
};
|
|
2529
|
+
const handleNextMonth = () => {
|
|
2530
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
2531
|
+
};
|
|
2532
|
+
const handleToday = () => {
|
|
2533
|
+
const now = /* @__PURE__ */ new Date();
|
|
2534
|
+
setViewDate(now);
|
|
2535
|
+
setSelectedTime({ hours: now.getHours(), minutes: now.getMinutes() });
|
|
2536
|
+
onChange?.(now);
|
|
2537
|
+
};
|
|
2538
|
+
const formatDateTime = (date) => {
|
|
2539
|
+
if (!date) return "";
|
|
2540
|
+
return date.toLocaleString("en-US", {
|
|
2541
|
+
month: "short",
|
|
2542
|
+
day: "numeric",
|
|
2543
|
+
year: "numeric",
|
|
2544
|
+
hour: "numeric",
|
|
2545
|
+
minute: "2-digit",
|
|
2546
|
+
hour12: true
|
|
2547
|
+
});
|
|
2548
|
+
};
|
|
2549
|
+
const formatTime = (hours, minutes) => {
|
|
2550
|
+
const period = hours >= 12 ? "PM" : "AM";
|
|
2551
|
+
const displayHours = hours % 12 || 12;
|
|
2552
|
+
const displayMinutes = minutes.toString().padStart(2, "0");
|
|
2553
|
+
return `${displayHours}:${displayMinutes} ${period}`;
|
|
2554
|
+
};
|
|
2555
|
+
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";
|
|
2556
|
+
const errorStyles = error ? "border-red-500 focus:ring-red-500 dark:border-red-500" : "";
|
|
2557
|
+
const disabledStyles = disabled ? "opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-900" : "";
|
|
2558
|
+
const picker = isOpen && mounted && pickerPosition ? /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
|
|
2559
|
+
"div",
|
|
2560
|
+
{
|
|
2561
|
+
ref: pickerRef,
|
|
2562
|
+
className: "fixed z-[9999] bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-xl p-4",
|
|
2563
|
+
style: {
|
|
2564
|
+
top: `${pickerPosition.top}px`,
|
|
2565
|
+
left: `${pickerPosition.left}px`,
|
|
2566
|
+
minWidth: "360px"
|
|
2567
|
+
},
|
|
2568
|
+
children: [
|
|
2569
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2570
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2571
|
+
"button",
|
|
2572
|
+
{
|
|
2573
|
+
onClick: handlePrevMonth,
|
|
2574
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2575
|
+
"aria-label": "Previous month",
|
|
2576
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime90.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_runtime90.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
2577
|
+
}
|
|
2578
|
+
),
|
|
2579
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2580
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("h2", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
2581
|
+
MONTHS2[month],
|
|
2582
|
+
" ",
|
|
2583
|
+
year
|
|
2584
|
+
] }),
|
|
2585
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2586
|
+
"button",
|
|
2587
|
+
{
|
|
2588
|
+
onClick: handleToday,
|
|
2589
|
+
className: "px-2 py-1 text-xs bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
2590
|
+
children: "Now"
|
|
2591
|
+
}
|
|
2592
|
+
)
|
|
2593
|
+
] }),
|
|
2594
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2595
|
+
"button",
|
|
2596
|
+
{
|
|
2597
|
+
onClick: handleNextMonth,
|
|
2598
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2599
|
+
"aria-label": "Next month",
|
|
2600
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime90.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_runtime90.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
2601
|
+
}
|
|
2602
|
+
)
|
|
2603
|
+
] }),
|
|
2604
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS2.map((day) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-1", children: day }, day)) }),
|
|
2605
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-4", children: calendarDays.map((date, index) => {
|
|
2606
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
2607
|
+
const isTodayDay = isToday(date);
|
|
2608
|
+
const isSelectedDay = isSelected(date);
|
|
2609
|
+
const isDisabledDay = isDisabled(date);
|
|
2610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2611
|
+
"button",
|
|
2612
|
+
{
|
|
2613
|
+
onClick: () => handleDateClick(date),
|
|
2614
|
+
disabled: isDisabledDay,
|
|
2615
|
+
className: `
|
|
2616
|
+
aspect-square p-1 rounded-lg text-sm font-medium transition-all
|
|
2617
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
2618
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
2619
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
2620
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
2621
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
2622
|
+
`,
|
|
2623
|
+
children: date.getDate()
|
|
2624
|
+
},
|
|
2625
|
+
index
|
|
2626
|
+
);
|
|
2627
|
+
}) }),
|
|
2628
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-4", children: [
|
|
2629
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "flex items-center justify-center gap-4 mb-4", children: [
|
|
2630
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
2631
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("label", { className: "text-xs font-semibold text-gray-600 dark:text-gray-400 mb-2", children: "Hour" }),
|
|
2632
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2633
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2634
|
+
"button",
|
|
2635
|
+
{
|
|
2636
|
+
type: "button",
|
|
2637
|
+
onClick: () => handleTimeChange((selectedTime.hours + 1) % 24, selectedTime.minutes),
|
|
2638
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2639
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime90.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_runtime90.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) })
|
|
2640
|
+
}
|
|
2641
|
+
),
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2643
|
+
"input",
|
|
2644
|
+
{
|
|
2645
|
+
type: "number",
|
|
2646
|
+
min: "0",
|
|
2647
|
+
max: "23",
|
|
2648
|
+
value: selectedTime.hours,
|
|
2649
|
+
onChange: (e) => {
|
|
2650
|
+
const val = parseInt(e.target.value);
|
|
2651
|
+
if (!isNaN(val) && val >= 0 && val <= 23) {
|
|
2652
|
+
handleTimeChange(val, selectedTime.minutes);
|
|
2653
|
+
}
|
|
2654
|
+
},
|
|
2655
|
+
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"
|
|
2656
|
+
}
|
|
2657
|
+
),
|
|
2658
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2659
|
+
"button",
|
|
2660
|
+
{
|
|
2661
|
+
type: "button",
|
|
2662
|
+
onClick: () => handleTimeChange((selectedTime.hours - 1 + 24) % 24, selectedTime.minutes),
|
|
2663
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2664
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime90.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_runtime90.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
2665
|
+
}
|
|
2666
|
+
)
|
|
2667
|
+
] })
|
|
2668
|
+
] }),
|
|
2669
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: "text-2xl font-bold text-gray-600 dark:text-gray-400 mt-8", children: ":" }),
|
|
2670
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
2671
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("label", { className: "text-xs font-semibold text-gray-600 dark:text-gray-400 mb-2", children: "Minute" }),
|
|
2672
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "flex flex-col items-center gap-1", children: [
|
|
2673
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2674
|
+
"button",
|
|
2675
|
+
{
|
|
2676
|
+
type: "button",
|
|
2677
|
+
onClick: () => handleTimeChange(selectedTime.hours, (selectedTime.minutes + 1) % 60),
|
|
2678
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2679
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime90.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_runtime90.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 15l7-7 7 7" }) })
|
|
2680
|
+
}
|
|
2681
|
+
),
|
|
2682
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2683
|
+
"input",
|
|
2684
|
+
{
|
|
2685
|
+
type: "number",
|
|
2686
|
+
min: "0",
|
|
2687
|
+
max: "59",
|
|
2688
|
+
value: selectedTime.minutes,
|
|
2689
|
+
onChange: (e) => {
|
|
2690
|
+
const val = parseInt(e.target.value);
|
|
2691
|
+
if (!isNaN(val) && val >= 0 && val <= 59) {
|
|
2692
|
+
handleTimeChange(selectedTime.hours, val);
|
|
2693
|
+
}
|
|
2694
|
+
},
|
|
2695
|
+
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"
|
|
2696
|
+
}
|
|
2697
|
+
),
|
|
2698
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2699
|
+
"button",
|
|
2700
|
+
{
|
|
2701
|
+
type: "button",
|
|
2702
|
+
onClick: () => handleTimeChange(selectedTime.hours, (selectedTime.minutes - 1 + 60) % 60),
|
|
2703
|
+
className: "p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded transition-colors",
|
|
2704
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime90.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_runtime90.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 9l-7 7-7-7" }) })
|
|
2705
|
+
}
|
|
2706
|
+
)
|
|
2707
|
+
] })
|
|
2708
|
+
] })
|
|
2709
|
+
] }),
|
|
2710
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { className: "text-center text-sm text-gray-600 dark:text-gray-400 mb-4", children: formatTime(selectedTime.hours, selectedTime.minutes) }),
|
|
2711
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
2712
|
+
"button",
|
|
2713
|
+
{
|
|
2714
|
+
onClick: handleDone,
|
|
2715
|
+
className: "w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium",
|
|
2716
|
+
children: "Done"
|
|
2717
|
+
}
|
|
2718
|
+
)
|
|
2719
|
+
] })
|
|
2720
|
+
]
|
|
2721
|
+
}
|
|
2722
|
+
) : null;
|
|
2723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className, children: [
|
|
2724
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
2725
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
|
|
2726
|
+
"div",
|
|
2727
|
+
{
|
|
2728
|
+
ref: inputRef,
|
|
2729
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
2730
|
+
className: `${baseStyles} ${errorStyles} ${disabledStyles} flex items-center justify-between`.trim(),
|
|
2731
|
+
children: [
|
|
2732
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { className: !value ? "text-gray-500 dark:text-gray-400" : "", children: value ? formatDateTime(value) : placeholder }),
|
|
2733
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("svg", { className: "w-5 h-5 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime90.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" }) })
|
|
2734
|
+
]
|
|
2735
|
+
}
|
|
2736
|
+
),
|
|
2737
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
2738
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
2739
|
+
mounted && (0, import_react_dom3.createPortal)(picker, document.body)
|
|
2740
|
+
] });
|
|
2741
|
+
};
|
|
2742
|
+
DateTimePicker.displayName = "DateTimePicker";
|
|
2743
|
+
|
|
2744
|
+
// src/components/Calendar.tsx
|
|
2745
|
+
var import_react16 = require("react");
|
|
2746
|
+
var import_jsx_runtime91 = require("react/jsx-runtime");
|
|
2747
|
+
var DAYS3 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2748
|
+
var MONTHS3 = [
|
|
2749
|
+
"January",
|
|
2750
|
+
"February",
|
|
2751
|
+
"March",
|
|
2752
|
+
"April",
|
|
2753
|
+
"May",
|
|
2754
|
+
"June",
|
|
2755
|
+
"July",
|
|
2756
|
+
"August",
|
|
2757
|
+
"September",
|
|
2758
|
+
"October",
|
|
2759
|
+
"November",
|
|
2760
|
+
"December"
|
|
2761
|
+
];
|
|
2762
|
+
var Calendar = ({
|
|
2763
|
+
value,
|
|
2764
|
+
onChange,
|
|
2765
|
+
minDate,
|
|
2766
|
+
maxDate,
|
|
2767
|
+
className = ""
|
|
2768
|
+
}) => {
|
|
2769
|
+
const { theme } = useTheme();
|
|
2770
|
+
const [currentDate, setCurrentDate] = (0, import_react16.useState)(value || /* @__PURE__ */ new Date());
|
|
2771
|
+
const [viewDate, setViewDate] = (0, import_react16.useState)(value || /* @__PURE__ */ new Date());
|
|
2772
|
+
const year = viewDate.getFullYear();
|
|
2773
|
+
const month = viewDate.getMonth();
|
|
2774
|
+
const firstDayOfMonth = new Date(year, month, 1).getDay();
|
|
2775
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
2776
|
+
const daysInPrevMonth = new Date(year, month, 0).getDate();
|
|
2777
|
+
const calendarDays = [];
|
|
2778
|
+
for (let i = firstDayOfMonth - 1; i >= 0; i--) {
|
|
2779
|
+
calendarDays.push(new Date(year, month - 1, daysInPrevMonth - i));
|
|
2780
|
+
}
|
|
2781
|
+
for (let i = 1; i <= daysInMonth; i++) {
|
|
2782
|
+
calendarDays.push(new Date(year, month, i));
|
|
2783
|
+
}
|
|
2784
|
+
const remainingDays = 42 - calendarDays.length;
|
|
2785
|
+
for (let i = 1; i <= remainingDays; i++) {
|
|
2786
|
+
calendarDays.push(new Date(year, month + 1, i));
|
|
2787
|
+
}
|
|
2788
|
+
const isSameDay = (date1, date2) => {
|
|
2789
|
+
return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
|
|
2790
|
+
};
|
|
2791
|
+
const isToday = (date) => {
|
|
2792
|
+
return isSameDay(date, /* @__PURE__ */ new Date());
|
|
2793
|
+
};
|
|
2794
|
+
const isSelected = (date) => {
|
|
2795
|
+
return value && isSameDay(date, value);
|
|
2796
|
+
};
|
|
2797
|
+
const isCurrentMonth = (date) => {
|
|
2798
|
+
return date.getMonth() === month;
|
|
2799
|
+
};
|
|
2800
|
+
const isDisabled = (date) => {
|
|
2801
|
+
if (minDate && date < minDate) return true;
|
|
2802
|
+
if (maxDate && date > maxDate) return true;
|
|
2803
|
+
return false;
|
|
2804
|
+
};
|
|
2805
|
+
const handleDateClick = (date) => {
|
|
2806
|
+
if (isDisabled(date)) return;
|
|
2807
|
+
setCurrentDate(date);
|
|
2808
|
+
onChange?.(date);
|
|
2809
|
+
};
|
|
2810
|
+
const handlePrevMonth = () => {
|
|
2811
|
+
setViewDate(new Date(year, month - 1, 1));
|
|
2812
|
+
};
|
|
2813
|
+
const handleNextMonth = () => {
|
|
2814
|
+
setViewDate(new Date(year, month + 1, 1));
|
|
2815
|
+
};
|
|
2816
|
+
const handleToday = () => {
|
|
2817
|
+
const today = /* @__PURE__ */ new Date();
|
|
2818
|
+
setViewDate(today);
|
|
2819
|
+
setCurrentDate(today);
|
|
2820
|
+
onChange?.(today);
|
|
2821
|
+
};
|
|
2822
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: `bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4 ${className}`, children: [
|
|
2823
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2824
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2825
|
+
"button",
|
|
2826
|
+
{
|
|
2827
|
+
onClick: handlePrevMonth,
|
|
2828
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2829
|
+
"aria-label": "Previous month",
|
|
2830
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime91.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_runtime91.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) })
|
|
2831
|
+
}
|
|
2832
|
+
),
|
|
2833
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
2834
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("h2", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: [
|
|
2835
|
+
MONTHS3[month],
|
|
2836
|
+
" ",
|
|
2837
|
+
year
|
|
2838
|
+
] }),
|
|
2839
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2840
|
+
"button",
|
|
2841
|
+
{
|
|
2842
|
+
onClick: handleToday,
|
|
2843
|
+
className: "px-3 py-1 text-sm bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors",
|
|
2844
|
+
children: "Today"
|
|
2845
|
+
}
|
|
2846
|
+
)
|
|
2847
|
+
] }),
|
|
2848
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2849
|
+
"button",
|
|
2850
|
+
{
|
|
2851
|
+
onClick: handleNextMonth,
|
|
2852
|
+
className: "p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors",
|
|
2853
|
+
"aria-label": "Next month",
|
|
2854
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime91.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_runtime91.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" }) })
|
|
2855
|
+
}
|
|
2856
|
+
)
|
|
2857
|
+
] }),
|
|
2858
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "grid grid-cols-7 gap-1 mb-2", children: DAYS3.map((day) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2859
|
+
"div",
|
|
2860
|
+
{
|
|
2861
|
+
className: "text-center text-xs font-semibold text-gray-600 dark:text-gray-400 py-2",
|
|
2862
|
+
children: day
|
|
2863
|
+
},
|
|
2864
|
+
day
|
|
2865
|
+
)) }),
|
|
2866
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "grid grid-cols-7 gap-1", children: calendarDays.map((date, index) => {
|
|
2867
|
+
if (!date) return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", {}, index);
|
|
2868
|
+
const isCurrentMonthDay = isCurrentMonth(date);
|
|
2869
|
+
const isTodayDay = isToday(date);
|
|
2870
|
+
const isSelectedDay = isSelected(date);
|
|
2871
|
+
const isDisabledDay = isDisabled(date);
|
|
2872
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
2873
|
+
"button",
|
|
2874
|
+
{
|
|
2875
|
+
onClick: () => handleDateClick(date),
|
|
2876
|
+
disabled: isDisabledDay,
|
|
2877
|
+
className: `
|
|
2878
|
+
aspect-square p-2 rounded-lg text-sm font-medium transition-all
|
|
2879
|
+
${!isCurrentMonthDay ? "text-gray-400 dark:text-gray-600" : "text-gray-900 dark:text-gray-100"}
|
|
2880
|
+
${isTodayDay && !isSelectedDay ? "bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-bold" : ""}
|
|
2881
|
+
${isSelectedDay ? "bg-blue-600 text-white hover:bg-blue-700" : ""}
|
|
2882
|
+
${!isSelectedDay && !isDisabledDay ? "hover:bg-gray-100 dark:hover:bg-gray-700" : ""}
|
|
2883
|
+
${isDisabledDay ? "opacity-30 cursor-not-allowed" : "cursor-pointer"}
|
|
2884
|
+
`,
|
|
2885
|
+
children: date.getDate()
|
|
2886
|
+
},
|
|
2887
|
+
index
|
|
2888
|
+
);
|
|
2889
|
+
}) })
|
|
2890
|
+
] });
|
|
2891
|
+
};
|
|
2892
|
+
|
|
2893
|
+
// src/components/Radio.tsx
|
|
2894
|
+
var import_react17 = __toESM(require("react"));
|
|
2895
|
+
var import_jsx_runtime92 = require("react/jsx-runtime");
|
|
2896
|
+
var Radio = ({
|
|
2897
|
+
name,
|
|
2898
|
+
options,
|
|
2899
|
+
value: controlledValue,
|
|
2900
|
+
defaultValue,
|
|
2901
|
+
onChange,
|
|
2902
|
+
disabled = false,
|
|
2903
|
+
orientation = "vertical",
|
|
2904
|
+
className = ""
|
|
2905
|
+
}) => {
|
|
2906
|
+
const [internalValue, setInternalValue] = import_react17.default.useState(defaultValue || "");
|
|
2907
|
+
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
2908
|
+
const handleChange = (optionValue) => {
|
|
2909
|
+
if (disabled) return;
|
|
2910
|
+
setInternalValue(optionValue);
|
|
2911
|
+
onChange?.(optionValue);
|
|
2912
|
+
};
|
|
2913
|
+
const containerClass = orientation === "horizontal" ? "flex flex-wrap gap-4" : "flex flex-col gap-2";
|
|
2914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: `${containerClass} ${className}`, role: "radiogroup", children: options.map((option) => {
|
|
2915
|
+
const isDisabled = disabled || option.disabled;
|
|
2916
|
+
const isChecked = value === option.value;
|
|
2917
|
+
const id = `${name}-${option.value}`;
|
|
2918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(
|
|
2919
|
+
"label",
|
|
2920
|
+
{
|
|
2921
|
+
htmlFor: id,
|
|
2922
|
+
className: `flex items-center gap-2 cursor-pointer group ${isDisabled ? "opacity-50 cursor-not-allowed" : ""}`,
|
|
2923
|
+
children: [
|
|
2924
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "relative inline-flex items-center", children: [
|
|
2925
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
2926
|
+
"input",
|
|
2927
|
+
{
|
|
2928
|
+
type: "radio",
|
|
2929
|
+
id,
|
|
2930
|
+
name,
|
|
2931
|
+
value: option.value,
|
|
2932
|
+
checked: isChecked,
|
|
2933
|
+
onChange: () => handleChange(option.value),
|
|
2934
|
+
disabled: isDisabled,
|
|
2935
|
+
className: "sr-only peer"
|
|
2936
|
+
}
|
|
2937
|
+
),
|
|
2938
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: `w-4 h-4 rounded-full border-2 transition-all duration-200 flex items-center justify-center
|
|
2939
|
+
border-gray-300 dark:border-gray-600
|
|
2940
|
+
${isDisabled ? "bg-gray-100 dark:bg-gray-800" : "peer-hover:border-gray-400 dark:peer-hover:border-gray-500"}
|
|
2941
|
+
${isChecked ? "border-blue-600 bg-white dark:bg-gray-900" : ""}
|
|
2942
|
+
peer-focus:ring-2 peer-focus:ring-blue-500 peer-focus:ring-offset-2
|
|
2943
|
+
`, children: /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: `w-2 h-2 rounded-full bg-blue-600 transition-all duration-200 ${isChecked ? "scale-100" : "scale-0"}` }) })
|
|
2944
|
+
] }),
|
|
2945
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: `text-sm font-medium text-gray-900 dark:text-gray-300 ${!isDisabled && "group-hover:text-gray-700 dark:group-hover:text-gray-100"}`, children: option.label })
|
|
2946
|
+
]
|
|
2947
|
+
},
|
|
2948
|
+
option.value
|
|
2949
|
+
);
|
|
2950
|
+
}) });
|
|
2951
|
+
};
|
|
2952
|
+
|
|
2953
|
+
// src/components/ProgressBar.tsx
|
|
2954
|
+
var import_jsx_runtime93 = require("react/jsx-runtime");
|
|
2955
|
+
var ProgressBar = ({
|
|
2956
|
+
value,
|
|
2957
|
+
max = 100,
|
|
2958
|
+
size = "md",
|
|
2959
|
+
variant = "default",
|
|
2960
|
+
showLabel = false,
|
|
2961
|
+
label,
|
|
2962
|
+
className = ""
|
|
2963
|
+
}) => {
|
|
2964
|
+
const percentage = Math.min(Math.max(value / max * 100, 0), 100);
|
|
2965
|
+
const sizeClasses7 = {
|
|
2966
|
+
sm: "h-1",
|
|
2967
|
+
md: "h-2",
|
|
2968
|
+
lg: "h-3"
|
|
2969
|
+
};
|
|
2970
|
+
const variantClasses = {
|
|
2971
|
+
default: "bg-blue-600 dark:bg-blue-500",
|
|
2972
|
+
success: "bg-green-600 dark:bg-green-500",
|
|
2973
|
+
warning: "bg-yellow-500 dark:bg-yellow-400",
|
|
2974
|
+
danger: "bg-red-600 dark:bg-red-500"
|
|
2975
|
+
};
|
|
2976
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
2977
|
+
(showLabel || label) && /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "flex justify-between items-center mb-1", children: [
|
|
2978
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label }),
|
|
2979
|
+
showLabel && /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
|
|
2980
|
+
Math.round(percentage),
|
|
2981
|
+
"%"
|
|
2982
|
+
] })
|
|
2983
|
+
] }),
|
|
2984
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
2985
|
+
"div",
|
|
2986
|
+
{
|
|
2987
|
+
className: `w-full bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden ${sizeClasses7[size]}`,
|
|
2988
|
+
role: "progressbar",
|
|
2989
|
+
"aria-valuenow": value,
|
|
2990
|
+
"aria-valuemin": 0,
|
|
2991
|
+
"aria-valuemax": max,
|
|
2992
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
2993
|
+
"div",
|
|
2994
|
+
{
|
|
2995
|
+
className: `${sizeClasses7[size]} ${variantClasses[variant]} rounded-full transition-all duration-300 ease-out`,
|
|
2996
|
+
style: { width: `${percentage}%` }
|
|
2997
|
+
}
|
|
2998
|
+
)
|
|
2999
|
+
}
|
|
3000
|
+
)
|
|
3001
|
+
] });
|
|
3002
|
+
};
|
|
3003
|
+
|
|
3004
|
+
// src/components/Slider.tsx
|
|
3005
|
+
var import_react18 = __toESM(require("react"));
|
|
3006
|
+
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
3007
|
+
var Slider = ({
|
|
3008
|
+
value: controlledValue,
|
|
3009
|
+
defaultValue = 50,
|
|
3010
|
+
min = 0,
|
|
3011
|
+
max = 100,
|
|
3012
|
+
step = 1,
|
|
3013
|
+
onChange,
|
|
3014
|
+
disabled = false,
|
|
3015
|
+
showValue = false,
|
|
3016
|
+
label,
|
|
3017
|
+
className = "",
|
|
3018
|
+
range = false,
|
|
3019
|
+
rangeValue: controlledRangeValue,
|
|
3020
|
+
defaultRangeValue = [25, 75],
|
|
3021
|
+
onRangeChange
|
|
3022
|
+
}) => {
|
|
3023
|
+
const [internalValue, setInternalValue] = import_react18.default.useState(defaultValue);
|
|
3024
|
+
const [internalRangeValue, setInternalRangeValue] = import_react18.default.useState(defaultRangeValue);
|
|
3025
|
+
const trackRef = (0, import_react18.useRef)(null);
|
|
3026
|
+
const [isDragging, setIsDragging] = import_react18.default.useState(null);
|
|
3027
|
+
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
3028
|
+
const rangeValue = controlledRangeValue !== void 0 ? controlledRangeValue : internalRangeValue;
|
|
3029
|
+
const handleChange = (e) => {
|
|
3030
|
+
const newValue = Number(e.target.value);
|
|
3031
|
+
setInternalValue(newValue);
|
|
3032
|
+
onChange?.(newValue);
|
|
3033
|
+
};
|
|
3034
|
+
const handleRangeMouseDown = (e, handle) => {
|
|
3035
|
+
if (disabled) return;
|
|
3036
|
+
e.preventDefault();
|
|
3037
|
+
setIsDragging(handle);
|
|
3038
|
+
};
|
|
3039
|
+
const handleRangeMouseMove = (e) => {
|
|
3040
|
+
if (!isDragging || !trackRef.current || disabled) return;
|
|
3041
|
+
const rect = trackRef.current.getBoundingClientRect();
|
|
3042
|
+
const percentage2 = Math.max(0, Math.min(100, (e.clientX - rect.left) / rect.width * 100));
|
|
3043
|
+
const newValue = Math.round(percentage2 / 100 * (max - min) / step) * step + min;
|
|
3044
|
+
if (isDragging === "min") {
|
|
3045
|
+
const newMin = Math.min(newValue, rangeValue[1] - step);
|
|
3046
|
+
const newRange = [newMin, rangeValue[1]];
|
|
3047
|
+
setInternalRangeValue(newRange);
|
|
3048
|
+
onRangeChange?.(newRange);
|
|
3049
|
+
} else {
|
|
3050
|
+
const newMax = Math.max(newValue, rangeValue[0] + step);
|
|
3051
|
+
const newRange = [rangeValue[0], newMax];
|
|
3052
|
+
setInternalRangeValue(newRange);
|
|
3053
|
+
onRangeChange?.(newRange);
|
|
3054
|
+
}
|
|
3055
|
+
};
|
|
3056
|
+
const handleRangeMouseUp = () => {
|
|
3057
|
+
setIsDragging(null);
|
|
3058
|
+
};
|
|
3059
|
+
import_react18.default.useEffect(() => {
|
|
3060
|
+
if (isDragging) {
|
|
3061
|
+
document.addEventListener("mousemove", handleRangeMouseMove);
|
|
3062
|
+
document.addEventListener("mouseup", handleRangeMouseUp);
|
|
3063
|
+
return () => {
|
|
3064
|
+
document.removeEventListener("mousemove", handleRangeMouseMove);
|
|
3065
|
+
document.removeEventListener("mouseup", handleRangeMouseUp);
|
|
3066
|
+
};
|
|
3067
|
+
}
|
|
3068
|
+
}, [isDragging, rangeValue]);
|
|
3069
|
+
const percentage = (value - min) / (max - min) * 100;
|
|
3070
|
+
const minPercentage = (rangeValue[0] - min) / (max - min) * 100;
|
|
3071
|
+
const maxPercentage = (rangeValue[1] - min) / (max - min) * 100;
|
|
3072
|
+
if (range) {
|
|
3073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3074
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [
|
|
3075
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label }),
|
|
3076
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
|
|
3077
|
+
rangeValue[0],
|
|
3078
|
+
" - ",
|
|
3079
|
+
rangeValue[1]
|
|
3080
|
+
] })
|
|
3081
|
+
] }),
|
|
3082
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "relative h-10 flex items-center", ref: trackRef, children: [
|
|
3083
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("div", { className: "absolute w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-full" }),
|
|
3084
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
3085
|
+
"div",
|
|
3086
|
+
{
|
|
3087
|
+
className: "absolute h-2 bg-blue-600 dark:bg-blue-500 rounded-full pointer-events-none",
|
|
3088
|
+
style: {
|
|
3089
|
+
left: `${minPercentage}%`,
|
|
3090
|
+
width: `${maxPercentage - minPercentage}%`
|
|
3091
|
+
}
|
|
3092
|
+
}
|
|
3093
|
+
),
|
|
3094
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
3095
|
+
"div",
|
|
3096
|
+
{
|
|
3097
|
+
className: `absolute w-4 h-4 -ml-2 rounded-sm bg-white dark:bg-gray-800 border-2 border-blue-600 shadow-md cursor-pointer z-10
|
|
3098
|
+
${disabled ? "opacity-50 cursor-not-allowed" : ""}
|
|
3099
|
+
`,
|
|
3100
|
+
style: { left: `${minPercentage}%` },
|
|
3101
|
+
onMouseDown: (e) => handleRangeMouseDown(e, "min"),
|
|
3102
|
+
role: "slider",
|
|
3103
|
+
"aria-label": `${label ? label + " " : ""}minimum value`,
|
|
3104
|
+
"aria-valuemin": min,
|
|
3105
|
+
"aria-valuemax": rangeValue[1],
|
|
3106
|
+
"aria-valuenow": rangeValue[0],
|
|
3107
|
+
tabIndex: disabled ? -1 : 0
|
|
3108
|
+
}
|
|
3109
|
+
),
|
|
3110
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
3111
|
+
"div",
|
|
3112
|
+
{
|
|
3113
|
+
className: `absolute w-4 h-4 -ml-2 rounded-sm bg-white dark:bg-gray-800 border-2 border-blue-600 shadow-md cursor-pointer z-10
|
|
3114
|
+
${disabled ? "opacity-50 cursor-not-allowed" : ""}
|
|
3115
|
+
`,
|
|
3116
|
+
style: { left: `${maxPercentage}%` },
|
|
3117
|
+
onMouseDown: (e) => handleRangeMouseDown(e, "max"),
|
|
3118
|
+
role: "slider",
|
|
3119
|
+
"aria-label": `${label ? label + " " : ""}maximum value`,
|
|
3120
|
+
"aria-valuemin": rangeValue[0],
|
|
3121
|
+
"aria-valuemax": max,
|
|
3122
|
+
"aria-valuenow": rangeValue[1],
|
|
3123
|
+
tabIndex: disabled ? -1 : 0
|
|
3124
|
+
}
|
|
3125
|
+
)
|
|
3126
|
+
] })
|
|
3127
|
+
] });
|
|
3128
|
+
}
|
|
3129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3130
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "flex justify-between items-center mb-2", children: [
|
|
3131
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: label }),
|
|
3132
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: value })
|
|
3133
|
+
] }),
|
|
3134
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "relative h-10 flex items-center", children: [
|
|
3135
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("div", { className: "absolute w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-full" }),
|
|
3136
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
3137
|
+
"div",
|
|
3138
|
+
{
|
|
3139
|
+
className: "absolute h-2 bg-blue-600 dark:bg-blue-500 rounded-full pointer-events-none",
|
|
3140
|
+
style: { width: `${percentage}%` }
|
|
3141
|
+
}
|
|
3142
|
+
),
|
|
3143
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
3144
|
+
"div",
|
|
3145
|
+
{
|
|
3146
|
+
className: `absolute w-4 h-4 -ml-2 rounded-sm bg-white dark:bg-gray-800 border-2 border-blue-600 shadow-md pointer-events-none z-10
|
|
3147
|
+
${disabled ? "opacity-50" : ""}
|
|
3148
|
+
`,
|
|
3149
|
+
style: { left: `${percentage}%` }
|
|
3150
|
+
}
|
|
3151
|
+
),
|
|
3152
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(
|
|
3153
|
+
"input",
|
|
3154
|
+
{
|
|
3155
|
+
type: "range",
|
|
3156
|
+
min,
|
|
3157
|
+
max,
|
|
3158
|
+
step,
|
|
3159
|
+
value,
|
|
3160
|
+
onChange: handleChange,
|
|
3161
|
+
disabled,
|
|
3162
|
+
className: "relative w-full h-10 bg-transparent appearance-none cursor-pointer disabled:cursor-not-allowed z-20\n [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4\n [&::-webkit-slider-thumb]:rounded-sm [&::-webkit-slider-thumb]:bg-transparent [&::-webkit-slider-thumb]:cursor-pointer\n [&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:rounded-sm\n [&::-moz-range-thumb]:bg-transparent [&::-moz-range-thumb]:cursor-pointer [&::-moz-range-thumb]:border-none",
|
|
3163
|
+
"aria-label": label,
|
|
3164
|
+
"aria-valuemin": min,
|
|
3165
|
+
"aria-valuemax": max,
|
|
3166
|
+
"aria-valuenow": value
|
|
3167
|
+
}
|
|
3168
|
+
)
|
|
3169
|
+
] })
|
|
3170
|
+
] });
|
|
3171
|
+
};
|
|
3172
|
+
|
|
3173
|
+
// src/components/Avatar.tsx
|
|
3174
|
+
var import_react19 = __toESM(require("react"));
|
|
3175
|
+
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
3176
|
+
var Avatar = ({
|
|
3177
|
+
src,
|
|
3178
|
+
alt,
|
|
3179
|
+
name,
|
|
3180
|
+
size = "md",
|
|
3181
|
+
shape = "circle",
|
|
3182
|
+
className = "",
|
|
3183
|
+
fallbackColor = "bg-blue-600"
|
|
3184
|
+
}) => {
|
|
3185
|
+
const [imageError, setImageError] = import_react19.default.useState(false);
|
|
3186
|
+
const sizeClasses7 = {
|
|
3187
|
+
xs: "w-6 h-6 text-xs",
|
|
3188
|
+
sm: "w-8 h-8 text-sm",
|
|
3189
|
+
md: "w-10 h-10 text-base",
|
|
3190
|
+
lg: "w-12 h-12 text-lg",
|
|
3191
|
+
xl: "w-16 h-16 text-2xl"
|
|
3192
|
+
};
|
|
3193
|
+
const shapeClass = shape === "circle" ? "rounded-full" : "rounded-md";
|
|
3194
|
+
const getInitials = (name2) => {
|
|
3195
|
+
const parts = name2.trim().split(" ");
|
|
3196
|
+
if (parts.length >= 2) {
|
|
3197
|
+
return `${parts[0][0]}${parts[parts.length - 1][0]}`.toUpperCase();
|
|
3198
|
+
}
|
|
3199
|
+
return name2.slice(0, 2).toUpperCase();
|
|
3200
|
+
};
|
|
3201
|
+
const showImage = src && !imageError;
|
|
3202
|
+
const showInitials = !showImage && name;
|
|
3203
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
3204
|
+
"div",
|
|
3205
|
+
{
|
|
3206
|
+
className: `${sizeClasses7[size]} ${shapeClass} flex items-center justify-center overflow-hidden ${showImage ? "bg-gray-200 dark:bg-gray-700" : `${fallbackColor} text-white`} ${className}`,
|
|
3207
|
+
children: showImage ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
3208
|
+
"img",
|
|
3209
|
+
{
|
|
3210
|
+
src,
|
|
3211
|
+
alt: alt || name || "Avatar",
|
|
3212
|
+
className: "w-full h-full object-cover",
|
|
3213
|
+
onError: () => setImageError(true)
|
|
3214
|
+
}
|
|
3215
|
+
) : showInitials ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "font-semibold select-none", children: getInitials(name) }) : /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
3216
|
+
"svg",
|
|
3217
|
+
{
|
|
3218
|
+
className: "w-full h-full text-gray-400 dark:text-gray-600",
|
|
3219
|
+
fill: "currentColor",
|
|
3220
|
+
viewBox: "0 0 24 24",
|
|
3221
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime95.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" })
|
|
3222
|
+
}
|
|
3223
|
+
)
|
|
3224
|
+
}
|
|
3225
|
+
);
|
|
3226
|
+
};
|
|
3227
|
+
|
|
3228
|
+
// src/components/Textarea.tsx
|
|
3229
|
+
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
3230
|
+
var Textarea = ({
|
|
3231
|
+
label,
|
|
3232
|
+
error,
|
|
3233
|
+
helperText,
|
|
3234
|
+
size = "md",
|
|
3235
|
+
resize = "vertical",
|
|
3236
|
+
className = "",
|
|
3237
|
+
disabled,
|
|
3238
|
+
...props
|
|
3239
|
+
}) => {
|
|
3240
|
+
const sizeClasses7 = {
|
|
3241
|
+
sm: "px-3 py-1.5 text-sm min-h-[80px]",
|
|
3242
|
+
md: "px-4 py-2 text-base min-h-[100px]",
|
|
3243
|
+
lg: "px-4 py-3 text-lg min-h-[120px]"
|
|
3244
|
+
};
|
|
3245
|
+
const resizeClasses = {
|
|
3246
|
+
none: "resize-none",
|
|
3247
|
+
vertical: "resize-y",
|
|
3248
|
+
horizontal: "resize-x",
|
|
3249
|
+
both: "resize"
|
|
3250
|
+
};
|
|
3251
|
+
const baseClasses = `w-full rounded-lg border transition-colors duration-150 focus:outline-none focus:ring-2
|
|
3252
|
+
${error ? "border-red-500 focus:ring-red-500 focus:border-red-500 dark:border-red-400 dark:focus:ring-red-400" : "border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:focus:ring-blue-400"}
|
|
3253
|
+
bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100
|
|
3254
|
+
placeholder:text-gray-500 dark:placeholder:text-gray-400
|
|
3255
|
+
disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-gray-50 dark:disabled:bg-gray-900`;
|
|
3256
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3257
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: label }),
|
|
3258
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
3259
|
+
"textarea",
|
|
3260
|
+
{
|
|
3261
|
+
className: `${baseClasses} ${sizeClasses7[size]} ${resizeClasses[resize]}`,
|
|
3262
|
+
disabled,
|
|
3263
|
+
...props
|
|
3264
|
+
}
|
|
3265
|
+
),
|
|
3266
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
3267
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime96.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText })
|
|
3268
|
+
] });
|
|
3269
|
+
};
|
|
3270
|
+
|
|
3271
|
+
// src/components/RichTextEditor.tsx
|
|
3272
|
+
var import_react20 = require("react");
|
|
3273
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
3274
|
+
var RichTextEditor = ({
|
|
3275
|
+
value = "",
|
|
3276
|
+
onChange,
|
|
3277
|
+
placeholder = "Start typing...",
|
|
3278
|
+
className = "",
|
|
3279
|
+
minHeight = "200px",
|
|
3280
|
+
maxHeight = "500px",
|
|
3281
|
+
disabled = false,
|
|
3282
|
+
label,
|
|
3283
|
+
error,
|
|
3284
|
+
helperText
|
|
3285
|
+
}) => {
|
|
3286
|
+
const { themeName } = useTheme();
|
|
3287
|
+
const editorRef = (0, import_react20.useRef)(null);
|
|
3288
|
+
const [isFocused, setIsFocused] = (0, import_react20.useState)(false);
|
|
3289
|
+
const [activeFormats, setActiveFormats] = (0, import_react20.useState)(/* @__PURE__ */ new Set());
|
|
3290
|
+
const [showLinkModal, setShowLinkModal] = (0, import_react20.useState)(false);
|
|
3291
|
+
const [linkUrl, setLinkUrl] = (0, import_react20.useState)("");
|
|
3292
|
+
const [showImageModal, setShowImageModal] = (0, import_react20.useState)(false);
|
|
3293
|
+
const [imageUrl, setImageUrl] = (0, import_react20.useState)("");
|
|
3294
|
+
const [imageAlt, setImageAlt] = (0, import_react20.useState)("");
|
|
3295
|
+
(0, import_react20.useLayoutEffect)(() => {
|
|
3296
|
+
const styleId = "rich-text-editor-styles";
|
|
3297
|
+
if (!document.getElementById(styleId)) {
|
|
3298
|
+
const style = document.createElement("style");
|
|
3299
|
+
style.id = styleId;
|
|
3300
|
+
style.textContent = `
|
|
3301
|
+
[contenteditable]:empty:before {
|
|
3302
|
+
content: attr(data-placeholder);
|
|
3303
|
+
color: #9ca3af;
|
|
3304
|
+
pointer-events: none;
|
|
3305
|
+
}
|
|
3306
|
+
[contenteditable] h1 {
|
|
3307
|
+
font-size: 2em;
|
|
3308
|
+
font-weight: bold;
|
|
3309
|
+
margin: 0.67em 0;
|
|
3310
|
+
}
|
|
3311
|
+
[contenteditable] h2 {
|
|
3312
|
+
font-size: 1.5em;
|
|
3313
|
+
font-weight: bold;
|
|
3314
|
+
margin: 0.75em 0;
|
|
3315
|
+
}
|
|
3316
|
+
[contenteditable] h3 {
|
|
3317
|
+
font-size: 1.17em;
|
|
3318
|
+
font-weight: bold;
|
|
3319
|
+
margin: 0.83em 0;
|
|
3320
|
+
}
|
|
3321
|
+
[contenteditable] ul, [contenteditable] ol {
|
|
3322
|
+
margin: 1em 0;
|
|
3323
|
+
padding-left: 2em;
|
|
3324
|
+
}
|
|
3325
|
+
[contenteditable] a {
|
|
3326
|
+
color: #3b82f6;
|
|
3327
|
+
text-decoration: underline;
|
|
3328
|
+
}
|
|
3329
|
+
.dark [contenteditable] a {
|
|
3330
|
+
color: #60a5fa;
|
|
3331
|
+
}
|
|
3332
|
+
[contenteditable] img {
|
|
3333
|
+
max-width: 100%;
|
|
3334
|
+
height: auto;
|
|
3335
|
+
border-radius: 0.5rem;
|
|
3336
|
+
margin: 1em 0;
|
|
3337
|
+
}
|
|
3338
|
+
[contenteditable] video {
|
|
3339
|
+
max-width: 100%;
|
|
3340
|
+
height: auto;
|
|
3341
|
+
border-radius: 0.5rem;
|
|
3342
|
+
margin: 1em 0;
|
|
3343
|
+
}
|
|
3344
|
+
`;
|
|
3345
|
+
document.head.appendChild(style);
|
|
3346
|
+
}
|
|
3347
|
+
}, []);
|
|
3348
|
+
const isInitialRender = (0, import_react20.useRef)(true);
|
|
3349
|
+
(0, import_react20.useEffect)(() => {
|
|
3350
|
+
if (!isInitialRender.current && editorRef.current && editorRef.current.innerHTML !== value) {
|
|
3351
|
+
editorRef.current.innerHTML = value;
|
|
3352
|
+
}
|
|
3353
|
+
isInitialRender.current = false;
|
|
3354
|
+
}, [value]);
|
|
3355
|
+
const updateActiveFormats = (0, import_react20.useCallback)(() => {
|
|
3356
|
+
const formats = /* @__PURE__ */ new Set();
|
|
3357
|
+
if (document.queryCommandState("bold")) formats.add("bold");
|
|
3358
|
+
if (document.queryCommandState("italic")) formats.add("italic");
|
|
3359
|
+
if (document.queryCommandState("underline")) formats.add("underline");
|
|
3360
|
+
if (document.queryCommandState("strikeThrough")) formats.add("strikeThrough");
|
|
3361
|
+
if (document.queryCommandState("insertUnorderedList")) formats.add("ul");
|
|
3362
|
+
if (document.queryCommandState("insertOrderedList")) formats.add("ol");
|
|
3363
|
+
const parentNode = window.getSelection()?.anchorNode?.parentElement;
|
|
3364
|
+
if (parentNode) {
|
|
3365
|
+
const tagName = parentNode.tagName.toLowerCase();
|
|
3366
|
+
if (["h1", "h2", "h3"].includes(tagName)) {
|
|
3367
|
+
formats.add(tagName);
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
setActiveFormats(formats);
|
|
3371
|
+
}, []);
|
|
3372
|
+
const handleInput = (0, import_react20.useCallback)(() => {
|
|
3373
|
+
if (editorRef.current && onChange) {
|
|
3374
|
+
onChange(editorRef.current.innerHTML);
|
|
3375
|
+
}
|
|
3376
|
+
updateActiveFormats();
|
|
3377
|
+
}, [onChange, updateActiveFormats]);
|
|
3378
|
+
const handleFormat = (0, import_react20.useCallback)((command) => {
|
|
3379
|
+
if (disabled) return;
|
|
3380
|
+
document.execCommand(command, false);
|
|
3381
|
+
editorRef.current?.focus();
|
|
3382
|
+
updateActiveFormats();
|
|
3383
|
+
handleInput();
|
|
3384
|
+
}, [disabled, updateActiveFormats, handleInput]);
|
|
3385
|
+
const handleList = (0, import_react20.useCallback)((command) => {
|
|
3386
|
+
if (disabled) return;
|
|
3387
|
+
document.execCommand(command, false);
|
|
3388
|
+
editorRef.current?.focus();
|
|
3389
|
+
updateActiveFormats();
|
|
3390
|
+
handleInput();
|
|
3391
|
+
}, [disabled, updateActiveFormats, handleInput]);
|
|
3392
|
+
const handleHeading = (0, import_react20.useCallback)((level) => {
|
|
3393
|
+
if (disabled) return;
|
|
3394
|
+
document.execCommand("formatBlock", false, level);
|
|
3395
|
+
editorRef.current?.focus();
|
|
3396
|
+
updateActiveFormats();
|
|
3397
|
+
handleInput();
|
|
3398
|
+
}, [disabled, updateActiveFormats, handleInput]);
|
|
3399
|
+
const handleLink = (0, import_react20.useCallback)(() => {
|
|
3400
|
+
if (disabled) return;
|
|
3401
|
+
setShowLinkModal(true);
|
|
3402
|
+
}, [disabled]);
|
|
3403
|
+
const insertLink = (0, import_react20.useCallback)(() => {
|
|
3404
|
+
if (linkUrl) {
|
|
3405
|
+
document.execCommand("createLink", false, linkUrl);
|
|
3406
|
+
setShowLinkModal(false);
|
|
3407
|
+
setLinkUrl("");
|
|
3408
|
+
editorRef.current?.focus();
|
|
3409
|
+
handleInput();
|
|
3410
|
+
}
|
|
3411
|
+
}, [linkUrl, handleInput]);
|
|
3412
|
+
const handleCode = (0, import_react20.useCallback)(() => {
|
|
3413
|
+
if (disabled) return;
|
|
3414
|
+
const selection = window.getSelection();
|
|
3415
|
+
if (selection && selection.rangeCount > 0) {
|
|
3416
|
+
const range = selection.getRangeAt(0);
|
|
3417
|
+
const code = document.createElement("code");
|
|
3418
|
+
code.className = "bg-gray-100 dark:bg-gray-700 px-1.5 py-0.5 rounded text-sm font-mono";
|
|
3419
|
+
try {
|
|
3420
|
+
range.surroundContents(code);
|
|
3421
|
+
handleInput();
|
|
3422
|
+
} catch (e) {
|
|
3423
|
+
console.warn("Could not apply code formatting");
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
editorRef.current?.focus();
|
|
3427
|
+
}, [disabled, handleInput]);
|
|
3428
|
+
const handleImage = (0, import_react20.useCallback)(() => {
|
|
3429
|
+
if (disabled) return;
|
|
3430
|
+
setShowImageModal(true);
|
|
3431
|
+
}, [disabled]);
|
|
3432
|
+
const insertImage = (0, import_react20.useCallback)(() => {
|
|
3433
|
+
if (!imageUrl) return;
|
|
3434
|
+
const img = document.createElement("img");
|
|
3435
|
+
img.src = imageUrl;
|
|
3436
|
+
img.alt = imageAlt || "";
|
|
3437
|
+
img.style.maxWidth = "100%";
|
|
3438
|
+
img.style.height = "auto";
|
|
3439
|
+
const selection = window.getSelection();
|
|
3440
|
+
if (selection && selection.rangeCount > 0) {
|
|
3441
|
+
const range = selection.getRangeAt(0);
|
|
3442
|
+
range.deleteContents();
|
|
3443
|
+
range.insertNode(img);
|
|
3444
|
+
range.setStartAfter(img);
|
|
3445
|
+
range.setEndAfter(img);
|
|
3446
|
+
selection.removeAllRanges();
|
|
3447
|
+
selection.addRange(range);
|
|
3448
|
+
} else if (editorRef.current) {
|
|
3449
|
+
editorRef.current.appendChild(img);
|
|
3450
|
+
}
|
|
3451
|
+
setShowImageModal(false);
|
|
3452
|
+
setImageUrl("");
|
|
3453
|
+
setImageAlt("");
|
|
3454
|
+
editorRef.current?.focus();
|
|
3455
|
+
handleInput();
|
|
3456
|
+
}, [imageUrl, imageAlt, handleInput, disabled]);
|
|
3457
|
+
const getButtonClass = (isActive) => {
|
|
3458
|
+
const baseClass = themeName === "minimalistic" ? "border border-white text-white transition-colors" : "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 transition-colors";
|
|
3459
|
+
const activeClass = themeName === "minimalistic" ? "bg-white text-black" : "bg-blue-100 dark:bg-blue-900 border-blue-500 dark:border-blue-400";
|
|
3460
|
+
const hoverClass = themeName === "minimalistic" ? "hover:bg-white hover:text-black" : "hover:bg-gray-100 dark:hover:bg-gray-700";
|
|
3461
|
+
const disabledClass = disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer";
|
|
3462
|
+
return `px-2.5 py-1.5 rounded text-sm font-medium ${baseClass} ${isActive ? activeClass : hoverClass} ${disabledClass}`;
|
|
3463
|
+
};
|
|
3464
|
+
const editorBaseClass = themeName === "minimalistic" ? "bg-transparent border-2 border-white text-white placeholder:text-gray-500" : "bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 text-gray-900 dark:text-gray-100";
|
|
3465
|
+
const focusClass = isFocused && !disabled ? themeName === "minimalistic" ? "border-white" : "border-blue-500 dark:border-blue-400 ring-2 ring-blue-500/20" : "";
|
|
3466
|
+
const errorClass = error ? "border-red-500 dark:border-red-400" : "";
|
|
3467
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
3468
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: label }),
|
|
3469
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: `rounded-t-lg border-b ${editorBaseClass} p-2 flex flex-wrap gap-1`, children: [
|
|
3470
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "flex gap-1", children: [
|
|
3471
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3472
|
+
"button",
|
|
3473
|
+
{
|
|
3474
|
+
type: "button",
|
|
3475
|
+
onClick: () => handleFormat("bold"),
|
|
3476
|
+
className: getButtonClass(activeFormats.has("bold")),
|
|
3477
|
+
disabled,
|
|
3478
|
+
title: "Bold (Ctrl+B)",
|
|
3479
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { d: "M12.78 4c1.09 0 2.04.38 2.84 1.14.8.76 1.2 1.74 1.2 2.94 0 .9-.25 1.68-.76 2.36-.51.68-1.2 1.14-2.04 1.38v.08c1.06.22 1.89.7 2.48 1.44.59.74.88 1.64.88 2.7 0 1.34-.47 2.43-1.41 3.27C14.96 19.77 13.74 20 12.24 20H4V4h8.78zm-.66 7.14c.62 0 1.12-.18 1.5-.54.38-.36.57-.84.57-1.44 0-.6-.19-1.08-.57-1.44-.38-.36-.88-.54-1.5-.54H7.5v3.96h4.62zm.24 6.86c.68 0 1.24-.19 1.68-.57.44-.38.66-.9.66-1.56 0-.66-.22-1.18-.66-1.56-.44-.38-1-.57-1.68-.57H7.5v4.26h4.86z" }) })
|
|
3480
|
+
}
|
|
3481
|
+
),
|
|
3482
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3483
|
+
"button",
|
|
3484
|
+
{
|
|
3485
|
+
type: "button",
|
|
3486
|
+
onClick: () => handleFormat("italic"),
|
|
3487
|
+
className: getButtonClass(activeFormats.has("italic")),
|
|
3488
|
+
disabled,
|
|
3489
|
+
title: "Italic (Ctrl+I)",
|
|
3490
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { d: "M11.59 4H16v2h-1.71l-3.58 8H13v2H8v-2h1.71l3.58-8H11.59V4z" }) })
|
|
3491
|
+
}
|
|
3492
|
+
),
|
|
3493
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3494
|
+
"button",
|
|
3495
|
+
{
|
|
3496
|
+
type: "button",
|
|
3497
|
+
onClick: () => handleFormat("underline"),
|
|
3498
|
+
className: getButtonClass(activeFormats.has("underline")),
|
|
3499
|
+
disabled,
|
|
3500
|
+
title: "Underline (Ctrl+U)",
|
|
3501
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { d: "M10 16c-2.21 0-4-1.79-4-4V4h2v8c0 1.1.9 2 2 2s2-.9 2-2V4h2v8c0 2.21-1.79 4-4 4zM4 18h12v2H4v-2z" }) })
|
|
3502
|
+
}
|
|
3503
|
+
),
|
|
3504
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3505
|
+
"button",
|
|
3506
|
+
{
|
|
3507
|
+
type: "button",
|
|
3508
|
+
onClick: () => handleFormat("strikeThrough"),
|
|
3509
|
+
className: getButtonClass(activeFormats.has("strikeThrough")),
|
|
3510
|
+
disabled,
|
|
3511
|
+
title: "Strikethrough",
|
|
3512
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { d: "M10 4c-2 0-3.5.5-4.5 1.5S4 7.5 4 9h2c0-.7.2-1.2.6-1.6.4-.4 1-.6 1.9-.6.8 0 1.4.2 1.8.5.4.3.7.8.7 1.4 0 .5-.2.9-.5 1.2-.3.3-.9.6-1.8.9l-.7.2c-1.2.3-2.1.7-2.7 1.2C4.2 12.7 4 13.5 4 14.5c0 1.1.4 2 1.1 2.6.7.6 1.7.9 3 .9 2.1 0 3.6-.5 4.6-1.5.9-1 1.3-2.3 1.3-3.8h-2c0 .9-.2 1.6-.7 2.1-.5.5-1.2.7-2.2.7-.8 0-1.4-.2-1.8-.5-.4-.3-.6-.8-.6-1.4 0-.5.2-.9.5-1.2.3-.3.9-.6 1.8-.9l.7-.2c1.2-.3 2.1-.7 2.7-1.2.6-.5.9-1.3.9-2.3 0-1.2-.4-2.1-1.2-2.8-.8-.7-1.9-1-3.3-1zM2 10h16v1H2v-1z" }) })
|
|
3513
|
+
}
|
|
3514
|
+
)
|
|
3515
|
+
] }),
|
|
3516
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "w-px bg-gray-300 dark:bg-gray-600 mx-1" }),
|
|
3517
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "flex gap-1", children: [
|
|
3518
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3519
|
+
"button",
|
|
3520
|
+
{
|
|
3521
|
+
type: "button",
|
|
3522
|
+
onClick: () => handleHeading("h1"),
|
|
3523
|
+
className: getButtonClass(activeFormats.has("h1")),
|
|
3524
|
+
disabled,
|
|
3525
|
+
title: "Heading 1",
|
|
3526
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("text", { x: "2", y: "16", fontSize: "14", fontWeight: "bold", children: "H1" }) })
|
|
3527
|
+
}
|
|
3528
|
+
),
|
|
3529
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3530
|
+
"button",
|
|
3531
|
+
{
|
|
3532
|
+
type: "button",
|
|
3533
|
+
onClick: () => handleHeading("h2"),
|
|
3534
|
+
className: getButtonClass(activeFormats.has("h2")),
|
|
3535
|
+
disabled,
|
|
3536
|
+
title: "Heading 2",
|
|
3537
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("text", { x: "2", y: "16", fontSize: "14", fontWeight: "bold", children: "H2" }) })
|
|
3538
|
+
}
|
|
3539
|
+
),
|
|
3540
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3541
|
+
"button",
|
|
3542
|
+
{
|
|
3543
|
+
type: "button",
|
|
3544
|
+
onClick: () => handleHeading("h3"),
|
|
3545
|
+
className: getButtonClass(activeFormats.has("h3")),
|
|
3546
|
+
disabled,
|
|
3547
|
+
title: "Heading 3",
|
|
3548
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("text", { x: "2", y: "16", fontSize: "14", fontWeight: "bold", children: "H3" }) })
|
|
3549
|
+
}
|
|
3550
|
+
)
|
|
3551
|
+
] }),
|
|
3552
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "w-px bg-gray-300 dark:bg-gray-600 mx-1" }),
|
|
3553
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "flex gap-1", children: [
|
|
3554
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3555
|
+
"button",
|
|
3556
|
+
{
|
|
3557
|
+
type: "button",
|
|
3558
|
+
onClick: () => handleList("insertUnorderedList"),
|
|
3559
|
+
className: getButtonClass(activeFormats.has("ul")),
|
|
3560
|
+
disabled,
|
|
3561
|
+
title: "Bullet List",
|
|
3562
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { d: "M4 4h2v2H4V4zm4 0h8v2H8V4zM4 8h2v2H4V8zm4 0h8v2H8V8zm-4 4h2v2H4v-2zm4 0h8v2H8v-2zm-4 4h2v2H4v-2zm4 0h8v2H8v-2z" }) })
|
|
3563
|
+
}
|
|
3564
|
+
),
|
|
3565
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3566
|
+
"button",
|
|
3567
|
+
{
|
|
3568
|
+
type: "button",
|
|
3569
|
+
onClick: () => handleList("insertOrderedList"),
|
|
3570
|
+
className: getButtonClass(activeFormats.has("ol")),
|
|
3571
|
+
disabled,
|
|
3572
|
+
title: "Numbered List",
|
|
3573
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { d: "M4 4h1v3H4V4zm0 4h1v1H3V8h2v1H4zm1 2H3v1h2v1H3v1h2v-3zM8 4h8v2H8V4zm0 4h8v2H8V8zm0 4h8v2H8v-2zm0 4h8v2H8v-2z" }) })
|
|
3574
|
+
}
|
|
3575
|
+
)
|
|
3576
|
+
] }),
|
|
3577
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "w-px bg-gray-300 dark:bg-gray-600 mx-1" }),
|
|
3578
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "flex gap-1", children: [
|
|
3579
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3580
|
+
"button",
|
|
3581
|
+
{
|
|
3582
|
+
type: "button",
|
|
3583
|
+
onClick: handleLink,
|
|
3584
|
+
className: getButtonClass(false),
|
|
3585
|
+
disabled,
|
|
3586
|
+
title: "Insert Link",
|
|
3587
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" }) })
|
|
3588
|
+
}
|
|
3589
|
+
),
|
|
3590
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3591
|
+
"button",
|
|
3592
|
+
{
|
|
3593
|
+
type: "button",
|
|
3594
|
+
onClick: handleImage,
|
|
3595
|
+
className: getButtonClass(false),
|
|
3596
|
+
disabled,
|
|
3597
|
+
title: "Insert Image/Video",
|
|
3598
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
|
|
3599
|
+
}
|
|
3600
|
+
),
|
|
3601
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3602
|
+
"button",
|
|
3603
|
+
{
|
|
3604
|
+
type: "button",
|
|
3605
|
+
onClick: handleCode,
|
|
3606
|
+
className: getButtonClass(false),
|
|
3607
|
+
disabled,
|
|
3608
|
+
title: "Code",
|
|
3609
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4" }) })
|
|
3610
|
+
}
|
|
3611
|
+
)
|
|
3612
|
+
] })
|
|
3613
|
+
] }),
|
|
3614
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3615
|
+
"div",
|
|
3616
|
+
{
|
|
3617
|
+
ref: editorRef,
|
|
3618
|
+
contentEditable: !disabled,
|
|
3619
|
+
onInput: handleInput,
|
|
3620
|
+
onFocus: () => setIsFocused(true),
|
|
3621
|
+
onBlur: () => setIsFocused(false),
|
|
3622
|
+
onMouseUp: updateActiveFormats,
|
|
3623
|
+
onKeyUp: updateActiveFormats,
|
|
3624
|
+
dangerouslySetInnerHTML: { __html: value },
|
|
3625
|
+
className: `
|
|
3626
|
+
w-full px-4 py-3 rounded-b-lg outline-none overflow-y-auto
|
|
3627
|
+
${editorBaseClass} ${focusClass} ${errorClass}
|
|
3628
|
+
${disabled ? "opacity-50 cursor-not-allowed" : ""}
|
|
3629
|
+
prose prose-sm dark:prose-invert max-w-none
|
|
3630
|
+
`,
|
|
3631
|
+
style: {
|
|
3632
|
+
minHeight,
|
|
3633
|
+
maxHeight
|
|
3634
|
+
},
|
|
3635
|
+
"data-placeholder": placeholder,
|
|
3636
|
+
suppressContentEditableWarning: true
|
|
3637
|
+
}
|
|
3638
|
+
),
|
|
3639
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("p", { className: "mt-1 text-sm text-red-600 dark:text-red-400", children: error }),
|
|
3640
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
3641
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3642
|
+
Modal,
|
|
3643
|
+
{
|
|
3644
|
+
isOpen: showLinkModal,
|
|
3645
|
+
onClose: () => {
|
|
3646
|
+
setShowLinkModal(false);
|
|
3647
|
+
setLinkUrl("");
|
|
3648
|
+
},
|
|
3649
|
+
title: "Insert Link",
|
|
3650
|
+
size: "sm",
|
|
3651
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "space-y-4", children: [
|
|
3652
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3653
|
+
TextInput,
|
|
3654
|
+
{
|
|
3655
|
+
label: "URL",
|
|
3656
|
+
value: linkUrl,
|
|
3657
|
+
onChange: (e) => setLinkUrl(e.target.value),
|
|
3658
|
+
placeholder: "https://example.com",
|
|
3659
|
+
autoFocus: true,
|
|
3660
|
+
onKeyDown: (e) => {
|
|
3661
|
+
if (e.key === "Enter") {
|
|
3662
|
+
e.preventDefault();
|
|
3663
|
+
insertLink();
|
|
3664
|
+
}
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
),
|
|
3668
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "flex gap-2 justify-end", children: [
|
|
3669
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3670
|
+
Button,
|
|
3671
|
+
{
|
|
3672
|
+
variant: "secondary",
|
|
3673
|
+
onClick: () => {
|
|
3674
|
+
setShowLinkModal(false);
|
|
3675
|
+
setLinkUrl("");
|
|
3676
|
+
},
|
|
3677
|
+
children: "Cancel"
|
|
3678
|
+
}
|
|
3679
|
+
),
|
|
3680
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3681
|
+
Button,
|
|
3682
|
+
{
|
|
3683
|
+
variant: "primary",
|
|
3684
|
+
onClick: insertLink,
|
|
3685
|
+
disabled: !linkUrl,
|
|
3686
|
+
children: "Insert"
|
|
3687
|
+
}
|
|
3688
|
+
)
|
|
3689
|
+
] })
|
|
3690
|
+
] })
|
|
3691
|
+
}
|
|
3692
|
+
),
|
|
3693
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3694
|
+
Modal,
|
|
3695
|
+
{
|
|
3696
|
+
isOpen: showImageModal,
|
|
3697
|
+
onClose: () => {
|
|
3698
|
+
setShowImageModal(false);
|
|
3699
|
+
setImageUrl("");
|
|
3700
|
+
setImageAlt("");
|
|
3701
|
+
},
|
|
3702
|
+
title: "Insert Image",
|
|
3703
|
+
size: "sm",
|
|
3704
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "space-y-4", children: [
|
|
3705
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3706
|
+
TextInput,
|
|
3707
|
+
{
|
|
3708
|
+
label: "Image URL",
|
|
3709
|
+
value: imageUrl,
|
|
3710
|
+
onChange: (e) => setImageUrl(e.target.value),
|
|
3711
|
+
placeholder: "https://example.com/image.jpg",
|
|
3712
|
+
autoFocus: true,
|
|
3713
|
+
onKeyDown: (e) => {
|
|
3714
|
+
if (e.key === "Enter") {
|
|
3715
|
+
e.preventDefault();
|
|
3716
|
+
insertImage();
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
),
|
|
3721
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3722
|
+
TextInput,
|
|
3723
|
+
{
|
|
3724
|
+
label: "Alt Text (optional)",
|
|
3725
|
+
value: imageAlt,
|
|
3726
|
+
onChange: (e) => setImageAlt(e.target.value),
|
|
3727
|
+
placeholder: "Describe the image"
|
|
3728
|
+
}
|
|
3729
|
+
),
|
|
3730
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "flex gap-2 justify-end", children: [
|
|
3731
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3732
|
+
Button,
|
|
3733
|
+
{
|
|
3734
|
+
variant: "secondary",
|
|
3735
|
+
onClick: () => {
|
|
3736
|
+
setShowImageModal(false);
|
|
3737
|
+
setImageUrl("");
|
|
3738
|
+
setImageAlt("");
|
|
3739
|
+
},
|
|
3740
|
+
children: "Cancel"
|
|
3741
|
+
}
|
|
3742
|
+
),
|
|
3743
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(
|
|
3744
|
+
Button,
|
|
3745
|
+
{
|
|
3746
|
+
variant: "primary",
|
|
3747
|
+
onClick: insertImage,
|
|
3748
|
+
disabled: !imageUrl,
|
|
3749
|
+
children: "Insert"
|
|
3750
|
+
}
|
|
3751
|
+
)
|
|
3752
|
+
] })
|
|
3753
|
+
] })
|
|
3754
|
+
}
|
|
3755
|
+
)
|
|
3756
|
+
] });
|
|
3757
|
+
};
|
|
3758
|
+
|
|
3759
|
+
// src/components/Toast.tsx
|
|
3760
|
+
var import_react21 = require("react");
|
|
3761
|
+
var import_jsx_runtime98 = require("react/jsx-runtime");
|
|
3762
|
+
var ToastContext = (0, import_react21.createContext)(void 0);
|
|
3763
|
+
var useToast = () => {
|
|
3764
|
+
const context = (0, import_react21.useContext)(ToastContext);
|
|
3765
|
+
if (!context) {
|
|
3766
|
+
throw new Error("useToast must be used within a ToastProvider");
|
|
3767
|
+
}
|
|
3768
|
+
return context;
|
|
3769
|
+
};
|
|
3770
|
+
var ToastProvider = ({ children, position = "top-right" }) => {
|
|
3771
|
+
const [toasts, setToasts] = (0, import_react21.useState)([]);
|
|
3772
|
+
const addToast = (0, import_react21.useCallback)((toast2) => {
|
|
3773
|
+
const id = Math.random().toString(36).substring(7);
|
|
3774
|
+
const newToast = { ...toast2, id };
|
|
3775
|
+
setToasts((prev) => [...prev, newToast]);
|
|
3776
|
+
const duration = toast2.duration || 5e3;
|
|
3777
|
+
setTimeout(() => {
|
|
3778
|
+
removeToast(id);
|
|
3779
|
+
}, duration);
|
|
3780
|
+
}, []);
|
|
3781
|
+
const removeToast = (0, import_react21.useCallback)((id) => {
|
|
3782
|
+
setToasts((prev) => prev.filter((toast2) => toast2.id !== id));
|
|
3783
|
+
}, []);
|
|
3784
|
+
const positionClasses2 = {
|
|
3785
|
+
"top-right": "top-4 right-4",
|
|
3786
|
+
"top-left": "top-4 left-4",
|
|
3787
|
+
"bottom-right": "bottom-4 right-4",
|
|
3788
|
+
"bottom-left": "bottom-4 left-4",
|
|
3789
|
+
"top-center": "top-4 left-1/2 -translate-x-1/2",
|
|
3790
|
+
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
3791
|
+
};
|
|
3792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(ToastContext.Provider, { value: { toasts, addToast, removeToast }, children: [
|
|
3793
|
+
children,
|
|
3794
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: `fixed ${positionClasses2[position]} z-50 flex flex-col gap-2 max-w-md`, children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(ToastItem, { toast: toast2, onClose: () => removeToast(toast2.id) }, toast2.id)) })
|
|
3795
|
+
] });
|
|
3796
|
+
};
|
|
3797
|
+
var ToastItem = ({ toast: toast2, onClose }) => {
|
|
3798
|
+
const typeStyles = {
|
|
3799
|
+
success: "bg-green-50 dark:bg-green-900/30 border-green-500 text-green-800 dark:text-green-200",
|
|
3800
|
+
error: "bg-red-50 dark:bg-red-900/30 border-red-500 text-red-800 dark:text-red-200",
|
|
3801
|
+
warning: "bg-yellow-50 dark:bg-yellow-900/30 border-yellow-500 text-yellow-800 dark:text-yellow-200",
|
|
3802
|
+
info: "bg-blue-50 dark:bg-blue-900/30 border-blue-500 text-blue-800 dark:text-blue-200"
|
|
3803
|
+
};
|
|
3804
|
+
const typeIcons = {
|
|
3805
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(CheckIcon, { size: "sm", className: "text-green-600 dark:text-green-400" }),
|
|
3806
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(CloseIcon, { size: "sm", className: "text-red-600 dark:text-red-400" }),
|
|
3807
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime98.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_runtime98.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" }) }),
|
|
3808
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime98.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_runtime98.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" }) })
|
|
3809
|
+
};
|
|
3810
|
+
const type = toast2.type || "info";
|
|
3811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)(
|
|
3812
|
+
"div",
|
|
3813
|
+
{
|
|
3814
|
+
className: `flex items-start gap-3 p-4 rounded-lg border-l-4 shadow-lg backdrop-blur-sm ${typeStyles[type]} animate-slide-in`,
|
|
3815
|
+
role: "alert",
|
|
3816
|
+
children: [
|
|
3817
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "flex-shrink-0 mt-0.5", children: typeIcons[type] }),
|
|
3818
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { className: "flex-1 text-sm font-medium", children: toast2.message }),
|
|
3819
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
3820
|
+
"button",
|
|
3821
|
+
{
|
|
3822
|
+
onClick: onClose,
|
|
3823
|
+
className: "flex-shrink-0 text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 transition-colors",
|
|
3824
|
+
"aria-label": "Close",
|
|
3825
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(CloseIcon, { size: "sm" })
|
|
3826
|
+
}
|
|
3827
|
+
)
|
|
3828
|
+
]
|
|
3829
|
+
}
|
|
3830
|
+
);
|
|
3831
|
+
};
|
|
3832
|
+
var toast = {
|
|
3833
|
+
success: (message, duration) => ({
|
|
3834
|
+
message,
|
|
3835
|
+
type: "success",
|
|
3836
|
+
duration
|
|
3837
|
+
}),
|
|
3838
|
+
error: (message, duration) => ({
|
|
3839
|
+
message,
|
|
3840
|
+
type: "error",
|
|
3841
|
+
duration
|
|
3842
|
+
}),
|
|
3843
|
+
warning: (message, duration) => ({
|
|
3844
|
+
message,
|
|
3845
|
+
type: "warning",
|
|
3846
|
+
duration
|
|
3847
|
+
}),
|
|
3848
|
+
info: (message, duration) => ({
|
|
3849
|
+
message,
|
|
3850
|
+
type: "info",
|
|
3851
|
+
duration
|
|
3852
|
+
})
|
|
3853
|
+
};
|
|
3854
|
+
|
|
3855
|
+
// src/components/Stepper.tsx
|
|
3856
|
+
var import_react22 = __toESM(require("react"));
|
|
3857
|
+
var import_jsx_runtime99 = require("react/jsx-runtime");
|
|
3858
|
+
var Stepper = ({
|
|
3859
|
+
steps,
|
|
3860
|
+
currentStep,
|
|
3861
|
+
orientation = "horizontal",
|
|
3862
|
+
className = ""
|
|
3863
|
+
}) => {
|
|
3864
|
+
const isHorizontal = orientation === "horizontal";
|
|
3865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: `${isHorizontal ? "flex items-center" : "flex flex-col"} ${className}`, children: steps.map((step, index) => {
|
|
3866
|
+
const stepNumber = index + 1;
|
|
3867
|
+
const isActive = stepNumber === currentStep;
|
|
3868
|
+
const isCompleted = stepNumber < currentStep;
|
|
3869
|
+
const isLast = index === steps.length - 1;
|
|
3870
|
+
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_react22.default.Fragment, { children: [
|
|
3871
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: `flex ${isHorizontal ? "flex-col items-center" : "flex-row items-start"} ${isHorizontal ? "" : "flex-1"}`, children: [
|
|
3872
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3873
|
+
"div",
|
|
3874
|
+
{
|
|
3875
|
+
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"}`,
|
|
3876
|
+
children: isCompleted ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(CheckIcon, { size: "sm", className: "text-white" }) : /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3877
|
+
"span",
|
|
3878
|
+
{
|
|
3879
|
+
className: `text-sm font-semibold ${isActive ? "text-blue-600 dark:text-blue-400" : "text-gray-500 dark:text-gray-400"}`,
|
|
3880
|
+
children: stepNumber
|
|
3881
|
+
}
|
|
3882
|
+
)
|
|
3883
|
+
}
|
|
3884
|
+
) }),
|
|
3885
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: `${isHorizontal ? "mt-2 text-center" : "ml-4 pb-8"} ${isLast && !isHorizontal ? "pb-0" : ""}`, children: [
|
|
3886
|
+
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3887
|
+
"p",
|
|
3888
|
+
{
|
|
3889
|
+
className: `text-sm font-medium ${isActive || isCompleted ? "text-gray-900 dark:text-gray-100" : "text-gray-500 dark:text-gray-400"}`,
|
|
3890
|
+
children: step.label
|
|
3891
|
+
}
|
|
3892
|
+
),
|
|
3893
|
+
step.description && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: step.description })
|
|
3894
|
+
] })
|
|
3895
|
+
] }),
|
|
3896
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|
|
3897
|
+
"div",
|
|
3898
|
+
{
|
|
3899
|
+
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"}`
|
|
3900
|
+
}
|
|
3901
|
+
)
|
|
3902
|
+
] }, index);
|
|
3903
|
+
}) });
|
|
3904
|
+
};
|
|
3905
|
+
|
|
3906
|
+
// src/components/Divider.tsx
|
|
3907
|
+
var import_jsx_runtime100 = require("react/jsx-runtime");
|
|
3908
|
+
var Divider = ({
|
|
3909
|
+
orientation = "horizontal",
|
|
3910
|
+
variant = "solid",
|
|
3911
|
+
className = "",
|
|
3912
|
+
label,
|
|
3913
|
+
labelPosition = "center"
|
|
3914
|
+
}) => {
|
|
3915
|
+
const variantClasses = {
|
|
3916
|
+
solid: "border-solid",
|
|
3917
|
+
dashed: "border-dashed",
|
|
3918
|
+
dotted: "border-dotted"
|
|
3919
|
+
};
|
|
3920
|
+
if (label && orientation === "horizontal") {
|
|
3921
|
+
const alignmentClasses = {
|
|
3922
|
+
left: "justify-start",
|
|
3923
|
+
center: "justify-center",
|
|
3924
|
+
right: "justify-end"
|
|
3925
|
+
};
|
|
3926
|
+
return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: `flex items-center ${alignmentClasses[labelPosition]} ${className}`, role: "separator", children: [
|
|
3927
|
+
labelPosition !== "left" && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: `flex-1 border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600` }),
|
|
3928
|
+
/* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "px-4 text-sm text-gray-500 dark:text-gray-400", children: label }),
|
|
3929
|
+
labelPosition !== "right" && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: `flex-1 border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600` })
|
|
3930
|
+
] });
|
|
3931
|
+
}
|
|
3932
|
+
if (orientation === "vertical") {
|
|
3933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
|
|
3934
|
+
"div",
|
|
3935
|
+
{
|
|
3936
|
+
className: `inline-block h-full border-l ${variantClasses[variant]} border-gray-300 dark:border-gray-600 ${className}`,
|
|
3937
|
+
role: "separator",
|
|
3938
|
+
"aria-orientation": "vertical"
|
|
3939
|
+
}
|
|
3940
|
+
);
|
|
3941
|
+
}
|
|
3942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
|
|
3943
|
+
"hr",
|
|
3944
|
+
{
|
|
3945
|
+
className: `border-t ${variantClasses[variant]} border-gray-300 dark:border-gray-600 ${className}`,
|
|
3946
|
+
role: "separator"
|
|
3947
|
+
}
|
|
3948
|
+
);
|
|
3949
|
+
};
|
|
3950
|
+
|
|
3951
|
+
// src/components/FileUpload.tsx
|
|
3952
|
+
var import_react23 = require("react");
|
|
3953
|
+
var import_jsx_runtime101 = require("react/jsx-runtime");
|
|
3954
|
+
var FileUpload = ({
|
|
3955
|
+
accept,
|
|
3956
|
+
multiple = false,
|
|
3957
|
+
maxSize,
|
|
3958
|
+
maxFiles = 10,
|
|
3959
|
+
disabled = false,
|
|
3960
|
+
onChange,
|
|
3961
|
+
onError,
|
|
3962
|
+
className = "",
|
|
3963
|
+
label,
|
|
3964
|
+
helperText
|
|
3965
|
+
}) => {
|
|
3966
|
+
const [files, setFiles] = (0, import_react23.useState)([]);
|
|
3967
|
+
const [isDragging, setIsDragging] = (0, import_react23.useState)(false);
|
|
3968
|
+
const fileInputRef = (0, import_react23.useRef)(null);
|
|
3969
|
+
const formatFileSize = (bytes) => {
|
|
3970
|
+
if (bytes === 0) return "0 Bytes";
|
|
3971
|
+
const k = 1024;
|
|
3972
|
+
const sizes = ["Bytes", "KB", "MB", "GB"];
|
|
3973
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
3974
|
+
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
|
|
3975
|
+
};
|
|
3976
|
+
const validateFiles = (fileList) => {
|
|
3977
|
+
const validFiles = [];
|
|
3978
|
+
const filesArray = Array.from(fileList);
|
|
3979
|
+
if (filesArray.length + files.length > maxFiles) {
|
|
3980
|
+
onError?.(`Maximum ${maxFiles} files allowed`);
|
|
3981
|
+
return validFiles;
|
|
3982
|
+
}
|
|
3983
|
+
for (const file of filesArray) {
|
|
3984
|
+
if (maxSize && file.size > maxSize) {
|
|
3985
|
+
onError?.(`File ${file.name} exceeds maximum size of ${formatFileSize(maxSize)}`);
|
|
3986
|
+
continue;
|
|
3987
|
+
}
|
|
3988
|
+
validFiles.push(file);
|
|
3989
|
+
}
|
|
3990
|
+
return validFiles;
|
|
3991
|
+
};
|
|
3992
|
+
const handleFiles = (fileList) => {
|
|
3993
|
+
if (!fileList || disabled) return;
|
|
3994
|
+
const validFiles = validateFiles(fileList);
|
|
3995
|
+
if (validFiles.length > 0) {
|
|
3996
|
+
const newFiles = multiple ? [...files, ...validFiles] : validFiles;
|
|
3997
|
+
setFiles(newFiles);
|
|
3998
|
+
onChange?.(newFiles);
|
|
3999
|
+
}
|
|
4000
|
+
};
|
|
4001
|
+
const handleDrop = (e) => {
|
|
4002
|
+
e.preventDefault();
|
|
4003
|
+
setIsDragging(false);
|
|
4004
|
+
handleFiles(e.dataTransfer.files);
|
|
4005
|
+
};
|
|
4006
|
+
const handleDragOver = (e) => {
|
|
4007
|
+
e.preventDefault();
|
|
4008
|
+
if (!disabled) {
|
|
4009
|
+
setIsDragging(true);
|
|
4010
|
+
}
|
|
4011
|
+
};
|
|
4012
|
+
const handleDragLeave = (e) => {
|
|
4013
|
+
e.preventDefault();
|
|
4014
|
+
setIsDragging(false);
|
|
4015
|
+
};
|
|
4016
|
+
const handleClick = () => {
|
|
4017
|
+
if (!disabled) {
|
|
4018
|
+
fileInputRef.current?.click();
|
|
4019
|
+
}
|
|
4020
|
+
};
|
|
4021
|
+
const handleRemoveFile = (index) => {
|
|
4022
|
+
const newFiles = files.filter((_, i) => i !== index);
|
|
4023
|
+
setFiles(newFiles);
|
|
4024
|
+
onChange?.(newFiles);
|
|
4025
|
+
};
|
|
4026
|
+
return /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
4027
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: label }),
|
|
4028
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
4029
|
+
"div",
|
|
4030
|
+
{
|
|
4031
|
+
onDrop: handleDrop,
|
|
4032
|
+
onDragOver: handleDragOver,
|
|
4033
|
+
onDragLeave: handleDragLeave,
|
|
4034
|
+
onClick: handleClick,
|
|
4035
|
+
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" : ""}`,
|
|
4036
|
+
children: [
|
|
4037
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
4038
|
+
"input",
|
|
4039
|
+
{
|
|
4040
|
+
ref: fileInputRef,
|
|
4041
|
+
type: "file",
|
|
4042
|
+
accept,
|
|
4043
|
+
multiple,
|
|
4044
|
+
onChange: (e) => handleFiles(e.target.files),
|
|
4045
|
+
disabled,
|
|
4046
|
+
className: "hidden"
|
|
4047
|
+
}
|
|
4048
|
+
),
|
|
4049
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "flex flex-col items-center gap-2", children: [
|
|
4050
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.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_runtime101.jsx)(UploadIcon, { size: "lg", className: "text-gray-400 dark:text-gray-500" }) }),
|
|
4051
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { children: [
|
|
4052
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300", children: [
|
|
4053
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("span", { className: "text-blue-600 dark:text-blue-400", children: "Click to upload" }),
|
|
4054
|
+
" or drag and drop"
|
|
4055
|
+
] }),
|
|
4056
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: [
|
|
4057
|
+
accept ? `Accepted: ${accept}` : "Any file type",
|
|
4058
|
+
maxSize && ` \u2022 Max size: ${formatFileSize(maxSize)}`
|
|
4059
|
+
] })
|
|
4060
|
+
] })
|
|
4061
|
+
] })
|
|
4062
|
+
]
|
|
4063
|
+
}
|
|
4064
|
+
),
|
|
4065
|
+
helperText && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "mt-2 text-sm text-gray-500 dark:text-gray-400", children: helperText }),
|
|
4066
|
+
files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime101.jsx)("div", { className: "mt-4 space-y-2", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime101.jsxs)(
|
|
4067
|
+
"div",
|
|
4068
|
+
{
|
|
4069
|
+
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",
|
|
4070
|
+
children: [
|
|
4071
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
4072
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 truncate", children: file.name }),
|
|
4073
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: formatFileSize(file.size) })
|
|
4074
|
+
] }),
|
|
4075
|
+
/* @__PURE__ */ (0, import_jsx_runtime101.jsx)(
|
|
4076
|
+
"button",
|
|
4077
|
+
{
|
|
4078
|
+
onClick: (e) => {
|
|
4079
|
+
e.stopPropagation();
|
|
4080
|
+
handleRemoveFile(index);
|
|
4081
|
+
},
|
|
4082
|
+
className: "ml-4 text-gray-400 hover:text-red-600 dark:hover:text-red-400 transition-colors",
|
|
4083
|
+
"aria-label": "Remove file",
|
|
4084
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime101.jsx)(CloseIcon, { size: "sm" })
|
|
4085
|
+
}
|
|
4086
|
+
)
|
|
4087
|
+
]
|
|
4088
|
+
},
|
|
4089
|
+
index
|
|
4090
|
+
)) })
|
|
4091
|
+
] });
|
|
4092
|
+
};
|
|
4093
|
+
|
|
4094
|
+
// src/components/AudioPlayer.tsx
|
|
4095
|
+
var import_react24 = require("react");
|
|
4096
|
+
var import_jsx_runtime102 = require("react/jsx-runtime");
|
|
4097
|
+
var AudioPlayer = ({
|
|
4098
|
+
src,
|
|
4099
|
+
title,
|
|
4100
|
+
artist,
|
|
4101
|
+
album,
|
|
4102
|
+
coverArt,
|
|
4103
|
+
variant = "default",
|
|
4104
|
+
autoPlay = false,
|
|
4105
|
+
loop = false,
|
|
4106
|
+
preload = "metadata",
|
|
4107
|
+
onPlay,
|
|
4108
|
+
onPause,
|
|
4109
|
+
onEnded,
|
|
4110
|
+
onTimeUpdate,
|
|
4111
|
+
className = "",
|
|
4112
|
+
showSkipButtons = false,
|
|
4113
|
+
onSkipBack,
|
|
4114
|
+
onSkipForward
|
|
4115
|
+
}) => {
|
|
4116
|
+
const audioRef = (0, import_react24.useRef)(null);
|
|
4117
|
+
const [isPlaying, setIsPlaying] = (0, import_react24.useState)(false);
|
|
4118
|
+
const [currentTime, setCurrentTime] = (0, import_react24.useState)(0);
|
|
4119
|
+
const [duration, setDuration] = (0, import_react24.useState)(0);
|
|
4120
|
+
const [volume, setVolume] = (0, import_react24.useState)(1);
|
|
4121
|
+
const [isMuted, setIsMuted] = (0, import_react24.useState)(false);
|
|
4122
|
+
const [isLoading, setIsLoading] = (0, import_react24.useState)(true);
|
|
4123
|
+
(0, import_react24.useEffect)(() => {
|
|
4124
|
+
const audio = audioRef.current;
|
|
4125
|
+
if (!audio) return;
|
|
4126
|
+
const handleLoadedMetadata = () => {
|
|
4127
|
+
setDuration(audio.duration);
|
|
4128
|
+
setIsLoading(false);
|
|
4129
|
+
};
|
|
4130
|
+
const handleCanPlay = () => {
|
|
4131
|
+
setIsLoading(false);
|
|
4132
|
+
};
|
|
4133
|
+
const handleTimeUpdate = () => {
|
|
4134
|
+
setCurrentTime(audio.currentTime);
|
|
4135
|
+
onTimeUpdate?.(audio.currentTime);
|
|
4136
|
+
};
|
|
4137
|
+
const handleEnded = () => {
|
|
4138
|
+
setIsPlaying(false);
|
|
4139
|
+
onEnded?.();
|
|
4140
|
+
};
|
|
4141
|
+
const handlePlay = () => {
|
|
4142
|
+
setIsPlaying(true);
|
|
4143
|
+
onPlay?.();
|
|
4144
|
+
};
|
|
4145
|
+
const handlePause = () => {
|
|
4146
|
+
setIsPlaying(false);
|
|
4147
|
+
onPause?.();
|
|
4148
|
+
};
|
|
4149
|
+
const handleError = (e) => {
|
|
4150
|
+
console.error("Audio error:", e);
|
|
4151
|
+
setIsPlaying(false);
|
|
4152
|
+
setIsLoading(false);
|
|
4153
|
+
};
|
|
4154
|
+
const handleLoadStart = () => {
|
|
4155
|
+
setIsLoading(true);
|
|
4156
|
+
};
|
|
4157
|
+
audio.addEventListener("loadstart", handleLoadStart);
|
|
4158
|
+
audio.addEventListener("loadedmetadata", handleLoadedMetadata);
|
|
4159
|
+
audio.addEventListener("canplay", handleCanPlay);
|
|
4160
|
+
audio.addEventListener("timeupdate", handleTimeUpdate);
|
|
4161
|
+
audio.addEventListener("ended", handleEnded);
|
|
4162
|
+
audio.addEventListener("play", handlePlay);
|
|
4163
|
+
audio.addEventListener("pause", handlePause);
|
|
4164
|
+
audio.addEventListener("error", handleError);
|
|
4165
|
+
if (audio.readyState >= 2) {
|
|
4166
|
+
setIsLoading(false);
|
|
4167
|
+
setDuration(audio.duration);
|
|
4168
|
+
}
|
|
4169
|
+
return () => {
|
|
4170
|
+
audio.removeEventListener("loadstart", handleLoadStart);
|
|
4171
|
+
audio.removeEventListener("loadedmetadata", handleLoadedMetadata);
|
|
4172
|
+
audio.removeEventListener("canplay", handleCanPlay);
|
|
4173
|
+
audio.removeEventListener("timeupdate", handleTimeUpdate);
|
|
4174
|
+
audio.removeEventListener("ended", handleEnded);
|
|
4175
|
+
audio.removeEventListener("play", handlePlay);
|
|
4176
|
+
audio.removeEventListener("pause", handlePause);
|
|
4177
|
+
audio.removeEventListener("error", handleError);
|
|
4178
|
+
};
|
|
4179
|
+
}, [onPlay, onPause, onEnded, onTimeUpdate]);
|
|
4180
|
+
(0, import_react24.useEffect)(() => {
|
|
4181
|
+
const audio = audioRef.current;
|
|
4182
|
+
if (!audio) return;
|
|
4183
|
+
audio.load();
|
|
4184
|
+
}, [src]);
|
|
4185
|
+
const togglePlayPause = async () => {
|
|
4186
|
+
const audio = audioRef.current;
|
|
4187
|
+
if (!audio) return;
|
|
4188
|
+
try {
|
|
4189
|
+
if (isPlaying) {
|
|
4190
|
+
audio.pause();
|
|
4191
|
+
} else {
|
|
4192
|
+
await audio.play();
|
|
4193
|
+
}
|
|
4194
|
+
} catch (error) {
|
|
4195
|
+
console.error("Playback error:", error);
|
|
4196
|
+
setIsPlaying(false);
|
|
4197
|
+
}
|
|
4198
|
+
};
|
|
4199
|
+
const handleSeek = (e) => {
|
|
4200
|
+
const audio = audioRef.current;
|
|
4201
|
+
if (!audio) return;
|
|
4202
|
+
const time = parseFloat(e.target.value);
|
|
4203
|
+
audio.currentTime = time;
|
|
4204
|
+
setCurrentTime(time);
|
|
4205
|
+
};
|
|
4206
|
+
const handleVolumeChange = (e) => {
|
|
4207
|
+
const audio = audioRef.current;
|
|
4208
|
+
if (!audio) return;
|
|
4209
|
+
const vol = parseFloat(e.target.value);
|
|
4210
|
+
audio.volume = vol;
|
|
4211
|
+
setVolume(vol);
|
|
4212
|
+
setIsMuted(vol === 0);
|
|
4213
|
+
};
|
|
4214
|
+
const toggleMute = () => {
|
|
4215
|
+
const audio = audioRef.current;
|
|
4216
|
+
if (!audio) return;
|
|
4217
|
+
if (isMuted) {
|
|
4218
|
+
audio.volume = volume || 0.5;
|
|
4219
|
+
setIsMuted(false);
|
|
4220
|
+
} else {
|
|
4221
|
+
audio.volume = 0;
|
|
4222
|
+
setIsMuted(true);
|
|
4223
|
+
}
|
|
4224
|
+
};
|
|
4225
|
+
const formatTime = (time) => {
|
|
4226
|
+
if (!isFinite(time)) return "0:00";
|
|
4227
|
+
const minutes = Math.floor(time / 60);
|
|
4228
|
+
const seconds = Math.floor(time % 60);
|
|
4229
|
+
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
|
4230
|
+
};
|
|
4231
|
+
const handleSkipBack = () => {
|
|
4232
|
+
const audio = audioRef.current;
|
|
4233
|
+
if (!audio) return;
|
|
4234
|
+
if (onSkipBack) {
|
|
4235
|
+
onSkipBack();
|
|
4236
|
+
} else {
|
|
4237
|
+
audio.currentTime = Math.max(0, audio.currentTime - 10);
|
|
4238
|
+
}
|
|
4239
|
+
};
|
|
4240
|
+
const handleSkipForward = () => {
|
|
4241
|
+
const audio = audioRef.current;
|
|
4242
|
+
if (!audio) return;
|
|
4243
|
+
if (onSkipForward) {
|
|
4244
|
+
onSkipForward();
|
|
4245
|
+
} else {
|
|
4246
|
+
audio.currentTime = Math.min(duration, audio.currentTime + 10);
|
|
4247
|
+
}
|
|
4248
|
+
};
|
|
4249
|
+
const progress = duration > 0 ? currentTime / duration * 100 : 0;
|
|
4250
|
+
if (variant === "mini") {
|
|
4251
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: `flex items-center gap-2 p-2 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 ${className}`, children: [
|
|
4252
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("audio", { ref: audioRef, src, preload, loop, autoPlay }),
|
|
4253
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4254
|
+
Button,
|
|
4255
|
+
{
|
|
4256
|
+
iconOnly: true,
|
|
4257
|
+
size: "sm",
|
|
4258
|
+
variant: "primary",
|
|
4259
|
+
onClick: togglePlayPause,
|
|
4260
|
+
disabled: isLoading,
|
|
4261
|
+
"aria-label": isPlaying ? "Pause" : "Play",
|
|
4262
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(PauseIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(PlayIcon, { size: "sm" })
|
|
4263
|
+
}
|
|
4264
|
+
),
|
|
4265
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 truncate", children: title })
|
|
4266
|
+
] });
|
|
4267
|
+
}
|
|
4268
|
+
if (variant === "compact") {
|
|
4269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: `flex items-center gap-3 p-3 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm ${className}`, children: [
|
|
4270
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("audio", { ref: audioRef, src, preload, loop, autoPlay }),
|
|
4271
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4272
|
+
Button,
|
|
4273
|
+
{
|
|
4274
|
+
iconOnly: true,
|
|
4275
|
+
size: "md",
|
|
4276
|
+
variant: "primary",
|
|
4277
|
+
onClick: togglePlayPause,
|
|
4278
|
+
disabled: isLoading,
|
|
4279
|
+
"aria-label": isPlaying ? "Pause" : "Play",
|
|
4280
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(PauseIcon, { size: "md" }) : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(PlayIcon, { size: "md" })
|
|
4281
|
+
}
|
|
4282
|
+
),
|
|
4283
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
4284
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 truncate", children: title }),
|
|
4285
|
+
artist && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "text-xs text-gray-500 dark:text-gray-400 truncate", children: artist })
|
|
4286
|
+
] }),
|
|
4287
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex items-center gap-2 flex-1", children: [
|
|
4288
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "text-xs text-gray-500 dark:text-gray-400 tabular-nums", children: formatTime(currentTime) }),
|
|
4289
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "relative flex-1 h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden", children: [
|
|
4290
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4291
|
+
"div",
|
|
4292
|
+
{
|
|
4293
|
+
className: "absolute h-full bg-blue-600 dark:bg-blue-500 rounded-full transition-all",
|
|
4294
|
+
style: { width: `${progress}%` }
|
|
4295
|
+
}
|
|
4296
|
+
),
|
|
4297
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4298
|
+
"input",
|
|
4299
|
+
{
|
|
4300
|
+
type: "range",
|
|
4301
|
+
min: 0,
|
|
4302
|
+
max: duration || 0,
|
|
4303
|
+
value: currentTime,
|
|
4304
|
+
onChange: handleSeek,
|
|
4305
|
+
disabled: isLoading,
|
|
4306
|
+
className: "absolute inset-0 w-full h-full opacity-0 cursor-pointer disabled:cursor-not-allowed",
|
|
4307
|
+
"aria-label": "Seek"
|
|
4308
|
+
}
|
|
4309
|
+
)
|
|
4310
|
+
] }),
|
|
4311
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { className: "text-xs text-gray-500 dark:text-gray-400 tabular-nums", children: formatTime(duration) })
|
|
4312
|
+
] }),
|
|
4313
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4314
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4315
|
+
"button",
|
|
4316
|
+
{
|
|
4317
|
+
onClick: toggleMute,
|
|
4318
|
+
className: "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200",
|
|
4319
|
+
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
4320
|
+
children: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(VolumeOffIcon, { size: "sm" }) : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(VolumeUpIcon, { size: "sm" })
|
|
4321
|
+
}
|
|
4322
|
+
),
|
|
4323
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4324
|
+
"input",
|
|
4325
|
+
{
|
|
4326
|
+
type: "range",
|
|
4327
|
+
min: 0,
|
|
4328
|
+
max: 1,
|
|
4329
|
+
step: 0.01,
|
|
4330
|
+
value: isMuted ? 0 : volume,
|
|
4331
|
+
onChange: handleVolumeChange,
|
|
4332
|
+
className: "w-16 h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full appearance-none cursor-pointer\n [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3\n [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-600 [&::-webkit-slider-thumb]:cursor-pointer\n [&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3 [&::-moz-range-thumb]:rounded-full\n [&::-moz-range-thumb]:bg-blue-600 [&::-moz-range-thumb]:cursor-pointer [&::-moz-range-thumb]:border-none",
|
|
4333
|
+
"aria-label": "Volume"
|
|
4334
|
+
}
|
|
4335
|
+
)
|
|
4336
|
+
] })
|
|
4337
|
+
] });
|
|
4338
|
+
}
|
|
4339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: `bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-md overflow-hidden ${className}`, children: [
|
|
4340
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("audio", { ref: audioRef, src, preload, loop, autoPlay }),
|
|
4341
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex items-center gap-4 p-4 border-b border-gray-200 dark:border-gray-700", children: [
|
|
4342
|
+
coverArt && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "w-16 h-16 flex-shrink-0 rounded-md overflow-hidden bg-gray-100 dark:bg-gray-700", children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4343
|
+
"img",
|
|
4344
|
+
{
|
|
4345
|
+
src: coverArt,
|
|
4346
|
+
alt: `${title || "Track"} cover art`,
|
|
4347
|
+
className: "w-full h-full object-cover"
|
|
4348
|
+
}
|
|
4349
|
+
) }),
|
|
4350
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
4351
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("h3", { className: "text-base font-semibold text-gray-900 dark:text-gray-100 truncate", children: title }),
|
|
4352
|
+
artist && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("p", { className: "text-sm text-gray-600 dark:text-gray-400 truncate", children: artist }),
|
|
4353
|
+
album && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-500 truncate", children: album })
|
|
4354
|
+
] })
|
|
4355
|
+
] }),
|
|
4356
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "px-4 pt-4", children: [
|
|
4357
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "relative h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden", children: [
|
|
4358
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4359
|
+
"div",
|
|
4360
|
+
{
|
|
4361
|
+
className: "absolute h-full bg-blue-600 dark:bg-blue-500 rounded-full transition-all",
|
|
4362
|
+
style: { width: `${progress}%` }
|
|
4363
|
+
}
|
|
4364
|
+
),
|
|
4365
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4366
|
+
"input",
|
|
4367
|
+
{
|
|
4368
|
+
type: "range",
|
|
4369
|
+
min: 0,
|
|
4370
|
+
max: duration || 0,
|
|
4371
|
+
value: currentTime,
|
|
4372
|
+
onChange: handleSeek,
|
|
4373
|
+
disabled: isLoading,
|
|
4374
|
+
className: "absolute inset-0 w-full h-full opacity-0 cursor-pointer disabled:cursor-not-allowed",
|
|
4375
|
+
"aria-label": "Seek"
|
|
4376
|
+
}
|
|
4377
|
+
)
|
|
4378
|
+
] }),
|
|
4379
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex justify-between items-center mt-1 text-xs text-gray-500 dark:text-gray-400 tabular-nums", children: [
|
|
4380
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { children: formatTime(currentTime) }),
|
|
4381
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("span", { children: formatTime(duration) })
|
|
4382
|
+
] })
|
|
4383
|
+
] }),
|
|
4384
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex items-center justify-between px-4 py-4", children: [
|
|
4385
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex items-center gap-2 flex-1", children: [
|
|
4386
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4387
|
+
"button",
|
|
4388
|
+
{
|
|
4389
|
+
onClick: toggleMute,
|
|
4390
|
+
className: "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors",
|
|
4391
|
+
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
4392
|
+
children: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(VolumeOffIcon, { size: "md" }) : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(VolumeUpIcon, { size: "md" })
|
|
4393
|
+
}
|
|
4394
|
+
),
|
|
4395
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4396
|
+
"input",
|
|
4397
|
+
{
|
|
4398
|
+
type: "range",
|
|
4399
|
+
min: 0,
|
|
4400
|
+
max: 1,
|
|
4401
|
+
step: 0.01,
|
|
4402
|
+
value: isMuted ? 0 : volume,
|
|
4403
|
+
onChange: handleVolumeChange,
|
|
4404
|
+
className: "w-20 h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full appearance-none cursor-pointer\n [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3\n [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-600 [&::-webkit-slider-thumb]:cursor-pointer\n [&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3 [&::-moz-range-thumb]:rounded-full\n [&::-moz-range-thumb]:bg-blue-600 [&::-moz-range-thumb]:cursor-pointer [&::-moz-range-thumb]:border-none",
|
|
4405
|
+
"aria-label": "Volume"
|
|
4406
|
+
}
|
|
4407
|
+
)
|
|
4408
|
+
] }),
|
|
4409
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4410
|
+
showSkipButtons && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4411
|
+
Button,
|
|
4412
|
+
{
|
|
4413
|
+
iconOnly: true,
|
|
4414
|
+
size: "md",
|
|
4415
|
+
variant: "secondary",
|
|
4416
|
+
onClick: handleSkipBack,
|
|
4417
|
+
disabled: isLoading,
|
|
4418
|
+
"aria-label": "Skip back 10 seconds",
|
|
4419
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkipBackIcon, { size: "md" })
|
|
4420
|
+
}
|
|
4421
|
+
),
|
|
4422
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4423
|
+
Button,
|
|
4424
|
+
{
|
|
4425
|
+
iconOnly: true,
|
|
4426
|
+
size: "lg",
|
|
4427
|
+
variant: "primary",
|
|
4428
|
+
onClick: togglePlayPause,
|
|
4429
|
+
disabled: isLoading,
|
|
4430
|
+
"aria-label": isPlaying ? "Pause" : "Play",
|
|
4431
|
+
children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(PauseIcon, { size: "lg" }) : /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(PlayIcon, { size: "lg" })
|
|
4432
|
+
}
|
|
4433
|
+
),
|
|
4434
|
+
showSkipButtons && /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(
|
|
4435
|
+
Button,
|
|
4436
|
+
{
|
|
4437
|
+
iconOnly: true,
|
|
4438
|
+
size: "md",
|
|
4439
|
+
variant: "secondary",
|
|
4440
|
+
onClick: handleSkipForward,
|
|
4441
|
+
disabled: isLoading,
|
|
4442
|
+
"aria-label": "Skip forward 10 seconds",
|
|
4443
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime102.jsx)(SkipForwardIcon, { size: "md" })
|
|
4444
|
+
}
|
|
4445
|
+
)
|
|
4446
|
+
] }),
|
|
4447
|
+
/* @__PURE__ */ (0, import_jsx_runtime102.jsx)("div", { className: "flex-1" })
|
|
4448
|
+
] })
|
|
313
4449
|
] });
|
|
314
4450
|
};
|
|
315
4451
|
|
|
@@ -347,12 +4483,113 @@ function getThemeScript() {
|
|
|
347
4483
|
}
|
|
348
4484
|
// Annotate the CommonJS export names for ESM import in node:
|
|
349
4485
|
0 && (module.exports = {
|
|
4486
|
+
ActionMenu,
|
|
4487
|
+
Alert,
|
|
4488
|
+
AlertCircleIcon,
|
|
4489
|
+
AppShell,
|
|
4490
|
+
AppleIcon,
|
|
4491
|
+
ArrowLeftIcon,
|
|
4492
|
+
ArrowRightIcon,
|
|
4493
|
+
AudioPlayer,
|
|
4494
|
+
Avatar,
|
|
4495
|
+
Badge,
|
|
4496
|
+
BeakerIcon,
|
|
4497
|
+
BellIcon,
|
|
4498
|
+
BookIcon,
|
|
4499
|
+
BrainIcon,
|
|
350
4500
|
Button,
|
|
4501
|
+
Calendar,
|
|
4502
|
+
CalendarIcon,
|
|
4503
|
+
CameraIcon,
|
|
4504
|
+
Card,
|
|
4505
|
+
ChatIcon,
|
|
4506
|
+
CheckCircleIcon,
|
|
4507
|
+
CheckIcon,
|
|
4508
|
+
Checkbox,
|
|
4509
|
+
ChevronDownIcon,
|
|
4510
|
+
ChevronLeftIcon,
|
|
4511
|
+
ChevronRightIcon,
|
|
4512
|
+
ChevronUpIcon,
|
|
4513
|
+
CloseIcon,
|
|
4514
|
+
CloudIcon,
|
|
4515
|
+
CodeIcon,
|
|
4516
|
+
CopyIcon,
|
|
4517
|
+
DatabaseIcon,
|
|
4518
|
+
DatePicker,
|
|
4519
|
+
DateTimePicker,
|
|
4520
|
+
Divider,
|
|
4521
|
+
DownloadIcon,
|
|
4522
|
+
Drawer,
|
|
4523
|
+
EditIcon,
|
|
4524
|
+
ExternalLinkIcon,
|
|
4525
|
+
EyeIcon,
|
|
4526
|
+
EyeOffIcon,
|
|
4527
|
+
FacebookIcon,
|
|
4528
|
+
FileIcon,
|
|
4529
|
+
FileUpload,
|
|
4530
|
+
FolderIcon,
|
|
4531
|
+
GitHubIcon,
|
|
4532
|
+
GlobeIcon,
|
|
4533
|
+
GoogleIcon,
|
|
4534
|
+
HeartIcon,
|
|
4535
|
+
HomeIcon,
|
|
4536
|
+
ImageIcon,
|
|
4537
|
+
InfoCircleIcon,
|
|
4538
|
+
KeyIcon,
|
|
4539
|
+
LinkedInIcon,
|
|
4540
|
+
LockIcon,
|
|
4541
|
+
MailIcon,
|
|
4542
|
+
MenuIcon,
|
|
4543
|
+
Modal,
|
|
4544
|
+
Navbar,
|
|
4545
|
+
NumberInput,
|
|
4546
|
+
Pagination,
|
|
4547
|
+
PauseIcon,
|
|
4548
|
+
PlayIcon,
|
|
4549
|
+
PlugIcon,
|
|
4550
|
+
PlusIcon,
|
|
4551
|
+
ProgressBar,
|
|
4552
|
+
Radio,
|
|
4553
|
+
RefreshIcon,
|
|
4554
|
+
RichTextEditor,
|
|
4555
|
+
SaveIcon,
|
|
4556
|
+
SearchIcon,
|
|
351
4557
|
Select,
|
|
4558
|
+
SettingsIcon,
|
|
4559
|
+
ShieldIcon,
|
|
4560
|
+
Sidebar,
|
|
4561
|
+
SidebarProvider,
|
|
4562
|
+
SkipBackIcon,
|
|
4563
|
+
SkipForwardIcon,
|
|
4564
|
+
SlackIcon,
|
|
4565
|
+
Slider,
|
|
4566
|
+
SparklesIcon,
|
|
4567
|
+
Spinner,
|
|
4568
|
+
StarIcon,
|
|
4569
|
+
Stepper,
|
|
4570
|
+
StopIcon,
|
|
4571
|
+
Table,
|
|
4572
|
+
Tabs,
|
|
4573
|
+
TerminalIcon,
|
|
4574
|
+
TextInput,
|
|
4575
|
+
Textarea,
|
|
352
4576
|
ThemeProvider,
|
|
4577
|
+
TimePicker,
|
|
4578
|
+
ToastProvider,
|
|
4579
|
+
Toggle,
|
|
4580
|
+
TrashIcon,
|
|
4581
|
+
TwitterIcon,
|
|
4582
|
+
UploadIcon,
|
|
4583
|
+
UserIcon,
|
|
4584
|
+
VolumeOffIcon,
|
|
4585
|
+
VolumeUpIcon,
|
|
4586
|
+
YouTubeIcon,
|
|
353
4587
|
getThemeScript,
|
|
354
4588
|
themeScript,
|
|
355
4589
|
themes,
|
|
356
|
-
|
|
4590
|
+
toast,
|
|
4591
|
+
useSidebar,
|
|
4592
|
+
useTheme,
|
|
4593
|
+
useToast
|
|
357
4594
|
});
|
|
358
4595
|
//# sourceMappingURL=index.js.map
|