alope-ui 1.2.8 → 1.2.10
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 +7522 -7522
- package/dist/main.cjs +117 -769
- package/dist/main.d.ts +0 -1
- package/dist/main.js +3215 -0
- package/package.json +88 -80
- package/dist/components/Popover/Popover.d.ts +0 -14
- /package/dist/{index.css → style.css} +0 -0
package/dist/main.js
ADDED
|
@@ -0,0 +1,3215 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState, isValidElement, cloneElement, useRef, useLayoutEffect, useEffect, Children, createContext, useContext } from "react";
|
|
3
|
+
import { cn } from "clsx-for-tailwind";
|
|
4
|
+
import { Link } from "react-router-dom";
|
|
5
|
+
import Select from "react-select";
|
|
6
|
+
const Accordion = ({
|
|
7
|
+
data,
|
|
8
|
+
openIndex,
|
|
9
|
+
single = true,
|
|
10
|
+
onToggleItem,
|
|
11
|
+
icon,
|
|
12
|
+
className,
|
|
13
|
+
labelClassName,
|
|
14
|
+
labelContainerClassName,
|
|
15
|
+
descriptionClassName,
|
|
16
|
+
...props
|
|
17
|
+
}) => {
|
|
18
|
+
const isControlled = openIndex !== void 0 && onToggleItem !== void 0;
|
|
19
|
+
const [internalOpen, setInternalOpen] = useState([]);
|
|
20
|
+
const activeIndexes = isControlled ? Array.isArray(openIndex) ? openIndex : openIndex != null ? [openIndex] : [] : internalOpen;
|
|
21
|
+
const toggle = (index) => {
|
|
22
|
+
const isActive = activeIndexes.includes(index);
|
|
23
|
+
const updated = single ? isActive ? [] : [index] : isActive ? activeIndexes.filter((i) => i !== index) : [...activeIndexes, index];
|
|
24
|
+
isControlled ? onToggleItem?.(single ? updated[0] ?? null : updated) : setInternalOpen(updated);
|
|
25
|
+
};
|
|
26
|
+
return /* @__PURE__ */ jsx("div", { className: cn("space-y-2", className), ...props, children: data.map((item, i) => {
|
|
27
|
+
const isOpen = activeIndexes.includes(i);
|
|
28
|
+
return /* @__PURE__ */ jsxs(
|
|
29
|
+
"div",
|
|
30
|
+
{
|
|
31
|
+
className: cn("border border-gray-300 dark:border-white/20 rounded-md overflow-hidden", labelContainerClassName),
|
|
32
|
+
children: [
|
|
33
|
+
/* @__PURE__ */ jsxs(
|
|
34
|
+
"button",
|
|
35
|
+
{
|
|
36
|
+
onClick: () => toggle(i),
|
|
37
|
+
className: "w-full flex justify-between items-center p-4 text-left dark:text-white",
|
|
38
|
+
children: [
|
|
39
|
+
/* @__PURE__ */ jsx("span", { className: cn("font-semibold", labelClassName), children: item.label }),
|
|
40
|
+
typeof icon === "function" ? icon(isOpen) : icon ?? /* @__PURE__ */ jsx(
|
|
41
|
+
"svg",
|
|
42
|
+
{
|
|
43
|
+
className: cn("w-5 h-5 transition-transform", isOpen && "rotate-180"),
|
|
44
|
+
viewBox: "0 0 24 24",
|
|
45
|
+
fill: "none",
|
|
46
|
+
stroke: "currentColor",
|
|
47
|
+
children: /* @__PURE__ */ jsx(
|
|
48
|
+
"path",
|
|
49
|
+
{
|
|
50
|
+
d: "M19 9l-7 7-7-7",
|
|
51
|
+
strokeWidth: "2",
|
|
52
|
+
strokeLinecap: "round",
|
|
53
|
+
strokeLinejoin: "round"
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
className: cn(
|
|
65
|
+
"overflow-hidden bg-gray-50 px-4 transition-all dark:bg-gray-700 dark:text-white",
|
|
66
|
+
isOpen ? "max-h-40 py-4" : "max-h-0",
|
|
67
|
+
descriptionClassName
|
|
68
|
+
),
|
|
69
|
+
children: item.description
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
i
|
|
75
|
+
);
|
|
76
|
+
}) });
|
|
77
|
+
};
|
|
78
|
+
const AlertVariants = {
|
|
79
|
+
outline: "outline-1",
|
|
80
|
+
solid: ""
|
|
81
|
+
};
|
|
82
|
+
const IconColors = {
|
|
83
|
+
success: "fill-success-700 dark:fill-success",
|
|
84
|
+
info: "fill-info-700 dark:fill-info",
|
|
85
|
+
error: "fill-error-700 dark:fill-error",
|
|
86
|
+
warning: "fill-warning-700 dark:fill-warning",
|
|
87
|
+
primary: "fill-primary-700 dark:fill-primary",
|
|
88
|
+
secondary: "dark:fill-secondary"
|
|
89
|
+
};
|
|
90
|
+
const AlertType = {
|
|
91
|
+
success: "bg-success-30/50 outline-success-700 text-success-700 dark:bg-success-dark-30/20 dark:text-success",
|
|
92
|
+
info: "bg-info-30/50 outline-info-700 text-info-700 dark:bg-info-dark-30/20 dark:text-info",
|
|
93
|
+
warning: "bg-warning-30/50 outline-warning-700 text-warning-700 dark:bg-warning-dark-30/20 dark:text-warning",
|
|
94
|
+
error: "bg-error-30/50 outline-error-700 text-error-700 dark:bg-error-dark-30/20 dark:text-error",
|
|
95
|
+
primary: "bg-primary-30/50 outline-primary-700 text-primary-700 dark:bg-primary-dark-30/20 dark:text-primary",
|
|
96
|
+
secondary: "bg-secondary-30/50 outline-secondary-700 dark:bg-secondary-dark-30/20 dark:text-secondary"
|
|
97
|
+
};
|
|
98
|
+
const Alert = ({
|
|
99
|
+
title,
|
|
100
|
+
description,
|
|
101
|
+
icon,
|
|
102
|
+
titleClassName,
|
|
103
|
+
descriptionClassName,
|
|
104
|
+
action,
|
|
105
|
+
withClose = false,
|
|
106
|
+
iconColor = "secondary",
|
|
107
|
+
type = "secondary",
|
|
108
|
+
variant = "outline"
|
|
109
|
+
}) => {
|
|
110
|
+
const [visible, setVisible] = useState(true);
|
|
111
|
+
if (!visible) return null;
|
|
112
|
+
return /* @__PURE__ */ jsxs("div", { id: "alopeAlert", className: cn("flex gap-2 p-4 rounded-md w-full", AlertType[type], AlertVariants[variant]), children: [
|
|
113
|
+
icon ?? /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: cn("w-6 h-6", IconColors[iconColor]), children: /* @__PURE__ */ jsx(
|
|
114
|
+
"path",
|
|
115
|
+
{
|
|
116
|
+
d: "M12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22ZM12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20ZM11 15H13V17H11V15ZM11 7H13V13H11V7Z"
|
|
117
|
+
}
|
|
118
|
+
) }),
|
|
119
|
+
/* @__PURE__ */ jsxs("div", { className: "flex md:flex-row flex-col justify-between md:items-center w-full", children: [
|
|
120
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
121
|
+
/* @__PURE__ */ jsx("p", { className: cn("font-medium", titleClassName), children: title }),
|
|
122
|
+
description && /* @__PURE__ */ jsx("p", { className: cn("text-sm", descriptionClassName), children: description }),
|
|
123
|
+
withClose && (typeof action === "function" ? /* @__PURE__ */ jsx("div", { className: "mt-2", children: action() }) : /* @__PURE__ */ jsx("div", { className: "mt-2", children: action }))
|
|
124
|
+
] }),
|
|
125
|
+
/* @__PURE__ */ jsx("div", { children: !withClose && (typeof action === "function" ? /* @__PURE__ */ jsx("div", { className: "mt-2", children: action() }) : /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })) })
|
|
126
|
+
] }),
|
|
127
|
+
withClose && /* @__PURE__ */ jsx("svg", { onClick: () => setVisible(false), viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", className: "w-7 h-7 hover:cursor-pointer", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M6 18L18 6M6 6l12 12" }) })
|
|
128
|
+
] });
|
|
129
|
+
};
|
|
130
|
+
const AvatarSize = {
|
|
131
|
+
sm: "w-8 h-8 text-xs",
|
|
132
|
+
md: "w-12 h-12 text-sm",
|
|
133
|
+
lg: "w-16 h-16 text-base"
|
|
134
|
+
};
|
|
135
|
+
const AvatarVariant = {
|
|
136
|
+
solid: "bg-opacity-100",
|
|
137
|
+
outline: "bg-transparent border-2"
|
|
138
|
+
};
|
|
139
|
+
const AvatarShape = {
|
|
140
|
+
sharp: "rounded-none",
|
|
141
|
+
cornered: "rounded-md",
|
|
142
|
+
rounded: "rounded-full"
|
|
143
|
+
};
|
|
144
|
+
const AvatarFallbackColor = {
|
|
145
|
+
primary: "bg-primary dark:bg-primary-dark text-white",
|
|
146
|
+
error: "bg-error dark:bg-error-dark text-white",
|
|
147
|
+
warning: "bg-warning dark:bg-warning-dark text-white",
|
|
148
|
+
success: "bg-success dark:bg-success-dark text-white",
|
|
149
|
+
info: "bg-info dark:bg-info-dark text-white",
|
|
150
|
+
secondary: "bg-secondary dark:bg-secondary-dark text-white"
|
|
151
|
+
};
|
|
152
|
+
const Avatar = ({
|
|
153
|
+
imageSrc,
|
|
154
|
+
fallbackName,
|
|
155
|
+
ring = false,
|
|
156
|
+
ringClassName,
|
|
157
|
+
shape = "rounded",
|
|
158
|
+
variant = "solid",
|
|
159
|
+
fallbackColor = "primary",
|
|
160
|
+
size = "md",
|
|
161
|
+
alt = "avatar",
|
|
162
|
+
status,
|
|
163
|
+
className
|
|
164
|
+
}) => {
|
|
165
|
+
const [imageError, setImageError] = useState(false);
|
|
166
|
+
const AvatarSizeClass = AvatarSize[size];
|
|
167
|
+
const AvatarVariantClass = AvatarVariant[variant];
|
|
168
|
+
const AvatarShapeClass = AvatarShape[shape];
|
|
169
|
+
const AvatarFallbackColorClass = AvatarFallbackColor[fallbackColor];
|
|
170
|
+
const RingClass = ring ? cn("ring-2 ring-offset-2", ringClassName || "ring-primary dark:ring-primary-dark") : "";
|
|
171
|
+
const initials = fallbackName ? fallbackName.split(" ").map((n) => n[0]).join("").toUpperCase() : "?";
|
|
172
|
+
const content = imageError || !imageSrc ? /* @__PURE__ */ jsx(
|
|
173
|
+
"div",
|
|
174
|
+
{
|
|
175
|
+
className: cn(
|
|
176
|
+
"flex items-center justify-center font-semibold",
|
|
177
|
+
AvatarFallbackColorClass,
|
|
178
|
+
AvatarSizeClass,
|
|
179
|
+
AvatarShapeClass,
|
|
180
|
+
AvatarVariantClass,
|
|
181
|
+
RingClass,
|
|
182
|
+
className
|
|
183
|
+
),
|
|
184
|
+
children: initials
|
|
185
|
+
}
|
|
186
|
+
) : /* @__PURE__ */ jsx(
|
|
187
|
+
"img",
|
|
188
|
+
{
|
|
189
|
+
src: imageSrc,
|
|
190
|
+
alt,
|
|
191
|
+
onError: () => setImageError(true),
|
|
192
|
+
className: cn(
|
|
193
|
+
"object-cover",
|
|
194
|
+
AvatarSizeClass,
|
|
195
|
+
AvatarShapeClass,
|
|
196
|
+
AvatarVariantClass,
|
|
197
|
+
RingClass,
|
|
198
|
+
className
|
|
199
|
+
)
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative inline-block", children: [
|
|
203
|
+
content,
|
|
204
|
+
status && /* @__PURE__ */ jsx(
|
|
205
|
+
"span",
|
|
206
|
+
{
|
|
207
|
+
className: cn(
|
|
208
|
+
"absolute bottom-0 right-0 w-3 h-3 rounded-full border-2",
|
|
209
|
+
status === "online" ? "bg-success" : "bg-secondary-700 dark:bg-secondary-dark-700",
|
|
210
|
+
"border-white"
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
)
|
|
214
|
+
] });
|
|
215
|
+
};
|
|
216
|
+
const AvatarGroup = ({
|
|
217
|
+
avatars,
|
|
218
|
+
maxVisible = 3,
|
|
219
|
+
size = "md",
|
|
220
|
+
overlap = "-ml-3",
|
|
221
|
+
className
|
|
222
|
+
}) => {
|
|
223
|
+
const visibleAvatars = avatars.slice(0, maxVisible);
|
|
224
|
+
const remaining = avatars.length - maxVisible;
|
|
225
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center", className), children: [
|
|
226
|
+
visibleAvatars.map((avatar, index) => /* @__PURE__ */ jsx("div", { className: cn(index !== 0 && overlap), children: /* @__PURE__ */ jsx(Avatar, { ...avatar, size }) }, index)),
|
|
227
|
+
remaining > 0 && /* @__PURE__ */ jsxs("div", { className: cn(
|
|
228
|
+
"flex items-center justify-center bg-secondary dark:bg-secondary-dark font-medium",
|
|
229
|
+
overlap,
|
|
230
|
+
size === "sm" && "w-8 h-8 text-xs rounded-full",
|
|
231
|
+
size === "md" && "w-12 h-12 text-sm rounded-full",
|
|
232
|
+
size === "lg" && "w-16 h-16 text-base rounded-full"
|
|
233
|
+
), children: [
|
|
234
|
+
"+",
|
|
235
|
+
remaining
|
|
236
|
+
] })
|
|
237
|
+
] });
|
|
238
|
+
};
|
|
239
|
+
const BadgeVariants = {
|
|
240
|
+
default: "bg-primary-30 text-primary-700 dark:bg-primary-dark-30",
|
|
241
|
+
secondary: "bg-secondary-30 text-black dark:bg-secondary-dark-30",
|
|
242
|
+
success: "bg-success-30 text-green-700 dark:bg-success-dark-30",
|
|
243
|
+
error: "bg-error-30 text-red-700 dark:bg-error-dark-30",
|
|
244
|
+
info: "bg-info-30 text-blue-700 dark:bg-info-dark-30",
|
|
245
|
+
warning: "bg-warning-30 text-amber-700 dark:bg-warning-dark-30"
|
|
246
|
+
};
|
|
247
|
+
const BadgePositions = {
|
|
248
|
+
"top-right": "absolute -top-3 -right-3",
|
|
249
|
+
"top-left": "absolute -top-3 -left-3",
|
|
250
|
+
"bottom-right": "absolute -bottom-3 -right-3",
|
|
251
|
+
"bottom-left": "absolute -bottom-3 -left-3"
|
|
252
|
+
};
|
|
253
|
+
const Badge = ({
|
|
254
|
+
children,
|
|
255
|
+
variant = "default",
|
|
256
|
+
position = "top-right",
|
|
257
|
+
isAbsolute = false,
|
|
258
|
+
className,
|
|
259
|
+
icon
|
|
260
|
+
}) => {
|
|
261
|
+
const variantClass = BadgeVariants[variant];
|
|
262
|
+
const positionClass = isAbsolute ? BadgePositions[position] : "";
|
|
263
|
+
return /* @__PURE__ */ jsxs(
|
|
264
|
+
"span",
|
|
265
|
+
{
|
|
266
|
+
className: cn(
|
|
267
|
+
`inline-flex items-center px-3 py-1 rounded-full text-sm font-semibold`,
|
|
268
|
+
variantClass,
|
|
269
|
+
positionClass,
|
|
270
|
+
className
|
|
271
|
+
),
|
|
272
|
+
children: [
|
|
273
|
+
icon && /* @__PURE__ */ jsx("span", { className: "mr-1", children: icon }),
|
|
274
|
+
children
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
};
|
|
279
|
+
const BottomNavbarAction = ({
|
|
280
|
+
label,
|
|
281
|
+
icon,
|
|
282
|
+
value,
|
|
283
|
+
selectedValue,
|
|
284
|
+
onChangeValue,
|
|
285
|
+
labelClassName,
|
|
286
|
+
className
|
|
287
|
+
}) => {
|
|
288
|
+
const isActive = value === selectedValue;
|
|
289
|
+
return /* @__PURE__ */ jsxs(
|
|
290
|
+
"button",
|
|
291
|
+
{
|
|
292
|
+
onClick: () => onChangeValue?.(value),
|
|
293
|
+
className: cn(
|
|
294
|
+
`inline-flex flex-1 flex-col items-center justify-center p-5 group`,
|
|
295
|
+
isActive ? "bg-secondary-30-50 dark:bg-secondary/10" : "hover:bg-secondary-30 dark:hover:bg-secondary/30",
|
|
296
|
+
className
|
|
297
|
+
),
|
|
298
|
+
children: [
|
|
299
|
+
icon,
|
|
300
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
301
|
+
`text-sm`,
|
|
302
|
+
isActive ? "text-primary" : "text-secondary-dark-700 dark:text-secondary-dark group-hover:text-secondary-700 dark:group-hover:text-white",
|
|
303
|
+
labelClassName
|
|
304
|
+
), children: label })
|
|
305
|
+
]
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
};
|
|
309
|
+
const BottomNavbar = ({
|
|
310
|
+
children,
|
|
311
|
+
className,
|
|
312
|
+
value,
|
|
313
|
+
onChangeValue
|
|
314
|
+
}) => {
|
|
315
|
+
return /* @__PURE__ */ jsx("div", { className: `fixed bottom-0 left-0 z-50 w-full bg-white border-t border-secondary dark:bg-gray-800 dark:border-secondary-dark-700 ${className ?? ""}`, children: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full max-w-lg md:max-w-md mx-auto font-medium", children: React.Children.map(children, (child) => {
|
|
316
|
+
if (isValidElement(child)) {
|
|
317
|
+
if (child.type === BottomNavbarAction) {
|
|
318
|
+
return cloneElement(child, {
|
|
319
|
+
selectedValue: value,
|
|
320
|
+
onChangeValue
|
|
321
|
+
});
|
|
322
|
+
} else {
|
|
323
|
+
if (process.env.NODE_ENV !== "production") {
|
|
324
|
+
console.warn(
|
|
325
|
+
`[BottomNavbar] Invalid child component: Only <BottomNavbarAction> is allowed.
|
|
326
|
+
Received:`,
|
|
327
|
+
child.type
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (process.env.NODE_ENV !== "production") {
|
|
334
|
+
console.warn(`[BottomNavbar] Invalid child: Only <BottomNavbarAction> components are allowed.`);
|
|
335
|
+
}
|
|
336
|
+
return null;
|
|
337
|
+
}) }) });
|
|
338
|
+
};
|
|
339
|
+
const Breadcrumb = ({
|
|
340
|
+
data,
|
|
341
|
+
labelClassName,
|
|
342
|
+
currentLinkClassName,
|
|
343
|
+
linkClassName,
|
|
344
|
+
separatorClassName,
|
|
345
|
+
separator = ">"
|
|
346
|
+
}) => {
|
|
347
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: "flex flex-wrap gap-2 text-gray-600", children: data.map((item, index) => {
|
|
348
|
+
const isLast = item.path === null || index === data.length - 1;
|
|
349
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex items-center", children: [
|
|
350
|
+
!isLast && item.path ? /* @__PURE__ */ jsxs(Link, { to: item.path, className: cn("hover:underline text-primary dark:text-primary-dark-30 flex items-center text-sm", labelClassName, linkClassName), children: [
|
|
351
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "mr-1", children: item.icon }),
|
|
352
|
+
item.label
|
|
353
|
+
] }) : /* @__PURE__ */ jsxs("span", { className: cn("font-semibold dark:text-white flex items-center text-sm", labelClassName, currentLinkClassName), children: [
|
|
354
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "mr-1", children: item.icon }),
|
|
355
|
+
item.label
|
|
356
|
+
] }),
|
|
357
|
+
!isLast && /* @__PURE__ */ jsx("span", { className: cn("mx-2 font-semibold dark:text-white", separatorClassName), children: separator })
|
|
358
|
+
] }, index);
|
|
359
|
+
}) }) });
|
|
360
|
+
};
|
|
361
|
+
const ButtonSizes = {
|
|
362
|
+
sm: "px-3 py-2 text-sm font-medium rounded-sm",
|
|
363
|
+
md: "px-4 py-2 text-base font-semibold tracking-[.2px] rounded-md",
|
|
364
|
+
lg: "px-6 py-3 text-lg font-semibold rounded-lg"
|
|
365
|
+
};
|
|
366
|
+
const ButtonRadius = {
|
|
367
|
+
regular: "rounded rounded-md",
|
|
368
|
+
stadium: "rounded rounded-full"
|
|
369
|
+
};
|
|
370
|
+
const ButtonVariantsMap = {
|
|
371
|
+
primary: {
|
|
372
|
+
solid: "bg-primary text-white hover:bg-primary-dark dark:bg-primary-dark dark:hover:bg-primary-dark/70",
|
|
373
|
+
outline: "border border-primary text-primary hover:bg-primary-20 dark:bg-primary-dark/30 dark:border-primary-dark dark:text-white dark:hover:bg-primary-dark/70",
|
|
374
|
+
ghost: "text-primary hover:bg-primary-30 dark:text-primary-dark dark:hover:bg-primary-dark/70 dark:hover:text-white",
|
|
375
|
+
plain: "text-primary dark:text-primary-dark"
|
|
376
|
+
},
|
|
377
|
+
secondary: {
|
|
378
|
+
solid: "bg-secondary text-black hover:bg-secondary-dark/80 dark:bg-secondary-dark dark:text-white dark:hover:bg-secondary-dark/70",
|
|
379
|
+
outline: "border border-secondary text-black hover:bg-secondary-20 dark:bg-secondary-dark/30 dark:border-secondary-dark dark:text-white dark:hover:bg-secondary-dark/70",
|
|
380
|
+
ghost: "text-black hover:bg-secondary-30 dark:text-white dark:hover:bg-secondary-dark/70",
|
|
381
|
+
plain: "text-black dark:text-white"
|
|
382
|
+
},
|
|
383
|
+
success: {
|
|
384
|
+
solid: "bg-success text-white hover:bg-success-dark dark:bg-success-dark dark:hover:bg-success-dark/70",
|
|
385
|
+
outline: "border border-success text-success hover:bg-success-20 dark:bg-success-dark/30 dark:border-success-dark dark:text-white dark:hover:bg-success-dark/70",
|
|
386
|
+
ghost: "text-success hover:bg-success-30 dark:text-success-dark dark:hover:bg-success-dark/70 dark:hover:text-white",
|
|
387
|
+
plain: "text-success dark:text-success-dark"
|
|
388
|
+
},
|
|
389
|
+
warning: {
|
|
390
|
+
solid: "bg-warning text-white hover:bg-warning-dark dark:bg-warning-dark dark:hover:bg-warning-dark/70",
|
|
391
|
+
outline: "border border-warning text-warning hover:bg-warning-20 dark:bg-warning-dark/30 dark:border-warning-dark dark:text-white dark:hover:bg-warning-dark/70",
|
|
392
|
+
ghost: "text-warning hover:bg-warning-30 dark:text-warning-dark dark:hover:bg-warning-dark/70 dark:hover:text-white",
|
|
393
|
+
plain: "text-warning dark:text-warning-dark"
|
|
394
|
+
},
|
|
395
|
+
error: {
|
|
396
|
+
solid: "bg-error text-white hover:bg-error-dark dark:bg-error-dark dark:hover:bg-error-dark/70",
|
|
397
|
+
outline: "border border-error text-error hover:bg-error-20 dark:bg-error-dark/30 dark:border-error-dark dark:text-white dark:hover:bg-error-dark/70",
|
|
398
|
+
ghost: "text-error hover:bg-error-30 dark:text-error-dark dark:hover:bg-error-dark/70 dark:hover:text-white",
|
|
399
|
+
plain: "text-error dark:text-error-dark"
|
|
400
|
+
},
|
|
401
|
+
info: {
|
|
402
|
+
solid: "bg-info text-white hover:bg-info-dark dark:bg-info-dark dark:hover:bg-info-dark/70",
|
|
403
|
+
outline: "border border-info text-info hover:bg-info-20 dark:bg-info-dark/30 dark:border-info-dark dark:text-white dark:hover:bg-info-dark/70",
|
|
404
|
+
ghost: "text-info hover:bg-info-30 dark:text-info-dark dark:hover:bg-info-dark/70 dark:hover:text-white",
|
|
405
|
+
plain: "text-info dark:text-info-dark"
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
const getVariantClasses = (variant, variantType) => {
|
|
409
|
+
return ButtonVariantsMap[variantType][variant] || "";
|
|
410
|
+
};
|
|
411
|
+
const Button = ({
|
|
412
|
+
children,
|
|
413
|
+
onClick,
|
|
414
|
+
size = "md",
|
|
415
|
+
to,
|
|
416
|
+
type = "button",
|
|
417
|
+
disabled = false,
|
|
418
|
+
variant = "solid",
|
|
419
|
+
variantType = "primary",
|
|
420
|
+
borderType = "regular",
|
|
421
|
+
fullWidth = false,
|
|
422
|
+
prefixIcon,
|
|
423
|
+
suffixIcon,
|
|
424
|
+
className
|
|
425
|
+
}) => {
|
|
426
|
+
const buttonBorderClass = ButtonRadius[borderType];
|
|
427
|
+
const variantClass = getVariantClasses(variant, variantType);
|
|
428
|
+
const sizeClass = ButtonSizes[size] || "";
|
|
429
|
+
const disabledClass = disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer";
|
|
430
|
+
const fullWidthClass = fullWidth ? "w-full" : "";
|
|
431
|
+
return to ? /* @__PURE__ */ jsxs(
|
|
432
|
+
Link,
|
|
433
|
+
{
|
|
434
|
+
to,
|
|
435
|
+
className: cn(`inline-flex items-center justify-center transition-all duration-[170ms] hover:scale-[98%]`, variantClass, sizeClass, disabledClass, fullWidthClass, buttonBorderClass, className),
|
|
436
|
+
children: [
|
|
437
|
+
prefixIcon && /* @__PURE__ */ jsx("span", { className: "mr-2", children: prefixIcon }),
|
|
438
|
+
children,
|
|
439
|
+
suffixIcon && /* @__PURE__ */ jsx("span", { className: "ml-2", children: suffixIcon })
|
|
440
|
+
]
|
|
441
|
+
}
|
|
442
|
+
) : /* @__PURE__ */ jsxs(
|
|
443
|
+
"button",
|
|
444
|
+
{
|
|
445
|
+
disabled,
|
|
446
|
+
type,
|
|
447
|
+
onClick,
|
|
448
|
+
className: cn(`inline-flex items-center justify-center transition-all duration-[170ms] hover:scale-[98%]`, variantClass, sizeClass, disabledClass, fullWidthClass, buttonBorderClass, className),
|
|
449
|
+
children: [
|
|
450
|
+
prefixIcon && /* @__PURE__ */ jsx("span", { className: "mr-2", children: prefixIcon }),
|
|
451
|
+
children,
|
|
452
|
+
suffixIcon && /* @__PURE__ */ jsx("span", { className: "ml-2", children: suffixIcon })
|
|
453
|
+
]
|
|
454
|
+
}
|
|
455
|
+
);
|
|
456
|
+
};
|
|
457
|
+
const Card = ({
|
|
458
|
+
title,
|
|
459
|
+
description,
|
|
460
|
+
image,
|
|
461
|
+
onClick,
|
|
462
|
+
footer,
|
|
463
|
+
horizontal = false,
|
|
464
|
+
size = "md",
|
|
465
|
+
containerClassName,
|
|
466
|
+
descriptionClassName,
|
|
467
|
+
imageClassName,
|
|
468
|
+
titleClassName,
|
|
469
|
+
ribbonClassName,
|
|
470
|
+
ribbon,
|
|
471
|
+
children
|
|
472
|
+
}) => {
|
|
473
|
+
const sizeClasses2 = {
|
|
474
|
+
sm: "max-w-xs",
|
|
475
|
+
md: "max-w-sm",
|
|
476
|
+
lg: "max-w-md",
|
|
477
|
+
full: "w-full"
|
|
478
|
+
};
|
|
479
|
+
const renderImage = () => {
|
|
480
|
+
if (!image) return null;
|
|
481
|
+
if (typeof image === "string") {
|
|
482
|
+
return /* @__PURE__ */ jsx(
|
|
483
|
+
"img",
|
|
484
|
+
{
|
|
485
|
+
src: image,
|
|
486
|
+
alt: title,
|
|
487
|
+
className: cn(
|
|
488
|
+
"object-cover w-full h-48 md:h-full",
|
|
489
|
+
horizontal ? "md:w-[40%]" : "w-full",
|
|
490
|
+
imageClassName
|
|
491
|
+
)
|
|
492
|
+
}
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
return /* @__PURE__ */ jsx(
|
|
496
|
+
"div",
|
|
497
|
+
{
|
|
498
|
+
className: cn(
|
|
499
|
+
"w-full h-48 md:h-full",
|
|
500
|
+
horizontal ? "md:w-[40%]" : "w-full",
|
|
501
|
+
imageClassName
|
|
502
|
+
),
|
|
503
|
+
children: image
|
|
504
|
+
}
|
|
505
|
+
);
|
|
506
|
+
};
|
|
507
|
+
return /* @__PURE__ */ jsx(
|
|
508
|
+
"div",
|
|
509
|
+
{
|
|
510
|
+
onClick,
|
|
511
|
+
className: cn(
|
|
512
|
+
"relative bg-white rounded-xl shadow-lg hover:shadow-xl transition-shadow duration-300 cursor-pointer overflow-hidden dark:border dark:bg-gray-800 dark:border-gray-700",
|
|
513
|
+
horizontal ? "flex flex-col md:flex-row" : "flex flex-col",
|
|
514
|
+
sizeClasses2[size] || size,
|
|
515
|
+
containerClassName
|
|
516
|
+
),
|
|
517
|
+
children: children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
518
|
+
renderImage(),
|
|
519
|
+
/* @__PURE__ */ jsxs("div", { className: "p-4 flex flex-col justify-between flex-1", children: [
|
|
520
|
+
ribbon && /* @__PURE__ */ jsx(
|
|
521
|
+
"span",
|
|
522
|
+
{
|
|
523
|
+
className: cn(
|
|
524
|
+
"bg-red-500 text-white py-1 absolute text-[10px] md:text-xs w-[150px] text-center z-10",
|
|
525
|
+
horizontal ? "top-3 -left-[50px] -rotate-45" : "top-3 -right-[50px] rotate-45",
|
|
526
|
+
ribbonClassName
|
|
527
|
+
),
|
|
528
|
+
children: ribbon
|
|
529
|
+
}
|
|
530
|
+
),
|
|
531
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
532
|
+
title && /* @__PURE__ */ jsx(
|
|
533
|
+
"h3",
|
|
534
|
+
{
|
|
535
|
+
className: cn(
|
|
536
|
+
"text-lg font-semibold text-gray-800 line-clamp-1 dark:text-white",
|
|
537
|
+
titleClassName
|
|
538
|
+
),
|
|
539
|
+
children: title
|
|
540
|
+
}
|
|
541
|
+
),
|
|
542
|
+
description && /* @__PURE__ */ jsx(
|
|
543
|
+
"p",
|
|
544
|
+
{
|
|
545
|
+
className: cn(
|
|
546
|
+
"mt-2 text-secondary-700 font-medium text-sm mb-2 line-clamp-3 dark:text-secondary-dark",
|
|
547
|
+
descriptionClassName
|
|
548
|
+
),
|
|
549
|
+
children: description
|
|
550
|
+
}
|
|
551
|
+
)
|
|
552
|
+
] }),
|
|
553
|
+
footer && /* @__PURE__ */ jsx("div", { className: "mt-2", children: footer })
|
|
554
|
+
] })
|
|
555
|
+
] })
|
|
556
|
+
}
|
|
557
|
+
);
|
|
558
|
+
};
|
|
559
|
+
const CheckboxInput = React.forwardRef(
|
|
560
|
+
({
|
|
561
|
+
label,
|
|
562
|
+
description,
|
|
563
|
+
className = "",
|
|
564
|
+
indeterminate = false,
|
|
565
|
+
descriptionClassName,
|
|
566
|
+
checkboxClassName,
|
|
567
|
+
labelClassName,
|
|
568
|
+
disabled,
|
|
569
|
+
readOnly,
|
|
570
|
+
children,
|
|
571
|
+
checked,
|
|
572
|
+
defaultChecked,
|
|
573
|
+
onChange,
|
|
574
|
+
...props
|
|
575
|
+
}, ref) => {
|
|
576
|
+
const internalRef = React.useRef(null);
|
|
577
|
+
React.useImperativeHandle(ref, () => internalRef.current);
|
|
578
|
+
const [internalChecked, setInternalChecked] = React.useState(defaultChecked ?? false);
|
|
579
|
+
const isControlled = typeof checked !== "undefined";
|
|
580
|
+
const isChecked = isControlled ? checked : internalChecked;
|
|
581
|
+
React.useEffect(() => {
|
|
582
|
+
if (internalRef.current) {
|
|
583
|
+
internalRef.current.indeterminate = indeterminate;
|
|
584
|
+
}
|
|
585
|
+
}, [indeterminate]);
|
|
586
|
+
const handleChange = (e) => {
|
|
587
|
+
if (!isControlled) {
|
|
588
|
+
setInternalChecked(e.target.checked);
|
|
589
|
+
}
|
|
590
|
+
onChange?.(e);
|
|
591
|
+
};
|
|
592
|
+
return /* @__PURE__ */ jsxs(
|
|
593
|
+
"label",
|
|
594
|
+
{
|
|
595
|
+
className: cn(
|
|
596
|
+
"inline-flex items-center gap-3 cursor-pointer select-none",
|
|
597
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
598
|
+
className
|
|
599
|
+
),
|
|
600
|
+
children: [
|
|
601
|
+
/* @__PURE__ */ jsxs("span", { className: "relative inline-flex items-center justify-center w-5 h-5", children: [
|
|
602
|
+
/* @__PURE__ */ jsx(
|
|
603
|
+
"input",
|
|
604
|
+
{
|
|
605
|
+
...props,
|
|
606
|
+
ref: internalRef,
|
|
607
|
+
type: "checkbox",
|
|
608
|
+
readOnly,
|
|
609
|
+
disabled,
|
|
610
|
+
onChange: handleChange,
|
|
611
|
+
checked: isChecked,
|
|
612
|
+
"aria-checked": indeterminate ? "mixed" : isChecked ? "true" : "false",
|
|
613
|
+
className: "absolute w-full h-full opacity-0 cursor-pointer peer"
|
|
614
|
+
}
|
|
615
|
+
),
|
|
616
|
+
/* @__PURE__ */ jsx(
|
|
617
|
+
"span",
|
|
618
|
+
{
|
|
619
|
+
className: cn(
|
|
620
|
+
"w-5 h-5 rounded border border-gray-300 dark:border-gray-600 flex items-center justify-center transition-colors duration-200",
|
|
621
|
+
{
|
|
622
|
+
"bg-primary border-primary dark:bg-primary-dark dark:border-primary-dark": isChecked || indeterminate
|
|
623
|
+
},
|
|
624
|
+
checkboxClassName
|
|
625
|
+
),
|
|
626
|
+
children: indeterminate ? /* @__PURE__ */ jsx(
|
|
627
|
+
"svg",
|
|
628
|
+
{
|
|
629
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
630
|
+
className: "w-3 h-3 text-white",
|
|
631
|
+
viewBox: "0 0 20 20",
|
|
632
|
+
fill: "currentColor",
|
|
633
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 10a1 1 0 011-1h6a1 1 0 110 2H7a1 1 0 01-1-1z" })
|
|
634
|
+
}
|
|
635
|
+
) : isChecked ? /* @__PURE__ */ jsx(
|
|
636
|
+
"svg",
|
|
637
|
+
{
|
|
638
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
639
|
+
className: "w-3 h-3 text-white fill-white",
|
|
640
|
+
viewBox: "0 0 20 20",
|
|
641
|
+
children: /* @__PURE__ */ jsx(
|
|
642
|
+
"path",
|
|
643
|
+
{
|
|
644
|
+
fillRule: "evenodd",
|
|
645
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-7.778 7.778a1 1 0 01-1.414 0L3.293 10.05a1 1 0 111.414-1.414l3.536 3.535 7.071-7.071a1 1 0 011.414 0z",
|
|
646
|
+
clipRule: "evenodd"
|
|
647
|
+
}
|
|
648
|
+
)
|
|
649
|
+
}
|
|
650
|
+
) : null
|
|
651
|
+
}
|
|
652
|
+
)
|
|
653
|
+
] }),
|
|
654
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
655
|
+
children,
|
|
656
|
+
label && /* @__PURE__ */ jsx("span", { className: cn("font-medium text-sm dark:text-white", labelClassName), children: label }),
|
|
657
|
+
description && /* @__PURE__ */ jsx("span", { className: cn("text-secondary-700 text-sm dark:text-secondary-dark", descriptionClassName), children: description })
|
|
658
|
+
] })
|
|
659
|
+
]
|
|
660
|
+
}
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
);
|
|
664
|
+
const CheckboxSizes = {
|
|
665
|
+
sm: {
|
|
666
|
+
container: "text-sm",
|
|
667
|
+
checkbox: "w-4 h-4",
|
|
668
|
+
label: "pl-2"
|
|
669
|
+
},
|
|
670
|
+
md: {
|
|
671
|
+
container: "text-base",
|
|
672
|
+
checkbox: "w-5 h-5",
|
|
673
|
+
label: "pl-2"
|
|
674
|
+
},
|
|
675
|
+
lg: {
|
|
676
|
+
container: "text-lg",
|
|
677
|
+
checkbox: "w-6 h-6",
|
|
678
|
+
label: "pl-3"
|
|
679
|
+
}
|
|
680
|
+
};
|
|
681
|
+
const CheckboxVariants = {
|
|
682
|
+
solid: {
|
|
683
|
+
label: "border-transparent bg-primary/90 text-white hover:bg-primary-700 dark:bg-primary-dark dark:hover:bg-primary-dark-700",
|
|
684
|
+
checked: "bg-primary-700 hover:bg-primary-700 dark:bg-primary-dark-700",
|
|
685
|
+
checkbox: "",
|
|
686
|
+
checkedCheckbox: "border-white bg-primary dark:bg-primary"
|
|
687
|
+
},
|
|
688
|
+
subtle: {
|
|
689
|
+
label: "border-slate-200 border-none bg-secondary/30 hover:bg-primary/30 hover:text-primary-700 dark:text-white dark:bg-primary-dark/50 hover:dark:text-primary-30",
|
|
690
|
+
checked: "bg-primary/30 text-primary-700 border-primary/30 dark:border-none hover:bg-primary-700/15 dark:bg-primary/30 dark:text-white hover:dark:text-white dark:hover:bg-primary-dark/50",
|
|
691
|
+
checkbox: "dark:bg-primary dark:border-none",
|
|
692
|
+
checkedCheckbox: "border-primary-700 bg-primary-700 dark:bg-primary"
|
|
693
|
+
},
|
|
694
|
+
outline: {
|
|
695
|
+
label: "border-secondary-700 bg-transparent hover:bg-primary/30 hover:text-primary-700 dark:hover:text-white hover:border-primary-700 dark:text-white dark:border-secondary-dark dark:hover:bg-primary-dark/20",
|
|
696
|
+
checked: "border-primary bg-primary/30 text-primary-700 dark:border-primary-700 dark:bg-primary-dark/20",
|
|
697
|
+
checkbox: "dark:border-secondary-dark",
|
|
698
|
+
checkedCheckbox: "border-primary bg-primary-700 dark:border-primary-700 dark:border-primary dark:bg-primary"
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
const ListCheckboxInput = ({
|
|
702
|
+
name,
|
|
703
|
+
options,
|
|
704
|
+
selectedValues,
|
|
705
|
+
onValueChange,
|
|
706
|
+
containerClassName,
|
|
707
|
+
inputGroupClassName,
|
|
708
|
+
inputLabelClassName,
|
|
709
|
+
inputCheckboxClassName,
|
|
710
|
+
variant = "subtle",
|
|
711
|
+
checkboxSize = "md",
|
|
712
|
+
disabled,
|
|
713
|
+
...props
|
|
714
|
+
}) => {
|
|
715
|
+
const sizeClasses2 = CheckboxSizes[checkboxSize];
|
|
716
|
+
const variantClasses = CheckboxVariants[variant];
|
|
717
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-3", containerClassName), children: options.map((option, index) => {
|
|
718
|
+
const isChecked = selectedValues?.some((selected) => selected.value === option.value) ?? false;
|
|
719
|
+
return /* @__PURE__ */ jsxs(
|
|
720
|
+
"label",
|
|
721
|
+
{
|
|
722
|
+
className: cn(
|
|
723
|
+
"relative flex items-center rounded-md cursor-pointer transition-all duration-200 border px-3 py-2",
|
|
724
|
+
sizeClasses2.container,
|
|
725
|
+
variantClasses.label,
|
|
726
|
+
{
|
|
727
|
+
[variantClasses.checked]: isChecked,
|
|
728
|
+
"opacity-50 cursor-not-allowed": disabled
|
|
729
|
+
},
|
|
730
|
+
inputGroupClassName?.(option, isChecked)
|
|
731
|
+
),
|
|
732
|
+
children: [
|
|
733
|
+
/* @__PURE__ */ jsx(
|
|
734
|
+
"input",
|
|
735
|
+
{
|
|
736
|
+
type: "checkbox",
|
|
737
|
+
name,
|
|
738
|
+
value: option.value,
|
|
739
|
+
checked: isChecked,
|
|
740
|
+
onChange: () => {
|
|
741
|
+
const newSelected = isChecked ? selectedValues?.filter((val) => val.value !== option.value) || [] : [...selectedValues || [], option];
|
|
742
|
+
onValueChange(newSelected);
|
|
743
|
+
},
|
|
744
|
+
disabled,
|
|
745
|
+
className: cn("absolute opacity-0 w-full h-full cursor-pointer", { "cursor-not-allowed": disabled }),
|
|
746
|
+
...props
|
|
747
|
+
}
|
|
748
|
+
),
|
|
749
|
+
/* @__PURE__ */ jsx(
|
|
750
|
+
"span",
|
|
751
|
+
{
|
|
752
|
+
className: cn(
|
|
753
|
+
"flex items-center justify-center rounded-md border transition-all duration-200",
|
|
754
|
+
sizeClasses2.checkbox,
|
|
755
|
+
variantClasses.checkbox,
|
|
756
|
+
{
|
|
757
|
+
[variantClasses.checkedCheckbox]: isChecked
|
|
758
|
+
},
|
|
759
|
+
inputCheckboxClassName?.(option, isChecked)
|
|
760
|
+
),
|
|
761
|
+
children: isChecked && /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
|
|
762
|
+
"svg",
|
|
763
|
+
{
|
|
764
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
765
|
+
viewBox: "0 0 20 20",
|
|
766
|
+
fill: "white",
|
|
767
|
+
className: "w-3 h-3",
|
|
768
|
+
children: /* @__PURE__ */ jsx(
|
|
769
|
+
"path",
|
|
770
|
+
{
|
|
771
|
+
fillRule: "evenodd",
|
|
772
|
+
d: "M16.707 5.293a1 1 0 010 1.414l-7.778 7.778a1 1 0 01-1.414 0L3.293 10.05a1 1 0 111.414-1.414l3.536 3.535 7.071-7.071a1 1 0 011.414 0z",
|
|
773
|
+
clipRule: "evenodd"
|
|
774
|
+
}
|
|
775
|
+
)
|
|
776
|
+
}
|
|
777
|
+
) })
|
|
778
|
+
}
|
|
779
|
+
),
|
|
780
|
+
/* @__PURE__ */ jsx("span", { className: cn("ml-2", sizeClasses2.label, inputLabelClassName?.(option, isChecked)), children: option.label })
|
|
781
|
+
]
|
|
782
|
+
},
|
|
783
|
+
index
|
|
784
|
+
);
|
|
785
|
+
}) });
|
|
786
|
+
};
|
|
787
|
+
const CodeInputSize = {
|
|
788
|
+
sm: "w-10 h-10 text-sm",
|
|
789
|
+
md: "w-12 h-12 text-base",
|
|
790
|
+
lg: "w-14 h-14 text-lg",
|
|
791
|
+
xl: "w-16 h-16 text-xl"
|
|
792
|
+
};
|
|
793
|
+
const CodeInput = ({
|
|
794
|
+
id,
|
|
795
|
+
label,
|
|
796
|
+
length,
|
|
797
|
+
value,
|
|
798
|
+
disabled,
|
|
799
|
+
labelClassName,
|
|
800
|
+
name,
|
|
801
|
+
onCodeChange,
|
|
802
|
+
inputSize = "md",
|
|
803
|
+
...props
|
|
804
|
+
}) => {
|
|
805
|
+
const inputRefs = useRef([]);
|
|
806
|
+
const inputSizeClasses = CodeInputSize[inputSize];
|
|
807
|
+
const findFirstEmptyIndex = () => {
|
|
808
|
+
for (let i = 0; i < length; i++) {
|
|
809
|
+
if (!inputRefs.current[i]?.value) {
|
|
810
|
+
return i;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
return -1;
|
|
814
|
+
};
|
|
815
|
+
const handleInputChange = (index) => {
|
|
816
|
+
const code = inputRefs.current.map((input) => input?.value || "").join("");
|
|
817
|
+
if (onCodeChange) {
|
|
818
|
+
onCodeChange(code);
|
|
819
|
+
}
|
|
820
|
+
if (inputRefs.current[index]?.value && index < length - 1) {
|
|
821
|
+
inputRefs.current[index + 1]?.focus();
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
const handleFocus = (index) => {
|
|
825
|
+
const firstEmptyIndex = findFirstEmptyIndex();
|
|
826
|
+
if (firstEmptyIndex !== -1 && firstEmptyIndex < index) {
|
|
827
|
+
inputRefs.current[firstEmptyIndex]?.focus();
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
const handleKeyDown = (e, index) => {
|
|
831
|
+
if (e.key === "Backspace" && !inputRefs.current[index]?.value && index > 0) {
|
|
832
|
+
inputRefs.current[index - 1]?.focus();
|
|
833
|
+
}
|
|
834
|
+
};
|
|
835
|
+
const handlePaste = (e) => {
|
|
836
|
+
e.preventDefault();
|
|
837
|
+
const pastedData = e.clipboardData.getData("text").slice(0, length);
|
|
838
|
+
pastedData.split("").forEach((char, index) => {
|
|
839
|
+
if (inputRefs.current[index]) {
|
|
840
|
+
inputRefs.current[index].value = char;
|
|
841
|
+
handleInputChange(index);
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
};
|
|
845
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
846
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id || name, className: cn("block text-sm font-medium mb-1 dark:text-white", labelClassName), children: label }),
|
|
847
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2", onPaste: handlePaste, children: Array.from({ length }, (_, index) => /* @__PURE__ */ jsx(
|
|
848
|
+
"input",
|
|
849
|
+
{
|
|
850
|
+
ref: (el) => {
|
|
851
|
+
inputRefs.current[index] = el;
|
|
852
|
+
},
|
|
853
|
+
type: "text",
|
|
854
|
+
disabled,
|
|
855
|
+
value: value?.[index],
|
|
856
|
+
maxLength: 1,
|
|
857
|
+
onChange: () => handleInputChange(index),
|
|
858
|
+
onKeyDown: (e) => handleKeyDown(e, index),
|
|
859
|
+
onFocus: () => handleFocus(index),
|
|
860
|
+
className: cn(
|
|
861
|
+
"text-center border rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary border-secondary dark:text-white dark:placeholder:text-white",
|
|
862
|
+
inputSizeClasses,
|
|
863
|
+
{
|
|
864
|
+
"bg-secondary/40 cursor-not-allowed ": disabled
|
|
865
|
+
}
|
|
866
|
+
),
|
|
867
|
+
...props
|
|
868
|
+
},
|
|
869
|
+
index
|
|
870
|
+
)) })
|
|
871
|
+
] });
|
|
872
|
+
};
|
|
873
|
+
function Collection({
|
|
874
|
+
data,
|
|
875
|
+
title,
|
|
876
|
+
className,
|
|
877
|
+
wrapperClassName,
|
|
878
|
+
children,
|
|
879
|
+
suffixIcon,
|
|
880
|
+
activeItem,
|
|
881
|
+
onChangeActive
|
|
882
|
+
}) {
|
|
883
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("p-3 border border-secondary-700 inline-block dark:border-secondary-dark-700 rounded-md dark:text-white", className), children: [
|
|
884
|
+
title && /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold mb-4", children: title }),
|
|
885
|
+
data.length > 0 ? /* @__PURE__ */ jsx("ul", { className: cn("space-y-3", wrapperClassName), children: data.map((item, index) => {
|
|
886
|
+
const isActive = item.id === activeItem;
|
|
887
|
+
return /* @__PURE__ */ jsx("li", { children: children ? /* @__PURE__ */ jsx("div", { onClick: () => onChangeActive?.(item, index), children: children(item, index, isActive) }) : /* @__PURE__ */ jsxs(
|
|
888
|
+
"div",
|
|
889
|
+
{
|
|
890
|
+
onClick: () => onChangeActive?.(item, index),
|
|
891
|
+
className: cn(
|
|
892
|
+
"p-3 border border-secondary-700 dark:border-secondary-dark-700 rounded-md flex gap-3 items-center justify-between cursor-pointer",
|
|
893
|
+
{ "bg-primary-100 dark:bg-primary-dark-100": isActive }
|
|
894
|
+
),
|
|
895
|
+
children: [
|
|
896
|
+
/* @__PURE__ */ jsx("p", { className: "font-bold", children: item.name || `Item ${item.id}` }),
|
|
897
|
+
suffixIcon && /* @__PURE__ */ jsx("span", { children: typeof suffixIcon === "function" ? suffixIcon(item, index, isActive) : suffixIcon })
|
|
898
|
+
]
|
|
899
|
+
}
|
|
900
|
+
) }, item.id);
|
|
901
|
+
}) }) : /* @__PURE__ */ jsx("p", { children: "No items to display." })
|
|
902
|
+
] });
|
|
903
|
+
}
|
|
904
|
+
const TextInput = React.forwardRef(
|
|
905
|
+
({
|
|
906
|
+
label,
|
|
907
|
+
id,
|
|
908
|
+
name,
|
|
909
|
+
error,
|
|
910
|
+
labelClassName,
|
|
911
|
+
errorClassName,
|
|
912
|
+
...props
|
|
913
|
+
}, ref) => {
|
|
914
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
915
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id || name, className: cn("block text-sm font-medium mb-1 dark:text-white", labelClassName), children: label }),
|
|
916
|
+
/* @__PURE__ */ jsx(
|
|
917
|
+
"input",
|
|
918
|
+
{
|
|
919
|
+
ref,
|
|
920
|
+
id: id || name,
|
|
921
|
+
name,
|
|
922
|
+
className: `block w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary sm:text-sm dark:text-white dark:placeholder:text-white ${error ? "border-error dark:border-error-dark" : "border-secondary dark:border-secondary-dark"} ${props.disabled ? "bg-secondary/30 cursor-not-allowed" : ""}`,
|
|
923
|
+
...props
|
|
924
|
+
}
|
|
925
|
+
),
|
|
926
|
+
error && /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-sm text-error", errorClassName), children: error })
|
|
927
|
+
] });
|
|
928
|
+
}
|
|
929
|
+
);
|
|
930
|
+
TextInput.displayName = "TextInput";
|
|
931
|
+
const DatePickerColors = {
|
|
932
|
+
success: {
|
|
933
|
+
input: "focus:ring-success focus:border-success",
|
|
934
|
+
outline: "outline-success dark:outline-success-dark",
|
|
935
|
+
header: "bg-success dark:bg-success-dark",
|
|
936
|
+
icon: "hover:bg-success-700 dark:hover:bg-success-dark-700",
|
|
937
|
+
day: "bg-success dark:bg-success-dark"
|
|
938
|
+
},
|
|
939
|
+
info: {
|
|
940
|
+
input: "focus:ring-info focus:border-info",
|
|
941
|
+
outline: "outline-info dark:outline-info-dark",
|
|
942
|
+
header: "bg-info dark:bg-info-dark",
|
|
943
|
+
icon: "hover:bg-info-700 dark:hover:bg-info-dark-700",
|
|
944
|
+
day: "bg-info dark:bg-info-dark"
|
|
945
|
+
},
|
|
946
|
+
error: {
|
|
947
|
+
input: "focus:ring-error focus:border-error",
|
|
948
|
+
outline: "outline-error dark:outline-error-dark",
|
|
949
|
+
header: "bg-error dark:bg-error-dark",
|
|
950
|
+
icon: "hover:bg-error-700 dark:hover:bg-error-dark-700",
|
|
951
|
+
day: "bg-error dark:bg-error-dark"
|
|
952
|
+
},
|
|
953
|
+
warning: {
|
|
954
|
+
input: "focus:ring-warning focus:border-warning",
|
|
955
|
+
outline: "outline-warning dark:outline-warning-dark",
|
|
956
|
+
header: "bg-warning dark:bg-warning-dark",
|
|
957
|
+
icon: "hover:bg-warning-700 dark:hover:bg-warning-dark-700",
|
|
958
|
+
day: "bg-warning dark:bg-warning-dark"
|
|
959
|
+
},
|
|
960
|
+
default: {
|
|
961
|
+
input: "",
|
|
962
|
+
outline: "",
|
|
963
|
+
header: "",
|
|
964
|
+
icon: "",
|
|
965
|
+
day: ""
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
const DatePicker = ({
|
|
969
|
+
label,
|
|
970
|
+
id,
|
|
971
|
+
name,
|
|
972
|
+
color = "default",
|
|
973
|
+
labelClassName,
|
|
974
|
+
selectedDate: initialSelectedDate,
|
|
975
|
+
onDateChange
|
|
976
|
+
}) => {
|
|
977
|
+
const [selectedDate, setSelectedDate] = useState(
|
|
978
|
+
initialSelectedDate || null
|
|
979
|
+
);
|
|
980
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
981
|
+
const [currentMonth, setCurrentMonth] = useState(
|
|
982
|
+
selectedDate ? selectedDate.getMonth() : (/* @__PURE__ */ new Date()).getMonth()
|
|
983
|
+
);
|
|
984
|
+
const [currentYear, setCurrentYear] = useState(
|
|
985
|
+
selectedDate ? selectedDate.getFullYear() : (/* @__PURE__ */ new Date()).getFullYear()
|
|
986
|
+
);
|
|
987
|
+
const [calendarPosition, setCalendarPosition] = useState("bottom");
|
|
988
|
+
const datePickerRef = useRef(null);
|
|
989
|
+
const inputRef = useRef(null);
|
|
990
|
+
const inputClasess = DatePickerColors[color].input;
|
|
991
|
+
const dayClasess = DatePickerColors[color].day;
|
|
992
|
+
const headerClasess = DatePickerColors[color].header;
|
|
993
|
+
const iconClasess = DatePickerColors[color].icon;
|
|
994
|
+
const outlineClasess = DatePickerColors[color].outline;
|
|
995
|
+
useLayoutEffect(() => {
|
|
996
|
+
if (isOpen && inputRef.current) {
|
|
997
|
+
const inputRect = inputRef.current.getBoundingClientRect();
|
|
998
|
+
const spaceBelow = window.innerHeight - inputRect.bottom;
|
|
999
|
+
const calendarHeight = 300;
|
|
1000
|
+
if (spaceBelow < calendarHeight) {
|
|
1001
|
+
setCalendarPosition("top");
|
|
1002
|
+
} else {
|
|
1003
|
+
setCalendarPosition("bottom");
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}, [isOpen]);
|
|
1007
|
+
useEffect(() => {
|
|
1008
|
+
if (initialSelectedDate) {
|
|
1009
|
+
setSelectedDate(initialSelectedDate);
|
|
1010
|
+
setCurrentMonth(initialSelectedDate.getMonth());
|
|
1011
|
+
setCurrentYear(initialSelectedDate.getFullYear());
|
|
1012
|
+
}
|
|
1013
|
+
}, [initialSelectedDate]);
|
|
1014
|
+
useEffect(() => {
|
|
1015
|
+
function handleClickOutside(event) {
|
|
1016
|
+
if (datePickerRef.current && !datePickerRef.current.contains(event.target)) {
|
|
1017
|
+
setIsOpen(false);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1021
|
+
return () => {
|
|
1022
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
1023
|
+
};
|
|
1024
|
+
}, [datePickerRef]);
|
|
1025
|
+
const handleDateChange = (date) => {
|
|
1026
|
+
setSelectedDate(date);
|
|
1027
|
+
if (onDateChange) {
|
|
1028
|
+
onDateChange(date);
|
|
1029
|
+
}
|
|
1030
|
+
setIsOpen(false);
|
|
1031
|
+
};
|
|
1032
|
+
const daysInMonth = (month, year) => {
|
|
1033
|
+
return new Date(year, month + 1, 0).getDate();
|
|
1034
|
+
};
|
|
1035
|
+
const firstDayOfMonth = (month, year) => {
|
|
1036
|
+
return new Date(year, month, 1).getDay();
|
|
1037
|
+
};
|
|
1038
|
+
const renderCalendar = () => {
|
|
1039
|
+
const days = [];
|
|
1040
|
+
const totalDays = daysInMonth(currentMonth, currentYear);
|
|
1041
|
+
const firstDay = firstDayOfMonth(currentMonth, currentYear);
|
|
1042
|
+
for (let i = 0; i < firstDay; i++) {
|
|
1043
|
+
days.push(/* @__PURE__ */ jsx("div", { className: "w-8 h-8" }, `empty-${i}`));
|
|
1044
|
+
}
|
|
1045
|
+
for (let i = 1; i <= totalDays; i++) {
|
|
1046
|
+
const date = new Date(currentYear, currentMonth, i);
|
|
1047
|
+
const isSelected = selectedDate && date.getDate() === selectedDate.getDate() && date.getMonth() === selectedDate.getMonth() && date.getFullYear() === selectedDate.getFullYear();
|
|
1048
|
+
days.push(
|
|
1049
|
+
/* @__PURE__ */ jsx(
|
|
1050
|
+
"div",
|
|
1051
|
+
{
|
|
1052
|
+
className: cn(
|
|
1053
|
+
`px-4 py-2 flex items-center justify-center cursor-pointer rounded-md text-sm font-medium hover:bg-secondary dark:hover:bg-secondary-dark`,
|
|
1054
|
+
{
|
|
1055
|
+
"bg-primary dark:bg-primary-dark text-white": isSelected,
|
|
1056
|
+
[dayClasess]: isSelected
|
|
1057
|
+
}
|
|
1058
|
+
),
|
|
1059
|
+
onClick: () => handleDateChange(date),
|
|
1060
|
+
children: i
|
|
1061
|
+
},
|
|
1062
|
+
i
|
|
1063
|
+
)
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-7 gap-1 p-2", children: [
|
|
1067
|
+
["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map((day) => /* @__PURE__ */ jsx("div", { className: "w-8 h-8 flex items-center justify-center font-semibold", children: day }, day)),
|
|
1068
|
+
days
|
|
1069
|
+
] });
|
|
1070
|
+
};
|
|
1071
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", ref: datePickerRef, children: [
|
|
1072
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id || name, className: cn("block text-sm font-medium mb-1 dark:text-white", labelClassName), children: label }),
|
|
1073
|
+
/* @__PURE__ */ jsx(
|
|
1074
|
+
TextInput,
|
|
1075
|
+
{
|
|
1076
|
+
type: "text",
|
|
1077
|
+
readOnly: true,
|
|
1078
|
+
ref: inputRef,
|
|
1079
|
+
value: selectedDate ? selectedDate.toLocaleDateString() : "",
|
|
1080
|
+
onClick: () => setIsOpen(!isOpen),
|
|
1081
|
+
placeholder: "Select a date",
|
|
1082
|
+
className: cn(
|
|
1083
|
+
"w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary sm:text-sm dark:placeholder:text-white dark:text-white",
|
|
1084
|
+
inputClasess
|
|
1085
|
+
)
|
|
1086
|
+
}
|
|
1087
|
+
),
|
|
1088
|
+
isOpen && /* @__PURE__ */ jsxs("div", { className: cn(
|
|
1089
|
+
`absolute overflow-auto z-10 w-full bg-white outline-3 outline-primary dark:outline-primary-dark rounded-md shadow-lg`,
|
|
1090
|
+
calendarPosition === "top" ? "bottom-full mb-2" : "top-full mt-2",
|
|
1091
|
+
outlineClasess
|
|
1092
|
+
), children: [
|
|
1093
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
1094
|
+
"flex justify-between items-center mb-1 bg-primary dark:bg-primary-dark p-2 text-white",
|
|
1095
|
+
headerClasess
|
|
1096
|
+
), children: [
|
|
1097
|
+
/* @__PURE__ */ jsx(
|
|
1098
|
+
"button",
|
|
1099
|
+
{
|
|
1100
|
+
onClick: () => {
|
|
1101
|
+
if (currentMonth === 0) {
|
|
1102
|
+
setCurrentMonth(11);
|
|
1103
|
+
setCurrentYear(currentYear - 1);
|
|
1104
|
+
} else {
|
|
1105
|
+
setCurrentMonth(currentMonth - 1);
|
|
1106
|
+
}
|
|
1107
|
+
},
|
|
1108
|
+
className: cn(
|
|
1109
|
+
"px-2 py-1 rounded-md hover:bg-primary-700 dark:hover:bg-primary-dark-700 hover:cursor-pointer",
|
|
1110
|
+
iconClasess
|
|
1111
|
+
),
|
|
1112
|
+
children: "<"
|
|
1113
|
+
}
|
|
1114
|
+
),
|
|
1115
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
1116
|
+
/* @__PURE__ */ jsx("div", { className: "font-semibold", children: new Date(currentYear, currentMonth).toLocaleString("default", {
|
|
1117
|
+
month: "long"
|
|
1118
|
+
// year: 'numeric',
|
|
1119
|
+
}) }),
|
|
1120
|
+
/* @__PURE__ */ jsx("div", { className: "w-20", children: /* @__PURE__ */ jsx(
|
|
1121
|
+
TextInput,
|
|
1122
|
+
{
|
|
1123
|
+
type: "number",
|
|
1124
|
+
value: currentYear,
|
|
1125
|
+
onChange: (e) => setCurrentYear(Number(e.target.value))
|
|
1126
|
+
}
|
|
1127
|
+
) })
|
|
1128
|
+
] }),
|
|
1129
|
+
/* @__PURE__ */ jsx(
|
|
1130
|
+
"button",
|
|
1131
|
+
{
|
|
1132
|
+
onClick: () => {
|
|
1133
|
+
if (currentMonth === 11) {
|
|
1134
|
+
setCurrentMonth(0);
|
|
1135
|
+
setCurrentYear(currentYear + 1);
|
|
1136
|
+
} else {
|
|
1137
|
+
setCurrentMonth(currentMonth + 1);
|
|
1138
|
+
}
|
|
1139
|
+
},
|
|
1140
|
+
className: cn(
|
|
1141
|
+
"px-2 py-1 rounded-md hover:bg-primary-700 dark:hover:bg-primary-dark-700 hover:cursor-pointer",
|
|
1142
|
+
iconClasess
|
|
1143
|
+
),
|
|
1144
|
+
children: ">"
|
|
1145
|
+
}
|
|
1146
|
+
)
|
|
1147
|
+
] }),
|
|
1148
|
+
renderCalendar()
|
|
1149
|
+
] })
|
|
1150
|
+
] });
|
|
1151
|
+
};
|
|
1152
|
+
const FABSizes = {
|
|
1153
|
+
sm: "w-11 h-11 font-medium rounded-sm rounded rounded-full",
|
|
1154
|
+
md: "w-14 h-14 font-semibold tracking-[.2px] rounded-md rounded rounded-full",
|
|
1155
|
+
lg: "w-19 h-19 text-lg font-semibold rounded-lg rounded rounded-full"
|
|
1156
|
+
};
|
|
1157
|
+
const FAB = ({
|
|
1158
|
+
children,
|
|
1159
|
+
direction = "vertical",
|
|
1160
|
+
size = "md",
|
|
1161
|
+
variant = "solid",
|
|
1162
|
+
variantType = "primary",
|
|
1163
|
+
isOpen,
|
|
1164
|
+
onOpen,
|
|
1165
|
+
icon = "+"
|
|
1166
|
+
}) => {
|
|
1167
|
+
const [shouldRender, setShouldRender] = useState(isOpen);
|
|
1168
|
+
const [isAnimatingOut, setIsAnimatingOut] = useState(false);
|
|
1169
|
+
useEffect(() => {
|
|
1170
|
+
if (isOpen) {
|
|
1171
|
+
setShouldRender(true);
|
|
1172
|
+
setIsAnimatingOut(false);
|
|
1173
|
+
} else if (shouldRender) {
|
|
1174
|
+
setIsAnimatingOut(true);
|
|
1175
|
+
const timeout = setTimeout(() => {
|
|
1176
|
+
setShouldRender(false);
|
|
1177
|
+
setIsAnimatingOut(false);
|
|
1178
|
+
}, 300);
|
|
1179
|
+
return () => clearTimeout(timeout);
|
|
1180
|
+
}
|
|
1181
|
+
}, [isOpen, shouldRender]);
|
|
1182
|
+
const directionClasses = {
|
|
1183
|
+
vertical: "flex-col-reverse space-y-2 space-y-reverse mb-2",
|
|
1184
|
+
horizontal: "flex-row-reverse space-x-2 space-x-reverse mr-2"
|
|
1185
|
+
};
|
|
1186
|
+
const sizeClasses2 = FABSizes[size];
|
|
1187
|
+
const variantClasses = getVariantClasses(variant, variantType);
|
|
1188
|
+
const animatedChildren = Children.toArray(children).map((child, index, arr) => {
|
|
1189
|
+
if (!isValidElement(child)) return child;
|
|
1190
|
+
const reverseIndex = arr.length - 1 - index;
|
|
1191
|
+
return /* @__PURE__ */ jsx(
|
|
1192
|
+
"div",
|
|
1193
|
+
{
|
|
1194
|
+
style: { animationDelay: `${isAnimatingOut ? reverseIndex * 100 : index * 100}ms` },
|
|
1195
|
+
className: cn(
|
|
1196
|
+
!isAnimatingOut && "opacity-0",
|
|
1197
|
+
isAnimatingOut ? "animate-pop-out" : "animate-pop"
|
|
1198
|
+
),
|
|
1199
|
+
children: child
|
|
1200
|
+
},
|
|
1201
|
+
index
|
|
1202
|
+
);
|
|
1203
|
+
});
|
|
1204
|
+
return /* @__PURE__ */ jsx("div", { className: "fixed bottom-8 right-8 flex flex-col items-end z-50", children: /* @__PURE__ */ jsxs("div", { className: direction === "vertical" ? "block" : "flex", children: [
|
|
1205
|
+
/* @__PURE__ */ jsx("div", { className: cn("flex items-center transition-all duration-300 ease-in-out", directionClasses[direction]), children: shouldRender && animatedChildren }),
|
|
1206
|
+
/* @__PURE__ */ jsx(
|
|
1207
|
+
"button",
|
|
1208
|
+
{
|
|
1209
|
+
onClick: onOpen,
|
|
1210
|
+
className: cn("shadow-lg flex w-full items-center justify-center hover:cursor-pointer", sizeClasses2, variantClasses),
|
|
1211
|
+
"aria-expanded": isOpen,
|
|
1212
|
+
"aria-haspopup": "true",
|
|
1213
|
+
children: /* @__PURE__ */ jsx(
|
|
1214
|
+
"span",
|
|
1215
|
+
{
|
|
1216
|
+
className: `transform transition-transform duration-300 ${isOpen ? "rotate-45" : "rotate-0"}`,
|
|
1217
|
+
children: icon
|
|
1218
|
+
}
|
|
1219
|
+
)
|
|
1220
|
+
}
|
|
1221
|
+
)
|
|
1222
|
+
] }) });
|
|
1223
|
+
};
|
|
1224
|
+
const FileUpload = ({
|
|
1225
|
+
acceptedFiles = "image/*",
|
|
1226
|
+
maxFiles = 1,
|
|
1227
|
+
inputLabel,
|
|
1228
|
+
maxKiloByte = 2048,
|
|
1229
|
+
helperText,
|
|
1230
|
+
mediaCapture,
|
|
1231
|
+
mode = "dropzone",
|
|
1232
|
+
clearable = true,
|
|
1233
|
+
onFilesChange
|
|
1234
|
+
}) => {
|
|
1235
|
+
const [files, setFiles] = useState([]);
|
|
1236
|
+
const [errorMessage, setErrorMessage] = useState("");
|
|
1237
|
+
const [isDragActive, setIsDragActive] = useState(false);
|
|
1238
|
+
const inputRef = useRef(null);
|
|
1239
|
+
const handleFileChange = (event) => {
|
|
1240
|
+
const newFiles = event.target.files ? Array.from(event.target.files) : [];
|
|
1241
|
+
if (newFiles.length === 0) return;
|
|
1242
|
+
const validFiles = handleValidation(newFiles);
|
|
1243
|
+
if (!validFiles.length) return;
|
|
1244
|
+
const allFiles = maxFiles === 1 ? validFiles.slice(0, 1) : [...files, ...validFiles].slice(0, maxFiles);
|
|
1245
|
+
setFiles(allFiles);
|
|
1246
|
+
onFilesChange(allFiles);
|
|
1247
|
+
setErrorMessage("");
|
|
1248
|
+
inputRef.current.value = "";
|
|
1249
|
+
};
|
|
1250
|
+
const handleDragEnter = (event) => {
|
|
1251
|
+
event.preventDefault();
|
|
1252
|
+
setIsDragActive(true);
|
|
1253
|
+
};
|
|
1254
|
+
const handleDragLeave = (event) => {
|
|
1255
|
+
event.preventDefault();
|
|
1256
|
+
setIsDragActive(false);
|
|
1257
|
+
};
|
|
1258
|
+
const handleDrop = (event) => {
|
|
1259
|
+
event.preventDefault();
|
|
1260
|
+
setIsDragActive(false);
|
|
1261
|
+
const droppedFiles = Array.from(event.dataTransfer.files);
|
|
1262
|
+
const validFiles = handleValidation(droppedFiles);
|
|
1263
|
+
if (!validFiles.length) return;
|
|
1264
|
+
const allFiles = maxFiles === 1 ? validFiles.slice(0, 1) : [...files, ...validFiles].slice(0, maxFiles);
|
|
1265
|
+
setFiles(allFiles);
|
|
1266
|
+
onFilesChange(allFiles);
|
|
1267
|
+
setErrorMessage("");
|
|
1268
|
+
inputRef.current.value = "";
|
|
1269
|
+
};
|
|
1270
|
+
const handleClear = (event, index) => {
|
|
1271
|
+
event.stopPropagation();
|
|
1272
|
+
const restFiles = files.filter((_, i) => i !== index);
|
|
1273
|
+
setFiles(restFiles);
|
|
1274
|
+
onFilesChange(restFiles);
|
|
1275
|
+
if (restFiles.length === 0 && inputRef.current) {
|
|
1276
|
+
inputRef.current.value = "";
|
|
1277
|
+
}
|
|
1278
|
+
};
|
|
1279
|
+
const handleClick = () => {
|
|
1280
|
+
if (inputRef.current) {
|
|
1281
|
+
inputRef.current.click();
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
const isFileAccepted = (file, accepted) => {
|
|
1285
|
+
const acceptedList = accepted.split(",").map((type) => type.trim());
|
|
1286
|
+
return acceptedList.some((type) => {
|
|
1287
|
+
if (type === "") return false;
|
|
1288
|
+
if (type === file.type) return true;
|
|
1289
|
+
if (type.endsWith("/*")) {
|
|
1290
|
+
const baseType = type.split("/")[0];
|
|
1291
|
+
return file.type.startsWith(baseType + "/");
|
|
1292
|
+
}
|
|
1293
|
+
if (type.startsWith(".")) {
|
|
1294
|
+
return file.name.toLowerCase().endsWith(type.toLowerCase());
|
|
1295
|
+
}
|
|
1296
|
+
return false;
|
|
1297
|
+
});
|
|
1298
|
+
};
|
|
1299
|
+
const handleValidation = (newFiles) => {
|
|
1300
|
+
const maxByte = maxKiloByte * 1024;
|
|
1301
|
+
const tooLarge = newFiles.find((f) => f.size > maxByte);
|
|
1302
|
+
if (tooLarge) {
|
|
1303
|
+
setErrorMessage(
|
|
1304
|
+
`File "${tooLarge.name}" exceeds size limit of ${(maxKiloByte / 1024).toFixed(2)} MB.`
|
|
1305
|
+
);
|
|
1306
|
+
inputRef.current.value = "";
|
|
1307
|
+
return [];
|
|
1308
|
+
}
|
|
1309
|
+
const invalidType = newFiles.find((f) => !isFileAccepted(f, acceptedFiles));
|
|
1310
|
+
if (invalidType) {
|
|
1311
|
+
setErrorMessage(`File type "${invalidType.type}" is not accepted.`);
|
|
1312
|
+
inputRef.current.value = "";
|
|
1313
|
+
return [];
|
|
1314
|
+
}
|
|
1315
|
+
const total = files.length + newFiles.length;
|
|
1316
|
+
if (total > maxFiles) {
|
|
1317
|
+
setErrorMessage(`You can only upload up to ${maxFiles} files.`);
|
|
1318
|
+
inputRef.current.value = "";
|
|
1319
|
+
return [];
|
|
1320
|
+
}
|
|
1321
|
+
return newFiles;
|
|
1322
|
+
};
|
|
1323
|
+
const renderPreview = () => {
|
|
1324
|
+
return files.map((file, index) => /* @__PURE__ */ jsxs(
|
|
1325
|
+
"div",
|
|
1326
|
+
{
|
|
1327
|
+
onClick: (e) => e.stopPropagation(),
|
|
1328
|
+
className: "relative pt-7 pb-3 px-5 border border-secondary dark:border-secondary-dark-700 rounded max-w-sm cursor-default",
|
|
1329
|
+
children: [
|
|
1330
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center max-w-full h-56 mb-3", children: file.type.startsWith("image/") ? /* @__PURE__ */ jsx("img", { src: URL.createObjectURL(file), alt: file.name, className: "max-w-full h-56 object-cover" }) : /* @__PURE__ */ jsx("div", { className: "text-secondary dark:text-secondary-dark text-sm italic", children: "Preview not available" }) }),
|
|
1331
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-secondary dark:text-secondary-dark text-center", children: file.name }),
|
|
1332
|
+
clearable && files.length > 0 && /* @__PURE__ */ jsx("div", { className: "absolute top-0 right-0 z-10", children: /* @__PURE__ */ jsx("button", { onClick: (event) => handleClear(event, index), className: "w-auto h-auto py-2 px-2 bg-error text-white rounded-xs hover:cursor-pointer", children: /* @__PURE__ */ jsx(
|
|
1333
|
+
"svg",
|
|
1334
|
+
{
|
|
1335
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1336
|
+
viewBox: "0 0 256 256",
|
|
1337
|
+
className: "w-4 h-4 fill-white",
|
|
1338
|
+
children: /* @__PURE__ */ jsx("g", { fill: "currentColor", fillRule: "nonzero", stroke: "none", strokeWidth: "1", strokeLinecap: "butt", strokeLinejoin: "miter", strokeMiterlimit: "10", strokeDasharray: "", strokeDashoffset: "0", fontFamily: "none", fontWeight: "none", fontSize: "none", textAnchor: "none", style: { mixBlendMode: "normal" }, children: /* @__PURE__ */ jsx("g", { transform: "scale(5.33333,5.33333)", children: /* @__PURE__ */ jsx("path", { d: "M39.48633,6.97852c-0.39614,0.00936 -0.77249,0.17506 -1.04687,0.46094l-14.43945,14.43945l-14.43945,-14.43945c-0.28248,-0.2909 -0.67069,-0.45506 -1.07617,-0.45508c-0.61064,0.00015 -1.16026,0.37042 -1.38978,0.93629c-0.22952,0.56587 -0.09314,1.21439 0.34486,1.63988l14.43945,14.43945l-14.43945,14.43945c-0.39185,0.37623 -0.54969,0.9349 -0.41265,1.46055c0.13704,0.52565 0.54754,0.93616 1.07319,1.07319c0.52565,0.13704 1.08432,-0.02081 1.46055,-0.41265l14.43945,-14.43945l14.43945,14.43945c0.37623,0.39185 0.9349,0.54969 1.46055,0.41265c0.52565,-0.13704 0.93616,-0.54754 1.07319,-1.07319c0.13704,-0.52565 -0.0208,-1.08432 -0.41265,-1.46055l-14.43945,-14.43945l14.43945,-14.43945c0.44646,-0.42851 0.58398,-1.08719 0.34628,-1.65854c-0.2377,-0.57135 -0.80184,-0.93811 -1.4205,-0.92349z" }) }) })
|
|
1339
|
+
}
|
|
1340
|
+
) }) })
|
|
1341
|
+
]
|
|
1342
|
+
},
|
|
1343
|
+
index
|
|
1344
|
+
));
|
|
1345
|
+
};
|
|
1346
|
+
if (mode === "dropzone") {
|
|
1347
|
+
return /* @__PURE__ */ jsxs("div", { className: "", children: [
|
|
1348
|
+
/* @__PURE__ */ jsxs(
|
|
1349
|
+
"div",
|
|
1350
|
+
{
|
|
1351
|
+
className: cn(
|
|
1352
|
+
"flex gap-5 flex-wrap items-center-safe justify-center-safe border-4 border-dashed rounded-lg p-6 text-center cursor-pointer dark:text-white",
|
|
1353
|
+
isDragActive ? "border-info dark:border-info-dark" : "border-secondary dark:border-secondary-dark"
|
|
1354
|
+
),
|
|
1355
|
+
onDragEnter: handleDragEnter,
|
|
1356
|
+
onDragOver: handleDragEnter,
|
|
1357
|
+
onDragLeave: handleDragLeave,
|
|
1358
|
+
onDrop: handleDrop,
|
|
1359
|
+
onClick: handleClick,
|
|
1360
|
+
children: [
|
|
1361
|
+
/* @__PURE__ */ jsx(
|
|
1362
|
+
"input",
|
|
1363
|
+
{
|
|
1364
|
+
type: "file",
|
|
1365
|
+
ref: inputRef,
|
|
1366
|
+
className: "hidden",
|
|
1367
|
+
accept: acceptedFiles,
|
|
1368
|
+
multiple: maxFiles > 1,
|
|
1369
|
+
capture: mediaCapture,
|
|
1370
|
+
onChange: handleFileChange
|
|
1371
|
+
}
|
|
1372
|
+
),
|
|
1373
|
+
files.length > 0 ? renderPreview() : /* @__PURE__ */ jsx("p", { className: "text-sm md:text-base", children: "Drag & drop files here, or click to select files" })
|
|
1374
|
+
]
|
|
1375
|
+
}
|
|
1376
|
+
),
|
|
1377
|
+
errorMessage ? /* @__PURE__ */ jsx("p", { className: "text-error text-sm mt-2", children: errorMessage }) : helperText && /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 dark:text-secondary-dark mt-2", children: helperText })
|
|
1378
|
+
] });
|
|
1379
|
+
}
|
|
1380
|
+
return /* @__PURE__ */ jsxs("div", { onClick: handleClick, className: "cursor-pointer inline-block", children: [
|
|
1381
|
+
/* @__PURE__ */ jsx(
|
|
1382
|
+
"input",
|
|
1383
|
+
{
|
|
1384
|
+
type: "file",
|
|
1385
|
+
ref: inputRef,
|
|
1386
|
+
accept: acceptedFiles,
|
|
1387
|
+
multiple: maxFiles > 1,
|
|
1388
|
+
capture: mediaCapture,
|
|
1389
|
+
onChange: handleFileChange,
|
|
1390
|
+
className: "hidden"
|
|
1391
|
+
}
|
|
1392
|
+
),
|
|
1393
|
+
/* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-2 px-4 py-2 border border-secondary rounded bg-gray-50 hover:bg-secondary-30 text-sm dark:border-secondary-dark dark:bg-gray-700 dark:hover:bg-secondary-dark-700 dark:text-white", children: /* @__PURE__ */ jsx("span", { className: "font-medium", children: files.length > 0 ? `${files.length} file${files.length > 1 ? "s" : ""} selected` : inputLabel ?? "Choose file" }) }),
|
|
1394
|
+
files.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex gap-5 flex-wrap mt-2", children: renderPreview() }),
|
|
1395
|
+
errorMessage ? /* @__PURE__ */ jsx("p", { className: "text-error text-sm mt-2", children: errorMessage }) : helperText && /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 dark:text-secondary-dark mt-2", children: helperText })
|
|
1396
|
+
] });
|
|
1397
|
+
};
|
|
1398
|
+
const responsiveColsClass$1 = {
|
|
1399
|
+
base: {
|
|
1400
|
+
1: "grid-cols-1",
|
|
1401
|
+
2: "grid-cols-2",
|
|
1402
|
+
3: "grid-cols-3",
|
|
1403
|
+
4: "grid-cols-4",
|
|
1404
|
+
5: "grid-cols-5",
|
|
1405
|
+
6: "grid-cols-6",
|
|
1406
|
+
7: "grid-cols-7",
|
|
1407
|
+
8: "grid-cols-8",
|
|
1408
|
+
9: "grid-cols-9",
|
|
1409
|
+
10: "grid-cols-10",
|
|
1410
|
+
11: "grid-cols-11",
|
|
1411
|
+
12: "grid-cols-12"
|
|
1412
|
+
},
|
|
1413
|
+
sm: {
|
|
1414
|
+
1: "sm:grid-cols-1",
|
|
1415
|
+
2: "sm:grid-cols-2",
|
|
1416
|
+
3: "sm:grid-cols-3",
|
|
1417
|
+
4: "sm:grid-cols-4",
|
|
1418
|
+
5: "sm:grid-cols-5",
|
|
1419
|
+
6: "sm:grid-cols-6",
|
|
1420
|
+
7: "sm:grid-cols-7",
|
|
1421
|
+
8: "sm:grid-cols-8",
|
|
1422
|
+
9: "sm:grid-cols-9",
|
|
1423
|
+
10: "sm:grid-cols-10",
|
|
1424
|
+
11: "sm:grid-cols-11",
|
|
1425
|
+
12: "sm:grid-cols-12"
|
|
1426
|
+
},
|
|
1427
|
+
md: {
|
|
1428
|
+
1: "md:grid-cols-1",
|
|
1429
|
+
2: "md:grid-cols-2",
|
|
1430
|
+
3: "md:grid-cols-3",
|
|
1431
|
+
4: "md:grid-cols-4",
|
|
1432
|
+
5: "md:grid-cols-5",
|
|
1433
|
+
6: "md:grid-cols-6",
|
|
1434
|
+
7: "md:grid-cols-7",
|
|
1435
|
+
8: "md:grid-cols-8",
|
|
1436
|
+
9: "md:grid-cols-9",
|
|
1437
|
+
10: "md:grid-cols-10",
|
|
1438
|
+
11: "md:grid-cols-11",
|
|
1439
|
+
12: "md:grid-cols-12"
|
|
1440
|
+
},
|
|
1441
|
+
lg: {
|
|
1442
|
+
1: "lg:grid-cols-1",
|
|
1443
|
+
2: "lg:grid-cols-2",
|
|
1444
|
+
3: "lg:grid-cols-3",
|
|
1445
|
+
4: "lg:grid-cols-4",
|
|
1446
|
+
5: "lg:grid-cols-5",
|
|
1447
|
+
6: "lg:grid-cols-6",
|
|
1448
|
+
7: "lg:grid-cols-7",
|
|
1449
|
+
8: "lg:grid-cols-8",
|
|
1450
|
+
9: "lg:grid-cols-9",
|
|
1451
|
+
10: "lg:grid-cols-10",
|
|
1452
|
+
11: "lg:grid-cols-11",
|
|
1453
|
+
12: "lg:grid-cols-12"
|
|
1454
|
+
},
|
|
1455
|
+
xl: {
|
|
1456
|
+
1: "xl:grid-cols-1",
|
|
1457
|
+
2: "xl:grid-cols-2",
|
|
1458
|
+
3: "xl:grid-cols-3",
|
|
1459
|
+
4: "xl:grid-cols-4",
|
|
1460
|
+
5: "xl:grid-cols-5",
|
|
1461
|
+
6: "xl:grid-cols-6",
|
|
1462
|
+
7: "xl:grid-cols-7",
|
|
1463
|
+
8: "xl:grid-cols-8",
|
|
1464
|
+
9: "xl:grid-cols-9",
|
|
1465
|
+
10: "xl:grid-cols-10",
|
|
1466
|
+
11: "xl:grid-cols-11",
|
|
1467
|
+
12: "xl:grid-cols-12"
|
|
1468
|
+
},
|
|
1469
|
+
"2xl": {
|
|
1470
|
+
1: "2xl:grid-cols-1",
|
|
1471
|
+
2: "2xl:grid-cols-2",
|
|
1472
|
+
3: "2xl:grid-cols-3",
|
|
1473
|
+
4: "2xl:grid-cols-4",
|
|
1474
|
+
5: "2xl:grid-cols-5",
|
|
1475
|
+
6: "2xl:grid-cols-6",
|
|
1476
|
+
7: "2xl:grid-cols-7",
|
|
1477
|
+
8: "2xl:grid-cols-8",
|
|
1478
|
+
9: "2xl:grid-cols-9",
|
|
1479
|
+
10: "2xl:grid-cols-10",
|
|
1480
|
+
11: "2xl:grid-cols-11",
|
|
1481
|
+
12: "2xl:grid-cols-12"
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1484
|
+
const responsiveGapClass$1 = {
|
|
1485
|
+
base: {
|
|
1486
|
+
1: "gap-1",
|
|
1487
|
+
2: "gap-2",
|
|
1488
|
+
3: "gap-3",
|
|
1489
|
+
4: "gap-4",
|
|
1490
|
+
5: "gap-5",
|
|
1491
|
+
6: "gap-6"
|
|
1492
|
+
},
|
|
1493
|
+
sm: {
|
|
1494
|
+
1: "sm:gap-1",
|
|
1495
|
+
2: "sm:gap-2",
|
|
1496
|
+
3: "sm:gap-3",
|
|
1497
|
+
4: "sm:gap-4",
|
|
1498
|
+
5: "sm:gap-5",
|
|
1499
|
+
6: "sm:gap-6"
|
|
1500
|
+
},
|
|
1501
|
+
md: {
|
|
1502
|
+
1: "md:gap-1",
|
|
1503
|
+
2: "md:gap-2",
|
|
1504
|
+
3: "md:gap-3",
|
|
1505
|
+
4: "md:gap-4",
|
|
1506
|
+
5: "md:gap-5",
|
|
1507
|
+
6: "md:gap-6"
|
|
1508
|
+
},
|
|
1509
|
+
lg: {
|
|
1510
|
+
1: "lg:gap-1",
|
|
1511
|
+
2: "lg:gap-2",
|
|
1512
|
+
3: "lg:gap-3",
|
|
1513
|
+
4: "lg:gap-4",
|
|
1514
|
+
5: "lg:gap-5",
|
|
1515
|
+
6: "lg:gap-6"
|
|
1516
|
+
},
|
|
1517
|
+
xl: {
|
|
1518
|
+
1: "xl:gap-1",
|
|
1519
|
+
2: "xl:gap-2",
|
|
1520
|
+
3: "xl:gap-3",
|
|
1521
|
+
4: "xl:gap-4",
|
|
1522
|
+
5: "xl:gap-5",
|
|
1523
|
+
6: "xl:gap-6"
|
|
1524
|
+
},
|
|
1525
|
+
"2xl": {
|
|
1526
|
+
1: "2xl:gap-1",
|
|
1527
|
+
2: "2xl:gap-2",
|
|
1528
|
+
3: "2xl:gap-3",
|
|
1529
|
+
4: "2xl:gap-4",
|
|
1530
|
+
5: "2xl:gap-5",
|
|
1531
|
+
6: "2xl:gap-6"
|
|
1532
|
+
}
|
|
1533
|
+
};
|
|
1534
|
+
function normalizeResponsiveProp$2(value) {
|
|
1535
|
+
if (typeof value === "number") {
|
|
1536
|
+
return { base: value };
|
|
1537
|
+
}
|
|
1538
|
+
return value;
|
|
1539
|
+
}
|
|
1540
|
+
function getResponsiveColsClasses$1(values) {
|
|
1541
|
+
if (!values) return [];
|
|
1542
|
+
return Object.entries(values).map(([breakpoint, value]) => {
|
|
1543
|
+
return responsiveColsClass$1[breakpoint]?.[value] ?? "";
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1546
|
+
function getResponsiveGapClasses$1(values) {
|
|
1547
|
+
if (!values) return [];
|
|
1548
|
+
return Object.entries(values).map(([breakpoint, value]) => {
|
|
1549
|
+
return responsiveGapClass$1[breakpoint]?.[value] ?? "";
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
const Grid = ({ className, cols, gap, children, style, ...props }) => {
|
|
1553
|
+
const colsClasses = getResponsiveColsClasses$1(normalizeResponsiveProp$2(cols));
|
|
1554
|
+
const gapClasses = getResponsiveGapClasses$1(normalizeResponsiveProp$2(gap));
|
|
1555
|
+
return /* @__PURE__ */ jsx(
|
|
1556
|
+
"div",
|
|
1557
|
+
{
|
|
1558
|
+
className: cn(
|
|
1559
|
+
"grid",
|
|
1560
|
+
colsClasses,
|
|
1561
|
+
gapClasses,
|
|
1562
|
+
className
|
|
1563
|
+
),
|
|
1564
|
+
...props,
|
|
1565
|
+
children
|
|
1566
|
+
}
|
|
1567
|
+
);
|
|
1568
|
+
};
|
|
1569
|
+
const responsiveColSpanClass = {
|
|
1570
|
+
base: {
|
|
1571
|
+
1: "col-span-1",
|
|
1572
|
+
2: "col-span-2",
|
|
1573
|
+
3: "col-span-3",
|
|
1574
|
+
4: "col-span-4",
|
|
1575
|
+
5: "col-span-5",
|
|
1576
|
+
6: "col-span-6",
|
|
1577
|
+
7: "col-span-7",
|
|
1578
|
+
8: "col-span-8",
|
|
1579
|
+
9: "col-span-9",
|
|
1580
|
+
10: "col-span-10",
|
|
1581
|
+
11: "col-span-11",
|
|
1582
|
+
12: "col-span-12",
|
|
1583
|
+
full: "col-span-full"
|
|
1584
|
+
},
|
|
1585
|
+
sm: {
|
|
1586
|
+
1: "sm:col-span-1",
|
|
1587
|
+
2: "sm:col-span-2",
|
|
1588
|
+
3: "sm:col-span-3",
|
|
1589
|
+
4: "sm:col-span-4",
|
|
1590
|
+
5: "sm:col-span-5",
|
|
1591
|
+
6: "sm:col-span-6",
|
|
1592
|
+
7: "sm:col-span-7",
|
|
1593
|
+
8: "sm:col-span-8",
|
|
1594
|
+
9: "sm:col-span-9",
|
|
1595
|
+
10: "sm:col-span-10",
|
|
1596
|
+
11: "sm:col-span-11",
|
|
1597
|
+
12: "sm:col-span-12",
|
|
1598
|
+
full: "sm:col-span-full"
|
|
1599
|
+
},
|
|
1600
|
+
md: {
|
|
1601
|
+
1: "md:col-span-1",
|
|
1602
|
+
2: "md:col-span-2",
|
|
1603
|
+
3: "md:col-span-3",
|
|
1604
|
+
4: "md:col-span-4",
|
|
1605
|
+
5: "md:col-span-5",
|
|
1606
|
+
6: "md:col-span-6",
|
|
1607
|
+
7: "md:col-span-7",
|
|
1608
|
+
8: "md:col-span-8",
|
|
1609
|
+
9: "md:col-span-9",
|
|
1610
|
+
10: "md:col-span-10",
|
|
1611
|
+
11: "md:col-span-11",
|
|
1612
|
+
12: "md:col-span-12",
|
|
1613
|
+
full: "md:col-span-full"
|
|
1614
|
+
},
|
|
1615
|
+
lg: {
|
|
1616
|
+
1: "lg:col-span-1",
|
|
1617
|
+
2: "lg:col-span-2",
|
|
1618
|
+
3: "lg:col-span-3",
|
|
1619
|
+
4: "lg:col-span-4",
|
|
1620
|
+
5: "lg:col-span-5",
|
|
1621
|
+
6: "lg:col-span-6",
|
|
1622
|
+
7: "lg:col-span-7",
|
|
1623
|
+
8: "lg:col-span-8",
|
|
1624
|
+
9: "lg:col-span-9",
|
|
1625
|
+
10: "lg:col-span-10",
|
|
1626
|
+
11: "lg:col-span-11",
|
|
1627
|
+
12: "lg:col-span-12",
|
|
1628
|
+
full: "lg:col-span-full"
|
|
1629
|
+
},
|
|
1630
|
+
xl: {
|
|
1631
|
+
1: "xl:col-span-1",
|
|
1632
|
+
2: "xl:col-span-2",
|
|
1633
|
+
3: "xl:col-span-3",
|
|
1634
|
+
4: "xl:col-span-4",
|
|
1635
|
+
5: "xl:col-span-5",
|
|
1636
|
+
6: "xl:col-span-6",
|
|
1637
|
+
7: "xl:col-span-7",
|
|
1638
|
+
8: "xl:col-span-8",
|
|
1639
|
+
9: "xl:col-span-9",
|
|
1640
|
+
10: "xl:col-span-10",
|
|
1641
|
+
11: "xl:col-span-11",
|
|
1642
|
+
12: "xl:col-span-12",
|
|
1643
|
+
full: "xl:col-span-full"
|
|
1644
|
+
},
|
|
1645
|
+
"2xl": {
|
|
1646
|
+
1: "2xl:col-span-1",
|
|
1647
|
+
2: "2xl:col-span-2",
|
|
1648
|
+
3: "2xl:col-span-3",
|
|
1649
|
+
4: "2xl:col-span-4",
|
|
1650
|
+
5: "2xl:col-span-5",
|
|
1651
|
+
6: "2xl:col-span-6",
|
|
1652
|
+
7: "2xl:col-span-7",
|
|
1653
|
+
8: "2xl:col-span-8",
|
|
1654
|
+
9: "2xl:col-span-9",
|
|
1655
|
+
10: "2xl:col-span-10",
|
|
1656
|
+
11: "2xl:col-span-11",
|
|
1657
|
+
12: "2xl:col-span-12",
|
|
1658
|
+
full: "2xl:col-span-full"
|
|
1659
|
+
}
|
|
1660
|
+
};
|
|
1661
|
+
function normalizeResponsiveProp$1(value) {
|
|
1662
|
+
if (typeof value === "number") {
|
|
1663
|
+
return { base: value };
|
|
1664
|
+
}
|
|
1665
|
+
return value;
|
|
1666
|
+
}
|
|
1667
|
+
function getResponsiveColSpanClasses(values) {
|
|
1668
|
+
if (!values) return [];
|
|
1669
|
+
return Object.entries(values).map(([breakpoint, value]) => {
|
|
1670
|
+
return responsiveColSpanClass[breakpoint]?.[value] ?? "";
|
|
1671
|
+
});
|
|
1672
|
+
}
|
|
1673
|
+
const GridItem = ({
|
|
1674
|
+
className,
|
|
1675
|
+
colSpan,
|
|
1676
|
+
children,
|
|
1677
|
+
...props
|
|
1678
|
+
}) => {
|
|
1679
|
+
const colSpanClasses = getResponsiveColSpanClasses(
|
|
1680
|
+
normalizeResponsiveProp$1(colSpan)
|
|
1681
|
+
);
|
|
1682
|
+
return /* @__PURE__ */ jsx("div", { className: cn(...colSpanClasses, className), ...props, children });
|
|
1683
|
+
};
|
|
1684
|
+
const responsiveColsClass = {
|
|
1685
|
+
base: {
|
|
1686
|
+
1: "columns-1",
|
|
1687
|
+
2: "columns-2",
|
|
1688
|
+
3: "columns-3",
|
|
1689
|
+
4: "columns-4",
|
|
1690
|
+
5: "columns-5",
|
|
1691
|
+
6: "columns-6",
|
|
1692
|
+
7: "columns-7",
|
|
1693
|
+
8: "columns-8",
|
|
1694
|
+
9: "columns-9",
|
|
1695
|
+
10: "columns-10",
|
|
1696
|
+
11: "columns-11",
|
|
1697
|
+
12: "columns-12"
|
|
1698
|
+
},
|
|
1699
|
+
sm: {
|
|
1700
|
+
1: "sm:columns-1",
|
|
1701
|
+
2: "sm:columns-2",
|
|
1702
|
+
3: "sm:columns-3",
|
|
1703
|
+
4: "sm:columns-4",
|
|
1704
|
+
5: "sm:columns-5",
|
|
1705
|
+
6: "sm:columns-6",
|
|
1706
|
+
7: "sm:columns-7",
|
|
1707
|
+
8: "sm:columns-8",
|
|
1708
|
+
9: "sm:columns-9",
|
|
1709
|
+
10: "sm:columns-10",
|
|
1710
|
+
11: "sm:columns-11",
|
|
1711
|
+
12: "sm:columns-12"
|
|
1712
|
+
},
|
|
1713
|
+
md: {
|
|
1714
|
+
1: "md:columns-1",
|
|
1715
|
+
2: "md:columns-2",
|
|
1716
|
+
3: "md:columns-3",
|
|
1717
|
+
4: "md:columns-4",
|
|
1718
|
+
5: "md:columns-5",
|
|
1719
|
+
6: "md:columns-6",
|
|
1720
|
+
7: "md:columns-7",
|
|
1721
|
+
8: "md:columns-8",
|
|
1722
|
+
9: "md:columns-9",
|
|
1723
|
+
10: "md:columns-10",
|
|
1724
|
+
11: "md:columns-11",
|
|
1725
|
+
12: "md:columns-12"
|
|
1726
|
+
},
|
|
1727
|
+
lg: {
|
|
1728
|
+
1: "lg:columns-1",
|
|
1729
|
+
2: "lg:columns-2",
|
|
1730
|
+
3: "lg:columns-3",
|
|
1731
|
+
4: "lg:columns-4",
|
|
1732
|
+
5: "lg:columns-5",
|
|
1733
|
+
6: "lg:columns-6",
|
|
1734
|
+
7: "lg:columns-7",
|
|
1735
|
+
8: "lg:columns-8",
|
|
1736
|
+
9: "lg:columns-9",
|
|
1737
|
+
10: "lg:columns-10",
|
|
1738
|
+
11: "lg:columns-11",
|
|
1739
|
+
12: "lg:columns-12"
|
|
1740
|
+
},
|
|
1741
|
+
xl: {
|
|
1742
|
+
1: "xl:columns-1",
|
|
1743
|
+
2: "xl:columns-2",
|
|
1744
|
+
3: "xl:columns-3",
|
|
1745
|
+
4: "xl:columns-4",
|
|
1746
|
+
5: "xl:columns-5",
|
|
1747
|
+
6: "xl:columns-6",
|
|
1748
|
+
7: "xl:columns-7",
|
|
1749
|
+
8: "xl:columns-8",
|
|
1750
|
+
9: "xl:columns-9",
|
|
1751
|
+
10: "xl:columns-10",
|
|
1752
|
+
11: "xl:columns-11",
|
|
1753
|
+
12: "xl:columns-12"
|
|
1754
|
+
},
|
|
1755
|
+
"2xl": {
|
|
1756
|
+
1: "2xl:columns-1",
|
|
1757
|
+
2: "2xl:columns-2",
|
|
1758
|
+
3: "2xl:columns-3",
|
|
1759
|
+
4: "2xl:columns-4",
|
|
1760
|
+
5: "2xl:columns-5",
|
|
1761
|
+
6: "2xl:columns-6",
|
|
1762
|
+
7: "2xl:columns-7",
|
|
1763
|
+
8: "2xl:columns-8",
|
|
1764
|
+
9: "2xl:columns-9",
|
|
1765
|
+
10: "2xl:columns-10",
|
|
1766
|
+
11: "2xl:columns-11",
|
|
1767
|
+
12: "2xl:columns-12"
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
const responsiveGapClass = {
|
|
1771
|
+
base: {
|
|
1772
|
+
1: "gap-1",
|
|
1773
|
+
2: "gap-2",
|
|
1774
|
+
3: "gap-3",
|
|
1775
|
+
4: "gap-4",
|
|
1776
|
+
5: "gap-5",
|
|
1777
|
+
6: "gap-6"
|
|
1778
|
+
},
|
|
1779
|
+
sm: {
|
|
1780
|
+
1: "sm:gap-1",
|
|
1781
|
+
2: "sm:gap-2",
|
|
1782
|
+
3: "sm:gap-3",
|
|
1783
|
+
4: "sm:gap-4",
|
|
1784
|
+
5: "sm:gap-5",
|
|
1785
|
+
6: "sm:gap-6"
|
|
1786
|
+
},
|
|
1787
|
+
md: {
|
|
1788
|
+
1: "md:gap-1",
|
|
1789
|
+
2: "md:gap-2",
|
|
1790
|
+
3: "md:gap-3",
|
|
1791
|
+
4: "md:gap-4",
|
|
1792
|
+
5: "md:gap-5",
|
|
1793
|
+
6: "md:gap-6"
|
|
1794
|
+
},
|
|
1795
|
+
lg: {
|
|
1796
|
+
1: "lg:gap-1",
|
|
1797
|
+
2: "lg:gap-2",
|
|
1798
|
+
3: "lg:gap-3",
|
|
1799
|
+
4: "lg:gap-4",
|
|
1800
|
+
5: "lg:gap-5",
|
|
1801
|
+
6: "lg:gap-6"
|
|
1802
|
+
},
|
|
1803
|
+
xl: {
|
|
1804
|
+
1: "xl:gap-1",
|
|
1805
|
+
2: "xl:gap-2",
|
|
1806
|
+
3: "xl:gap-3",
|
|
1807
|
+
4: "xl:gap-4",
|
|
1808
|
+
5: "xl:gap-5",
|
|
1809
|
+
6: "xl:gap-6"
|
|
1810
|
+
},
|
|
1811
|
+
"2xl": {
|
|
1812
|
+
1: "2xl:gap-1",
|
|
1813
|
+
2: "2xl:gap-2",
|
|
1814
|
+
3: "2xl:gap-3",
|
|
1815
|
+
4: "2xl:gap-4",
|
|
1816
|
+
5: "2xl:gap-5",
|
|
1817
|
+
6: "2xl:gap-6"
|
|
1818
|
+
}
|
|
1819
|
+
};
|
|
1820
|
+
function normalizeResponsiveProp(value) {
|
|
1821
|
+
if (typeof value === "number") {
|
|
1822
|
+
return { base: value };
|
|
1823
|
+
}
|
|
1824
|
+
return value;
|
|
1825
|
+
}
|
|
1826
|
+
function getResponsiveColsClasses(values) {
|
|
1827
|
+
if (!values) return [];
|
|
1828
|
+
return Object.entries(values).map(([breakpoint, value]) => {
|
|
1829
|
+
return responsiveColsClass[breakpoint]?.[value] ?? "";
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
function getResponsiveGapClasses(values) {
|
|
1833
|
+
if (!values) return [];
|
|
1834
|
+
return Object.entries(values).map(([breakpoint, value]) => {
|
|
1835
|
+
return responsiveGapClass[breakpoint]?.[value] ?? "";
|
|
1836
|
+
});
|
|
1837
|
+
}
|
|
1838
|
+
const Masonry = React.forwardRef(
|
|
1839
|
+
({ children, className, cols, gap = 4, ...props }, ref) => {
|
|
1840
|
+
const colsClasses = getResponsiveColsClasses(normalizeResponsiveProp(cols));
|
|
1841
|
+
const gapClasses = getResponsiveGapClasses(normalizeResponsiveProp(gap));
|
|
1842
|
+
return /* @__PURE__ */ jsx(
|
|
1843
|
+
"div",
|
|
1844
|
+
{
|
|
1845
|
+
ref,
|
|
1846
|
+
className: cn("grid-mason", colsClasses, gapClasses, className),
|
|
1847
|
+
...props,
|
|
1848
|
+
children
|
|
1849
|
+
}
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1852
|
+
);
|
|
1853
|
+
const ToastVariants = {
|
|
1854
|
+
outline: "border border-current",
|
|
1855
|
+
solid: ""
|
|
1856
|
+
};
|
|
1857
|
+
const ToastPositions = {
|
|
1858
|
+
topLeft: "top-5 left-5",
|
|
1859
|
+
bottomLeft: "bottom-5 left-5",
|
|
1860
|
+
topRight: "top-5 right-5",
|
|
1861
|
+
bottomRight: "bottom-5 right-5"
|
|
1862
|
+
};
|
|
1863
|
+
const ToastTypes = {
|
|
1864
|
+
success: "bg-success-30 border-success-700 text-success-700",
|
|
1865
|
+
info: "bg-info-30 border-info-700 text-info-700",
|
|
1866
|
+
warning: "bg-warning-30 border-warning-700 text-warning-700",
|
|
1867
|
+
error: "bg-error-30 border-error-700 text-error-700"
|
|
1868
|
+
};
|
|
1869
|
+
const enterAnimationByPosition = {
|
|
1870
|
+
topRight: "translate-x-0",
|
|
1871
|
+
bottomRight: "translate-x-0",
|
|
1872
|
+
topLeft: "-translate-x-0",
|
|
1873
|
+
bottomLeft: "-translate-x-0"
|
|
1874
|
+
};
|
|
1875
|
+
const exitAnimationByPosition = {
|
|
1876
|
+
topRight: "translate-x-40",
|
|
1877
|
+
bottomRight: "translate-x-40",
|
|
1878
|
+
topLeft: "-translate-x-40",
|
|
1879
|
+
bottomLeft: "-translate-x-40"
|
|
1880
|
+
};
|
|
1881
|
+
const initialAnimationByPosition = {
|
|
1882
|
+
topRight: "translate-x-10",
|
|
1883
|
+
bottomRight: "translate-x-10",
|
|
1884
|
+
topLeft: "-translate-x-10",
|
|
1885
|
+
bottomLeft: "-translate-x-10"
|
|
1886
|
+
};
|
|
1887
|
+
const Toast = ({
|
|
1888
|
+
title,
|
|
1889
|
+
message,
|
|
1890
|
+
type,
|
|
1891
|
+
icon,
|
|
1892
|
+
position = "bottomRight",
|
|
1893
|
+
variant = "solid",
|
|
1894
|
+
onClose
|
|
1895
|
+
}) => {
|
|
1896
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
1897
|
+
const [isFadingOut, setIsFadingOut] = useState(false);
|
|
1898
|
+
const timeoutRef = React.useRef(null);
|
|
1899
|
+
useEffect(() => {
|
|
1900
|
+
setTimeout(() => setIsVisible(true), 50);
|
|
1901
|
+
timeoutRef.current = setTimeout(() => {
|
|
1902
|
+
handleClose();
|
|
1903
|
+
}, 3500);
|
|
1904
|
+
return () => {
|
|
1905
|
+
timeoutRef.current && clearTimeout(timeoutRef.current);
|
|
1906
|
+
};
|
|
1907
|
+
}, []);
|
|
1908
|
+
const handleClose = () => {
|
|
1909
|
+
setIsFadingOut(true);
|
|
1910
|
+
setTimeout(() => {
|
|
1911
|
+
if (onClose) onClose();
|
|
1912
|
+
}, 500);
|
|
1913
|
+
};
|
|
1914
|
+
const handleOnMouseEnter = () => {
|
|
1915
|
+
if (timeoutRef.current) {
|
|
1916
|
+
clearTimeout(timeoutRef.current);
|
|
1917
|
+
timeoutRef.current = null;
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
const handleOnMouseLeave = () => {
|
|
1921
|
+
timeoutRef.current = setTimeout(() => {
|
|
1922
|
+
handleClose();
|
|
1923
|
+
}, 3500);
|
|
1924
|
+
};
|
|
1925
|
+
return /* @__PURE__ */ jsxs(
|
|
1926
|
+
"div",
|
|
1927
|
+
{
|
|
1928
|
+
onMouseEnter: handleOnMouseEnter,
|
|
1929
|
+
onMouseLeave: handleOnMouseLeave,
|
|
1930
|
+
className: cn(
|
|
1931
|
+
`flex max-w-sm items-start gap-3 p-4 mb-3 rounded-lg shadow-lg transition-all duration-500 transform`,
|
|
1932
|
+
ToastTypes[type],
|
|
1933
|
+
ToastVariants[variant],
|
|
1934
|
+
isFadingOut ? `opacity-0 ${exitAnimationByPosition[position]}` : isVisible ? `opacity-100 ${enterAnimationByPosition[position]}` : `opacity-0 ${initialAnimationByPosition[position]}`
|
|
1935
|
+
),
|
|
1936
|
+
children: [
|
|
1937
|
+
icon && /* @__PURE__ */ jsx("div", { className: "text-2xl mt-1", children: icon }),
|
|
1938
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
1939
|
+
title && /* @__PURE__ */ jsx("p", { className: "font-semibold text-base mb-1", children: title }),
|
|
1940
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm leading-snug", children: message })
|
|
1941
|
+
] }),
|
|
1942
|
+
/* @__PURE__ */ jsx(
|
|
1943
|
+
"button",
|
|
1944
|
+
{
|
|
1945
|
+
onClick: handleClose,
|
|
1946
|
+
className: "ml-2 text-lg leading-none hover:text-red-500 focus:outline-none cursor-pointer",
|
|
1947
|
+
"aria-label": "Close",
|
|
1948
|
+
children: "×"
|
|
1949
|
+
}
|
|
1950
|
+
)
|
|
1951
|
+
]
|
|
1952
|
+
}
|
|
1953
|
+
);
|
|
1954
|
+
};
|
|
1955
|
+
const ToastContext = createContext(void 0);
|
|
1956
|
+
const useToast = () => {
|
|
1957
|
+
const context = useContext(ToastContext);
|
|
1958
|
+
if (!context) {
|
|
1959
|
+
throw new Error("useToast must be used within a ToastProvider");
|
|
1960
|
+
}
|
|
1961
|
+
return context;
|
|
1962
|
+
};
|
|
1963
|
+
const ToastProvider = ({ children }) => {
|
|
1964
|
+
const [toasts, setToasts] = useState([]);
|
|
1965
|
+
const addToast = ({
|
|
1966
|
+
title,
|
|
1967
|
+
message,
|
|
1968
|
+
type,
|
|
1969
|
+
variant,
|
|
1970
|
+
icon,
|
|
1971
|
+
onClose,
|
|
1972
|
+
position = "bottomRight"
|
|
1973
|
+
}) => {
|
|
1974
|
+
const id = Date.now();
|
|
1975
|
+
setToasts((prevToasts) => [
|
|
1976
|
+
...prevToasts,
|
|
1977
|
+
{ title, id, message, type, variant, icon, onClose, position }
|
|
1978
|
+
]);
|
|
1979
|
+
};
|
|
1980
|
+
const removeToast = (id) => {
|
|
1981
|
+
setToasts((prevToasts) => prevToasts.filter((toast) => toast.id !== id));
|
|
1982
|
+
};
|
|
1983
|
+
const positions = Object.keys(
|
|
1984
|
+
ToastPositions
|
|
1985
|
+
);
|
|
1986
|
+
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: { addToast }, children: [
|
|
1987
|
+
children,
|
|
1988
|
+
positions.map((pos) => /* @__PURE__ */ jsx("div", { className: `fixed z-50 ${ToastPositions[pos]}`, children: toasts.filter((toast) => toast.position === pos).map((toast) => /* @__PURE__ */ jsx(
|
|
1989
|
+
Toast,
|
|
1990
|
+
{
|
|
1991
|
+
title: toast.title,
|
|
1992
|
+
message: toast.message,
|
|
1993
|
+
type: toast.type,
|
|
1994
|
+
variant: toast.variant,
|
|
1995
|
+
icon: toast.icon,
|
|
1996
|
+
position: toast.position,
|
|
1997
|
+
onClose: () => removeToast(toast.id)
|
|
1998
|
+
},
|
|
1999
|
+
toast.id
|
|
2000
|
+
)) }, pos))
|
|
2001
|
+
] });
|
|
2002
|
+
};
|
|
2003
|
+
const sizeClasses = {
|
|
2004
|
+
sm: "max-w-sm",
|
|
2005
|
+
md: "max-w-md",
|
|
2006
|
+
lg: "max-w-2xl",
|
|
2007
|
+
xl: "max-w-4xl"
|
|
2008
|
+
};
|
|
2009
|
+
const Modal = ({
|
|
2010
|
+
isOpen,
|
|
2011
|
+
overlayClose = true,
|
|
2012
|
+
onClose,
|
|
2013
|
+
title,
|
|
2014
|
+
children,
|
|
2015
|
+
showCloseButton = true,
|
|
2016
|
+
size = "md",
|
|
2017
|
+
className
|
|
2018
|
+
}) => {
|
|
2019
|
+
useEffect(() => {
|
|
2020
|
+
const handleEsc = (e) => {
|
|
2021
|
+
if (e.key === "Escape") onClose();
|
|
2022
|
+
};
|
|
2023
|
+
if (isOpen) document.addEventListener("keydown", handleEsc);
|
|
2024
|
+
return () => document.removeEventListener("keydown", handleEsc);
|
|
2025
|
+
}, [isOpen, onClose]);
|
|
2026
|
+
if (!isOpen) return null;
|
|
2027
|
+
return /* @__PURE__ */ jsxs(
|
|
2028
|
+
"div",
|
|
2029
|
+
{
|
|
2030
|
+
className: "fixed inset-0 z-[999] flex items-center justify-center px-4",
|
|
2031
|
+
role: "dialog",
|
|
2032
|
+
"aria-modal": "true",
|
|
2033
|
+
children: [
|
|
2034
|
+
/* @__PURE__ */ jsx(
|
|
2035
|
+
"div",
|
|
2036
|
+
{
|
|
2037
|
+
className: "absolute inset-0 bg-black/50 backdrop-blur-sm",
|
|
2038
|
+
onClick: overlayClose ? onClose : void 0
|
|
2039
|
+
}
|
|
2040
|
+
),
|
|
2041
|
+
/* @__PURE__ */ jsxs(
|
|
2042
|
+
"div",
|
|
2043
|
+
{
|
|
2044
|
+
className: cn(
|
|
2045
|
+
"relative z-10 bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-h-[90vh] overflow-y-auto transition-all",
|
|
2046
|
+
sizeClasses[size],
|
|
2047
|
+
className
|
|
2048
|
+
),
|
|
2049
|
+
onClick: (e) => e.stopPropagation(),
|
|
2050
|
+
children: [
|
|
2051
|
+
(title || showCloseButton) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700", children: [
|
|
2052
|
+
title && /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-gray-800 dark:text-white", children: title }),
|
|
2053
|
+
showCloseButton && /* @__PURE__ */ jsx(
|
|
2054
|
+
"button",
|
|
2055
|
+
{
|
|
2056
|
+
onClick: onClose,
|
|
2057
|
+
className: "text-gray-500 hover:text-gray-800 transition dark:text-gray-400 dark:hover:text-white hover:cursor-pointer",
|
|
2058
|
+
"aria-label": "Close modal",
|
|
2059
|
+
children: "✕"
|
|
2060
|
+
}
|
|
2061
|
+
)
|
|
2062
|
+
] }),
|
|
2063
|
+
/* @__PURE__ */ jsx("div", { className: "p-4", children })
|
|
2064
|
+
]
|
|
2065
|
+
}
|
|
2066
|
+
)
|
|
2067
|
+
]
|
|
2068
|
+
}
|
|
2069
|
+
);
|
|
2070
|
+
};
|
|
2071
|
+
const OffcanvasWidthVariants = {
|
|
2072
|
+
default: "w-3/4 md:w-1/2",
|
|
2073
|
+
sm: "w-3/4 md:w-60",
|
|
2074
|
+
md: "w-3/4 md:w-80",
|
|
2075
|
+
lg: "w-3/4 md:w-[40rem]"
|
|
2076
|
+
};
|
|
2077
|
+
const Offcanvas = ({
|
|
2078
|
+
isOpen,
|
|
2079
|
+
onClose,
|
|
2080
|
+
title,
|
|
2081
|
+
children,
|
|
2082
|
+
position = "right",
|
|
2083
|
+
width = "default",
|
|
2084
|
+
titleClassName,
|
|
2085
|
+
closeButtonClassName,
|
|
2086
|
+
className
|
|
2087
|
+
}) => {
|
|
2088
|
+
const positionClasses = position === "right" ? "right-0" : "left-0";
|
|
2089
|
+
const animationClasses = isOpen ? "translate-x-0" : position === "right" ? "translate-x-full" : "-translate-x-full";
|
|
2090
|
+
const baseClasses = "fixed top-0 h-full bg-white dark:bg-gray-700 z-50 shadow-xl transform transition-transform duration-300 ease-in-out";
|
|
2091
|
+
const offcanvasClassName = cn(
|
|
2092
|
+
baseClasses,
|
|
2093
|
+
OffcanvasWidthVariants[width],
|
|
2094
|
+
positionClasses,
|
|
2095
|
+
animationClasses,
|
|
2096
|
+
className
|
|
2097
|
+
);
|
|
2098
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2099
|
+
isOpen && /* @__PURE__ */ jsx(
|
|
2100
|
+
"div",
|
|
2101
|
+
{
|
|
2102
|
+
className: "fixed inset-0 bg-black/50 z-40",
|
|
2103
|
+
onClick: onClose
|
|
2104
|
+
}
|
|
2105
|
+
),
|
|
2106
|
+
/* @__PURE__ */ jsxs("div", { className: offcanvasClassName, children: [
|
|
2107
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center p-4 border-b border-secondary dark:border-secondary-dark", children: [
|
|
2108
|
+
/* @__PURE__ */ jsx("h5", { className: cn("text-lg font-semibold dark:text-white", titleClassName), children: title }),
|
|
2109
|
+
/* @__PURE__ */ jsx(
|
|
2110
|
+
"button",
|
|
2111
|
+
{
|
|
2112
|
+
type: "button",
|
|
2113
|
+
onClick: onClose,
|
|
2114
|
+
className: cn("text-secondary-700 hover:text-secondary dark:hover:text-secondary-dark text-2xl dark:text-white hover:cursor-pointer", closeButtonClassName),
|
|
2115
|
+
"aria-label": "Close",
|
|
2116
|
+
children: "×"
|
|
2117
|
+
}
|
|
2118
|
+
)
|
|
2119
|
+
] }),
|
|
2120
|
+
/* @__PURE__ */ jsx("div", { className: "p-4 overflow-y-auto", children })
|
|
2121
|
+
] })
|
|
2122
|
+
] });
|
|
2123
|
+
};
|
|
2124
|
+
const PaginationSizes = {
|
|
2125
|
+
sm: "px-3 py-2 text-sm font-medium rounded-lg",
|
|
2126
|
+
md: "px-4 py-2 text-base font-medium rounded-lg",
|
|
2127
|
+
lg: "px-6 py-3 text-lg font-medium rounded-lg"
|
|
2128
|
+
};
|
|
2129
|
+
const Pagination = ({
|
|
2130
|
+
currentPage,
|
|
2131
|
+
simplified = false,
|
|
2132
|
+
format = "none",
|
|
2133
|
+
count,
|
|
2134
|
+
pageSize,
|
|
2135
|
+
asLink = false,
|
|
2136
|
+
getPageHref,
|
|
2137
|
+
totalPages: customTotalPages,
|
|
2138
|
+
onPageChange,
|
|
2139
|
+
siblingCount = 1,
|
|
2140
|
+
prevIcon,
|
|
2141
|
+
nextIcon,
|
|
2142
|
+
size = "sm"
|
|
2143
|
+
}) => {
|
|
2144
|
+
if (process.env.NODE_ENV !== "production" && count && pageSize && customTotalPages && Math.ceil(count / pageSize) !== customTotalPages) {
|
|
2145
|
+
console.warn(
|
|
2146
|
+
'[Pagination] Both "count/pageSize" and "totalPages" props are provided, but are inconsistent. "totalPages" will be ignored in favor of count/pageSize.'
|
|
2147
|
+
);
|
|
2148
|
+
}
|
|
2149
|
+
const totalPages = count && pageSize && siblingCount === 1 ? Math.ceil(count / pageSize) : customTotalPages ?? 1;
|
|
2150
|
+
if (totalPages <= 1) return null;
|
|
2151
|
+
const DOTS = "...";
|
|
2152
|
+
const createPageRange = () => {
|
|
2153
|
+
const totalPageNumbers = siblingCount * 2 + 5;
|
|
2154
|
+
if (totalPageNumbers >= totalPages) {
|
|
2155
|
+
return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
2156
|
+
}
|
|
2157
|
+
const leftSiblingIndex = Math.max(currentPage - siblingCount, 1);
|
|
2158
|
+
const rightSiblingIndex = Math.min(currentPage + siblingCount, totalPages);
|
|
2159
|
+
const shouldShowLeftDots = leftSiblingIndex > 2;
|
|
2160
|
+
const shouldShowRightDots = rightSiblingIndex < totalPages - 1;
|
|
2161
|
+
const firstPageIndex = 1;
|
|
2162
|
+
const lastPageIndex = totalPages;
|
|
2163
|
+
if (!shouldShowLeftDots && shouldShowRightDots) {
|
|
2164
|
+
const leftItemCount = 3 + 2 * siblingCount;
|
|
2165
|
+
const leftRange = Array.from({ length: leftItemCount }, (_, i) => i + 1);
|
|
2166
|
+
return [...leftRange, DOTS, totalPages];
|
|
2167
|
+
}
|
|
2168
|
+
if (shouldShowLeftDots && !shouldShowRightDots) {
|
|
2169
|
+
const rightItemCount = 3 + 2 * siblingCount;
|
|
2170
|
+
const rightRange = Array.from(
|
|
2171
|
+
{ length: rightItemCount },
|
|
2172
|
+
(_, i) => totalPages - rightItemCount + 1 + i
|
|
2173
|
+
);
|
|
2174
|
+
return [firstPageIndex, DOTS, ...rightRange];
|
|
2175
|
+
}
|
|
2176
|
+
if (shouldShowLeftDots && shouldShowRightDots) {
|
|
2177
|
+
const middleRange = Array.from(
|
|
2178
|
+
{ length: rightSiblingIndex - leftSiblingIndex + 1 },
|
|
2179
|
+
(_, i) => leftSiblingIndex + i
|
|
2180
|
+
);
|
|
2181
|
+
return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex];
|
|
2182
|
+
}
|
|
2183
|
+
return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
2184
|
+
};
|
|
2185
|
+
const goToPage = (page) => {
|
|
2186
|
+
const newPage = Math.max(1, Math.min(page, totalPages));
|
|
2187
|
+
if (newPage !== currentPage) {
|
|
2188
|
+
onPageChange(newPage);
|
|
2189
|
+
}
|
|
2190
|
+
};
|
|
2191
|
+
const paginationRange = createPageRange();
|
|
2192
|
+
const sizeClass = PaginationSizes[size] || "";
|
|
2193
|
+
const disabledClass = "opacity-50 pointer-events-none";
|
|
2194
|
+
const getHref = (page) => getPageHref?.(page) ?? `?page=${page}`;
|
|
2195
|
+
const PrevButton = asLink ? /* @__PURE__ */ jsx(
|
|
2196
|
+
"a",
|
|
2197
|
+
{
|
|
2198
|
+
className: cn("px-3 py-1 rounded-lg border dark:border-gray-600 dark:text-white dark:hover:bg-gray-700", sizeClass, currentPage === 1 ? disabledClass : "hover:cursor-pointer"),
|
|
2199
|
+
href: currentPage > 1 ? getHref(currentPage - 1) : void 0,
|
|
2200
|
+
onClick: (e) => {
|
|
2201
|
+
if (currentPage === 1) {
|
|
2202
|
+
e.preventDefault();
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2205
|
+
e.preventDefault();
|
|
2206
|
+
goToPage(currentPage - 1);
|
|
2207
|
+
},
|
|
2208
|
+
"aria-disabled": currentPage === 1,
|
|
2209
|
+
children: prevIcon ?? /* @__PURE__ */ jsx("span", { children: "<" })
|
|
2210
|
+
}
|
|
2211
|
+
) : /* @__PURE__ */ jsx(
|
|
2212
|
+
"button",
|
|
2213
|
+
{
|
|
2214
|
+
className: cn("px-3 py-1 rounded-lg border dark:border-gray-600 dark:text-white dark:hover:bg-gray-700", sizeClass, currentPage === 1 ? disabledClass : "hover:cursor-pointer"),
|
|
2215
|
+
onClick: () => goToPage(currentPage - 1),
|
|
2216
|
+
disabled: currentPage === 1,
|
|
2217
|
+
children: prevIcon ?? /* @__PURE__ */ jsx("span", { children: "<" })
|
|
2218
|
+
}
|
|
2219
|
+
);
|
|
2220
|
+
const NextButton = asLink ? /* @__PURE__ */ jsx(
|
|
2221
|
+
"a",
|
|
2222
|
+
{
|
|
2223
|
+
className: cn("px-3 py-1 rounded-lg border dark:border-gray-600 dark:text-white dark:hover:bg-gray-700", sizeClass, currentPage === totalPages ? disabledClass : "hover:cursor-pointer"),
|
|
2224
|
+
href: currentPage < totalPages ? getHref(currentPage + 1) : void 0,
|
|
2225
|
+
onClick: (e) => {
|
|
2226
|
+
if (currentPage === totalPages) {
|
|
2227
|
+
e.preventDefault();
|
|
2228
|
+
return;
|
|
2229
|
+
}
|
|
2230
|
+
e.preventDefault();
|
|
2231
|
+
goToPage(currentPage + 1);
|
|
2232
|
+
},
|
|
2233
|
+
"aria-disabled": currentPage === totalPages,
|
|
2234
|
+
children: nextIcon ?? /* @__PURE__ */ jsx("span", { children: ">" })
|
|
2235
|
+
}
|
|
2236
|
+
) : /* @__PURE__ */ jsx(
|
|
2237
|
+
"button",
|
|
2238
|
+
{
|
|
2239
|
+
className: cn("px-3 py-1 rounded-lg border dark:border-gray-600 dark:text-white dark:hover:bg-gray-700", sizeClass, currentPage === totalPages ? disabledClass : "hover:cursor-pointer"),
|
|
2240
|
+
onClick: () => goToPage(currentPage + 1),
|
|
2241
|
+
disabled: currentPage === totalPages,
|
|
2242
|
+
children: nextIcon ?? /* @__PURE__ */ jsx("span", { children: ">" })
|
|
2243
|
+
}
|
|
2244
|
+
);
|
|
2245
|
+
const renderPageInfo = () => {
|
|
2246
|
+
if (format === "long" && pageSize && count) {
|
|
2247
|
+
const start = (currentPage - 1) * pageSize + 1;
|
|
2248
|
+
const end = Math.min(currentPage * pageSize, count);
|
|
2249
|
+
return /* @__PURE__ */ jsxs("p", { className: "dark:text-white", children: [
|
|
2250
|
+
"Showing ",
|
|
2251
|
+
start,
|
|
2252
|
+
" - ",
|
|
2253
|
+
end,
|
|
2254
|
+
" of ",
|
|
2255
|
+
count
|
|
2256
|
+
] });
|
|
2257
|
+
}
|
|
2258
|
+
if (format === "none") {
|
|
2259
|
+
return /* @__PURE__ */ jsxs("p", { className: "dark:text-white", children: [
|
|
2260
|
+
currentPage,
|
|
2261
|
+
" of ",
|
|
2262
|
+
totalPages
|
|
2263
|
+
] });
|
|
2264
|
+
}
|
|
2265
|
+
return null;
|
|
2266
|
+
};
|
|
2267
|
+
if (!simplified) {
|
|
2268
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2269
|
+
PrevButton,
|
|
2270
|
+
paginationRange.map((page, idx) => {
|
|
2271
|
+
if (page === "...") {
|
|
2272
|
+
return /* @__PURE__ */ jsx("span", { className: cn("px-3 py-1 text-gray-500 dark:text-gray-400", sizeClass), children: "..." }, idx);
|
|
2273
|
+
}
|
|
2274
|
+
const isActive = page === currentPage;
|
|
2275
|
+
const baseClasses = cn(
|
|
2276
|
+
"px-3 py-1 rounded-lg border",
|
|
2277
|
+
isActive ? "bg-primary text-white dark:bg-primary-dark dark:border-primary-dark" : "hover:bg-secondary hover:cursor-pointer dark:border-gray-600 dark:text-white dark:hover:bg-gray-700",
|
|
2278
|
+
sizeClass,
|
|
2279
|
+
isActive && "pointer-events-none"
|
|
2280
|
+
);
|
|
2281
|
+
if (asLink) {
|
|
2282
|
+
return /* @__PURE__ */ jsx(
|
|
2283
|
+
"a",
|
|
2284
|
+
{
|
|
2285
|
+
className: baseClasses,
|
|
2286
|
+
href: getHref(Number(page)),
|
|
2287
|
+
onClick: (e) => {
|
|
2288
|
+
e.preventDefault();
|
|
2289
|
+
goToPage(Number(page));
|
|
2290
|
+
},
|
|
2291
|
+
children: page
|
|
2292
|
+
},
|
|
2293
|
+
idx
|
|
2294
|
+
);
|
|
2295
|
+
}
|
|
2296
|
+
return /* @__PURE__ */ jsx(
|
|
2297
|
+
"button",
|
|
2298
|
+
{
|
|
2299
|
+
className: baseClasses,
|
|
2300
|
+
onClick: () => goToPage(Number(page)),
|
|
2301
|
+
children: page
|
|
2302
|
+
},
|
|
2303
|
+
idx
|
|
2304
|
+
);
|
|
2305
|
+
}),
|
|
2306
|
+
NextButton
|
|
2307
|
+
] });
|
|
2308
|
+
}
|
|
2309
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
2310
|
+
PrevButton,
|
|
2311
|
+
renderPageInfo(),
|
|
2312
|
+
NextButton
|
|
2313
|
+
] });
|
|
2314
|
+
};
|
|
2315
|
+
const RadioSizes = {
|
|
2316
|
+
sm: {
|
|
2317
|
+
container: "text-sm",
|
|
2318
|
+
radio: "w-4 h-4",
|
|
2319
|
+
label: "pl-2"
|
|
2320
|
+
},
|
|
2321
|
+
md: {
|
|
2322
|
+
container: "text-base",
|
|
2323
|
+
radio: "w-5 h-5",
|
|
2324
|
+
label: "pl-2"
|
|
2325
|
+
},
|
|
2326
|
+
lg: {
|
|
2327
|
+
container: "text-lg",
|
|
2328
|
+
radio: "w-6 h-6",
|
|
2329
|
+
label: "pl-3"
|
|
2330
|
+
}
|
|
2331
|
+
};
|
|
2332
|
+
const RadioVariants = {
|
|
2333
|
+
solid: {
|
|
2334
|
+
label: "border-transparent bg-primary dark:bg-primary-dark text-white dark:hover:bg-primary-dark-700 hover:bg-primary-700",
|
|
2335
|
+
checked: "bg-primary-700 dark:bg-primary-dark-700",
|
|
2336
|
+
radio: "",
|
|
2337
|
+
checkedRadio: "border-white bg-primary dark:bg-primary"
|
|
2338
|
+
},
|
|
2339
|
+
subtle: {
|
|
2340
|
+
label: "border-none bg-secondary/30 dark:text-white hover:text-primary-700 hover:dark:text-primary-30 dark:text-white dark:bg-primary-dark/50 hover:bg-primary/30",
|
|
2341
|
+
checked: "bg-primary/30 text-primary-700 dark:bg-primary/30 dark:text-white hover:dark:text-white",
|
|
2342
|
+
radio: "dark:bg-primary",
|
|
2343
|
+
checkedRadio: "bg-primary dark:bg-primary-500 border-none"
|
|
2344
|
+
},
|
|
2345
|
+
outline: {
|
|
2346
|
+
label: "border-secondary-700 hover:bg-primary/30 hover:text-primary-700 hover:border-primary-700 dark:hover:bg-primary/20 bg-transparent dark:text-white dark:border-secondary-dark dark:hover:bg-primary-dark/20",
|
|
2347
|
+
checked: "border-primary bg-primary/30 text-primary-700 dark:border-primary-700 dark:bg-primary-dark/20",
|
|
2348
|
+
radio: " dark:border-secondary-dark hover:border-primary",
|
|
2349
|
+
checkedRadio: "bg-primary-700 dark:border-primary-700 dark:border-primary dark:bg-primary"
|
|
2350
|
+
}
|
|
2351
|
+
};
|
|
2352
|
+
const RadioInput = ({
|
|
2353
|
+
name,
|
|
2354
|
+
options,
|
|
2355
|
+
selectedValue,
|
|
2356
|
+
onValueChange,
|
|
2357
|
+
containerClassName,
|
|
2358
|
+
inputGroupClassName,
|
|
2359
|
+
inputLabelClassName,
|
|
2360
|
+
inputRadioClassName,
|
|
2361
|
+
variant = "subtle",
|
|
2362
|
+
radioSize = "md",
|
|
2363
|
+
disabled,
|
|
2364
|
+
...props
|
|
2365
|
+
}) => {
|
|
2366
|
+
const sizeClasses2 = RadioSizes[radioSize];
|
|
2367
|
+
const variantClasses = RadioVariants[variant];
|
|
2368
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-3", containerClassName), children: options.map((option, index) => {
|
|
2369
|
+
const isChecked = selectedValue?.value === option.value;
|
|
2370
|
+
return /* @__PURE__ */ jsxs(
|
|
2371
|
+
"label",
|
|
2372
|
+
{
|
|
2373
|
+
className: cn(
|
|
2374
|
+
"relative flex items-center rounded-md cursor-pointer transition-all duration-200 border px-3 py-2",
|
|
2375
|
+
sizeClasses2.container,
|
|
2376
|
+
variantClasses.label,
|
|
2377
|
+
{
|
|
2378
|
+
[variantClasses.checked]: isChecked,
|
|
2379
|
+
"opacity-50 cursor-not-allowed": disabled
|
|
2380
|
+
},
|
|
2381
|
+
inputGroupClassName?.(isChecked, option)
|
|
2382
|
+
),
|
|
2383
|
+
children: [
|
|
2384
|
+
/* @__PURE__ */ jsx(
|
|
2385
|
+
"input",
|
|
2386
|
+
{
|
|
2387
|
+
type: "radio",
|
|
2388
|
+
name,
|
|
2389
|
+
value: option.value,
|
|
2390
|
+
checked: isChecked,
|
|
2391
|
+
onChange: () => onValueChange(option),
|
|
2392
|
+
disabled,
|
|
2393
|
+
className: cn("absolute opacity-0 w-full h-full cursor-pointer", { "cursor-not-allowed": disabled }),
|
|
2394
|
+
...props
|
|
2395
|
+
}
|
|
2396
|
+
),
|
|
2397
|
+
/* @__PURE__ */ jsx(
|
|
2398
|
+
"span",
|
|
2399
|
+
{
|
|
2400
|
+
className: cn(
|
|
2401
|
+
"flex items-center justify-center rounded-full border transition-all duration-200",
|
|
2402
|
+
sizeClasses2.radio,
|
|
2403
|
+
variantClasses.radio,
|
|
2404
|
+
{
|
|
2405
|
+
[variantClasses.checkedRadio]: isChecked
|
|
2406
|
+
},
|
|
2407
|
+
inputRadioClassName?.(isChecked, option)
|
|
2408
|
+
),
|
|
2409
|
+
children: isChecked && /* @__PURE__ */ jsx(
|
|
2410
|
+
"span",
|
|
2411
|
+
{
|
|
2412
|
+
className: cn(
|
|
2413
|
+
"w-1/2 h-1/2 rounded-full bg-white dark:bg-primary-dark transition-transform duration-200 transform scale-100"
|
|
2414
|
+
)
|
|
2415
|
+
}
|
|
2416
|
+
)
|
|
2417
|
+
}
|
|
2418
|
+
),
|
|
2419
|
+
/* @__PURE__ */ jsx("span", { className: cn("ml-2", sizeClasses2.label, inputLabelClassName?.(isChecked, option)), children: option.label })
|
|
2420
|
+
]
|
|
2421
|
+
},
|
|
2422
|
+
index
|
|
2423
|
+
);
|
|
2424
|
+
}) });
|
|
2425
|
+
};
|
|
2426
|
+
const SelectInput = ({ label, error, labelClassName, errorClassName, customClassNames, ...props }) => {
|
|
2427
|
+
const defaultClassNames = {
|
|
2428
|
+
clearIndicator: () => cn(
|
|
2429
|
+
"hover:cursor-pointer hover:!text-error dark:hover:!text-error-dark"
|
|
2430
|
+
),
|
|
2431
|
+
control: ({ isFocused }) => cn(
|
|
2432
|
+
`!w-full !border !rounded-md !shadow-sm !sm:text-sm !min-h-[38px] !bg-transparent`,
|
|
2433
|
+
error ? isFocused ? "border-primary !ring-1 !ring-primary" : "!border-error dark:!border-error-dark" : isFocused ? "border-primary !ring-1 !ring-primary" : "!border-secondary dark:!border-secondary-dark"
|
|
2434
|
+
),
|
|
2435
|
+
option: ({ isFocused, isSelected }) => `!px-4 !py-2 !cursor-pointer ${isSelected ? "!bg-primary !text-white" : isFocused ? "!bg-primary/30 dark:!bg-primary-dark/30" : "!bg-white dark:!bg-gray-700"}`,
|
|
2436
|
+
multiValue: () => "!bg-primary-30 dark:!bg-primary-dark-30-50 !rounded-md !flex !items-center !mr-1",
|
|
2437
|
+
multiValueLabel: () => "!text-primary-700 dark:!text-primary-dark-30-20 !text-sm !px-2 !py-0.5",
|
|
2438
|
+
multiValueRemove: () => "!text-primary-700 !hover:bg-primary/30 !hover:text-primary-700 !rounded-r-md !px-1 !cursor-pointer",
|
|
2439
|
+
menu: () => "!mt-1 dark:!text-white !border-secondary dark:!border-secondary-dark !bg-white dark:!bg-gray-700 !rounded-md !shadow-lg !z-10",
|
|
2440
|
+
input: () => "!text-gray-900 dark:!text-white",
|
|
2441
|
+
placeholder: () => "!text-gray-400",
|
|
2442
|
+
singleValue: () => "!text-gray-900 dark:!text-white"
|
|
2443
|
+
};
|
|
2444
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
2445
|
+
label && /* @__PURE__ */ jsx("label", { className: cn("block text-sm font-medium dark:text-white mb-1", labelClassName), children: label }),
|
|
2446
|
+
/* @__PURE__ */ jsx(
|
|
2447
|
+
Select,
|
|
2448
|
+
{
|
|
2449
|
+
classNames: { ...defaultClassNames, ...customClassNames },
|
|
2450
|
+
...props
|
|
2451
|
+
}
|
|
2452
|
+
),
|
|
2453
|
+
error && /* @__PURE__ */ jsx("p", { className: cn("mt-1 text-sm text-error", errorClassName), children: error })
|
|
2454
|
+
] });
|
|
2455
|
+
};
|
|
2456
|
+
const Skeleton = ({
|
|
2457
|
+
width,
|
|
2458
|
+
height,
|
|
2459
|
+
rounded = false,
|
|
2460
|
+
isLoading = true,
|
|
2461
|
+
animode = "flash",
|
|
2462
|
+
children
|
|
2463
|
+
}) => {
|
|
2464
|
+
if (!isLoading) {
|
|
2465
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2466
|
+
}
|
|
2467
|
+
const style = {
|
|
2468
|
+
width: width ?? "fit-content",
|
|
2469
|
+
height: height ?? (children ? "auto" : "1rem")
|
|
2470
|
+
};
|
|
2471
|
+
if (children) {
|
|
2472
|
+
return /* @__PURE__ */ jsx(Fragment, { children: React.Children.map(children, (child, i) => /* @__PURE__ */ jsx(
|
|
2473
|
+
"div",
|
|
2474
|
+
{
|
|
2475
|
+
className: `${animode} ${rounded ? "rounded-full" : "rounded-sm"} mb-1`,
|
|
2476
|
+
style,
|
|
2477
|
+
children: /* @__PURE__ */ jsx("span", { className: "invisible", children: child })
|
|
2478
|
+
},
|
|
2479
|
+
i
|
|
2480
|
+
)) });
|
|
2481
|
+
}
|
|
2482
|
+
return /* @__PURE__ */ jsx(
|
|
2483
|
+
"div",
|
|
2484
|
+
{
|
|
2485
|
+
className: `${animode} ${rounded ? "rounded-full" : "rounded-sm"}`,
|
|
2486
|
+
style
|
|
2487
|
+
}
|
|
2488
|
+
);
|
|
2489
|
+
};
|
|
2490
|
+
const Tooltip = ({
|
|
2491
|
+
children,
|
|
2492
|
+
text,
|
|
2493
|
+
showArrow = true,
|
|
2494
|
+
placement = "top",
|
|
2495
|
+
offset = 8,
|
|
2496
|
+
bgColor = "bg-gray-800 dark:bg-gray-600",
|
|
2497
|
+
isOpen: controlledIsOpen,
|
|
2498
|
+
onOpenChange,
|
|
2499
|
+
disabled = false,
|
|
2500
|
+
animationDuration = 300,
|
|
2501
|
+
delay = 700
|
|
2502
|
+
}) => {
|
|
2503
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
2504
|
+
const getTooltipPosition = () => {
|
|
2505
|
+
switch (placement) {
|
|
2506
|
+
case "top":
|
|
2507
|
+
return { bottom: "100%", left: "50%", transform: "translateX(-50%)", marginBottom: `${offset}px` };
|
|
2508
|
+
case "bottom":
|
|
2509
|
+
return { top: "100%", left: "50%", transform: "translateX(-50%)", marginTop: `${offset}px` };
|
|
2510
|
+
case "left":
|
|
2511
|
+
return { right: "100%", top: "50%", transform: "translateY(-50%)", marginRight: `${offset}px` };
|
|
2512
|
+
case "right":
|
|
2513
|
+
return { left: "100%", top: "50%", transform: "translateY(-50%)", marginLeft: `${offset}px` };
|
|
2514
|
+
default:
|
|
2515
|
+
return { bottom: "100%", left: "50%", transform: "translateX(-50%)", marginBottom: `${offset}px` };
|
|
2516
|
+
}
|
|
2517
|
+
};
|
|
2518
|
+
const getArrowPosition = () => {
|
|
2519
|
+
switch (placement) {
|
|
2520
|
+
case "top":
|
|
2521
|
+
return { bottom: "-4px", left: "50%", transform: "translateX(-50%) rotate(45deg)" };
|
|
2522
|
+
case "bottom":
|
|
2523
|
+
return { top: "-4px", left: "50%", transform: "translateX(-50%) rotate(225deg)" };
|
|
2524
|
+
case "left":
|
|
2525
|
+
return { right: "-4px", top: "50%", transform: "translateY(-50%) rotate(135deg)" };
|
|
2526
|
+
case "right":
|
|
2527
|
+
return { left: "-4px", top: "50%", transform: "translateY(-50%) rotate(-45deg)" };
|
|
2528
|
+
default:
|
|
2529
|
+
return { bottom: "-4px", left: "50%", transform: "translateX(-50%) rotate(45deg)" };
|
|
2530
|
+
}
|
|
2531
|
+
};
|
|
2532
|
+
const isVisible = controlledIsOpen ?? isHovering;
|
|
2533
|
+
const tooltipStyle = {
|
|
2534
|
+
...getTooltipPosition(),
|
|
2535
|
+
transitionDelay: isVisible && !controlledIsOpen ? `${delay}ms` : "0ms",
|
|
2536
|
+
transitionDuration: `${animationDuration}ms`
|
|
2537
|
+
};
|
|
2538
|
+
if (disabled) {
|
|
2539
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
2540
|
+
}
|
|
2541
|
+
return /* @__PURE__ */ jsxs(
|
|
2542
|
+
"div",
|
|
2543
|
+
{
|
|
2544
|
+
className: "relative inline-block group",
|
|
2545
|
+
onMouseEnter: () => setIsHovering(true),
|
|
2546
|
+
onMouseLeave: () => {
|
|
2547
|
+
if (controlledIsOpen !== void 0) onOpenChange?.(false);
|
|
2548
|
+
setIsHovering(false);
|
|
2549
|
+
},
|
|
2550
|
+
children: [
|
|
2551
|
+
children,
|
|
2552
|
+
/* @__PURE__ */ jsxs(
|
|
2553
|
+
"div",
|
|
2554
|
+
{
|
|
2555
|
+
className: cn(
|
|
2556
|
+
`absolute text-white text-[.70rem] font-medium tracking-tight rounded py-1 px-2 z-10 transition-all ${bgColor}`,
|
|
2557
|
+
isVisible ? "opacity-100 visible" : "opacity-0 invisible"
|
|
2558
|
+
),
|
|
2559
|
+
style: tooltipStyle,
|
|
2560
|
+
children: [
|
|
2561
|
+
text,
|
|
2562
|
+
showArrow && /* @__PURE__ */ jsx(
|
|
2563
|
+
"div",
|
|
2564
|
+
{
|
|
2565
|
+
className: `absolute w-2 h-2 ${bgColor}`,
|
|
2566
|
+
style: getArrowPosition()
|
|
2567
|
+
}
|
|
2568
|
+
)
|
|
2569
|
+
]
|
|
2570
|
+
}
|
|
2571
|
+
)
|
|
2572
|
+
]
|
|
2573
|
+
}
|
|
2574
|
+
);
|
|
2575
|
+
};
|
|
2576
|
+
const SliderColor = {
|
|
2577
|
+
primary: "bg-primary-30 dark:bg-primary-dark-30 hover:[&::-webkit-slider-thumb]:transition-all hover:[&::-webkit-slider-thumb]:duration-300 [&::-webkit-slider-thumb]:outline-5 hover:[&::-webkit-slider-thumb]:outline-10 [&::-webkit-slider-thumb]:outline-primary-30 [&::-webkit-slider-thumb]:bg-primary dark:[&::-webkit-slider-thumb]:bg-primary-dark [&::-webkit-slider-thumb]:outline-primary-30 dark:[&::-webkit-slider-thumb]:outline-primary-dark-30",
|
|
2578
|
+
error: "bg-error-30 dark:bg-error-dark-30 [&::-webkit-slider-thumb]:outline-5 [&::-webkit-slider-thumb]:outline-error-30 [&::-webkit-slider-thumb]:bg-error dark:[&::-webkit-slider-thumb]:bg-error-dark dark:[&::-webkit-slider-thumb]:outline-5 dark:[&::-webkit-slider-thumb]:outline-error-dark-30",
|
|
2579
|
+
warning: "bg-warning-30 dark:bg-warning-dark-30 [&::-webkit-slider-thumb]:outline-5 [&::-webkit-slider-thumb]:outline-warning-30 [&::-webkit-slider-thumb]:bg-warning dark:[&::-webkit-slider-thumb]:bg-warning-dark dark:[&::-webkit-slider-thumb]:outline-5 dark:[&::-webkit-slider-thumb]:outline-warning-dark-30",
|
|
2580
|
+
success: "bg-success-30 dark:bg-success-dark-30 [&::-webkit-slider-thumb]:outline-5 [&::-webkit-slider-thumb]:outline-success-30 [&::-webkit-slider-thumb]:bg-success dark:[&::-webkit-slider-thumb]:bg-success-dark dark:[&::-webkit-slider-thumb]:outline-5 dark:[&::-webkit-slider-thumb]:outline-success-dark-30",
|
|
2581
|
+
info: "bg-info-30 dark:bg-info-dark-30 [&::-webkit-slider-thumb]:outline-5 [&::-webkit-slider-thumb]:outline-info-30 [&::-webkit-slider-thumb]:bg-info dark:[&::-webkit-slider-thumb]:bg-info-dark dark:[&::-webkit-slider-thumb]:outline-5 dark:[&::-webkit-slider-thumb]:outline-info-dark-30",
|
|
2582
|
+
secondary: "bg-secondary dark:bg-secondary-dark [&::-webkit-slider-thumb]:outline-5 [&::-webkit-slider-thumb]:outline-secondary [&::-webkit-slider-thumb]:bg-secondary-700 dark:[&::-webkit-slider-thumb]:bg-secondary-dark-700 dark:[&::-webkit-slider-thumb]:outline-5 dark:[&::-webkit-slider-thumb]:outline-secondary-dark"
|
|
2583
|
+
};
|
|
2584
|
+
const SliderSize = {
|
|
2585
|
+
sm: "h-1 [&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3 [&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3",
|
|
2586
|
+
md: "h-2 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4 [&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4",
|
|
2587
|
+
lg: "h-3 [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5",
|
|
2588
|
+
xl: "h-4 [&::-webkit-slider-thumb]:w-6 [&::-webkit-slider-thumb]:h-6 [&::-moz-range-thumb]:w-6 [&::-moz-range-thumb]:h-6"
|
|
2589
|
+
};
|
|
2590
|
+
const Slider = ({
|
|
2591
|
+
id,
|
|
2592
|
+
name,
|
|
2593
|
+
label,
|
|
2594
|
+
min = 0,
|
|
2595
|
+
disabled,
|
|
2596
|
+
max = 100,
|
|
2597
|
+
step = 1,
|
|
2598
|
+
value,
|
|
2599
|
+
showTooltip = true,
|
|
2600
|
+
showMarks = true,
|
|
2601
|
+
onChange,
|
|
2602
|
+
color = "primary",
|
|
2603
|
+
prefixIcon,
|
|
2604
|
+
suffixIcon,
|
|
2605
|
+
sliderSize = "md"
|
|
2606
|
+
}) => {
|
|
2607
|
+
const [isInteracting, setIsInteracting] = useState(false);
|
|
2608
|
+
const sliderColorClassName = SliderColor[color];
|
|
2609
|
+
const sliderSizeClassName = SliderSize[sliderSize];
|
|
2610
|
+
const webkitClassName = "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:appearance-none";
|
|
2611
|
+
const mozClassName = "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:appearance-none";
|
|
2612
|
+
const thumbWidthMap = { sm: 12, md: 16, lg: 20, xl: 24 };
|
|
2613
|
+
const thumbWidth = thumbWidthMap[sliderSize];
|
|
2614
|
+
const getTooltipStyle = () => {
|
|
2615
|
+
const range = Number(max) - Number(min);
|
|
2616
|
+
const percentage = range === 0 ? 0 : (Number(value) - Number(min)) / range;
|
|
2617
|
+
const offset = percentage * -thumbWidth + thumbWidth / 2;
|
|
2618
|
+
return {
|
|
2619
|
+
left: `calc(${percentage * 100}% + ${offset}px)`,
|
|
2620
|
+
opacity: isInteracting ? 1 : 0,
|
|
2621
|
+
pointerEvents: "none"
|
|
2622
|
+
};
|
|
2623
|
+
};
|
|
2624
|
+
const renderMarks = () => {
|
|
2625
|
+
if (!showMarks || Number(step) <= 1) return null;
|
|
2626
|
+
const range = Number(max) - Number(min);
|
|
2627
|
+
const stepCount = Math.floor(range / Number(step));
|
|
2628
|
+
const marks = Array.from({ length: stepCount + 1 }, (_, i) => {
|
|
2629
|
+
const left = i / stepCount * 100;
|
|
2630
|
+
return /* @__PURE__ */ jsx(
|
|
2631
|
+
"div",
|
|
2632
|
+
{
|
|
2633
|
+
className: cn(
|
|
2634
|
+
"absolute top-1/2 -translate-y-1/2 w-[2px] h-2 rounded-full",
|
|
2635
|
+
sliderColorClassName
|
|
2636
|
+
),
|
|
2637
|
+
style: { left: `${left}%` }
|
|
2638
|
+
},
|
|
2639
|
+
i
|
|
2640
|
+
);
|
|
2641
|
+
});
|
|
2642
|
+
return /* @__PURE__ */ jsx("div", { className: "absolute top-full mt-2 -left-0.5 -right-0.5 h-2 me-[11px] ms-[9px]", children: marks });
|
|
2643
|
+
};
|
|
2644
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-full p-4 relative overflow-x-clip", children: [
|
|
2645
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id || name, className: "block text-sm font-medium mb-1 dark:text-white", children: label }),
|
|
2646
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 items-center relative", children: [
|
|
2647
|
+
prefixIcon,
|
|
2648
|
+
/* @__PURE__ */ jsxs(
|
|
2649
|
+
"div",
|
|
2650
|
+
{
|
|
2651
|
+
className: "relative w-full flex items-center",
|
|
2652
|
+
onMouseEnter: () => setIsInteracting(true),
|
|
2653
|
+
onMouseLeave: () => setIsInteracting(false),
|
|
2654
|
+
children: [
|
|
2655
|
+
showTooltip && /* @__PURE__ */ jsx(
|
|
2656
|
+
"div",
|
|
2657
|
+
{
|
|
2658
|
+
className: "absolute z-10 -top-7 transition-opacity duration-300",
|
|
2659
|
+
style: getTooltipStyle(),
|
|
2660
|
+
children: /* @__PURE__ */ jsx(Tooltip, { text: String(value), isOpen: isInteracting, placement: "top", children: /* @__PURE__ */ jsx("div", {}) })
|
|
2661
|
+
}
|
|
2662
|
+
),
|
|
2663
|
+
/* @__PURE__ */ jsx(
|
|
2664
|
+
"input",
|
|
2665
|
+
{
|
|
2666
|
+
disabled,
|
|
2667
|
+
type: "range",
|
|
2668
|
+
id: id || "slider-range",
|
|
2669
|
+
min,
|
|
2670
|
+
max,
|
|
2671
|
+
step,
|
|
2672
|
+
value,
|
|
2673
|
+
onChange,
|
|
2674
|
+
onMouseDown: () => setIsInteracting(true),
|
|
2675
|
+
className: cn(
|
|
2676
|
+
"w-full rounded-full appearance-none cursor-pointer dark:bg-gray-700",
|
|
2677
|
+
"transition-all duration-300 ease-in-out",
|
|
2678
|
+
sliderSizeClassName,
|
|
2679
|
+
webkitClassName,
|
|
2680
|
+
mozClassName,
|
|
2681
|
+
sliderColorClassName,
|
|
2682
|
+
{
|
|
2683
|
+
[SliderColor["secondary"]]: disabled,
|
|
2684
|
+
"bg-secondary opacity-50": disabled
|
|
2685
|
+
}
|
|
2686
|
+
)
|
|
2687
|
+
}
|
|
2688
|
+
),
|
|
2689
|
+
renderMarks()
|
|
2690
|
+
]
|
|
2691
|
+
}
|
|
2692
|
+
),
|
|
2693
|
+
suffixIcon,
|
|
2694
|
+
/* @__PURE__ */ jsx("div", { className: "w-32", children: /* @__PURE__ */ jsx(
|
|
2695
|
+
TextInput,
|
|
2696
|
+
{
|
|
2697
|
+
min,
|
|
2698
|
+
max,
|
|
2699
|
+
step,
|
|
2700
|
+
type: Number(value) <= 0 ? "text" : "number",
|
|
2701
|
+
value: Number(value) <= 0 ? "" : value,
|
|
2702
|
+
onChange
|
|
2703
|
+
}
|
|
2704
|
+
) })
|
|
2705
|
+
] })
|
|
2706
|
+
] });
|
|
2707
|
+
};
|
|
2708
|
+
const SpinnerSize = {
|
|
2709
|
+
sm: "h-4 w-4 border-2",
|
|
2710
|
+
md: "h-6 w-6 border-3",
|
|
2711
|
+
lg: "h-8 w-8 border-4"
|
|
2712
|
+
};
|
|
2713
|
+
const SpinnerColor = {
|
|
2714
|
+
primary: "border-primary dark:border-primary-dark",
|
|
2715
|
+
error: "border-error dark:border-error-dark",
|
|
2716
|
+
warning: "border-warning dark:border-warning-dark",
|
|
2717
|
+
success: "border-success dark:border-success-dark",
|
|
2718
|
+
info: "border-info dark:border-info-dark",
|
|
2719
|
+
secondary: "border-secondary dark:border-secondary-dark"
|
|
2720
|
+
};
|
|
2721
|
+
const Spinner = ({
|
|
2722
|
+
color = "primary",
|
|
2723
|
+
size = "md",
|
|
2724
|
+
className: customClassName,
|
|
2725
|
+
duration = 1e3,
|
|
2726
|
+
thickness
|
|
2727
|
+
}) => {
|
|
2728
|
+
const spinnerColor = SpinnerColor[color];
|
|
2729
|
+
const spinnerSize = SpinnerSize[size];
|
|
2730
|
+
const animationDuration = `${duration}ms`;
|
|
2731
|
+
const borderWidth = thickness && `${thickness}px`;
|
|
2732
|
+
return /* @__PURE__ */ jsx(
|
|
2733
|
+
"span",
|
|
2734
|
+
{
|
|
2735
|
+
className: cn(
|
|
2736
|
+
spinnerSize,
|
|
2737
|
+
spinnerColor,
|
|
2738
|
+
`flex rounded-full animate-spin`,
|
|
2739
|
+
customClassName,
|
|
2740
|
+
"border-t-transparent dark:border-t-transparent"
|
|
2741
|
+
),
|
|
2742
|
+
style: { animationDuration, borderWidth }
|
|
2743
|
+
}
|
|
2744
|
+
);
|
|
2745
|
+
};
|
|
2746
|
+
const TableSize = {
|
|
2747
|
+
sm: "text-sm py-[5px] px-2",
|
|
2748
|
+
md: "text-base py-2 px-4",
|
|
2749
|
+
lg: "text-lg py-3 px-6"
|
|
2750
|
+
};
|
|
2751
|
+
function Table({
|
|
2752
|
+
columns,
|
|
2753
|
+
data,
|
|
2754
|
+
striped = false,
|
|
2755
|
+
stripeColor,
|
|
2756
|
+
headerClassName,
|
|
2757
|
+
dataColumnClassName,
|
|
2758
|
+
dataRowClassName,
|
|
2759
|
+
customEmptyData,
|
|
2760
|
+
tableClassName,
|
|
2761
|
+
captionClassName,
|
|
2762
|
+
containerClassName,
|
|
2763
|
+
size = "md",
|
|
2764
|
+
caption,
|
|
2765
|
+
captionPosition = "bottom",
|
|
2766
|
+
stickyHeader = false,
|
|
2767
|
+
selectable = false,
|
|
2768
|
+
onSelectionChange,
|
|
2769
|
+
selectedRows = []
|
|
2770
|
+
}) {
|
|
2771
|
+
const tableSizeClass = TableSize[size];
|
|
2772
|
+
const handleSelectAll = (e) => {
|
|
2773
|
+
if (e.target.checked) {
|
|
2774
|
+
onSelectionChange?.(data);
|
|
2775
|
+
} else {
|
|
2776
|
+
onSelectionChange?.([]);
|
|
2777
|
+
}
|
|
2778
|
+
};
|
|
2779
|
+
const handleSelectRow = (row) => {
|
|
2780
|
+
const isSelected = selectedRows.some((r) => r.id === row.id);
|
|
2781
|
+
if (isSelected) {
|
|
2782
|
+
onSelectionChange?.(selectedRows.filter((r) => r.id !== row.id));
|
|
2783
|
+
} else {
|
|
2784
|
+
onSelectionChange?.([...selectedRows, row]);
|
|
2785
|
+
}
|
|
2786
|
+
};
|
|
2787
|
+
const isAllSelected = data.length > 0 && selectedRows.length === data.length;
|
|
2788
|
+
const isIndeterminate = selectedRows.length > 0 && selectedRows.length < data.length;
|
|
2789
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("overflow-x-auto w-full", stickyHeader && "max-h-[400px] overflow-y-auto", containerClassName), children: [
|
|
2790
|
+
caption && captionPosition === "top" && /* @__PURE__ */ jsx("p", { className: cn("text-center text-sm font-medium mb-1 dark:text-white", captionClassName), children: caption }),
|
|
2791
|
+
/* @__PURE__ */ jsxs("table", { className: cn("relative min-w-full outline outline-gray-200 dark:outline-gray-600", tableSizeClass, tableClassName), children: [
|
|
2792
|
+
/* @__PURE__ */ jsx("thead", { className: cn("dark:bg-gray-700 dark:text-white", headerClassName), children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
2793
|
+
selectable && /* @__PURE__ */ jsx(
|
|
2794
|
+
"th",
|
|
2795
|
+
{
|
|
2796
|
+
className: cn(
|
|
2797
|
+
"px-4 py-2 text-left text-sm border-b dark:border-b-secondary-700",
|
|
2798
|
+
tableSizeClass,
|
|
2799
|
+
stickyHeader && "sticky top-0 bg-secondary dark:bg-gray-700 z-10",
|
|
2800
|
+
headerClassName
|
|
2801
|
+
),
|
|
2802
|
+
children: /* @__PURE__ */ jsx(
|
|
2803
|
+
CheckboxInput,
|
|
2804
|
+
{
|
|
2805
|
+
checked: isAllSelected,
|
|
2806
|
+
indeterminate: isIndeterminate,
|
|
2807
|
+
onChange: handleSelectAll
|
|
2808
|
+
}
|
|
2809
|
+
)
|
|
2810
|
+
}
|
|
2811
|
+
),
|
|
2812
|
+
columns.map((col, idx) => /* @__PURE__ */ jsx(
|
|
2813
|
+
"th",
|
|
2814
|
+
{
|
|
2815
|
+
className: cn(
|
|
2816
|
+
"px-4 py-2 text-left text-sm border-b dark:border-b-secondary-700",
|
|
2817
|
+
tableSizeClass,
|
|
2818
|
+
stickyHeader && "sticky top-0 bg-secondary dark:bg-gray-700 z-10",
|
|
2819
|
+
headerClassName
|
|
2820
|
+
),
|
|
2821
|
+
children: col.header
|
|
2822
|
+
},
|
|
2823
|
+
idx
|
|
2824
|
+
))
|
|
2825
|
+
] }) }),
|
|
2826
|
+
/* @__PURE__ */ jsx("tbody", { className: "dark:bg-gray-800 dark:text-white", children: data.length > 0 ? data.map((row, rIdx) => /* @__PURE__ */ jsxs(
|
|
2827
|
+
"tr",
|
|
2828
|
+
{
|
|
2829
|
+
className: cn("hover:bg-gray-700 hover:text-white dark:hover:bg-gray-600 transition-colors", striped && rIdx % 2 !== 0 && (stripeColor ?? "bg-gray-300 dark:bg-gray-700"), dataRowClassName),
|
|
2830
|
+
children: [
|
|
2831
|
+
selectable && /* @__PURE__ */ jsx("td", { className: cn("px-4 py-2 border-b border-secondary-700 dark:border-secondary-dark-700", (striped || stripeColor) && "border-none", dataColumnClassName, tableSizeClass), children: /* @__PURE__ */ jsx(
|
|
2832
|
+
CheckboxInput,
|
|
2833
|
+
{
|
|
2834
|
+
checked: selectedRows.some((r) => r.id === row.id),
|
|
2835
|
+
onChange: () => handleSelectRow(row)
|
|
2836
|
+
}
|
|
2837
|
+
) }),
|
|
2838
|
+
columns.map((col, cIdx) => /* @__PURE__ */ jsx(
|
|
2839
|
+
"td",
|
|
2840
|
+
{
|
|
2841
|
+
className: cn("px-4 py-2 border-b border-secondary-700 dark:border-secondary-dark-700", (striped || stripeColor) && "border-none", dataColumnClassName, tableSizeClass),
|
|
2842
|
+
children: col.render ? col.render(row[col.accessor], row) : String(row[col.accessor])
|
|
2843
|
+
},
|
|
2844
|
+
cIdx
|
|
2845
|
+
))
|
|
2846
|
+
]
|
|
2847
|
+
},
|
|
2848
|
+
rIdx
|
|
2849
|
+
)) : /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
2850
|
+
"td",
|
|
2851
|
+
{
|
|
2852
|
+
colSpan: columns.length + (selectable ? 1 : 0),
|
|
2853
|
+
className: cn("px-4 py-6 text-center", tableSizeClass),
|
|
2854
|
+
children: customEmptyData ?? "Tidak ada data."
|
|
2855
|
+
}
|
|
2856
|
+
) }) })
|
|
2857
|
+
] }),
|
|
2858
|
+
caption && captionPosition === "bottom" && /* @__PURE__ */ jsx("p", { className: cn("text-center text-sm font-medium mt-1 dark:text-white", captionClassName), children: caption })
|
|
2859
|
+
] });
|
|
2860
|
+
}
|
|
2861
|
+
const TabsVariants = {
|
|
2862
|
+
line: {
|
|
2863
|
+
wrapper: "border-b border-secondary dark:border-secondary-dark",
|
|
2864
|
+
button: "whitespace-nowrap py-4 px-1 font-medium text-sm",
|
|
2865
|
+
active: "border-primary text-primary dark:text-primary-30 transition-all duration-300 ease-in-out",
|
|
2866
|
+
inactive: "border-transparent text-gray-500 hover:text-secondary-700 dark:text-white dark:hover:text-secondary-dark-700"
|
|
2867
|
+
},
|
|
2868
|
+
solid: {
|
|
2869
|
+
wrapper: "rounded-md p-1",
|
|
2870
|
+
button: "whitespace-nowrap py-2 px-4 font-medium text-sm rounded-md",
|
|
2871
|
+
active: "bg-indigo-100 dark:bg-indigo-200 text-primary dark:text-primary-dark transition-all duration-300 ease-in-out",
|
|
2872
|
+
inactive: "text-gray-500 hover:text-secondary-700 dark:text-white dark:hover:text-secondary-dark-700"
|
|
2873
|
+
},
|
|
2874
|
+
subtle: {
|
|
2875
|
+
wrapper: "rounded-md bg-transparent p-1",
|
|
2876
|
+
button: "whitespace-nowrap py-2 px-4 font-medium text-sm",
|
|
2877
|
+
active: "text-white transition-all duration-300 ease-in-out z-10",
|
|
2878
|
+
inactive: "bg-transparent text-primary dark:text-primary-30 hover:text-primary-700"
|
|
2879
|
+
},
|
|
2880
|
+
inline: {
|
|
2881
|
+
wrapper: "border border-primary rounded-t-md border-b dark:border-primary-dark-30",
|
|
2882
|
+
button: "whitespace-nowrap py-2 px-4 font-medium text-sm z-10",
|
|
2883
|
+
active: "text-white transition-all duration-300 ease-in-out",
|
|
2884
|
+
inactive: "text-gray-500 hover:text-secondary-700 dark:text-white dark:hover:text-secondary-dark"
|
|
2885
|
+
},
|
|
2886
|
+
outline: {
|
|
2887
|
+
wrapper: "border border-primary dark:border-primary-dark-30 rounded-md p-1",
|
|
2888
|
+
button: "whitespace-nowrap py-2 px-4 font-medium text-sm rounded-md",
|
|
2889
|
+
active: "bg-indigo-100 dark:bg-indigo-200 text-primary dark:text-primary-dark transition-all duration-300 ease-in-out",
|
|
2890
|
+
inactive: "text-gray-500 hover:text-secondary-700 dark:text-white dark:hover:text-secondary-dark"
|
|
2891
|
+
},
|
|
2892
|
+
plain: {
|
|
2893
|
+
wrapper: "",
|
|
2894
|
+
button: "whitespace-nowrap py-2 px-4 font-medium text-sm",
|
|
2895
|
+
active: "text-primary dark:text-primary-30 transition-all duration-300 ease-in-out",
|
|
2896
|
+
inactive: "text-gray-500 hover:text-secondary-700 dark:text-white dark:hover:text-secondary"
|
|
2897
|
+
}
|
|
2898
|
+
};
|
|
2899
|
+
const IndicatorVariants = {
|
|
2900
|
+
line: "absolute bottom-0 h-1 bg-primary dark:bg-primary-30 transition-all duration-300 ease-in-out",
|
|
2901
|
+
solid: "absolute bottom-0 h-1 bg-primary transition-all duration-300 ease-in-out",
|
|
2902
|
+
subtle: "absolute bottom-0 h-full bg-primary rounded-md transition-all duration-300 ease-in-out",
|
|
2903
|
+
inline: "absolute bottom-0 h-full bg-primary border-t border-r border-l border-primary-700 rounded-tl-md rounded-tr-md transition-all duration-300 ease-in-out",
|
|
2904
|
+
outline: "absolute bottom-0 h-1 bg-primary transition-all duration-300 ease-in-out",
|
|
2905
|
+
plain: ""
|
|
2906
|
+
};
|
|
2907
|
+
const Tabs = ({
|
|
2908
|
+
tabs,
|
|
2909
|
+
fitted,
|
|
2910
|
+
variant = "line",
|
|
2911
|
+
wrapperClassName,
|
|
2912
|
+
buttonClassName,
|
|
2913
|
+
activeClassName,
|
|
2914
|
+
inactiveClassName,
|
|
2915
|
+
activeTab: controlledActiveTab,
|
|
2916
|
+
onTabChange
|
|
2917
|
+
}) => {
|
|
2918
|
+
const [internalActiveTab, setInternalActiveTab] = useState(0);
|
|
2919
|
+
const isControlled = controlledActiveTab !== void 0 && onTabChange !== void 0;
|
|
2920
|
+
const activeTab = isControlled ? controlledActiveTab : internalActiveTab;
|
|
2921
|
+
const variantClasses = TabsVariants[variant];
|
|
2922
|
+
const indicatorVariantClasses = IndicatorVariants[variant];
|
|
2923
|
+
const tabRefs = useRef([]);
|
|
2924
|
+
const indicatorRef = useRef(null);
|
|
2925
|
+
useEffect(() => {
|
|
2926
|
+
if (!isControlled && activeTab >= tabs.length) {
|
|
2927
|
+
setInternalActiveTab(Math.max(0, tabs.length - 1));
|
|
2928
|
+
}
|
|
2929
|
+
}, [tabs, activeTab, isControlled]);
|
|
2930
|
+
useEffect(() => {
|
|
2931
|
+
const currentTab = tabRefs.current[activeTab];
|
|
2932
|
+
const indicator = indicatorRef.current;
|
|
2933
|
+
if (currentTab && indicator) {
|
|
2934
|
+
const left = currentTab.offsetLeft;
|
|
2935
|
+
const width = currentTab.offsetWidth;
|
|
2936
|
+
indicator.style.transform = `translateX(${left}px)`;
|
|
2937
|
+
indicator.style.width = `${width}px`;
|
|
2938
|
+
currentTab.scrollIntoView({ behavior: "smooth", inline: "center", block: "nearest" });
|
|
2939
|
+
}
|
|
2940
|
+
}, [activeTab, tabs]);
|
|
2941
|
+
const handleTabClick = (index) => {
|
|
2942
|
+
if (isControlled) {
|
|
2943
|
+
onTabChange(index);
|
|
2944
|
+
} else {
|
|
2945
|
+
setInternalActiveTab(index);
|
|
2946
|
+
}
|
|
2947
|
+
};
|
|
2948
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
2949
|
+
/* @__PURE__ */ jsx("div", { className: cn("relative", variantClasses.wrapper, wrapperClassName), children: /* @__PURE__ */ jsxs("nav", { className: "relative -mb-px flex space-x-2 overflow-x-auto scroll-smooth", "aria-label": "Tabs", children: [
|
|
2950
|
+
tabs.map((tab, index) => {
|
|
2951
|
+
const className = cn(
|
|
2952
|
+
"hover:cursor-pointer",
|
|
2953
|
+
fitted && "flex-1",
|
|
2954
|
+
variantClasses.button,
|
|
2955
|
+
buttonClassName,
|
|
2956
|
+
activeTab === index ? cn(variantClasses.active, activeClassName) : cn(variantClasses.inactive, inactiveClassName),
|
|
2957
|
+
tab.disabled && "hover:cursor-not-allowed cursor-not-allowed opacity-50"
|
|
2958
|
+
);
|
|
2959
|
+
if (tab.link) {
|
|
2960
|
+
return /* @__PURE__ */ jsx(
|
|
2961
|
+
"a",
|
|
2962
|
+
{
|
|
2963
|
+
href: !tab.disabled ? tab.link : void 0,
|
|
2964
|
+
ref: (el) => {
|
|
2965
|
+
tabRefs.current[index] = el;
|
|
2966
|
+
},
|
|
2967
|
+
className,
|
|
2968
|
+
"aria-disabled": tab.disabled,
|
|
2969
|
+
onClick: (e) => tab.disabled && e.preventDefault(),
|
|
2970
|
+
children: tab.label
|
|
2971
|
+
},
|
|
2972
|
+
tab.label
|
|
2973
|
+
);
|
|
2974
|
+
}
|
|
2975
|
+
return /* @__PURE__ */ jsx(
|
|
2976
|
+
"button",
|
|
2977
|
+
{
|
|
2978
|
+
ref: (el) => {
|
|
2979
|
+
tabRefs.current[index] = el;
|
|
2980
|
+
},
|
|
2981
|
+
onClick: () => handleTabClick(index),
|
|
2982
|
+
disabled: tab.disabled,
|
|
2983
|
+
className,
|
|
2984
|
+
children: tab.label
|
|
2985
|
+
},
|
|
2986
|
+
tab.label
|
|
2987
|
+
);
|
|
2988
|
+
}),
|
|
2989
|
+
/* @__PURE__ */ jsx(
|
|
2990
|
+
"div",
|
|
2991
|
+
{
|
|
2992
|
+
ref: indicatorRef,
|
|
2993
|
+
className: cn(indicatorVariantClasses),
|
|
2994
|
+
style: { width: 0, transform: "translateX(0px)" }
|
|
2995
|
+
}
|
|
2996
|
+
)
|
|
2997
|
+
] }) }),
|
|
2998
|
+
/* @__PURE__ */ jsx("div", { className: "mt-4", children: tabs[activeTab]?.content })
|
|
2999
|
+
] });
|
|
3000
|
+
};
|
|
3001
|
+
const Textarea = ({
|
|
3002
|
+
label,
|
|
3003
|
+
id,
|
|
3004
|
+
name,
|
|
3005
|
+
error,
|
|
3006
|
+
autoResize = false,
|
|
3007
|
+
customClassName,
|
|
3008
|
+
...props
|
|
3009
|
+
}) => {
|
|
3010
|
+
const textareaRef = useRef(null);
|
|
3011
|
+
const handleResize = () => {
|
|
3012
|
+
const el = textareaRef.current;
|
|
3013
|
+
if (el) {
|
|
3014
|
+
el.style.height = "auto";
|
|
3015
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
3016
|
+
}
|
|
3017
|
+
};
|
|
3018
|
+
useEffect(() => {
|
|
3019
|
+
if (autoResize) handleResize();
|
|
3020
|
+
}, []);
|
|
3021
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
3022
|
+
label && /* @__PURE__ */ jsx(
|
|
3023
|
+
"label",
|
|
3024
|
+
{
|
|
3025
|
+
htmlFor: id || name,
|
|
3026
|
+
className: "inline-block text-sm font-medium mb-1 dark:text-white",
|
|
3027
|
+
children: label
|
|
3028
|
+
}
|
|
3029
|
+
),
|
|
3030
|
+
/* @__PURE__ */ jsx(
|
|
3031
|
+
"textarea",
|
|
3032
|
+
{
|
|
3033
|
+
id: id || name,
|
|
3034
|
+
name,
|
|
3035
|
+
rows: autoResize ? 1 : 5,
|
|
3036
|
+
ref: textareaRef,
|
|
3037
|
+
onInput: handleResize,
|
|
3038
|
+
className: cn(
|
|
3039
|
+
`overflow-hidden bg-gray-50 w-full block px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary sm:text-sm border-secondary min-h-[58px] max-h-[10rem]`,
|
|
3040
|
+
"dark:bg-gray-800 dark:border-secondary-dark dark:text-white dark:placeholder:text-gray-400",
|
|
3041
|
+
autoResize ? "resize-none" : "resize",
|
|
3042
|
+
error && "border-error dark:border-error-dark",
|
|
3043
|
+
props.disabled && "bg-secondary/40 cursor-not-allowed",
|
|
3044
|
+
customClassName
|
|
3045
|
+
),
|
|
3046
|
+
...props
|
|
3047
|
+
}
|
|
3048
|
+
),
|
|
3049
|
+
error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-red-600 dark:text-red-500", children: error })
|
|
3050
|
+
] });
|
|
3051
|
+
};
|
|
3052
|
+
const DotColors = {
|
|
3053
|
+
success: "bg-success dark:bg-success-dark",
|
|
3054
|
+
info: "bg-info dark:bg-info-dark",
|
|
3055
|
+
error: "bg-error dark:bg-error-dark",
|
|
3056
|
+
warning: "bg-warning dark:bg-warning-dark",
|
|
3057
|
+
primary: "bg-primary dark:bg-primary-dark",
|
|
3058
|
+
default: "bg-secondary-700 dark:bg-secondary-dark"
|
|
3059
|
+
};
|
|
3060
|
+
const LineColors = {
|
|
3061
|
+
success: "border-success dark:border-success-dark md:before:border-success md:before:dark:border-success-dark",
|
|
3062
|
+
info: "border-info dark:border-info-dark md:before:border-info md:before:dark:border-info-dark",
|
|
3063
|
+
error: "border-error dark:border-error-dark md:before:border-error md:before:dark:border-error-dark",
|
|
3064
|
+
warning: "border-warning dark:border-warning-dark md:before:border-warning md:before:dark:border-warning-dark",
|
|
3065
|
+
primary: "border-primary dark:border-primary-dark md:before:border-primary md:before:dark:border-primary-dark",
|
|
3066
|
+
default: "border-secondary-700 dark:border-secondary-dark md:before:border-secondary md:before:dark:border-secondary-dark"
|
|
3067
|
+
};
|
|
3068
|
+
const TimelineItem = ({
|
|
3069
|
+
title,
|
|
3070
|
+
time,
|
|
3071
|
+
children,
|
|
3072
|
+
dotColor = "default",
|
|
3073
|
+
icon,
|
|
3074
|
+
position
|
|
3075
|
+
// prop from parent
|
|
3076
|
+
}) => {
|
|
3077
|
+
const dotColorClassName = DotColors[dotColor];
|
|
3078
|
+
return /* @__PURE__ */ jsxs("li", { className: cn("mb-5", {
|
|
3079
|
+
"ms-8": position === "left",
|
|
3080
|
+
"me-8 text-end": position === "right",
|
|
3081
|
+
"ms-4 md:w-1/2 ps-4 md:odd:pe-8 md:odd:ms-0 md:odd:text-end md:even:ps-8 md:even:ms-auto": position === "split"
|
|
3082
|
+
}), children: [
|
|
3083
|
+
icon ? /* @__PURE__ */ jsx("div", { className: cn(
|
|
3084
|
+
"flex items-center justify-center absolute w-10 h-10 rounded-full mt-1.5 outline outline-white dark:outline-secondary",
|
|
3085
|
+
dotColorClassName,
|
|
3086
|
+
{
|
|
3087
|
+
"-start-[20px]": position === "left" || position === "split" && "md:hidden",
|
|
3088
|
+
"-end-[21px]": position === "right",
|
|
3089
|
+
"-start-[21px] md:start-1/2 md:-ms-[19px]": position === "split"
|
|
3090
|
+
}
|
|
3091
|
+
), children: icon }) : /* @__PURE__ */ jsx("div", { className: cn(
|
|
3092
|
+
"absolute w-3 h-3 rounded-full mt-1.5 outline outline-white dark:outline-secondary",
|
|
3093
|
+
dotColorClassName,
|
|
3094
|
+
{
|
|
3095
|
+
"-start-[7px]": position === "left" || position === "split" && "md:hidden",
|
|
3096
|
+
"-end-[7px]": position === "right",
|
|
3097
|
+
"-start-[7.1px] md:start-1/2 md:-ms-[4.7px]": position === "split"
|
|
3098
|
+
}
|
|
3099
|
+
) }),
|
|
3100
|
+
/* @__PURE__ */ jsx("time", { className: "mb-1 text-sm font-normal leading-none text-gray-400 dark:text-secondary-dark", children: time }),
|
|
3101
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: title }),
|
|
3102
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 text-base font-normal text-secondary-foreground dark:text-secondary-foreground-dark", children })
|
|
3103
|
+
] });
|
|
3104
|
+
};
|
|
3105
|
+
const Timeline = ({
|
|
3106
|
+
position = "left",
|
|
3107
|
+
lineColor = "default",
|
|
3108
|
+
children
|
|
3109
|
+
}) => {
|
|
3110
|
+
const childrenWithProps = Children.map(children, (child) => {
|
|
3111
|
+
if (isValidElement(child)) {
|
|
3112
|
+
return cloneElement(child, { position });
|
|
3113
|
+
}
|
|
3114
|
+
return child;
|
|
3115
|
+
});
|
|
3116
|
+
const lineColorClassName = LineColors[lineColor];
|
|
3117
|
+
return /* @__PURE__ */ jsx("ol", { className: cn(
|
|
3118
|
+
"relative",
|
|
3119
|
+
{
|
|
3120
|
+
"border-s-2": position === "left",
|
|
3121
|
+
"border-e-2": position === "right",
|
|
3122
|
+
"border-s-2 md:border-s-0 md:before:content-[''] md:before:absolute md:before:top-0 md:before:left-1/2 md:before:h-full md:before:border-s-2 md:before:border-secondary md:before:dark:border-secondary-dark": position === "split"
|
|
3123
|
+
},
|
|
3124
|
+
lineColorClassName
|
|
3125
|
+
), children: childrenWithProps });
|
|
3126
|
+
};
|
|
3127
|
+
Timeline.Item = TimelineItem;
|
|
3128
|
+
const ToggleVariant = {
|
|
3129
|
+
primary: "peer-checked:bg-primary dark:peer-checked:bg-primary-dark",
|
|
3130
|
+
error: "peer-checked:bg-error dark:peer-checked:bg-error-dark",
|
|
3131
|
+
warning: "peer-checked:bg-warning dark:peer-checked:bg-warning-dark",
|
|
3132
|
+
success: "peer-checked:bg-success dark:peer-checked:bg-success-dark",
|
|
3133
|
+
info: "peer-checked:bg-info dark:peer-checked:bg-info-dark",
|
|
3134
|
+
secondary: "peer-checked:bg-secondary dark:peer-checked:bg-secondary-dark"
|
|
3135
|
+
};
|
|
3136
|
+
const ToggleThumbShape = {
|
|
3137
|
+
stadium: "rounded-full after:rounded-full",
|
|
3138
|
+
rounded: "rounded-md after:rounded-sm"
|
|
3139
|
+
};
|
|
3140
|
+
const ToggleSize = {
|
|
3141
|
+
sm: "w-9 h-5 after:h-4 after:w-4 after:start-[2px] after:top-[2px] peer-checked:after:translate-x-[16px]",
|
|
3142
|
+
md: "w-11 h-6 after:h-5 after:w-5 after:start-[2px] after:top-[2px] peer-checked:after:translate-x-[20px]",
|
|
3143
|
+
lg: "w-14 h-7 after:h-6 after:w-6 after:start-[2px] after:top-[2px] peer-checked:after:translate-x-[28px]"
|
|
3144
|
+
};
|
|
3145
|
+
const Toggle = ({
|
|
3146
|
+
variant = "primary",
|
|
3147
|
+
customSize: size = "md",
|
|
3148
|
+
thumbShape = "stadium",
|
|
3149
|
+
label,
|
|
3150
|
+
wrapperClassName,
|
|
3151
|
+
labelClassName,
|
|
3152
|
+
...props
|
|
3153
|
+
}) => {
|
|
3154
|
+
const divClasses = [
|
|
3155
|
+
"relative",
|
|
3156
|
+
"bg-secondary-700 dark:bg-secondary-dark-700",
|
|
3157
|
+
"peer-checked:after:translate-x-full",
|
|
3158
|
+
"rtl:peer-checked:after:-translate-x-full",
|
|
3159
|
+
"peer-checked:after:border-white",
|
|
3160
|
+
"after:absolute",
|
|
3161
|
+
"after:bg-white",
|
|
3162
|
+
"after:transition-colors",
|
|
3163
|
+
"after:transition-transform",
|
|
3164
|
+
"duration-500"
|
|
3165
|
+
].filter(Boolean).join(" ");
|
|
3166
|
+
const wrapperClasses = [
|
|
3167
|
+
"inline-flex items-center cursor-pointer"
|
|
3168
|
+
].filter(Boolean).join(" ");
|
|
3169
|
+
return /* @__PURE__ */ jsxs("label", { className: cn(wrapperClasses, wrapperClassName, props.disabled && "cursor-not-allowed"), children: [
|
|
3170
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", value: "", className: "sr-only peer", ...props }),
|
|
3171
|
+
/* @__PURE__ */ jsx("div", { className: cn(divClasses, ToggleSize[size], ToggleVariant[variant], ToggleThumbShape[thumbShape], props.disabled && "opacity-50 cursor-not-allowed") }),
|
|
3172
|
+
label && /* @__PURE__ */ jsx("span", { className: cn("ms-3 text-sm font-medium dark:text-white", labelClassName), children: label })
|
|
3173
|
+
] });
|
|
3174
|
+
};
|
|
3175
|
+
export {
|
|
3176
|
+
Accordion,
|
|
3177
|
+
Alert,
|
|
3178
|
+
Avatar,
|
|
3179
|
+
AvatarGroup,
|
|
3180
|
+
Badge,
|
|
3181
|
+
BottomNavbar,
|
|
3182
|
+
BottomNavbarAction,
|
|
3183
|
+
Breadcrumb,
|
|
3184
|
+
Button,
|
|
3185
|
+
ButtonVariantsMap,
|
|
3186
|
+
Card,
|
|
3187
|
+
CheckboxInput,
|
|
3188
|
+
CodeInput,
|
|
3189
|
+
Collection,
|
|
3190
|
+
DatePicker,
|
|
3191
|
+
FAB,
|
|
3192
|
+
FileUpload,
|
|
3193
|
+
Grid,
|
|
3194
|
+
GridItem,
|
|
3195
|
+
ListCheckboxInput,
|
|
3196
|
+
Masonry,
|
|
3197
|
+
Modal,
|
|
3198
|
+
Offcanvas,
|
|
3199
|
+
Pagination,
|
|
3200
|
+
RadioInput,
|
|
3201
|
+
SelectInput,
|
|
3202
|
+
Skeleton,
|
|
3203
|
+
Slider,
|
|
3204
|
+
Spinner,
|
|
3205
|
+
Table,
|
|
3206
|
+
Tabs,
|
|
3207
|
+
TextInput,
|
|
3208
|
+
Textarea,
|
|
3209
|
+
Timeline,
|
|
3210
|
+
ToastProvider,
|
|
3211
|
+
Toggle,
|
|
3212
|
+
Tooltip,
|
|
3213
|
+
getVariantClasses,
|
|
3214
|
+
useToast
|
|
3215
|
+
};
|