Forms
- Several core components are used under the hood to construct form inputs and fields.
- We generally recommend the Formik adapters for most cases.
- Accessory components are helpful for creating layouts and providing supplementary functionality.
- Our form components are built to leverage native attributes and behaviors as much as possible.
- Check out out our suggestions for writing validation text.
Formik adapters
We recommend these field components that include a lot of functionality out of the box:
- Labels
- Helper text
- Formik integration
- Validation text handling
Component | Purpose | Documentation |
---|---|---|
Checkbox | Field for a checkbox input | |
NumberField | Field for a number input | |
Radio | Field for a radio input | |
SelectableCard | Field for a SelectableCard | |
SelectField | Field for a select input | |
SubmitButton | A specialized submit button with a loading state | |
Switch | Field for boolean toggle switches | |
TextAreaField | Field for a textarea input | |
TextField | Field for a text input |
Accessory components
These accessory components are frequently used when creating form layouts.
Core inputs and fields
Workbench forms are built using several building-block components. These are typically abstracted when using the field components, but they are provided here as a reference.
This example uses all of our Formik-adapted components, our recommended approach to building forms. Remember to import from the @gusto/workbench-formik
package when using this pattern.
- We suggest
Grid
for form layout. Following this approach, each form field will become its own row, which is the suggested approach when designing and building for responsive design; side-by-side layouts should be avoided except where the format is expected (dates, phone numbers, etc.). - We currently suggest a
rowGap
of 3 spacing units. A suggested form width is still being established, but632
is a good suggestion for the time being. - The
Actions
component is a container responsible for organizing primary, secondary, and tertiary actions in a consistent UI.
Each of the TextField
s and the Actions
container will render as a row.
<Form><Grid maxWidth={632} autoRows="max-content" rowGap={3}><TextFieldrequiredname="name"label="Full name"helperText="Please use your full name. You may use initials for your middle name(s)"/><TextFieldrequiredname="email"label="Email address"helperText="Please enter your email address."/><TextFieldname="preferredName"label="Preferred name"helperText="Enter an alternate name if you prefer to be called something else."/><Actions justifyContent="center"><SubmitButton>Submit</SubmitButton><Button>Back</Button></Actions></Grid></Form>
See the Forms pattern page to learn more about form anatomy, interactions, states, and UX writing guidelines.
The following testing snippet(s) offer suggestions for testing the component using React Testing Library with occasional help from Jest.
const onReset = jest.fn();const onSubmit = jest.fn(e => e.preventDefault());render(<Form onSubmit={onSubmit} onReset={onReset}><button type="submit">Submit</button><button type="reset">Clear</button></Form>,);const submitButton = screen.getByRole('button', {name: 'Submit',}) as HTMLButtonElement;const resetButton = screen.getByRole('button', {name: 'Clear',}) as HTMLButtonElement;userEvent.click(submitButton);expect(onSubmit).toHaveBeenCalledTimes(1);expect(onReset).not.toHaveBeenCalled();fireEvent.reset(resetButton.form as HTMLFormElement);expect(onReset).toHaveBeenCalledTimes(1);