ssovee-os-web-ui 0.1.4
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/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/index.cjs +2027 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +313 -0
- package/dist/index.d.ts +313 -0
- package/dist/index.js +1972 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
- package/tailwind-preset.js +20 -0
- package/theme.css +11 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2027 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React20 = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var react = require('@phosphor-icons/react');
|
|
6
|
+
|
|
7
|
+
function _interopNamespace(e) {
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n.default = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var React20__namespace = /*#__PURE__*/_interopNamespace(React20);
|
|
26
|
+
|
|
27
|
+
// src/components/Button.tsx
|
|
28
|
+
|
|
29
|
+
// src/utils/helpers.ts
|
|
30
|
+
function cn(...inputs) {
|
|
31
|
+
return inputs.filter(Boolean).join(" ");
|
|
32
|
+
}
|
|
33
|
+
var Button = React20__namespace.default.forwardRef(
|
|
34
|
+
({
|
|
35
|
+
className,
|
|
36
|
+
variant = "primary",
|
|
37
|
+
tone = "primary",
|
|
38
|
+
size = "md",
|
|
39
|
+
loading = false,
|
|
40
|
+
leftIcon,
|
|
41
|
+
rightIcon,
|
|
42
|
+
fullWidth = false,
|
|
43
|
+
rounded = "lg",
|
|
44
|
+
disabled,
|
|
45
|
+
children,
|
|
46
|
+
...props
|
|
47
|
+
}, ref) => {
|
|
48
|
+
const baseClasses = "inline-flex items-center justify-center font-medium transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed";
|
|
49
|
+
const variantClasses = {
|
|
50
|
+
primary: "bg-brand-color text-white hover:bg-brand-color/90 active:bg-brand-color/80 focus-visible:ring-brand-color/50 shadow-sm hover:shadow-md active:shadow-none disabled:bg-brand-color/50 disabled:text-white/80",
|
|
51
|
+
secondary: "bg-surface-3 text-neutral-100 hover:bg-surface-4 active:bg-surface-4 focus-visible:ring-surface-3/50 border border-surface-4 shadow-sm hover:shadow-md active:shadow-none disabled:bg-surface-3/50",
|
|
52
|
+
outline: "bg-transparent text-neutral-400 border border-surface-1 hover:bg-surface-1 active:bg-surface-1 focus-visible:ring-surface-1/50",
|
|
53
|
+
ghost: "bg-transparent text-neutral-400 hover:bg-surface-1 active:bg-surface-1 focus-visible:ring-surface-1/50",
|
|
54
|
+
danger: "bg-red-500 text-white hover:bg-red-600 active:bg-red-600 focus-visible:ring-red-500/50 shadow-sm hover:shadow-md active:shadow-none disabled:bg-red-500/50",
|
|
55
|
+
success: "bg-green-500 text-white hover:bg-green-600 active:bg-green-600 focus-visible:ring-green-500/50 shadow-sm hover:shadow-md active:shadow-none disabled:bg-green-500/50",
|
|
56
|
+
filled: "",
|
|
57
|
+
text: ""
|
|
58
|
+
};
|
|
59
|
+
const filledToneClasses = {
|
|
60
|
+
primary: "bg-brand-color text-white hover:bg-brand-color/90 active:bg-brand-color/80 focus-visible:ring-brand-color/50 shadow-sm hover:shadow-md active:shadow-none disabled:bg-brand-color/50 disabled:text-white/80",
|
|
61
|
+
neutral: "bg-surface-3 text-neutral-100 hover:bg-surface-4 active:bg-surface-4 focus-visible:ring-surface-3/50 shadow-sm hover:shadow-md active:shadow-none disabled:bg-surface-3/50",
|
|
62
|
+
success: "bg-green-500 text-white hover:bg-green-600 active:bg-green-600 focus-visible:ring-green-500/50 shadow-sm hover:shadow-md active:shadow-none disabled:bg-green-500/50",
|
|
63
|
+
danger: "bg-red-500 text-white hover:bg-red-600 active:bg-red-600 focus-visible:ring-red-500/50 shadow-sm hover:shadow-md active:shadow-none disabled:bg-red-500/50"
|
|
64
|
+
};
|
|
65
|
+
const textToneClasses = {
|
|
66
|
+
primary: "bg-transparent text-brand-color hover:text-brand-color/90 active:text-brand-color/80 hover:underline underline-offset-2 focus-visible:ring-brand-color/30",
|
|
67
|
+
neutral: "bg-transparent text-neutral-400 hover:text-neutral-300 active:text-neutral-300 focus-visible:ring-surface-1/50",
|
|
68
|
+
success: "bg-transparent text-green-600 hover:text-green-700 active:text-green-700 focus-visible:ring-green-500/30",
|
|
69
|
+
danger: "bg-transparent text-red-600 hover:text-red-700 active:text-red-700 focus-visible:ring-red-500/30"
|
|
70
|
+
};
|
|
71
|
+
const sizeClasses = {
|
|
72
|
+
sm: "h-8 px-3 text-sm",
|
|
73
|
+
md: "h-10 px-4 text-base",
|
|
74
|
+
lg: "h-12 px-5 text-lg",
|
|
75
|
+
xl: "h-14 px-6 text-xl"
|
|
76
|
+
};
|
|
77
|
+
const roundedClasses = {
|
|
78
|
+
sm: "rounded-[6px]",
|
|
79
|
+
md: "rounded-[6px]",
|
|
80
|
+
lg: "rounded-[6px]",
|
|
81
|
+
full: "rounded-full"
|
|
82
|
+
};
|
|
83
|
+
const widthClasses = fullWidth ? "w-full" : "";
|
|
84
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
85
|
+
"button",
|
|
86
|
+
{
|
|
87
|
+
ref,
|
|
88
|
+
className: cn(
|
|
89
|
+
baseClasses,
|
|
90
|
+
variant === "filled" ? filledToneClasses[tone] : variant === "text" ? textToneClasses[tone] : variantClasses[variant],
|
|
91
|
+
sizeClasses[size],
|
|
92
|
+
roundedClasses[rounded],
|
|
93
|
+
widthClasses,
|
|
94
|
+
className
|
|
95
|
+
),
|
|
96
|
+
"data-variant": variant,
|
|
97
|
+
"data-tone": tone,
|
|
98
|
+
disabled: disabled || loading,
|
|
99
|
+
...props,
|
|
100
|
+
children: [
|
|
101
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" }),
|
|
102
|
+
!loading && leftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-2", children: leftIcon }),
|
|
103
|
+
children,
|
|
104
|
+
!loading && rightIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2", children: rightIcon })
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
Button.displayName = "Button";
|
|
111
|
+
var Button_default = Button;
|
|
112
|
+
var Typography = ({
|
|
113
|
+
as,
|
|
114
|
+
variant = "p",
|
|
115
|
+
size,
|
|
116
|
+
weight,
|
|
117
|
+
color,
|
|
118
|
+
className,
|
|
119
|
+
children
|
|
120
|
+
}) => {
|
|
121
|
+
const Component = as || variant;
|
|
122
|
+
const sizeClasses = {
|
|
123
|
+
xs: "text-xs",
|
|
124
|
+
sm: "text-sm",
|
|
125
|
+
md: "text-base",
|
|
126
|
+
lg: "text-lg",
|
|
127
|
+
xl: "text-xl",
|
|
128
|
+
"2xl": "text-2xl",
|
|
129
|
+
"3xl": "text-3xl",
|
|
130
|
+
"4xl": "text-4xl",
|
|
131
|
+
"5xl": "text-5xl"
|
|
132
|
+
};
|
|
133
|
+
const weightClasses = {
|
|
134
|
+
thin: "font-thin",
|
|
135
|
+
extralight: "font-extralight",
|
|
136
|
+
light: "font-light",
|
|
137
|
+
normal: "font-normal",
|
|
138
|
+
medium: "font-medium",
|
|
139
|
+
semibold: "font-semibold",
|
|
140
|
+
bold: "font-bold",
|
|
141
|
+
extrabold: "font-extrabold",
|
|
142
|
+
black: "font-black"
|
|
143
|
+
};
|
|
144
|
+
const colorClasses = {
|
|
145
|
+
"neutral-100": "text-neutral-100",
|
|
146
|
+
"neutral-200": "text-neutral-200",
|
|
147
|
+
"neutral-300": "text-neutral-300",
|
|
148
|
+
"neutral-400": "text-neutral-400",
|
|
149
|
+
"neutral-500": "text-neutral-500",
|
|
150
|
+
"neutral-600": "text-neutral-600",
|
|
151
|
+
"neutral-700": "text-neutral-700",
|
|
152
|
+
"neutral-800": "text-neutral-800",
|
|
153
|
+
"neutral-900": "text-neutral-900",
|
|
154
|
+
"brand-color": "text-brand-color",
|
|
155
|
+
"red-500": "text-red-500",
|
|
156
|
+
"green-500": "text-green-500",
|
|
157
|
+
"blue-500": "text-blue-500",
|
|
158
|
+
"yellow-500": "text-yellow-500"
|
|
159
|
+
};
|
|
160
|
+
const classes = cn(
|
|
161
|
+
size && sizeClasses[size],
|
|
162
|
+
weight && weightClasses[weight],
|
|
163
|
+
color && colorClasses[color],
|
|
164
|
+
className
|
|
165
|
+
);
|
|
166
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component, { className: classes, children });
|
|
167
|
+
};
|
|
168
|
+
var Typography_default = Typography;
|
|
169
|
+
var Input = React20__namespace.default.forwardRef(
|
|
170
|
+
({
|
|
171
|
+
className,
|
|
172
|
+
variant = "default",
|
|
173
|
+
size = "md",
|
|
174
|
+
leftIcon,
|
|
175
|
+
rightIcon,
|
|
176
|
+
showSubmitButton = false,
|
|
177
|
+
onSubmit,
|
|
178
|
+
error,
|
|
179
|
+
label,
|
|
180
|
+
helperText,
|
|
181
|
+
fullWidth = false,
|
|
182
|
+
onKeyUp,
|
|
183
|
+
...props
|
|
184
|
+
}, ref) => {
|
|
185
|
+
const baseClasses = "transition-all duration-200 focus:outline-none placeholder:text-neutral-300 rounded-[6px]";
|
|
186
|
+
const variantClasses = {
|
|
187
|
+
default: "bg-primary border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
188
|
+
filled: "bg-surface-4 border border-surface-4 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
189
|
+
outline: "bg-transparent border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50"
|
|
190
|
+
};
|
|
191
|
+
const sizeClasses = {
|
|
192
|
+
sm: "h-8 px-2 text-sm",
|
|
193
|
+
md: "h-10 px-3 text-base",
|
|
194
|
+
lg: "h-12 px-4 text-lg"
|
|
195
|
+
};
|
|
196
|
+
const widthClasses = fullWidth ? "w-full" : "";
|
|
197
|
+
const handleKeyUp = (e) => {
|
|
198
|
+
if (e.key === "Enter" && onSubmit) {
|
|
199
|
+
onSubmit();
|
|
200
|
+
}
|
|
201
|
+
onKeyUp?.(e);
|
|
202
|
+
};
|
|
203
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", fullWidth && "w-full"), children: [
|
|
204
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium text-neutral-500 mb-1", children: label }),
|
|
205
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
206
|
+
leftIcon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-neutral-400", children: leftIcon }),
|
|
207
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
208
|
+
"input",
|
|
209
|
+
{
|
|
210
|
+
ref,
|
|
211
|
+
className: cn(
|
|
212
|
+
baseClasses,
|
|
213
|
+
variantClasses[variant],
|
|
214
|
+
sizeClasses[size],
|
|
215
|
+
widthClasses,
|
|
216
|
+
leftIcon ? "pl-10" : "",
|
|
217
|
+
rightIcon || showSubmitButton ? "pr-10" : "",
|
|
218
|
+
error && "border-red-500 focus:border-red-500 focus:ring-red-500/50",
|
|
219
|
+
className
|
|
220
|
+
),
|
|
221
|
+
onKeyUp: handleKeyUp,
|
|
222
|
+
...props
|
|
223
|
+
}
|
|
224
|
+
),
|
|
225
|
+
rightIcon && !showSubmitButton && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-neutral-400", children: rightIcon }),
|
|
226
|
+
showSubmitButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
227
|
+
react.ArrowCircleRightIcon,
|
|
228
|
+
{
|
|
229
|
+
size: 20,
|
|
230
|
+
onClick: onSubmit,
|
|
231
|
+
className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-neutral-300 cursor-pointer hover:text-neutral-400 transition-colors"
|
|
232
|
+
}
|
|
233
|
+
)
|
|
234
|
+
] }),
|
|
235
|
+
(error || helperText) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1", children: [
|
|
236
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-red-500", children: error }),
|
|
237
|
+
helperText && !error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-neutral-400", children: helperText })
|
|
238
|
+
] })
|
|
239
|
+
] });
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
Input.displayName = "Input";
|
|
243
|
+
var Input_default = Input;
|
|
244
|
+
var TextArea = React20__namespace.default.forwardRef(
|
|
245
|
+
({
|
|
246
|
+
className,
|
|
247
|
+
variant = "default",
|
|
248
|
+
size = "md",
|
|
249
|
+
error,
|
|
250
|
+
label,
|
|
251
|
+
helperText,
|
|
252
|
+
fullWidth = false,
|
|
253
|
+
resize = "vertical",
|
|
254
|
+
...props
|
|
255
|
+
}, ref) => {
|
|
256
|
+
const baseClasses = "transition-all duration-200 focus:outline-none placeholder:text-neutral-300 rounded-[6px]";
|
|
257
|
+
const variantClasses = {
|
|
258
|
+
default: "bg-primary border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
259
|
+
filled: "bg-surface-4 border border-surface-4 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
260
|
+
outline: "bg-transparent border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50"
|
|
261
|
+
};
|
|
262
|
+
const sizeClasses = {
|
|
263
|
+
sm: "px-2 py-1 text-sm",
|
|
264
|
+
md: "px-3 py-2 text-base",
|
|
265
|
+
lg: "px-4 py-3 text-lg"
|
|
266
|
+
};
|
|
267
|
+
const resizeClasses = {
|
|
268
|
+
none: "resize-none",
|
|
269
|
+
vertical: "resize-y",
|
|
270
|
+
horizontal: "resize-x",
|
|
271
|
+
both: "resize"
|
|
272
|
+
};
|
|
273
|
+
const widthClasses = fullWidth ? "w-full" : "";
|
|
274
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", fullWidth && "w-full"), children: [
|
|
275
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium text-neutral-500 mb-1", children: label }),
|
|
276
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
277
|
+
"textarea",
|
|
278
|
+
{
|
|
279
|
+
ref,
|
|
280
|
+
className: cn(
|
|
281
|
+
baseClasses,
|
|
282
|
+
variantClasses[variant],
|
|
283
|
+
sizeClasses[size],
|
|
284
|
+
resizeClasses[resize],
|
|
285
|
+
widthClasses,
|
|
286
|
+
error && "border-red-500 focus:border-red-500 focus:ring-red-500/50",
|
|
287
|
+
className
|
|
288
|
+
),
|
|
289
|
+
...props
|
|
290
|
+
}
|
|
291
|
+
),
|
|
292
|
+
(error || helperText) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1", children: [
|
|
293
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-red-500", children: error }),
|
|
294
|
+
helperText && !error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-neutral-400", children: helperText })
|
|
295
|
+
] })
|
|
296
|
+
] });
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
TextArea.displayName = "TextArea";
|
|
300
|
+
var TextArea_default = TextArea;
|
|
301
|
+
var Select = React20__namespace.default.forwardRef(
|
|
302
|
+
({
|
|
303
|
+
className,
|
|
304
|
+
options,
|
|
305
|
+
variant = "default",
|
|
306
|
+
size = "md",
|
|
307
|
+
error,
|
|
308
|
+
label,
|
|
309
|
+
helperText,
|
|
310
|
+
fullWidth = false,
|
|
311
|
+
onChange,
|
|
312
|
+
placeholder,
|
|
313
|
+
value,
|
|
314
|
+
...props
|
|
315
|
+
}, ref) => {
|
|
316
|
+
const baseClasses = "transition-all duration-200 focus:outline-none appearance-none cursor-pointer rounded-[6px]";
|
|
317
|
+
const variantClasses = {
|
|
318
|
+
default: "bg-primary border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
319
|
+
filled: "bg-surface-4 border border-surface-4 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
320
|
+
outline: "bg-transparent border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50"
|
|
321
|
+
};
|
|
322
|
+
const sizeClasses = {
|
|
323
|
+
sm: "h-8 px-2 text-sm",
|
|
324
|
+
md: "h-10 px-3 text-base",
|
|
325
|
+
lg: "h-12 px-4 text-lg"
|
|
326
|
+
};
|
|
327
|
+
const widthClasses = fullWidth ? "w-full" : "";
|
|
328
|
+
const handleChange = (e) => {
|
|
329
|
+
onChange?.(e.target.value);
|
|
330
|
+
};
|
|
331
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", fullWidth && "w-full"), children: [
|
|
332
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium text-neutral-500 mb-1", children: label }),
|
|
333
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
334
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
335
|
+
"select",
|
|
336
|
+
{
|
|
337
|
+
ref,
|
|
338
|
+
className: cn(
|
|
339
|
+
baseClasses,
|
|
340
|
+
variantClasses[variant],
|
|
341
|
+
sizeClasses[size],
|
|
342
|
+
widthClasses,
|
|
343
|
+
"pr-10",
|
|
344
|
+
error && "border-red-500 focus:border-red-500 focus:ring-red-500/50",
|
|
345
|
+
className
|
|
346
|
+
),
|
|
347
|
+
value,
|
|
348
|
+
onChange: handleChange,
|
|
349
|
+
...props,
|
|
350
|
+
children: [
|
|
351
|
+
placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
352
|
+
options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
353
|
+
"option",
|
|
354
|
+
{
|
|
355
|
+
value: option.value,
|
|
356
|
+
disabled: option.disabled,
|
|
357
|
+
children: option.label
|
|
358
|
+
},
|
|
359
|
+
option.value
|
|
360
|
+
))
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
),
|
|
364
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
365
|
+
react.CaretDownIcon,
|
|
366
|
+
{
|
|
367
|
+
size: 16,
|
|
368
|
+
className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-neutral-400 pointer-events-none"
|
|
369
|
+
}
|
|
370
|
+
)
|
|
371
|
+
] }),
|
|
372
|
+
(error || helperText) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1", children: [
|
|
373
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-red-500", children: error }),
|
|
374
|
+
helperText && !error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-neutral-400", children: helperText })
|
|
375
|
+
] })
|
|
376
|
+
] });
|
|
377
|
+
}
|
|
378
|
+
);
|
|
379
|
+
Select.displayName = "Select";
|
|
380
|
+
var Select_default = Select;
|
|
381
|
+
var Checkbox = React20__namespace.default.forwardRef(
|
|
382
|
+
({
|
|
383
|
+
className,
|
|
384
|
+
variant = "default",
|
|
385
|
+
size = "md",
|
|
386
|
+
error,
|
|
387
|
+
label,
|
|
388
|
+
helperText,
|
|
389
|
+
indeterminate = false,
|
|
390
|
+
checked,
|
|
391
|
+
onChange,
|
|
392
|
+
...props
|
|
393
|
+
}, ref) => {
|
|
394
|
+
const baseClasses = "transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 cursor-pointer rounded-[6px]";
|
|
395
|
+
const variantClasses = {
|
|
396
|
+
default: "bg-primary border border-surface-1 focus:border-brand-color focus:ring-brand-color/50 checked:bg-brand-color checked:border-brand-color",
|
|
397
|
+
filled: "bg-surface-4 border border-surface-4 focus:border-brand-color focus:ring-brand-color/50 checked:bg-brand-color checked:border-brand-color"
|
|
398
|
+
};
|
|
399
|
+
const sizeClasses = {
|
|
400
|
+
sm: "w-4 h-4",
|
|
401
|
+
md: "w-5 h-5",
|
|
402
|
+
lg: "w-6 h-6"
|
|
403
|
+
};
|
|
404
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
405
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
406
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
407
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
408
|
+
"input",
|
|
409
|
+
{
|
|
410
|
+
ref,
|
|
411
|
+
type: "checkbox",
|
|
412
|
+
className: cn(
|
|
413
|
+
baseClasses,
|
|
414
|
+
variantClasses[variant],
|
|
415
|
+
sizeClasses[size],
|
|
416
|
+
"appearance-none",
|
|
417
|
+
error && "border-red-500 focus:border-red-500 focus:ring-red-500/50",
|
|
418
|
+
className
|
|
419
|
+
),
|
|
420
|
+
defaultChecked: checked,
|
|
421
|
+
onChange,
|
|
422
|
+
...props
|
|
423
|
+
}
|
|
424
|
+
),
|
|
425
|
+
(checked || indeterminate) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
426
|
+
react.CheckIcon,
|
|
427
|
+
{
|
|
428
|
+
size: size === "sm" ? 12 : size === "md" ? 16 : 20,
|
|
429
|
+
className: "text-white",
|
|
430
|
+
weight: indeterminate ? "bold" : "regular"
|
|
431
|
+
}
|
|
432
|
+
) })
|
|
433
|
+
] }),
|
|
434
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-neutral-400 cursor-pointer select-none", children: label })
|
|
435
|
+
] }),
|
|
436
|
+
(error || helperText) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 ml-6", children: [
|
|
437
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-red-500", children: error }),
|
|
438
|
+
helperText && !error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-neutral-400", children: helperText })
|
|
439
|
+
] })
|
|
440
|
+
] });
|
|
441
|
+
}
|
|
442
|
+
);
|
|
443
|
+
Checkbox.displayName = "Checkbox";
|
|
444
|
+
var Checkbox_default = Checkbox;
|
|
445
|
+
var Toggle = React20__namespace.default.forwardRef(
|
|
446
|
+
({
|
|
447
|
+
checked,
|
|
448
|
+
onChange,
|
|
449
|
+
variant = "default",
|
|
450
|
+
size = "md",
|
|
451
|
+
disabled = false,
|
|
452
|
+
label,
|
|
453
|
+
helperText,
|
|
454
|
+
fullWidth = false
|
|
455
|
+
}, ref) => {
|
|
456
|
+
const baseClasses = "flex items-center rounded-full cursor-pointer transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-offset-2";
|
|
457
|
+
const variantClasses = {
|
|
458
|
+
default: "focus:ring-brand-color/50",
|
|
459
|
+
success: "focus:ring-green-500/50",
|
|
460
|
+
warning: "focus:ring-yellow-500/50",
|
|
461
|
+
danger: "focus:ring-red-500/50"
|
|
462
|
+
};
|
|
463
|
+
const toggleClasses = {
|
|
464
|
+
default: checked ? "bg-brand-color" : "bg-gray-500",
|
|
465
|
+
success: checked ? "bg-green-500" : "bg-gray-500",
|
|
466
|
+
warning: checked ? "bg-yellow-500" : "bg-gray-500",
|
|
467
|
+
danger: checked ? "bg-red-500" : "bg-gray-500"
|
|
468
|
+
};
|
|
469
|
+
const sizeClasses = {
|
|
470
|
+
sm: "w-8 h-4 px-0.5",
|
|
471
|
+
md: "w-10 h-5 px-0.5",
|
|
472
|
+
lg: "w-12 h-6 px-1"
|
|
473
|
+
};
|
|
474
|
+
const thumbSizeClasses = {
|
|
475
|
+
sm: "w-3 h-3",
|
|
476
|
+
md: "w-4 h-4",
|
|
477
|
+
lg: "w-5 h-5"
|
|
478
|
+
};
|
|
479
|
+
const thumbTransformClasses = {
|
|
480
|
+
sm: checked ? "translate-x-4" : "translate-x-0",
|
|
481
|
+
md: checked ? "translate-x-5" : "translate-x-0",
|
|
482
|
+
lg: checked ? "translate-x-6" : "translate-x-0"
|
|
483
|
+
};
|
|
484
|
+
const widthClasses = fullWidth ? "w-full" : "";
|
|
485
|
+
const handleClick = () => {
|
|
486
|
+
if (!disabled) {
|
|
487
|
+
onChange(!checked);
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", fullWidth && "w-full"), children: [
|
|
491
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2", fullWidth && "w-full"), children: [
|
|
492
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
493
|
+
"button",
|
|
494
|
+
{
|
|
495
|
+
ref,
|
|
496
|
+
type: "button",
|
|
497
|
+
className: cn(
|
|
498
|
+
baseClasses,
|
|
499
|
+
variantClasses[variant],
|
|
500
|
+
toggleClasses[variant],
|
|
501
|
+
sizeClasses[size],
|
|
502
|
+
widthClasses,
|
|
503
|
+
disabled && "opacity-50 cursor-not-allowed"
|
|
504
|
+
),
|
|
505
|
+
onClick: handleClick,
|
|
506
|
+
disabled,
|
|
507
|
+
role: "switch",
|
|
508
|
+
"aria-checked": checked,
|
|
509
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
510
|
+
"div",
|
|
511
|
+
{
|
|
512
|
+
className: cn(
|
|
513
|
+
"bg-white rounded-full shadow-md transform transition-transform duration-300",
|
|
514
|
+
thumbSizeClasses[size],
|
|
515
|
+
thumbTransformClasses[size]
|
|
516
|
+
)
|
|
517
|
+
}
|
|
518
|
+
)
|
|
519
|
+
}
|
|
520
|
+
),
|
|
521
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-neutral-500 cursor-pointer select-none", onClick: handleClick, children: label })
|
|
522
|
+
] }),
|
|
523
|
+
helperText && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 ml-12", children: /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-neutral-400", children: helperText }) })
|
|
524
|
+
] });
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
Toggle.displayName = "Toggle";
|
|
528
|
+
var Toggle_default = Toggle;
|
|
529
|
+
var Dropdown = ({
|
|
530
|
+
options,
|
|
531
|
+
value,
|
|
532
|
+
onChange,
|
|
533
|
+
placeholder = "Select an option",
|
|
534
|
+
variant = "default",
|
|
535
|
+
size = "md",
|
|
536
|
+
disabled = false,
|
|
537
|
+
className,
|
|
538
|
+
trigger
|
|
539
|
+
}) => {
|
|
540
|
+
const [isOpen, setIsOpen] = React20.useState(false);
|
|
541
|
+
const dropdownRef = React20.useRef(null);
|
|
542
|
+
const selectedOption = options.find((option) => option.value === value);
|
|
543
|
+
React20.useEffect(() => {
|
|
544
|
+
const handleClickOutside = (event) => {
|
|
545
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
546
|
+
setIsOpen(false);
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
550
|
+
return () => {
|
|
551
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
552
|
+
};
|
|
553
|
+
}, []);
|
|
554
|
+
const handleToggle = () => {
|
|
555
|
+
if (!disabled) {
|
|
556
|
+
setIsOpen(!isOpen);
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
const handleSelect = (option) => {
|
|
560
|
+
if (!option.disabled) {
|
|
561
|
+
onChange?.(option.value);
|
|
562
|
+
setIsOpen(false);
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
const baseClasses = "transition-all duration-200 focus:outline-none cursor-pointer rounded-[6px]";
|
|
566
|
+
const variantClasses = {
|
|
567
|
+
default: "bg-primary border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
568
|
+
filled: "bg-surface-4 border border-surface-4 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
569
|
+
outline: "bg-transparent border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50"
|
|
570
|
+
};
|
|
571
|
+
const sizeClasses = {
|
|
572
|
+
sm: "h-8 px-2 text-sm",
|
|
573
|
+
md: "h-10 px-3 text-base",
|
|
574
|
+
lg: "h-12 px-4 text-lg"
|
|
575
|
+
};
|
|
576
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: dropdownRef, className: "", children: [
|
|
577
|
+
trigger ? /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: handleToggle, className: "cursor-pointer", children: trigger }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
578
|
+
"button",
|
|
579
|
+
{
|
|
580
|
+
onClick: handleToggle,
|
|
581
|
+
disabled,
|
|
582
|
+
className: cn(
|
|
583
|
+
baseClasses,
|
|
584
|
+
variantClasses[variant],
|
|
585
|
+
sizeClasses[size],
|
|
586
|
+
"w-full flex items-center justify-between pr-8",
|
|
587
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
588
|
+
className
|
|
589
|
+
),
|
|
590
|
+
children: [
|
|
591
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: selectedOption ? "text-neutral-500" : "text-neutral-300", children: selectedOption ? selectedOption.label : placeholder }),
|
|
592
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
593
|
+
react.CaretDownIcon,
|
|
594
|
+
{
|
|
595
|
+
size: 16,
|
|
596
|
+
className: cn(
|
|
597
|
+
"text-neutral-400 transition-transform duration-200",
|
|
598
|
+
isOpen && "rotate-180"
|
|
599
|
+
)
|
|
600
|
+
}
|
|
601
|
+
)
|
|
602
|
+
]
|
|
603
|
+
}
|
|
604
|
+
),
|
|
605
|
+
isOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-full left-0 right-0 mt-1 bg-secondary border border-surface-1 rounded-[6px] shadow-lg z-50 max-h-60 overflow-y-auto", children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
606
|
+
"div",
|
|
607
|
+
{
|
|
608
|
+
onClick: () => handleSelect(option),
|
|
609
|
+
className: cn(
|
|
610
|
+
"px-3 py-2 cursor-pointer transition-colors duration-200 flex items-center gap-2",
|
|
611
|
+
option.value === value && "bg-brand-color text-neutral-500",
|
|
612
|
+
!option.disabled && "hover:bg-surface-3",
|
|
613
|
+
option.disabled && "opacity-50 cursor-not-allowed"
|
|
614
|
+
),
|
|
615
|
+
children: [
|
|
616
|
+
option.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { children: option.icon }),
|
|
617
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
|
|
618
|
+
]
|
|
619
|
+
},
|
|
620
|
+
option.value
|
|
621
|
+
)) })
|
|
622
|
+
] });
|
|
623
|
+
};
|
|
624
|
+
var Dropdown_default = Dropdown;
|
|
625
|
+
var ImageWithPlaceholder = ({
|
|
626
|
+
src,
|
|
627
|
+
alt,
|
|
628
|
+
fallbackSrc = "",
|
|
629
|
+
className,
|
|
630
|
+
onError,
|
|
631
|
+
...props
|
|
632
|
+
}) => {
|
|
633
|
+
const isValidSrc = (s) => {
|
|
634
|
+
if (!s) return false;
|
|
635
|
+
if (typeof s === "object") return true;
|
|
636
|
+
if (typeof s === "string") {
|
|
637
|
+
const trimmed = s.trim();
|
|
638
|
+
if (trimmed === "") return false;
|
|
639
|
+
if (trimmed.startsWith("data:")) return true;
|
|
640
|
+
if (trimmed.startsWith("/") || trimmed.startsWith("./") || trimmed.startsWith("../")) return true;
|
|
641
|
+
try {
|
|
642
|
+
new URL(trimmed);
|
|
643
|
+
return true;
|
|
644
|
+
} catch {
|
|
645
|
+
return false;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return true;
|
|
649
|
+
};
|
|
650
|
+
const initialSrc = isValidSrc(src) ? src : fallbackSrc;
|
|
651
|
+
const [imgSrc, setImgSrc] = React20.useState(initialSrc);
|
|
652
|
+
const [hasError, setHasError] = React20.useState(!isValidSrc(src));
|
|
653
|
+
React20.useEffect(() => {
|
|
654
|
+
if (isValidSrc(src)) {
|
|
655
|
+
setImgSrc(src);
|
|
656
|
+
setHasError(false);
|
|
657
|
+
} else {
|
|
658
|
+
setImgSrc(fallbackSrc);
|
|
659
|
+
setHasError(true);
|
|
660
|
+
}
|
|
661
|
+
}, [src, fallbackSrc]);
|
|
662
|
+
const handleError = (e) => {
|
|
663
|
+
if (!hasError) {
|
|
664
|
+
setHasError(true);
|
|
665
|
+
setImgSrc(fallbackSrc);
|
|
666
|
+
}
|
|
667
|
+
if (onError) {
|
|
668
|
+
onError(e);
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
672
|
+
"img",
|
|
673
|
+
{
|
|
674
|
+
...props,
|
|
675
|
+
src: typeof imgSrc === "string" ? imgSrc : void 0,
|
|
676
|
+
alt,
|
|
677
|
+
className: cn(className),
|
|
678
|
+
onError: handleError
|
|
679
|
+
}
|
|
680
|
+
);
|
|
681
|
+
};
|
|
682
|
+
var ImageWithPlaceholder_default = ImageWithPlaceholder;
|
|
683
|
+
var Loading = ({
|
|
684
|
+
variant = "image",
|
|
685
|
+
size = "md",
|
|
686
|
+
text = "Loading...",
|
|
687
|
+
fullScreen = false,
|
|
688
|
+
className
|
|
689
|
+
}) => {
|
|
690
|
+
const sizeClasses = {
|
|
691
|
+
sm: "w-6 h-6",
|
|
692
|
+
md: "w-8 h-8",
|
|
693
|
+
lg: "w-12 h-12",
|
|
694
|
+
xl: "w-16 h-16"
|
|
695
|
+
};
|
|
696
|
+
const textSizeClasses = {
|
|
697
|
+
sm: "text-xs",
|
|
698
|
+
md: "text-sm",
|
|
699
|
+
lg: "text-base",
|
|
700
|
+
xl: "text-lg"
|
|
701
|
+
};
|
|
702
|
+
const renderSpinner = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("animate-spin rounded-full border-2 border-current border-t-transparent", sizeClasses[size]) });
|
|
703
|
+
const renderDots = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-1", children: [
|
|
704
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("animate-bounce rounded-full bg-current", sizeClasses[size]), style: { animationDelay: "0ms" } }),
|
|
705
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("animate-bounce rounded-full bg-current", sizeClasses[size]), style: { animationDelay: "150ms" } }),
|
|
706
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("animate-bounce rounded-full bg-current", sizeClasses[size]), style: { animationDelay: "300ms" } })
|
|
707
|
+
] });
|
|
708
|
+
const renderPulse = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("animate-pulse rounded-full bg-current", sizeClasses[size]) });
|
|
709
|
+
const imageSizes = {
|
|
710
|
+
sm: 24,
|
|
711
|
+
md: 32,
|
|
712
|
+
lg: 48,
|
|
713
|
+
xl: 64
|
|
714
|
+
};
|
|
715
|
+
const renderImage = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
716
|
+
ImageWithPlaceholder_default,
|
|
717
|
+
{
|
|
718
|
+
src: "/app-assets/Loader.gif",
|
|
719
|
+
alt: "Loader",
|
|
720
|
+
width: imageSizes[size],
|
|
721
|
+
height: imageSizes[size],
|
|
722
|
+
className: sizeClasses[size]
|
|
723
|
+
}
|
|
724
|
+
);
|
|
725
|
+
const renderLoader = () => {
|
|
726
|
+
switch (variant) {
|
|
727
|
+
case "spinner":
|
|
728
|
+
return renderSpinner();
|
|
729
|
+
case "dots":
|
|
730
|
+
return renderDots();
|
|
731
|
+
case "pulse":
|
|
732
|
+
return renderPulse();
|
|
733
|
+
case "image":
|
|
734
|
+
default:
|
|
735
|
+
return renderImage();
|
|
736
|
+
}
|
|
737
|
+
};
|
|
738
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col justify-center items-center", className), children: [
|
|
739
|
+
renderLoader(),
|
|
740
|
+
text && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("mt-2 text-neutral-500", textSizeClasses[size]), children: text })
|
|
741
|
+
] });
|
|
742
|
+
if (fullScreen) {
|
|
743
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 flex items-center justify-center bg-primary/50 backdrop-blur-sm z-50", children: content });
|
|
744
|
+
}
|
|
745
|
+
return content;
|
|
746
|
+
};
|
|
747
|
+
var Loading_default = Loading;
|
|
748
|
+
var Toast = ({
|
|
749
|
+
heading,
|
|
750
|
+
message,
|
|
751
|
+
type,
|
|
752
|
+
isVisible,
|
|
753
|
+
onClose,
|
|
754
|
+
duration = 5e3,
|
|
755
|
+
position = "bottom-left",
|
|
756
|
+
showCloseButton = true,
|
|
757
|
+
className
|
|
758
|
+
}) => {
|
|
759
|
+
const [isShowing, setIsShowing] = React20.useState(false);
|
|
760
|
+
React20.useEffect(() => {
|
|
761
|
+
if (isVisible) {
|
|
762
|
+
setIsShowing(true);
|
|
763
|
+
let timer = null;
|
|
764
|
+
if (type !== "error" && duration > 0) {
|
|
765
|
+
timer = setTimeout(() => {
|
|
766
|
+
setIsShowing(false);
|
|
767
|
+
setTimeout(onClose, 300);
|
|
768
|
+
}, duration);
|
|
769
|
+
}
|
|
770
|
+
return () => {
|
|
771
|
+
if (timer) {
|
|
772
|
+
clearTimeout(timer);
|
|
773
|
+
}
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
}, [isVisible, type, duration, onClose]);
|
|
777
|
+
if (!isVisible) return null;
|
|
778
|
+
const getIcon = () => {
|
|
779
|
+
switch (type) {
|
|
780
|
+
case "error":
|
|
781
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.WarningIcon, { size: 20, className: "text-red-500" });
|
|
782
|
+
case "success":
|
|
783
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.CheckCircleIcon, { size: 20, className: "text-green-500" });
|
|
784
|
+
case "warning":
|
|
785
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.WarningIcon, { size: 20, className: "text-yellow-500" });
|
|
786
|
+
case "info":
|
|
787
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.InfoIcon, { size: 20, className: "text-blue-500" });
|
|
788
|
+
default:
|
|
789
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.InfoIcon, { size: 20, className: "text-blue-500" });
|
|
790
|
+
}
|
|
791
|
+
};
|
|
792
|
+
const getTypeClasses = () => {
|
|
793
|
+
switch (type) {
|
|
794
|
+
case "error":
|
|
795
|
+
return "border-l-red-500 bg-red-50";
|
|
796
|
+
case "success":
|
|
797
|
+
return "border-l-green-500 bg-green-50";
|
|
798
|
+
case "warning":
|
|
799
|
+
return "border-l-yellow-500 bg-yellow-50";
|
|
800
|
+
case "info":
|
|
801
|
+
return "border-l-blue-500 bg-blue-50";
|
|
802
|
+
default:
|
|
803
|
+
return "border-l-blue-500 bg-blue-50";
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
const getPositionClasses = () => {
|
|
807
|
+
switch (position) {
|
|
808
|
+
case "top-left":
|
|
809
|
+
return "top-4 left-4";
|
|
810
|
+
case "top-right":
|
|
811
|
+
return "top-4 right-4";
|
|
812
|
+
case "bottom-left":
|
|
813
|
+
return "bottom-4 left-4";
|
|
814
|
+
case "bottom-right":
|
|
815
|
+
return "bottom-4 right-4";
|
|
816
|
+
case "top-center":
|
|
817
|
+
return "top-4 left-1/2 transform -translate-x-1/2";
|
|
818
|
+
case "bottom-center":
|
|
819
|
+
return "bottom-4 left-1/2 transform -translate-x-1/2";
|
|
820
|
+
default:
|
|
821
|
+
return "bottom-4 left-4";
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
const handleClose = () => {
|
|
825
|
+
setIsShowing(false);
|
|
826
|
+
setTimeout(onClose, 300);
|
|
827
|
+
};
|
|
828
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
829
|
+
"div",
|
|
830
|
+
{
|
|
831
|
+
className: cn(
|
|
832
|
+
"fixed z-50 transform transition-all duration-300",
|
|
833
|
+
getPositionClasses(),
|
|
834
|
+
isShowing ? "translate-x-0 opacity-100" : "-translate-x-full opacity-0"
|
|
835
|
+
),
|
|
836
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
837
|
+
"div",
|
|
838
|
+
{
|
|
839
|
+
className: cn(
|
|
840
|
+
"w-80 max-w-sm bg-secondary rounded-[6px] shadow-lg border-l-4 p-4",
|
|
841
|
+
getTypeClasses(),
|
|
842
|
+
className
|
|
843
|
+
),
|
|
844
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
845
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 mt-0.5", children: getIcon() }),
|
|
846
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
847
|
+
heading && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "h4", className: "text-sm font-medium text-neutral-700 mb-1", children: heading }),
|
|
848
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-sm text-neutral-600 leading-relaxed", children: message })
|
|
849
|
+
] }),
|
|
850
|
+
showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
851
|
+
"button",
|
|
852
|
+
{
|
|
853
|
+
onClick: handleClose,
|
|
854
|
+
className: "flex-shrink-0 ml-2 text-neutral-400 hover:text-neutral-600 transition-colors",
|
|
855
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(react.XIcon, { size: 16 })
|
|
856
|
+
}
|
|
857
|
+
)
|
|
858
|
+
] })
|
|
859
|
+
}
|
|
860
|
+
)
|
|
861
|
+
}
|
|
862
|
+
);
|
|
863
|
+
};
|
|
864
|
+
var Toast_default = Toast;
|
|
865
|
+
var Alert = ({
|
|
866
|
+
type,
|
|
867
|
+
title,
|
|
868
|
+
message,
|
|
869
|
+
onClose,
|
|
870
|
+
showCloseButton = false,
|
|
871
|
+
variant = "default",
|
|
872
|
+
className,
|
|
873
|
+
children
|
|
874
|
+
}) => {
|
|
875
|
+
const getIcon = () => {
|
|
876
|
+
switch (type) {
|
|
877
|
+
case "success":
|
|
878
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.CheckCircleIcon, { size: 20, className: "text-green-500" });
|
|
879
|
+
case "error":
|
|
880
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.WarningIcon, { size: 20, className: "text-red-500" });
|
|
881
|
+
case "warning":
|
|
882
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.WarningIcon, { size: 20, className: "text-yellow-500" });
|
|
883
|
+
case "info":
|
|
884
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.InfoIcon, { size: 20, className: "text-blue-500" });
|
|
885
|
+
default:
|
|
886
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.InfoIcon, { size: 20, className: "text-blue-500" });
|
|
887
|
+
}
|
|
888
|
+
};
|
|
889
|
+
const getTypeClasses = () => {
|
|
890
|
+
switch (type) {
|
|
891
|
+
case "success":
|
|
892
|
+
return {
|
|
893
|
+
default: "bg-green-50 border-green-200 text-green-800",
|
|
894
|
+
filled: "bg-green-500 text-white",
|
|
895
|
+
outline: "bg-transparent border-green-500 text-green-700"
|
|
896
|
+
};
|
|
897
|
+
case "error":
|
|
898
|
+
return {
|
|
899
|
+
default: "bg-red-50 border-red-200 text-red-800",
|
|
900
|
+
filled: "bg-red-500 text-white",
|
|
901
|
+
outline: "bg-transparent border-red-500 text-red-700"
|
|
902
|
+
};
|
|
903
|
+
case "warning":
|
|
904
|
+
return {
|
|
905
|
+
default: "bg-yellow-50 border-yellow-200 text-yellow-800",
|
|
906
|
+
filled: "bg-yellow-500 text-white",
|
|
907
|
+
outline: "bg-transparent border-yellow-500 text-yellow-700"
|
|
908
|
+
};
|
|
909
|
+
case "info":
|
|
910
|
+
return {
|
|
911
|
+
default: "bg-blue-50 border-blue-200 text-blue-800",
|
|
912
|
+
filled: "bg-blue-500 text-white",
|
|
913
|
+
outline: "bg-transparent border-blue-500 text-blue-700"
|
|
914
|
+
};
|
|
915
|
+
default:
|
|
916
|
+
return {
|
|
917
|
+
default: "bg-blue-50 border-blue-200 text-blue-800",
|
|
918
|
+
filled: "bg-blue-500 text-white",
|
|
919
|
+
outline: "bg-transparent border-blue-500 text-blue-700"
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
};
|
|
923
|
+
const typeClasses = getTypeClasses()[variant];
|
|
924
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
925
|
+
"div",
|
|
926
|
+
{
|
|
927
|
+
className: cn(
|
|
928
|
+
"rounded-[6px] border p-4",
|
|
929
|
+
typeClasses,
|
|
930
|
+
className
|
|
931
|
+
),
|
|
932
|
+
role: "alert",
|
|
933
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
934
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 mt-0.5", children: getIcon() }),
|
|
935
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
936
|
+
title && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "h4", className: "text-sm font-medium mb-1", children: title }),
|
|
937
|
+
message && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-sm leading-relaxed", children: message }),
|
|
938
|
+
children
|
|
939
|
+
] }),
|
|
940
|
+
showCloseButton && onClose && /* @__PURE__ */ jsxRuntime.jsx(
|
|
941
|
+
"button",
|
|
942
|
+
{
|
|
943
|
+
onClick: onClose,
|
|
944
|
+
className: "flex-shrink-0 ml-2 text-current opacity-70 hover:opacity-100 transition-opacity",
|
|
945
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(react.XIcon, { size: 16 })
|
|
946
|
+
}
|
|
947
|
+
)
|
|
948
|
+
] })
|
|
949
|
+
}
|
|
950
|
+
);
|
|
951
|
+
};
|
|
952
|
+
var Alert_default = Alert;
|
|
953
|
+
var Modal = ({
|
|
954
|
+
isOpen,
|
|
955
|
+
onClose,
|
|
956
|
+
title,
|
|
957
|
+
children,
|
|
958
|
+
size = "md",
|
|
959
|
+
showCloseButton = true,
|
|
960
|
+
closeOnOverlayClick = true,
|
|
961
|
+
closeOnEscape = true,
|
|
962
|
+
className
|
|
963
|
+
}) => {
|
|
964
|
+
React20.useEffect(() => {
|
|
965
|
+
if (!isOpen) return;
|
|
966
|
+
const handleEscape = (e) => {
|
|
967
|
+
if (e.key === "Escape" && closeOnEscape) {
|
|
968
|
+
onClose();
|
|
969
|
+
}
|
|
970
|
+
};
|
|
971
|
+
document.addEventListener("keydown", handleEscape);
|
|
972
|
+
document.body.style.overflow = "hidden";
|
|
973
|
+
return () => {
|
|
974
|
+
document.removeEventListener("keydown", handleEscape);
|
|
975
|
+
document.body.style.overflow = "unset";
|
|
976
|
+
};
|
|
977
|
+
}, [isOpen, onClose, closeOnEscape]);
|
|
978
|
+
if (!isOpen) return null;
|
|
979
|
+
const sizeClasses = {
|
|
980
|
+
sm: "max-w-sm",
|
|
981
|
+
md: "max-w-md",
|
|
982
|
+
lg: "max-w-lg",
|
|
983
|
+
xl: "max-w-xl",
|
|
984
|
+
full: "max-w-full mx-4"
|
|
985
|
+
};
|
|
986
|
+
const handleOverlayClick = (e) => {
|
|
987
|
+
if (e.target === e.currentTarget && closeOnOverlayClick) {
|
|
988
|
+
onClose();
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
992
|
+
"div",
|
|
993
|
+
{
|
|
994
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm",
|
|
995
|
+
onClick: handleOverlayClick,
|
|
996
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
997
|
+
"div",
|
|
998
|
+
{
|
|
999
|
+
className: cn(
|
|
1000
|
+
"bg-secondary rounded-[6px] shadow-xl w-full mx-4 max-h-[90vh] overflow-hidden",
|
|
1001
|
+
sizeClasses[size],
|
|
1002
|
+
className
|
|
1003
|
+
),
|
|
1004
|
+
children: [
|
|
1005
|
+
(title || showCloseButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-2 border-b border-surface-1", children: [
|
|
1006
|
+
title && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1007
|
+
Typography_default,
|
|
1008
|
+
{
|
|
1009
|
+
variant: "h2",
|
|
1010
|
+
className: "text-lg font-semibold text-neutral-500",
|
|
1011
|
+
children: title
|
|
1012
|
+
}
|
|
1013
|
+
),
|
|
1014
|
+
showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1015
|
+
"button",
|
|
1016
|
+
{
|
|
1017
|
+
onClick: onClose,
|
|
1018
|
+
className: "p-1 text-neutral-400 hover:text-neutral-600 transition-colors",
|
|
1019
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(react.XIcon, { size: 20 })
|
|
1020
|
+
}
|
|
1021
|
+
)
|
|
1022
|
+
] }),
|
|
1023
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 overflow-y-auto max-h-[calc(90vh-120px)]", children })
|
|
1024
|
+
]
|
|
1025
|
+
}
|
|
1026
|
+
)
|
|
1027
|
+
}
|
|
1028
|
+
);
|
|
1029
|
+
};
|
|
1030
|
+
var Modal_default = Modal;
|
|
1031
|
+
var Card = React20__namespace.default.forwardRef(
|
|
1032
|
+
({
|
|
1033
|
+
className,
|
|
1034
|
+
variant = "default",
|
|
1035
|
+
padding = "md",
|
|
1036
|
+
children,
|
|
1037
|
+
...props
|
|
1038
|
+
}, ref) => {
|
|
1039
|
+
const variantClasses = {
|
|
1040
|
+
default: "bg-secondary border border-surface-1",
|
|
1041
|
+
elevated: "bg-secondary border border-surface-1 shadow-lg",
|
|
1042
|
+
outlined: "bg-transparent border border-surface-1",
|
|
1043
|
+
filled: "bg-surface-4 border border-surface-4"
|
|
1044
|
+
};
|
|
1045
|
+
const paddingClasses = {
|
|
1046
|
+
none: "",
|
|
1047
|
+
sm: "p-3",
|
|
1048
|
+
md: "p-4",
|
|
1049
|
+
lg: "p-6"
|
|
1050
|
+
};
|
|
1051
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1052
|
+
"div",
|
|
1053
|
+
{
|
|
1054
|
+
ref,
|
|
1055
|
+
className: cn(
|
|
1056
|
+
"rounded-[6px] transition-all duration-200",
|
|
1057
|
+
variantClasses[variant],
|
|
1058
|
+
paddingClasses[padding],
|
|
1059
|
+
className
|
|
1060
|
+
),
|
|
1061
|
+
...props,
|
|
1062
|
+
children
|
|
1063
|
+
}
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
);
|
|
1067
|
+
Card.displayName = "Card";
|
|
1068
|
+
var Card_default = Card;
|
|
1069
|
+
var Badge = React20__namespace.default.forwardRef(
|
|
1070
|
+
({
|
|
1071
|
+
className,
|
|
1072
|
+
variant = "default",
|
|
1073
|
+
size = "md",
|
|
1074
|
+
rounded = "md",
|
|
1075
|
+
children,
|
|
1076
|
+
...props
|
|
1077
|
+
}, ref) => {
|
|
1078
|
+
const variantClasses = {
|
|
1079
|
+
default: "bg-surface-3 text-neutral-400",
|
|
1080
|
+
primary: "bg-brand-color text-neutral-500",
|
|
1081
|
+
success: "bg-green-500 text-white",
|
|
1082
|
+
warning: "bg-yellow-500 text-white",
|
|
1083
|
+
danger: "bg-red-500 text-white",
|
|
1084
|
+
info: "bg-blue-500 text-white"
|
|
1085
|
+
};
|
|
1086
|
+
const sizeClasses = {
|
|
1087
|
+
sm: "px-2 py-0.5 text-xs",
|
|
1088
|
+
md: "px-2.5 py-1 text-sm",
|
|
1089
|
+
lg: "px-3 py-1.5 text-base"
|
|
1090
|
+
};
|
|
1091
|
+
const roundedClasses = {
|
|
1092
|
+
sm: "rounded-[6px]",
|
|
1093
|
+
md: "rounded-[6px]",
|
|
1094
|
+
lg: "rounded-[6px]",
|
|
1095
|
+
full: "rounded-full"
|
|
1096
|
+
};
|
|
1097
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1098
|
+
"span",
|
|
1099
|
+
{
|
|
1100
|
+
ref,
|
|
1101
|
+
className: cn(
|
|
1102
|
+
"inline-flex items-center font-medium",
|
|
1103
|
+
variantClasses[variant],
|
|
1104
|
+
sizeClasses[size],
|
|
1105
|
+
roundedClasses[rounded],
|
|
1106
|
+
className
|
|
1107
|
+
),
|
|
1108
|
+
...props,
|
|
1109
|
+
children
|
|
1110
|
+
}
|
|
1111
|
+
);
|
|
1112
|
+
}
|
|
1113
|
+
);
|
|
1114
|
+
Badge.displayName = "Badge";
|
|
1115
|
+
var Badge_default = Badge;
|
|
1116
|
+
var Avatar = ({
|
|
1117
|
+
src,
|
|
1118
|
+
alt = "Avatar",
|
|
1119
|
+
size = "md",
|
|
1120
|
+
fallback,
|
|
1121
|
+
className,
|
|
1122
|
+
onClick
|
|
1123
|
+
}) => {
|
|
1124
|
+
const [imgError, setImgError] = React20.useState(false);
|
|
1125
|
+
const sizeClasses = {
|
|
1126
|
+
sm: "w-8 h-8 text-xs",
|
|
1127
|
+
md: "w-10 h-10 text-sm",
|
|
1128
|
+
lg: "w-12 h-12 text-base",
|
|
1129
|
+
xl: "w-16 h-16 text-lg"
|
|
1130
|
+
};
|
|
1131
|
+
const getInitials = (name) => {
|
|
1132
|
+
return name.split(" ").map((word) => word[0]).join("").toUpperCase().slice(0, 2);
|
|
1133
|
+
};
|
|
1134
|
+
const renderFallback = () => {
|
|
1135
|
+
if (fallback) {
|
|
1136
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-full h-full bg-surface-3 text-neutral-400 font-medium", children: getInitials(fallback) });
|
|
1137
|
+
}
|
|
1138
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center w-full h-full bg-surface-3 text-neutral-400", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-1/2 h-1/2", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1139
|
+
"path",
|
|
1140
|
+
{
|
|
1141
|
+
fillRule: "evenodd",
|
|
1142
|
+
d: "M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z",
|
|
1143
|
+
clipRule: "evenodd"
|
|
1144
|
+
}
|
|
1145
|
+
) }) });
|
|
1146
|
+
};
|
|
1147
|
+
const handleImgError = React20.useCallback(() => {
|
|
1148
|
+
setImgError(true);
|
|
1149
|
+
}, []);
|
|
1150
|
+
const isSrcAvailable = typeof src === "string" && src.trim() !== "";
|
|
1151
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1152
|
+
"div",
|
|
1153
|
+
{
|
|
1154
|
+
className: cn(
|
|
1155
|
+
"relative rounded-full overflow-hidden bg-surface-3",
|
|
1156
|
+
sizeClasses[size],
|
|
1157
|
+
className
|
|
1158
|
+
),
|
|
1159
|
+
onClick,
|
|
1160
|
+
style: onClick ? { cursor: "pointer" } : void 0,
|
|
1161
|
+
children: isSrcAvailable && !imgError ? (
|
|
1162
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
1163
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1164
|
+
"img",
|
|
1165
|
+
{
|
|
1166
|
+
src,
|
|
1167
|
+
alt,
|
|
1168
|
+
className: "object-cover",
|
|
1169
|
+
sizes: size === "sm" ? "32px" : size === "md" ? "40px" : size === "lg" ? "48px" : "64px",
|
|
1170
|
+
onError: handleImgError
|
|
1171
|
+
}
|
|
1172
|
+
)
|
|
1173
|
+
) : renderFallback()
|
|
1174
|
+
}
|
|
1175
|
+
);
|
|
1176
|
+
};
|
|
1177
|
+
var Avatar_default = Avatar;
|
|
1178
|
+
var Divider = ({
|
|
1179
|
+
orientation = "horizontal",
|
|
1180
|
+
variant = "solid",
|
|
1181
|
+
size = "md",
|
|
1182
|
+
className
|
|
1183
|
+
}) => {
|
|
1184
|
+
const variantClasses = {
|
|
1185
|
+
solid: "border-solid",
|
|
1186
|
+
dashed: "border-dashed",
|
|
1187
|
+
dotted: "border-dotted"
|
|
1188
|
+
};
|
|
1189
|
+
const sizeClasses = {
|
|
1190
|
+
sm: orientation === "horizontal" ? "border-t" : "border-l",
|
|
1191
|
+
md: orientation === "horizontal" ? "border-t-2" : "border-l-2",
|
|
1192
|
+
lg: orientation === "horizontal" ? "border-t-4" : "border-l-4"
|
|
1193
|
+
};
|
|
1194
|
+
const orientationClasses = {
|
|
1195
|
+
horizontal: "w-full",
|
|
1196
|
+
vertical: "h-full"
|
|
1197
|
+
};
|
|
1198
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1199
|
+
"div",
|
|
1200
|
+
{
|
|
1201
|
+
className: cn(
|
|
1202
|
+
"border-surface-1",
|
|
1203
|
+
variantClasses[variant],
|
|
1204
|
+
sizeClasses[size],
|
|
1205
|
+
orientationClasses[orientation],
|
|
1206
|
+
className
|
|
1207
|
+
)
|
|
1208
|
+
}
|
|
1209
|
+
);
|
|
1210
|
+
};
|
|
1211
|
+
var Divider_default = Divider;
|
|
1212
|
+
var Tooltip = ({
|
|
1213
|
+
content,
|
|
1214
|
+
children,
|
|
1215
|
+
position = "top",
|
|
1216
|
+
delay = 200,
|
|
1217
|
+
className
|
|
1218
|
+
}) => {
|
|
1219
|
+
const [isVisible, setIsVisible] = React20.useState(false);
|
|
1220
|
+
const [timeoutId, setTimeoutId] = React20.useState(null);
|
|
1221
|
+
const showTooltip = () => {
|
|
1222
|
+
const id = setTimeout(() => setIsVisible(true), delay);
|
|
1223
|
+
setTimeoutId(id);
|
|
1224
|
+
};
|
|
1225
|
+
const hideTooltip = () => {
|
|
1226
|
+
if (timeoutId) {
|
|
1227
|
+
clearTimeout(timeoutId);
|
|
1228
|
+
}
|
|
1229
|
+
setIsVisible(false);
|
|
1230
|
+
};
|
|
1231
|
+
const positionClasses = {
|
|
1232
|
+
top: "bottom-full left-1/2 transform -translate-x-1/2 mb-2",
|
|
1233
|
+
bottom: "top-full left-1/2 transform -translate-x-1/2 mt-2",
|
|
1234
|
+
left: "right-full top-1/2 transform -translate-y-1/2 mr-2",
|
|
1235
|
+
right: "left-full top-1/2 transform -translate-y-1/2 ml-2"
|
|
1236
|
+
};
|
|
1237
|
+
const arrowClasses = {
|
|
1238
|
+
top: "top-full left-1/2 transform -translate-x-1/2 border-t-surface-1",
|
|
1239
|
+
bottom: "bottom-full left-1/2 transform -translate-x-1/2 border-b-surface-1",
|
|
1240
|
+
left: "left-full top-1/2 transform -translate-y-1/2 border-l-surface-1",
|
|
1241
|
+
right: "right-full top-1/2 transform -translate-y-1/2 border-r-surface-1"
|
|
1242
|
+
};
|
|
1243
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1244
|
+
"div",
|
|
1245
|
+
{
|
|
1246
|
+
className: "relative inline-block",
|
|
1247
|
+
onMouseEnter: showTooltip,
|
|
1248
|
+
onMouseLeave: hideTooltip,
|
|
1249
|
+
children: [
|
|
1250
|
+
children,
|
|
1251
|
+
isVisible && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1252
|
+
"div",
|
|
1253
|
+
{
|
|
1254
|
+
className: cn(
|
|
1255
|
+
"absolute z-50 px-2 py-1 text-xs text-white bg-surface-1 rounded shadow-lg whitespace-nowrap",
|
|
1256
|
+
positionClasses[position],
|
|
1257
|
+
className
|
|
1258
|
+
),
|
|
1259
|
+
children: [
|
|
1260
|
+
content,
|
|
1261
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1262
|
+
"div",
|
|
1263
|
+
{
|
|
1264
|
+
className: cn(
|
|
1265
|
+
"absolute w-0 h-0 border-4 border-transparent",
|
|
1266
|
+
arrowClasses[position]
|
|
1267
|
+
)
|
|
1268
|
+
}
|
|
1269
|
+
)
|
|
1270
|
+
]
|
|
1271
|
+
}
|
|
1272
|
+
)
|
|
1273
|
+
]
|
|
1274
|
+
}
|
|
1275
|
+
);
|
|
1276
|
+
};
|
|
1277
|
+
var Tooltip_default = Tooltip;
|
|
1278
|
+
var globalKeyboardShortcuts = [
|
|
1279
|
+
{ command: "focus_search", shortcut: ["ctrl", "k"] },
|
|
1280
|
+
{ command: "escape_button_action", shortcut: ["escape"] }
|
|
1281
|
+
];
|
|
1282
|
+
var keyMap = {
|
|
1283
|
+
windows: {
|
|
1284
|
+
ctrl: "Ctrl",
|
|
1285
|
+
alt: "Alt",
|
|
1286
|
+
shift: "Shift",
|
|
1287
|
+
meta: "Win",
|
|
1288
|
+
escape: "Esc",
|
|
1289
|
+
enter: "Enter",
|
|
1290
|
+
k: "K"
|
|
1291
|
+
},
|
|
1292
|
+
mac: {
|
|
1293
|
+
ctrl: "Ctrl",
|
|
1294
|
+
alt: "\u2325",
|
|
1295
|
+
shift: "\u21E7",
|
|
1296
|
+
meta: "\u2318",
|
|
1297
|
+
escape: "Esc",
|
|
1298
|
+
enter: "Enter",
|
|
1299
|
+
k: "K"
|
|
1300
|
+
},
|
|
1301
|
+
linux: {
|
|
1302
|
+
ctrl: "Ctrl",
|
|
1303
|
+
alt: "Alt",
|
|
1304
|
+
shift: "Shift",
|
|
1305
|
+
meta: "Meta",
|
|
1306
|
+
escape: "Esc",
|
|
1307
|
+
enter: "Enter",
|
|
1308
|
+
k: "K"
|
|
1309
|
+
}
|
|
1310
|
+
};
|
|
1311
|
+
var detectOS = () => {
|
|
1312
|
+
if (typeof navigator === "undefined") {
|
|
1313
|
+
return "windows";
|
|
1314
|
+
}
|
|
1315
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
1316
|
+
if (userAgent.includes("mac")) return "mac";
|
|
1317
|
+
if (userAgent.includes("win")) return "windows";
|
|
1318
|
+
return "linux";
|
|
1319
|
+
};
|
|
1320
|
+
var matchShortcut = (event, shortcut, os) => {
|
|
1321
|
+
const normalizedShortcut = shortcut.map((key) => key.toLowerCase());
|
|
1322
|
+
const hasModifier = normalizedShortcut.includes("ctrl") ? event.ctrlKey : normalizedShortcut.includes("meta") ? event.metaKey : normalizedShortcut.includes("alt") ? event.altKey : true;
|
|
1323
|
+
if (!hasModifier) return false;
|
|
1324
|
+
const primaryKey = normalizedShortcut.find((key) => !["ctrl", "meta", "alt", "shift"].includes(key));
|
|
1325
|
+
if (!primaryKey) return normalizedShortcut.every((key) => {
|
|
1326
|
+
if (key === "ctrl") return event.ctrlKey;
|
|
1327
|
+
if (key === "meta") return event.metaKey;
|
|
1328
|
+
if (key === "alt") return event.altKey;
|
|
1329
|
+
if (key === "shift") return event.shiftKey;
|
|
1330
|
+
return false;
|
|
1331
|
+
});
|
|
1332
|
+
const matchesPrimaryKey = event.key.toLowerCase() === primaryKey;
|
|
1333
|
+
const shiftRequired = normalizedShortcut.includes("shift");
|
|
1334
|
+
const shiftMatches = shiftRequired ? event.shiftKey : true;
|
|
1335
|
+
return matchesPrimaryKey && shiftMatches;
|
|
1336
|
+
};
|
|
1337
|
+
var useShortcutFormatter = () => {
|
|
1338
|
+
const [os, setOS] = React20.useState("windows");
|
|
1339
|
+
const listenersRef = React20.useRef(/* @__PURE__ */ new Map());
|
|
1340
|
+
React20.useEffect(() => {
|
|
1341
|
+
setOS(detectOS());
|
|
1342
|
+
}, []);
|
|
1343
|
+
React20.useEffect(() => {
|
|
1344
|
+
const handleKeyDown = (event) => {
|
|
1345
|
+
for (const shortcut of globalKeyboardShortcuts) {
|
|
1346
|
+
if (matchShortcut(event, shortcut.shortcut)) {
|
|
1347
|
+
const listeners = listenersRef.current.get(shortcut.command);
|
|
1348
|
+
if (listeners) {
|
|
1349
|
+
event.preventDefault();
|
|
1350
|
+
listeners.forEach((cb) => cb(event));
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
1356
|
+
return () => {
|
|
1357
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
1358
|
+
};
|
|
1359
|
+
}, [os]);
|
|
1360
|
+
const formatKeys = (keys = []) => {
|
|
1361
|
+
return keys.map((key) => keyMap[os][key.toLowerCase()] || key.toUpperCase()).join(" + ");
|
|
1362
|
+
};
|
|
1363
|
+
const getShortcutByCommand = (command) => {
|
|
1364
|
+
const found = globalKeyboardShortcuts.find((shortcut) => shortcut.command === command);
|
|
1365
|
+
return found ? found.shortcut : [""];
|
|
1366
|
+
};
|
|
1367
|
+
const addShortcutListener = (command, listener) => {
|
|
1368
|
+
if (!listenersRef.current.has(command)) {
|
|
1369
|
+
listenersRef.current.set(command, /* @__PURE__ */ new Set());
|
|
1370
|
+
}
|
|
1371
|
+
listenersRef.current.get(command).add(listener);
|
|
1372
|
+
};
|
|
1373
|
+
const removeShortcutListener = (command, listener) => {
|
|
1374
|
+
if (listenersRef.current.has(command)) {
|
|
1375
|
+
listenersRef.current.get(command).delete(listener);
|
|
1376
|
+
}
|
|
1377
|
+
};
|
|
1378
|
+
return {
|
|
1379
|
+
formatKeys,
|
|
1380
|
+
getShortcutByCommand,
|
|
1381
|
+
addShortcutListener,
|
|
1382
|
+
removeShortcutListener
|
|
1383
|
+
};
|
|
1384
|
+
};
|
|
1385
|
+
var useShortcutFormatter_default = useShortcutFormatter;
|
|
1386
|
+
var SearchInput = React20__namespace.default.forwardRef(
|
|
1387
|
+
({
|
|
1388
|
+
onSearch,
|
|
1389
|
+
placeholder = "Search...",
|
|
1390
|
+
variant = "default",
|
|
1391
|
+
size = "md",
|
|
1392
|
+
showClearButton = true,
|
|
1393
|
+
className,
|
|
1394
|
+
value,
|
|
1395
|
+
onChange,
|
|
1396
|
+
enableKeyboardShortcuts = false,
|
|
1397
|
+
isActive = true,
|
|
1398
|
+
...props
|
|
1399
|
+
}, ref) => {
|
|
1400
|
+
const [searchValue, setSearchValue] = React20__namespace.default.useState(value || "");
|
|
1401
|
+
const inputRef = React20.useRef(null);
|
|
1402
|
+
React20.useImperativeHandle(ref, () => inputRef.current);
|
|
1403
|
+
const { addShortcutListener, removeShortcutListener, formatKeys, getShortcutByCommand } = useShortcutFormatter_default();
|
|
1404
|
+
const handleChange = (e) => {
|
|
1405
|
+
const newValue = e.target.value;
|
|
1406
|
+
setSearchValue(newValue);
|
|
1407
|
+
onChange?.(e);
|
|
1408
|
+
onSearch?.(newValue);
|
|
1409
|
+
};
|
|
1410
|
+
const handleClear = React20.useCallback(() => {
|
|
1411
|
+
setSearchValue("");
|
|
1412
|
+
onSearch?.("");
|
|
1413
|
+
const syntheticEvent = {
|
|
1414
|
+
target: { value: "" }
|
|
1415
|
+
};
|
|
1416
|
+
onChange?.(syntheticEvent);
|
|
1417
|
+
}, [onChange, onSearch]);
|
|
1418
|
+
React20.useEffect(() => {
|
|
1419
|
+
if (!enableKeyboardShortcuts || !isActive) return;
|
|
1420
|
+
const handleFocusSearch = (e) => {
|
|
1421
|
+
e?.preventDefault();
|
|
1422
|
+
inputRef.current?.focus();
|
|
1423
|
+
};
|
|
1424
|
+
const handleClearShortcut = (e) => {
|
|
1425
|
+
e?.preventDefault();
|
|
1426
|
+
handleClear();
|
|
1427
|
+
inputRef.current?.blur();
|
|
1428
|
+
};
|
|
1429
|
+
addShortcutListener("focus_search", handleFocusSearch);
|
|
1430
|
+
addShortcutListener("escape_button_action", handleClearShortcut);
|
|
1431
|
+
return () => {
|
|
1432
|
+
removeShortcutListener("focus_search", handleFocusSearch);
|
|
1433
|
+
removeShortcutListener("escape_button_action", handleClearShortcut);
|
|
1434
|
+
};
|
|
1435
|
+
}, [enableKeyboardShortcuts, isActive, handleClear, addShortcutListener, removeShortcutListener]);
|
|
1436
|
+
const displayPlaceholder = enableKeyboardShortcuts ? `${placeholder} (${formatKeys(getShortcutByCommand("focus_search"))})` : placeholder;
|
|
1437
|
+
const baseClasses = "transition-all duration-200 focus:outline-none placeholder:text-neutral-300 rounded-[6px]";
|
|
1438
|
+
const variantClasses = {
|
|
1439
|
+
default: "bg-primary border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
1440
|
+
filled: "bg-surface-4 border border-surface-4 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
1441
|
+
outline: "bg-transparent border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50"
|
|
1442
|
+
};
|
|
1443
|
+
const sizeClasses = {
|
|
1444
|
+
sm: "h-8 px-2 pl-8 text-sm",
|
|
1445
|
+
md: "h-10 px-3 pl-10 text-base",
|
|
1446
|
+
lg: "h-12 px-4 pl-12 text-lg"
|
|
1447
|
+
};
|
|
1448
|
+
const iconSizeClasses = {
|
|
1449
|
+
sm: "w-4 h-4",
|
|
1450
|
+
md: "w-5 h-5",
|
|
1451
|
+
lg: "w-6 h-6"
|
|
1452
|
+
};
|
|
1453
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1454
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-neutral-400", children: /* @__PURE__ */ jsxRuntime.jsx(react.MagnifyingGlassIcon, { className: iconSizeClasses[size] }) }),
|
|
1455
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1456
|
+
"input",
|
|
1457
|
+
{
|
|
1458
|
+
ref: inputRef,
|
|
1459
|
+
type: "text",
|
|
1460
|
+
placeholder: displayPlaceholder,
|
|
1461
|
+
value: searchValue,
|
|
1462
|
+
onChange: handleChange,
|
|
1463
|
+
className: cn(
|
|
1464
|
+
baseClasses,
|
|
1465
|
+
variantClasses[variant],
|
|
1466
|
+
sizeClasses[size],
|
|
1467
|
+
showClearButton && searchValue ? "pr-10" : "",
|
|
1468
|
+
className
|
|
1469
|
+
),
|
|
1470
|
+
...props
|
|
1471
|
+
}
|
|
1472
|
+
),
|
|
1473
|
+
showClearButton && searchValue && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1474
|
+
"button",
|
|
1475
|
+
{
|
|
1476
|
+
onClick: handleClear,
|
|
1477
|
+
className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-neutral-400 hover:text-neutral-600 transition-colors",
|
|
1478
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: iconSizeClasses[size], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
1479
|
+
}
|
|
1480
|
+
)
|
|
1481
|
+
] });
|
|
1482
|
+
}
|
|
1483
|
+
);
|
|
1484
|
+
SearchInput.displayName = "SearchInput";
|
|
1485
|
+
var SearchInput_default = SearchInput;
|
|
1486
|
+
var FileUpload = ({
|
|
1487
|
+
onFileSelect,
|
|
1488
|
+
accept,
|
|
1489
|
+
multiple = false,
|
|
1490
|
+
maxSize,
|
|
1491
|
+
variant = "default",
|
|
1492
|
+
size = "md",
|
|
1493
|
+
disabled = false,
|
|
1494
|
+
className,
|
|
1495
|
+
children,
|
|
1496
|
+
dragAndDrop = false
|
|
1497
|
+
}) => {
|
|
1498
|
+
const fileInputRef = React20.useRef(null);
|
|
1499
|
+
const [isDragOver, setIsDragOver] = React20__namespace.default.useState(false);
|
|
1500
|
+
const handleFileSelect = (files) => {
|
|
1501
|
+
if (!files) return;
|
|
1502
|
+
const fileArray = Array.from(files);
|
|
1503
|
+
if (maxSize) {
|
|
1504
|
+
const validFiles = fileArray.filter((file) => file.size <= maxSize);
|
|
1505
|
+
if (validFiles.length !== fileArray.length) {
|
|
1506
|
+
console.warn("Some files were too large and were skipped");
|
|
1507
|
+
}
|
|
1508
|
+
onFileSelect?.(validFiles);
|
|
1509
|
+
} else {
|
|
1510
|
+
onFileSelect?.(fileArray);
|
|
1511
|
+
}
|
|
1512
|
+
};
|
|
1513
|
+
const handleInputChange = (e) => {
|
|
1514
|
+
handleFileSelect(e.target.files);
|
|
1515
|
+
};
|
|
1516
|
+
const handleClick = () => {
|
|
1517
|
+
if (!disabled) {
|
|
1518
|
+
fileInputRef.current?.click();
|
|
1519
|
+
}
|
|
1520
|
+
};
|
|
1521
|
+
const handleDragOver = (e) => {
|
|
1522
|
+
e.preventDefault();
|
|
1523
|
+
if (dragAndDrop && !disabled) {
|
|
1524
|
+
setIsDragOver(true);
|
|
1525
|
+
}
|
|
1526
|
+
};
|
|
1527
|
+
const handleDragLeave = (e) => {
|
|
1528
|
+
e.preventDefault();
|
|
1529
|
+
setIsDragOver(false);
|
|
1530
|
+
};
|
|
1531
|
+
const handleDrop = (e) => {
|
|
1532
|
+
e.preventDefault();
|
|
1533
|
+
setIsDragOver(false);
|
|
1534
|
+
if (dragAndDrop && !disabled) {
|
|
1535
|
+
handleFileSelect(e.dataTransfer.files);
|
|
1536
|
+
}
|
|
1537
|
+
};
|
|
1538
|
+
const baseClasses = "transition-all duration-200 focus:outline-none cursor-pointer rounded-[6px]";
|
|
1539
|
+
const variantClasses = {
|
|
1540
|
+
default: "bg-primary border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
1541
|
+
filled: "bg-surface-4 border border-surface-4 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50",
|
|
1542
|
+
outline: "bg-transparent border border-surface-1 focus:border-brand-color focus:ring-1 focus:ring-brand-color/50"
|
|
1543
|
+
};
|
|
1544
|
+
const sizeClasses = {
|
|
1545
|
+
sm: "h-20 px-3 text-sm",
|
|
1546
|
+
md: "h-24 px-4 text-base",
|
|
1547
|
+
lg: "h-32 px-6 text-lg"
|
|
1548
|
+
};
|
|
1549
|
+
const defaultContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center", children: [
|
|
1550
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.UploadIcon, { size: 24, className: "text-neutral-400 mb-2" }),
|
|
1551
|
+
/* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-sm text-neutral-400", children: dragAndDrop ? "Drag and drop files here" : "Click to upload files" }),
|
|
1552
|
+
accept && /* @__PURE__ */ jsxRuntime.jsxs(Typography_default, { variant: "p", className: "text-xs text-neutral-300 mt-1", children: [
|
|
1553
|
+
"Accepted: ",
|
|
1554
|
+
accept
|
|
1555
|
+
] })
|
|
1556
|
+
] });
|
|
1557
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1558
|
+
"div",
|
|
1559
|
+
{
|
|
1560
|
+
onClick: handleClick,
|
|
1561
|
+
onDragOver: handleDragOver,
|
|
1562
|
+
onDragLeave: handleDragLeave,
|
|
1563
|
+
onDrop: handleDrop,
|
|
1564
|
+
className: cn(
|
|
1565
|
+
baseClasses,
|
|
1566
|
+
variantClasses[variant],
|
|
1567
|
+
sizeClasses[size],
|
|
1568
|
+
"w-full rounded-[6px] border-2 border-dashed flex items-center justify-center",
|
|
1569
|
+
isDragOver && "border-brand-color bg-brand-color/10",
|
|
1570
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
1571
|
+
className
|
|
1572
|
+
),
|
|
1573
|
+
children: [
|
|
1574
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1575
|
+
"input",
|
|
1576
|
+
{
|
|
1577
|
+
ref: fileInputRef,
|
|
1578
|
+
type: "file",
|
|
1579
|
+
accept,
|
|
1580
|
+
multiple,
|
|
1581
|
+
onChange: handleInputChange,
|
|
1582
|
+
className: "hidden",
|
|
1583
|
+
disabled
|
|
1584
|
+
}
|
|
1585
|
+
),
|
|
1586
|
+
children || defaultContent
|
|
1587
|
+
]
|
|
1588
|
+
}
|
|
1589
|
+
);
|
|
1590
|
+
};
|
|
1591
|
+
var FileUpload_default = FileUpload;
|
|
1592
|
+
var Progress = ({
|
|
1593
|
+
value,
|
|
1594
|
+
max = 100,
|
|
1595
|
+
variant = "default",
|
|
1596
|
+
size = "md",
|
|
1597
|
+
showLabel = false,
|
|
1598
|
+
animated = false,
|
|
1599
|
+
className
|
|
1600
|
+
}) => {
|
|
1601
|
+
const percentage = Math.min(Math.max(value / max * 100, 0), 100);
|
|
1602
|
+
const variantClasses = {
|
|
1603
|
+
default: "bg-brand-color",
|
|
1604
|
+
success: "bg-green-500",
|
|
1605
|
+
warning: "bg-yellow-500",
|
|
1606
|
+
danger: "bg-red-500"
|
|
1607
|
+
};
|
|
1608
|
+
const sizeClasses = {
|
|
1609
|
+
sm: "h-1",
|
|
1610
|
+
md: "h-2",
|
|
1611
|
+
lg: "h-3"
|
|
1612
|
+
};
|
|
1613
|
+
const labelSizeClasses = {
|
|
1614
|
+
sm: "text-xs",
|
|
1615
|
+
md: "text-sm",
|
|
1616
|
+
lg: "text-base"
|
|
1617
|
+
};
|
|
1618
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("w-full", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1619
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1620
|
+
"div",
|
|
1621
|
+
{
|
|
1622
|
+
className: cn(
|
|
1623
|
+
"w-full bg-surface-3 rounded-[6px] overflow-hidden",
|
|
1624
|
+
sizeClasses[size]
|
|
1625
|
+
),
|
|
1626
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1627
|
+
"div",
|
|
1628
|
+
{
|
|
1629
|
+
className: cn(
|
|
1630
|
+
"h-full rounded-[6px] transition-all duration-300",
|
|
1631
|
+
variantClasses[variant],
|
|
1632
|
+
animated && "animate-pulse"
|
|
1633
|
+
),
|
|
1634
|
+
style: { width: `${percentage}%` }
|
|
1635
|
+
}
|
|
1636
|
+
)
|
|
1637
|
+
}
|
|
1638
|
+
) }),
|
|
1639
|
+
showLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-neutral-400 font-medium", labelSizeClasses[size]), children: [
|
|
1640
|
+
Math.round(percentage),
|
|
1641
|
+
"%"
|
|
1642
|
+
] })
|
|
1643
|
+
] }) });
|
|
1644
|
+
};
|
|
1645
|
+
var Progress_default = Progress;
|
|
1646
|
+
var Pagination = ({
|
|
1647
|
+
currentPage,
|
|
1648
|
+
totalPages,
|
|
1649
|
+
onPageChange,
|
|
1650
|
+
showFirstLast = true,
|
|
1651
|
+
showPrevNext = true,
|
|
1652
|
+
maxVisiblePages = 5,
|
|
1653
|
+
size = "md",
|
|
1654
|
+
variant = "default",
|
|
1655
|
+
className
|
|
1656
|
+
}) => {
|
|
1657
|
+
const getVisiblePages = () => {
|
|
1658
|
+
const pages = [];
|
|
1659
|
+
const halfVisible = Math.floor(maxVisiblePages / 2);
|
|
1660
|
+
if (totalPages <= maxVisiblePages) {
|
|
1661
|
+
for (let i = 1; i <= totalPages; i++) {
|
|
1662
|
+
pages.push(i);
|
|
1663
|
+
}
|
|
1664
|
+
} else {
|
|
1665
|
+
let start = Math.max(1, currentPage - halfVisible);
|
|
1666
|
+
const end = Math.min(totalPages, start + maxVisiblePages - 1);
|
|
1667
|
+
if (end - start + 1 < maxVisiblePages) {
|
|
1668
|
+
start = Math.max(1, end - maxVisiblePages + 1);
|
|
1669
|
+
}
|
|
1670
|
+
if (start > 1) {
|
|
1671
|
+
pages.push(1);
|
|
1672
|
+
if (start > 2) {
|
|
1673
|
+
pages.push("...");
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
for (let i = start; i <= end; i++) {
|
|
1677
|
+
pages.push(i);
|
|
1678
|
+
}
|
|
1679
|
+
if (end < totalPages) {
|
|
1680
|
+
if (end < totalPages - 1) {
|
|
1681
|
+
pages.push("...");
|
|
1682
|
+
}
|
|
1683
|
+
pages.push(totalPages);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
return pages;
|
|
1687
|
+
};
|
|
1688
|
+
const handlePageClick = (page) => {
|
|
1689
|
+
if (typeof page === "number") {
|
|
1690
|
+
onPageChange(page);
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
const sizeClasses = {
|
|
1694
|
+
sm: "h-8 px-2 text-sm",
|
|
1695
|
+
md: "h-10 px-3 text-base",
|
|
1696
|
+
lg: "h-12 px-4 text-lg"
|
|
1697
|
+
};
|
|
1698
|
+
const variantClasses = {
|
|
1699
|
+
default: "bg-primary border border-surface-1 hover:bg-surface-3",
|
|
1700
|
+
outline: "bg-transparent border border-surface-1 hover:bg-surface-3"
|
|
1701
|
+
};
|
|
1702
|
+
const activeClasses = {
|
|
1703
|
+
default: "bg-brand-color text-neutral-500 border-brand-color",
|
|
1704
|
+
outline: "bg-brand-color text-neutral-500 border-brand-color"
|
|
1705
|
+
};
|
|
1706
|
+
const renderPageButton = (page, index) => {
|
|
1707
|
+
if (page === "...") {
|
|
1708
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1709
|
+
"span",
|
|
1710
|
+
{
|
|
1711
|
+
className: cn(
|
|
1712
|
+
"flex items-center justify-center",
|
|
1713
|
+
sizeClasses[size],
|
|
1714
|
+
"text-neutral-400"
|
|
1715
|
+
),
|
|
1716
|
+
children: "..."
|
|
1717
|
+
},
|
|
1718
|
+
`ellipsis-${index}`
|
|
1719
|
+
);
|
|
1720
|
+
}
|
|
1721
|
+
const isActive = page === currentPage;
|
|
1722
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1723
|
+
"button",
|
|
1724
|
+
{
|
|
1725
|
+
onClick: () => handlePageClick(page),
|
|
1726
|
+
className: cn(
|
|
1727
|
+
"flex items-center justify-center font-medium transition-all duration-200 rounded-[6px]",
|
|
1728
|
+
sizeClasses[size],
|
|
1729
|
+
variantClasses[variant],
|
|
1730
|
+
isActive ? activeClasses[variant] : "text-neutral-400",
|
|
1731
|
+
!isActive && "hover:text-neutral-500"
|
|
1732
|
+
),
|
|
1733
|
+
children: page
|
|
1734
|
+
},
|
|
1735
|
+
page
|
|
1736
|
+
);
|
|
1737
|
+
};
|
|
1738
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center justify-center gap-1", className), children: [
|
|
1739
|
+
showFirstLast && currentPage > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1740
|
+
"button",
|
|
1741
|
+
{
|
|
1742
|
+
onClick: () => onPageChange(1),
|
|
1743
|
+
className: cn(
|
|
1744
|
+
"flex items-center justify-center font-medium transition-all duration-200 rounded-[6px]",
|
|
1745
|
+
sizeClasses[size],
|
|
1746
|
+
variantClasses[variant],
|
|
1747
|
+
"text-neutral-400 hover:text-neutral-500"
|
|
1748
|
+
),
|
|
1749
|
+
children: "First"
|
|
1750
|
+
}
|
|
1751
|
+
),
|
|
1752
|
+
showPrevNext && currentPage > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1753
|
+
"button",
|
|
1754
|
+
{
|
|
1755
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
1756
|
+
className: cn(
|
|
1757
|
+
"flex items-center justify-center font-medium transition-all duration-200 rounded-[6px]",
|
|
1758
|
+
sizeClasses[size],
|
|
1759
|
+
variantClasses[variant],
|
|
1760
|
+
"text-neutral-400 hover:text-neutral-500"
|
|
1761
|
+
),
|
|
1762
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(react.CaretLeftIcon, { size: 16 })
|
|
1763
|
+
}
|
|
1764
|
+
),
|
|
1765
|
+
getVisiblePages().map((page, index) => renderPageButton(page, index)),
|
|
1766
|
+
showPrevNext && currentPage < totalPages && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1767
|
+
"button",
|
|
1768
|
+
{
|
|
1769
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
1770
|
+
className: cn(
|
|
1771
|
+
"flex items-center justify-center font-medium transition-all duration-200 rounded-[6px]",
|
|
1772
|
+
sizeClasses[size],
|
|
1773
|
+
variantClasses[variant],
|
|
1774
|
+
"text-neutral-400 hover:text-neutral-500"
|
|
1775
|
+
),
|
|
1776
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(react.CaretRightIcon, { size: 16 })
|
|
1777
|
+
}
|
|
1778
|
+
),
|
|
1779
|
+
showFirstLast && currentPage < totalPages && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1780
|
+
"button",
|
|
1781
|
+
{
|
|
1782
|
+
onClick: () => onPageChange(totalPages),
|
|
1783
|
+
className: cn(
|
|
1784
|
+
"flex items-center justify-center font-medium transition-all duration-200 rounded-[6px]",
|
|
1785
|
+
sizeClasses[size],
|
|
1786
|
+
variantClasses[variant],
|
|
1787
|
+
"text-neutral-400 hover:text-neutral-500"
|
|
1788
|
+
),
|
|
1789
|
+
children: "Last"
|
|
1790
|
+
}
|
|
1791
|
+
)
|
|
1792
|
+
] });
|
|
1793
|
+
};
|
|
1794
|
+
var Pagination_default = Pagination;
|
|
1795
|
+
var Radio = React20__namespace.default.forwardRef(
|
|
1796
|
+
({
|
|
1797
|
+
className,
|
|
1798
|
+
label,
|
|
1799
|
+
size = "md",
|
|
1800
|
+
variant = "default",
|
|
1801
|
+
error,
|
|
1802
|
+
helperText,
|
|
1803
|
+
...props
|
|
1804
|
+
}, ref) => {
|
|
1805
|
+
const baseClasses = "transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 cursor-pointer rounded-[6px]";
|
|
1806
|
+
const variantClasses = {
|
|
1807
|
+
default: "bg-primary border border-surface-1 focus:border-brand-color focus:ring-brand-color/50 checked:bg-brand-color checked:border-brand-color",
|
|
1808
|
+
filled: "bg-surface-4 border border-surface-4 focus:border-brand-color focus:ring-brand-color/50 checked:bg-brand-color checked:border-brand-color"
|
|
1809
|
+
};
|
|
1810
|
+
const sizeClasses = {
|
|
1811
|
+
sm: "w-4 h-4",
|
|
1812
|
+
md: "w-5 h-5",
|
|
1813
|
+
lg: "w-6 h-6"
|
|
1814
|
+
};
|
|
1815
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
1816
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
1817
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
1818
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1819
|
+
"input",
|
|
1820
|
+
{
|
|
1821
|
+
ref,
|
|
1822
|
+
type: "radio",
|
|
1823
|
+
className: cn(
|
|
1824
|
+
baseClasses,
|
|
1825
|
+
variantClasses[variant],
|
|
1826
|
+
sizeClasses[size],
|
|
1827
|
+
"appearance-none",
|
|
1828
|
+
error && "border-red-500 focus:border-red-500 focus:ring-red-500/50",
|
|
1829
|
+
className
|
|
1830
|
+
),
|
|
1831
|
+
...props
|
|
1832
|
+
}
|
|
1833
|
+
),
|
|
1834
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1/2 h-1/2 bg-white rounded-full opacity-0 checked:opacity-100" }) })
|
|
1835
|
+
] }),
|
|
1836
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm text-neutral-400 cursor-pointer select-none", children: label })
|
|
1837
|
+
] }),
|
|
1838
|
+
(error || helperText) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 ml-6", children: [
|
|
1839
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-red-500", children: error }),
|
|
1840
|
+
helperText && !error && /* @__PURE__ */ jsxRuntime.jsx(Typography_default, { variant: "p", className: "text-xs text-neutral-400", children: helperText })
|
|
1841
|
+
] })
|
|
1842
|
+
] });
|
|
1843
|
+
}
|
|
1844
|
+
);
|
|
1845
|
+
Radio.displayName = "Radio";
|
|
1846
|
+
var Radio_default = Radio;
|
|
1847
|
+
var Accordion = ({ items, active = -1 }) => {
|
|
1848
|
+
const [activeIndex, setActiveIndex] = React20.useState(active);
|
|
1849
|
+
const toggleAccordion = (index) => {
|
|
1850
|
+
setActiveIndex(activeIndex === index ? null : index);
|
|
1851
|
+
};
|
|
1852
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full space-y-[12px]", children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1853
|
+
"div",
|
|
1854
|
+
{
|
|
1855
|
+
className: "border border-surface-1 mx-[10px] rounded-[6px]",
|
|
1856
|
+
children: [
|
|
1857
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1858
|
+
"button",
|
|
1859
|
+
{
|
|
1860
|
+
onClick: () => toggleAccordion(index),
|
|
1861
|
+
className: "w-full text-left px-[12px] py-[10px] bg-surface-4 flex justify-between items-center focus:outline-none",
|
|
1862
|
+
children: [
|
|
1863
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-neutral-400 text-[13px]", children: item.title }),
|
|
1864
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-row gap-[16px]", children: activeIndex === index ? /* @__PURE__ */ jsxRuntime.jsx(react.CaretUpIcon, { size: 18 }) : /* @__PURE__ */ jsxRuntime.jsx(react.CaretDownIcon, { size: 18 }) })
|
|
1865
|
+
]
|
|
1866
|
+
}
|
|
1867
|
+
),
|
|
1868
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1869
|
+
"div",
|
|
1870
|
+
{
|
|
1871
|
+
className: `overflow-hidden transition-all duration-300 ${activeIndex === index ? "px-[12px] py-[12px]" : "max-h-0"}`,
|
|
1872
|
+
children: item.content
|
|
1873
|
+
}
|
|
1874
|
+
)
|
|
1875
|
+
]
|
|
1876
|
+
},
|
|
1877
|
+
index
|
|
1878
|
+
)) });
|
|
1879
|
+
};
|
|
1880
|
+
var Accordion_default = Accordion;
|
|
1881
|
+
var Tabs = ({
|
|
1882
|
+
tabs,
|
|
1883
|
+
defaultActiveTab = 0,
|
|
1884
|
+
onTabChange,
|
|
1885
|
+
containerClassName = "flex w-full border border-border-1 rounded-[6px] mt-[16px]",
|
|
1886
|
+
buttonClassName = "flex items-center gap-1 px-[8px] py-[2px] text-[13px] cursor-pointer transition-all duration-300 text-neutral-300 rounded-[6px] m-[8px]",
|
|
1887
|
+
activeButtonClassName = "bg-surface-3 text-neutral-400"
|
|
1888
|
+
}) => {
|
|
1889
|
+
const [activeTab, setActiveTab] = React20.useState(defaultActiveTab);
|
|
1890
|
+
React20.useEffect(() => {
|
|
1891
|
+
setActiveTab(defaultActiveTab);
|
|
1892
|
+
}, [defaultActiveTab]);
|
|
1893
|
+
const handleTabClick = (index) => {
|
|
1894
|
+
setActiveTab(index);
|
|
1895
|
+
if (onTabChange) {
|
|
1896
|
+
onTabChange(index);
|
|
1897
|
+
}
|
|
1898
|
+
};
|
|
1899
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", children: [
|
|
1900
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: containerClassName, children: tabs.map((tab, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1901
|
+
"div",
|
|
1902
|
+
{
|
|
1903
|
+
className: `${buttonClassName} ${activeTab === index ? activeButtonClassName : ""}`,
|
|
1904
|
+
onClick: () => handleTabClick(index),
|
|
1905
|
+
children: [
|
|
1906
|
+
tab.icon,
|
|
1907
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: tab.label })
|
|
1908
|
+
]
|
|
1909
|
+
},
|
|
1910
|
+
index
|
|
1911
|
+
)) }),
|
|
1912
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full mt-4 flex flex-col gap-4", children: tabs[activeTab].content })
|
|
1913
|
+
] });
|
|
1914
|
+
};
|
|
1915
|
+
var Tabs_default = Tabs;
|
|
1916
|
+
var Table = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative w-full overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1917
|
+
"table",
|
|
1918
|
+
{
|
|
1919
|
+
ref,
|
|
1920
|
+
className: cn("w-full caption-bottom text-[13px]", className),
|
|
1921
|
+
...props
|
|
1922
|
+
}
|
|
1923
|
+
) }));
|
|
1924
|
+
Table.displayName = "Table";
|
|
1925
|
+
var TableHeader = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("thead", { ref, className: cn("[&_tr]:border-b text-neutral-400 bg-surface-2", className), ...props }));
|
|
1926
|
+
TableHeader.displayName = "TableHeader";
|
|
1927
|
+
var TableBody = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1928
|
+
"tbody",
|
|
1929
|
+
{
|
|
1930
|
+
ref,
|
|
1931
|
+
className: cn("[&_tr:last-child]:border-0 text-neutral-300", className),
|
|
1932
|
+
...props
|
|
1933
|
+
}
|
|
1934
|
+
));
|
|
1935
|
+
TableBody.displayName = "TableBody";
|
|
1936
|
+
var TableFooter = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1937
|
+
"tfoot",
|
|
1938
|
+
{
|
|
1939
|
+
ref,
|
|
1940
|
+
className: cn(
|
|
1941
|
+
"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
|
|
1942
|
+
className
|
|
1943
|
+
),
|
|
1944
|
+
...props
|
|
1945
|
+
}
|
|
1946
|
+
));
|
|
1947
|
+
TableFooter.displayName = "TableFooter";
|
|
1948
|
+
var TableRow = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1949
|
+
"tr",
|
|
1950
|
+
{
|
|
1951
|
+
ref,
|
|
1952
|
+
className: cn(
|
|
1953
|
+
"border-t border-surface-1 group hover:bg-surface-4 hover:text-neutral-500 cursor-pointer",
|
|
1954
|
+
className
|
|
1955
|
+
),
|
|
1956
|
+
...props
|
|
1957
|
+
}
|
|
1958
|
+
));
|
|
1959
|
+
TableRow.displayName = "TableRow";
|
|
1960
|
+
var TableHead = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1961
|
+
"th",
|
|
1962
|
+
{
|
|
1963
|
+
ref,
|
|
1964
|
+
className: cn(
|
|
1965
|
+
"py-[4px] px-[8px] font-medium",
|
|
1966
|
+
className
|
|
1967
|
+
),
|
|
1968
|
+
...props
|
|
1969
|
+
}
|
|
1970
|
+
));
|
|
1971
|
+
TableHead.displayName = "TableHead";
|
|
1972
|
+
var TableCell = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1973
|
+
"td",
|
|
1974
|
+
{
|
|
1975
|
+
ref,
|
|
1976
|
+
className: cn("py-[6px] px-[8px]", className),
|
|
1977
|
+
...props
|
|
1978
|
+
}
|
|
1979
|
+
));
|
|
1980
|
+
TableCell.displayName = "TableCell";
|
|
1981
|
+
var TableCaption = React20__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1982
|
+
"caption",
|
|
1983
|
+
{
|
|
1984
|
+
ref,
|
|
1985
|
+
className: cn("mt-4 text-sm text-muted-foreground", className),
|
|
1986
|
+
...props
|
|
1987
|
+
}
|
|
1988
|
+
));
|
|
1989
|
+
TableCaption.displayName = "TableCaption";
|
|
1990
|
+
|
|
1991
|
+
exports.Accordion = Accordion_default;
|
|
1992
|
+
exports.Alert = Alert_default;
|
|
1993
|
+
exports.Avatar = Avatar_default;
|
|
1994
|
+
exports.Badge = Badge_default;
|
|
1995
|
+
exports.Button = Button_default;
|
|
1996
|
+
exports.Card = Card_default;
|
|
1997
|
+
exports.Checkbox = Checkbox_default;
|
|
1998
|
+
exports.Divider = Divider_default;
|
|
1999
|
+
exports.Dropdown = Dropdown_default;
|
|
2000
|
+
exports.FileUpload = FileUpload_default;
|
|
2001
|
+
exports.ImageWithPlaceholder = ImageWithPlaceholder_default;
|
|
2002
|
+
exports.Input = Input_default;
|
|
2003
|
+
exports.Loading = Loading_default;
|
|
2004
|
+
exports.Modal = Modal_default;
|
|
2005
|
+
exports.Pagination = Pagination_default;
|
|
2006
|
+
exports.Progress = Progress_default;
|
|
2007
|
+
exports.Radio = Radio_default;
|
|
2008
|
+
exports.SearchInput = SearchInput_default;
|
|
2009
|
+
exports.Select = Select_default;
|
|
2010
|
+
exports.Table = Table;
|
|
2011
|
+
exports.TableBody = TableBody;
|
|
2012
|
+
exports.TableCaption = TableCaption;
|
|
2013
|
+
exports.TableCell = TableCell;
|
|
2014
|
+
exports.TableFooter = TableFooter;
|
|
2015
|
+
exports.TableHead = TableHead;
|
|
2016
|
+
exports.TableHeader = TableHeader;
|
|
2017
|
+
exports.TableRow = TableRow;
|
|
2018
|
+
exports.Tabs = Tabs_default;
|
|
2019
|
+
exports.TextArea = TextArea_default;
|
|
2020
|
+
exports.Toast = Toast_default;
|
|
2021
|
+
exports.Toggle = Toggle_default;
|
|
2022
|
+
exports.Tooltip = Tooltip_default;
|
|
2023
|
+
exports.Typography = Typography_default;
|
|
2024
|
+
exports.cn = cn;
|
|
2025
|
+
exports.useShortcutFormatter = useShortcutFormatter_default;
|
|
2026
|
+
//# sourceMappingURL=index.cjs.map
|
|
2027
|
+
//# sourceMappingURL=index.cjs.map
|