shadcn-zod-formkit 1.14.0 → 1.16.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 +1 -1
- package/dist/index.cjs +180 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.mjs +180 -8
- package/dist/index.mjs.map +1 -1
- package/dist/shadcn-zod-formkit-1.16.0.tgz +0 -0
- package/package.json +4 -4
- package/dist/shadcn-zod-formkit-1.14.0.tgz +0 -0
package/dist/index.d.mts
CHANGED
|
@@ -73,13 +73,15 @@ declare enum InputTypes {
|
|
|
73
73
|
REPEATER = "repeater",
|
|
74
74
|
MULTI_SELECT = "multi_select",
|
|
75
75
|
COMBOBOX = "COMBO_BOX",
|
|
76
|
-
SORTABLE_LIST = "sortable_list"
|
|
76
|
+
SORTABLE_LIST = "sortable_list",
|
|
77
|
+
REPEATER_TABS = "repeater_tabs"
|
|
77
78
|
}
|
|
78
79
|
declare const inputFieldComp: InputTypes[];
|
|
79
80
|
|
|
80
81
|
interface FieldProps<T = Record<string, any>> {
|
|
81
82
|
name: keyof T;
|
|
82
83
|
label: string;
|
|
84
|
+
tabLabelField?: string;
|
|
83
85
|
childrenPosition?: 'up' | 'down';
|
|
84
86
|
children?: ReactNode | ((item: any, index: number) => ReactNode);
|
|
85
87
|
defaultValue?: any;
|
|
@@ -193,6 +195,8 @@ interface FormResp<T> {
|
|
|
193
195
|
data: T;
|
|
194
196
|
}
|
|
195
197
|
interface Props$4<T extends Record<string, any>> {
|
|
198
|
+
showIcon?: boolean;
|
|
199
|
+
showFormHeader?: boolean;
|
|
196
200
|
formTitle: string;
|
|
197
201
|
formSubTitle?: string;
|
|
198
202
|
readOnly?: boolean;
|
|
@@ -205,8 +209,10 @@ interface Props$4<T extends Record<string, any>> {
|
|
|
205
209
|
withCard?: boolean;
|
|
206
210
|
submitBtnLabel?: string;
|
|
207
211
|
submitBtnClass?: string;
|
|
212
|
+
children?: ReactNode;
|
|
213
|
+
childrenHeader?: ReactNode;
|
|
208
214
|
}
|
|
209
|
-
declare const DynamicForm: <T extends Record<string, any>>({ formTitle, formSubTitle, fields, readOnly, record, onSubmit, extraValidations, withErrorsAlert, errorAlertPosition, withCard, submitBtnClass, submitBtnLabel, }: Props$4<T>) => react_jsx_runtime.JSX.Element;
|
|
215
|
+
declare const DynamicForm: <T extends Record<string, any>>({ formTitle, formSubTitle, fields, readOnly, record, onSubmit, extraValidations, children, childrenHeader, showIcon, showFormHeader, withErrorsAlert, errorAlertPosition, withCard, submitBtnClass, submitBtnLabel, }: Props$4<T>) => react_jsx_runtime.JSX.Element;
|
|
210
216
|
|
|
211
217
|
declare const DynamicFormExample: () => react_jsx_runtime.JSX.Element;
|
|
212
218
|
declare const mockFields: Array<FieldProps | FieldProps[]>;
|
package/dist/index.d.ts
CHANGED
|
@@ -73,13 +73,15 @@ declare enum InputTypes {
|
|
|
73
73
|
REPEATER = "repeater",
|
|
74
74
|
MULTI_SELECT = "multi_select",
|
|
75
75
|
COMBOBOX = "COMBO_BOX",
|
|
76
|
-
SORTABLE_LIST = "sortable_list"
|
|
76
|
+
SORTABLE_LIST = "sortable_list",
|
|
77
|
+
REPEATER_TABS = "repeater_tabs"
|
|
77
78
|
}
|
|
78
79
|
declare const inputFieldComp: InputTypes[];
|
|
79
80
|
|
|
80
81
|
interface FieldProps<T = Record<string, any>> {
|
|
81
82
|
name: keyof T;
|
|
82
83
|
label: string;
|
|
84
|
+
tabLabelField?: string;
|
|
83
85
|
childrenPosition?: 'up' | 'down';
|
|
84
86
|
children?: ReactNode | ((item: any, index: number) => ReactNode);
|
|
85
87
|
defaultValue?: any;
|
|
@@ -193,6 +195,8 @@ interface FormResp<T> {
|
|
|
193
195
|
data: T;
|
|
194
196
|
}
|
|
195
197
|
interface Props$4<T extends Record<string, any>> {
|
|
198
|
+
showIcon?: boolean;
|
|
199
|
+
showFormHeader?: boolean;
|
|
196
200
|
formTitle: string;
|
|
197
201
|
formSubTitle?: string;
|
|
198
202
|
readOnly?: boolean;
|
|
@@ -205,8 +209,10 @@ interface Props$4<T extends Record<string, any>> {
|
|
|
205
209
|
withCard?: boolean;
|
|
206
210
|
submitBtnLabel?: string;
|
|
207
211
|
submitBtnClass?: string;
|
|
212
|
+
children?: ReactNode;
|
|
213
|
+
childrenHeader?: ReactNode;
|
|
208
214
|
}
|
|
209
|
-
declare const DynamicForm: <T extends Record<string, any>>({ formTitle, formSubTitle, fields, readOnly, record, onSubmit, extraValidations, withErrorsAlert, errorAlertPosition, withCard, submitBtnClass, submitBtnLabel, }: Props$4<T>) => react_jsx_runtime.JSX.Element;
|
|
215
|
+
declare const DynamicForm: <T extends Record<string, any>>({ formTitle, formSubTitle, fields, readOnly, record, onSubmit, extraValidations, children, childrenHeader, showIcon, showFormHeader, withErrorsAlert, errorAlertPosition, withCard, submitBtnClass, submitBtnLabel, }: Props$4<T>) => react_jsx_runtime.JSX.Element;
|
|
210
216
|
|
|
211
217
|
declare const DynamicFormExample: () => react_jsx_runtime.JSX.Element;
|
|
212
218
|
declare const mockFields: Array<FieldProps | FieldProps[]>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, CheckIcon, XIcon, MinusIcon, GripVerticalIcon, ChevronUpIcon, CalendarIcon, EyeOff, Eye, Pencil, Loader2, Save, Plus, MessageCircleWarning, Info, CircleCheck, CircleX, ChevronsUpDown, Check,
|
|
1
|
+
import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, CheckIcon, XIcon, MinusIcon, GripVerticalIcon, ChevronUpIcon, CalendarIcon, EyeOff, Eye, Pencil, Loader2, Save, Plus, MessageCircleWarning, Info, CircleCheck, CircleX, Trash2, ChevronsUpDown, Check, Upload, GripVertical, SearchIcon, CircleIcon } from 'lucide-react';
|
|
2
2
|
import { InfoCircledIcon } from '@radix-ui/react-icons';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -26,6 +26,7 @@ import { Toaster as Toaster$1 } from 'sonner';
|
|
|
26
26
|
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
27
27
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
28
28
|
import { Command as Command$1 } from 'cmdk';
|
|
29
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
29
30
|
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
30
31
|
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
|
|
31
32
|
import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable';
|
|
@@ -236,9 +237,11 @@ var InputTypes = /* @__PURE__ */ ((InputTypes2) => {
|
|
|
236
237
|
InputTypes2["MULTI_SELECT"] = "multi_select";
|
|
237
238
|
InputTypes2["COMBOBOX"] = "COMBO_BOX";
|
|
238
239
|
InputTypes2["SORTABLE_LIST"] = "sortable_list";
|
|
240
|
+
InputTypes2["REPEATER_TABS"] = "repeater_tabs";
|
|
239
241
|
return InputTypes2;
|
|
240
242
|
})(InputTypes || {});
|
|
241
243
|
var inputFieldComp = [
|
|
244
|
+
"repeater_tabs" /* REPEATER_TABS */,
|
|
242
245
|
"sortable_list" /* SORTABLE_LIST */,
|
|
243
246
|
"COMBO_BOX" /* COMBOBOX */,
|
|
244
247
|
"multi_select" /* MULTI_SELECT */,
|
|
@@ -4583,6 +4586,161 @@ var FieldRepeater = ({ form, input, isSubmitting }) => {
|
|
|
4583
4586
|
}
|
|
4584
4587
|
);
|
|
4585
4588
|
};
|
|
4589
|
+
function Tabs({
|
|
4590
|
+
className,
|
|
4591
|
+
...props
|
|
4592
|
+
}) {
|
|
4593
|
+
return /* @__PURE__ */ jsx(
|
|
4594
|
+
TabsPrimitive.Root,
|
|
4595
|
+
{
|
|
4596
|
+
"data-slot": "tabs",
|
|
4597
|
+
className: cn("flex flex-col gap-2", className),
|
|
4598
|
+
...props
|
|
4599
|
+
}
|
|
4600
|
+
);
|
|
4601
|
+
}
|
|
4602
|
+
function TabsList({
|
|
4603
|
+
className,
|
|
4604
|
+
...props
|
|
4605
|
+
}) {
|
|
4606
|
+
return /* @__PURE__ */ jsx(
|
|
4607
|
+
TabsPrimitive.List,
|
|
4608
|
+
{
|
|
4609
|
+
"data-slot": "tabs-list",
|
|
4610
|
+
className: cn(
|
|
4611
|
+
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
|
4612
|
+
className
|
|
4613
|
+
),
|
|
4614
|
+
...props
|
|
4615
|
+
}
|
|
4616
|
+
);
|
|
4617
|
+
}
|
|
4618
|
+
function TabsTrigger({
|
|
4619
|
+
className,
|
|
4620
|
+
...props
|
|
4621
|
+
}) {
|
|
4622
|
+
return /* @__PURE__ */ jsx(
|
|
4623
|
+
TabsPrimitive.Trigger,
|
|
4624
|
+
{
|
|
4625
|
+
"data-slot": "tabs-trigger",
|
|
4626
|
+
className: cn(
|
|
4627
|
+
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
4628
|
+
className
|
|
4629
|
+
),
|
|
4630
|
+
...props
|
|
4631
|
+
}
|
|
4632
|
+
);
|
|
4633
|
+
}
|
|
4634
|
+
function TabsContent({
|
|
4635
|
+
className,
|
|
4636
|
+
...props
|
|
4637
|
+
}) {
|
|
4638
|
+
return /* @__PURE__ */ jsx(
|
|
4639
|
+
TabsPrimitive.Content,
|
|
4640
|
+
{
|
|
4641
|
+
"data-slot": "tabs-content",
|
|
4642
|
+
className: cn("flex-1 outline-none", className),
|
|
4643
|
+
...props
|
|
4644
|
+
}
|
|
4645
|
+
);
|
|
4646
|
+
}
|
|
4647
|
+
var RepeaterTabsInput = class extends BaseInput {
|
|
4648
|
+
render() {
|
|
4649
|
+
const { input, form, isSubmitting } = this;
|
|
4650
|
+
return /* @__PURE__ */ jsx(FieldRepeaterTabs, { form, input, isSubmitting });
|
|
4651
|
+
}
|
|
4652
|
+
};
|
|
4653
|
+
var FieldRepeaterTabs = ({ form, input, isSubmitting }) => {
|
|
4654
|
+
const { control } = form;
|
|
4655
|
+
const { fields, append, remove } = useFieldArray({
|
|
4656
|
+
control,
|
|
4657
|
+
name: input.name
|
|
4658
|
+
});
|
|
4659
|
+
const [activeTab, setActiveTab] = useState(fields[0]?.id ?? "");
|
|
4660
|
+
const canAdd = !input.maxItems || fields.length < input.maxItems;
|
|
4661
|
+
const canRemove = fields.length > (input.minItems ?? 0);
|
|
4662
|
+
const handleAdd = () => {
|
|
4663
|
+
const newItem = { id: `tab-${Date.now()}` };
|
|
4664
|
+
append(newItem);
|
|
4665
|
+
setActiveTab(newItem.id);
|
|
4666
|
+
};
|
|
4667
|
+
const handleRemove = (index) => {
|
|
4668
|
+
const removedId = fields[index].id;
|
|
4669
|
+
remove(index);
|
|
4670
|
+
if (activeTab === removedId && fields.length > 1) {
|
|
4671
|
+
const nextTab = fields[index - 1] ?? fields[0];
|
|
4672
|
+
if (nextTab) setActiveTab(nextTab.id);
|
|
4673
|
+
}
|
|
4674
|
+
};
|
|
4675
|
+
return /* @__PURE__ */ jsx(
|
|
4676
|
+
FormField,
|
|
4677
|
+
{
|
|
4678
|
+
control,
|
|
4679
|
+
name: input.name,
|
|
4680
|
+
render: () => /* @__PURE__ */ jsxs(FormItem, { className: input.className, children: [
|
|
4681
|
+
input.label && /* @__PURE__ */ jsx(FormLabel, { children: /* @__PURE__ */ jsx("b", { children: input.label }) }),
|
|
4682
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxs(Tabs, { value: activeTab, onValueChange: setActiveTab, className: "w-full", children: [
|
|
4683
|
+
/* @__PURE__ */ jsxs(TabsList, { className: "flex w-full justify-start overflow-x-auto", children: [
|
|
4684
|
+
fields.map((item, index) => /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
4685
|
+
/* @__PURE__ */ jsx(TabsTrigger, { value: item.id, className: "flex items-center gap-1", children: input.tabLabelField ? form.watch(`${input.name}.${index}.${input.tabLabelField}`) || `Item ${index + 1}` : `Item ${index + 1}` }),
|
|
4686
|
+
canRemove && /* @__PURE__ */ jsx(
|
|
4687
|
+
Button,
|
|
4688
|
+
{
|
|
4689
|
+
type: "button",
|
|
4690
|
+
size: "icon",
|
|
4691
|
+
variant: "ghost",
|
|
4692
|
+
onClick: () => handleRemove(index),
|
|
4693
|
+
children: /* @__PURE__ */ jsx(Trash2, { size: 14 })
|
|
4694
|
+
}
|
|
4695
|
+
)
|
|
4696
|
+
] }, item.id)),
|
|
4697
|
+
canAdd && /* @__PURE__ */ jsxs(
|
|
4698
|
+
Button,
|
|
4699
|
+
{
|
|
4700
|
+
type: "button",
|
|
4701
|
+
variant: "secondary",
|
|
4702
|
+
size: "sm",
|
|
4703
|
+
onClick: handleAdd,
|
|
4704
|
+
disabled: isSubmitting,
|
|
4705
|
+
className: "ml-2",
|
|
4706
|
+
children: [
|
|
4707
|
+
/* @__PURE__ */ jsx(Plus, { size: 14, className: "mr-1" }),
|
|
4708
|
+
" Agregar"
|
|
4709
|
+
]
|
|
4710
|
+
}
|
|
4711
|
+
)
|
|
4712
|
+
] }),
|
|
4713
|
+
fields.map((item, index) => /* @__PURE__ */ jsx(TabsContent, { value: item.id, className: "mt-4", children: input.repeaterFields?.map((fieldGroup, groupIndex) => {
|
|
4714
|
+
const group = Array.isArray(fieldGroup) ? fieldGroup : [fieldGroup];
|
|
4715
|
+
const cols = group.length;
|
|
4716
|
+
return /* @__PURE__ */ jsx("div", { className: `grid gap-3 grid-cols-${cols}`, children: group.map((subField) => /* @__PURE__ */ jsx(
|
|
4717
|
+
FormField,
|
|
4718
|
+
{
|
|
4719
|
+
control,
|
|
4720
|
+
name: `${input.name}.${index}.${subField.name}`,
|
|
4721
|
+
render: ({ field, fieldState }) => /* @__PURE__ */ jsxs(FormItem, { className: "flex-1", children: [
|
|
4722
|
+
/* @__PURE__ */ jsx(FormLabel, { children: subField.label }),
|
|
4723
|
+
/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
|
|
4724
|
+
Input,
|
|
4725
|
+
{
|
|
4726
|
+
placeholder: subField.placeHolder,
|
|
4727
|
+
disabled: subField.disabled || isSubmitting,
|
|
4728
|
+
...field
|
|
4729
|
+
}
|
|
4730
|
+
) }),
|
|
4731
|
+
/* @__PURE__ */ jsx(FormMessage, { children: fieldState.error?.message })
|
|
4732
|
+
] })
|
|
4733
|
+
},
|
|
4734
|
+
`${input.name}.${index}.${subField.name}`
|
|
4735
|
+
)) }, groupIndex);
|
|
4736
|
+
}) }, item.id))
|
|
4737
|
+
] }) }) }),
|
|
4738
|
+
input.description && /* @__PURE__ */ jsx(FormDescription, { children: input.description }),
|
|
4739
|
+
/* @__PURE__ */ jsx(FormMessage, {})
|
|
4740
|
+
] })
|
|
4741
|
+
}
|
|
4742
|
+
);
|
|
4743
|
+
};
|
|
4586
4744
|
var SelectInput = class extends BaseInput {
|
|
4587
4745
|
render() {
|
|
4588
4746
|
const { input, form, isSubmitting } = this;
|
|
@@ -5262,6 +5420,7 @@ var inputMap = {
|
|
|
5262
5420
|
["multi_select" /* MULTI_SELECT */]: MultiSelectInput,
|
|
5263
5421
|
["COMBO_BOX" /* COMBOBOX */]: ComboboxInput,
|
|
5264
5422
|
["sortable_list" /* SORTABLE_LIST */]: SortableListInput,
|
|
5423
|
+
["repeater_tabs" /* REPEATER_TABS */]: RepeaterTabsInput,
|
|
5265
5424
|
//ToDos: ============================================================
|
|
5266
5425
|
["slider" /* SLIDER */]: SliderInput,
|
|
5267
5426
|
//ToDo: // PENDIENTE ... VISUALMENTE NO SE VE BIEN.!!!
|
|
@@ -5424,6 +5583,10 @@ var DynamicForm = ({
|
|
|
5424
5583
|
record = {},
|
|
5425
5584
|
onSubmit,
|
|
5426
5585
|
extraValidations,
|
|
5586
|
+
children,
|
|
5587
|
+
childrenHeader,
|
|
5588
|
+
showIcon = true,
|
|
5589
|
+
showFormHeader = true,
|
|
5427
5590
|
withErrorsAlert = true,
|
|
5428
5591
|
errorAlertPosition = "up",
|
|
5429
5592
|
withCard = false,
|
|
@@ -5453,12 +5616,18 @@ var DynamicForm = ({
|
|
|
5453
5616
|
}
|
|
5454
5617
|
};
|
|
5455
5618
|
const formContent = /* @__PURE__ */ jsxs("div", { children: [
|
|
5456
|
-
/* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center gap-2 p-2 border-b", children: [
|
|
5457
|
-
/* @__PURE__ */
|
|
5458
|
-
|
|
5459
|
-
/* @__PURE__ */
|
|
5460
|
-
|
|
5461
|
-
|
|
5619
|
+
showFormHeader && /* @__PURE__ */ jsxs(CardTitle, { className: "flex flex-row items-center gap-2 p-2 border-b", children: [
|
|
5620
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-2 w-full", children: [
|
|
5621
|
+
showIcon && /* @__PURE__ */ jsx(Pencil, { className: "h-5 w-5" }),
|
|
5622
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
5623
|
+
/* @__PURE__ */ jsxs(CardTitle, { className: "text-xl", children: [
|
|
5624
|
+
formTitle,
|
|
5625
|
+
" "
|
|
5626
|
+
] }),
|
|
5627
|
+
formSubTitle && /* @__PURE__ */ jsx(CardDescription, { children: formSubTitle })
|
|
5628
|
+
] })
|
|
5629
|
+
] }),
|
|
5630
|
+
childrenHeader && /* @__PURE__ */ jsx("div", { className: "flex flex-row items-center gap-2 w-full h-full", children: childrenHeader })
|
|
5462
5631
|
] }),
|
|
5463
5632
|
withErrorsAlert && errorAlertPosition === "up" && /* @__PURE__ */ jsx(FormErrorsAlert, { formState: form.formState, fields }),
|
|
5464
5633
|
/* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs(
|
|
@@ -5467,7 +5636,10 @@ var DynamicForm = ({
|
|
|
5467
5636
|
onSubmit: form.handleSubmit(handleSubmit),
|
|
5468
5637
|
className: `flex flex-col gap-2 ${readOnly ? "opacity-70 pointer-events-none select-none" : ""}`,
|
|
5469
5638
|
children: [
|
|
5470
|
-
/* @__PURE__ */
|
|
5639
|
+
/* @__PURE__ */ jsxs("div", { className: "w-full grid grid-cols-1", children: [
|
|
5640
|
+
/* @__PURE__ */ jsx(FormFieldsGrid, { fields, form, readOnly }),
|
|
5641
|
+
children && /* @__PURE__ */ jsx("div", { className: "flex flex-row items-center gap-2 w-full h-full", children })
|
|
5642
|
+
] }),
|
|
5471
5643
|
!readOnly && /* @__PURE__ */ jsx("div", { className: "flex flex-row gap-2 justify-end items-end", children: /* @__PURE__ */ jsx(Button, { type: "submit", size: "lg", className: submitBtnClass, disabled: isPending, children: isPending ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5472
5644
|
/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
5473
5645
|
"Guardando..."
|