shadcn-zod-formkit 1.22.3 → 1.23.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 CHANGED
@@ -79,8 +79,8 @@ declare enum InputTypes {
79
79
  declare const inputFieldComp: InputTypes[];
80
80
 
81
81
  declare const flattenFields: <T extends Record<string, any>>(fields: FieldConfig<T>[]) => FieldProps<T>[];
82
- type FieldConfig<T> = FieldProps<T> | FieldConfig<T>[];
83
- interface FieldProps<T = Record<string, any>> {
82
+ type FieldConfig<T, RT = Record<string, any>> = FieldProps<T, RT> | FieldConfig<T, RT>[];
83
+ interface FieldProps<T = Record<string, any>, RT = Record<string, any>> {
84
84
  name: keyof T;
85
85
  label: string;
86
86
  onChange?: (...event: any[]) => void;
@@ -89,7 +89,7 @@ interface FieldProps<T = Record<string, any>> {
89
89
  children?: ReactNode | ((item: any, index: number) => ReactNode);
90
90
  defaultValue?: any;
91
91
  direction?: 'row' | 'col';
92
- repeaterFields?: Array<FieldProps | FieldProps[]>;
92
+ repeaterFields?: FieldConfig<RT>;
93
93
  minItems?: number;
94
94
  maxItems?: number;
95
95
  currencyFormat?: Intl.NumberFormatOptions;
@@ -219,13 +219,17 @@ interface Props$4<T extends Record<string, any>> {
219
219
  withErrorsAlert?: boolean;
220
220
  errorAlertPosition?: alertPositionType;
221
221
  withCard?: boolean;
222
+ withFormWrapper?: boolean;
223
+ withSubmitBtn?: boolean;
222
224
  submitBtnLabel?: string;
225
+ submitBtnLabelSubmiting?: string;
223
226
  submitBtnClass?: string;
227
+ btnGroupDirection?: 'flex-start' | 'flex-end' | 'flex-center';
224
228
  children?: ReactNode;
225
229
  childrenHeader?: ReactNode;
226
230
  listBtnConfig?: BtnConfig[];
227
231
  }
228
- declare const DynamicForm: <T extends Record<string, any>>({ formTitle, formSubTitle, fields, readOnly, record, onSubmit, onClick, extraValidations, children, childrenHeader, showIcon, showFormHeader, withErrorsAlert, errorAlertPosition, withCard, submitBtnClass, listBtnConfig, submitBtnLabel, }: Props$4<T>) => react_jsx_runtime.JSX.Element;
232
+ declare const DynamicForm: <T extends Record<string, any>>({ formTitle, formSubTitle, fields, readOnly, record, onSubmit, onClick, extraValidations, children, childrenHeader, showIcon, showFormHeader, withErrorsAlert, errorAlertPosition, withCard, submitBtnClass, listBtnConfig, submitBtnLabel, submitBtnLabelSubmiting, withFormWrapper, btnGroupDirection, withSubmitBtn }: Props$4<T>) => react_jsx_runtime.JSX.Element;
229
233
 
230
234
  declare const DynamicFormExample: () => react_jsx_runtime.JSX.Element;
231
235
  declare const mockFields: Array<FieldProps | FieldProps[]>;
package/dist/index.d.ts CHANGED
@@ -79,8 +79,8 @@ declare enum InputTypes {
79
79
  declare const inputFieldComp: InputTypes[];
80
80
 
81
81
  declare const flattenFields: <T extends Record<string, any>>(fields: FieldConfig<T>[]) => FieldProps<T>[];
82
- type FieldConfig<T> = FieldProps<T> | FieldConfig<T>[];
83
- interface FieldProps<T = Record<string, any>> {
82
+ type FieldConfig<T, RT = Record<string, any>> = FieldProps<T, RT> | FieldConfig<T, RT>[];
83
+ interface FieldProps<T = Record<string, any>, RT = Record<string, any>> {
84
84
  name: keyof T;
85
85
  label: string;
86
86
  onChange?: (...event: any[]) => void;
@@ -89,7 +89,7 @@ interface FieldProps<T = Record<string, any>> {
89
89
  children?: ReactNode | ((item: any, index: number) => ReactNode);
90
90
  defaultValue?: any;
91
91
  direction?: 'row' | 'col';
92
- repeaterFields?: Array<FieldProps | FieldProps[]>;
92
+ repeaterFields?: FieldConfig<RT>;
93
93
  minItems?: number;
94
94
  maxItems?: number;
95
95
  currencyFormat?: Intl.NumberFormatOptions;
@@ -219,13 +219,17 @@ interface Props$4<T extends Record<string, any>> {
219
219
  withErrorsAlert?: boolean;
220
220
  errorAlertPosition?: alertPositionType;
221
221
  withCard?: boolean;
222
+ withFormWrapper?: boolean;
223
+ withSubmitBtn?: boolean;
222
224
  submitBtnLabel?: string;
225
+ submitBtnLabelSubmiting?: string;
223
226
  submitBtnClass?: string;
227
+ btnGroupDirection?: 'flex-start' | 'flex-end' | 'flex-center';
224
228
  children?: ReactNode;
225
229
  childrenHeader?: ReactNode;
226
230
  listBtnConfig?: BtnConfig[];
227
231
  }
228
- declare const DynamicForm: <T extends Record<string, any>>({ formTitle, formSubTitle, fields, readOnly, record, onSubmit, onClick, extraValidations, children, childrenHeader, showIcon, showFormHeader, withErrorsAlert, errorAlertPosition, withCard, submitBtnClass, listBtnConfig, submitBtnLabel, }: Props$4<T>) => react_jsx_runtime.JSX.Element;
232
+ declare const DynamicForm: <T extends Record<string, any>>({ formTitle, formSubTitle, fields, readOnly, record, onSubmit, onClick, extraValidations, children, childrenHeader, showIcon, showFormHeader, withErrorsAlert, errorAlertPosition, withCard, submitBtnClass, listBtnConfig, submitBtnLabel, submitBtnLabelSubmiting, withFormWrapper, btnGroupDirection, withSubmitBtn }: Props$4<T>) => react_jsx_runtime.JSX.Element;
229
233
 
230
234
  declare const DynamicFormExample: () => react_jsx_runtime.JSX.Element;
231
235
  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, Trash2, ChevronsUpDown, Check, Upload, GripVertical, SearchIcon, CircleIcon } from 'lucide-react';
1
+ import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, CheckIcon, XIcon, MinusIcon, GripVerticalIcon, ChevronUpIcon, CalendarIcon, EyeOff, Eye, Loader2, Save, Pencil, 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';
@@ -5551,49 +5551,55 @@ var getFieldLabel = (fieldErrorKey, fields) => {
5551
5551
  return foundField?.label ?? fieldErrorKey;
5552
5552
  };
5553
5553
  var isRenderableChild = (c) => c !== void 0 && c !== null && typeof c !== "function";
5554
- var isFieldProps = (f) => !Array.isArray(f);
5555
5554
  var FormFieldsGrid = ({
5556
5555
  fields,
5557
5556
  form,
5558
5557
  isPending,
5559
5558
  readOnly,
5560
5559
  className = "",
5561
- gap = "gap-4"
5560
+ gap = "gap-2"
5562
5561
  }) => {
5563
- const renderField = (field) => {
5564
- const fieldCopy = { ...field, disabled: readOnly ? true : field.disabled };
5565
- const renderUp = fieldCopy.childrenPosition !== "down" && isRenderableChild(fieldCopy.children);
5566
- const renderDown = fieldCopy.childrenPosition === "down" && isRenderableChild(fieldCopy.children);
5567
- const dirClass = fieldCopy.direction === "row" ? "flex flex-col sm:flex-row sm:items-center sm:gap-x-4 gap-y-2 flex-wrap" : "flex flex-col gap-2";
5568
- return /* @__PURE__ */ jsxs("div", { className: dirClass, children: [
5569
- renderUp && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children }),
5570
- InputFactory.create(fieldCopy, form, isPending),
5571
- renderDown && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children })
5572
- ] });
5573
- };
5574
- const renderColumn = (col, parentKey = "") => {
5575
- if (col.length === 0) return null;
5576
- const colDirection = isFieldProps(col[0]) && col[0].direction === "row" ? "flex flex-col sm:flex-row sm:items-center sm:gap-x-4 gap-y-2 flex-wrap" : "flex flex-col w-full";
5577
- return /* @__PURE__ */ jsx("div", { className: colDirection, children: col.map((item, idx) => {
5578
- if (isFieldProps(item))
5579
- return /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-[200px]", children: renderField(item) }, `${parentKey}${item.name.toString()}-${idx}`);
5580
- if (Array.isArray(item)) return renderColumn(item, `${parentKey}col${idx}-`);
5581
- return null;
5582
- }) });
5583
- };
5584
- const renderRow = (row, parentKey = "") => {
5585
- if (row.length === 0) return null;
5586
- return /* @__PURE__ */ jsx("div", { className: "w-full flex flex-col sm:flex-row sm:gap-x-4 gap-y-2 py-2 flex-wrap gap-4", children: row.map((col, idx) => {
5587
- if (isFieldProps(col)) return renderColumn([col], `${parentKey}row${idx}-`);
5588
- if (Array.isArray(col)) return renderColumn(col, `${parentKey}row${idx}-`);
5589
- return null;
5590
- }) });
5591
- };
5592
- return /* @__PURE__ */ jsx("div", { className: `w-full flex flex-col ${gap} ${className}`, children: fields.map((f, idx) => {
5593
- if (isFieldProps(f)) return /* @__PURE__ */ jsx("div", { children: renderField(f) }, `field-${f.name.toString()}-${idx}`);
5594
- if (Array.isArray(f)) return /* @__PURE__ */ jsx("div", { children: renderRow(f, `row-${idx}-`) }, `row-${idx}`);
5595
- return null;
5596
- }) });
5562
+ return /* @__PURE__ */ jsx("div", { className: `w-full grid grid-cols-1 ${gap} ${className}`, children: fields.map(
5563
+ (inputOrGroup, idx) => Array.isArray(inputOrGroup) ? /* @__PURE__ */ jsx(
5564
+ "div",
5565
+ {
5566
+ className: "w-full flex flex-row items-start gap-4 py-3",
5567
+ children: inputOrGroup.map((field, subIdx) => {
5568
+ const fieldCopy = {
5569
+ ...field,
5570
+ disabled: readOnly ? true : field.disabled
5571
+ };
5572
+ const renderInlineChild = fieldCopy.childrenPosition !== "down" && isRenderableChild(fieldCopy.children);
5573
+ const renderInlineChildDown = fieldCopy.childrenPosition === "down" && isRenderableChild(fieldCopy.children);
5574
+ return /* @__PURE__ */ jsxs("div", { className: "w-full px-2", children: [
5575
+ renderInlineChild && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children }),
5576
+ InputFactory.create(fieldCopy, form, isPending),
5577
+ renderInlineChildDown && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children })
5578
+ ] }, `field-${idx}-${subIdx}`);
5579
+ })
5580
+ },
5581
+ `field-group-${idx}`
5582
+ ) : /* @__PURE__ */ jsx(
5583
+ "div",
5584
+ {
5585
+ className: "flex flex-col justify-between py-3 w-full px-2",
5586
+ children: (() => {
5587
+ const fieldCopy = {
5588
+ ...inputOrGroup,
5589
+ disabled: readOnly ? true : inputOrGroup.disabled
5590
+ };
5591
+ const renderUp = fieldCopy.childrenPosition !== "down" && isRenderableChild(fieldCopy.children);
5592
+ const renderDown = fieldCopy.childrenPosition === "down" && isRenderableChild(fieldCopy.children);
5593
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5594
+ renderUp && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children }),
5595
+ InputFactory.create(fieldCopy, form, isPending),
5596
+ renderDown && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children })
5597
+ ] });
5598
+ })()
5599
+ },
5600
+ `field-single-${idx}`
5601
+ )
5602
+ ) });
5597
5603
  };
