shadcn-zod-formkit 1.10.0 → 1.12.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
@@ -27,6 +27,9 @@ var sonner = require('sonner');
27
27
  var SwitchPrimitive = require('@radix-ui/react-switch');
28
28
  var TooltipPrimitive = require('@radix-ui/react-tooltip');
29
29
  var cmdk = require('cmdk');
30
+ var sortable = require('@dnd-kit/sortable');
31
+ var utilities = require('@dnd-kit/utilities');
32
+ var core = require('@dnd-kit/core');
30
33
  var SliderPrimitive = require('@radix-ui/react-slider');
31
34
  var z2 = require('zod');
32
35
  var zod = require('@hookform/resolvers/zod');
@@ -268,9 +271,13 @@ var InputTypes = /* @__PURE__ */ ((InputTypes2) => {
268
271
  InputTypes2["KEY_VALUE"] = "key_value";
269
272
  InputTypes2["REPEATER"] = "repeater";
270
273
  InputTypes2["MULTI_SELECT"] = "multi_select";
274
+ InputTypes2["COMBOBOX"] = "COMBO_BOX";
275
+ InputTypes2["SORTABLE_LIST"] = "sortable_list";
271
276
  return InputTypes2;
272
277
  })(InputTypes || {});
273
278
  var inputFieldComp = [
279
+ "sortable_list" /* SORTABLE_LIST */,
280
+ "COMBO_BOX" /* COMBOBOX */,
274
281
  "multi_select" /* MULTI_SELECT */,
275
282
  "repeater" /* REPEATER */,
276
283
  "key_value" /* KEY_VALUE */,
@@ -1986,6 +1993,210 @@ var ColorComp = React3__namespace.default.forwardRef(
1986
1993
  ] });
1987
1994
  }
1988
1995
  );
