diff --git a/src/components/form.tsx b/src/components/form.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/ui/auto-form/common/label.tsx b/src/components/ui/auto-form/common/label.tsx deleted file mode 100644 index d570830..0000000 --- a/src/components/ui/auto-form/common/label.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { FormLabel } from "@/components/ui/form"; -import { cn } from "@/lib/utils"; - -function AutoFormLabel({ - label, - isRequired, - className, -}: { - label: string; - isRequired: boolean; - className?: string; -}) { - return ( - <> - - {label} - {isRequired && *} - - - ); -} - -export default AutoFormLabel; diff --git a/src/components/ui/auto-form/common/tooltip.tsx b/src/components/ui/auto-form/common/tooltip.tsx deleted file mode 100644 index cafdb79..0000000 --- a/src/components/ui/auto-form/common/tooltip.tsx +++ /dev/null @@ -1,13 +0,0 @@ -function AutoFormTooltip({ fieldConfigItem }: { fieldConfigItem: any }) { - return ( - <> - {fieldConfigItem?.description && ( -

- {fieldConfigItem.description} -

- )} - - ); -} - -export default AutoFormTooltip; diff --git a/src/components/ui/auto-form/config.ts b/src/components/ui/auto-form/config.ts deleted file mode 100644 index be416ba..0000000 --- a/src/components/ui/auto-form/config.ts +++ /dev/null @@ -1,35 +0,0 @@ -import AutoFormCheckbox from "./fields/checkbox"; -import AutoFormDate from "./fields/date"; -import AutoFormEnum from "./fields/enum"; -import AutoFormFile from "./fields/file"; -import AutoFormInput from "./fields/input"; -import AutoFormNumber from "./fields/number"; -import AutoFormRadioGroup from "./fields/radio-group"; -import AutoFormSwitch from "./fields/switch"; -import AutoFormTextarea from "./fields/textarea"; - -export const INPUT_COMPONENTS = { - checkbox: AutoFormCheckbox, - date: AutoFormDate, - select: AutoFormEnum, - radio: AutoFormRadioGroup, - switch: AutoFormSwitch, - textarea: AutoFormTextarea, - number: AutoFormNumber, - file: AutoFormFile, - fallback: AutoFormInput, -}; - -/** - * Define handlers for specific Zod types. - * You can expand this object to support more types. - */ -export const DEFAULT_ZOD_HANDLERS: { - [key: string]: keyof typeof INPUT_COMPONENTS; -} = { - ZodBoolean: "checkbox", - ZodDate: "date", - ZodEnum: "select", - ZodNativeEnum: "select", - ZodNumber: "number", -}; diff --git a/src/components/ui/auto-form/dependencies.ts b/src/components/ui/auto-form/dependencies.ts deleted file mode 100644 index 4d9cada..0000000 --- a/src/components/ui/auto-form/dependencies.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { FieldValues, UseFormWatch } from "react-hook-form"; -import { Dependency, DependencyType, EnumValues } from "./types"; -import * as z from "zod"; - -export default function resolveDependencies< - SchemaType extends z.infer>, ->( - dependencies: Dependency[], - currentFieldName: keyof SchemaType, - watch: UseFormWatch, -) { - let isDisabled = false; - let isHidden = false; - let isRequired = false; - let overrideOptions: EnumValues | undefined; - - const currentFieldValue = watch(currentFieldName as string); - - const currentFieldDependencies = dependencies.filter( - (dependency) => dependency.targetField === currentFieldName, - ); - for (const dependency of currentFieldDependencies) { - const watchedValue = watch(dependency.sourceField as string); - - const conditionMet = dependency.when(watchedValue, currentFieldValue); - - switch (dependency.type) { - case DependencyType.DISABLES: - if (conditionMet) { - isDisabled = true; - } - break; - case DependencyType.REQUIRES: - if (conditionMet) { - isRequired = true; - } - break; - case DependencyType.HIDES: - if (conditionMet) { - isHidden = true; - } - break; - case DependencyType.SETS_OPTIONS: - if (conditionMet) { - overrideOptions = dependency.options; - } - break; - } - } - - return { - isDisabled, - isHidden, - isRequired, - overrideOptions, - }; -} diff --git a/src/components/ui/auto-form/fields/array.tsx b/src/components/ui/auto-form/fields/array.tsx deleted file mode 100644 index c66e972..0000000 --- a/src/components/ui/auto-form/fields/array.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import { - AccordionContent, - AccordionItem, - AccordionTrigger, -} from "@/components/ui/accordion"; -import { Button } from "@/components/ui/button"; -import { Separator } from "@/components/ui/separator"; -import { Plus, Trash } from "lucide-react"; -import { useFieldArray, useForm } from "react-hook-form"; -import * as z from "zod"; -import { beautifyObjectName } from "../utils"; -import AutoFormObject from "./object"; - -function isZodArray( - item: z.ZodArray | z.ZodDefault, -): item is z.ZodArray { - return item instanceof z.ZodArray; -} - -function isZodDefault( - item: z.ZodArray | z.ZodDefault, -): item is z.ZodDefault { - return item instanceof z.ZodDefault; -} - -export default function AutoFormArray({ - name, - item, - form, - path = [], - fieldConfig, -}: { - name: string; - item: z.ZodArray | z.ZodDefault; - form: ReturnType; - path?: string[]; - fieldConfig?: any; -}) { - const { fields, append, remove } = useFieldArray({ - control: form.control, - name, - }); - const title = item._def.description ?? beautifyObjectName(name); - - const itemDefType = isZodArray(item) - ? item._def.type - : isZodDefault(item) - ? item._def.innerType._def.type - : null; - - return ( - - {title} - - {fields.map((_field, index) => { - const key = _field.id; - return ( -
- } - form={form} - fieldConfig={fieldConfig} - path={[...path, index.toString()]} - /> -
- -
- - -
- ); - })} - -
-
- ); -} diff --git a/src/components/ui/auto-form/fields/checkbox.tsx b/src/components/ui/auto-form/fields/checkbox.tsx deleted file mode 100644 index 2b0121c..0000000 --- a/src/components/ui/auto-form/fields/checkbox.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { Checkbox } from "@/components/ui/checkbox"; -import { FormControl, FormItem } from "@/components/ui/form"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; -import AutoFormLabel from "../common/label"; - -export default function AutoFormCheckbox({ - label, - isRequired, - field, - fieldConfigItem, - fieldProps, -}: AutoFormInputComponentProps) { - return ( -
- -
- - - - -
-
- -
- ); -} diff --git a/src/components/ui/auto-form/fields/date.tsx b/src/components/ui/auto-form/fields/date.tsx deleted file mode 100644 index 9c06cdc..0000000 --- a/src/components/ui/auto-form/fields/date.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { DatePicker } from "@/components/ui/date-picker"; -import { FormControl, FormItem, FormMessage } from "@/components/ui/form"; -import AutoFormLabel from "../common/label"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; - -export default function AutoFormDate({ - label, - isRequired, - field, - fieldConfigItem, - fieldProps, -}: AutoFormInputComponentProps) { - return ( - - - - - - - - - - ); -} diff --git a/src/components/ui/auto-form/fields/enum.tsx b/src/components/ui/auto-form/fields/enum.tsx deleted file mode 100644 index d5a68db..0000000 --- a/src/components/ui/auto-form/fields/enum.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { FormControl, FormItem, FormMessage } from "@/components/ui/form"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; -import * as z from "zod"; -import AutoFormLabel from "../common/label"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; -import { getBaseSchema } from "../utils"; - -export default function AutoFormEnum({ - label, - isRequired, - field, - fieldConfigItem, - zodItem, - fieldProps, -}: AutoFormInputComponentProps) { - const baseValues = (getBaseSchema(zodItem) as unknown as z.ZodEnum)._def - .values; - - let values: [string, string][] = []; - if (!Array.isArray(baseValues)) { - values = Object.entries(baseValues); - } else { - values = baseValues.map((value) => [value, value]); - } - - function findItem(value: any) { - return values.find((item) => item[0] === value); - } - - return ( - - - - - - - - - ); -} diff --git a/src/components/ui/auto-form/fields/file.tsx b/src/components/ui/auto-form/fields/file.tsx deleted file mode 100644 index 058aab7..0000000 --- a/src/components/ui/auto-form/fields/file.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { FormControl, FormItem, FormMessage } from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; -import { Trash2 } from "lucide-react"; -import { ChangeEvent, useState } from "react"; -import AutoFormLabel from "../common/label"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; -export default function AutoFormFile({ - label, - isRequired, - fieldConfigItem, - fieldProps, - field, -}: AutoFormInputComponentProps) { - const { showLabel: _showLabel, ...fieldPropsWithoutShowLabel } = fieldProps; - const showLabel = _showLabel === undefined ? true : _showLabel; - const [file, setFile] = useState(null); - const [fileName, setFileName] = useState(null); - const handleFileChange = (e: ChangeEvent) => { - const file = e.target.files?.[0]; - - if (file) { - const reader = new FileReader(); - reader.onloadend = () => { - setFile(reader.result as string); - setFileName(file.name); - field.onChange(reader.result as string); - }; - reader.readAsDataURL(file); - } - }; - - const handleRemoveClick = () => { - setFile(null); - }; - - return ( - - {showLabel && ( - - )} - {!file && ( - - - - )} - {file && ( -
-

{fileName}

- -
- )} - - -
- ); -} diff --git a/src/components/ui/auto-form/fields/input.tsx b/src/components/ui/auto-form/fields/input.tsx deleted file mode 100644 index 33fcd36..0000000 --- a/src/components/ui/auto-form/fields/input.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { FormControl, FormItem, FormMessage } from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; -import AutoFormLabel from "../common/label"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; - -export default function AutoFormInput({ - label, - isRequired, - fieldConfigItem, - fieldProps, -}: AutoFormInputComponentProps) { - const { showLabel: _showLabel, ...fieldPropsWithoutShowLabel } = fieldProps; - const showLabel = _showLabel === undefined ? true : _showLabel; - const type = fieldProps.type || "text"; - - return ( -
- - {showLabel && ( - - )} - - - - - - -
- ); -} diff --git a/src/components/ui/auto-form/fields/number.tsx b/src/components/ui/auto-form/fields/number.tsx deleted file mode 100644 index 8637732..0000000 --- a/src/components/ui/auto-form/fields/number.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { FormControl, FormItem, FormMessage } from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; -import AutoFormLabel from "../common/label"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; - -export default function AutoFormNumber({ - label, - isRequired, - fieldConfigItem, - fieldProps, -}: AutoFormInputComponentProps) { - const { showLabel: _showLabel, ...fieldPropsWithoutShowLabel } = fieldProps; - const showLabel = _showLabel === undefined ? true : _showLabel; - - return ( - - {showLabel && ( - - )} - - - - - - - ); -} diff --git a/src/components/ui/auto-form/fields/object.tsx b/src/components/ui/auto-form/fields/object.tsx deleted file mode 100644 index 5ec122d..0000000 --- a/src/components/ui/auto-form/fields/object.tsx +++ /dev/null @@ -1,183 +0,0 @@ -import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, -} from "@/components/ui/accordion"; -import { FormField } from "@/components/ui/form"; -import { useForm, useFormContext } from "react-hook-form"; -import * as z from "zod"; -import { DEFAULT_ZOD_HANDLERS, INPUT_COMPONENTS } from "../config"; -import { Dependency, FieldConfig, FieldConfigItem } from "../types"; -import { - beautifyObjectName, - getBaseSchema, - getBaseType, - zodToHtmlInputProps, -} from "../utils"; -import AutoFormArray from "./array"; -import resolveDependencies from "../dependencies"; - -function DefaultParent({ children }: { children: React.ReactNode }) { - return <>{children}; -} - -export default function AutoFormObject< - SchemaType extends z.ZodObject, ->({ - schema, - form, - fieldConfig, - path = [], - dependencies = [], -}: { - schema: SchemaType | z.ZodEffects; - form: ReturnType; - fieldConfig?: FieldConfig>; - path?: string[]; - dependencies?: Dependency>[]; -}) { - const { watch } = useFormContext(); // Use useFormContext to access the watch function - - if (!schema) { - return null; - } - const { shape } = getBaseSchema(schema) || {}; - - if (!shape) { - return null; - } - - const handleIfZodNumber = (item: z.ZodAny) => { - const isZodNumber = (item as any)._def.typeName === "ZodNumber"; - const isInnerZodNumber = - (item._def as any).innerType?._def?.typeName === "ZodNumber"; - - if (isZodNumber) { - (item as any)._def.coerce = true; - } else if (isInnerZodNumber) { - (item._def as any).innerType._def.coerce = true; - } - - return item; - }; - - return ( - - {Object.keys(shape).map((name) => { - let item = shape[name] as z.ZodAny; - item = handleIfZodNumber(item) as z.ZodAny; - const zodBaseType = getBaseType(item); - const itemName = item._def.description ?? beautifyObjectName(name); - const key = [...path, name].join("."); - - const { - isHidden, - isDisabled, - isRequired: isRequiredByDependency, - overrideOptions, - } = resolveDependencies(dependencies, name, watch); - if (isHidden) { - return null; - } - - if (zodBaseType === "ZodObject") { - return ( - - {itemName} - - } - form={form} - fieldConfig={ - (fieldConfig?.[name] ?? {}) as FieldConfig< - z.infer - > - } - path={[...path, name]} - /> - - - ); - } - if (zodBaseType === "ZodArray") { - return ( - } - form={form} - fieldConfig={fieldConfig?.[name] ?? {}} - path={[...path, name]} - /> - ); - } - - const fieldConfigItem: FieldConfigItem = fieldConfig?.[name] ?? {}; - const zodInputProps = zodToHtmlInputProps(item); - const isRequired = - isRequiredByDependency || - zodInputProps.required || - fieldConfigItem.inputProps?.required || - false; - - if (overrideOptions) { - item = z.enum(overrideOptions) as unknown as z.ZodAny; - } - - return ( - { - const inputType = - fieldConfigItem.fieldType ?? - DEFAULT_ZOD_HANDLERS[zodBaseType] ?? - "fallback"; - - const InputComponent = - typeof inputType === "function" - ? inputType - : INPUT_COMPONENTS[inputType]; - - const ParentElement = - fieldConfigItem.renderParent ?? DefaultParent; - - const defaultValue = fieldConfigItem.inputProps?.defaultValue; - const value = field.value ?? defaultValue ?? ""; - - const fieldProps = { - ...zodToHtmlInputProps(item), - ...field, - ...fieldConfigItem.inputProps, - disabled: fieldConfigItem.inputProps?.disabled || isDisabled, - ref: undefined, - value: value, - }; - - if (InputComponent === undefined) { - return <>; - } - - return ( - - - - ); - }} - /> - ); - })} - - ); -} diff --git a/src/components/ui/auto-form/fields/radio-group.tsx b/src/components/ui/auto-form/fields/radio-group.tsx deleted file mode 100644 index fd192f0..0000000 --- a/src/components/ui/auto-form/fields/radio-group.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { - FormControl, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; -import * as z from "zod"; -import AutoFormLabel from "../common/label"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; -import { getBaseSchema } from "../utils"; - -export default function AutoFormRadioGroup({ - label, - isRequired, - field, - zodItem, - fieldProps, - fieldConfigItem, -}: AutoFormInputComponentProps) { - const baseValues = (getBaseSchema(zodItem) as unknown as z.ZodEnum)._def - .values; - - let values: string[] = []; - if (!Array.isArray(baseValues)) { - values = Object.entries(baseValues).map((item) => item[0]); - } else { - values = baseValues; - } - - return ( -
- - - - - {values?.map((value: any) => ( - - - - - {value} - - ))} - - - - - -
- ); -} diff --git a/src/components/ui/auto-form/fields/switch.tsx b/src/components/ui/auto-form/fields/switch.tsx deleted file mode 100644 index 24ea9ff..0000000 --- a/src/components/ui/auto-form/fields/switch.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { FormControl, FormItem } from "@/components/ui/form"; -import { Switch } from "@/components/ui/switch"; -import AutoFormLabel from "../common/label"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; - -export default function AutoFormSwitch({ - label, - isRequired, - field, - fieldConfigItem, - fieldProps, -}: AutoFormInputComponentProps) { - return ( -
- -
- - - - -
-
- -
- ); -} diff --git a/src/components/ui/auto-form/fields/textarea.tsx b/src/components/ui/auto-form/fields/textarea.tsx deleted file mode 100644 index 2064551..0000000 --- a/src/components/ui/auto-form/fields/textarea.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { FormControl, FormItem, FormMessage } from "@/components/ui/form"; -import { Textarea } from "@/components/ui/textarea"; -import AutoFormLabel from "../common/label"; -import AutoFormTooltip from "../common/tooltip"; -import { AutoFormInputComponentProps } from "../types"; - -export default function AutoFormTextarea({ - label, - isRequired, - fieldConfigItem, - fieldProps, -}: AutoFormInputComponentProps) { - const { showLabel: _showLabel, ...fieldPropsWithoutShowLabel } = fieldProps; - const showLabel = _showLabel === undefined ? true : _showLabel; - return ( - - {showLabel && ( - - )} - -