@yomologic/react-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -0
- package/dist/index.d.mts +208 -0
- package/dist/index.d.ts +208 -0
- package/dist/index.js +1104 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1047 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +64 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
Alert: () => Alert,
|
|
34
|
+
Badge: () => Badge,
|
|
35
|
+
Button: () => Button,
|
|
36
|
+
Card: () => Card,
|
|
37
|
+
CardContent: () => CardContent,
|
|
38
|
+
CardDescription: () => CardDescription,
|
|
39
|
+
CardFooter: () => CardFooter,
|
|
40
|
+
CardHeader: () => CardHeader,
|
|
41
|
+
CardTitle: () => CardTitle,
|
|
42
|
+
Checkbox: () => Checkbox,
|
|
43
|
+
CheckboxGroup: () => CheckboxGroup,
|
|
44
|
+
CodeSnippet: () => CodeSnippet,
|
|
45
|
+
Container: () => Container,
|
|
46
|
+
Dropdown: () => Dropdown,
|
|
47
|
+
EmptyState: () => EmptyState,
|
|
48
|
+
Input: () => Input,
|
|
49
|
+
RadioGroup: () => RadioGroup,
|
|
50
|
+
SectionLayout: () => SectionLayout,
|
|
51
|
+
SidebarNav: () => SidebarNav,
|
|
52
|
+
Spinner: () => Spinner,
|
|
53
|
+
cn: () => cn
|
|
54
|
+
});
|
|
55
|
+
module.exports = __toCommonJS(index_exports);
|
|
56
|
+
|
|
57
|
+
// src/ui/button.tsx
|
|
58
|
+
var import_react = __toESM(require("react"));
|
|
59
|
+
|
|
60
|
+
// src/lib/utils.ts
|
|
61
|
+
var import_clsx = require("clsx");
|
|
62
|
+
function cn(...inputs) {
|
|
63
|
+
return (0, import_clsx.clsx)(inputs);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/ui/button.tsx
|
|
67
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
68
|
+
var Button = import_react.default.forwardRef(
|
|
69
|
+
({
|
|
70
|
+
className,
|
|
71
|
+
variant = "primary",
|
|
72
|
+
size = "md",
|
|
73
|
+
isLoading = false,
|
|
74
|
+
leftIcon,
|
|
75
|
+
rightIcon,
|
|
76
|
+
children,
|
|
77
|
+
disabled,
|
|
78
|
+
...props
|
|
79
|
+
}, ref) => {
|
|
80
|
+
const baseStyles = "inline-flex items-center justify-center transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed";
|
|
81
|
+
const variants = {
|
|
82
|
+
primary: "[background-color:var(--color-primary)] text-white hover:[background-color:var(--color-primary-hover)] focus:[--tw-ring-color:var(--color-primary)]",
|
|
83
|
+
secondary: "[background-color:var(--color-secondary)] text-white hover:[background-color:var(--color-secondary-hover)] focus:[--tw-ring-color:var(--color-secondary)]",
|
|
84
|
+
outline: "border-2 [border-color:var(--color-primary)] [color:var(--color-primary)] hover:bg-blue-50 focus:[--tw-ring-color:var(--color-primary)]",
|
|
85
|
+
ghost: "text-gray-700 hover:bg-gray-100 focus:ring-gray-500",
|
|
86
|
+
danger: "[background-color:var(--color-error)] text-white hover:bg-red-700 focus:[--tw-ring-color:var(--color-error)]"
|
|
87
|
+
};
|
|
88
|
+
const sizes = {
|
|
89
|
+
sm: "[font-size:var(--button-text-sm)] [padding-left:var(--button-padding-sm-x)] [padding-right:var(--button-padding-sm-x)] [padding-top:var(--button-padding-sm-y)] [padding-bottom:var(--button-padding-sm-y)] gap-1.5",
|
|
90
|
+
md: "[font-size:var(--button-text-md)] [padding-left:var(--button-padding-md-x)] [padding-right:var(--button-padding-md-x)] [padding-top:var(--button-padding-md-y)] [padding-bottom:var(--button-padding-md-y)] gap-2",
|
|
91
|
+
lg: "[font-size:var(--button-text-lg)] [padding-left:var(--button-padding-lg-x)] [padding-right:var(--button-padding-lg-x)] [padding-top:var(--button-padding-lg-y)] [padding-bottom:var(--button-padding-lg-y)] gap-2.5"
|
|
92
|
+
};
|
|
93
|
+
const radiusStyle = "[border-radius:var(--button-radius)]";
|
|
94
|
+
const fontWeightStyle = "[font-weight:var(--button-font-weight)]";
|
|
95
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
96
|
+
"button",
|
|
97
|
+
{
|
|
98
|
+
ref,
|
|
99
|
+
className: cn(
|
|
100
|
+
baseStyles,
|
|
101
|
+
variants[variant],
|
|
102
|
+
sizes[size],
|
|
103
|
+
radiusStyle,
|
|
104
|
+
fontWeightStyle,
|
|
105
|
+
className
|
|
106
|
+
),
|
|
107
|
+
disabled: disabled || isLoading,
|
|
108
|
+
...props,
|
|
109
|
+
children: [
|
|
110
|
+
isLoading && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
111
|
+
"svg",
|
|
112
|
+
{
|
|
113
|
+
className: "animate-spin h-4 w-4",
|
|
114
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
115
|
+
fill: "none",
|
|
116
|
+
viewBox: "0 0 24 24",
|
|
117
|
+
children: [
|
|
118
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
119
|
+
"circle",
|
|
120
|
+
{
|
|
121
|
+
className: "opacity-25",
|
|
122
|
+
cx: "12",
|
|
123
|
+
cy: "12",
|
|
124
|
+
r: "10",
|
|
125
|
+
stroke: "currentColor",
|
|
126
|
+
strokeWidth: "4"
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
130
|
+
"path",
|
|
131
|
+
{
|
|
132
|
+
className: "opacity-75",
|
|
133
|
+
fill: "currentColor",
|
|
134
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
),
|
|
140
|
+
!isLoading && leftIcon && leftIcon,
|
|
141
|
+
children,
|
|
142
|
+
!isLoading && rightIcon && rightIcon
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
Button.displayName = "Button";
|
|
149
|
+
|
|
150
|
+
// src/ui/input.tsx
|
|
151
|
+
var import_react2 = __toESM(require("react"));
|
|
152
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
153
|
+
var Input = import_react2.default.forwardRef(
|
|
154
|
+
({
|
|
155
|
+
className,
|
|
156
|
+
type = "text",
|
|
157
|
+
label,
|
|
158
|
+
error,
|
|
159
|
+
helperText,
|
|
160
|
+
leftIcon,
|
|
161
|
+
rightIcon,
|
|
162
|
+
fullWidth = false,
|
|
163
|
+
id,
|
|
164
|
+
...props
|
|
165
|
+
}, ref) => {
|
|
166
|
+
const inputId = id || label?.toLowerCase().replace(/\s+/g, "-");
|
|
167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: cn("flex flex-col", fullWidth && "w-full"), children: [
|
|
168
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
169
|
+
"label",
|
|
170
|
+
{
|
|
171
|
+
htmlFor: inputId,
|
|
172
|
+
className: "block text-sm font-semibold text-gray-600 mb-1",
|
|
173
|
+
children: [
|
|
174
|
+
label,
|
|
175
|
+
props.required && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
),
|
|
179
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "relative", children: [
|
|
180
|
+
leftIcon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-gray-400", children: leftIcon }),
|
|
181
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
182
|
+
"input",
|
|
183
|
+
{
|
|
184
|
+
ref,
|
|
185
|
+
type,
|
|
186
|
+
id: inputId,
|
|
187
|
+
className: cn(
|
|
188
|
+
"w-full px-3 py-2 border rounded-md transition-colors",
|
|
189
|
+
"text-gray-700 placeholder-gray-400",
|
|
190
|
+
"focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent",
|
|
191
|
+
"disabled:bg-gray-100 disabled:cursor-not-allowed disabled:text-gray-500",
|
|
192
|
+
error ? "border-red-500 focus:ring-red-500" : "border-gray-400",
|
|
193
|
+
leftIcon && "pl-10",
|
|
194
|
+
rightIcon && "pr-10",
|
|
195
|
+
className
|
|
196
|
+
),
|
|
197
|
+
...props
|
|
198
|
+
}
|
|
199
|
+
),
|
|
200
|
+
rightIcon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none text-gray-400", children: rightIcon })
|
|
201
|
+
] }),
|
|
202
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mt-1 text-sm text-red-600", children: error }),
|
|
203
|
+
helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mt-1 text-sm text-gray-500", children: helperText })
|
|
204
|
+
] });
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
Input.displayName = "Input";
|
|
208
|
+
|
|
209
|
+
// src/ui/card.tsx
|
|
210
|
+
var import_react3 = __toESM(require("react"));
|
|
211
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
212
|
+
var Card = import_react3.default.forwardRef(
|
|
213
|
+
({
|
|
214
|
+
className,
|
|
215
|
+
variant = "default",
|
|
216
|
+
padding = "md",
|
|
217
|
+
hoverable = false,
|
|
218
|
+
children,
|
|
219
|
+
...props
|
|
220
|
+
}, ref) => {
|
|
221
|
+
const baseStyles = "bg-white rounded-lg";
|
|
222
|
+
const variants = {
|
|
223
|
+
default: "border border-gray-200",
|
|
224
|
+
bordered: "border-2 border-gray-300",
|
|
225
|
+
elevated: "shadow-md"
|
|
226
|
+
};
|
|
227
|
+
const paddings = {
|
|
228
|
+
none: "",
|
|
229
|
+
sm: "p-3",
|
|
230
|
+
md: "p-4",
|
|
231
|
+
lg: "p-6"
|
|
232
|
+
};
|
|
233
|
+
const hoverStyles = hoverable ? "hover:shadow-lg transition-shadow cursor-pointer" : "";
|
|
234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
235
|
+
"div",
|
|
236
|
+
{
|
|
237
|
+
ref,
|
|
238
|
+
className: cn(
|
|
239
|
+
baseStyles,
|
|
240
|
+
variants[variant],
|
|
241
|
+
paddings[padding],
|
|
242
|
+
hoverStyles,
|
|
243
|
+
className
|
|
244
|
+
),
|
|
245
|
+
...props,
|
|
246
|
+
children
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
Card.displayName = "Card";
|
|
252
|
+
var CardHeader = import_react3.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
253
|
+
"div",
|
|
254
|
+
{
|
|
255
|
+
ref,
|
|
256
|
+
className: cn("flex flex-col space-y-1.5", className),
|
|
257
|
+
...props
|
|
258
|
+
}
|
|
259
|
+
));
|
|
260
|
+
CardHeader.displayName = "CardHeader";
|
|
261
|
+
var CardTitle = import_react3.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
262
|
+
"h3",
|
|
263
|
+
{
|
|
264
|
+
ref,
|
|
265
|
+
className: cn("text-lg font-semibold text-gray-800", className),
|
|
266
|
+
...props
|
|
267
|
+
}
|
|
268
|
+
));
|
|
269
|
+
CardTitle.displayName = "CardTitle";
|
|
270
|
+
var CardDescription = import_react3.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { ref, className: cn("text-sm text-gray-600", className), ...props }));
|
|
271
|
+
CardDescription.displayName = "CardDescription";
|
|
272
|
+
var CardContent = import_react3.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref, className: cn("pt-0", className), ...props }));
|
|
273
|
+
CardContent.displayName = "CardContent";
|
|
274
|
+
var CardFooter = import_react3.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
275
|
+
"div",
|
|
276
|
+
{
|
|
277
|
+
ref,
|
|
278
|
+
className: cn("flex items-center pt-4", className),
|
|
279
|
+
...props
|
|
280
|
+
}
|
|
281
|
+
));
|
|
282
|
+
CardFooter.displayName = "CardFooter";
|
|
283
|
+
|
|
284
|
+
// src/ui/badge.tsx
|
|
285
|
+
var import_react4 = __toESM(require("react"));
|
|
286
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
287
|
+
var Badge = import_react4.default.forwardRef(
|
|
288
|
+
({
|
|
289
|
+
className,
|
|
290
|
+
variant = "default",
|
|
291
|
+
size = "md",
|
|
292
|
+
dot = false,
|
|
293
|
+
children,
|
|
294
|
+
...props
|
|
295
|
+
}, ref) => {
|
|
296
|
+
const baseStyles = "inline-flex items-center font-medium rounded-full";
|
|
297
|
+
const variants = {
|
|
298
|
+
default: "bg-gray-100 text-gray-800",
|
|
299
|
+
primary: "bg-blue-100 text-blue-800",
|
|
300
|
+
success: "bg-green-100 text-green-800",
|
|
301
|
+
warning: "bg-yellow-100 text-yellow-800",
|
|
302
|
+
danger: "bg-red-100 text-red-800",
|
|
303
|
+
info: "bg-cyan-100 text-cyan-800"
|
|
304
|
+
};
|
|
305
|
+
const sizes = {
|
|
306
|
+
sm: "text-xs px-2 py-0.5",
|
|
307
|
+
md: "text-sm px-2.5 py-1",
|
|
308
|
+
lg: "text-base px-3 py-1.5"
|
|
309
|
+
};
|
|
310
|
+
const dotVariants = {
|
|
311
|
+
default: "bg-gray-600",
|
|
312
|
+
primary: "bg-blue-600",
|
|
313
|
+
success: "bg-green-600",
|
|
314
|
+
warning: "bg-yellow-600",
|
|
315
|
+
danger: "bg-red-600",
|
|
316
|
+
info: "bg-cyan-600"
|
|
317
|
+
};
|
|
318
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
319
|
+
"span",
|
|
320
|
+
{
|
|
321
|
+
ref,
|
|
322
|
+
className: cn(baseStyles, variants[variant], sizes[size], className),
|
|
323
|
+
...props,
|
|
324
|
+
children: [
|
|
325
|
+
dot && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
326
|
+
"span",
|
|
327
|
+
{
|
|
328
|
+
className: cn("w-2 h-2 rounded-full mr-1.5", dotVariants[variant])
|
|
329
|
+
}
|
|
330
|
+
),
|
|
331
|
+
children
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
Badge.displayName = "Badge";
|
|
338
|
+
|
|
339
|
+
// src/ui/checkbox.tsx
|
|
340
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
341
|
+
function Checkbox({
|
|
342
|
+
label,
|
|
343
|
+
checked = false,
|
|
344
|
+
onChange,
|
|
345
|
+
disabled = false,
|
|
346
|
+
className,
|
|
347
|
+
id
|
|
348
|
+
}) {
|
|
349
|
+
const checkboxId = id || `checkbox-${Math.random().toString(36).substr(2, 9)}`;
|
|
350
|
+
const handleChange = (e) => {
|
|
351
|
+
if (onChange) {
|
|
352
|
+
onChange(e.target.checked);
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("flex items-center", className), children: [
|
|
356
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
357
|
+
"input",
|
|
358
|
+
{
|
|
359
|
+
type: "checkbox",
|
|
360
|
+
id: checkboxId,
|
|
361
|
+
checked,
|
|
362
|
+
onChange: handleChange,
|
|
363
|
+
disabled,
|
|
364
|
+
className: cn(
|
|
365
|
+
"h-4 w-4 rounded border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
|
|
366
|
+
disabled && "cursor-not-allowed opacity-50"
|
|
367
|
+
)
|
|
368
|
+
}
|
|
369
|
+
),
|
|
370
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
371
|
+
"label",
|
|
372
|
+
{
|
|
373
|
+
htmlFor: checkboxId,
|
|
374
|
+
className: cn(
|
|
375
|
+
"ml-2 text-sm font-medium text-gray-600",
|
|
376
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
377
|
+
!disabled && "cursor-pointer"
|
|
378
|
+
),
|
|
379
|
+
children: label
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
] });
|
|
383
|
+
}
|
|
384
|
+
function CheckboxGroup({
|
|
385
|
+
label,
|
|
386
|
+
name,
|
|
387
|
+
options,
|
|
388
|
+
value = [],
|
|
389
|
+
onChange,
|
|
390
|
+
className,
|
|
391
|
+
orientation = "vertical",
|
|
392
|
+
required = false,
|
|
393
|
+
disabled = false
|
|
394
|
+
}) {
|
|
395
|
+
const handleChange = (optionValue, checked) => {
|
|
396
|
+
if (onChange) {
|
|
397
|
+
if (checked) {
|
|
398
|
+
onChange([...value, optionValue]);
|
|
399
|
+
} else {
|
|
400
|
+
onChange(value.filter((v) => v !== optionValue));
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className, children: [
|
|
405
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "block text-sm font-semibold text-gray-600 mb-1", children: [
|
|
406
|
+
label,
|
|
407
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
|
|
408
|
+
] }),
|
|
409
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
410
|
+
"div",
|
|
411
|
+
{
|
|
412
|
+
className: cn(
|
|
413
|
+
"space-y-2",
|
|
414
|
+
orientation === "horizontal" && "flex flex-wrap gap-4 space-y-0"
|
|
415
|
+
),
|
|
416
|
+
children: options.map((option) => {
|
|
417
|
+
const isDisabled = disabled || option.disabled;
|
|
418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center", children: [
|
|
419
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
420
|
+
"input",
|
|
421
|
+
{
|
|
422
|
+
type: "checkbox",
|
|
423
|
+
id: `${name}-${option.value}`,
|
|
424
|
+
name,
|
|
425
|
+
value: option.value,
|
|
426
|
+
checked: value.includes(option.value),
|
|
427
|
+
onChange: (e) => handleChange(option.value, e.target.checked),
|
|
428
|
+
disabled: isDisabled,
|
|
429
|
+
className: cn(
|
|
430
|
+
"h-4 w-4 rounded border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
|
|
431
|
+
isDisabled && "cursor-not-allowed opacity-50"
|
|
432
|
+
)
|
|
433
|
+
}
|
|
434
|
+
),
|
|
435
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
436
|
+
"label",
|
|
437
|
+
{
|
|
438
|
+
htmlFor: `${name}-${option.value}`,
|
|
439
|
+
className: cn(
|
|
440
|
+
"ml-2 text-sm font-medium text-gray-600",
|
|
441
|
+
isDisabled && "cursor-not-allowed opacity-50",
|
|
442
|
+
!isDisabled && "cursor-pointer"
|
|
443
|
+
),
|
|
444
|
+
children: option.label
|
|
445
|
+
}
|
|
446
|
+
)
|
|
447
|
+
] }, option.value);
|
|
448
|
+
})
|
|
449
|
+
}
|
|
450
|
+
)
|
|
451
|
+
] });
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// src/ui/radio.tsx
|
|
455
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
456
|
+
function RadioGroup({
|
|
457
|
+
label,
|
|
458
|
+
name,
|
|
459
|
+
options,
|
|
460
|
+
value,
|
|
461
|
+
onChange,
|
|
462
|
+
className,
|
|
463
|
+
orientation = "vertical",
|
|
464
|
+
required = false,
|
|
465
|
+
disabled = false
|
|
466
|
+
}) {
|
|
467
|
+
const handleChange = (e) => {
|
|
468
|
+
if (onChange) {
|
|
469
|
+
onChange(e.target.value);
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className, children: [
|
|
473
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "block text-sm font-semibold text-gray-600 mb-1", children: [
|
|
474
|
+
label,
|
|
475
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
|
|
476
|
+
] }),
|
|
477
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
478
|
+
"div",
|
|
479
|
+
{
|
|
480
|
+
className: cn(
|
|
481
|
+
orientation === "vertical" && "space-y-2",
|
|
482
|
+
orientation === "horizontal" && "flex flex-wrap gap-4"
|
|
483
|
+
),
|
|
484
|
+
children: options.map((option) => {
|
|
485
|
+
const isDisabled = disabled || option.disabled;
|
|
486
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center", children: [
|
|
487
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
488
|
+
"input",
|
|
489
|
+
{
|
|
490
|
+
type: "radio",
|
|
491
|
+
id: `${name}-${option.value}`,
|
|
492
|
+
name,
|
|
493
|
+
value: option.value,
|
|
494
|
+
checked: value === option.value,
|
|
495
|
+
onChange: handleChange,
|
|
496
|
+
disabled: isDisabled,
|
|
497
|
+
className: cn(
|
|
498
|
+
"h-4 w-4 border-gray-400 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2",
|
|
499
|
+
isDisabled && "cursor-not-allowed opacity-50"
|
|
500
|
+
)
|
|
501
|
+
}
|
|
502
|
+
),
|
|
503
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
504
|
+
"label",
|
|
505
|
+
{
|
|
506
|
+
htmlFor: `${name}-${option.value}`,
|
|
507
|
+
className: cn(
|
|
508
|
+
"ml-2 text-sm font-medium text-gray-600",
|
|
509
|
+
isDisabled && "cursor-not-allowed opacity-50",
|
|
510
|
+
!isDisabled && "cursor-pointer"
|
|
511
|
+
),
|
|
512
|
+
children: option.label
|
|
513
|
+
}
|
|
514
|
+
)
|
|
515
|
+
] }, option.value);
|
|
516
|
+
})
|
|
517
|
+
}
|
|
518
|
+
)
|
|
519
|
+
] });
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// src/ui/dropdown.tsx
|
|
523
|
+
var import_react5 = require("react");
|
|
524
|
+
var import_lucide_react = require("lucide-react");
|
|
525
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
526
|
+
function Dropdown({
|
|
527
|
+
label,
|
|
528
|
+
placeholder = "Select an option",
|
|
529
|
+
options = [],
|
|
530
|
+
value,
|
|
531
|
+
onChange,
|
|
532
|
+
children,
|
|
533
|
+
disabled = false,
|
|
534
|
+
error,
|
|
535
|
+
helperText,
|
|
536
|
+
required = false,
|
|
537
|
+
className = ""
|
|
538
|
+
}) {
|
|
539
|
+
const [isOpen, setIsOpen] = (0, import_react5.useState)(false);
|
|
540
|
+
const dropdownRef = (0, import_react5.useRef)(null);
|
|
541
|
+
const getSelectedLabel = () => {
|
|
542
|
+
if (!value) return placeholder;
|
|
543
|
+
const selected = options.find((opt) => opt.value === value);
|
|
544
|
+
return selected ? selected.label : placeholder;
|
|
545
|
+
};
|
|
546
|
+
(0, import_react5.useEffect)(() => {
|
|
547
|
+
const handleClickOutside = (event) => {
|
|
548
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
549
|
+
setIsOpen(false);
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
553
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
554
|
+
}, []);
|
|
555
|
+
const handleSelect = (optionValue) => {
|
|
556
|
+
onChange?.(optionValue);
|
|
557
|
+
setIsOpen(false);
|
|
558
|
+
};
|
|
559
|
+
const handleKeyDown = (e) => {
|
|
560
|
+
if (disabled) return;
|
|
561
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
562
|
+
e.preventDefault();
|
|
563
|
+
setIsOpen(!isOpen);
|
|
564
|
+
} else if (e.key === "Escape") {
|
|
565
|
+
setIsOpen(false);
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `w-full ${className}`, children: [
|
|
569
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "block text-sm font-semibold text-gray-600 mb-1", children: [
|
|
570
|
+
label,
|
|
571
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
|
|
572
|
+
] }),
|
|
573
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ref: dropdownRef, className: "relative", children: [
|
|
574
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
575
|
+
"button",
|
|
576
|
+
{
|
|
577
|
+
type: "button",
|
|
578
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
579
|
+
onKeyDown: handleKeyDown,
|
|
580
|
+
disabled,
|
|
581
|
+
className: `
|
|
582
|
+
w-full px-4 py-2 text-left bg-white border rounded-lg
|
|
583
|
+
flex items-center justify-between
|
|
584
|
+
transition-all duration-200
|
|
585
|
+
${error ? "border-red-500 focus:ring-2 focus:ring-red-200 focus:border-red-500" : "border-gray-400 focus:ring-2 focus:ring-blue-200 focus:border-blue-500"}
|
|
586
|
+
${disabled ? "bg-gray-100 cursor-not-allowed opacity-60" : "hover:border-gray-400"}
|
|
587
|
+
${!value ? "text-gray-400" : "text-gray-900"}
|
|
588
|
+
`,
|
|
589
|
+
children: [
|
|
590
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate", children: getSelectedLabel() }),
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
592
|
+
import_lucide_react.ChevronDown,
|
|
593
|
+
{
|
|
594
|
+
className: `w-5 h-5 text-gray-400 transition-transform duration-200 shrink-0 ml-2 ${isOpen ? "transform rotate-180" : ""}`
|
|
595
|
+
}
|
|
596
|
+
)
|
|
597
|
+
]
|
|
598
|
+
}
|
|
599
|
+
),
|
|
600
|
+
isOpen && !disabled && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
601
|
+
"div",
|
|
602
|
+
{
|
|
603
|
+
className: "absolute z-50 w-full mt-1 bg-white border border-gray-400 rounded-lg shadow-lg max-h-60 overflow-auto",
|
|
604
|
+
role: "listbox",
|
|
605
|
+
children: children ? (
|
|
606
|
+
// Custom content
|
|
607
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { onClick: () => setIsOpen(false), children })
|
|
608
|
+
) : (
|
|
609
|
+
// Standard options
|
|
610
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
611
|
+
"button",
|
|
612
|
+
{
|
|
613
|
+
type: "button",
|
|
614
|
+
onClick: () => !option.disabled && handleSelect(option.value),
|
|
615
|
+
disabled: option.disabled,
|
|
616
|
+
className: `
|
|
617
|
+
w-full px-4 py-2 text-left text-sm
|
|
618
|
+
transition-colors duration-150
|
|
619
|
+
${option.value === value ? "bg-blue-50 text-blue-700 font-medium" : "text-gray-900 hover:bg-gray-100"}
|
|
620
|
+
${option.disabled ? "opacity-50 cursor-not-allowed" : ""}
|
|
621
|
+
`,
|
|
622
|
+
role: "option",
|
|
623
|
+
"aria-selected": option.value === value,
|
|
624
|
+
children: option.label
|
|
625
|
+
}
|
|
626
|
+
) }, option.value)) })
|
|
627
|
+
)
|
|
628
|
+
}
|
|
629
|
+
)
|
|
630
|
+
] }),
|
|
631
|
+
(helperText || error) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
632
|
+
"p",
|
|
633
|
+
{
|
|
634
|
+
className: `mt-1 text-xs ${error ? "text-red-600" : "text-gray-500"}`,
|
|
635
|
+
children: error || helperText
|
|
636
|
+
}
|
|
637
|
+
)
|
|
638
|
+
] });
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// src/ui/spinner.tsx
|
|
642
|
+
var import_react6 = __toESM(require("react"));
|
|
643
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
644
|
+
var Spinner = import_react6.default.forwardRef(
|
|
645
|
+
({ className, size = "md", color = "primary", label, ...props }, ref) => {
|
|
646
|
+
const sizes = {
|
|
647
|
+
sm: "h-4 w-4",
|
|
648
|
+
md: "h-8 w-8",
|
|
649
|
+
lg: "h-12 w-12",
|
|
650
|
+
xl: "h-16 w-16"
|
|
651
|
+
};
|
|
652
|
+
const colors = {
|
|
653
|
+
primary: "text-blue-600",
|
|
654
|
+
secondary: "text-gray-600",
|
|
655
|
+
white: "text-white"
|
|
656
|
+
};
|
|
657
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
658
|
+
"div",
|
|
659
|
+
{
|
|
660
|
+
ref,
|
|
661
|
+
className: cn(
|
|
662
|
+
"flex flex-col items-center justify-center gap-2",
|
|
663
|
+
className
|
|
664
|
+
),
|
|
665
|
+
...props,
|
|
666
|
+
children: [
|
|
667
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
668
|
+
"svg",
|
|
669
|
+
{
|
|
670
|
+
className: cn("animate-spin", sizes[size], colors[color]),
|
|
671
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
672
|
+
fill: "none",
|
|
673
|
+
viewBox: "0 0 24 24",
|
|
674
|
+
children: [
|
|
675
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
676
|
+
"circle",
|
|
677
|
+
{
|
|
678
|
+
className: "opacity-25",
|
|
679
|
+
cx: "12",
|
|
680
|
+
cy: "12",
|
|
681
|
+
r: "10",
|
|
682
|
+
stroke: "currentColor",
|
|
683
|
+
strokeWidth: "4"
|
|
684
|
+
}
|
|
685
|
+
),
|
|
686
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
687
|
+
"path",
|
|
688
|
+
{
|
|
689
|
+
className: "opacity-75",
|
|
690
|
+
fill: "currentColor",
|
|
691
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
692
|
+
}
|
|
693
|
+
)
|
|
694
|
+
]
|
|
695
|
+
}
|
|
696
|
+
),
|
|
697
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-gray-600", children: label })
|
|
698
|
+
]
|
|
699
|
+
}
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
);
|
|
703
|
+
Spinner.displayName = "Spinner";
|
|
704
|
+
|
|
705
|
+
// src/ui/code-snippet.tsx
|
|
706
|
+
var import_react7 = require("react");
|
|
707
|
+
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
708
|
+
var import_prism = require("react-syntax-highlighter/dist/esm/styles/prism");
|
|
709
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
710
|
+
function CodeSnippet({ code, language = "tsx" }) {
|
|
711
|
+
const [copied, setCopied] = (0, import_react7.useState)(false);
|
|
712
|
+
const [showTooltip, setShowTooltip] = (0, import_react7.useState)(false);
|
|
713
|
+
const handleCopy = async () => {
|
|
714
|
+
try {
|
|
715
|
+
await navigator.clipboard.writeText(code);
|
|
716
|
+
setCopied(true);
|
|
717
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
718
|
+
} catch (err) {
|
|
719
|
+
console.error("Failed to copy:", err);
|
|
720
|
+
}
|
|
721
|
+
};
|
|
722
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "relative group", children: [
|
|
723
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "absolute right-3 top-3 z-10", children: [
|
|
724
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
725
|
+
"button",
|
|
726
|
+
{
|
|
727
|
+
onClick: handleCopy,
|
|
728
|
+
onMouseEnter: () => setShowTooltip(true),
|
|
729
|
+
onMouseLeave: () => setShowTooltip(false),
|
|
730
|
+
className: "p-2 rounded-md bg-gray-800 hover:bg-gray-700 text-gray-400 hover:text-gray-200 transition-all duration-200 border border-gray-700 hover:border-gray-600 shadow-lg",
|
|
731
|
+
"aria-label": "Copy code",
|
|
732
|
+
children: copied ? (
|
|
733
|
+
// Check icon
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
735
|
+
"svg",
|
|
736
|
+
{
|
|
737
|
+
className: "w-4 h-4 text-green-400",
|
|
738
|
+
fill: "none",
|
|
739
|
+
stroke: "currentColor",
|
|
740
|
+
viewBox: "0 0 24 24",
|
|
741
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
742
|
+
"path",
|
|
743
|
+
{
|
|
744
|
+
strokeLinecap: "round",
|
|
745
|
+
strokeLinejoin: "round",
|
|
746
|
+
strokeWidth: 2,
|
|
747
|
+
d: "M5 13l4 4L19 7"
|
|
748
|
+
}
|
|
749
|
+
)
|
|
750
|
+
}
|
|
751
|
+
)
|
|
752
|
+
) : (
|
|
753
|
+
// Copy icon
|
|
754
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
755
|
+
"svg",
|
|
756
|
+
{
|
|
757
|
+
className: "w-4 h-4",
|
|
758
|
+
fill: "none",
|
|
759
|
+
stroke: "currentColor",
|
|
760
|
+
viewBox: "0 0 24 24",
|
|
761
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
762
|
+
"path",
|
|
763
|
+
{
|
|
764
|
+
strokeLinecap: "round",
|
|
765
|
+
strokeLinejoin: "round",
|
|
766
|
+
strokeWidth: 2,
|
|
767
|
+
d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
|
|
768
|
+
}
|
|
769
|
+
)
|
|
770
|
+
}
|
|
771
|
+
)
|
|
772
|
+
)
|
|
773
|
+
}
|
|
774
|
+
),
|
|
775
|
+
showTooltip && !copied && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "absolute right-0 top-full mt-2 px-2 py-1 bg-gray-800 text-white text-xs rounded shadow-lg whitespace-nowrap border border-gray-700", children: [
|
|
776
|
+
"Copy code",
|
|
777
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute -top-1 right-3 w-2 h-2 bg-gray-800 border-l border-t border-gray-700 transform rotate-45" })
|
|
778
|
+
] }),
|
|
779
|
+
copied && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "absolute right-0 top-full mt-2 px-2 py-1 bg-green-600 text-white text-xs rounded shadow-lg whitespace-nowrap", children: [
|
|
780
|
+
"Copied!",
|
|
781
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "absolute -top-1 right-3 w-2 h-2 bg-green-600 transform rotate-45" })
|
|
782
|
+
] })
|
|
783
|
+
] }),
|
|
784
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "rounded-lg overflow-hidden border border-gray-800", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
785
|
+
import_react_syntax_highlighter.Prism,
|
|
786
|
+
{
|
|
787
|
+
language,
|
|
788
|
+
style: import_prism.vscDarkPlus,
|
|
789
|
+
customStyle: {
|
|
790
|
+
margin: 0,
|
|
791
|
+
padding: "1rem 3.5rem 1rem 1rem",
|
|
792
|
+
fontSize: "0.875rem",
|
|
793
|
+
lineHeight: "1.5",
|
|
794
|
+
background: "#1a1b26"
|
|
795
|
+
},
|
|
796
|
+
showLineNumbers: false,
|
|
797
|
+
children: code
|
|
798
|
+
}
|
|
799
|
+
) })
|
|
800
|
+
] });
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// src/feedback/alert.tsx
|
|
804
|
+
var import_react8 = __toESM(require("react"));
|
|
805
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
806
|
+
var Alert = import_react8.default.forwardRef(
|
|
807
|
+
({
|
|
808
|
+
className,
|
|
809
|
+
variant = "info",
|
|
810
|
+
title,
|
|
811
|
+
dismissible = false,
|
|
812
|
+
onDismiss,
|
|
813
|
+
icon,
|
|
814
|
+
children,
|
|
815
|
+
...props
|
|
816
|
+
}, ref) => {
|
|
817
|
+
const variants = {
|
|
818
|
+
info: "bg-blue-50 border-blue-200 text-blue-800",
|
|
819
|
+
success: "bg-green-50 border-green-200 text-green-800",
|
|
820
|
+
warning: "bg-yellow-50 border-yellow-200 text-yellow-800",
|
|
821
|
+
error: "bg-red-50 border-red-200 text-red-800"
|
|
822
|
+
};
|
|
823
|
+
const iconColors = {
|
|
824
|
+
info: "text-blue-500",
|
|
825
|
+
success: "text-green-500",
|
|
826
|
+
warning: "text-yellow-500",
|
|
827
|
+
error: "text-red-500"
|
|
828
|
+
};
|
|
829
|
+
const defaultIcons = {
|
|
830
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
831
|
+
"path",
|
|
832
|
+
{
|
|
833
|
+
fillRule: "evenodd",
|
|
834
|
+
d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z",
|
|
835
|
+
clipRule: "evenodd"
|
|
836
|
+
}
|
|
837
|
+
) }),
|
|
838
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
839
|
+
"path",
|
|
840
|
+
{
|
|
841
|
+
fillRule: "evenodd",
|
|
842
|
+
d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",
|
|
843
|
+
clipRule: "evenodd"
|
|
844
|
+
}
|
|
845
|
+
) }),
|
|
846
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
847
|
+
"path",
|
|
848
|
+
{
|
|
849
|
+
fillRule: "evenodd",
|
|
850
|
+
d: "M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",
|
|
851
|
+
clipRule: "evenodd"
|
|
852
|
+
}
|
|
853
|
+
) }),
|
|
854
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-5 h-5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
855
|
+
"path",
|
|
856
|
+
{
|
|
857
|
+
fillRule: "evenodd",
|
|
858
|
+
d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",
|
|
859
|
+
clipRule: "evenodd"
|
|
860
|
+
}
|
|
861
|
+
) })
|
|
862
|
+
};
|
|
863
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
864
|
+
"div",
|
|
865
|
+
{
|
|
866
|
+
ref,
|
|
867
|
+
className: cn(
|
|
868
|
+
"relative border rounded-lg p-4",
|
|
869
|
+
variants[variant],
|
|
870
|
+
className
|
|
871
|
+
),
|
|
872
|
+
role: "alert",
|
|
873
|
+
...props,
|
|
874
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-start gap-3", children: [
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cn("flex-shrink-0", iconColors[variant]), children: icon || defaultIcons[variant] }),
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex-1", children: [
|
|
877
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h5", { className: "font-semibold mb-1", children: title }),
|
|
878
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-sm", children })
|
|
879
|
+
] }),
|
|
880
|
+
dismissible && onDismiss && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
881
|
+
"button",
|
|
882
|
+
{
|
|
883
|
+
type: "button",
|
|
884
|
+
onClick: onDismiss,
|
|
885
|
+
className: cn(
|
|
886
|
+
"flex-shrink-0 rounded-lg p-1.5 inline-flex focus:outline-none focus:ring-2",
|
|
887
|
+
iconColors[variant],
|
|
888
|
+
"hover:bg-black hover:bg-opacity-10"
|
|
889
|
+
),
|
|
890
|
+
"aria-label": "Close",
|
|
891
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "w-4 h-4", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
892
|
+
"path",
|
|
893
|
+
{
|
|
894
|
+
fillRule: "evenodd",
|
|
895
|
+
d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",
|
|
896
|
+
clipRule: "evenodd"
|
|
897
|
+
}
|
|
898
|
+
) })
|
|
899
|
+
}
|
|
900
|
+
)
|
|
901
|
+
] })
|
|
902
|
+
}
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
);
|
|
906
|
+
Alert.displayName = "Alert";
|
|
907
|
+
|
|
908
|
+
// src/layout/container.tsx
|
|
909
|
+
var import_react9 = __toESM(require("react"));
|
|
910
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
911
|
+
var Container = import_react9.default.forwardRef(
|
|
912
|
+
({
|
|
913
|
+
className,
|
|
914
|
+
maxWidth = "xl",
|
|
915
|
+
centered = true,
|
|
916
|
+
padding = true,
|
|
917
|
+
children,
|
|
918
|
+
...props
|
|
919
|
+
}, ref) => {
|
|
920
|
+
const maxWidths = {
|
|
921
|
+
sm: "max-w-screen-sm",
|
|
922
|
+
md: "max-w-screen-md",
|
|
923
|
+
lg: "max-w-screen-lg",
|
|
924
|
+
xl: "max-w-screen-xl",
|
|
925
|
+
"2xl": "max-w-screen-2xl",
|
|
926
|
+
full: "max-w-full"
|
|
927
|
+
};
|
|
928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
929
|
+
"div",
|
|
930
|
+
{
|
|
931
|
+
ref,
|
|
932
|
+
className: cn(
|
|
933
|
+
"w-full",
|
|
934
|
+
maxWidths[maxWidth],
|
|
935
|
+
centered && "mx-auto",
|
|
936
|
+
padding && "px-4 sm:px-6 lg:px-8",
|
|
937
|
+
className
|
|
938
|
+
),
|
|
939
|
+
...props,
|
|
940
|
+
children
|
|
941
|
+
}
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
);
|
|
945
|
+
Container.displayName = "Container";
|
|
946
|
+
|
|
947
|
+
// src/layout/section-layout.tsx
|
|
948
|
+
var import_react10 = __toESM(require("react"));
|
|
949
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
950
|
+
function SectionLayout({
|
|
951
|
+
children,
|
|
952
|
+
hasStickyPreview = false
|
|
953
|
+
}) {
|
|
954
|
+
if (!hasStickyPreview) {
|
|
955
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_jsx_runtime12.Fragment, { children });
|
|
956
|
+
}
|
|
957
|
+
const childArray = import_react10.default.Children.toArray(children);
|
|
958
|
+
if (childArray.length === 0) {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
const stickyPreview = childArray[0];
|
|
962
|
+
const scrollableContent = childArray.slice(1);
|
|
963
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
964
|
+
stickyPreview,
|
|
965
|
+
scrollableContent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-8", children: scrollableContent })
|
|
966
|
+
] });
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
// src/layout/sidebar-nav.tsx
|
|
970
|
+
var import_react11 = require("react");
|
|
971
|
+
var import_lucide_react2 = require("lucide-react");
|
|
972
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
973
|
+
function SidebarNav({
|
|
974
|
+
title,
|
|
975
|
+
subtitle,
|
|
976
|
+
items,
|
|
977
|
+
activeItem,
|
|
978
|
+
onItemClick,
|
|
979
|
+
footer,
|
|
980
|
+
position = "right"
|
|
981
|
+
}) {
|
|
982
|
+
const [mobileMenuOpen, setMobileMenuOpen] = (0, import_react11.useState)(false);
|
|
983
|
+
const isLeft = position === "left";
|
|
984
|
+
const handleItemClick = (itemId) => {
|
|
985
|
+
onItemClick(itemId);
|
|
986
|
+
setMobileMenuOpen(false);
|
|
987
|
+
};
|
|
988
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
989
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "lg:hidden fixed top-0 left-0 right-0 z-50 bg-white border-b border-gray-200 px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
990
|
+
"div",
|
|
991
|
+
{
|
|
992
|
+
className: `flex items-center ${isLeft ? "justify-between" : "justify-between flex-row-reverse"}`,
|
|
993
|
+
children: [
|
|
994
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
995
|
+
"button",
|
|
996
|
+
{
|
|
997
|
+
onClick: () => setMobileMenuOpen(!mobileMenuOpen),
|
|
998
|
+
className: "p-2 rounded-lg hover:bg-gray-100 transition-colors",
|
|
999
|
+
"aria-label": "Toggle menu",
|
|
1000
|
+
children: mobileMenuOpen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.X, { className: "w-6 h-6 text-gray-700" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react2.Menu, { className: "w-6 h-6 text-gray-700" })
|
|
1001
|
+
}
|
|
1002
|
+
),
|
|
1003
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { children: [
|
|
1004
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h1", { className: "text-lg font-bold text-gray-900", children: title }),
|
|
1005
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-xs text-gray-500", children: subtitle })
|
|
1006
|
+
] })
|
|
1007
|
+
]
|
|
1008
|
+
}
|
|
1009
|
+
) }),
|
|
1010
|
+
mobileMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1011
|
+
"div",
|
|
1012
|
+
{
|
|
1013
|
+
className: "fixed inset-0 bg-black/50 lg:hidden",
|
|
1014
|
+
style: { zIndex: 35 },
|
|
1015
|
+
onClick: () => setMobileMenuOpen(false)
|
|
1016
|
+
}
|
|
1017
|
+
),
|
|
1018
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1019
|
+
"aside",
|
|
1020
|
+
{
|
|
1021
|
+
className: `
|
|
1022
|
+
fixed top-0 h-screen w-64 bg-white z-40
|
|
1023
|
+
transition-transform duration-300 ease-in-out overflow-y-auto
|
|
1024
|
+
${isLeft ? "left-0 border-r" : "right-0 border-l"} border-gray-200
|
|
1025
|
+
lg:translate-x-0
|
|
1026
|
+
${mobileMenuOpen ? "translate-x-0" : `${isLeft ? "-translate-x-full" : "translate-x-full"} lg:translate-x-0`}
|
|
1027
|
+
`,
|
|
1028
|
+
children: [
|
|
1029
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "hidden lg:block p-6 border-b border-gray-200", children: [
|
|
1030
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h1", { className: "text-xl font-bold text-gray-900", children: title }),
|
|
1031
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-xs text-gray-500 mt-1", children: subtitle })
|
|
1032
|
+
] }),
|
|
1033
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "lg:hidden h-[57px]", "aria-hidden": "true" }),
|
|
1034
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("nav", { className: "p-4", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("ul", { className: "space-y-1", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1035
|
+
"button",
|
|
1036
|
+
{
|
|
1037
|
+
onClick: () => handleItemClick(item.id),
|
|
1038
|
+
className: `
|
|
1039
|
+
w-full flex items-center gap-3 px-4 py-3 rounded-lg text-sm font-medium transition-colors
|
|
1040
|
+
${activeItem === item.id ? "bg-blue-50 text-blue-700" : "text-gray-700 hover:bg-gray-50"}
|
|
1041
|
+
`,
|
|
1042
|
+
children: [
|
|
1043
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "shrink-0", children: item.icon }),
|
|
1044
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: item.label })
|
|
1045
|
+
]
|
|
1046
|
+
}
|
|
1047
|
+
) }, item.id)) }) }),
|
|
1048
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "p-4 border-t border-gray-200 mt-auto", children: footer })
|
|
1049
|
+
]
|
|
1050
|
+
}
|
|
1051
|
+
)
|
|
1052
|
+
] });
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
// src/shared/empty-state.tsx
|
|
1056
|
+
var import_react12 = __toESM(require("react"));
|
|
1057
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1058
|
+
var EmptyState = import_react12.default.forwardRef(
|
|
1059
|
+
({ className, icon, title, description, action, ...props }, ref) => {
|
|
1060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1061
|
+
"div",
|
|
1062
|
+
{
|
|
1063
|
+
ref,
|
|
1064
|
+
className: cn(
|
|
1065
|
+
"flex flex-col items-center justify-center text-center py-12 px-4",
|
|
1066
|
+
className
|
|
1067
|
+
),
|
|
1068
|
+
...props,
|
|
1069
|
+
children: [
|
|
1070
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "mb-4 text-gray-400", children: icon }),
|
|
1071
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: title }),
|
|
1072
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-gray-500 mb-6 max-w-sm", children: description }),
|
|
1073
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { children: action })
|
|
1074
|
+
]
|
|
1075
|
+
}
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
);
|
|
1079
|
+
EmptyState.displayName = "EmptyState";
|
|
1080
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1081
|
+
0 && (module.exports = {
|
|
1082
|
+
Alert,
|
|
1083
|
+
Badge,
|
|
1084
|
+
Button,
|
|
1085
|
+
Card,
|
|
1086
|
+
CardContent,
|
|
1087
|
+
CardDescription,
|
|
1088
|
+
CardFooter,
|
|
1089
|
+
CardHeader,
|
|
1090
|
+
CardTitle,
|
|
1091
|
+
Checkbox,
|
|
1092
|
+
CheckboxGroup,
|
|
1093
|
+
CodeSnippet,
|
|
1094
|
+
Container,
|
|
1095
|
+
Dropdown,
|
|
1096
|
+
EmptyState,
|
|
1097
|
+
Input,
|
|
1098
|
+
RadioGroup,
|
|
1099
|
+
SectionLayout,
|
|
1100
|
+
SidebarNav,
|
|
1101
|
+
Spinner,
|
|
1102
|
+
cn
|
|
1103
|
+
});
|
|
1104
|
+
//# sourceMappingURL=index.js.map
|