shadcn-zod-formkit 1.19.0 → 1.21.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
@@ -234,6 +234,19 @@ var entitiesToGroupedOption = (data, optionValue = "name") => {
234
234
  };
235
235
 
236
236
  // src/components/custom/form/inputs/base/definitions.ts
237
+ var flattenFields = (fields) => {
238
+ const result = [];
239
+ for (const field of fields) {
240
+ if (Array.isArray(field)) {
241
+ result.push(...flattenFields(field));
242
+ } else if (field.fields) {
243
+ result.push(...flattenFields(field.fields));
244
+ } else {
245
+ result.push(field);
246
+ }
247
+ }
248
+ return result;
249
+ };
237
250
  var TextInputType = /* @__PURE__ */ ((TextInputType2) => {
238
251
  TextInputType2["DEFAULT"] = "default";
239
252
  TextInputType2["NUMBER"] = "number";
@@ -1806,25 +1819,28 @@ function ButtonGroup({
1806
1819
  var ButtonGroupInput = class extends BaseInput {
1807
1820
  render() {
1808
1821
  const { input, form, isSubmitting } = this;
1809
- return /* @__PURE__ */ jsxRuntime.jsx(FieldButtonGroup, { input, form, isSubmitting });
1822
+ const className = input.className;
1823
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldButtonGroup, { input, form, isSubmitting, className });
1810
1824
  }
1811
1825
  };
1812
- var FieldButtonGroup = ({ input, form, isSubmitting }) => {
1826
+ var FieldButtonGroup = ({ input, form, isSubmitting, className = "w-full flex-1" }) => {
1813
1827
  const options = (input.listConfig?.list ?? []).filter((option) => "name" in option);
1814
1828
  const handleSelect = (value) => {
1815
1829
  form.setValue(input.name, value, { shouldValidate: true });
1830
+ if (input.listConfig?.onOptionChange) input.listConfig.onOptionChange(value);
1816
1831
  };
1817
1832
  const selectedValue = form.watch(input.name);
1818
- return /* @__PURE__ */ jsxRuntime.jsx(ButtonGroup, { children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
1833
+ return /* @__PURE__ */ jsxRuntime.jsx(ButtonGroup, { className: "flex flex-row w-full", children: options.map((option, key) => /* @__PURE__ */ jsxRuntime.jsx(
1819
1834
  Button,
1820
1835
  {
1821
1836
  type: "button",
1837
+ className,
1822
1838
  variant: selectedValue === option.value ? "default" : "outline",
1823
1839
  onClick: () => handleSelect(option.value),
1824
1840
  disabled: isSubmitting,
1825
1841
  children: option.label ?? option.name
1826
1842
  },
1827
- option.value
1843
+ key
1828
1844
  )) });
1829
1845
  };
1830
1846
  var CheckListInput = class extends BaseInput {
@@ -4015,7 +4031,6 @@ var FieldFile = ({ form, input, isSubmitting }) => {
4015
4031
  if (file) {
4016
4032
  const objectUrl = URL.createObjectURL(file);
4017
4033
  setPreview(objectUrl);
4018
- console.log("\u{1F680} ~ handleFileChange ~ objectUrl:", objectUrl);
4019
4034
  } else {
4020
4035
  setPreview(null);
4021
4036
  }
@@ -5491,32 +5506,12 @@ var InputFactory = class {
5491
5506
  function getDefaultValues(entity, fields) {
5492
5507
  const defaults = {};
5493
5508
  if (entity) {
5494
- for (const key in entity) {
5495
- const value = entity[key];
5496
- if (value === null || value === void 0) {
5497
- defaults[key] = "";
5498
- continue;
5499
- }
5500
- switch (typeof value) {
5501
- case "string":
5502
- defaults[key] = value;
5503
- break;
5504
- case "number":
5505
- defaults[key] = value;
5506
- break;
5507
- case "boolean":
5508
- defaults[key] = value;
5509
- break;
5510
- case "object":
5511
- defaults[key] = Array.isArray(value) ? [...value] : { ...value };
5512
- break;
5513
- default:
5514
- defaults[key] = value;
5515
- }
5516
- }
5509
+ Object.entries(entity).forEach(([key, value]) => {
5510
+ defaults[key] = value ?? "";
5511
+ });
5517
5512
  }
5518
5513
  if (fields) {
5519
- const flatFields = fields.flat();
5514
+ const flatFields = flattenFields2(fields);
5520
5515
  for (const field of flatFields) {
5521
5516
  const key = field.name;
5522
5517
  if (defaults[key] === void 0) {
@@ -5526,10 +5521,21 @@ function getDefaultValues(entity, fields) {
5526
5521
  }
5527
5522
  return defaults;
5528
5523
  }
5524
+ var flattenFields2 = (fields) => {
5525
+ const result = [];
5526
+ for (const field of fields) {
5527
+ if (Array.isArray(field)) {
5528
+ result.push(...flattenFields2(field));
5529
+ } else if (field.fields) {
5530
+ result.push(...flattenFields2(field.fields));
5531
+ } else {
5532
+ result.push(field);
5533
+ }
5534
+ }
5535
+ return result;
5536
+ };
5529
5537
  var getDynamicSchema = (fields, extraValidations) => {
5530
- const flatFields = fields.flatMap(
5531
- (f) => Array.isArray(f) ? f : [f]
5532
- );
5538
+ const flatFields = flattenFields2(fields);
5533
5539
  const shape = flatFields.reduce((acc, f) => {
5534
5540
  acc[f.name] = f.zodType ?? z2__default.default.any();
5535
5541
  return acc;
@@ -5542,12 +5548,26 @@ var getDynamicSchema = (fields, extraValidations) => {
5542
5548
  }
5543
5549
  return schema;
5544
5550
  };
5551
+ var flattenFields3 = (fields) => {
5552
+ const result = [];
5553
+ for (const field of fields) {
5554
+ if (Array.isArray(field)) {
5555
+ result.push(...flattenFields3(field));
5556
+ } else if (field.fields) {
5557
+ result.push(...flattenFields3(field.fields));
5558
+ } else {
5559
+ result.push(field);
5560
+ }
5561
+ }
5562
+ return result;
5563
+ };
5545
5564
  var FormErrorsAlert = ({
5546
5565
  formState,
5547
5566
  fields
5548
5567
  }) => {
5549
- const flatFields = fields.flatMap((f) => Array.isArray(f) ? f : [f]);
5550
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 4 }, children: Object.entries(formState.errors).length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
5568
+ const flatFields = flattenFields3(fields);
5569
+ const hasErrors = Object.keys(formState.errors).length > 0;
5570
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 4 }, children: hasErrors && /* @__PURE__ */ jsxRuntime.jsx(
5551
5571
  CustomAlert,
5552
5572
  {
5553
5573
  title: "Revisar los siguientes criterios",
@@ -5569,6 +5589,9 @@ var getFieldLabel = (fieldErrorKey, fields) => {
5569
5589
  return foundField?.label ?? fieldErrorKey;
5570
5590
  };
5571
5591
  var isRenderableChild = (c) => c !== void 0 && c !== null && typeof c !== "function";
5592
+ var isFieldProps = (f) => {
5593
+ return !Array.isArray(f);
5594
+ };
5572
5595
  var FormFieldsGrid = ({
5573
5596
  fields,
5574
5597
  form,
@@ -5577,47 +5600,54 @@ var FormFieldsGrid = ({
5577
5600
  className = "",
5578
5601
  gap = "gap-2"
5579
5602
  }) => {
5580
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full grid grid-cols-1 ${gap} ${className}`, children: fields.map(
5581
- (inputOrGroup, idx) => Array.isArray(inputOrGroup) ? /* @__PURE__ */ jsxRuntime.jsx(
5582
- "div",
5583
- {
5584
- className: "w-full flex flex-row items-start gap-4 py-3",
5585
- children: inputOrGroup.map((field, subIdx) => {
5586
- const fieldCopy = {
5587
- ...field,
5588
- disabled: readOnly ? true : field.disabled
5589
- };
5590
- const renderInlineChild = fieldCopy.childrenPosition !== "down" && isRenderableChild(fieldCopy.children);
5591
- const renderInlineChildDown = fieldCopy.childrenPosition === "down" && isRenderableChild(fieldCopy.children);
5592
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full px-2", children: [
5593
- renderInlineChild && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fieldCopy.children }),
5594
- InputFactory.create(fieldCopy, form, isPending),
5595
- renderInlineChildDown && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fieldCopy.children })
5596
- ] }, `field-${idx}-${subIdx}`);
5597
- })
5598
- },
5599
- `field-group-${idx}`
5600
- ) : /* @__PURE__ */ jsxRuntime.jsx(
5601
- "div",
5602
- {
5603
- className: "flex flex-col justify-between py-3 w-full px-2",
5604
- children: (() => {
5605
- const fieldCopy = {
5606
- ...inputOrGroup,
5607
- disabled: readOnly ? true : inputOrGroup.disabled
5608
- };
5609
- const renderUp = fieldCopy.childrenPosition !== "down" && isRenderableChild(fieldCopy.children);
5610
- const renderDown = fieldCopy.childrenPosition === "down" && isRenderableChild(fieldCopy.children);
5611
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5612
- renderUp && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fieldCopy.children }),
5613
- InputFactory.create(fieldCopy, form, isPending),
5614
- renderDown && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fieldCopy.children })
5615
- ] });
5616
- })()
5617
- },
5618
- `field-single-${idx}`
5619
- )
5620
- ) });
5603
+ const renderField = (field) => {
5604
+ const fieldCopy = {
5605
+ ...field,
5606
+ disabled: readOnly ? true : field.disabled
5607
+ };
5608
+ const renderUp = fieldCopy.childrenPosition !== "down" && isRenderableChild(fieldCopy.children);
5609
+ const renderDown = fieldCopy.childrenPosition === "down" && isRenderableChild(fieldCopy.children);
5610
+ const dirClass = fieldCopy.direction === "row" ? "flex flex-row items-center gap-4 w-full px-2" : "flex flex-col gap-2 w-full px-2";
5611
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: dirClass, children: [
5612
+ renderUp && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fieldCopy.children }),
5613
+ InputFactory.create(fieldCopy, form, isPending),
5614
+ renderDown && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fieldCopy.children })
5615
+ ] });
5616
+ };
5617
+ const renderGroup = (group, groupDirection = "row") => {
5618
+ const dirClass = groupDirection === "row" ? "flex flex-row items-start gap-4 py-3 w-full" : "flex flex-col gap-4 py-3 w-full";
5619
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: dirClass, children: group.map(
5620
+ (f, idx) => isFieldProps(f) ? renderField(f) : Array.isArray(f) ? (
5621
+ // ⚠ Solo soportamos [[FieldProps]] como subgrupo
5622
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full flex flex-row items-start gap-4", children: f.map(
5623
+ (subField) => isFieldProps(subField) ? renderField(subField) : null
5624
+ ) }, idx)
5625
+ ) : null
5626
+ ) });
5627
+ };
5628
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-full grid grid-cols-1 ${gap} ${className}`, children: fields.map((f, idx) => {
5629
+ if (isFieldProps(f)) {
5630
+ return renderField(f);
5631
+ } else if (Array.isArray(f)) {
5632
+ if (f.length > 0 && Array.isArray(f[0])) {
5633
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 py-3", children: f.map((subGroup, subIdx) => /* @__PURE__ */ jsxRuntime.jsx(
5634
+ "div",
5635
+ {
5636
+ className: "w-full flex flex-row items-start gap-4",
5637
+ children: Array.isArray(subGroup) && subGroup.map(
5638
+ (subField) => isFieldProps(subField) ? renderField(subField) : null
5639
+ )
5640
+ },
5641
+ subIdx
5642
+ )) }, idx);
5643
+ } else {
5644
+ const firstField = f[0];
5645
+ const direction = firstField?.direction ?? "row";
5646
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderGroup(f, direction) }, idx);
5647
+ }
5648
+ }
5649
+ return null;
5650
+ }) });
5621
5651
  };
5622
5652
  var DynamicForm = ({
5623
5653
  formTitle,
@@ -5640,7 +5670,10 @@ var DynamicForm = ({
5640
5670
  submitBtnLabel = "Guardar"
5641
5671
  }) => {
5642
5672
  const [isPending, startTransition] = React3.useTransition();
5643
- const schema = React3.useMemo(() => getDynamicSchema(fields, extraValidations), [fields, extraValidations]);
5673
+ const schema = React3.useMemo(() => {
5674
+ const allFields = flattenFields(fields);
5675
+ return getDynamicSchema(allFields, extraValidations);
5676
+ }, [fields, extraValidations]);
5644
5677
  const resolver = zod.zodResolver(schema);
5645
5678
  const initialValues = React3.useMemo(() => getDefaultValues(record), [record]);
5646
5679
  const form = reactHookForm.useForm({
@@ -5676,7 +5709,13 @@ var DynamicForm = ({
5676
5709
  ] }),
5677
5710
  childrenHeader && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row items-center gap-2 w-full h-full", children: childrenHeader })
5678
5711
  ] }),
5679
- withErrorsAlert && errorAlertPosition === "up" && /* @__PURE__ */ jsxRuntime.jsx(FormErrorsAlert, { formState: form.formState, fields }),
5712
+ withErrorsAlert && errorAlertPosition === "up" && /* @__PURE__ */ jsxRuntime.jsx(
5713
+ FormErrorsAlert,
5714
+ {
5715
+ formState: form.formState,
5716
+ fields
5717
+ }
5718
+ ),
5680
5719
  /* @__PURE__ */ jsxRuntime.jsx(Form, { ...form, children: /* @__PURE__ */ jsxRuntime.jsxs(
5681
5720
  "form",
5682
5721
  {
@@ -5684,10 +5723,17 @@ var DynamicForm = ({
5684
5723
  className: `flex flex-col gap-2 ${readOnly ? "opacity-70 pointer-events-none select-none" : ""}`,
5685
5724
  children: [
5686
5725
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full grid grid-cols-1", children: [
5687
- /* @__PURE__ */ jsxRuntime.jsx(FormFieldsGrid, { fields, form, readOnly }),
5726
+ /* @__PURE__ */ jsxRuntime.jsx(
5727
+ FormFieldsGrid,
5728
+ {
5729
+ fields,
5730
+ form,
5731
+ readOnly
5732
+ }
5733
+ ),
5688
5734
  children && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row items-center gap-2 w-full h-full", children })
5689
5735
  ] }),
5690
- /* @__PURE__ */ jsxRuntime.jsxs(ButtonGroup, { className: "flex flex-row w-full", children: [
5736
+ /* @__PURE__ */ jsxRuntime.jsxs(ButtonGroup, { className: "flex flex-row w-full", children: [
5691
5737
  listBtnConfig.map((btn, key) => /* @__PURE__ */ jsxRuntime.jsx(
5692
5738
  Button,
5693
5739
  {
@@ -5722,7 +5768,13 @@ var DynamicForm = ({
5722
5768
  ]
5723
5769
  }
5724
5770
  ) }),
5725
- withErrorsAlert && errorAlertPosition === "down" && /* @__PURE__ */ jsxRuntime.jsx(FormErrorsAlert, { formState: form.formState, fields })
5771
+ withErrorsAlert && errorAlertPosition === "down" && /* @__PURE__ */ jsxRuntime.jsx(
5772
+ FormErrorsAlert,
5773
+ {
5774
+ formState: form.formState,
5775
+ fields: fields.flatMap((f) => Array.isArray(f) ? f : [f])
5776
+ }
5777
+ )
5726
5778
  ] });
5727
5779
  if (!withCard) return formContent;
5728
5780
  return /* @__PURE__ */ jsxRuntime.jsx(Card, { children: /* @__PURE__ */ jsxRuntime.jsx(CardContent, { children: formContent }) });
@@ -6000,6 +6052,7 @@ exports.entitiesToGroupedOption = entitiesToGroupedOption;
6000
6052
  exports.entitiesToInputOption = entitiesToInputOption;
6001
6053
  exports.entityToGroupedOption = entityToGroupedOption;
6002
6054
  exports.entityToInputOption = entityToInputOption;
6055
+ exports.flattenFields = flattenFields;
6003
6056
  exports.getDefaultValues = getDefaultValues;
6004
6057
  exports.getDynamicSchema = getDynamicSchema;
6005
6058
  exports.getFieldLabel = getFieldLabel;