5598
5604
  var DynamicForm = ({
5599
5605
  formTitle,
@@ -5611,9 +5617,13 @@ var DynamicForm = ({
5611
5617
  withErrorsAlert = true,
5612
5618
  errorAlertPosition = "up",
5613
5619
  withCard = false,
5614
- submitBtnClass = "",
5620
+ submitBtnClass,
5615
5621
  listBtnConfig = [],
5616
- submitBtnLabel = "Guardar"
5622
+ submitBtnLabel = "Guardar",
5623
+ submitBtnLabelSubmiting = "Guardando...",
5624
+ withFormWrapper = true,
5625
+ btnGroupDirection = "flex-end",
5626
+ withSubmitBtn = true
5617
5627
  }) => {
5618
5628
  const [isPending, startTransition] = useTransition();
5619
5629
  const schema = useMemo(() => {
@@ -5644,6 +5654,56 @@ var DynamicForm = ({
5644
5654
  const resp = { data, form };
5645
5655
  onClick(resp);
5646
5656
  };
5657
+ const formBody = /* @__PURE__ */ jsxs(Fragment, { children: [
5658
+ /* @__PURE__ */ jsxs("div", { className: "w-full grid grid-cols-1", children: [
5659
+ /* @__PURE__ */ jsx(
5660
+ FormFieldsGrid,
5661
+ {
5662
+ fields,
5663
+ form,
5664
+ readOnly
5665
+ }
5666
+ ),
5667
+ children && /* @__PURE__ */ jsx("div", { className: "flex flex-row items-center gap-2 w-full h-full", children })
5668
+ ] }),
5669
+ /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex flex-row w-full h-full", style: {
5670
+ justifyContent: btnGroupDirection,
5671
+ // Alinea horizontalmente a la derecha
5672
+ alignItems: "center"
5673
+ // Centra verticalmente (opcional)
5674
+ }, children: [
5675
+ listBtnConfig.map((btn, key) => /* @__PURE__ */ jsx(
5676
+ Button,
5677
+ {
5678
+ type: btn.btnType,
5679
+ size: "icon-lg",
5680
+ className: submitBtnClass,
5681
+ variant: btn.variant,
5682
+ onClick: btn.onClick,
5683
+ disabled: btn.disabled,
5684
+ children: btn.label
5685
+ },
5686
+ key
5687
+ )),
5688
+ !readOnly && withSubmitBtn && /* @__PURE__ */ jsx(
5689
+ Button,
5690
+ {
5691
+ type: onClick ? "button" : "submit",
5692
+ size: "icon-lg",
5693
+ className: cn("text-lg", submitBtnClass),
5694
+ disabled: isPending,
5695
+ onClick: onClick ? handleClick : void 0,
5696
+ children: isPending ? /* @__PURE__ */ jsxs(Fragment, { children: [
5697
+ /* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 mr-2 animate-spin" }),
5698
+ submitBtnLabelSubmiting
5699
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
5700
+ /* @__PURE__ */ jsx(Save, { className: "h-5 w-5 mr-2" }),
5701
+ submitBtnLabel
5702
+ ] })
5703
+ }
5704
+ )
5705
+ ] })
5706
+ ] });
5647
5707
  const formContent = /* @__PURE__ */ jsxs("div", { children: [
5648
5708
  showFormHeader && /* @__PURE__ */ jsxs(CardTitle, { className: "flex flex-row items-center gap-2 p-2 border-b", children: [
5649
5709
  /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-2 w-full", children: [
@@ -5662,58 +5722,8 @@ var DynamicForm = ({
5662
5722
  fields
5663
5723
  }
5664
5724
  ),
5665
- /* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsxs(
5666
- "form",
5667
- {
5668
- onSubmit: form.handleSubmit(handleSubmit),
5669
- className: `flex flex-col gap-2 ${readOnly ? "opacity-70 pointer-events-none select-none" : ""}`,
5670
- children: [
5671
- /* @__PURE__ */ jsxs("div", { className: "w-full grid grid-cols-1", children: [
5672
- /* @__PURE__ */ jsx(
5673
- FormFieldsGrid,
5674
- {
5675
- fields,
5676
- form,
5677
- readOnly
5678
- }
5679
- ),
5680
- children && /* @__PURE__ */ jsx("div", { className: "flex flex-row items-center gap-2 w-full h-full", children })
5681
- ] }),
5682
- /* @__PURE__ */ jsxs(ButtonGroup, { className: "flex flex-row w-full", children: [
5683
- listBtnConfig.map((btn, key) => /* @__PURE__ */ jsx(
5684
- Button,
5685
- {
5686
- type: btn.btnType,
5687
- size: "lg",
5688
- className: submitBtnClass,
5689
- variant: btn.variant,
5690
- onClick: btn.onClick,
5691
- disabled: btn.disabled,
5692
- children: btn.label
5693
- },
5694
- key
5695
- )),
5696
- !readOnly && /* @__PURE__ */ jsx(
5697
- Button,
5698
- {
5699
- type: onClick ? "button" : "submit",
5700
- size: "lg",
5701
- className: submitBtnClass,
5702
- disabled: isPending,
5703
- onClick: onClick ? handleClick : void 0,
5704
- children: isPending ? /* @__PURE__ */ jsxs(Fragment, { children: [
5705
- /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
5706
- "Guardando..."
5707
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
5708
- /* @__PURE__ */ jsx(Save, { className: "h-4 w-4 mr-2" }),
5709
- submitBtnLabel
5710
- ] })
5711
- }
5712
- )
5713
- ] })
5714
- ]
5715
- }
5716
- ) }),
5725
+ withFormWrapper && /* @__PURE__ */ jsx(FormWrapper, { form, handleSubmit, children: formBody }),
5726
+ !withFormWrapper && formBody,
5717
5727
  withErrorsAlert && errorAlertPosition === "down" && /* @__PURE__ */ jsx(
5718
5728
  FormErrorsAlert,
5719
5729
  {
@@ -5725,6 +5735,16 @@ var DynamicForm = ({
5725
5735
  if (!withCard) return formContent;
5726
5736
  return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { children: formContent }) });
5727
5737
  };
5738
+ var FormWrapper = ({ form, handleSubmit, children, readOnly }) => {
5739
+ return /* @__PURE__ */ jsx(Form, { ...form, children: /* @__PURE__ */ jsx(
5740
+ "form",
5741
+ {
5742
+ onSubmit: form.handleSubmit(handleSubmit),
5743
+ className: `flex flex-col gap-2 ${readOnly ? "opacity-70 pointer-events-none select-none" : ""}`,
5744
+ children
5745
+ }
5746
+ ) });
5747
+ };
5728
5748
  var DynamicFormExample = () => {
5729
5749
  const record = {
5730
5750
  username: "John Doe ",