[Feature]: AutoForm: more flexibility
razbakov opened this issue · comments
Describe the feature
Background
In my vue2 project I used form builder based on json array of fields.
I was looking for similar solution for vue3 projects. I found https://formkit.com/ and it seemed like a good choice in the beginning, but then I encountered:
- Styling problems.
- Basic components only available in Pro: Repeater, Toggle, Autocomplete, Datepicker, Dropdown.
- Creating a custom input is too complex.
I am trying to think of some solution that is simple and flexible. For a long time I couldn't decide how to build forms: with js config or with template. With template you can define a custom layout and place multiple inputs (for example "first name" and "last name") in one row. On other hand you can re-use js config in multiple places.
I discovered Building forms with VeeValidate and Zod and I love how Zod makes life easier with validation and types.
When I integrated Form in my new project, I created form builder based on zod schema.
Recently I discovered AutoForm, I love the idea! It's very similar to what I was doing! Amazing!
Problem
Here is example of registration form with AutoForm.
Customization
What I am missing here is:
- AutoFormFieldDate, AutoFormFieldEnum, etc. repeat FormField/FormItem/FormLabel structure in each file, but there is no need to do it. It's better to place it all in one "form field" wrapper (see my gist examples above), which can have any component inside
<FormControl>
. component
infield-config
is mapped toINPUT_COMPONENTS
in AutoFormField and it limits component only to pre-defined values. It would be great to be able to use any component without changingINPUT_COMPONENTS
.- AutoFormFieldEnum has a
v-if="config?.component === 'radio'"
to switch between<RadioGroup>
and<Select>
. But what if I want to use<ButtonGroup>
or something else?
Configuration
And a smaller issue is 3 configs for one form: schema, field-config and slots. It would be awesome to have a single configuration. zod doesn't let add any additional information in schema, so I was thinking on creating a new type that would allow to integrate zod objects inside of it, for example:
const form = model({
username: {
label: "Username",
component: "InputUsername",
type: z
.string()
.min(2, "Username must be at least 2 characters.")
.max(30)
.refine(
noMultiplePeriods,
"Username cannot have multiple periods in a row."
)
.refine(notEndingInPeriod, "Username cannot end in a period.")
.refine(usernameValidator, "Username is already taken."),
},
city: z.string(),
email: z.string().email().default("me@example.com"),
password: z.string().min(8),
acceptTerms: z.boolean().refine((value) => value, {
message: "You must accept the terms and conditions.",
}),
});
const schema = form.schema(); // returns z.object
Additional information
- I intend to submit a PR for this feature.
- I have already implemented and/or tested this feature.