How to use in input
There are three ways to declare a controlled input, two using the form system and the other in the traditional way, with useState.
It's important to declare form and fields outside the lifecycle of any component. Declaring them inside a component may cause several issues.
Declaring through a form field
If you have a form with a field, then you should declare your input like this:
import { form, fields } from '@codeleap/form'
const myForm = form('example', {
field1: fields.text({ label: 'Field 1' }),
})
function Form() {
return <TextInput {...myForm.register('field1')} />
}
This is the default path for package-aware inputs in normal form screens.
Declaring through a field
If you don't have a form but have an input and want to take advantage of the full validation system and global value access, then declare your own field and pass it to the input.
All inputs accept this
fieldproperty.
import { fields } from '@codeleap/form'
const fieldExample = fields.text({
label: 'Example',
placeholder: 'Placeholder',
onValueChange: (value) => console.log(value),
})
function Field() {
return <TextInput field={fieldExample} />
}
This is the usual choice for one reusable validated control without a full form object.
Declaring through a custom input
If you are building your own input component, the component should usually accept a specific field type and consume it through useField(...).
import { type TextField, fields, useField } from '@codeleap/form'
type Props = {
field?: TextField<any>
placeholder?: string
}
function TextInput({ field: fieldProp, placeholder }: Props) {
const { value, setValue, validation, options } = useField(fieldProp, [undefined, []], fields.text)
return (
<input
value={value ?? ''}
onChange={(e) => setValue(e.target.value)}
onBlur={validation.onInputBlurred}
placeholder={placeholder ?? options.placeholder}
/>
)
}
Do not flatten register(...) into guessed controlled props before the custom component even receives the field.
Declaring through a useState
If you don't have a form and don't need to use the benefits of a field, then declare using the standard approach.
All inputs receive
onValueChange, and this property should be used.
import { useState } from 'react'
function Component() {
const [value, setValue] = useState('')
return <TextInput value={value} onValueChange={setValue} />
}