1996
+ function Command({
1997
+ className,
1998
+ ...props
1999
+ }) {
2000
+ return /* @__PURE__ */ jsxRuntime.jsx(
2001
+ cmdk.Command,
2002
+ {
2003
+ "data-slot": "command",
2004
+ className: cn(
2005
+ "bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
2006
+ className
2007
+ ),
2008
+ ...props
2009
+ }
2010
+ );
2011
+ }
2012
+ function CommandInput({
2013
+ className,
2014
+ ...props
2015
+ }) {
2016
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2017
+ "div",
2018
+ {
2019
+ "data-slot": "command-input-wrapper",
2020
+ className: "flex h-9 items-center gap-2 border-b px-3",
2021
+ children: [
2022
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
2023
+ /* @__PURE__ */ jsxRuntime.jsx(
2024
+ cmdk.Command.Input,
2025
+ {
2026
+ "data-slot": "command-input",
2027
+ className: cn(
2028
+ "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",
2029
+ className
2030
+ ),
2031
+ ...props
2032
+ }
2033
+ )
2034
+ ]
2035
+ }
2036
+ );
2037
+ }
2038
+ function CommandList({
2039
+ className,
2040
+ ...props
2041
+ }) {
2042
+ return /* @__PURE__ */ jsxRuntime.jsx(
2043
+ cmdk.Command.List,
2044
+ {
2045
+ "data-slot": "command-list",
2046
+ className: cn(
2047
+ "max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
2048
+ className
2049
+ ),
2050
+ ...props
2051
+ }
2052
+ );
2053
+ }
2054
+ function CommandEmpty({
2055
+ ...props
2056
+ }) {
2057
+ return /* @__PURE__ */ jsxRuntime.jsx(
2058
+ cmdk.Command.Empty,
2059
+ {
2060
+ "data-slot": "command-empty",
2061
+ className: "py-6 text-center text-sm",
2062
+ ...props
2063
+ }
2064
+ );
2065
+ }
2066
+ function CommandGroup({
2067
+ className,
2068
+ ...props
2069
+ }) {
2070
+ return /* @__PURE__ */ jsxRuntime.jsx(
2071
+ cmdk.Command.Group,
2072
+ {
2073
+ "data-slot": "command-group",
2074
+ className: cn(
2075
+ "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",
2076
+ className
2077
+ ),
2078
+ ...props
2079
+ }
2080
+ );
2081
+ }
2082
+ function CommandItem({
2083
+ className,
2084
+ ...props
2085
+ }) {
2086
+ return /* @__PURE__ */ jsxRuntime.jsx(
2087
+ cmdk.Command.Item,
2088
+ {
2089
+ "data-slot": "command-item",
2090
+ className: cn(
2091
+ "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",
2092
+ className
2093
+ ),
2094
+ ...props
2095
+ }
2096
+ );
2097
+ }
2098
+ var ComboboxInput = class extends BaseInput {
2099
+ render() {
2100
+ const { input, form, isSubmitting } = this;
2101
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldCombobox, { input, form, isSubmitting });
2102
+ }
2103
+ };
2104
+ var FieldCombobox = ({ form, input, isSubmitting }) => {
2105
+ const [open, setOpen] = React3__namespace.useState(false);
2106
+ const [options, setOptions] = React3__namespace.useState(
2107
+ () => input.listConfig?.list?.length ? input.listConfig.list : []
2108
+ );
2109
+ const optionValue = input?.listConfig?.optionValue ?? input.optionValue ?? "id";
2110
+ const [value, setValue] = React3__namespace.useState(input.value?.toString() ?? "");
2111
+ React3__namespace.useEffect(() => {
2112
+ const dependsOn = input.dependsOn;
2113
+ if (!dependsOn || !input.loadOptions) return;
2114
+ const subscription = form.watch(async (values) => {
2115
+ const parentValue = values[dependsOn];
2116
+ if (parentValue) {
2117
+ const loader = input.loadOptions;
2118
+ const newOptions = await loader(parentValue);
2119
+ setOptions(newOptions);
2120
+ form.setValue(input.name, "");
2121
+ setValue("");
2122
+ } else {
2123
+ setOptions([]);
2124
+ }
2125
+ });
2126
+ return () => subscription.unsubscribe?.();
2127
+ }, [form, input.loadOptions, input.dependsOn]);
2128
+ React3__namespace.useEffect(() => {
2129
+ const currentValue = form.getValues(input.name);
2130
+ if (!currentValue && input.value) {
2131
+ form.setValue(input.name, input.value);
2132
+ setValue(input.value.toString());
2133
+ }
2134
+ }, [form, input.name, input.value]);
2135
+ const getValue = (item) => (optionValue === "name" ? item.name : item.value?.toString() ?? item.id?.toString()) ?? "";
2136
+ const selectedOption = options.find((o) => getValue(o) === value);
2137
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
2138
+ input.label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "font-medium text-sm", children: input.label }),
2139
+ /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
2140
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
2141
+ Button,
2142
+ {
2143
+ disabled: input.disabled || isSubmitting,
2144
+ variant: "outline",
2145
+ role: "combobox",
2146
+ "aria-expanded": open,
2147
+ className: "w-[60%] justify-between bg-black/10 dark:bg-white/25",
2148
+ children: [
2149
+ selectedOption ? selectedOption.name : input.placeHolder ?? "Seleccionar...",
2150
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, { className: "opacity-50" })
2151
+ ]
2152
+ }
2153
+ ) }),
2154
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverContent, { className: "w-[60%] p-0", children: /* @__PURE__ */ jsxRuntime.jsxs(
2155
+ Command,
2156
+ {
2157
+ filter: (value2, search) => {
2158
+ const option = options.find((o) => getValue(o) === value2);
2159
+ return option?.name?.toLowerCase().includes(search.toLowerCase()) ? 1 : 0;
2160
+ },
2161
+ children: [
2162
+ /* @__PURE__ */ jsxRuntime.jsx(CommandInput, { placeholder: `Buscar ${input.label?.toLowerCase()}...`, className: "h-9" }),
2163
+ /* @__PURE__ */ jsxRuntime.jsxs(CommandList, { children: [
2164
+ /* @__PURE__ */ jsxRuntime.jsx(CommandEmpty, { children: "No se encontraron resultados." }),
2165
+ /* @__PURE__ */ jsxRuntime.jsx(CommandGroup, { children: options.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
2166
+ CommandItem,
2167
+ {
2168
+ value: getValue(item),
2169
+ onSelect: (currentValue) => {
2170
+ const newValue = currentValue === value ? "" : currentValue;
2171
+ setValue(newValue);
2172
+ form.setValue(input.name, newValue);
2173
+ input.listConfig?.onOptionChange?.(
2174
+ options.find((o) => getValue(o) === newValue)
2175
+ );
2176
+ setOpen(false);
2177
+ },
2178
+ children: [
2179
+ item.name,
2180
+ /* @__PURE__ */ jsxRuntime.jsx(
2181
+ lucideReact.Check,
2182
+ {
2183
+ className: cn(
2184
+ "ml-auto",
2185
+ value === getValue(item) ? "opacity-100" : "opacity-0"
2186
+ )
2187
+ }
2188
+ )
2189
+ ]
2190
+ },
2191
+ item.id
2192
+ )) })
2193
+ ] })
2194
+ ]
2195
+ }
2196
+ ) })
2197
+ ] })
2198
+ ] });
2199
+ };
1989
2200
  var CurrencyInput = class extends BaseInput {
1990
2201
  render() {
1991
2202
  const { input, form, isSubmitting } = this;
@@ -3786,6 +3997,105 @@ var FieldDateTimeInput = ({ form, input, isSubmitting }) => {
3786
3997
  input.name
3787
3998
  );
3788
3999
  };
4000
+ var SortableListInput = class extends BaseInput {
4001
+ render() {
4002
+ const { input, form, isSubmitting } = this;
4003
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldSortableList, { form, input, isSubmitting });
4004
+ }
4005
+ };
4006
+ var FieldSortableList = ({ form, input, isSubmitting }) => {
4007
+ const [items, setItems] = React3.useState((input.listConfig?.list ?? []).filter((item) => "name" in item));
4008
+ const sensors = core.useSensors(
4009
+ core.useSensor(core.PointerSensor),
4010
+ core.useSensor(core.KeyboardSensor, {
4011
+ coordinateGetter: sortable.sortableKeyboardCoordinates
4012
+ })
4013
+ );
4014
+ const handleDragEnd = (event) => {
4015
+ const { active, over } = event;
4016
+ if (!over || active.id === over.id) return;
4017
+ const oldIndex = items.findIndex((i) => i.id === active.id);
4018
+ const newIndex = items.findIndex((i) => i.id === over.id);
4019
+ const newList = sortable.arrayMove(items, oldIndex, newIndex);
4020
+ setItems(newList);
4021
+ form.setValue(input.name, newList);
4022
+ if (input.listConfig?.onOptionChange) {
4023
+ input.listConfig.onOptionChange(newList);
4024
+ }
4025
+ };
4026
+ return /* @__PURE__ */ jsxRuntime.jsx(
4027
+ FormField,
4028
+ {
4029
+ control: form.control,
4030
+ name: input.name,
4031
+ render: () => /* @__PURE__ */ jsxRuntime.jsxs(FormItem, { className: cn("space-y-2", input.className), children: [
4032
+ /* @__PURE__ */ jsxRuntime.jsx(FormLabel, { children: /* @__PURE__ */ jsxRuntime.jsx("b", { children: input.label }) }),
4033
+ /* @__PURE__ */ jsxRuntime.jsx(FormControl, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border rounded-md p-3 bg-white", children: /* @__PURE__ */ jsxRuntime.jsx(
4034
+ core.DndContext,
4035
+ {
4036
+ sensors,
4037
+ collisionDetection: core.closestCenter,
4038
+ onDragEnd: handleDragEnd,
4039
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4040
+ sortable.SortableContext,
4041
+ {
4042
+ items: items.map((i) => i.id),
4043
+ strategy: sortable.verticalListSortingStrategy,
4044
+ children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
4045
+ SortableItem,
4046
+ {
4047
+ id: item.id,
4048
+ name: item.name,
4049
+ disabled: isSubmitting
4050
+ },
4051
+ item.id
4052
+ ))
4053
+ }
4054
+ )
4055
+ }
4056
+ ) }) }),
4057
+ input.description && /* @__PURE__ */ jsxRuntime.jsx(FormDescription, { children: input.description }),
4058
+ /* @__PURE__ */ jsxRuntime.jsx(FormMessage, {})
4059
+ ] })
4060
+ },
4061
+ input.name
4062
+ );
4063
+ };
4064
+ function SortableItem({
4065
+ id,
4066
+ name,
4067
+ disabled
4068
+ }) {
4069
+ const {
4070
+ attributes,
4071
+ listeners,
4072
+ setNodeRef,
4073
+ transform,
4074
+ transition,
4075
+ isDragging
4076
+ } = sortable.useSortable({ id });
4077
+ const style = {
4078
+ transform: utilities.CSS.Transform.toString(transform),
4079
+ transition
4080
+ };
4081
+ return /* @__PURE__ */ jsxRuntime.jsx(
4082
+ "div",
4083
+ {
4084
+ ref: setNodeRef,
4085
+ style,
4086
+ ...attributes,
4087
+ ...listeners,
4088
+ className: cn(
4089
+ "flex items-center justify-between p-2 border rounded-md mb-1 bg-muted/30 cursor-grab select-none",
4090
+ isDragging && "opacity-60 bg-muted/50"
4091
+ ),
4092
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
4093
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GripVertical, { className: "w-4 h-4 opacity-70" }),
4094
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: name })
4095
+ ] })
4096
+ }
4097
+ );
4098
+ }
3789
4099
  var FileInput = class extends BaseInput {
3790
4100
  render() {
3791
4101
  const { input, form, isSubmitting } = this;
@@ -4047,108 +4357,6 @@ var FieldKeyValueList = ({ form, input, isSubmitting }) => {
4047
4357
  }
4048
4358
  );
4049
4359
  };
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
4360
  var MultiSelectInput = class extends BaseInput {
4153
4361
  render() {
4154
4362
  const { input, form, isSubmitting } = this;
@@ -5091,6 +5299,8 @@ var inputMap = {
5091
5299
  ["key_value" /* KEY_VALUE */]: KeyValueListInput,
5092
5300
  ["repeater" /* REPEATER */]: RepeaterInput,
5093
5301
  ["multi_select" /* MULTI_SELECT */]: MultiSelectInput,
5302
+ ["COMBO_BOX" /* COMBOBOX */]: ComboboxInput,
5303
+ ["sortable_list" /* SORTABLE_LIST */]: SortableListInput,
5094
5304
  //ToDos: ============================================================
5095
5305
  ["slider" /* SLIDER */]: SliderInput,
5096
5306
  //ToDo: // PENDIENTE ... VISUALMENTE NO SE VE BIEN.!!!
@@ -5241,7 +5451,6 @@ var DynamicForm = ({
5241
5451
  const schema = React3.useMemo(() => getDynamicSchema(fields, extraValidations), [fields, extraValidations]);
5242
5452
  const resolver = zod.zodResolver(schema);
5243
5453
  const initialValues = React3.useMemo(() => getDefaultValues(record), [record]);
5244
- console.log("initialValues", initialValues);
5245
5454
  const form = reactHookForm.useForm({
5246
5455
  resolver,
5247
5456
  defaultValues: initialValues