import { any, array, boolean, lazy, literal, number, object, optional, parse, required, string, union, type GenericSchema, type InferOutput } from "valibot" import { FormNodeName, FormNodeNameEnum } from "../../../models/constants" // boolean (checkbox, switch) // date (date picker) // enum (select, radio group) // number (input) // string (input, textfield) // file (file) // This is only for string inputs (types that outputs string) export const InputTypes = union([ literal("color"), literal("date"), literal("datetime-local"), literal("month"), literal("number"), literal("password"), literal("text"), literal("url"), literal("week"), literal("time"), literal("search") ]) export type InputTypes = InferOutput // export const InputProps = object({ // placeholder: optional(string()), // // defaultValue: optional(string()), // // these types can be properly rendered and output a string // type: optional(InputTypes), // showLabel: optional(boolean()), // required: optional(boolean()) // }) export const BaseField = object({ nodeName: FormNodeName, key: string(), label: optional(string()), hideLabel: optional(boolean()), placeholder: optional(string()), optional: optional(boolean()), description: optional(string()), default: optional(any()) }) export type BaseField = InferOutput /* -------------------------------------------------------------------------- */ /* Input Element */ /* -------------------------------------------------------------------------- */ export const InputField = object({ ...BaseField.entries, type: optional(InputTypes), component: optional(union([literal("textarea"), literal("default")])), default: optional(string()) }) export type InputField = InferOutput /* -------------------------------------------------------------------------- */ /* Number */ /* -------------------------------------------------------------------------- */ export const NumberField = object({ ...BaseField.entries, nodeName: FormNodeName, default: optional(number()) }) export type NumberField = InferOutput /* -------------------------------------------------------------------------- */ /* Select */ /* -------------------------------------------------------------------------- */ // with zod enum export const SelectField = object({ ...BaseField.entries, options: array(string()), default: optional(string()) }) export type SelectField = InferOutput /* -------------------------------------------------------------------------- */ /* Boolean */ /* -------------------------------------------------------------------------- */ export const BooleanField = object({ ...BaseField.entries, component: optional(union([literal("checkbox"), literal("switch")])) }) export type BooleanField = InferOutput /* -------------------------------------------------------------------------- */ /* Date */ /* -------------------------------------------------------------------------- */ export const DateField = object({ ...BaseField.entries, default: optional(string()) }) export type DateField = InferOutput export const AllFormFields = union([InputField, NumberField, SelectField, BooleanField, DateField]) /* -------------------------------------------------------------------------- */ /* Array */ /* -------------------------------------------------------------------------- */ export const ArrayField = object({ ...BaseField.entries, content: AllFormFields }) export type ArrayField = InferOutput /* -------------------------------------------------------------------------- */ /* Form */ /* -------------------------------------------------------------------------- */ export const FormField = union([ ArrayField, // this must be placed first, otherwise its content field won't be parsed SelectField, InputField, NumberField, BooleanField, DateField ]) export type FormField = InferOutput // export type Form = InferOutput export const Form: GenericSchema
= object({ nodeName: FormNodeName, key: string(), showFormDataDebug: optional(boolean()), fields: array(union([lazy(() => Form), FormField])), title: optional(string()), description: optional(string()), submitBtnText: optional(string()) }) export type Form = { nodeName: FormNodeName title?: string showFormDataDebug?: boolean description?: string submitBtnText?: string key: string fields: (FormField | Form)[] }