shadcn-zod-formkit 1.26.0 → 1.27.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.cjs CHANGED
@@ -233,13 +233,23 @@ var entitiesToGroupedOption = (data, optionValue = "name") => {
233
233
  return entities;
234
234
  };
235
235
  var handleOnChage = (event, input, field) => {
236
- console.log("\u{1F680} ~ handleOnChage ~ event:", event);
237
236
  if (event) field?.onChange(event);
238
- input.onChange?.(event);
237
+ const data = input.form?.getValues();
238
+ input.onChange?.(event, data);
239
+ if (input.onAnyFieldChange) input.onAnyFieldChange?.(data);
240
+ };
241
+ var isValidField = (input, form, defaultValue) => {
242
+ const value = defaultValue ?? form.getValues(input.name);
243
+ const fieldState = form.getFieldState(input.name);
244
+ if (input.zodType) {
245
+ const result = input.zodType.safeParse(value);
246
+ return result.success;
247
+ }
248
+ return !fieldState.error && value !== void 0 && value !== "";
239
249
  };
240
250
 
241
251
  // src/components/custom/form/inputs/base/definitions.ts
242
- var flattenFields = (fields) => {
252
+ var flattenFields = (fields, onAnyFieldChange) => {
243
253
  const result = [];
244
254
  for (const field of fields) {
245
255
  if (Array.isArray(field)) {
@@ -247,6 +257,7 @@ var flattenFields = (fields) => {
247
257
  } else if (field.fields) {
248
258
  result.push(...flattenFields(field.fields));
249
259
  } else {
260
+ if (onAnyFieldChange) field.onAnyFieldChange = (data) => onAnyFieldChange(data);
250
261
  result.push(field);
251
262
  }
252
263
  }
@@ -4204,60 +4215,82 @@ function cleanEscapedString(input) {
4204
4215
  var DateInput = class extends BaseInput {
4205
4216
  render() {
4206
4217
  const { input, form, isSubmitting } = this;
4207
- const formField = /* @__PURE__ */ jsxRuntime.jsx(
4208
- FormField,
4209
- {
4210
- control: form.control,
4211
- name: input.name,
4212
- render: ({ field }) => {
4213
- const [date, setDate] = React3__namespace.useState(
4214
- field.value ? new Date(field.value) : void 0
4215
- );
4216
- React3__namespace.useEffect(() => {
4217
- if (field.value && !date) {
4218
- setDate(new Date(field.value));
4219
- }
4220
- }, [field.value]);
4221
- const handleSelect = (selectedDate) => {
4222
- setDate(selectedDate);
4223
- handleOnChage(selectedDate, input, field);
4224
- };
4225
- return /* @__PURE__ */ jsxRuntime.jsxs(FormItem, { children: [
4226
- /* @__PURE__ */ jsxRuntime.jsx(FormLabel, { children: /* @__PURE__ */ jsxRuntime.jsx("b", { children: input.label }) }),
4227
- /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
4228
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(FormControl, { children: /* @__PURE__ */ jsxRuntime.jsxs(
4229
- Button,
4230
- {
4231
- variant: "outline",
4232
- className: cn(
4233
- "w-full justify-start text-left font-normal",
4234
- !date && "text-muted-foreground"
4235
- ),
4236
- children: [
4218
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldTimeInput, { input, form, isSubmitting });
4219
+ }
4220
+ };
4221
+ var FieldTimeInput = ({ form, input, isSubmitting }) => {
4222
+ const [isValid2, setIsValid] = React3.useState(isValidField(input, form));
4223
+ const groupConfig = input.inputGroupConfig;
4224
+ const autoValidate = groupConfig?.autoValidIcons ?? input.zodType ? true : false;
4225
+ const iconValidState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleCheck, { style: { color: "#00bf3e" } });
4226
+ const iconInvalidState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleX, { style: { color: "#ff8080" } });
4227
+ const iconLoadingState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin", style: { color: "#1e90ff" } });
4228
+ const iconsRight = groupConfig?.iconsRight ?? [];
4229
+ groupConfig?.iconsLeft ?? [];
4230
+ groupConfig?.textLeft;
4231
+ const textRight = groupConfig?.textRight;
4232
+ const formField = /* @__PURE__ */ jsxRuntime.jsx(
4233
+ FormField,
4234
+ {
4235
+ control: form.control,
4236
+ name: input.name,
4237
+ render: ({ field }) => {
4238
+ setIsValid(isValidField(input, form));
4239
+ const [date, setDate] = React3__namespace.useState(
4240
+ field.value ? new Date(field.value) : void 0
4241
+ );
4242
+ React3__namespace.useEffect(() => {
4243
+ if (field.value && !date) {
4244
+ setDate(new Date(field.value));
4245
+ setIsValid(isValidField(input, form));
4246
+ }
4247
+ }, [field.value]);
4248
+ const handleSelect = (selectedDate) => {
4249
+ setDate(selectedDate);
4250
+ handleOnChage(selectedDate, input, field);
4251
+ };
4252
+ return /* @__PURE__ */ jsxRuntime.jsxs(FormItem, { children: [
4253
+ /* @__PURE__ */ jsxRuntime.jsx(FormLabel, { children: /* @__PURE__ */ jsxRuntime.jsx("b", { children: input.label }) }),
4254
+ /* @__PURE__ */ jsxRuntime.jsxs(Popover, { children: [
4255
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx(InputGroup, { className: "flex flex-row gap-1", children: /* @__PURE__ */ jsxRuntime.jsxs(
4256
+ Button,
4257
+ {
4258
+ variant: "outline",
4259
+ className: cn(
4260
+ "w-full justify-start text-left py-0.5 ",
4261
+ !date && "text-muted-foreground"
4262
+ ),
4263
+ children: [
4264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 items-center gap-1 justify-start text-left ", children: [
4237
4265
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CalendarIcon, {}),
4238
4266
  date ? format(date, "PPP") : /* @__PURE__ */ jsxRuntime.jsx("span", { children: input.placeHolder ?? "Fecha" })
4239
- ]
4240
- }
4241
- ) }) }),
4242
- /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-auto p-0", children: /* @__PURE__ */ jsxRuntime.jsx(
4243
- Calendar,
4244
- {
4245
- mode: "single",
4246
- selected: date,
4247
- onSelect: handleSelect,
4248
- initialFocus: true
4249
- }
4250
- ) })
4251
- ] }),
4252
- /* @__PURE__ */ jsxRuntime.jsx(FormDescription, { children: input.description }),
4253
- /* @__PURE__ */ jsxRuntime.jsx(FormMessage, {})
4254
- ] });
4255
- }
4256
- },
4257
- input.name
4258
- );
4259
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: formField });
4260
- }
4267
+ ] }),
4268
+ (iconsRight.length > 0 || textRight || autoValidate) && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4269
+ textRight && /* @__PURE__ */ jsxRuntime.jsx(InputGroupText, { children: textRight }),
4270
+ iconsRight.map((IconComponent, index) => /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { size: 24, className: "w-6! h-6!" }, index)),
4271
+ autoValidate && /* @__PURE__ */ jsxRuntime.jsx("div", { children: isSubmitting ? iconLoadingState : isValid2 ? iconValidState : iconInvalidState })
4272
+ ] })
4273
+ ]
4274
+ }
4275
+ ) }) }) }),
4276
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-auto p-0", children: /* @__PURE__ */ jsxRuntime.jsx(
4277
+ Calendar,
4278
+ {
4279
+ mode: "single",
4280
+ selected: date,
4281
+ onSelect: handleSelect,
4282
+ initialFocus: true
4283
+ }
4284
+ ) })
4285
+ ] }),
4286
+ /* @__PURE__ */ jsxRuntime.jsx(FormDescription, { children: input.description }),
4287
+ /* @__PURE__ */ jsxRuntime.jsx(FormMessage, {})
4288
+ ] });
4289
+ }
4290
+ },
4291
+ input.name
4292
+ );
4293
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: formField });
4261
4294
  };
