Skip to content

Forms

Workbench provides a collection of components to build forms on Gusto. Formik adapters are provided to simplify data management and validation.
Figma logo
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
Workbench components wrapped with Formik
ComponentPurposeDocumentation
CheckboxField for a checkbox input
NumberFieldField for a number input
RadioField for a radio input
SelectableCardField for a SelectableCard
SelectFieldField for a select input
SubmitButtonA specialized submit button with a loading state
SwitchField for boolean toggle switches
TextAreaFieldField for a textarea input
TextFieldField for a text input
Accessory components

These accessory components are frequently used when creating form layouts.

The collection of accessory components used when building forms with Workbench
ComponentPurposeDocumentation
ActionsOrganizes calls to action at the bottom of a page (typically buttons)
BoxProvides provides spacing, layout, and color helpers
ButtonUsed for secondary actions
CharacterCountOffers immediate validation for text fields with character limits
GridBuilds layouts based on CSS grids
useIdGenerates random strings; useful for populating the id attribute to create relationships between elements
visuallyHiddenUsed to hide form field labels
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.

The collection of form components in Workbench
ComponentPurposeDocumentation
CheckboxGroupCheckbox wrapped in a Field with label, helper, and validation text
CheckboxInputPlain checkbox input
FieldWraps inputs with a label, helper text, and validation text.Storybook logo
FieldGroupWraps a group of inputs with one label, helper, and validation textStorybook logo
FormGeneric wrapper around the form elementStorybook logo
InputBasic text fieldStorybook logo
NumberFieldNumberInput wrapped in a Field with label, helper, and validation text
NumberInputPlain number input
RadioRadioInput wrapped in a Field with label, helper, and validation text
RadioInputPlain radio input
SelectPlain select inputStorybook logo
SelectFieldSelect wrapped in a Field with label, helper, and validation text
SubmitButtonA specialized submit button with a loading state
SwitchSwitchInput wrapped in a Field with label, helper, and validation text
SwitchInputA toggle input for toggling boolean values
TextAreaPlain textarea fieldStorybook logo
TextAreaFieldTextArea wrapped in a Field with label, helper, and validation text
TextFieldText Input wrapped in a Field with label, helper, and validation text

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, but 632 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 TextFields and the Actions container will render as a row.

<Form>
<Grid maxWidth={632} autoRows="max-content" rowGap={3}>
<TextField
required
name="name"
label="Full name"
helperText="Please use your full name. You may use initials for your middle name(s)"
/>
<TextField
required
name="email"
label="Email address"
helperText="Please enter your email address."
/>
<TextField
name="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);