import { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/comps/ui/form"; import { useLocal } from "@/utils/use-local"; import autosize from "autosize"; import { FC, ReactNode, useEffect, useRef } from "react"; import { Input } from "../ui/input"; import { Textarea } from "../ui/textarea"; import { Date } from "./Date"; import { Datetime } from "./Datetime"; import { Dropdown } from "./Dropdown"; import { Relation } from "./Dropdown/relation"; import { InputMoney } from "./InputMoney"; import { Radio } from "./Radio"; import { SliderOptions } from "./Slider/types"; import { FieldOptions } from "./type"; import { FormHook, modify } from "./utils/utils"; export const Field: FC<{ name: string; label: string; desc?: string; form?: FormHook; type: | "text" | "number" | "textarea" | "dropdown" | "relation" | "password" | "radio" | "date" | "datetime" | "money" | "slider" | "master-link" | "custom"; required: "y" | "n"; options: FieldOptions; slider: () => Promise; on_change: (arg: { value: any }) => void | Promise; PassProp: any; custom: "y" | "n"; child: any; selection: "single" | "multi"; suffix: any; placeholder?: any; label_alt: | ReactNode | FC<{ modify: typeof modify; data: any; current_name: string }>; rel_table: string; rel_fields: string[]; rel_query: () => any; }> = ({ name, form, desc, label, type, required, options, slider, on_change, PassProp, custom, selection, suffix, child, placeholder, label_alt, rel_fields, rel_table, rel_query, }) => { const values = form?.hook.getValues(); const value = values[name]; const local = useLocal({ date: { // label: "", popup: false, }, slider: { value: 0, opt: { step: 1, min: { value: 0, label: "Start" }, max: { value: 100, label: "End" }, } as SliderOptions, status: "init" as "init" | "loading" | "ready", }, modify: null as any, }); const textAreaRef = useRef(); useEffect(() => { autosize(textAreaRef.current); return () => { autosize.destroy(textAreaRef.current); }; }, []); useEffect(() => { if (type === "slider") { local.slider.value = parseSliderValue(value, local.slider.opt); if (typeof slider === "function") { if (local.slider.status === "init") { local.slider.status = "ready"; local.render(); (async () => { const res = await slider(); local.slider.opt = res; local.render(); })(); } } else { local.slider.status = "ready"; local.render(); } } }, [value]); const inputKeyDown = (e: any) => { if (e.key === "Enter" && form?.ref) { form.submit(); } }; const onChange = (e: any) => { form?.hook.setValue(name, e.currentTarget.value); form?.render(); }; if (form) { form.label[name] = label; if (required === "y") { form.validation[name] = "required"; if (value) { delete form.hook.formState.errors[name]; } } else { delete form.validation[name]; } } return ( <> (
{label} {required === "y" && (

*

)}
{typeof label_alt === "function" && form && label_alt({ modify: local.modify ? local.modify : modify.bind({ form, }), current_name: name, data: form.hook.getValues(), })} {typeof label_alt !== "function" && label_alt}
<> {type === "custom" && (
{custom}
)} {type === "slider" && (
{local.slider.opt.min.value}
{local.slider.opt.min.label}
{ const value = e.currentTarget.value; local.slider.value = parseSliderValue( value, local.slider.opt ); form?.hook.setValue(name, value); local.render(); }} value={local.slider.value} min={local.slider.opt.min.value} max={local.slider.opt.max.value} />
{local.slider.value}
{local.slider.opt.max.value}
{local.slider.opt.max.label}
)} {["text", "number", "password"].includes(type) && (suffix !== "" ? (
{suffix || "-"}
) : ( ))} {type === "textarea" && (