UNPKG

@sparkstone/solid-validation

Version:

A lightweight form validation library for Solid.js with PocketBase integration.

197 lines (141 loc) 5.54 kB
# @sparkstone/solid-validation A lightweight and flexible form validation library for Solid.js. It provides a simple API to validate form inputs, handle submission state, and manage error messages. ## Installation ```sh npm install @sparkstone/solid-validation ``` or ```sh pnpm add @sparkstone/solid-validation ``` ## Table of Contents - [Usage](#usage) - Basic Example - [API](#api) - `useForm(options?: { errorClass?: string })` - `validate` - `formSubmit` - `errors` - `isSubmitting` - `isSubmitted` - `validateRef` - `validateField` - `getFieldValue` - [Custom Validation](#custom-validation) - Example Validator - [PocketBase Integration](#pocketbase-integration) - `prepareFormDataForPocketbase` - `parsePocketbaseError` ## Usage ### Basic Example ```tsx import { createSignal } from 'solid-js'; import { useForm } from '@sparkstone/solid-validation'; function min5Characters(el: HTMLInputElement) { if (el.value.length < 5) { return 'must be at least 5 characters long'; } } function MyForm() { const { formSubmit, validate, errors, isSubmitting, isSubmitted } = useForm(); async function onSubmit(form: HTMLFormElement) { const formData = new FormData(form); try { // Submit form data here } catch (e) { return { myCustomFormError: e.message, }; } } return ( <form use:formSubmit={onSubmit}> <input type='text' name='username' placeholder='Enter username' required use:validate /> <span>{errors.username}</span> <input type='text' name='message' placeholder='Enter message' required use:validate={[min5Characters]} /> <span>{errors.message}</span> <span>{errors.myCustomFormError}</span> <button type='submit' disabled={isSubmitting()}> {isSubmitting() ? 'Submitting...' : 'Submit'} </button> {isSubmitted() && <p>Form successfully submitted!</p>} </form> ); } function required(el: HTMLInputElement) { return el.value.trim() ? false : 'This field is required'; } ``` ## API ### `useForm(options?: { errorClass?: string })` Creates a form validation context. #### Returns: - `validate(ref: HTMLInputElement, validators?: Validator[])` Registers an input for validation. - `formSubmit(ref: HTMLFormElement, callback: OnFormSubmit)` Handles form submission, running all validations. - `errors: Partial<Record<string, string>>` Reactive store of validation errors. - `isSubmitting: () => boolean` Tracks whether the form is currently submitting. - `isSubmitted: () => boolean` Tracks whether the form was successfully submitted. - `validateRef: (...args: Parameters<typeof validate>) => (ref: HTMLInputElement) => void` If you're validating a custom element, you can pass this in with `ref={validateRef()}`. - `validateField(fieldName: keyof ErrorFields): Promise<boolean>` Validates a field based on its name. It returns `true` if the field is valid. If the field fails validation, it automatically focuses the field and updates the error state. - `getFieldValue(fieldName: keyof ErrorFields)` Retrieves the current value of the specified field. This is useful when you need to access a field’s value programmatically during form interactions. ### Custom Validation A validator function receives an `HTMLInputElement` and returns: - `false | "" | null | undefined` for valid inputs. - A `string` error message for invalid inputs. - A `Promise<string | Falsy>` for async validation. Example: ```tsx function minLength(el: HTMLInputElement) { return el.value.length < 5 && 'Must be at least 5 characters'; } ``` ## PocketBase Integration For integrating form validation with [PocketBase](https://pocketbase.io/), this package provides helper functions to prepare form data and handle errors from PocketBase responses. ### `prepareFormDataForPocketbase(formData: FormData, form: HTMLFormElement)` PocketBase does not include unchecked checkboxes in `FormData` submissions. This function ensures that all checkbox fields are included, defaulting to `"false"` if unchecked. #### Example: ```ts import { prepareFormDataForPocketbase } from '@sparkstone/solid-validation/pocketbase'; function handleSubmit(event: Event) { event.preventDefault(); const form = event.currentTarget as HTMLFormElement; const formData = new FormData(form); prepareFormDataForPocketbase(formData, form); // Now formData is ready to be sent to PocketBase } ``` ### `parsePocketbaseError(error: PocketbaseError, rootErrorKey = "form")` PocketBase API errors return a structured `data` object. This function extracts error messages and formats them for easy use in your validation logic. #### Example: ```ts import { parsePocketbaseError } from '@sparkstone/solid-validation/pocketbase'; async function handleSubmit(event: Event) { event.preventDefault(); const form = event.currentTarget as HTMLFormElement; const formData = new FormData(form); try { // Replace with your PocketBase API call await pocketbase.collection('users').create(formData); } catch (e) { const errors = parsePocketbaseError(e); console.log(errors); // { email: "Invalid email", password: "Too short", form: "Something went wrong" } } } ``` This allows for easy mapping of errors to form fields and a general error message under the `"form"` key. --- These functions help streamline form submissions and error handling when using PocketBase as your backend.