Skip to content

Quickstart

IMPORTANT

This library is still in early development and the API might change before the first stable release.

This is a quickstart guide to get you started with the Form Signals core library. If you want to use a UI library, check out the other quickstart guides.

Installation

To install the package, run:

bash
npm install @formsignals/form-core @preact/signals-core

INFO

@preact/signals-core is a peer dependency of @formsignals/form-core and needs to be installed as well.

If you want to use a schema validation library you can also install the corresponding package.

Zod

bash
npm install @formsignals/validation-adapter-zod

Creating your first form

This is what a simple registration form with a name and email field would look like. This example also includes validation using the Zod library. Connecting the form state to a UI is not covered here. For an example with React bindings, check out the React quickstart guide.

ts
import {FormLogic} from '@formsignals/form-core';
import {ZodAdapter} from "@formsignals/validation-adapter-zod";
import {z} from "zod";

// Setup the form
const form = new FormLogic({
  validatorAdapter: ZodAdapter,
  defaultValues: {
    username: '',
    email: '',
    password: '',
    confirmPassword: '',
  },
  onSubmit: (values) => {
    console.log('Form submitted with values', values)
  }
})
// Mount the form
form.mount()

// Create the fields
const usernameField = form.getOrCreateField('username', {
  validator: z.string().min(3),
})
const emailField = form.getOrCreateField('email', {
  validator: z.string().email(),
})
const passwordField = form.getOrCreateField('password', {
  validator: z.string().min(8, 'Invalid email address'),
})
const confirmPasswordField = form.getOrCreateField('confirmPassword', {
  validator: z
    .tuple([z.string(), z.string()])
    .refine(
      ([checkValue, originalValue]) => checkValue === originalValue,
      'Passwords do not match',
    ),
  validateMixin: ['password'] as const,
})
// Mount the fields
usernameField.mount()
emailField.mount()
passwordField.mount()
confirmPasswordField.mount()

// Update the data
usernameField.handleChange('john_doe')
emailField.handleChange('not.a.valid.email')
passwordField.handleChange('password')
confirmPasswordField.handleChange('password2')

// Submit the form
form.handleSubmit() // Nothing happens

// Read the errors
console.log(emailField.errors.value) // ["Invalid email"]
console.log(confirmPasswordField.errors.value) // ["Passwords do not match"]

// Fix errors directly through signals
emailField.data.value = "real@email.com"
confirmPasswordField.data.value = "password"

// Submit the form
form.handleSubmit() // Form submitted with values { username: 'john_doe', email: 'real@email.com', password: 'password', confirmPassword: 'password' }