Form
Handle user inputs
Example
{ "data": { "name": "", "feedback": "Officia incididunt do officia eiusmod commodo.", "email": "foo@bar.baz", "gender": "", "foo": true, "bar": false, "counter": 0, "nested": { "nested": "nested" }, "submitted": false }, "loading": false, "error": null }
import {
Button,
Container,
Form,
FormGroup,
NumberInput,
SubmitRow,
TextInput,
useForm,
} from 'matterial'
const initialFormVals = {
name: '',
feedback: 'Officia incididunt do officia eiusmod commodo.',
email: 'foo@bar.baz',
gender: '',
foo: true,
bar: false,
counter: 0,
nested: { nested: 'nested' },
submitted: false,
}
export function FormExample() {
const { form, handleChange, setForm } = useForm(initialFormVals)
const handleSubmit = (e: React.SyntheticEvent) => {
e.preventDefault()
handleChange('submitted', true)
}
const handleReset = () => {
setForm({ data: initialFormVals })
}
return (
<>
<Form onSubmit={handleSubmit}>
<FormGroup
label="Full Name"
input={
<TextInput
name="name"
value={form.data.name}
placeholder="Your name"
onChange={handleChange}
/>
}
helperText="Please enter your full name"
/>
<FormGroup
label="Feedback"
input={
<TextInput
name="feedback"
value={form.data.feedback}
multiline={true}
rows={3}
onChange={handleChange}
/>
}
/>
<FormGroup
label="Email Address"
input={
<TextInput
type="email"
name="email"
value={form.data.email}
onChange={handleChange}
/>
}
/>
<CheckButtonGroup>
<CheckButton
name="gender"
value="male"
checked={form.data.gender === 'male'}
onChange={() => handleChange({ gender: 'male' })}
>
👨 Male
</CheckButton>
<CheckButton
name="gender"
value="female"
checked={form.data.gender === 'female'}
onChange={() => handleChange('gender', 'female')}
>
👩 Female
</CheckButton>
<CheckButton
name="gender"
value="other"
checked={form.data.gender === 'other'}
onChange={() => handleChange('gender', 'other')}
>
🧑 Other
</CheckButton>
</CheckButtonGroup>
<Container row>
<Checkbox name="foo" checked={form.data.foo} onChange={handleChange}>
Foo
</Checkbox>
<Checkbox name="bar" checked={form.data.bar} onChange={handleChange}>
Bar
</Checkbox>
</Container>
<Container row>
<Button
variant="outlined"
onClick={() => handleChange('counter', form.data.counter + 1)}
>
Synced Inputs
</Button>
<NumberInput
name="bazDescription"
value={form.data.counter}
readOnly
width="25ch"
/>
</Container>
<Container row>
<TextInput
name="nested.nested"
value={form.data.nested.nested}
onChange={(
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
) => handleChange({ nested: { nested: e.target.value } })}
/>
</Container>
<SubmitRow>
<Button type="submit" variant="contained" color="primary">
Submit
</Button>
<Button type="reset" onClick={handleReset}>
Reset
</Button>
</SubmitRow>
</Form>
<pre className="surface">{JSON.stringify(form, null, 2)}</pre>
</>
)
}
Uncontrolled Forms
Form components are controlled via inputs to the value
or checked
prop. To render an uncontrolled component, simply omit the controlling prop.
<TextInput name="foo" defaultValue="foo" />
<Checkbox name="check" defaultChecked={true}>Check</Checkbox>
Insert Content
Use the prepend
and append
props to add content like icons or additional labels.
required
$
<TextInput name="search" append={<Button><Icon icon="search" /></Button>} />
<TextInput name="required-item" required append={<span style={{color: 'var(--color-error)', paddingRight: 'var(--input-padding)'}}>required</span>} />
<NumberInput name="bones" step="0.01" prepend={<b style={{ marginLeft: 'var(--input-padding)', color: '#00a264' }}>$</b>} style={{ paddingLeft: 'calc(0.2em + var(--input-padding) * 2)' }} />
Width
Use the width
prop to set the width of the input to any CSS unit.
<TextInput name="100-px-width" width={100} />
<TextInput name="search" width="max(50%, 150px)" />