TypeScript reference
This page lists every type exported from @samline/forms, what it represents, and where it shows up. Each type links to the method(s) that consume or produce it.
All types are exported from the package root:
import type { AppendContentOptions, AutoSubmitOptions, FieldFormatConfig, FieldFormatConfigMap, FieldValidationContext, FieldValidationRules, FieldValidator, FormController, FormControllerOptions, FormErrors, FormFieldElement, FormFieldValue, FormsApi, FormsAvailable, FormStateListener, FormStateSnapshot, FormSubmitHandler, FormTarget, FormValues, NewFormInput, RuleConfig, SerializedFormResult, SerializedFormValue, ValidationResult, ValidationSchema, VisualAttributes} from '@samline/forms'FormController
Section titled “FormController”The full controller surface returned by form().
interface FormController { readonly element: HTMLFormElement | null readonly f: HTMLFormElement | null readonly options: FormControllerOptions onSubmit: (callback: FormSubmitHandler, preventDefault?: boolean) => FormController watch: (field: string, callback: FormFieldWatcher) => FormController observe: (field: string, callback: FormFieldWatcher) => () => void unwatch: (field?: string, callback?: FormFieldWatcher) => FormController subscribe: (listener: FormStateListener) => () => void prefill: (fieldName?: string) => FormController append: (options: AppendContentOptions) => HTMLElement | null setErrors: (fields: string[] | FormErrors) => FormController clearErrors: (fields?: string[]) => FormController setValue: (name: string, value: unknown) => FormController validate: (fields?: string[]) => ValidationResult revalidate: (fields?: string[]) => ValidationResult reset: () => FormController autoSubmit: (options?: boolean | AutoSubmitOptions) => FormController disableAutoSubmit: () => FormController getValue: (name: string) => FormFieldValue getField: (name: string) => FormFieldElement | FormFieldElement[] | null getData: () => SerializedFormResult getState: () => FormStateSnapshot destroy: () => void}FormControllerOptions
Section titled “FormControllerOptions”The second argument to form(). See Configuration for the full reference.
interface FormControllerOptions { attributes?: Partial<VisualAttributes> autoValidate?: boolean autoSubmit?: boolean | AutoSubmitOptions clearManualErrorsOnChange?: boolean clearErrorsOnSubmit?: boolean validators?: ValidationSchema formats?: FieldFormatConfigMap}FormTarget
Section titled “FormTarget”What form() accepts as its first argument.
type FormTarget = | string // element id | HTMLFormElement // direct element | { current: HTMLFormElement | null } // ref-like | null | undefinedA string is treated as a document.getElementById(id) lookup; only HTMLFormElement matches count. A ref-like value lets you pass a Vue/React-style ref object.
FormFieldElement
Section titled “FormFieldElement”The set of DOM field types the controller manages.
type FormFieldElement = | HTMLInputElement | HTMLSelectElement | HTMLTextAreaElementReturned by getField.
FormFieldValue
Section titled “FormFieldValue”The normalized value of a field.
type FormFieldValue = string | string[] | File[] | undefinedstring— for text inputs, textareas, single selects, and single checked checkboxes / radios.string[]— for groups of checkboxes / radios where more than one is selected.File[]— for<input type="file">(may be empty).undefined— when no field with that name exists.
Returned by getValue.
FormValues
Section titled “FormValues”The aggregated values map produced by the controller and the helpers.
type FormValues = Record<string, FormFieldValue>Useful when you build custom validators that need to read other fields:
form('signup-form', { validators: { confirm: { validate: ({ value, values }) => value === values.password ? null : 'Passwords do not match.' } }})FormErrors
Section titled “FormErrors”A map from field name to an array of error messages. Each field can have multiple errors (one per failed rule or per failing custom validator).
type FormErrors = Record<string, string[]>Drives the css-error attribute on fields and is returned inside FormStateSnapshot and ValidationResult.
FormStateSnapshot
Section titled “FormStateSnapshot”The shape returned by getState(). Built fresh on every call — it does not retain references to controller internals.
interface FormStateSnapshot { values: FormValues errors: FormErrors filledFields: string[] isValid: boolean isValidated: boolean autoSubmit: boolean submitCount: number}| Field | Meaning |
|---|---|
values |
Current values for every tracked field. |
errors |
Merged validation and manual errors. |
filledFields |
Names of fields that have a non-empty value. |
isValid |
true when errors has no entries. |
isValidated |
true once validate has run at least once. |
autoSubmit |
true while auto-submit is enabled. |
submitCount |
Number of submit attempts (valid or invalid). |
FormStateListener
Section titled “FormStateListener”The callback passed to subscribe.
type FormStateListener = (state: FormStateSnapshot) => voidReceives the current snapshot immediately on subscription, then on every state mutation.
FormSubmitHandler
Section titled “FormSubmitHandler”The callback passed to onSubmit.
type FormSubmitHandler = ( form: HTMLFormElement, data: Record<string, SerializedFormValue>, formData: FormData, state: FormStateSnapshot) => voidOnly invoked when the form is valid. data and formData are produced fresh on each invocation.
FormFieldWatcher
Section titled “FormFieldWatcher”The callback passed to watch and observe.
type FormFieldWatcher = ( value: FormFieldValue, field: FormFieldElement | FormFieldElement[] | null, form: HTMLFormElement, state: FormStateSnapshot) => voidvalue— the current value of the field that just changed.field— the DOM element(s) backing the field. Single matching field →HTMLInputElement/HTMLSelectElement/HTMLTextAreaElement; repeated fields → array; no match →null.form— the boundHTMLFormElement.state— a snapshot of the whole controller state.
observe fires this once immediately with the current value, then on every change. watch is a chainable alias and only fires on changes after it is registered.
SerializedFormResult
Section titled “SerializedFormResult”The shape returned by getData() and parseFormData().
interface SerializedFormResult { data: Record<string, SerializedFormValue> formData: FormData}data is a plain object mirror of the FormData. Repeated names become arrays. Empty file entries are filtered out.
SerializedFormValue
Section titled “SerializedFormValue”The value shape inside SerializedFormResult.data.
type SerializedFormValue = FormDataPrimitive | FormDataPrimitive[]type FormDataPrimitive = FormDataEntryValue // string | FileValidationResult
Section titled “ValidationResult”The shape returned by validate, revalidate, and validateValues.
interface ValidationResult { isValid: boolean errors: FormErrors}errors is always a fresh object — safe to mutate.
ValidationSchema
Section titled “ValidationSchema”The shape of options.validators.
type ValidationSchema = Record<string, FieldValidationRules>FieldValidationRules
Section titled “FieldValidationRules”The rule set for a single field.
interface FieldValidationRules { required?: RuleConfig<boolean> minLength?: RuleConfig<number> maxLength?: RuleConfig<number> pattern?: RuleConfig<RegExp> validate?: FieldValidator | FieldValidator[]}Rules run in the order: required → minLength → maxLength → pattern → validate. All are optional; an empty rules object contributes nothing.
RuleConfig<T>
Section titled “RuleConfig<T>”Lets a rule be configured with a plain value or a { value, message } object.
type RuleConfig<T> = T | { value: T; message?: string }form('signup-form', { validators: { password: { minLength: { value: 8, message: 'Use at least 8 characters.' } }, terms: { required: { value: true, message: 'Please accept the terms.' } } }})When the plain form is used, default messages are produced automatically.
FieldValidationContext
Section titled “FieldValidationContext”The argument passed to a custom validator.
interface FieldValidationContext { field: string value: FormFieldValue values: FormValues}Use it to write cross-field validators:
form('checkout-form', { validators: { card: { validate: ({ value, field }) => { if (typeof value !== 'string') return `${field} is required.` return /^\d{16}$/.test(value.replace(/\s+/g, '')) ? null : 'Card number must be 16 digits.' } } }})FieldValidator
Section titled “FieldValidator”The custom validator signature.
type FieldValidator = ( context: FieldValidationContext) => string | undefined | null | false | true| Return | Meaning |
|---|---|
string (non-empty) |
Push as the error message. |
undefined, null, true |
Pass. |
false |
Push the generic error message "Validation failed.". |
Multiple validators can be chained by passing an array as validate:
form('order-form', { validators: { quantity: { validate: [ ({ value }) => (typeof value === 'string' && Number(value) > 0 ? null : 'Must be greater than zero.'), ({ value }) => (typeof value === 'string' && Number.isInteger(Number(value)) ? null : 'Must be an integer.') ] } }})AutoSubmitOptions
Section titled “AutoSubmitOptions”The argument to autoSubmit() and the autoSubmit option.
interface AutoSubmitOptions { debounce?: number}debounce is in milliseconds.
AppendContentOptions
Section titled “AppendContentOptions”The argument to append().
interface AppendContentOptions { tag: keyof HTMLElementTagNameMap content: string class?: string atStart?: boolean}| Field | Meaning |
|---|---|
tag |
The HTML tag to create. |
content |
innerHTML content for the new node. |
class |
Optional class name. If a node with the same first class already exists inside the form, it is removed before the new one is inserted. |
atStart |
When true, inserts at the start of the form. Defaults to false (append at the end). |
VisualAttributes
Section titled “VisualAttributes”The shape of options.attributes.
interface VisualAttributes { filled: string error: string}Partial<VisualAttributes> is accepted, so you can override only one of them. See CSS styling.
FieldFormatConfig and FieldFormatConfigMap
Section titled “FieldFormatConfig and FieldFormatConfigMap”The argument to format() and formatAll().
interface FieldFormatConfig { type: FormatType field: string | string[] rawField?: string options?: Record<string, unknown>}
type FormatType = | 'general' | 'phone' | 'numeral' | 'date' | 'time' | 'creditCard' | 'creditCardType'
interface FieldFormatConfigMap { [field: string]: Omit<FieldFormatConfig, 'field'>}The field name is the name attribute of the visible input(s). rawField defaults to ${fieldName}Raw. options is forwarded to @samline/formatter — see its options reference.
FormsApi
Section titled “FormsApi”The shape of the browser singleton exported from the vanilla entrypoint. The IIFE bundle exposes the same shape as window.Forms.
interface FormsApi { form: (target: FormTarget, options?: FormControllerOptions) => FormController newForm: (input: NewFormInput) => FormController | undefined destroyForm: (id: string) => void available: FormsAvailable}form is the same reference exported from @samline/forms. newForm and destroyForm manage the module-level available registry keyed by the form id. Spread browser into a new object to derive a fresh registry (with its own available map); see the getting-started guide for the pattern.
NewFormInput
Section titled “NewFormInput”The argument to FormsApi.newForm.
interface NewFormInput { id: string options?: FormControllerOptions}A missing id logs Form ID is required to console.error and newForm returns undefined without touching the registry.
FormsAvailable
Section titled “FormsAvailable”The shape of FormsApi.available.
interface FormsAvailable { [id: string]: FormController}Use it to inspect or iterate over every live controller in the registry. Each entry is the FormController returned by newForm for that id.