shadcn-zod-formkit 1.6.0 → 1.8.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 +4 -2
- package/dist/index.cjs +229 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.mjs +230 -16
- package/dist/index.mjs.map +1 -1
- package/dist/shadcn-zod-formkit-1.8.0.tgz +0 -0
- package/package.json +2 -1
- package/dist/shadcn-zod-formkit-1.6.0.tgz +0 -0
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ yarn add shadcn-zod-formkit
|
|
|
26
26
|
You need installa shadcn basic components
|
|
27
27
|
```typescript
|
|
28
28
|
# Add Shadcn Basics
|
|
29
|
-
npx shadcn@latest add accordion alert badge button calendar card checkbox dialog popover form input label select sonner tooltip switch textarea input-otp collapsible input-group radio-group slider button-group
|
|
29
|
+
npx shadcn@latest add accordion alert badge button calendar card checkbox dialog popover form input label select sonner tooltip switch textarea input-otp collapsible input-group radio-group slider button-group command
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
|
|
@@ -116,7 +116,9 @@ const mockFields: Array<FieldProps |FieldProps[]> = [
|
|
|
116
116
|
| **Upload Multi File** | `InputTypes.FILE_MULTI_UPLOAD` |
|
|
117
117
|
| **Button Group** | `InputTypes.BUTTON_GROUP` |
|
|
118
118
|
| **Input Currency** | `InputTypes.CURRENCY` |
|
|
119
|
-
| **Input Key Value** | `InputTypes.KEY_VALUE`
|
|
119
|
+
| **Input Key Value** | `InputTypes.KEY_VALUE` |
|
|
120
|
+
| **Input Repeater** | `InputTypes.REPEATER` |
|
|
121
|
+
| **Input Multi Select** | `InputTypes.MULTI_SELECT` |
|
|
120
122
|
|
|
121
123
|
|
|
122
124
|
|
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ var nextThemes = require('next-themes');
|
|
|
26
26
|
var sonner = require('sonner');
|
|
27
27
|
var SwitchPrimitive = require('@radix-ui/react-switch');
|
|
28
28
|
var TooltipPrimitive = require('@radix-ui/react-tooltip');
|
|
29
|
+
var cmdk = require('cmdk');
|
|
29
30
|
var SliderPrimitive = require('@radix-ui/react-slider');
|
|
30
31
|
var z2 = require('zod');
|
|
31
32
|
var zod = require('@hookform/resolvers/zod');
|
|
@@ -266,9 +267,11 @@ var InputTypes = /* @__PURE__ */ ((InputTypes2) => {
|
|
|
266
267
|
InputTypes2["CURRENCY"] = "currency";
|
|
267
268
|
InputTypes2["KEY_VALUE"] = "key_value";
|
|
268
269
|
InputTypes2["REPEATER"] = "repeater";
|
|
270
|
+
InputTypes2["MULTI_SELECT"] = "multi_select";
|
|
269
271
|
return InputTypes2;
|
|
270
272
|
})(InputTypes || {});
|
|
271
273
|
var inputFieldComp = [
|
|
274
|
+
"multi_select" /* MULTI_SELECT */,
|
|
272
275
|
"repeater" /* REPEATER */,
|
|
273
276
|
"key_value" /* KEY_VALUE */,
|
|
274
277
|
"currency" /* CURRENCY */,
|
|
@@ -4044,6 +4047,201 @@ var FieldKeyValueList = ({ form, input, isSubmitting }) => {
|
|
|
4044
4047
|
}
|
|
4045
4048
|
);
|
|
4046
4049
|
};
|
|
4050
|
+
function Command({
|
|
4051
|
+
className,
|
|
4052
|
+
...props
|
|
4053
|
+
}) {
|
|
4054
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4055
|
+
cmdk.Command,
|
|
4056
|
+
{
|
|
4057
|
+
"data-slot": "command",
|
|
4058
|
+
className: cn(
|
|
4059
|
+
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
|
|
4060
|
+
className
|
|
4061
|
+
),
|
|
4062
|
+
...props
|
|
4063
|
+
}
|
|
4064
|
+
);
|
|
4065
|
+
}
|
|
4066
|
+
function CommandInput({
|
|
4067
|
+
className,
|
|
4068
|
+
...props
|
|
4069
|
+
}) {
|
|
4070
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4071
|
+
"div",
|
|
4072
|
+
{
|
|
4073
|
+
"data-slot": "command-input-wrapper",
|
|
4074
|
+
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
4075
|
+
children: [
|
|
4076
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
4077
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4078
|
+
cmdk.Command.Input,
|
|
4079
|
+
{
|
|
4080
|
+
"data-slot": "command-input",
|
|
4081
|
+
className: cn(
|
|
4082
|
+
"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
|
|
4083
|
+
className
|
|
4084
|
+
),
|
|
4085
|
+
...props
|
|
4086
|
+
}
|
|
4087
|
+
)
|
|
4088
|
+
]
|
|
4089
|
+
}
|
|
4090
|
+
);
|
|
4091
|
+
}
|
|
4092
|
+
function CommandList({
|
|
4093
|
+
className,
|
|
4094
|
+
...props
|
|
4095
|
+
}) {
|
|
4096
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4097
|
+
cmdk.Command.List,
|
|
4098
|
+
{
|
|
4099
|
+
"data-slot": "command-list",
|
|
4100
|
+
className: cn(
|
|
4101
|
+
"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
|
|
4102
|
+
className
|
|
4103
|
+
),
|
|
4104
|
+
...props
|
|
4105
|
+
}
|
|
4106
|
+
);
|
|
4107
|
+
}
|
|
4108
|
+
function CommandEmpty({
|
|
4109
|
+
...props
|
|
4110
|
+
}) {
|
|
4111
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4112
|
+
cmdk.Command.Empty,
|
|
4113
|
+
{
|
|
4114
|
+
"data-slot": "command-empty",
|
|
4115
|
+
className: "py-6 text-center text-sm",
|
|
4116
|
+
...props
|
|
4117
|
+
}
|
|
4118
|
+
);
|
|
4119
|
+
}
|
|
4120
|
+
function CommandGroup({
|
|
4121
|
+
className,
|
|
4122
|
+
...props
|
|
4123
|
+
}) {
|
|
4124
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4125
|
+
cmdk.Command.Group,
|
|
4126
|
+
{
|
|
4127
|
+
"data-slot": "command-group",
|
|
4128
|
+
className: cn(
|
|
4129
|
+
"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
|
|
4130
|
+
className
|
|
4131
|
+
),
|
|
4132
|
+
...props
|
|
4133
|
+
}
|
|
4134
|
+
);
|
|
4135
|
+
}
|
|
4136
|
+
function CommandItem({
|
|
4137
|
+
className,
|
|
4138
|
+
...props
|
|
4139
|
+
}) {
|
|
4140
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4141
|
+
cmdk.Command.Item,
|
|
4142
|
+
{
|
|
4143
|
+
"data-slot": "command-item",
|
|
4144
|
+
className: cn(
|
|
4145
|
+
"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
4146
|
+
className
|
|
4147
|
+
),
|
|
4148
|
+
...props
|
|
4149
|
+
}
|
|
4150
|
+
);
|
|
4151
|
+
}
|
|
4152
|
+
var MultiSelectInput = class extends BaseInput {
|
|
4153
|
+
render() {
|
|
4154
|
+
const { input, form, isSubmitting } = this;
|
|
4155
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FieldMultiSelect, { input, form, isSubmitting });
|
|
4156
|
+
}
|
|
4157
|
+
};
|
|
4158
|
+
var FieldMultiSelect = ({ form, input, isSubmitting }) => {
|
|
4159
|
+
const mockInputOptions = [
|
|
4160
|
+
{ id: 1, name: "PERMISO 1" },
|
|
4161
|
+
{ id: 2, name: "PERMISO 2" },
|
|
4162
|
+
{ id: 3, name: "PERMISO 3" },
|
|
4163
|
+
{ id: 4, name: "PERMISO 4" }
|
|
4164
|
+
];
|
|
4165
|
+
const lista = input?.listConfig?.list ?? mockInputOptions;
|
|
4166
|
+
const optionValue = input?.listConfig?.optionValue ?? input.optionValue ?? "id";
|
|
4167
|
+
const getValue = (item) => {
|
|
4168
|
+
if (optionValue === "name") return item[optionValue];
|
|
4169
|
+
return item.value ?? item.id;
|
|
4170
|
+
};
|
|
4171
|
+
const [open, setOpen] = React3.useState(false);
|
|
4172
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4173
|
+
FormField,
|
|
4174
|
+
{
|
|
4175
|
+
control: form.control,
|
|
4176
|
+
name: input.name,
|
|
4177
|
+
render: ({ field }) => {
|
|
4178
|
+
const selectedValues = Array.isArray(field.value) ? field.value : [];
|
|
4179
|
+
const toggleOption = (value) => {
|
|
4180
|
+
const newValues = selectedValues.includes(value) ? selectedValues.filter((v) => v !== value) : [...selectedValues, value];
|
|
4181
|
+
field.onChange(newValues);
|
|
4182
|
+
};
|
|
4183
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(FormItem, { className: "flex flex-col rounded-lg border p-3 shadow bg-blue-100/20", children: [
|
|
4184
|
+
/* @__PURE__ */ jsxRuntime.jsx(FormLabel, { children: /* @__PURE__ */ jsxRuntime.jsx("b", { children: input.label }) }),
|
|
4185
|
+
input.description && /* @__PURE__ */ jsxRuntime.jsx(FormDescription, { children: input.description }),
|
|
4186
|
+
/* @__PURE__ */ jsxRuntime.jsx(FormControl, { children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
4187
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4188
|
+
Button,
|
|
4189
|
+
{
|
|
4190
|
+
variant: "outline",
|
|
4191
|
+
role: "combobox",
|
|
4192
|
+
disabled: input.disabled || isSubmitting,
|
|
4193
|
+
className: cn(
|
|
4194
|
+
"justify-between w-full bg-black/10 dark:bg-white/10",
|
|
4195
|
+
!selectedValues.length && "text-muted-foreground"
|
|
4196
|
+
),
|
|
4197
|
+
children: [
|
|
4198
|
+
selectedValues.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: selectedValues.map((val) => {
|
|
4199
|
+
const option = lista.find(
|
|
4200
|
+
(item) => getValue(item).toString() === val
|
|
4201
|
+
);
|
|
4202
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "secondary", children: option?.name ?? val }, val);
|
|
4203
|
+
}) }) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: input.placeHolder ?? "Selecciona..." }),
|
|
4204
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "ml-2 h-4 w-4 opacity-50" })
|
|
4205
|
+
]
|
|
4206
|
+
}
|
|
4207
|
+
) }),
|
|
4208
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "p-0 w-[var(--radix-popover-trigger-width)]", children: /* @__PURE__ */ jsxRuntime.jsxs(Command, { children: [
|
|
4209
|
+
/* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: "Buscar..." }),
|
|
4210
|
+
/* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
|
|
4211
|
+
/* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No hay resultados." }),
|
|
4212
|
+
/* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: lista.map((item) => {
|
|
4213
|
+
const value = getValue(item).toString();
|
|
4214
|
+
const selected = selectedValues.includes(value);
|
|
4215
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4216
|
+
CommandItem,
|
|
4217
|
+
{
|
|
4218
|
+
onSelect: () => toggleOption(value),
|
|
4219
|
+
children: [
|
|
4220
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4221
|
+
lucideReact.Check,
|
|
4222
|
+
{
|
|
4223
|
+
className: cn(
|
|
4224
|
+
"mr-2 h-4 w-4",
|
|
4225
|
+
selected ? "opacity-100" : "opacity-0"
|
|
4226
|
+
)
|
|
4227
|
+
}
|
|
4228
|
+
),
|
|
4229
|
+
item.name
|
|
4230
|
+
]
|
|
4231
|
+
},
|
|
4232
|
+
value
|
|
4233
|
+
);
|
|
4234
|
+
}) })
|
|
4235
|
+
] })
|
|
4236
|
+
] }) })
|
|
4237
|
+
] }) }),
|
|
4238
|
+
/* @__PURE__ */ jsxRuntime.jsx(FormMessage, {})
|
|
4239
|
+
] });
|
|
4240
|
+
}
|
|
4241
|
+
},
|
|
4242
|
+
input.name
|
|
4243
|
+
);
|
|
4244
|
+
};
|
|
4047
4245
|
var TextInputGroup = class extends BaseInput {
|
|
4048
4246
|
render() {
|
|
4049
4247
|
const { input, form, isSubmitting } = this;
|
|
@@ -4841,6 +5039,7 @@ var inputMap = {
|
|
|
4841
5039
|
["currency" /* CURRENCY */]: CurrencyInput,
|
|
4842
5040
|
["key_value" /* KEY_VALUE */]: KeyValueListInput,
|
|
4843
5041
|
["repeater" /* REPEATER */]: RepeaterInput,
|
|
5042
|
+
["multi_select" /* MULTI_SELECT */]: MultiSelectInput,
|
|
4844
5043
|
//ToDos: ============================================================
|
|
4845
5044
|
["slider" /* SLIDER */]: SliderInput,
|
|
4846
5045
|
//ToDo: // PENDIENTE ... VISUALMENTE NO SE VE BIEN.!!!
|
|
@@ -4932,15 +5131,19 @@ var getFieldLabel = (fieldErrorKey, fields) => {
|
|
|
4932
5131
|
const findedField = fields.find((field) => field.name == fieldErrorKey);
|
|
4933
5132
|
return findedField?.label ?? fieldErrorKey;
|
|
4934
5133
|
};
|
|
4935
|
-
var FormFieldsGrid = ({ fields, form, isPending, className = "", gap = "gap-2" }) => {
|
|
5134
|
+
var FormFieldsGrid = ({ fields, form, isPending, readOnly, className = "", gap = "gap-2" }) => {
|
|
4936
5135
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fields.map(
|
|
4937
|
-
(input, idx) => Array.isArray(input) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-full flex flex-row justify-between py-3", children: input.map((field, subIdx) =>
|
|
5136
|
+
(input, idx) => Array.isArray(input) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-full flex flex-row justify-between py-3", children: input.map((field, subIdx) => {
|
|
5137
|
+
if (readOnly) field.disabled = readOnly;
|
|
5138
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full px-2", children: InputFactory.create(field, form, isPending) }, subIdx);
|
|
5139
|
+
}) }, `field-group-${idx}`) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-col justify-between py-3 w-full px-2", children: InputFactory.create(input, form, isPending) }, `field-group-${idx}`)
|
|
4938
5140
|
) });
|
|
4939
5141
|
};
|
|
4940
5142
|
var DynamicForm = ({
|
|
4941
5143
|
formTitle,
|
|
4942
5144
|
formSubTitle,
|
|
4943
5145
|
fields,
|
|
5146
|
+
readOnly = false,
|
|
4944
5147
|
record = {},
|
|
4945
5148
|
onSubmit,
|
|
4946
5149
|
extraValidations,
|
|
@@ -4948,7 +5151,7 @@ var DynamicForm = ({
|
|
|
4948
5151
|
errorAlertPosition = "up",
|
|
4949
5152
|
withCard = false,
|
|
4950
5153
|
submitBtnClass = "",
|
|
4951
|
-
submitBtnLabel = "
|
|
5154
|
+
submitBtnLabel = "Guardar"
|
|
4952
5155
|
}) => {
|
|
4953
5156
|
const [isPending, startTransition] = React3.useTransition();
|
|
4954
5157
|
const schema = React3.useMemo(() => getDynamicSchema(fields, extraValidations), [fields, extraValidations]);
|
|
@@ -4961,6 +5164,7 @@ var DynamicForm = ({
|
|
|
4961
5164
|
form.reset(defaultValues);
|
|
4962
5165
|
}, [defaultValues, form]);
|
|
4963
5166
|
const handleSubmit = (data) => {
|
|
5167
|
+
if (readOnly) return;
|
|
4964
5168
|
try {
|
|
4965
5169
|
startTransition(async () => {
|
|
4966
5170
|
const resp = { data, form };
|
|
@@ -4972,20 +5176,30 @@ var DynamicForm = ({
|
|
|
4972
5176
|
};
|
|
4973
5177
|
const formContent = /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
4974
5178
|
/* @__PURE__ */ jsxRuntime.jsxs(CardTitle, { className: "flex items-center gap-2 p-2 border-b", children: [
|
|
4975
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.
|
|
4976
|
-
|
|
5179
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-5 w-5" }),
|
|
5180
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
5181
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: formTitle }),
|
|
5182
|
+
formSubTitle && /* @__PURE__ */ jsxRuntime.jsx(CardDescription, { children: formSubTitle })
|
|
5183
|
+
] })
|
|
4977
5184
|
] }),
|
|
4978
5185
|
withErrorsAlert && errorAlertPosition === "up" && /* @__PURE__ */ jsxRuntime.jsx(FormErrorsAlert, { formState: form.formState, fields }),
|
|
4979
|
-
/* @__PURE__ */ jsxRuntime.jsx(Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
5186
|
+
/* @__PURE__ */ jsxRuntime.jsx(Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5187
|
+
"form",
|
|
5188
|
+
{
|
|
5189
|
+
onSubmit: form.handleSubmit(handleSubmit),
|
|
5190
|
+
className: `flex flex-col gap-2 ${readOnly ? "opacity-70 pointer-events-none select-none" : ""}`,
|
|
5191
|
+
children: [
|
|
5192
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full grid grid-cols-1", children: /* @__PURE__ */ jsxRuntime.jsx(FormFieldsGrid, { fields, form, readOnly }) }),
|
|
5193
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row gap-2 justify-end items-end", children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", size: "lg", className: submitBtnClass, disabled: isPending, children: isPending ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5194
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
|
|
5195
|
+
"Guardando..."
|
|
5196
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5197
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { className: "h-4 w-4 mr-2" }),
|
|
5198
|
+
submitBtnLabel
|
|
5199
|
+
] }) }) })
|
|
5200
|
+
]
|
|
5201
|
+
}
|
|
5202
|
+
) }),
|
|
4989
5203
|
withErrorsAlert && errorAlertPosition === "down" && /* @__PURE__ */ jsxRuntime.jsx(FormErrorsAlert, { formState: form.formState, fields })
|
|
4990
5204
|
] });
|
|
4991
5205
|
if (!withCard) return formContent;
|