@gamecp/ui 0.1.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 +244 -0
- package/dist/index.d.mts +211 -0
- package/dist/index.d.ts +211 -0
- package/dist/index.js +1306 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1276 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +56 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1276 @@
|
|
|
1
|
+
import React4, { forwardRef, useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { RiCheckLine, RiFileCopyLine, RiEyeOffLine, RiEyeLine, RiRefreshLine, RiCloseLine, RiArrowDownSLine } from 'react-icons/ri';
|
|
4
|
+
import NextLink from 'next/link';
|
|
5
|
+
import { createPortal } from 'react-dom';
|
|
6
|
+
import { AnimatePresence, motion } from 'framer-motion';
|
|
7
|
+
|
|
8
|
+
// src/Button.tsx
|
|
9
|
+
var variantClasses = {
|
|
10
|
+
primary: "bg-primary text-primary-foreground hover:bg-primary/90 border-transparent",
|
|
11
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent",
|
|
12
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 border-transparent",
|
|
13
|
+
ghost: "bg-transparent hover:bg-muted hover:text-foreground border-transparent",
|
|
14
|
+
link: "bg-transparent text-primary underline-offset-4 hover:underline border-transparent p-0",
|
|
15
|
+
outline: "bg-transparent border-border hover:bg-muted hover:text-foreground"
|
|
16
|
+
};
|
|
17
|
+
var sizeClasses = {
|
|
18
|
+
sm: "px-3 py-1.5 text-sm",
|
|
19
|
+
md: "px-4 py-2 text-sm",
|
|
20
|
+
lg: "px-6 py-3 text-base"
|
|
21
|
+
};
|
|
22
|
+
var Button = forwardRef(
|
|
23
|
+
({
|
|
24
|
+
variant = "primary",
|
|
25
|
+
size = "md",
|
|
26
|
+
isLoading = false,
|
|
27
|
+
leftIcon,
|
|
28
|
+
rightIcon,
|
|
29
|
+
fullWidth = false,
|
|
30
|
+
className = "",
|
|
31
|
+
disabled,
|
|
32
|
+
children,
|
|
33
|
+
...props
|
|
34
|
+
}, ref) => {
|
|
35
|
+
const baseClasses = "inline-flex items-center justify-center gap-2 font-medium rounded-md border transition-colors focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed";
|
|
36
|
+
const classes = [
|
|
37
|
+
baseClasses,
|
|
38
|
+
variantClasses[variant],
|
|
39
|
+
variant !== "link" ? sizeClasses[size] : "",
|
|
40
|
+
fullWidth ? "w-full" : "",
|
|
41
|
+
className
|
|
42
|
+
].filter(Boolean).join(" ");
|
|
43
|
+
return /* @__PURE__ */ jsxs(
|
|
44
|
+
"button",
|
|
45
|
+
{
|
|
46
|
+
ref,
|
|
47
|
+
className: classes,
|
|
48
|
+
disabled: disabled || isLoading,
|
|
49
|
+
...props,
|
|
50
|
+
children: [
|
|
51
|
+
isLoading && /* @__PURE__ */ jsxs(
|
|
52
|
+
"svg",
|
|
53
|
+
{
|
|
54
|
+
className: "animate-spin h-4 w-4",
|
|
55
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
56
|
+
fill: "none",
|
|
57
|
+
viewBox: "0 0 24 24",
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ jsx(
|
|
60
|
+
"circle",
|
|
61
|
+
{
|
|
62
|
+
className: "opacity-25",
|
|
63
|
+
cx: "12",
|
|
64
|
+
cy: "12",
|
|
65
|
+
r: "10",
|
|
66
|
+
stroke: "currentColor",
|
|
67
|
+
strokeWidth: "4"
|
|
68
|
+
}
|
|
69
|
+
),
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
"path",
|
|
72
|
+
{
|
|
73
|
+
className: "opacity-75",
|
|
74
|
+
fill: "currentColor",
|
|
75
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
),
|
|
81
|
+
!isLoading && leftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: leftIcon }),
|
|
82
|
+
children,
|
|
83
|
+
!isLoading && rightIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: rightIcon })
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
Button.displayName = "Button";
|
|
90
|
+
var Button_default = Button;
|
|
91
|
+
var badgeVariants = {
|
|
92
|
+
default: "bg-gray-100 text-foreground border-border",
|
|
93
|
+
primary: "bg-primary-100 text-primary-800 border-primary-200",
|
|
94
|
+
secondary: "bg-gray-100 text-foreground border-border",
|
|
95
|
+
success: "bg-success text-success-dark border-success-light",
|
|
96
|
+
warning: "bg-yellow-100 text-yellow-800 border-yellow-200",
|
|
97
|
+
error: "bg-red-100 text-red-800 border-red-200",
|
|
98
|
+
info: "bg-muted text-muted-foreground border-ring",
|
|
99
|
+
gray: "bg-gray-100 text-foreground border-border",
|
|
100
|
+
purple: "bg-purple-100 text-purple-800 border-purple-200",
|
|
101
|
+
pink: "bg-pink-100 text-pink-800 border-pink-200",
|
|
102
|
+
indigo: "bg-indigo-100 text-indigo-800 border-indigo-200",
|
|
103
|
+
yellow: "bg-yellow-100 text-yellow-800 border-yellow-200",
|
|
104
|
+
orange: "bg-orange-100 text-orange-800 border-orange-200",
|
|
105
|
+
teal: "bg-teal-100 text-teal-800 border-teal-200",
|
|
106
|
+
cyan: "bg-cyan-100 text-cyan-800 border-cyan-200",
|
|
107
|
+
lime: "bg-lime-100 text-lime-800 border-lime-200",
|
|
108
|
+
emerald: "bg-emerald-100 text-emerald-800 border-emerald-200",
|
|
109
|
+
rose: "bg-rose-100 text-rose-800 border-rose-200",
|
|
110
|
+
sky: "bg-sky-100 text-sky-800 border-sky-200",
|
|
111
|
+
violet: "bg-violet-100 text-violet-800 border-violet-200",
|
|
112
|
+
fuchsia: "bg-fuchsia-100 text-fuchsia-800 border-fuchsia-200",
|
|
113
|
+
amber: "bg-amber-100 text-amber-800 border-amber-200"
|
|
114
|
+
};
|
|
115
|
+
var badgeSizes = {
|
|
116
|
+
sm: "px-2 py-0.5 text-xs",
|
|
117
|
+
md: "px-2.5 py-0.5 text-xs",
|
|
118
|
+
lg: "px-3 py-1 text-sm"
|
|
119
|
+
};
|
|
120
|
+
function Badge({
|
|
121
|
+
children,
|
|
122
|
+
variant = "default",
|
|
123
|
+
size = "md",
|
|
124
|
+
className = "",
|
|
125
|
+
customColors
|
|
126
|
+
}) {
|
|
127
|
+
const baseClasses = "inline-flex items-center font-medium rounded-full border";
|
|
128
|
+
const variantClasses4 = variant === "custom" ? "" : badgeVariants[variant];
|
|
129
|
+
const sizeClasses4 = badgeSizes[size];
|
|
130
|
+
const customStyles = variant === "custom" && customColors ? {
|
|
131
|
+
backgroundColor: customColors.background,
|
|
132
|
+
color: customColors.text,
|
|
133
|
+
borderColor: customColors.border || customColors.background
|
|
134
|
+
} : {};
|
|
135
|
+
return /* @__PURE__ */ jsx(
|
|
136
|
+
"span",
|
|
137
|
+
{
|
|
138
|
+
className: `${baseClasses} ${variantClasses4} ${sizeClasses4} ${className}`,
|
|
139
|
+
style: customStyles,
|
|
140
|
+
children
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
var SuccessBadge = (props) => /* @__PURE__ */ jsx(Badge, { ...props, variant: "success" });
|
|
145
|
+
var WarningBadge = (props) => /* @__PURE__ */ jsx(Badge, { ...props, variant: "warning" });
|
|
146
|
+
var ErrorBadge = (props) => /* @__PURE__ */ jsx(Badge, { ...props, variant: "error" });
|
|
147
|
+
var InfoBadge = (props) => /* @__PURE__ */ jsx(Badge, { ...props, variant: "info" });
|
|
148
|
+
var PrimaryBadge = (props) => /* @__PURE__ */ jsx(Badge, { ...props, variant: "primary" });
|
|
149
|
+
var GrayBadge = (props) => /* @__PURE__ */ jsx(Badge, { ...props, variant: "gray" });
|
|
150
|
+
function StatusBadge({
|
|
151
|
+
isActive,
|
|
152
|
+
activeText = "Active",
|
|
153
|
+
inactiveText = "Inactive",
|
|
154
|
+
...props
|
|
155
|
+
}) {
|
|
156
|
+
return /* @__PURE__ */ jsx(Badge, { ...props, variant: isActive ? "success" : "error", children: isActive ? activeText : inactiveText });
|
|
157
|
+
}
|
|
158
|
+
var sizeClasses2 = {
|
|
159
|
+
xs: "w-3 h-3",
|
|
160
|
+
sm: "w-4 h-4",
|
|
161
|
+
md: "w-5 h-5",
|
|
162
|
+
lg: "w-6 h-6",
|
|
163
|
+
xl: "w-8 h-8",
|
|
164
|
+
"2": "w-2 h-2",
|
|
165
|
+
"3": "w-3 h-3",
|
|
166
|
+
"4": "w-4 h-4",
|
|
167
|
+
"5": "w-5 h-5",
|
|
168
|
+
"6": "w-6 h-6"
|
|
169
|
+
};
|
|
170
|
+
var colorClasses = {
|
|
171
|
+
default: "text-muted-foreground hover:text-muted-foreground",
|
|
172
|
+
gray: "text-muted-foreground hover:text-muted-foreground",
|
|
173
|
+
primary: "text-ring hover:text-primary-foreground",
|
|
174
|
+
secondary: "text-secondary-foreground hover:text-foreground"
|
|
175
|
+
};
|
|
176
|
+
function DropDownArrow({
|
|
177
|
+
isOpen,
|
|
178
|
+
disabled = false,
|
|
179
|
+
size = "sm",
|
|
180
|
+
color = "default",
|
|
181
|
+
className = "",
|
|
182
|
+
"aria-hidden": ariaHidden
|
|
183
|
+
}) {
|
|
184
|
+
const baseClasses = `${sizeClasses2[size]} flex-shrink-0 transition-transform`;
|
|
185
|
+
const rotationClasses = isOpen ? "rotate-180" : "";
|
|
186
|
+
const colorClassesApplied = disabled ? "text-muted-foreground" : colorClasses[color];
|
|
187
|
+
const combinedClasses = `${baseClasses} ${rotationClasses} ${colorClassesApplied} ${className}`.trim();
|
|
188
|
+
return /* @__PURE__ */ jsx(RiArrowDownSLine, { className: combinedClasses, "aria-hidden": ariaHidden });
|
|
189
|
+
}
|
|
190
|
+
var paddingClasses = {
|
|
191
|
+
none: "",
|
|
192
|
+
sm: "p-3",
|
|
193
|
+
md: "p-4",
|
|
194
|
+
lg: "p-6",
|
|
195
|
+
xl: "p-8"
|
|
196
|
+
};
|
|
197
|
+
var borderAccentClasses = {
|
|
198
|
+
none: "",
|
|
199
|
+
green: "border-l-4 border-l-green-500",
|
|
200
|
+
blue: "border-l-4 border-l-ring",
|
|
201
|
+
red: "border-l-4 border-l-red-500",
|
|
202
|
+
yellow: "border-l-4 border-l-yellow-500",
|
|
203
|
+
purple: "border-l-4 border-l-purple-500",
|
|
204
|
+
orange: "border-l-4 border-l-orange-500",
|
|
205
|
+
gray: "border-l-4 border-l-gray-500"
|
|
206
|
+
};
|
|
207
|
+
var variantClasses2 = {
|
|
208
|
+
default: "card",
|
|
209
|
+
elevated: "card shadow-lg border border-border",
|
|
210
|
+
outlined: "card rounded-lg border-2 border-border",
|
|
211
|
+
filled: "bg-muted rounded-lg border border-border"
|
|
212
|
+
};
|
|
213
|
+
var iconColorClasses = {
|
|
214
|
+
green: "text-success",
|
|
215
|
+
blue: "text-primary",
|
|
216
|
+
red: "text-destructive",
|
|
217
|
+
yellow: "text-yellow-600",
|
|
218
|
+
purple: "text-purple-600",
|
|
219
|
+
orange: "text-orange-600",
|
|
220
|
+
gray: "text-muted-foreground",
|
|
221
|
+
indigo: "text-indigo-600",
|
|
222
|
+
pink: "text-pink-600"
|
|
223
|
+
};
|
|
224
|
+
var iconSizeClasses = {
|
|
225
|
+
sm: "w-4 h-4",
|
|
226
|
+
md: "w-6 h-6",
|
|
227
|
+
lg: "w-8 h-8"
|
|
228
|
+
};
|
|
229
|
+
var statusClasses = {
|
|
230
|
+
success: "bg-success-light border-success-light",
|
|
231
|
+
warning: "bg-yellow-50 border-yellow-200",
|
|
232
|
+
error: "bg-destructive border-destructive",
|
|
233
|
+
info: "bg-primary border-primary",
|
|
234
|
+
neutral: "bg-muted border-border"
|
|
235
|
+
};
|
|
236
|
+
function Card({
|
|
237
|
+
children,
|
|
238
|
+
className = "",
|
|
239
|
+
onClick,
|
|
240
|
+
disabled = false,
|
|
241
|
+
padding = "md",
|
|
242
|
+
borderAccent = "none",
|
|
243
|
+
variant = "default",
|
|
244
|
+
overflow = "visible",
|
|
245
|
+
minHeight,
|
|
246
|
+
maxHeight,
|
|
247
|
+
hover = false,
|
|
248
|
+
clickable = false,
|
|
249
|
+
title,
|
|
250
|
+
subtitle,
|
|
251
|
+
description,
|
|
252
|
+
icon: Icon,
|
|
253
|
+
iconColor = "blue",
|
|
254
|
+
iconSize = "md",
|
|
255
|
+
actionButton,
|
|
256
|
+
headerClassName = "",
|
|
257
|
+
accordion = false,
|
|
258
|
+
defaultExpanded = true,
|
|
259
|
+
onToggle,
|
|
260
|
+
contentClassName = "",
|
|
261
|
+
status,
|
|
262
|
+
statusIcon,
|
|
263
|
+
statusText
|
|
264
|
+
}) {
|
|
265
|
+
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
266
|
+
const baseClasses = [
|
|
267
|
+
variantClasses2[variant],
|
|
268
|
+
paddingClasses[padding],
|
|
269
|
+
borderAccentClasses[borderAccent],
|
|
270
|
+
overflow !== "visible" ? `overflow-${overflow}` : "",
|
|
271
|
+
hover ? "hover:shadow-md transition-shadow" : "",
|
|
272
|
+
clickable || onClick ? "cursor-pointer" : "",
|
|
273
|
+
disabled ? "opacity-50 cursor-not-allowed" : "",
|
|
274
|
+
status ? statusClasses[status] : ""
|
|
275
|
+
].filter(Boolean).join(" ");
|
|
276
|
+
const style = {};
|
|
277
|
+
if (minHeight) style.minHeight = minHeight;
|
|
278
|
+
if (maxHeight) style.maxHeight = maxHeight;
|
|
279
|
+
const handleClick = () => {
|
|
280
|
+
if (disabled) return;
|
|
281
|
+
onClick?.();
|
|
282
|
+
};
|
|
283
|
+
const handleToggle = () => {
|
|
284
|
+
if (accordion) {
|
|
285
|
+
const newExpanded = !isExpanded;
|
|
286
|
+
setIsExpanded(newExpanded);
|
|
287
|
+
onToggle?.(newExpanded);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
return /* @__PURE__ */ jsxs(
|
|
291
|
+
"div",
|
|
292
|
+
{
|
|
293
|
+
className: `${baseClasses} ${className}`,
|
|
294
|
+
style,
|
|
295
|
+
onClick: clickable || onClick ? handleClick : void 0,
|
|
296
|
+
children: [
|
|
297
|
+
(title || subtitle || description || Icon || actionButton || status) && /* @__PURE__ */ jsx("div", { className: `${headerClassName}`, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
298
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3 flex-1 min-w-0", children: [
|
|
299
|
+
Icon && /* @__PURE__ */ jsx("div", { className: `${iconColorClasses[iconColor]} flex-shrink-0`, children: /* @__PURE__ */ jsx(Icon, { className: iconSizeClasses[iconSize] }) }),
|
|
300
|
+
statusIcon && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: statusIcon }),
|
|
301
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
302
|
+
title && /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground truncate", children: title }),
|
|
303
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-muted-foreground truncate", children: subtitle }),
|
|
304
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: description }),
|
|
305
|
+
statusText && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: statusText })
|
|
306
|
+
] })
|
|
307
|
+
] }),
|
|
308
|
+
actionButton && /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 ml-4", children: actionButton }),
|
|
309
|
+
accordion && /* @__PURE__ */ jsxs(
|
|
310
|
+
"button",
|
|
311
|
+
{
|
|
312
|
+
type: "button",
|
|
313
|
+
onClick: (e) => {
|
|
314
|
+
e.stopPropagation();
|
|
315
|
+
handleToggle();
|
|
316
|
+
},
|
|
317
|
+
"aria-expanded": isExpanded,
|
|
318
|
+
"aria-label": `${isExpanded ? "Hide" : "Show"} ${title || "content"}`,
|
|
319
|
+
className: "flex items-center text-sm text-muted-foreground hover:text-foreground transition-colors ml-4",
|
|
320
|
+
children: [
|
|
321
|
+
/* @__PURE__ */ jsx("span", { className: "mr-1", children: isExpanded ? "Hide" : "Show" }),
|
|
322
|
+
/* @__PURE__ */ jsx(
|
|
323
|
+
DropDownArrow,
|
|
324
|
+
{
|
|
325
|
+
isOpen: isExpanded,
|
|
326
|
+
size: "sm",
|
|
327
|
+
color: "gray",
|
|
328
|
+
"aria-hidden": true
|
|
329
|
+
}
|
|
330
|
+
)
|
|
331
|
+
]
|
|
332
|
+
}
|
|
333
|
+
)
|
|
334
|
+
] }) }),
|
|
335
|
+
/* @__PURE__ */ jsx(
|
|
336
|
+
"div",
|
|
337
|
+
{
|
|
338
|
+
className: `${contentClassName} ${accordion && !isExpanded ? "hidden" : ""}`,
|
|
339
|
+
children
|
|
340
|
+
}
|
|
341
|
+
)
|
|
342
|
+
]
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
function SimpleCard({
|
|
347
|
+
children,
|
|
348
|
+
className = "",
|
|
349
|
+
...props
|
|
350
|
+
}) {
|
|
351
|
+
return /* @__PURE__ */ jsx(Card, { className, ...props, children });
|
|
352
|
+
}
|
|
353
|
+
function HeaderCard({
|
|
354
|
+
title,
|
|
355
|
+
subtitle,
|
|
356
|
+
description,
|
|
357
|
+
icon,
|
|
358
|
+
iconColor,
|
|
359
|
+
iconSize,
|
|
360
|
+
actionButton,
|
|
361
|
+
children,
|
|
362
|
+
className = "",
|
|
363
|
+
...props
|
|
364
|
+
}) {
|
|
365
|
+
return /* @__PURE__ */ jsx(
|
|
366
|
+
Card,
|
|
367
|
+
{
|
|
368
|
+
title,
|
|
369
|
+
subtitle,
|
|
370
|
+
description,
|
|
371
|
+
icon,
|
|
372
|
+
iconColor,
|
|
373
|
+
iconSize,
|
|
374
|
+
actionButton,
|
|
375
|
+
className,
|
|
376
|
+
...props,
|
|
377
|
+
children
|
|
378
|
+
}
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
function StatusCard({
|
|
382
|
+
status,
|
|
383
|
+
statusIcon,
|
|
384
|
+
statusText,
|
|
385
|
+
children,
|
|
386
|
+
className = "",
|
|
387
|
+
...props
|
|
388
|
+
}) {
|
|
389
|
+
return /* @__PURE__ */ jsx(
|
|
390
|
+
Card,
|
|
391
|
+
{
|
|
392
|
+
status,
|
|
393
|
+
statusIcon,
|
|
394
|
+
statusText,
|
|
395
|
+
className,
|
|
396
|
+
...props,
|
|
397
|
+
children
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
function ClickableCard({
|
|
402
|
+
onClick,
|
|
403
|
+
children,
|
|
404
|
+
className = "",
|
|
405
|
+
...props
|
|
406
|
+
}) {
|
|
407
|
+
return /* @__PURE__ */ jsx(Card, { onClick, clickable: true, hover: true, className, ...props, children });
|
|
408
|
+
}
|
|
409
|
+
function AccordionCard({
|
|
410
|
+
accordion = true,
|
|
411
|
+
children,
|
|
412
|
+
className = "",
|
|
413
|
+
...props
|
|
414
|
+
}) {
|
|
415
|
+
return /* @__PURE__ */ jsx(Card, { accordion, className, ...props, children });
|
|
416
|
+
}
|
|
417
|
+
var variantClasses3 = {
|
|
418
|
+
default: "text-foreground hover:text-primary",
|
|
419
|
+
primary: "text-primary hover:text-primary/80",
|
|
420
|
+
muted: "text-muted-foreground hover:text-foreground"
|
|
421
|
+
};
|
|
422
|
+
var Link = forwardRef(
|
|
423
|
+
({
|
|
424
|
+
href,
|
|
425
|
+
variant = "default",
|
|
426
|
+
underline = false,
|
|
427
|
+
external = false,
|
|
428
|
+
className = "",
|
|
429
|
+
children,
|
|
430
|
+
...props
|
|
431
|
+
}, ref) => {
|
|
432
|
+
const classes = [
|
|
433
|
+
"transition-colors",
|
|
434
|
+
variantClasses3[variant],
|
|
435
|
+
underline ? "underline underline-offset-4" : "hover:underline hover:underline-offset-4",
|
|
436
|
+
className
|
|
437
|
+
].filter(Boolean).join(" ");
|
|
438
|
+
if (external || href.startsWith("http")) {
|
|
439
|
+
return /* @__PURE__ */ jsx(
|
|
440
|
+
"a",
|
|
441
|
+
{
|
|
442
|
+
ref,
|
|
443
|
+
href,
|
|
444
|
+
className: classes,
|
|
445
|
+
target: "_blank",
|
|
446
|
+
rel: "noopener noreferrer",
|
|
447
|
+
...props,
|
|
448
|
+
children
|
|
449
|
+
}
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
return /* @__PURE__ */ jsx(NextLink, { ref, href, className: classes, ...props, children });
|
|
453
|
+
}
|
|
454
|
+
);
|
|
455
|
+
Link.displayName = "Link";
|
|
456
|
+
var Link_default = Link;
|
|
457
|
+
function FormInput({
|
|
458
|
+
label,
|
|
459
|
+
name,
|
|
460
|
+
type = "text",
|
|
461
|
+
value,
|
|
462
|
+
onChange,
|
|
463
|
+
placeholder,
|
|
464
|
+
required = false,
|
|
465
|
+
disabled = false,
|
|
466
|
+
error,
|
|
467
|
+
className = "",
|
|
468
|
+
inputClassName = "",
|
|
469
|
+
min,
|
|
470
|
+
max,
|
|
471
|
+
step,
|
|
472
|
+
maxLength,
|
|
473
|
+
autoComplete,
|
|
474
|
+
description,
|
|
475
|
+
footerDescription,
|
|
476
|
+
autoFocus = false,
|
|
477
|
+
onKeyDown,
|
|
478
|
+
onBlur,
|
|
479
|
+
icon,
|
|
480
|
+
rows = 3,
|
|
481
|
+
showHidePassword = false,
|
|
482
|
+
onGeneratePassword,
|
|
483
|
+
copyable = false,
|
|
484
|
+
readOnly = false,
|
|
485
|
+
clearable = true
|
|
486
|
+
}) {
|
|
487
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
488
|
+
const [copied, setCopied] = useState(false);
|
|
489
|
+
const handleCopy = async () => {
|
|
490
|
+
try {
|
|
491
|
+
await navigator.clipboard.writeText(String(value));
|
|
492
|
+
setCopied(true);
|
|
493
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
494
|
+
} catch (err) {
|
|
495
|
+
console.error("Failed to copy:", err);
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
const shouldShowIcons = (inputType) => {
|
|
499
|
+
return inputType !== "checkbox" && inputType !== "textarea";
|
|
500
|
+
};
|
|
501
|
+
const getIconConfig = (iconProp) => {
|
|
502
|
+
if (!iconProp) return { left: null, right: null };
|
|
503
|
+
if (React4.isValidElement(iconProp)) {
|
|
504
|
+
return { left: iconProp, right: null };
|
|
505
|
+
}
|
|
506
|
+
if (typeof iconProp === "object" && iconProp !== null && ("left" in iconProp || "right" in iconProp)) {
|
|
507
|
+
return { left: iconProp.left || null, right: iconProp.right || null };
|
|
508
|
+
}
|
|
509
|
+
return {
|
|
510
|
+
left: React4.isValidElement(iconProp) ? iconProp : null,
|
|
511
|
+
right: null
|
|
512
|
+
};
|
|
513
|
+
};
|
|
514
|
+
const renderIcon = (iconNode, position) => {
|
|
515
|
+
if (!iconNode) return null;
|
|
516
|
+
const rightPositionClass = position === "right" && type === "number" ? "right-4 pr-3" : position === "right" ? "right-0 pr-3" : "left-0 pl-3";
|
|
517
|
+
return /* @__PURE__ */ jsx(
|
|
518
|
+
"div",
|
|
519
|
+
{
|
|
520
|
+
className: `absolute inset-y-0 ${rightPositionClass} flex items-center pointer-events-none`,
|
|
521
|
+
children: /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: iconNode })
|
|
522
|
+
}
|
|
523
|
+
);
|
|
524
|
+
};
|
|
525
|
+
const getInputPaddingClasses = (inputType, iconConfig) => {
|
|
526
|
+
if (!shouldShowIcons(inputType)) return "";
|
|
527
|
+
const paddingClasses2 = [];
|
|
528
|
+
if (iconConfig.left) paddingClasses2.push("pl-10");
|
|
529
|
+
if (iconConfig.right) {
|
|
530
|
+
paddingClasses2.push(inputType === "number" ? "pr-12" : "pr-10");
|
|
531
|
+
}
|
|
532
|
+
return paddingClasses2.join(" ");
|
|
533
|
+
};
|
|
534
|
+
return /* @__PURE__ */ jsx("div", { className: `form-group ${className}`, children: type === "checkbox" ? /* @__PURE__ */ jsxs("div", { className: "flex items-center p-2 space-x-3 h-full", children: [
|
|
535
|
+
/* @__PURE__ */ jsx(
|
|
536
|
+
"input",
|
|
537
|
+
{
|
|
538
|
+
id: name,
|
|
539
|
+
name,
|
|
540
|
+
type: "checkbox",
|
|
541
|
+
checked: Boolean(value),
|
|
542
|
+
onChange: (e) => {
|
|
543
|
+
const newValue = e.target.checked;
|
|
544
|
+
const syntheticEvent = {
|
|
545
|
+
target: {
|
|
546
|
+
name: e.target.name,
|
|
547
|
+
value: newValue,
|
|
548
|
+
checked: newValue
|
|
549
|
+
},
|
|
550
|
+
currentTarget: {
|
|
551
|
+
name: e.target.name,
|
|
552
|
+
value: newValue,
|
|
553
|
+
checked: newValue
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
onChange(syntheticEvent);
|
|
557
|
+
},
|
|
558
|
+
required,
|
|
559
|
+
disabled,
|
|
560
|
+
onKeyDown,
|
|
561
|
+
className: "sr-only",
|
|
562
|
+
"aria-label": label,
|
|
563
|
+
"aria-describedby": error ? `${name}-error` : description ? `${name}-description` : void 0,
|
|
564
|
+
"aria-invalid": error ? "true" : "false"
|
|
565
|
+
}
|
|
566
|
+
),
|
|
567
|
+
/* @__PURE__ */ jsx(
|
|
568
|
+
"button",
|
|
569
|
+
{
|
|
570
|
+
type: "button",
|
|
571
|
+
onClick: () => {
|
|
572
|
+
if (!disabled) {
|
|
573
|
+
const checkbox = document.getElementById(
|
|
574
|
+
name
|
|
575
|
+
);
|
|
576
|
+
if (checkbox) {
|
|
577
|
+
checkbox.click();
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
disabled,
|
|
582
|
+
className: `
|
|
583
|
+
relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2
|
|
584
|
+
${Boolean(value) ? "bg-primary" : "bg-muted"}
|
|
585
|
+
${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
|
|
586
|
+
${error ? "ring-2 ring-destructive" : ""}
|
|
587
|
+
`,
|
|
588
|
+
"aria-label": `${label}${required ? " (required)" : ""}`,
|
|
589
|
+
"aria-describedby": name,
|
|
590
|
+
children: /* @__PURE__ */ jsx(
|
|
591
|
+
"span",
|
|
592
|
+
{
|
|
593
|
+
className: `
|
|
594
|
+
inline-block h-4 w-4 transform rounded-full bg-background border border-border transition duration-200 ease-in-out
|
|
595
|
+
${Boolean(value) ? "translate-x-6" : "translate-x-1"}
|
|
596
|
+
`
|
|
597
|
+
}
|
|
598
|
+
)
|
|
599
|
+
}
|
|
600
|
+
),
|
|
601
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
602
|
+
/* @__PURE__ */ jsxs(
|
|
603
|
+
"label",
|
|
604
|
+
{
|
|
605
|
+
htmlFor: name,
|
|
606
|
+
className: "text-sm font-medium text-foreground cursor-pointer",
|
|
607
|
+
onClick: () => {
|
|
608
|
+
if (!disabled) {
|
|
609
|
+
const checkbox = document.getElementById(
|
|
610
|
+
name
|
|
611
|
+
);
|
|
612
|
+
if (checkbox) {
|
|
613
|
+
checkbox.click();
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
children: [
|
|
618
|
+
label,
|
|
619
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-1", "aria-label": "required", children: "*" })
|
|
620
|
+
]
|
|
621
|
+
}
|
|
622
|
+
),
|
|
623
|
+
description && /* @__PURE__ */ jsx(
|
|
624
|
+
"span",
|
|
625
|
+
{
|
|
626
|
+
id: `${name}-description`,
|
|
627
|
+
className: "text-xs text-muted-foreground",
|
|
628
|
+
children: description
|
|
629
|
+
}
|
|
630
|
+
)
|
|
631
|
+
] }),
|
|
632
|
+
error && /* @__PURE__ */ jsx("div", { id: `${name}-error`, className: "form-error", role: "alert", children: typeof error === "string" ? /* @__PURE__ */ jsx("p", { children: error }) : error })
|
|
633
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
634
|
+
label && /* @__PURE__ */ jsxs("label", { htmlFor: name, className: "form-label", children: [
|
|
635
|
+
label,
|
|
636
|
+
required && /* @__PURE__ */ jsx("span", { className: "form-label-required", children: "*" })
|
|
637
|
+
] }),
|
|
638
|
+
description && /* @__PURE__ */ jsx("p", { id: `${name}-description`, className: "form-description", children: description }),
|
|
639
|
+
type === "textarea" ? /* @__PURE__ */ jsx(
|
|
640
|
+
"textarea",
|
|
641
|
+
{
|
|
642
|
+
id: name,
|
|
643
|
+
name,
|
|
644
|
+
value,
|
|
645
|
+
onChange,
|
|
646
|
+
placeholder,
|
|
647
|
+
required,
|
|
648
|
+
disabled,
|
|
649
|
+
autoFocus,
|
|
650
|
+
onKeyDown,
|
|
651
|
+
onBlur,
|
|
652
|
+
rows,
|
|
653
|
+
maxLength,
|
|
654
|
+
"aria-invalid": error ? "true" : "false",
|
|
655
|
+
"aria-describedby": error ? `${name}-error` : description ? `${name}-description` : void 0,
|
|
656
|
+
className: `form-input ${error ? "form-input-error" : ""} ${inputClassName}`
|
|
657
|
+
}
|
|
658
|
+
) : type === "color" ? /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3", children: [
|
|
659
|
+
/* @__PURE__ */ jsxs("div", { className: "relative w-10 h-10 border border-input rounded-md overflow-hidden bg-card", children: [
|
|
660
|
+
/* @__PURE__ */ jsx(
|
|
661
|
+
"input",
|
|
662
|
+
{
|
|
663
|
+
id: name,
|
|
664
|
+
name,
|
|
665
|
+
type: "color",
|
|
666
|
+
value,
|
|
667
|
+
onChange,
|
|
668
|
+
required,
|
|
669
|
+
disabled,
|
|
670
|
+
className: "absolute inset-0 w-full h-full cursor-pointer opacity-0"
|
|
671
|
+
}
|
|
672
|
+
),
|
|
673
|
+
/* @__PURE__ */ jsx(
|
|
674
|
+
"div",
|
|
675
|
+
{
|
|
676
|
+
className: "w-full h-full rounded-md",
|
|
677
|
+
style: { backgroundColor: value }
|
|
678
|
+
}
|
|
679
|
+
)
|
|
680
|
+
] }),
|
|
681
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
682
|
+
/* @__PURE__ */ jsx(
|
|
683
|
+
"input",
|
|
684
|
+
{
|
|
685
|
+
id: `${name}-text`,
|
|
686
|
+
name: `${name}-text`,
|
|
687
|
+
type: "text",
|
|
688
|
+
value,
|
|
689
|
+
onChange,
|
|
690
|
+
placeholder,
|
|
691
|
+
required,
|
|
692
|
+
disabled,
|
|
693
|
+
maxLength,
|
|
694
|
+
autoComplete,
|
|
695
|
+
autoFocus,
|
|
696
|
+
onKeyDown,
|
|
697
|
+
onBlur,
|
|
698
|
+
className: `form-input max-w-24 ${error ? "form-input-error" : ""} ${getInputPaddingClasses(type, getIconConfig(icon))} ${inputClassName}`,
|
|
699
|
+
"aria-label": `${label} text input`
|
|
700
|
+
}
|
|
701
|
+
),
|
|
702
|
+
shouldShowIcons(type) && (() => {
|
|
703
|
+
const iconConfig = getIconConfig(icon);
|
|
704
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
705
|
+
renderIcon(iconConfig.left, "left"),
|
|
706
|
+
renderIcon(iconConfig.right, "right")
|
|
707
|
+
] });
|
|
708
|
+
})()
|
|
709
|
+
] })
|
|
710
|
+
] }) : showHidePassword && type === "password" ? /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
711
|
+
/* @__PURE__ */ jsx(
|
|
712
|
+
"input",
|
|
713
|
+
{
|
|
714
|
+
id: name,
|
|
715
|
+
name,
|
|
716
|
+
type: showPassword ? "text" : "password",
|
|
717
|
+
value,
|
|
718
|
+
onChange,
|
|
719
|
+
placeholder,
|
|
720
|
+
required,
|
|
721
|
+
disabled: disabled || readOnly,
|
|
722
|
+
readOnly,
|
|
723
|
+
maxLength,
|
|
724
|
+
autoComplete,
|
|
725
|
+
autoFocus,
|
|
726
|
+
onKeyDown,
|
|
727
|
+
onBlur,
|
|
728
|
+
"aria-invalid": error ? "true" : "false",
|
|
729
|
+
"aria-describedby": error ? `${name}-error` : description ? `${name}-description` : void 0,
|
|
730
|
+
className: `form-input ${error ? "form-input-error" : ""} ${readOnly ? "bg-muted cursor-default" : ""} ${copyable ? "pr-20" : "pr-10"} ${getInputPaddingClasses(type, getIconConfig(icon))} ${inputClassName}`
|
|
731
|
+
}
|
|
732
|
+
),
|
|
733
|
+
shouldShowIcons(type) && (() => {
|
|
734
|
+
const iconConfig = getIconConfig(icon);
|
|
735
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
736
|
+
renderIcon(iconConfig.left, "left"),
|
|
737
|
+
renderIcon(iconConfig.right, "right")
|
|
738
|
+
] });
|
|
739
|
+
})(),
|
|
740
|
+
copyable && /* @__PURE__ */ jsx(
|
|
741
|
+
"button",
|
|
742
|
+
{
|
|
743
|
+
type: "button",
|
|
744
|
+
onClick: handleCopy,
|
|
745
|
+
className: "absolute inset-y-0 right-8 flex items-center pr-3 text-muted-foreground hover:text-foreground transition-colors duration-200 z-10",
|
|
746
|
+
"aria-label": `Copy ${label}`,
|
|
747
|
+
title: copied ? "Copied!" : `Copy ${label}`,
|
|
748
|
+
children: copied ? /* @__PURE__ */ jsx(RiCheckLine, { className: "w-4 h-4 text-green-500", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(RiFileCopyLine, { className: "w-4 h-4", "aria-hidden": "true" })
|
|
749
|
+
}
|
|
750
|
+
),
|
|
751
|
+
/* @__PURE__ */ jsx(
|
|
752
|
+
"button",
|
|
753
|
+
{
|
|
754
|
+
type: "button",
|
|
755
|
+
onClick: () => setShowPassword(!showPassword),
|
|
756
|
+
className: "absolute inset-y-0 right-0 flex items-center pr-3 text-muted-foreground hover:text-foreground transition-colors duration-200 z-10",
|
|
757
|
+
"aria-label": showPassword ? "Hide password" : "Show password",
|
|
758
|
+
title: showPassword ? "Hide password" : "Show password",
|
|
759
|
+
children: showPassword ? /* @__PURE__ */ jsx(RiEyeOffLine, { className: "w-4 h-4", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(RiEyeLine, { className: "w-4 h-4", "aria-hidden": "true" })
|
|
760
|
+
}
|
|
761
|
+
),
|
|
762
|
+
onGeneratePassword && !readOnly && /* @__PURE__ */ jsx(
|
|
763
|
+
"button",
|
|
764
|
+
{
|
|
765
|
+
type: "button",
|
|
766
|
+
onClick: onGeneratePassword,
|
|
767
|
+
className: `absolute inset-y-0 ${copyable ? "right-16" : "right-8"} flex items-center pr-3 text-muted-foreground hover:text-foreground transition-colors duration-200 z-10`,
|
|
768
|
+
"aria-label": "Generate new password",
|
|
769
|
+
title: "Generate new password",
|
|
770
|
+
children: /* @__PURE__ */ jsx(RiRefreshLine, { className: "w-4 h-4", "aria-hidden": "true" })
|
|
771
|
+
}
|
|
772
|
+
)
|
|
773
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "relative group", children: [
|
|
774
|
+
/* @__PURE__ */ jsx(
|
|
775
|
+
"input",
|
|
776
|
+
{
|
|
777
|
+
id: name,
|
|
778
|
+
name,
|
|
779
|
+
type,
|
|
780
|
+
value,
|
|
781
|
+
onChange,
|
|
782
|
+
placeholder,
|
|
783
|
+
required,
|
|
784
|
+
disabled: disabled || readOnly,
|
|
785
|
+
readOnly,
|
|
786
|
+
min,
|
|
787
|
+
max,
|
|
788
|
+
step,
|
|
789
|
+
maxLength,
|
|
790
|
+
autoComplete,
|
|
791
|
+
autoFocus,
|
|
792
|
+
onKeyDown,
|
|
793
|
+
onBlur,
|
|
794
|
+
"aria-invalid": error ? "true" : "false",
|
|
795
|
+
"aria-describedby": error ? `${name}-error` : description ? `${name}-description` : void 0,
|
|
796
|
+
className: `form-input ${error ? "form-input-error" : ""} ${readOnly ? "bg-muted cursor-default" : ""} ${copyable ? "pr-10" : ""} ${getInputPaddingClasses(type, getIconConfig(icon))} ${inputClassName}`
|
|
797
|
+
}
|
|
798
|
+
),
|
|
799
|
+
shouldShowIcons(type) && (() => {
|
|
800
|
+
const iconConfig = getIconConfig(icon);
|
|
801
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
802
|
+
renderIcon(iconConfig.left, "left"),
|
|
803
|
+
renderIcon(iconConfig.right, "right")
|
|
804
|
+
] });
|
|
805
|
+
})(),
|
|
806
|
+
copyable && /* @__PURE__ */ jsx(
|
|
807
|
+
"button",
|
|
808
|
+
{
|
|
809
|
+
type: "button",
|
|
810
|
+
onClick: handleCopy,
|
|
811
|
+
className: `absolute inset-y-0 right-0 flex items-center pr-3 text-muted-foreground hover:text-foreground transition-all duration-200 z-10`,
|
|
812
|
+
"aria-label": `Copy ${label}`,
|
|
813
|
+
title: copied ? "Copied!" : `Copy ${label}`,
|
|
814
|
+
children: copied ? /* @__PURE__ */ jsx(RiCheckLine, { className: "w-4 h-4 text-green-500", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(RiFileCopyLine, { className: "w-4 h-4", "aria-hidden": "true" })
|
|
815
|
+
}
|
|
816
|
+
),
|
|
817
|
+
clearable && !copyable && value !== "" && value !== null && value !== void 0 && !disabled && !readOnly && /* @__PURE__ */ jsx(
|
|
818
|
+
"button",
|
|
819
|
+
{
|
|
820
|
+
type: "button",
|
|
821
|
+
onClick: () => {
|
|
822
|
+
const syntheticEvent = {
|
|
823
|
+
target: { name, value: "" }
|
|
824
|
+
};
|
|
825
|
+
onChange(syntheticEvent);
|
|
826
|
+
},
|
|
827
|
+
className: `absolute inset-y-0 ${type === "number" ? "right-4" : "right-0"} flex items-center pr-3 text-muted-foreground hover:text-muted-foreground transition-all duration-200 z-10 opacity-0 group-hover:opacity-100`,
|
|
828
|
+
"aria-label": `Clear ${label}`,
|
|
829
|
+
title: `Clear ${label}`,
|
|
830
|
+
children: /* @__PURE__ */ jsx(RiCloseLine, { className: "w-4 h-4", "aria-hidden": "true" })
|
|
831
|
+
}
|
|
832
|
+
)
|
|
833
|
+
] }),
|
|
834
|
+
footerDescription && /* @__PURE__ */ jsx("p", { className: "text-xs mt-1", children: footerDescription }),
|
|
835
|
+
error && /* @__PURE__ */ jsx("div", { id: `${name}-error`, className: "form-error", role: "alert", children: typeof error === "string" ? /* @__PURE__ */ jsx("p", { children: error }) : error })
|
|
836
|
+
] }) });
|
|
837
|
+
}
|
|
838
|
+
function Switch({
|
|
839
|
+
checked,
|
|
840
|
+
onChange,
|
|
841
|
+
disabled = false,
|
|
842
|
+
label,
|
|
843
|
+
description,
|
|
844
|
+
className = "",
|
|
845
|
+
size = "md"
|
|
846
|
+
}) {
|
|
847
|
+
const toggle = () => {
|
|
848
|
+
if (!disabled) {
|
|
849
|
+
onChange(!checked);
|
|
850
|
+
}
|
|
851
|
+
};
|
|
852
|
+
const sizes = {
|
|
853
|
+
sm: { track: "w-8 h-4", thumb: "w-3 h-3", translate: "translate-x-4" },
|
|
854
|
+
md: { track: "w-11 h-6", thumb: "w-5 h-5", translate: "translate-x-5" },
|
|
855
|
+
lg: { track: "w-14 h-8", thumb: "w-7 h-7", translate: "translate-x-6" }
|
|
856
|
+
};
|
|
857
|
+
const currentSize = sizes[size];
|
|
858
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex items-start ${className}`, children: [
|
|
859
|
+
/* @__PURE__ */ jsx(
|
|
860
|
+
"button",
|
|
861
|
+
{
|
|
862
|
+
type: "button",
|
|
863
|
+
role: "switch",
|
|
864
|
+
"aria-checked": checked,
|
|
865
|
+
disabled,
|
|
866
|
+
onClick: toggle,
|
|
867
|
+
className: `
|
|
868
|
+
relative inline-flex flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent
|
|
869
|
+
transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2
|
|
870
|
+
${checked ? "bg-primary" : "bg-muted"}
|
|
871
|
+
${disabled ? "opacity-50 cursor-not-allowed" : ""}
|
|
872
|
+
${currentSize.track}
|
|
873
|
+
`,
|
|
874
|
+
children: /* @__PURE__ */ jsx(
|
|
875
|
+
"span",
|
|
876
|
+
{
|
|
877
|
+
"aria-hidden": "true",
|
|
878
|
+
className: `
|
|
879
|
+
pointer-events-none inline-block transform rounded-full bg-white shadow ring-0
|
|
880
|
+
transition duration-200 ease-in-out
|
|
881
|
+
${checked ? currentSize.translate : "translate-x-0"}
|
|
882
|
+
${currentSize.thumb}
|
|
883
|
+
`
|
|
884
|
+
}
|
|
885
|
+
)
|
|
886
|
+
}
|
|
887
|
+
),
|
|
888
|
+
(label || description) && /* @__PURE__ */ jsxs("div", { className: "ml-3 text-sm leading-6", children: [
|
|
889
|
+
label && /* @__PURE__ */ jsx("label", { className: "font-medium text-foreground cursor-pointer", onClick: toggle, children: label }),
|
|
890
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: description })
|
|
891
|
+
] })
|
|
892
|
+
] });
|
|
893
|
+
}
|
|
894
|
+
var sizeClasses3 = {
|
|
895
|
+
sm: "max-w-md",
|
|
896
|
+
md: "max-w-2xl",
|
|
897
|
+
lg: "max-w-4xl",
|
|
898
|
+
xl: "max-w-6xl",
|
|
899
|
+
full: "max-w-full mx-4"
|
|
900
|
+
};
|
|
901
|
+
function Modal({
|
|
902
|
+
isOpen,
|
|
903
|
+
onClose,
|
|
904
|
+
children,
|
|
905
|
+
title,
|
|
906
|
+
header,
|
|
907
|
+
blocking = false,
|
|
908
|
+
size = "md",
|
|
909
|
+
className = "",
|
|
910
|
+
footer,
|
|
911
|
+
fullScreen = false,
|
|
912
|
+
noPadding = false,
|
|
913
|
+
footerBg = "gray",
|
|
914
|
+
variant = "default",
|
|
915
|
+
scrollable = true,
|
|
916
|
+
"aria-describedby": ariaDescribedBy,
|
|
917
|
+
customStyles = {}
|
|
918
|
+
}) {
|
|
919
|
+
const modalContentRef = useRef(null);
|
|
920
|
+
const previousActiveElementRef = useRef(null);
|
|
921
|
+
const hasPerformedInitialFocusRef = useRef(false);
|
|
922
|
+
const getFocusableElements = () => {
|
|
923
|
+
if (!modalContentRef.current) return [];
|
|
924
|
+
const focusableSelectors = [
|
|
925
|
+
"button:not([disabled])",
|
|
926
|
+
"a[href]",
|
|
927
|
+
"input:not([disabled])",
|
|
928
|
+
"select:not([disabled])",
|
|
929
|
+
"textarea:not([disabled])",
|
|
930
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
931
|
+
].join(", ");
|
|
932
|
+
return Array.from(
|
|
933
|
+
modalContentRef.current.querySelectorAll(focusableSelectors)
|
|
934
|
+
);
|
|
935
|
+
};
|
|
936
|
+
useEffect(() => {
|
|
937
|
+
if (!isOpen) {
|
|
938
|
+
hasPerformedInitialFocusRef.current = false;
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
if (!hasPerformedInitialFocusRef.current) {
|
|
942
|
+
previousActiveElementRef.current = document.activeElement;
|
|
943
|
+
}
|
|
944
|
+
let timeoutId = null;
|
|
945
|
+
if (!hasPerformedInitialFocusRef.current) {
|
|
946
|
+
const focusableElements = getFocusableElements();
|
|
947
|
+
const firstFocusable = focusableElements[0];
|
|
948
|
+
timeoutId = setTimeout(() => {
|
|
949
|
+
const activeElement = document.activeElement;
|
|
950
|
+
const isHTMLElement = activeElement instanceof HTMLElement;
|
|
951
|
+
const isUserTyping = activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || isHTMLElement && activeElement.isContentEditable);
|
|
952
|
+
const isFocusInModal = modalContentRef.current?.contains(activeElement);
|
|
953
|
+
if (!isUserTyping && !isFocusInModal) {
|
|
954
|
+
if (firstFocusable) {
|
|
955
|
+
firstFocusable.focus();
|
|
956
|
+
hasPerformedInitialFocusRef.current = true;
|
|
957
|
+
} else if (modalContentRef.current) {
|
|
958
|
+
modalContentRef.current.focus();
|
|
959
|
+
hasPerformedInitialFocusRef.current = true;
|
|
960
|
+
}
|
|
961
|
+
} else if (isFocusInModal) {
|
|
962
|
+
hasPerformedInitialFocusRef.current = true;
|
|
963
|
+
}
|
|
964
|
+
}, 100);
|
|
965
|
+
}
|
|
966
|
+
const handleTab = (event) => {
|
|
967
|
+
if (event.key !== "Tab") return;
|
|
968
|
+
const focusableElements = getFocusableElements();
|
|
969
|
+
if (focusableElements.length === 0) return;
|
|
970
|
+
const firstElement = focusableElements[0];
|
|
971
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
972
|
+
if (event.shiftKey) {
|
|
973
|
+
if (document.activeElement === firstElement) {
|
|
974
|
+
event.preventDefault();
|
|
975
|
+
lastElement.focus();
|
|
976
|
+
}
|
|
977
|
+
} else {
|
|
978
|
+
if (document.activeElement === lastElement) {
|
|
979
|
+
event.preventDefault();
|
|
980
|
+
firstElement.focus();
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
const handleEsc = (event) => {
|
|
985
|
+
if (event.key === "Escape" && !blocking) {
|
|
986
|
+
onClose();
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
document.addEventListener("keydown", handleTab);
|
|
990
|
+
document.addEventListener("keydown", handleEsc);
|
|
991
|
+
document.body.style.overflow = "hidden";
|
|
992
|
+
return () => {
|
|
993
|
+
if (timeoutId) {
|
|
994
|
+
clearTimeout(timeoutId);
|
|
995
|
+
}
|
|
996
|
+
document.removeEventListener("keydown", handleTab);
|
|
997
|
+
document.removeEventListener("keydown", handleEsc);
|
|
998
|
+
document.body.style.overflow = "unset";
|
|
999
|
+
if (!isOpen && previousActiveElementRef.current) {
|
|
1000
|
+
previousActiveElementRef.current.focus();
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
}, [isOpen, onClose, blocking]);
|
|
1004
|
+
const modalRoot = (() => {
|
|
1005
|
+
if (typeof document === "undefined") return null;
|
|
1006
|
+
let root = document.getElementById("modal-root");
|
|
1007
|
+
if (!root) {
|
|
1008
|
+
root = document.createElement("div");
|
|
1009
|
+
root.id = "modal-root";
|
|
1010
|
+
document.body.appendChild(root);
|
|
1011
|
+
}
|
|
1012
|
+
return root;
|
|
1013
|
+
})();
|
|
1014
|
+
if (!modalRoot) {
|
|
1015
|
+
return null;
|
|
1016
|
+
}
|
|
1017
|
+
const backdropVariants = {
|
|
1018
|
+
hidden: { opacity: 0 },
|
|
1019
|
+
visible: { opacity: 1 }
|
|
1020
|
+
};
|
|
1021
|
+
const modalVariants = {
|
|
1022
|
+
hidden: {
|
|
1023
|
+
opacity: 0,
|
|
1024
|
+
scale: 0.95,
|
|
1025
|
+
y: 20
|
|
1026
|
+
},
|
|
1027
|
+
visible: {
|
|
1028
|
+
opacity: 1,
|
|
1029
|
+
scale: 1,
|
|
1030
|
+
y: 0,
|
|
1031
|
+
transition: {
|
|
1032
|
+
duration: 0.2,
|
|
1033
|
+
ease: "easeOut"
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
exit: {
|
|
1037
|
+
opacity: 0,
|
|
1038
|
+
scale: 0.9,
|
|
1039
|
+
y: 100,
|
|
1040
|
+
// Slide down much further for reverse effect
|
|
1041
|
+
transition: {
|
|
1042
|
+
duration: 0.3,
|
|
1043
|
+
ease: "easeIn"
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
if (!isOpen) return null;
|
|
1048
|
+
if (variant === "plain") {
|
|
1049
|
+
return createPortal(
|
|
1050
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsx(
|
|
1051
|
+
motion.div,
|
|
1052
|
+
{
|
|
1053
|
+
className: `modal-backdrop fixed inset-0 w-screen h-screen flex items-center ${customStyles.backdrop?.includes("justify-") ? customStyles.backdrop : customStyles.backdrop ? `${customStyles.backdrop} justify-center` : "justify-center bg-black/10"} z-[999999] m-0 ${fullScreen ? "p-0" : "p-4"}`,
|
|
1054
|
+
variants: backdropVariants,
|
|
1055
|
+
initial: "hidden",
|
|
1056
|
+
animate: isOpen ? "visible" : "hidden",
|
|
1057
|
+
exit: "hidden",
|
|
1058
|
+
onClick: blocking ? void 0 : onClose,
|
|
1059
|
+
children: /* @__PURE__ */ jsx(
|
|
1060
|
+
motion.div,
|
|
1061
|
+
{
|
|
1062
|
+
ref: modalContentRef,
|
|
1063
|
+
role: "dialog",
|
|
1064
|
+
"aria-modal": "true",
|
|
1065
|
+
"aria-labelledby": title ? "modal-title-plain" : void 0,
|
|
1066
|
+
"aria-describedby": ariaDescribedBy || "modal-content-plain",
|
|
1067
|
+
tabIndex: -1,
|
|
1068
|
+
className: `w-full flex flex-col overflow-hidden relative z-[1000000] ${customStyles.container || "bg-card shadow-xl"} ${fullScreen ? "h-full rounded-none" : `rounded-lg ${className} ${sizeClasses3[size]} max-h-[90vh]`}`,
|
|
1069
|
+
variants: modalVariants,
|
|
1070
|
+
initial: "hidden",
|
|
1071
|
+
animate: isOpen ? "visible" : "exit",
|
|
1072
|
+
exit: "exit",
|
|
1073
|
+
onClick: (e) => e.stopPropagation(),
|
|
1074
|
+
children: /* @__PURE__ */ jsx(
|
|
1075
|
+
"div",
|
|
1076
|
+
{
|
|
1077
|
+
id: "modal-content-plain",
|
|
1078
|
+
className: `flex-1 ${customStyles.content || ""}`,
|
|
1079
|
+
children
|
|
1080
|
+
}
|
|
1081
|
+
)
|
|
1082
|
+
},
|
|
1083
|
+
"modal-content"
|
|
1084
|
+
)
|
|
1085
|
+
},
|
|
1086
|
+
"modal-backdrop"
|
|
1087
|
+
) }),
|
|
1088
|
+
modalRoot
|
|
1089
|
+
);
|
|
1090
|
+
}
|
|
1091
|
+
return createPortal(
|
|
1092
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsx(
|
|
1093
|
+
motion.div,
|
|
1094
|
+
{
|
|
1095
|
+
className: `modal-backdrop fixed inset-0 w-screen h-screen bg-black/10 flex items-center ${customStyles.backdrop || "justify-center"} z-[999999] m-0 ${fullScreen ? "p-0" : "p-4"}`,
|
|
1096
|
+
variants: backdropVariants,
|
|
1097
|
+
initial: "hidden",
|
|
1098
|
+
animate: isOpen ? "visible" : "hidden",
|
|
1099
|
+
exit: "hidden",
|
|
1100
|
+
onClick: blocking ? void 0 : onClose,
|
|
1101
|
+
children: /* @__PURE__ */ jsxs(
|
|
1102
|
+
motion.div,
|
|
1103
|
+
{
|
|
1104
|
+
ref: modalContentRef,
|
|
1105
|
+
role: "dialog",
|
|
1106
|
+
"aria-modal": "true",
|
|
1107
|
+
"aria-labelledby": title ? "modal-title" : void 0,
|
|
1108
|
+
"aria-describedby": ariaDescribedBy || "modal-content",
|
|
1109
|
+
tabIndex: -1,
|
|
1110
|
+
className: `bg-card border border-border shadow-xl w-full flex flex-col overflow-hidden relative z-[1000000] ${fullScreen ? "h-full rounded-none" : `rounded-lg ${customStyles.container || className || sizeClasses3[size]} max-h-[90vh]`}`,
|
|
1111
|
+
variants: modalVariants,
|
|
1112
|
+
initial: "hidden",
|
|
1113
|
+
animate: isOpen ? "visible" : "exit",
|
|
1114
|
+
exit: "exit",
|
|
1115
|
+
onClick: (e) => e.stopPropagation(),
|
|
1116
|
+
children: [
|
|
1117
|
+
header ? /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: header }) : title ? /* @__PURE__ */ jsxs(
|
|
1118
|
+
"div",
|
|
1119
|
+
{
|
|
1120
|
+
className: `px-6 py-4 border-b border-border flex justify-between items-center flex-shrink-0 ${customStyles.header || ""}`,
|
|
1121
|
+
children: [
|
|
1122
|
+
/* @__PURE__ */ jsx(
|
|
1123
|
+
"h2",
|
|
1124
|
+
{
|
|
1125
|
+
id: "modal-title",
|
|
1126
|
+
className: "text-xl font-semibold text-foreground",
|
|
1127
|
+
children: title
|
|
1128
|
+
}
|
|
1129
|
+
),
|
|
1130
|
+
/* @__PURE__ */ jsx(
|
|
1131
|
+
"button",
|
|
1132
|
+
{
|
|
1133
|
+
onClick: onClose,
|
|
1134
|
+
className: "p-2 text-muted-foreground hover:text-foreground hover:bg-muted rounded-full transition-colors",
|
|
1135
|
+
title: "Close",
|
|
1136
|
+
"aria-label": "Close modal",
|
|
1137
|
+
disabled: blocking,
|
|
1138
|
+
children: /* @__PURE__ */ jsx(RiCloseLine, { className: "w-5 h-5", "aria-hidden": "true" })
|
|
1139
|
+
}
|
|
1140
|
+
)
|
|
1141
|
+
]
|
|
1142
|
+
}
|
|
1143
|
+
) : null,
|
|
1144
|
+
/* @__PURE__ */ jsx(
|
|
1145
|
+
"div",
|
|
1146
|
+
{
|
|
1147
|
+
id: "modal-content",
|
|
1148
|
+
className: `bg-background text-foreground flex-1 ${scrollable ? "overflow-y-auto" : ""} ${fullScreen || noPadding ? "p-0" : "px-6 py-4"}`,
|
|
1149
|
+
children
|
|
1150
|
+
}
|
|
1151
|
+
),
|
|
1152
|
+
footer && /* @__PURE__ */ jsx(
|
|
1153
|
+
"div",
|
|
1154
|
+
{
|
|
1155
|
+
className: `flex-shrink-0 px-6 py-4 border-t border-border ${footerBg === "white" ? "bg-card" : "bg-muted"} ${customStyles.footer || ""}`,
|
|
1156
|
+
children: footer
|
|
1157
|
+
}
|
|
1158
|
+
)
|
|
1159
|
+
]
|
|
1160
|
+
},
|
|
1161
|
+
"modal-content"
|
|
1162
|
+
)
|
|
1163
|
+
},
|
|
1164
|
+
"modal-backdrop"
|
|
1165
|
+
) }),
|
|
1166
|
+
modalRoot
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1169
|
+
var LoadingSpinner = ({
|
|
1170
|
+
message = "Initializing...",
|
|
1171
|
+
className,
|
|
1172
|
+
showMessage = false
|
|
1173
|
+
}) => {
|
|
1174
|
+
const containerClasses = className !== void 0 ? className : "flex items-center justify-center h-screen min-h-screen";
|
|
1175
|
+
return /* @__PURE__ */ jsx(
|
|
1176
|
+
"div",
|
|
1177
|
+
{
|
|
1178
|
+
className: containerClasses,
|
|
1179
|
+
role: "status",
|
|
1180
|
+
"aria-live": "polite",
|
|
1181
|
+
"aria-label": message,
|
|
1182
|
+
children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
1183
|
+
/* @__PURE__ */ jsxs(
|
|
1184
|
+
"div",
|
|
1185
|
+
{
|
|
1186
|
+
className: "flex items-center justify-center space-x-2 mb-6",
|
|
1187
|
+
"aria-hidden": "true",
|
|
1188
|
+
children: [
|
|
1189
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-12 bg-gradient-to-t from-primary-600 to-primary-400 rounded-full shadow-sm [animation:wave_1.2s_ease-in-out_infinite] [animation-delay:0s]" }),
|
|
1190
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-8 bg-gradient-to-t from-primary-600 to-primary-400 rounded-full shadow-sm [animation:wave_1.2s_ease-in-out_infinite] [animation-delay:0.2s]" }),
|
|
1191
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-8 bg-gradient-to-t from-primary-600 to-primary-400 rounded-full shadow-sm [animation:wave_1.2s_ease-in-out_infinite] [animation-delay:0.4s]" }),
|
|
1192
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-12 bg-gradient-to-t from-primary-600 to-primary-400 rounded-full shadow-sm [animation:wave_1.2s_ease-in-out_infinite] [animation-delay:0.6s]" })
|
|
1193
|
+
]
|
|
1194
|
+
}
|
|
1195
|
+
),
|
|
1196
|
+
showMessage && /* @__PURE__ */ jsx("div", { className: "space-y-2", children: /* @__PURE__ */ jsx(
|
|
1197
|
+
"p",
|
|
1198
|
+
{
|
|
1199
|
+
className: "text-sm text-secondary-foreground animate-pulse",
|
|
1200
|
+
"aria-live": "polite",
|
|
1201
|
+
children: message
|
|
1202
|
+
}
|
|
1203
|
+
) })
|
|
1204
|
+
] })
|
|
1205
|
+
}
|
|
1206
|
+
);
|
|
1207
|
+
};
|
|
1208
|
+
var LoadingSpinner_default = LoadingSpinner;
|
|
1209
|
+
function PageHeader({
|
|
1210
|
+
icon: Icon,
|
|
1211
|
+
title,
|
|
1212
|
+
subtitle,
|
|
1213
|
+
rightContent,
|
|
1214
|
+
className = ""
|
|
1215
|
+
}) {
|
|
1216
|
+
return /* @__PURE__ */ jsx("div", { className: `mb-6 lg:mb-8 ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "header-layout", children: [
|
|
1217
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3", children: [
|
|
1218
|
+
Icon && /* @__PURE__ */ jsx(Icon, { className: "w-6 h-6 lg:w-8 lg:h-8 flex-shrink-0" }),
|
|
1219
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1220
|
+
/* @__PURE__ */ jsx("h1", { className: "text-xl lg:text-3xl font-bold text-foreground truncate", children: title }),
|
|
1221
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm lg:text-base text-muted-foreground", children: subtitle })
|
|
1222
|
+
] })
|
|
1223
|
+
] }),
|
|
1224
|
+
rightContent && /* @__PURE__ */ jsx("div", { className: "flex items-center space-x-2 lg:space-x-3 flex-shrink-0", children: rightContent })
|
|
1225
|
+
] }) });
|
|
1226
|
+
}
|
|
1227
|
+
function FormSection({
|
|
1228
|
+
title,
|
|
1229
|
+
description,
|
|
1230
|
+
children,
|
|
1231
|
+
className = ""
|
|
1232
|
+
}) {
|
|
1233
|
+
return /* @__PURE__ */ jsxs("div", { className: `space-y-4 ${className}`, children: [
|
|
1234
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1235
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-medium ", children: title }),
|
|
1236
|
+
description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
|
|
1237
|
+
] }),
|
|
1238
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-4", children })
|
|
1239
|
+
] });
|
|
1240
|
+
}
|
|
1241
|
+
function Grid({
|
|
1242
|
+
children,
|
|
1243
|
+
cols = 1,
|
|
1244
|
+
gap = 4,
|
|
1245
|
+
className = ""
|
|
1246
|
+
}) {
|
|
1247
|
+
const colClasses = {
|
|
1248
|
+
1: "grid-cols-1",
|
|
1249
|
+
2: "grid-cols-1 md:grid-cols-2",
|
|
1250
|
+
3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
|
|
1251
|
+
4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
|
|
1252
|
+
5: "grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5",
|
|
1253
|
+
6: "grid-cols-2 md:grid-cols-3 lg:grid-cols-6",
|
|
1254
|
+
12: "grid-cols-12"
|
|
1255
|
+
};
|
|
1256
|
+
const gapClasses = {
|
|
1257
|
+
1: "gap-1",
|
|
1258
|
+
2: "gap-2",
|
|
1259
|
+
3: "gap-3",
|
|
1260
|
+
4: "gap-4",
|
|
1261
|
+
6: "gap-6",
|
|
1262
|
+
8: "gap-8"
|
|
1263
|
+
};
|
|
1264
|
+
return /* @__PURE__ */ jsx("div", { className: `grid ${colClasses[cols]} ${gapClasses[gap]} ${className}`, children });
|
|
1265
|
+
}
|
|
1266
|
+
function GridItem({
|
|
1267
|
+
children,
|
|
1268
|
+
span = 1,
|
|
1269
|
+
className = ""
|
|
1270
|
+
}) {
|
|
1271
|
+
return /* @__PURE__ */ jsx("div", { className: `col-span-${span} ${className}`, children });
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
export { AccordionCard, Badge, Button_default as Button, Card, ClickableCard, ErrorBadge, FormInput, FormSection, GrayBadge, Grid, GridItem, HeaderCard, InfoBadge, Link_default as Link, LoadingSpinner_default as LoadingSpinner, Modal, PageHeader, PrimaryBadge, SimpleCard, StatusBadge, StatusCard, SuccessBadge, Switch, WarningBadge };
|
|
1275
|
+
//# sourceMappingURL=index.mjs.map
|
|
1276
|
+
//# sourceMappingURL=index.mjs.map
|