A simple tool for converting a zod schema to a form automatically. Simply pass in a schema, and receive an automatically validated form!
Here's a look at what's possible. Edit this example at the playground:
This is a side project, and somewhat broken right now. Only svelte is supported for now.
I'm just beginning to write this, so I'm sorry if it's incomplete. Please feel free to create an issue and ask me for any feature request, or create a pull request yourself.
This example will be assuming you're starting a new project from scratch. If you already have a project, make sure you have the dependencies installed, and skip to installing the package with npm.
Run the following to set up a project
npx sv create # Select the options you want in your new project npm i zod zxforms-svelteSimply create a zod schema. Each input you want should be a subobject, for now either a string, number, boolean, or enum. Enums appear as dropdown single select, and booleans as checkboxes.
z.object({ input: z.string() })Include meta information for more customization. You can include the following on an input:
- default - for a default value
- type - for a custom input type (like 'password')
- title
- description
On the main form, you can also include the following:
- title
- description
- callback - a function that receives the form data. If callback is set, the form will have event.preventDefault() called, so the default form submission will not occur
Here's an example which attempts to show off all features. This example creates the forms shown at the top of this README
<script> import { z } from "zod"; import ZxForm from "zxforms-svelte" function cb(data: any) { console.log("Form submitted, data:"); console.log(data); } const schema = z .object({ email: z .email({ message: "Please enter a valid email" }) // Custom invalid messages .meta({ description: "We <b>promise</b> you won't be spammed!", // Custom html is available in descriptions, placeholders and the submit button placeholder: "example@gmail.com", }), name: z.string().nonempty(), mood: z .enum(["Happy", "Sad", "Excited", "Bored"]) .meta({ title: "How are you feeling?", placeholder: "Happy" }), // Custom input title age: z.number().gte(4).optional(), // Optional inputs password: z.string().nonempty().meta({ type: "password" }), // Set a custom type, like "password" feedback: z.string().nonempty().meta({ type: "textarea" }), terms: z .boolean() .refine((v) => v, { message: "You must agree to the terms and conditions", }) .meta({ title: "Terms and Conditions", description: 'You must agree to our <a href="#" style="text-decoration: underline;">Terms and Conditions</a>', }), }) .meta({ title: "Example Form", // Form title description: "An example form to show you what's possible", // Description at the top of the form submitName: "Sign up", // Custom submit button title callback: cb, // Custom submit callback }); </script> <!-- Then, pass the schema object to the ZxForm element --> <!-- You can also include action and method attributes, as if it was an html form element --> <ZxForm {schema}> <!-- Use snippets to include a custom header or footer --> <!-- {#snippet header()} // Snippet content here {/snippet} --> {#snippet footer()} <div class="flex justify-between"> <p class="dark:text-gray-100 text-sm mt-4 font-semibold text-stone-900"> Visit us at <a href="#" class="underline">example.com</a> ❤️ </p> <a href="#" class="dark:text-neutral-400 underline text-sm mt-4 font-semibold text-stone-800 flex">Sign in instead</a> </div> {/snippet} </ZxForm>
