shru-design-system 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +96 -23
- package/dist/index.d.ts +96 -23
- package/dist/index.js +512 -49
- package/dist/index.mjs +512 -49
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -143,7 +143,8 @@ var badgeVariantsConfig = {
|
|
|
143
143
|
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
144
144
|
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
|
145
145
|
destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
146
|
-
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
|
|
146
|
+
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
147
|
+
disabled: "border-transparent bg-muted text-muted-foreground opacity-50 cursor-not-allowed"
|
|
147
148
|
}
|
|
148
149
|
},
|
|
149
150
|
defaultVariants: {
|
|
@@ -154,14 +155,15 @@ var badgeVariants = classVarianceAuthority.cva(
|
|
|
154
155
|
"inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium font-sans w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-component-xs [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] duration-normal overflow-hidden",
|
|
155
156
|
badgeVariantsConfig
|
|
156
157
|
);
|
|
157
|
-
var Badge = React14__namespace.forwardRef(({ className, variant, asChild = false, ...props }, ref) => {
|
|
158
|
+
var Badge = React14__namespace.forwardRef(({ className, variant, asChild = false, onClick, ...props }, ref) => {
|
|
158
159
|
const Comp = asChild ? reactSlot.Slot : "span";
|
|
159
160
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
160
161
|
Comp,
|
|
161
162
|
{
|
|
162
163
|
ref,
|
|
163
164
|
"data-slot": "badge",
|
|
164
|
-
className: cn(badgeVariants({ variant }), className),
|
|
165
|
+
className: cn(badgeVariants({ variant }), onClick && "cursor-pointer", className),
|
|
166
|
+
onClick,
|
|
165
167
|
...props
|
|
166
168
|
}
|
|
167
169
|
);
|
|
@@ -4004,10 +4006,12 @@ var variantMap3 = {
|
|
|
4004
4006
|
function InfoBanner({
|
|
4005
4007
|
message,
|
|
4006
4008
|
variant = "info",
|
|
4007
|
-
className
|
|
4009
|
+
className,
|
|
4010
|
+
tooltip = false,
|
|
4011
|
+
children
|
|
4008
4012
|
}) {
|
|
4009
4013
|
const { icon: Icon2 } = variantMap3[variant];
|
|
4010
|
-
|
|
4014
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4011
4015
|
Alert,
|
|
4012
4016
|
{
|
|
4013
4017
|
"data-slot": "info-banner",
|
|
@@ -4023,6 +4027,13 @@ function InfoBanner({
|
|
|
4023
4027
|
]
|
|
4024
4028
|
}
|
|
4025
4029
|
);
|
|
4030
|
+
if (tooltip) {
|
|
4031
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
4032
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: children || /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "size-4" }) }),
|
|
4033
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: message }) })
|
|
4034
|
+
] }) });
|
|
4035
|
+
}
|
|
4036
|
+
return content;
|
|
4026
4037
|
}
|
|
4027
4038
|
function InlineEdit({
|
|
4028
4039
|
value: initialValue,
|
|
@@ -4207,21 +4218,107 @@ function InputGroupTextarea({
|
|
|
4207
4218
|
}
|
|
4208
4219
|
function FormInput({
|
|
4209
4220
|
className,
|
|
4221
|
+
type = "text",
|
|
4210
4222
|
label,
|
|
4211
4223
|
error,
|
|
4212
4224
|
description,
|
|
4225
|
+
variant = "default",
|
|
4213
4226
|
id,
|
|
4227
|
+
options,
|
|
4228
|
+
onValueChange,
|
|
4229
|
+
checked,
|
|
4230
|
+
onCheckedChange,
|
|
4214
4231
|
...props
|
|
4215
4232
|
}) {
|
|
4216
4233
|
const inputId = id || React14__namespace.useId();
|
|
4234
|
+
if (type === "checkbox") {
|
|
4235
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "form-input", className: cn("space-y-2", className), children: [
|
|
4236
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
4237
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4238
|
+
Checkbox,
|
|
4239
|
+
{
|
|
4240
|
+
id: inputId,
|
|
4241
|
+
checked,
|
|
4242
|
+
onCheckedChange,
|
|
4243
|
+
disabled: props.disabled
|
|
4244
|
+
}
|
|
4245
|
+
),
|
|
4246
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: inputId, className: cn("cursor-pointer", error && "text-destructive"), children: [
|
|
4247
|
+
label,
|
|
4248
|
+
props.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
|
|
4249
|
+
] })
|
|
4250
|
+
] }),
|
|
4251
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: description }),
|
|
4252
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", role: "alert", children: error })
|
|
4253
|
+
] });
|
|
4254
|
+
}
|
|
4255
|
+
if (type === "select") {
|
|
4256
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "form-input", className: cn("space-y-2", className), children: [
|
|
4257
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: inputId, className: error && "text-destructive", children: [
|
|
4258
|
+
label,
|
|
4259
|
+
props.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
|
|
4260
|
+
] }),
|
|
4261
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: description }),
|
|
4262
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4263
|
+
Select,
|
|
4264
|
+
{
|
|
4265
|
+
value: props.value,
|
|
4266
|
+
onValueChange,
|
|
4267
|
+
children: [
|
|
4268
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4269
|
+
SelectTrigger,
|
|
4270
|
+
{
|
|
4271
|
+
id: inputId,
|
|
4272
|
+
className: cn(
|
|
4273
|
+
error && "border-destructive",
|
|
4274
|
+
variant === "minimal" && "border-0 shadow-none bg-transparent"
|
|
4275
|
+
),
|
|
4276
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: props.placeholder || "Select..." })
|
|
4277
|
+
}
|
|
4278
|
+
),
|
|
4279
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: options?.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
|
|
4280
|
+
]
|
|
4281
|
+
}
|
|
4282
|
+
),
|
|
4283
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", role: "alert", children: error })
|
|
4284
|
+
] });
|
|
4285
|
+
}
|
|
4286
|
+
if (type === "textarea") {
|
|
4287
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "form-input", className: cn("space-y-2", className), children: [
|
|
4288
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: inputId, className: error && "text-destructive", children: [
|
|
4289
|
+
label,
|
|
4290
|
+
props.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
|
|
4291
|
+
] }),
|
|
4292
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: description }),
|
|
4293
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4294
|
+
Textarea,
|
|
4295
|
+
{
|
|
4296
|
+
id: inputId,
|
|
4297
|
+
className: cn(
|
|
4298
|
+
error && "border-destructive",
|
|
4299
|
+
variant === "minimal" && "border-0 shadow-none bg-transparent"
|
|
4300
|
+
),
|
|
4301
|
+
...props
|
|
4302
|
+
}
|
|
4303
|
+
),
|
|
4304
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", role: "alert", children: error })
|
|
4305
|
+
] });
|
|
4306
|
+
}
|
|
4217
4307
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "form-input", className: cn("space-y-2", className), children: [
|
|
4218
|
-
label && /* @__PURE__ */ jsxRuntime.
|
|
4308
|
+
label && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: inputId, className: error && "text-destructive", children: [
|
|
4309
|
+
label,
|
|
4310
|
+
props.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
|
|
4311
|
+
] }),
|
|
4219
4312
|
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: description }),
|
|
4220
4313
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4221
4314
|
TextInput,
|
|
4222
4315
|
{
|
|
4223
4316
|
id: inputId,
|
|
4224
|
-
|
|
4317
|
+
type,
|
|
4318
|
+
className: cn(
|
|
4319
|
+
error && "border-destructive",
|
|
4320
|
+
variant === "minimal" && "border-0 shadow-none bg-transparent"
|
|
4321
|
+
),
|
|
4225
4322
|
...props
|
|
4226
4323
|
}
|
|
4227
4324
|
),
|
|
@@ -4229,38 +4326,112 @@ function FormInput({
|
|
|
4229
4326
|
] });
|
|
4230
4327
|
}
|
|
4231
4328
|
function ConfirmModal({
|
|
4232
|
-
open,
|
|
4329
|
+
open: openProp,
|
|
4233
4330
|
onOpenChange,
|
|
4234
|
-
|
|
4331
|
+
triggerLabel,
|
|
4332
|
+
triggerProps,
|
|
4333
|
+
text,
|
|
4235
4334
|
title,
|
|
4236
4335
|
description,
|
|
4237
|
-
|
|
4336
|
+
onConfirm,
|
|
4337
|
+
confirmLabel,
|
|
4238
4338
|
cancelLabel = "Cancel",
|
|
4239
|
-
variant = "default"
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4339
|
+
variant = "default",
|
|
4340
|
+
loading = false,
|
|
4341
|
+
error,
|
|
4342
|
+
showModal = true
|
|
4343
|
+
}) {
|
|
4344
|
+
const [open, setOpen] = React14__namespace.useState(openProp ?? false);
|
|
4345
|
+
const [isSubmitting, setIsSubmitting] = React14__namespace.useState(false);
|
|
4346
|
+
const isControlled = openProp !== void 0;
|
|
4347
|
+
const isOpen = isControlled ? openProp : open;
|
|
4348
|
+
const setIsOpen = isControlled ? onOpenChange : setOpen;
|
|
4349
|
+
const handleConfirm = async () => {
|
|
4350
|
+
setIsSubmitting(true);
|
|
4351
|
+
try {
|
|
4352
|
+
await onConfirm();
|
|
4353
|
+
setIsOpen?.(false);
|
|
4354
|
+
} catch (err) {
|
|
4355
|
+
console.error("Confirm action error:", err);
|
|
4356
|
+
} finally {
|
|
4357
|
+
setIsSubmitting(false);
|
|
4358
|
+
}
|
|
4244
4359
|
};
|
|
4245
|
-
|
|
4360
|
+
const getVariantConfig = () => {
|
|
4361
|
+
switch (variant) {
|
|
4362
|
+
case "delete":
|
|
4363
|
+
case "destructive":
|
|
4364
|
+
return {
|
|
4365
|
+
buttonVariant: "destructive",
|
|
4366
|
+
defaultConfirmLabel: "Delete"
|
|
4367
|
+
};
|
|
4368
|
+
case "save":
|
|
4369
|
+
return {
|
|
4370
|
+
buttonVariant: "default",
|
|
4371
|
+
defaultConfirmLabel: "Save"
|
|
4372
|
+
};
|
|
4373
|
+
case "warning":
|
|
4374
|
+
return {
|
|
4375
|
+
buttonVariant: "default",
|
|
4376
|
+
defaultConfirmLabel: "Continue"
|
|
4377
|
+
};
|
|
4378
|
+
default:
|
|
4379
|
+
return {
|
|
4380
|
+
buttonVariant: "default",
|
|
4381
|
+
defaultConfirmLabel: "Confirm"
|
|
4382
|
+
};
|
|
4383
|
+
}
|
|
4384
|
+
};
|
|
4385
|
+
const { buttonVariant, defaultConfirmLabel } = getVariantConfig();
|
|
4386
|
+
const finalConfirmLabel = confirmLabel || defaultConfirmLabel;
|
|
4387
|
+
const isLoading = loading || isSubmitting;
|
|
4388
|
+
const modalContent = /* @__PURE__ */ jsxRuntime.jsx(Modal, { open: isOpen && showModal, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(ModalContent, { "data-slot": "confirm-modal", children: [
|
|
4246
4389
|
/* @__PURE__ */ jsxRuntime.jsxs(ModalHeader, { children: [
|
|
4247
4390
|
/* @__PURE__ */ jsxRuntime.jsx(ModalTitle, { children: title }),
|
|
4248
|
-
description && /* @__PURE__ */ jsxRuntime.jsx(ModalDescription, { children: description })
|
|
4391
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(ModalDescription, { children: description }),
|
|
4392
|
+
text && /* @__PURE__ */ jsxRuntime.jsx(ModalDescription, { children: text })
|
|
4249
4393
|
] }),
|
|
4394
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", children: error }) }),
|
|
4250
4395
|
/* @__PURE__ */ jsxRuntime.jsxs(ModalFooter, { children: [
|
|
4251
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4252
|
-
|
|
4396
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4397
|
+
Button,
|
|
4398
|
+
{
|
|
4399
|
+
variant: "outline",
|
|
4400
|
+
onClick: () => setIsOpen?.(false),
|
|
4401
|
+
disabled: isLoading,
|
|
4402
|
+
children: cancelLabel
|
|
4403
|
+
}
|
|
4404
|
+
),
|
|
4405
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4406
|
+
Button,
|
|
4407
|
+
{
|
|
4408
|
+
variant: buttonVariant,
|
|
4409
|
+
onClick: handleConfirm,
|
|
4410
|
+
disabled: isLoading,
|
|
4411
|
+
children: isLoading ? "Loading..." : finalConfirmLabel
|
|
4412
|
+
}
|
|
4413
|
+
)
|
|
4253
4414
|
] })
|
|
4254
4415
|
] }) });
|
|
4416
|
+
if (triggerLabel) {
|
|
4417
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { open: isOpen && showModal, onOpenChange: setIsOpen, children: [
|
|
4418
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { ...triggerProps, children: triggerLabel }) }),
|
|
4419
|
+
modalContent
|
|
4420
|
+
] });
|
|
4421
|
+
}
|
|
4422
|
+
return modalContent;
|
|
4255
4423
|
}
|
|
4256
4424
|
function CopyButton({
|
|
4257
4425
|
text,
|
|
4426
|
+
getText,
|
|
4258
4427
|
onCopy,
|
|
4259
4428
|
...props
|
|
4260
4429
|
}) {
|
|
4261
4430
|
const [copied, setCopied] = React14__namespace.useState(false);
|
|
4262
4431
|
const handleCopy = async () => {
|
|
4263
|
-
|
|
4432
|
+
const textToCopy = getText ? getText() : text || "";
|
|
4433
|
+
if (!textToCopy) return;
|
|
4434
|
+
await navigator.clipboard.writeText(textToCopy);
|
|
4264
4435
|
setCopied(true);
|
|
4265
4436
|
onCopy?.();
|
|
4266
4437
|
setTimeout(() => setCopied(false), 2e3);
|
|
@@ -4278,36 +4449,235 @@ function CopyButton({
|
|
|
4278
4449
|
);
|
|
4279
4450
|
}
|
|
4280
4451
|
function FormModal({
|
|
4281
|
-
open,
|
|
4452
|
+
open: openProp,
|
|
4282
4453
|
onOpenChange,
|
|
4454
|
+
triggerLabel,
|
|
4455
|
+
triggerProps,
|
|
4283
4456
|
title,
|
|
4284
4457
|
onSubmit,
|
|
4285
|
-
children,
|
|
4286
4458
|
submitLabel = "Submit",
|
|
4287
|
-
cancelLabel = "Cancel"
|
|
4288
|
-
|
|
4289
|
-
|
|
4459
|
+
cancelLabel = "Cancel",
|
|
4460
|
+
fields,
|
|
4461
|
+
children,
|
|
4462
|
+
beforeFields,
|
|
4463
|
+
afterFields
|
|
4464
|
+
}) {
|
|
4465
|
+
const [open, setOpen] = React14__namespace.useState(openProp ?? false);
|
|
4466
|
+
const [formData, setFormData] = React14__namespace.useState({});
|
|
4467
|
+
const [errors, setErrors] = React14__namespace.useState({});
|
|
4468
|
+
const [isSubmitting, setIsSubmitting] = React14__namespace.useState(false);
|
|
4469
|
+
const isControlled = openProp !== void 0;
|
|
4470
|
+
const isOpen = isControlled ? openProp : open;
|
|
4471
|
+
const setIsOpen = isControlled ? onOpenChange : setOpen;
|
|
4472
|
+
React14__namespace.useEffect(() => {
|
|
4473
|
+
if (fields) {
|
|
4474
|
+
const initialData = {};
|
|
4475
|
+
fields.forEach((field) => {
|
|
4476
|
+
if (field.defaultValue !== void 0) {
|
|
4477
|
+
initialData[field.name] = field.defaultValue;
|
|
4478
|
+
}
|
|
4479
|
+
});
|
|
4480
|
+
setFormData(initialData);
|
|
4481
|
+
}
|
|
4482
|
+
}, [fields]);
|
|
4483
|
+
const handleChange = (name, value) => {
|
|
4484
|
+
setFormData((prev) => ({ ...prev, [name]: value }));
|
|
4485
|
+
if (errors[name]) {
|
|
4486
|
+
setErrors((prev) => {
|
|
4487
|
+
const next = { ...prev };
|
|
4488
|
+
delete next[name];
|
|
4489
|
+
return next;
|
|
4490
|
+
});
|
|
4491
|
+
}
|
|
4492
|
+
};
|
|
4493
|
+
const validateField = (field, value) => {
|
|
4494
|
+
if (field.required && (value === void 0 || value === null || value === "")) {
|
|
4495
|
+
return `${field.label || field.name} is required`;
|
|
4496
|
+
}
|
|
4497
|
+
if (field.validation) {
|
|
4498
|
+
return field.validation(value);
|
|
4499
|
+
}
|
|
4500
|
+
return void 0;
|
|
4501
|
+
};
|
|
4502
|
+
const handleSubmit = async (e) => {
|
|
4290
4503
|
e.preventDefault();
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4504
|
+
if (!fields) {
|
|
4505
|
+
return;
|
|
4506
|
+
}
|
|
4507
|
+
const newErrors = {};
|
|
4508
|
+
fields.forEach((field) => {
|
|
4509
|
+
const isActive = typeof field.active === "function" ? field.active(formData) : field.active !== false;
|
|
4510
|
+
if (isActive) {
|
|
4511
|
+
const error = validateField(field, formData[field.name]);
|
|
4512
|
+
if (error) {
|
|
4513
|
+
newErrors[field.name] = error;
|
|
4514
|
+
}
|
|
4515
|
+
}
|
|
4516
|
+
});
|
|
4517
|
+
if (Object.keys(newErrors).length > 0) {
|
|
4518
|
+
setErrors(newErrors);
|
|
4519
|
+
return;
|
|
4520
|
+
}
|
|
4521
|
+
setIsSubmitting(true);
|
|
4522
|
+
try {
|
|
4523
|
+
await onSubmit(formData);
|
|
4524
|
+
setIsOpen?.(false);
|
|
4525
|
+
setFormData({});
|
|
4526
|
+
setErrors({});
|
|
4527
|
+
} catch (error) {
|
|
4528
|
+
console.error("Form submission error:", error);
|
|
4529
|
+
} finally {
|
|
4530
|
+
setIsSubmitting(false);
|
|
4531
|
+
}
|
|
4532
|
+
};
|
|
4533
|
+
const renderField = (field) => {
|
|
4534
|
+
const isActive = typeof field.active === "function" ? field.active(formData) : field.active !== false;
|
|
4535
|
+
if (!isActive) return null;
|
|
4536
|
+
const value = formData[field.name] ?? field.defaultValue;
|
|
4537
|
+
const error = errors[field.name];
|
|
4538
|
+
switch (field.type) {
|
|
4539
|
+
case "text":
|
|
4540
|
+
case "email":
|
|
4541
|
+
case "url":
|
|
4542
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4543
|
+
FormInput,
|
|
4544
|
+
{
|
|
4545
|
+
label: field.label,
|
|
4546
|
+
description: field.description,
|
|
4547
|
+
error,
|
|
4548
|
+
type: field.type,
|
|
4549
|
+
placeholder: field.placeholder,
|
|
4550
|
+
value: value || "",
|
|
4551
|
+
onChange: (e) => handleChange(field.name, e.target.value),
|
|
4552
|
+
required: field.required
|
|
4553
|
+
},
|
|
4554
|
+
field.name
|
|
4555
|
+
);
|
|
4556
|
+
case "number":
|
|
4557
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4558
|
+
FormInput,
|
|
4559
|
+
{
|
|
4560
|
+
label: field.label,
|
|
4561
|
+
description: field.description,
|
|
4562
|
+
error,
|
|
4563
|
+
type: "number",
|
|
4564
|
+
placeholder: field.placeholder,
|
|
4565
|
+
value: value || "",
|
|
4566
|
+
onChange: (e) => handleChange(field.name, parseFloat(e.target.value) || 0),
|
|
4567
|
+
min: field.min,
|
|
4568
|
+
max: field.max,
|
|
4569
|
+
step: field.step,
|
|
4570
|
+
required: field.required
|
|
4571
|
+
},
|
|
4572
|
+
field.name
|
|
4573
|
+
);
|
|
4574
|
+
case "textarea":
|
|
4575
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
4576
|
+
field.label && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: field.name, className: error && "text-destructive", children: [
|
|
4577
|
+
field.label,
|
|
4578
|
+
field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
|
|
4579
|
+
] }),
|
|
4580
|
+
field.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: field.description }),
|
|
4581
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4582
|
+
Textarea,
|
|
4583
|
+
{
|
|
4584
|
+
id: field.name,
|
|
4585
|
+
placeholder: field.placeholder,
|
|
4586
|
+
value: value || "",
|
|
4587
|
+
onChange: (e) => handleChange(field.name, e.target.value),
|
|
4588
|
+
className: error && "border-destructive",
|
|
4589
|
+
required: field.required
|
|
4590
|
+
}
|
|
4591
|
+
),
|
|
4592
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", role: "alert", children: error })
|
|
4593
|
+
] }, field.name);
|
|
4594
|
+
case "select":
|
|
4595
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
4596
|
+
field.label && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: field.name, className: error && "text-destructive", children: [
|
|
4597
|
+
field.label,
|
|
4598
|
+
field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
|
|
4599
|
+
] }),
|
|
4600
|
+
field.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: field.description }),
|
|
4601
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4602
|
+
Select,
|
|
4603
|
+
{
|
|
4604
|
+
value: value || "",
|
|
4605
|
+
onValueChange: (val) => handleChange(field.name, val),
|
|
4606
|
+
children: [
|
|
4607
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: field.name, className: error && "border-destructive", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: field.placeholder || "Select..." }) }),
|
|
4608
|
+
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: field.options?.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
|
|
4609
|
+
]
|
|
4610
|
+
}
|
|
4611
|
+
),
|
|
4612
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", role: "alert", children: error })
|
|
4613
|
+
] }, field.name);
|
|
4614
|
+
case "checkbox":
|
|
4615
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
4616
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4617
|
+
Checkbox,
|
|
4618
|
+
{
|
|
4619
|
+
id: field.name,
|
|
4620
|
+
checked: value || false,
|
|
4621
|
+
onCheckedChange: (checked) => handleChange(field.name, checked)
|
|
4622
|
+
}
|
|
4623
|
+
),
|
|
4624
|
+
field.label && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: field.name, className: "cursor-pointer", children: [
|
|
4625
|
+
field.label,
|
|
4626
|
+
field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
|
|
4627
|
+
] }),
|
|
4628
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", role: "alert", children: error })
|
|
4629
|
+
] }, field.name);
|
|
4630
|
+
case "upload":
|
|
4631
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
4632
|
+
field.label && /* @__PURE__ */ jsxRuntime.jsxs(Label, { htmlFor: field.name, className: error && "text-destructive", children: [
|
|
4633
|
+
field.label,
|
|
4634
|
+
field.required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive ml-1", children: "*" })
|
|
4635
|
+
] }),
|
|
4636
|
+
field.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: field.description }),
|
|
4637
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4638
|
+
Upload,
|
|
4639
|
+
{
|
|
4640
|
+
id: field.name,
|
|
4641
|
+
accept: field.accept,
|
|
4642
|
+
multiple: field.multiple,
|
|
4643
|
+
onChange: (e) => handleChange(field.name, e.target.files),
|
|
4644
|
+
className: error && "border-destructive"
|
|
4645
|
+
}
|
|
4646
|
+
),
|
|
4647
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive", role: "alert", children: error })
|
|
4648
|
+
] }, field.name);
|
|
4649
|
+
default:
|
|
4650
|
+
return null;
|
|
4651
|
+
}
|
|
4294
4652
|
};
|
|
4295
|
-
|
|
4653
|
+
const modalContent = /* @__PURE__ */ jsxRuntime.jsx(Modal, { open: isOpen, onOpenChange: setIsOpen, children: /* @__PURE__ */ jsxRuntime.jsx(ModalContent, { "data-slot": "form-modal", children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
|
|
4296
4654
|
/* @__PURE__ */ jsxRuntime.jsx(ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(ModalTitle, { children: title }) }),
|
|
4297
|
-
children
|
|
4655
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 px-6 py-4", children: [
|
|
4656
|
+
beforeFields,
|
|
4657
|
+
fields ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fields.map((field) => renderField(field)) }) : children,
|
|
4658
|
+
afterFields
|
|
4659
|
+
] }),
|
|
4298
4660
|
/* @__PURE__ */ jsxRuntime.jsxs(ModalFooter, { children: [
|
|
4299
4661
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4300
4662
|
Button,
|
|
4301
4663
|
{
|
|
4302
4664
|
type: "button",
|
|
4303
4665
|
variant: "outline",
|
|
4304
|
-
onClick: () =>
|
|
4666
|
+
onClick: () => setIsOpen?.(false),
|
|
4667
|
+
disabled: isSubmitting,
|
|
4305
4668
|
children: cancelLabel
|
|
4306
4669
|
}
|
|
4307
4670
|
),
|
|
4308
|
-
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", children: submitLabel })
|
|
4671
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: isSubmitting, children: isSubmitting ? "Submitting..." : submitLabel })
|
|
4309
4672
|
] })
|
|
4310
4673
|
] }) }) });
|
|
4674
|
+
if (triggerLabel) {
|
|
4675
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Modal, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
4676
|
+
/* @__PURE__ */ jsxRuntime.jsx(ModalTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { ...triggerProps, children: triggerLabel }) }),
|
|
4677
|
+
modalContent
|
|
4678
|
+
] });
|
|
4679
|
+
}
|
|
4680
|
+
return modalContent;
|
|
4311
4681
|
}
|
|
4312
4682
|
function TriggerModal({
|
|
4313
4683
|
trigger,
|
|
@@ -4441,16 +4811,49 @@ function Grid({
|
|
|
4441
4811
|
}
|
|
4442
4812
|
);
|
|
4443
4813
|
}
|
|
4444
|
-
|
|
4445
|
-
|
|
4814
|
+
var cardVariants = classVarianceAuthority.cva(
|
|
4815
|
+
"bg-card text-card-foreground flex flex-col rounded-xl border shadow-sm",
|
|
4816
|
+
{
|
|
4817
|
+
variants: {
|
|
4818
|
+
variant: {
|
|
4819
|
+
minimal: "border-0 shadow-none bg-transparent",
|
|
4820
|
+
filled: "bg-muted border-0",
|
|
4821
|
+
subtle: "bg-muted/50 border-muted",
|
|
4822
|
+
outlined: "bg-transparent border-2"
|
|
4823
|
+
},
|
|
4824
|
+
size: {
|
|
4825
|
+
xs: "gap-3 py-3 text-xs",
|
|
4826
|
+
sm: "gap-4 py-4 text-sm",
|
|
4827
|
+
md: "gap-6 py-6 text-base",
|
|
4828
|
+
lg: "gap-8 py-8 text-lg"
|
|
4829
|
+
}
|
|
4830
|
+
},
|
|
4831
|
+
defaultVariants: {
|
|
4832
|
+
variant: "outlined",
|
|
4833
|
+
size: "md"
|
|
4834
|
+
}
|
|
4835
|
+
}
|
|
4836
|
+
);
|
|
4837
|
+
function Card({
|
|
4838
|
+
className,
|
|
4839
|
+
variant,
|
|
4840
|
+
size,
|
|
4841
|
+
header,
|
|
4842
|
+
footer,
|
|
4843
|
+
children,
|
|
4844
|
+
...props
|
|
4845
|
+
}) {
|
|
4846
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4446
4847
|
"div",
|
|
4447
4848
|
{
|
|
4448
4849
|
"data-slot": "card",
|
|
4449
|
-
className: cn(
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4850
|
+
className: cn(cardVariants({ variant, size }), className),
|
|
4851
|
+
...props,
|
|
4852
|
+
children: [
|
|
4853
|
+
header && /* @__PURE__ */ jsxRuntime.jsx(CardHeader, { children: header }),
|
|
4854
|
+
children,
|
|
4855
|
+
footer && /* @__PURE__ */ jsxRuntime.jsx(CardFooter, { children: footer })
|
|
4856
|
+
]
|
|
4454
4857
|
}
|
|
4455
4858
|
);
|
|
4456
4859
|
}
|
|
@@ -4723,9 +5126,29 @@ function List3({
|
|
|
4723
5126
|
}
|
|
4724
5127
|
);
|
|
4725
5128
|
}
|
|
5129
|
+
var headerVariants = classVarianceAuthority.cva(
|
|
5130
|
+
"w-full bg-background",
|
|
5131
|
+
{
|
|
5132
|
+
variants: {
|
|
5133
|
+
variant: {
|
|
5134
|
+
default: "border-b",
|
|
5135
|
+
bordered: "border-b-2"
|
|
5136
|
+
}
|
|
5137
|
+
},
|
|
5138
|
+
defaultVariants: {
|
|
5139
|
+
variant: "default"
|
|
5140
|
+
}
|
|
5141
|
+
}
|
|
5142
|
+
);
|
|
4726
5143
|
function Header2({
|
|
4727
5144
|
className,
|
|
4728
5145
|
sticky = false,
|
|
5146
|
+
variant,
|
|
5147
|
+
heading,
|
|
5148
|
+
caption,
|
|
5149
|
+
left,
|
|
5150
|
+
right,
|
|
5151
|
+
children,
|
|
4729
5152
|
...props
|
|
4730
5153
|
}) {
|
|
4731
5154
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4734,11 +5157,21 @@ function Header2({
|
|
|
4734
5157
|
as: "header",
|
|
4735
5158
|
"data-slot": "header",
|
|
4736
5159
|
className: cn(
|
|
4737
|
-
|
|
5160
|
+
headerVariants({ variant }),
|
|
4738
5161
|
sticky && "sticky top-0 z-50",
|
|
4739
5162
|
className
|
|
4740
5163
|
),
|
|
4741
|
-
...props
|
|
5164
|
+
...props,
|
|
5165
|
+
children: heading || caption || left || right ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 sm:px-6 lg:px-8 py-4", children: [
|
|
5166
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
5167
|
+
left,
|
|
5168
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
5169
|
+
heading && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-lg font-semibold", children: heading }),
|
|
5170
|
+
caption && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: caption })
|
|
5171
|
+
] })
|
|
5172
|
+
] }),
|
|
5173
|
+
right
|
|
5174
|
+
] }) : children
|
|
4742
5175
|
}
|
|
4743
5176
|
);
|
|
4744
5177
|
}
|
|
@@ -4759,21 +5192,51 @@ function Footer({
|
|
|
4759
5192
|
}
|
|
4760
5193
|
);
|
|
4761
5194
|
}
|
|
5195
|
+
var emptyScreenVariants = classVarianceAuthority.cva(
|
|
5196
|
+
"py-12",
|
|
5197
|
+
{
|
|
5198
|
+
variants: {
|
|
5199
|
+
variant: {
|
|
5200
|
+
default: "",
|
|
5201
|
+
minimal: "py-6",
|
|
5202
|
+
spacious: "py-16"
|
|
5203
|
+
},
|
|
5204
|
+
size: {
|
|
5205
|
+
sm: "text-sm",
|
|
5206
|
+
md: "text-base",
|
|
5207
|
+
lg: "text-lg"
|
|
5208
|
+
}
|
|
5209
|
+
},
|
|
5210
|
+
defaultVariants: {
|
|
5211
|
+
variant: "default",
|
|
5212
|
+
size: "md"
|
|
5213
|
+
}
|
|
5214
|
+
}
|
|
5215
|
+
);
|
|
4762
5216
|
function EmptyScreen({
|
|
4763
5217
|
title = "No items",
|
|
4764
5218
|
description,
|
|
4765
5219
|
icon,
|
|
4766
5220
|
action,
|
|
5221
|
+
variant,
|
|
5222
|
+
size,
|
|
4767
5223
|
className
|
|
4768
5224
|
}) {
|
|
4769
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
5225
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5226
|
+
Empty,
|
|
5227
|
+
{
|
|
5228
|
+
className: cn(emptyScreenVariants({ variant, size }), className),
|
|
5229
|
+
"data-slot": "empty-screen",
|
|
5230
|
+
children: [
|
|
5231
|
+
icon && /* @__PURE__ */ jsxRuntime.jsx(EmptyContent, { children: icon }),
|
|
5232
|
+
/* @__PURE__ */ jsxRuntime.jsxs(EmptyHeader, { children: [
|
|
5233
|
+
/* @__PURE__ */ jsxRuntime.jsx(EmptyTitle, { children: title }),
|
|
5234
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(EmptyDescription, { children: description })
|
|
5235
|
+
] }),
|
|
5236
|
+
action && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: action })
|
|
5237
|
+
]
|
|
5238
|
+
}
|
|
5239
|
+
);
|
|
4777
5240
|
}
|
|
4778
5241
|
function CollapsiblePanel({
|
|
4779
5242
|
title,
|