4262
4295
  var DateTimeInput = class extends BaseInput {
4263
4296
  render() {
@@ -4267,7 +4300,7 @@ var DateTimeInput = class extends BaseInput {
4267
4300
  };
4268
4301
  var FieldDateTimeInput = ({ form, input, isSubmitting }) => {
4269
4302
  const groupConfig = input.inputGroupConfig;
4270
- const autoValidate = groupConfig?.autoValidIcons;
4303
+ const autoValidate = groupConfig?.autoValidIcons ?? input.zodType ? true : false;
4271
4304
  const iconValidState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleCheck, { style: { color: "#00bf3e" } });
4272
4305
  const iconInvalidState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleX, { style: { color: "#ff8080" } });
4273
4306
  const iconLoadingState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin", style: { color: "#1e90ff" } });
@@ -4318,7 +4351,7 @@ var FieldDateTimeInput = ({ form, input, isSubmitting }) => {
4318
4351
  ),
4319
4352
  (iconsRight.length > 0 || textRight || autoValidate) && /* @__PURE__ */ jsxRuntime.jsxs(InputGroupAddon, { align: "inline-end", children: [
4320
4353
  textRight && /* @__PURE__ */ jsxRuntime.jsx(InputGroupText, { children: textRight }),
4321
- iconsRight.map((IconComponent, index) => /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { size: 20 }, index)),
4354
+ iconsRight.map((IconComponent, index) => /* @__PURE__ */ jsxRuntime.jsx(IconComponent, { size: 24 }, index)),
4322
4355
  autoValidate && /* @__PURE__ */ jsxRuntime.jsx("div", { children: isSubmitting ? iconLoadingState : isValid2 ? iconValidState : iconInvalidState })
4323
4356
  ] })
