shadcn-zod-formkit 1.12.0 → 1.14.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
@@ -80,6 +80,8 @@ declare const inputFieldComp: InputTypes[];
80
80
  interface FieldProps<T = Record<string, any>> {
81
81
  name: keyof T;
82
82
  label: string;
83
+ childrenPosition?: 'up' | 'down';
84
+ children?: ReactNode | ((item: any, index: number) => ReactNode);
83
85
  defaultValue?: any;
84
86
  repeaterFields?: Array<FieldProps | FieldProps[]>;
85
87
  minItems?: number;
@@ -124,12 +126,14 @@ interface inputGroudConfig {
124
126
  textRight?: string;
125
127
  }
126
128
  interface ListConfig {
129
+ children?: ReactNode | ((item: any, index: number) => ReactNode);
127
130
  list: InputOption[] | GroupedOption[];
128
131
  optionLabel?: string;
129
132
  optionValue?: InputOption | string | number | object;
130
133
  onOptionChange: (item?: InputOption | InputOption[] | GroupedOption) => void;
131
134
  optionDescription?: string;
132
135
  selectedList?: InputOption[];
136
+ sortable?: boolean;
133
137
  }
134
138
  interface InputOption {
135
139
  id: number | string;
package/dist/index.d.ts CHANGED
@@ -80,6 +80,8 @@ declare const inputFieldComp: InputTypes[];
80
80
  interface FieldProps<T = Record<string, any>> {
81
81
  name: keyof T;
82
82
  label: string;
83
+ childrenPosition?: 'up' | 'down';
84
+ children?: ReactNode | ((item: any, index: number) => ReactNode);
83
85
  defaultValue?: any;
84
86
  repeaterFields?: Array<FieldProps | FieldProps[]>;
85
87
  minItems?: number;
@@ -124,12 +126,14 @@ interface inputGroudConfig {
124
126
  textRight?: string;
125
127
  }
126
128
  interface ListConfig {
129
+ children?: ReactNode | ((item: any, index: number) => ReactNode);
127
130
  list: InputOption[] | GroupedOption[];
128
131
  optionLabel?: string;
129
132
  optionValue?: InputOption | string | number | object;
130
133
  onOptionChange: (item?: InputOption | InputOption[] | GroupedOption) => void;
131
134
  optionDescription?: string;
132
135
  selectedList?: InputOption[];
136
+ sortable?: boolean;
133
137
  }
134
138
  interface InputOption {
135
139
  id: number | string;
package/dist/index.mjs CHANGED
@@ -26,10 +26,10 @@ 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 SliderPrimitive from '@radix-ui/react-slider';
30
+ import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
29
31
  import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable';
30
32
  import { CSS } from '@dnd-kit/utilities';
31
- import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
32
- import * as SliderPrimitive from '@radix-ui/react-slider';
33
33
  import z2 from 'zod';
34
34
  import { zodResolver } from '@hookform/resolvers/zod';
35
35
 
@@ -3960,105 +3960,6 @@ var FieldDateTimeInput = ({ form, input, isSubmitting }) => {
3960
3960
  input.name
3961
3961
  );
3962
3962
  };
3963
- var SortableListInput = class extends BaseInput {
3964
- render() {
3965
- const { input, form, isSubmitting } = this;
3966
- return /* @__PURE__ */ jsx(FieldSortableList, { form, input, isSubmitting });
3967
- }
3968
- };
3969
- var FieldSortableList = ({ form, input, isSubmitting }) => {
3970
- const [items, setItems] = useState((input.listConfig?.list ?? []).filter((item) => "name" in item));
3971
- const sensors = useSensors(
3972
- useSensor(PointerSensor),
3973
- useSensor(KeyboardSensor, {
3974
- coordinateGetter: sortableKeyboardCoordinates
3975
- })
3976
- );
3977
- const handleDragEnd = (event) => {
3978
- const { active, over } = event;
3979
- if (!over || active.id === over.id) return;
3980
- const oldIndex = items.findIndex((i) => i.id === active.id);
3981
- const newIndex = items.findIndex((i) => i.id === over.id);
3982
- const newList = arrayMove(items, oldIndex, newIndex);
3983
- setItems(newList);
3984
- form.setValue(input.name, newList);
3985
- if (input.listConfig?.onOptionChange) {
3986
- input.listConfig.onOptionChange(newList);
3987
- }
3988
- };
3989
- return /* @__PURE__ */ jsx(
3990
- FormField,
3991
- {
3992
- control: form.control,
3993
- name: input.name,
3994
- render: () => /* @__PURE__ */ jsxs(FormItem, { className: cn("space-y-2", input.className), children: [
3995
- /* @__PURE__ */ jsx(FormLabel, { children: /* @__PURE__ */ jsx("b", { children: input.label }) }),
3996
- /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx("div", { className: "border rounded-md p-3 bg-white", children: /* @__PURE__ */ jsx(
3997
- DndContext,
3998
- {
3999
- sensors,
4000
- collisionDetection: closestCenter,
4001
- onDragEnd: handleDragEnd,
4002
- children: /* @__PURE__ */ jsx(
4003
- SortableContext,
4004
- {
4005
- items: items.map((i) => i.id),
4006
- strategy: verticalListSortingStrategy,
4007
- children: items.map((item) => /* @__PURE__ */ jsx(
4008
- SortableItem,
4009
- {
4010
- id: item.id,
4011
- name: item.name,
4012
- disabled: isSubmitting
4013
- },
4014
- item.id
4015
- ))
4016
- }
4017
- )
4018
- }
4019
- ) }) }),
4020
- input.description && /* @__PURE__ */ jsx(FormDescription, { children: input.description }),
4021
- /* @__PURE__ */ jsx(FormMessage, {})
4022
- ] })
4023
- },
4024
- input.name
4025
- );
4026
- };
4027
- function SortableItem({
4028
- id,
4029
- name,
4030
- disabled
4031
- }) {
4032
- const {
4033
- attributes,
4034
- listeners,
4035
- setNodeRef,
4036
- transform,
4037
- transition,
4038
- isDragging
4039
- } = useSortable({ id });
4040
- const style = {
4041
- transform: CSS.Transform.toString(transform),
4042
- transition
4043
- };
4044
- return /* @__PURE__ */ jsx(
4045
- "div",
4046
- {
4047
- ref: setNodeRef,
4048
- style,
4049
- ...attributes,
4050
- ...listeners,
4051
- className: cn(
4052
- "flex items-center justify-between p-2 border rounded-md mb-1 bg-muted/30 cursor-grab select-none",
4053
- isDragging && "opacity-60 bg-muted/50"
4054
- ),
4055
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4056
- /* @__PURE__ */ jsx(GripVertical, { className: "w-4 h-4 opacity-70" }),
4057
- /* @__PURE__ */ jsx("span", { children: name })
4058
- ] })
4059
- }
4060
- );
4061
- }
4062
3963
  var FileInput = class extends BaseInput {
4063
3964
  render() {
4064
3965
  const { input, form, isSubmitting } = this;
@@ -4969,6 +4870,103 @@ var FieldSlider = ({ input, form, isSubmitting }) => {
4969
4870
  input.name
4970
4871
  );
4971
4872
  };
4873
+ var SortableListInput = class extends BaseInput {
4874
+ render() {
4875
+ const { input, form, isSubmitting } = this;
4876
+ const children = input.listConfig?.children ?? void 0;
4877
+ return /* @__PURE__ */ jsx(
4878
+ FieldSortableList,
4879
+ {
4880
+ form,
4881
+ input,
4882
+ isSubmitting,
4883
+ children
4884
+ }
4885
+ );
4886
+ }
4887
+ };
4888
+ function FieldSortableList({
4889
+ form,
4890
+ input,
4891
+ isSubmitting,
4892
+ children
4893
+ }) {
4894
+ const [items, setItems] = useState(() => input.listConfig?.list ?? []);
4895
+ const sortableEnabled = input.listConfig?.sortable ?? true;
4896
+ useSensors(
4897
+ useSensor(PointerSensor),
4898
+ useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
4899
+ );
4900
+ const handleDragEnd = (event) => {
4901
+ if (!sortableEnabled) return;
4902
+ const { active, over } = event;
4903
+ if (!over || active.id === over.id) return;
4904
+ const oldIndex = items.findIndex((i) => i.id === active.id);
4905
+ const newIndex = items.findIndex((i) => i.id === over.id);
4906
+ const newList = arrayMove(items, oldIndex, newIndex);
4907
+ setItems(newList);
4908
+ form.setValue(input.name, newList);
4909
+ input.listConfig?.onOptionChange?.(newList);
4910
+ };
4911
+ return /* @__PURE__ */ jsx(
4912
+ FormField,
4913
+ {
4914
+ control: form.control,
4915
+ name: input.name,
4916
+ render: () => /* @__PURE__ */ jsxs(FormItem, { className: cn("space-y-2", input.className), children: [
4917
+ input.label && /* @__PURE__ */ jsx(FormLabel, { children: /* @__PURE__ */ jsx("b", { children: input.label }) }),
4918
+ /* @__PURE__ */ jsx(FormControl, { children: sortableEnabled ? /* @__PURE__ */ jsx(DndContext, { collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: /* @__PURE__ */ jsx(
4919
+ SortableContext,
4920
+ {
4921
+ items: items.map((i) => i.id),
4922
+ strategy: verticalListSortingStrategy,
4923
+ children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: items.map((item, index) => /* @__PURE__ */ jsx(SortableWrapper, { id: item.id, children: typeof children === "function" ? children(item, index) : /* @__PURE__ */ jsx("div", { className: "p-3 border rounded-md bg-white", children: item.name }) }, item.id)) })
4924
+ }
4925
+ ) }) : /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: items.map(
4926
+ (item, index) => typeof children === "function" ? children(item, index) : /* @__PURE__ */ jsx("div", { className: "p-3 border rounded-md bg-gray-50", children: item.name }, item.id)
4927
+ ) }) }),
4928
+ input.description && /* @__PURE__ */ jsx(FormDescription, { children: input.description }),
4929
+ /* @__PURE__ */ jsx(FormMessage, {})
4930
+ ] })
4931
+ },
4932
+ input.name
4933
+ );
4934
+ }
4935
+ function SortableWrapper({
4936
+ id,
4937
+ children,
4938
+ disabled
4939
+ }) {
4940
+ const {
4941
+ attributes,
4942
+ listeners,
4943
+ setNodeRef,
4944
+ transform,
4945
+ transition,
4946
+ isDragging
4947
+ } = useSortable({ id, disabled });
4948
+ const style = {
4949
+ transform: CSS.Transform.toString(transform),
4950
+ transition
4951
+ };
4952
+ return /* @__PURE__ */ jsxs(
4953
+ "div",
4954
+ {
4955
+ ref: setNodeRef,
4956
+ style,
4957
+ ...attributes,
4958
+ ...listeners,
4959
+ className: cn(
4960
+ "flex items-center gap-2 p-2 border rounded-md mb-1 bg-muted/30 cursor-grab select-none transition-all",
4961
+ isDragging && "opacity-60 bg-muted/50 scale-[0.98]"
4962
+ ),
4963
+ children: [
4964
+ /* @__PURE__ */ jsx(GripVertical, { className: "w-4 h-4 opacity-70" }),
4965
+ /* @__PURE__ */ jsx("div", { className: "flex-1", children })
4966
+ ]
4967
+ }
4968
+ );
4969
+ }
4972
4970
  var SwitchInput = class extends BaseInput {
4973
4971
  render() {
4974
4972
  const { input, form, isSubmitting } = this;
@@ -5367,6 +5365,7 @@ var getFieldLabel = (fieldErrorKey, fields) => {
5367
5365
  const foundField = fields.find((field) => field.name === fieldErrorKey);
5368
5366
  return foundField?.label ?? fieldErrorKey;
5369
5367
  };
5368
+ var isRenderableChild = (c) => c !== void 0 && c !== null && typeof c !== "function";
5370
5369
  var FormFieldsGrid = ({
5371
5370
  fields,
5372
5371
  form,
@@ -5376,23 +5375,44 @@ var FormFieldsGrid = ({
5376
5375
  gap = "gap-2"
5377
5376
  }) => {
5378
5377
  return /* @__PURE__ */ jsx("div", { className: `w-full grid grid-cols-1 ${gap} ${className}`, children: fields.map(
5379
- (input, idx) => Array.isArray(input) ? /* @__PURE__ */ jsx(
5380
- "span",
5378
+ (inputOrGroup, idx) => Array.isArray(inputOrGroup) ? /* @__PURE__ */ jsx(
5379
+ "div",
5381
5380
  {
5382
- className: "w-full flex flex-row justify-between py-3",
5383
- children: input.map((field, subIdx) => {
5384
- if (readOnly) field.disabled = true;
5385
- return /* @__PURE__ */ jsx("div", { className: "w-full px-2", children: InputFactory.create(field, form, isPending) }, subIdx);
5381
+ className: "w-full flex flex-row items-start gap-4 py-3",
5382
+ children: inputOrGroup.map((field, subIdx) => {
5383
+ const fieldCopy = {
5384
+ ...field,
5385
+ disabled: readOnly ? true : field.disabled
5386
+ };
5387
+ const renderInlineChild = fieldCopy.childrenPosition !== "down" && isRenderableChild(fieldCopy.children);
5388
+ const renderInlineChildDown = fieldCopy.childrenPosition === "down" && isRenderableChild(fieldCopy.children);
5389
+ return /* @__PURE__ */ jsxs("div", { className: "w-full px-2", children: [
5390
+ renderInlineChild && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children }),
5391
+ InputFactory.create(fieldCopy, form, isPending),
5392
+ renderInlineChildDown && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children })
5393
+ ] }, `field-${idx}-${subIdx}`);
5386
5394
  })
5387
5395
  },
5388
5396
  `field-group-${idx}`
5389
5397
  ) : /* @__PURE__ */ jsx(
5390
- "span",
5398
+ "div",
5391
5399
  {
5392
5400
  className: "flex flex-col justify-between py-3 w-full px-2",
5393
- children: InputFactory.create(input, form, isPending)
5401
+ children: (() => {
5402
+ const fieldCopy = {
5403
+ ...inputOrGroup,
5404
+ disabled: readOnly ? true : inputOrGroup.disabled
5405
+ };
5406
+ const renderUp = fieldCopy.childrenPosition !== "down" && isRenderableChild(fieldCopy.children);
5407
+ const renderDown = fieldCopy.childrenPosition === "down" && isRenderableChild(fieldCopy.children);
5408
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5409
+ renderUp && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children }),
5410
+ InputFactory.create(fieldCopy, form, isPending),
5411
+ renderDown && /* @__PURE__ */ jsx(Fragment, { children: fieldCopy.children })
5412
+ ] });
5413
+ })()
5394
5414
  },
5395
- `field-group-${idx}`
5415
+ `field-single-${idx}`
5396
5416
  )
5397
5417
  ) });
5398
5418
  };