Forms
The createForm function builds a form manager with field definitions, validation, and the ability to render to a Vio node descriptor.
Import
import { createForm } from '@atrotos/vio'createForm Signature
function createForm(config: FormConfig): VioFormParameters
| Name | Type | Required | Description |
|---|---|---|---|
config | FormConfig | Yes | Form configuration with field definitions and optional submit handler |
FormConfig
interface FormConfig {
fields: Record<string, FieldDef>
onSubmit?: (values: Record<string, unknown>) => void
}| Property | Type | Required | Description |
|---|---|---|---|
fields | Record<string, FieldDef> | Yes | Map of field name to field definition |
onSubmit | (values: Record<string, unknown>) => void | No | Callback invoked on form submission |
FieldDef
interface FieldDef {
initial: unknown
validate?: (value: unknown) => string | null
label?: string
type?: string
}| Property | Type | Required | Description |
|---|---|---|---|
initial | unknown | Yes | Initial value for the field |
validate | (value: unknown) => string | null | No | Validation function. Return null for valid, or a string error message. |
label | string | No | Display label for the field |
type | string | No | HTML input type (defaults to 'text') |
Return Type
Returns a VioForm instance.
VioForm Interface
interface VioForm {
getValues(): Record<string, unknown>
setValue(field: string, value: unknown): void
validate(): Record<string, string | null>
isValid(): boolean
reset(): void
toNodeDescriptor(): VioNodeDescriptor
}Methods
getValues()
Returns a shallow copy of all current field values.
getValues(): Record<string, unknown>const values = form.getValues()
console.log(values.email) // '[email protected]'setValue(field, value)
Sets the value of a specific field. The field name must match a key in the fields config. Unknown field names are silently ignored.
setValue(field: string, value: unknown): void| Parameter | Type | Description |
|---|---|---|
field | string | Field name |
value | unknown | New value |
form.setValue('email', '[email protected]')
form.setValue('age', 30)validate()
Runs validation on all fields. Returns an object mapping field names to error messages (string) or null if the field is valid. Fields without a validate function always return null.
validate(): Record<string, string | null>const errors = form.validate()
// { email: null, age: 'Must be at least 18' }isValid()
Returns true if all fields pass validation (all validate functions return null). Fields without a validate function are considered valid.
isValid(): booleanif (form.isValid()) {
submitData(form.getValues())
}reset()
Resets all field values to their initial values as defined in the FieldDef.
reset(): voidform.reset()
// All fields back to initial valuestoNodeDescriptor()
Generates a VioNodeDescriptor representing the form as HTML. Each field is wrapped in a <div class="form-field"> containing an optional <label> and an <input>.
toNodeDescriptor(): VioNodeDescriptorThe generated structure:
{
tag: 'form',
children: [
{
tag: 'div',
props: { class: 'form-field' },
children: [
{ tag: 'label', props: { for: 'email' }, children: ['Email'] },
{
tag: 'input',
props: {
type: 'text',
name: 'email',
id: 'email',
value: 'current-value'
}
}
]
}
// ...one div per field
]
}const LoginForm = defineComponent({
name: 'LoginForm',
state: {},
render: () => form.toNodeDescriptor()
})Full Example
import { createForm, defineComponent, createApp } from '@atrotos/vio'
const form = createForm({
fields: {
username: {
initial: '',
label: 'Username',
validate: (v) => {
if (!v || (v as string).length < 3) return 'Username must be at least 3 characters'
return null
}
},
email: {
initial: '',
label: 'Email',
type: 'email',
validate: (v) => {
if (!v || !(v as string).includes('@')) return 'Invalid email address'
return null
}
},
age: {
initial: 0,
label: 'Age',
type: 'number',
validate: (v) => {
if ((v as number) < 18) return 'Must be at least 18'
return null
}
}
},
onSubmit: (values) => {
console.log('Submitted:', values)
}
})
// Set values
form.setValue('username', 'alice')
form.setValue('email', '[email protected]')
form.setValue('age', 25)
// Validate
const errors = form.validate()
console.log(errors) // { username: null, email: null, age: null }
console.log(form.isValid()) // true
// Get all values
console.log(form.getValues())
// { username: 'alice', email: '[email protected]', age: 25 }
// Render as a component
const SignupPage = defineComponent({
name: 'SignupPage',
render: () => ({
tag: 'div',
children: [
{ tag: 'h1', children: ['Sign Up'] },
form.toNodeDescriptor()
]
})
})
// Reset to initial values
form.reset()
console.log(form.getValues())
// { username: '', email: '', age: 0 }