4324
4357
  ] }) }),
@@ -4531,34 +4564,40 @@ var FieldKeyValueList = ({ form, input, isSubmitting }) => {
4531
4564
  return /* @__PURE__ */ jsxRuntime.jsxs(FormItem, { className: input.className, children: [
4532
4565
  /* @__PURE__ */ jsxRuntime.jsx(FormLabel, { children: /* @__PURE__ */ jsxRuntime.jsx("b", { children: input.label }) }),
4533
4566
  /* @__PURE__ */ jsxRuntime.jsx(FormMessage, {}),
4534
- /* @__PURE__ */ jsxRuntime.jsx(FormControl, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 rounded-xl p-3 ", children: [
4567
+ /* @__PURE__ */ jsxRuntime.jsx(FormControl, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 rounded-xl ", children: [
4535
4568
  pairs.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "No pairs have been added yet." }),
4536
4569
  pairs.map((pair, index) => /* @__PURE__ */ jsxRuntime.jsxs(
4537
4570
  "div",
4538
4571
  {
4539
- className: "flex gap-2 items-center",
4572
+ className: "flex flex-row w-full gap-2 items-center py-0.5",
4540
4573
  children: [
4541
- /* @__PURE__ */ jsxRuntime.jsx(
4542
- Input,
4543
- {
4544
- placeholder: "Key",
4545
- value: pair.key,
4546
- disabled: isSubmitting,
4547
- onChange: (e) => handleChange(index, "key", e.target.value),
4548
- className: "w-1/2"
4549
- }
4550
- ),
4551
- /* @__PURE__ */ jsxRuntime.jsx(
4552
- Input,
4553
- {
4554
- placeholder: "Value",
4555
- value: pair.value,
4556
- disabled: isSubmitting,
4557
- onChange: (e) => handleChange(index, "value", e.target.value),
4558
- className: "w-1/2"
4559
- }
4560
- ),
4561
- /* @__PURE__ */ jsxRuntime.jsx(
4574
+ /* @__PURE__ */ jsxRuntime.jsxs(ButtonGroup, { className: "w-full", children: [
4575
+ /* @__PURE__ */ jsxRuntime.jsx(ButtonGroupText, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(LabelPrimitive.Label, { htmlFor: "key", children: "Key" }) }),
4576
+ /* @__PURE__ */ jsxRuntime.jsx(InputGroup, { children: /* @__PURE__ */ jsxRuntime.jsx(
4577
+ InputGroupInput,
4578
+ {
4579
+ placeholder: "Key",
4580
+ value: pair.key,
4581
+ disabled: isSubmitting,
4582
+ onChange: (e) => handleChange(index, "key", e.target.value),
4583
+ className: "flex-1"
4584
+ }
4585
+ ) })
4586
+ ] }),
4587
+ /* @__PURE__ */ jsxRuntime.jsxs(ButtonGroup, { className: "w-full", children: [
4588
+ /* @__PURE__ */ jsxRuntime.jsx(ButtonGroupText, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(LabelPrimitive.Label, { htmlFor: "value", children: "Value" }) }),
4589
+ /* @__PURE__ */ jsxRuntime.jsx(InputGroup, { children: /* @__PURE__ */ jsxRuntime.jsx(
4590
+ InputGroupInput,
4591
+ {
4592
+ placeholder: "Value",
4593
+ value: pair.value,
4594
+ disabled: isSubmitting,
4595
+ onChange: (e) => handleChange(index, "value", e.target.value),
4596
+ className: "flex-1"
4597
+ }
4598
+ ) })
4599
+ ] }),
4600
+ input.isRemovebleOption && /* @__PURE__ */ jsxRuntime.jsx(
4562
4601
  Button,
4563
4602
  {
4564
4603
  type: "button",
@@ -4696,7 +4735,7 @@ var TextInputGroup = class extends BaseInput {
4696
4735
  var FieldTextGroup = ({ form, input, isSubmitting }) => {
4697
4736
  const groupConfig = input.inputGroupConfig;
4698
4737
  const infoTooltip = input?.infoTooltip;
4699
- const autoValidate = groupConfig?.autoValidIcons;
4738
+ const autoValidate = groupConfig?.autoValidIcons ?? input.zodType ? true : false;
4700
4739
  const iconValidState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleCheck, { style: { color: "#00bf3e" } });
4701
4740
  const iconInvalidState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleX, { style: { color: "#ff8080" } });
4702
4741
  const iconLoadingState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin", style: { color: "#1e90ff" } });
@@ -4704,11 +4743,7 @@ var FieldTextGroup = ({ form, input, isSubmitting }) => {
4704
4743
  const iconsLeft = groupConfig?.iconsLeft ?? [];
4705
4744
  const textLeft = groupConfig?.textLeft;
4706
4745
  const textRight = groupConfig?.textRight;
4707
- const [isValid2, setIsValid] = React3.useState(() => {
4708
- const value = form.getValues(input.name);
4709
- const fieldState = form.getFieldState(input.name);
4710
- return !fieldState.error && value !== void 0 && value !== "";
4711
- });
4746
+ const [isValid2, setIsValid] = React3.useState(isValidField(input, form));
4712
4747
  const [showPassword, setShowPassword] = React3.useState(false);
4713
4748
  const isPasswordField = input.keyboardType === "password" /* PASSWORD */;
4714
4749
  const isNumberField = input.keyboardType === "number" /* NUMBER */;
@@ -4718,9 +4753,8 @@ var FieldTextGroup = ({ form, input, isSubmitting }) => {
4718
4753
  {
4719
4754
  control: form.control,
4720
4755
  name: input.name,
4721
- render: ({ field, fieldState }) => {
4722
- const validNow = !fieldState.error && field.value !== void 0 && field.value !== "";
4723
- if (validNow !== isValid2) setIsValid(validNow);
4756
+ render: ({ field }) => {
4757
+ setIsValid(isValidField(input, form));
4724
4758
  return /* @__PURE__ */ jsxRuntime.jsxs(FormItem, { className: input.className, children: [
4725
4759
  /* @__PURE__ */ jsxRuntime.jsx(FormLabel, { children: /* @__PURE__ */ jsxRuntime.jsx("b", { children: input.label }) }),
4726
4760
  /* @__PURE__ */ jsxRuntime.jsx(FormControl, { className: "shadow-lg", children: /* @__PURE__ */ jsxRuntime.jsxs(InputGroup, { children: [
@@ -4745,6 +4779,7 @@ var FieldTextGroup = ({ form, input, isSubmitting }) => {
4745
4779
  }
4746
4780
  handleOnChage(value, input, field);
4747
4781
  field.onChange(value);
4782
+ isValidField(input, form);
4748
4783
  }
4749
4784
  }
4750
4785
  ),
@@ -4899,7 +4934,7 @@ var FieldRepeater = ({ form, input, isSubmitting }) => {
4899
4934
  fields.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
4900
4935
  "div",
4901
4936
  {
4902
- className: "border p-3 rounded-md flex flex-col gap-3",
4937
+ className: "border p-3 rounded-md flex flex-col gap-4 py-3",
4903
4938
  children: [
4904
4939
  input.repeaterFields?.map((fieldGroup, groupIndex) => {
4905
4940
  const group = Array.isArray(fieldGroup) ? fieldGroup : [fieldGroup];
@@ -5561,7 +5596,7 @@ var FieldStringValueList = ({ form, input, isSubmitting }) => {
5561
5596
  items.map((value, index) => /* @__PURE__ */ jsxRuntime.jsxs(
5562
5597
  "div",
5563
5598
  {
5564
- className: "flex gap-2 items-center",
5599
+ className: "flex items-center gap-4 py-2",
5565
5600
  children: [
5566
5601
  /* @__PURE__ */ jsxRuntime.jsx(
5567
5602
  Input,
@@ -5822,10 +5857,10 @@ var FieldText = ({ input, form, isSubmitting }) => {
5822
5857
  var TimeInput = class extends BaseInput {
5823
5858
  render() {
5824
5859
  const { input, form, isSubmitting } = this;
5825
- return /* @__PURE__ */ jsxRuntime.jsx(FieldTimeInput, { input, form, isSubmitting });
5860
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldTimeInput2, { input, form, isSubmitting });
5826
5861
  }
5827
5862
  };
5828
- var FieldTimeInput = ({ form, input, isSubmitting }) => {
5863
+ var FieldTimeInput2 = ({ form, input, isSubmitting }) => {
5829
5864
  const groupConfig = input.inputGroupConfig;
5830
5865
  const autoValidate = groupConfig?.autoValidIcons;
5831
5866
  const iconValidState = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleCheck, { style: { color: "#00bf3e" } });
@@ -5933,6 +5968,7 @@ var inputMap = {
5933
5968
  };
5934
5969
  var InputFactory = class {
5935
5970
  static create(input, form, isSubmitting = false) {
5971
+ input.form = form;
5936
5972
  const inputType = input.inputType ?? "text" /* TEXT */;
5937
5973
  const InputClass = inputMap[inputType] ?? TextInput;
5938
5974
  const instance = new InputClass(input, form, isSubmitting);
@@ -6082,6 +6118,7 @@ var DynamicForm = ({
6082
6118
  fields,
6083
6119
  readOnly = false,
6084
6120
  record = {},
6121
+ onAnyFieldChange,
6085
6122
  onSubmit,
6086
6123
  onClick,
6087
6124
  extraValidations,
@@ -6102,7 +6139,7 @@ var DynamicForm = ({
6102
6139
  }) => {
6103
6140
  const [isPending, startTransition] = React3.useTransition();
6104
6141
  const schema = React3.useMemo(() => {
6105
- const allFields = flattenFields(fields);
6142
+ const allFields = flattenFields(fields, onAnyFieldChange);
6106
6143
  return getDynamicSchema(allFields, extraValidations);
6107
6144
  }, [fields, extraValidations]);
6108
6145
  const resolver = zod.zodResolver(schema);
@@ -6113,7 +6150,7 @@ var DynamicForm = ({
6113
6150
  });
6114
6151
  React3.useEffect(() => {
6115
6152
  form.reset(initialValues);
6116
- }, [initialValues, form]);
6153
+ }, []);
6117
6154
  const handleSubmit = (data) => {
6118
6155
  if (readOnly) return;
6119
6156
  startTransition(() => {
@@ -6585,7 +6622,7 @@ exports.FieldSimpleCheckList = FieldSimpleCheckList;
6585
6622
  exports.FieldSlider = FieldSlider;
6586
6623
  exports.FieldStringValueList = FieldStringValueList;
6587
6624
  exports.FieldTextGroup = FieldTextGroup;
6588
- exports.FieldTimeInput = FieldTimeInput;
6625
+ exports.FieldTimeInput = FieldTimeInput2;
6589
6626
  exports.FieldTitle = FieldTitle;
6590
6627
  exports.FileInput = FileInput;
6591
6628
  exports.FileMultiUploadInput = FileMultiUploadInput;
@@ -6683,6 +6720,7 @@ exports.getDynamicSchema = getDynamicSchema;
6683
6720
  exports.getFieldLabel = getFieldLabel;
6684
6721
  exports.handleOnChage = handleOnChage;
6685
6722
  exports.inputFieldComp = inputFieldComp;
6723
+ exports.isValidField = isValidField;
6686
6724
  exports.mockFields = mockFields;
6687
6725
  exports.useFormField = useFormField;
6688
6726
  exports.validationMessages = validationMessages;