Form

React

composes together:

  • state management
  • ,
    , etc. components
  • Show and edit views, discretely known as
    ,
    ,
  • Two layout styles
  • Conditionally rendered components, noted by a third subcomponent
    pattern

Usage

Peer Dependency is Required
The dependency "formik" is required for this component, hook, and context to work.

Example

Create and Update

There is currently no visual difference between

and
. In the future that could change anywhere within the
, like displaying meta data only on
views. Today they exist for flexibility of a field in a workflow. More about customizing between the "edit" views can be read in the props per view.

Read

Validation

Validation runs each submit. Failed validation will prevent form submission and update error messages.

The recommended validation method is

with a Yup schema. They are extremely expressive and allow modeling complex, interdependent validations, or value transformations. Validation on the
level opposed to
guarantees fields are validated even if they are unmounted.

Yup Validation

From Formik documentation:

We use Yup for object schema validation. It has an API that's pretty similar to Joi and React PropTypes but is small enough for the browser and fast enough for runtime usage. Because we ❤️ Yup sooo much, Formik has a special config option / prop for Yup object schemas called

which will automatically transform Yup's validation errors into a pretty object whose keys match values and touched. This symmetry makes it easy to manage business logic around error messages. -- Formik, The Palmer Group

The following examples show some cases of

, more information can be found from the Yup documentation.

Required Yup Validation

Using a Yup required schema,

, will result with a required marker automatically include on the field. The auto include marker feature may not work with complex Yup schemas.

Inputs that can clear a value with an

button will result with a
value. To assure the error message is correct and using your translated requried text when null, add
to the object's schema.

Conditional Yup Validation

Async Yup Validation

Props

Not recommended alternatives.

I suggest using

and Yup for validation. However, validate is a dependency-free, straightforward way to validate your forms. -- Formik

Resources:

  • https://formik.org/docs/api/formik#validate-values-values--formikerrorsvalues--promiseany
  • https://formik.org/docs/guides/validation#validate

You can run independent field-level validations by passing a function to the validate prop.

Note: The components'

function will only be executed on mounted fields. That is to say, if any of your fields unmount during the flow of your form, those fields will not be validated during form validation/submission. -- Formik

This cannot be used in collapsible sections.

Resources:

  • https://formik.org/docs/api/field#validate
  • https://formik.org/docs/guides/validation#validate-1

Initial Errors

A form can mount with errors based on the navigation experience or technical constraints.

Submission

A

inside the
tag (
component) will trigger submission. If any validations fail, the submission will not continue.

It is recommended to use the promise path for submission. Promise submission is required when using

to 'clean up' after submission. More about Formik submission.

returns

Submission promise will provide a success and an error callback. State changes like toggling

and removing the
event will be updated automatically in the component.

If the

function is
and it returns
, it will always be considered a success.

If the

function is synchronous and it returns
, it will never reset certain states.

Confirm Navigation

Setting the prop

to
will have
apply a
listener to prevent losing unsaved changes, and after a successful submission it will remove the listener. The
must be notified after successful submission by calling the promise success callback in the
function. The browser warning of unsaved data when leaving a page will not work in Safari.

Review Tearsheet docs to learn how this prop works in tandem with a

or
trying to close.

Customization

Width Examples

Column spans and column placements should align or be confirmed with the Design System.

  • with

Props Per View

Using a self-closing tag with a field, e.g.

, it will have uniformity across
,
, and
views, i.e. this field has all the same properties like
and
across views. When a field needs to have different props per view, we can customize with the third subcomponent pattern.

Conditionally rendered subcomponents based on

, a way to differenciate a field based on form state. The same rules apply for
apply to
,
, etc. Using children of
we can customize the props per view. However, the form will make no assumptions about the number of child and the field on create, read, update view, you need to explicitly place
,
, and
if you want all views once using the
API. By placing common props on the parent and specific props on the child, each view can be customized. (Behind the scenes,
switched from rendering HTML and is now a context provider for shared props).

What is the difference between

and
? That is for the client to decide! Both
and
use the same layout and input components. Depending on the UX and context of the field in a workflow, aspects might change with the field. If the create and update views are always identical, it is possible to stick to one view variant for both "edit" views.

The third tier subcomponent props are nearly identical to the second tier,

, except for
. Anything on this level like
,
,
will trump props on
or
. For example, when the global state is
or
, a
could overwrite it with
or
, while all other fields in the form are in their respective
view.

is capable of letting the client customize the "input component" for a field while keeping the layout closed. The key thing at play is the
API.

prop with a Component

If using TypeScript, these components will need to extend a specific type from Core React, documented below.

prop with a object of Components

It is possible to create custom components for the input and output of a value. Leveraging the

prop as an object with keys of each of the view states,
,
,
. It is recommended to define this object outside of render, as it should be a static object we can keep the same memory reference for React context performance gains. (Outside of render in a functional component means top level in a file, outside of the function scope. The entire function is the render! Moving the object above the
but inside the functional component does not keep the same memory reference each render.)

TypeScript and
prop components

The input and output components for

inside the layout are typed to extend and receive the
prop with the field API. It will be necessary to import and
the type in an
. The type of
will default to
. To supply the value's type, pass the type as a generic arg.

prop

The children of a field, e.g.

, should be another subcomponent of the same field, e.g.
, to customize props on a particular view.

prop

It only makes sense here for

to be a Component.
will ever only pick the
key from the object.

If you are separating a form into distinct files like

,
,
and hard setting a constant
state, each of those files would use a consistent subcomponent.

prop

The

at the third level is a more typical React prop, like text, JSX, or a callback function that receives the
API.

Props

The provider from Formik. Additional props from Formik's

as well as the ones stated here.

NameTypeRequiredDefaultDescription
children
ReactNode | (() => ReactNode)
true
since

10.19.0

disabled
boolean
false

Disable all fields at once.

default

false

enableConfirmNavigation
boolean
false

Enable a browser confirmation about losing of unsaved data when the form values are visually different from the initial values. Uses window.onbeforeunload and window.confirm for dialogs(Modal, Tearsheet). Requires onSubmit to return a promise to remove onbeforeunload.

a11y

To prevent accidental data loss, it is recommended to enable.

default

false

Accessibility notes:
To prevent accidental data loss, it is recommended to enable.
onSubmit
((values: Values, formikHelpers: FormikHelpers<Values>) => void | Promise<any>)
false
viewfalse

Determines show or edit state of form.

default

'create'

Formik's

component.

This component toggles between a

tag on edit views and a
on show views. When on
, the
will only apply
and
props.

More information about steps of submission.

Leveraging the HTML

element allows simple form submission. The
component will automatically receive the
's
and
and apply it to the
tag. Leveraging the
tag, we can use a button with
for submission. Otherwise it will be required to call the
hook or use
as a render prop function to access the submit handler.

A nicety of leveraging the HTML spec inside React like this:

An app can freely change all the children (React or DOM nodes) of a

, and as long as the
is still present in the React tree, all the values will appear in onSubmit when the button is triggered.

Rendering a

onto the document around
components is more semantically correct. Assistive technologies and browser plugins can discover
elements and implement special hooks to make them easier to use [source].

Note: It's strictly forbidden to nest a

inside another
. Nesting can cause forms to behave in an unpredictable manner based on the browser that is being used. [source]

Contextual conditional error banner. Will only display when errors are present and contains predifined text for create and update views. Will not display on the read view.

NameTypeRequiredDefaultDescription
i18nScope
string
false
since

10.19.0

item
string
true
since

10.19.0

Each row is a CSS grid, based on a 12 column system.

All fields take these general props.

NameTypeRequiredDefaultDescription
asfalse

Customize the input component, either a single component for all views or an object with the keys of the views to render on that particular view. This input component will receive the field prop. If using TypeScript, these components will need to extend a specific type from Core React, read more about the props per view

One of:

ReactComponent or { '{ read: ReactComponent, create: ReactComponent, update: ReactComponent }' }

since

10.19.0

children
ReactElement<BaseFieldProps<Value, FormFieldValueComponentProps<Value>>, string | JSXElementConstructor<any>> | ReactElement<BaseFieldProps<Value, FormFieldValueComponentProps<Value>>, string | JSXElementConstructor<any>>[]
false
since

10.19.0

colStart
1 | 10 | 8 | 2 | 3 | 4 | 5 | 12 | 6 | 7 | 9 | 11
false

Starting location of column.

since

10.19.0

colWidth
1 | 10 | 8 | 2 | 3 | 4 | 5 | 12 | 6 | 7 | 9 | 11
false

Width of column.

default

6

since

10.19.0

data-qa
string
false
since

10.19.0

description
ReactNode
false
since

11.25.0

disabled
boolean
false

Specify disabled. Field disabled replaces the overall Form disabled state.

since

10.19.0

error
string | boolean
false
since

10.19.0

label
string
false
since

10.19.0

name
string
true

Key path in store. Accepts bracket[notation] or dot.notation.

since

10.19.0

required
boolean
false

The required asterisk if not using Yup required

<Form
 validationSchema={Yup.object().shape({
   input_name: Yup.mixed().required(),
 })}
>
since

10.19.0

tooltip
any
false
since

10.19.0

validate
FieldValidator
false

The validate function from Formik for single field validation.

(value: Value = any) => undefined | string | Promise<Value>
since

10.19.0

viewfalse

Determines show or edit state of field.

since

10.19.0

Specific types of fields include:

props and
props.

props and
props.

props. A series of several checkboxes. Similiar to a multiselect.

NameTypeRequiredDefaultDescription
checked
boolean
false

Checked state of the checkbox

since

10.19.0

children
ReactNode
false

The contents of the checkbox label

since

10.19.0

className
string
false

Additional classNames

since

10.19.0

disabled
boolean
false

Disabled state of the checkbox

since

10.19.0

error
boolean
false

Error state of the checkbox

since

10.19.0

fieldtrue
hasRequiredMark
boolean
false
since

11.25.0

i18nScope
string
false
since

10.19.0

indeterminate
boolean
false

Indeterminate state of the checkbox

since

10.19.0

inlineLabel
string
false

Next to checkbox label

since

11.25.0

requiredMark
boolean
false

Whether to show requiredMark

since

11.25.0

tooltip
any
false
since

11.25.0

props and
props.

is about a single checkbox, while the HTML checkbox input type is designed for a series of checkboxes. Traditionally with checkboxes,
is
while
is
, where
is the
of each
input. This pattern does not fit well with boolean backed data. The form state is oriented towards "yes/no" friendliness and is stored as a boolean not array. The value in store will be
or
and the
on the DOM will be
or
".

props and
props.

props and
props.

Unlike

which only accepts date objects,
can have a
as a date object or string in the ISO format:
. Like
, date changes will be a date oject or
. Be careful when providing string values, the string will be the argument to
.

The following examples were ran in California during DST

Format with
results in UTC midnight
Format with
results in local midnight
Format ISO results in local midnight
Format zoned time results in UTC midnight
Leading zeros on two digit entries are required

props and
props.

props and
props.

props and
props.

props and
props.

props and
props.

NameTypeRequiredDefaultDescription
afterHide
((e?: Event) => void)
false
afterShow
(() => void)
false
beforeHide
BeforeCallback
false
since

10.19.0

beforeShow
BeforeCallback
false
since

10.19.0

block
boolean
false

Make the Select button 100% width

since

10.19.0

container
HTMLElement | ShadowRoot
false
since

10.19.0

disabled
boolean
false
default

false

since

10.19.0

emptyMessage
string
false

When there are no children this will render

since

10.19.0

fieldtrue
footer
ReactNode
false
since

10.19.0

header
ReactNode
false
since

12.15.0

hideDelay
number
false
since

10.19.0

i18nScope
string
false

The i18n key to use for the select's configurable strings. Defaults to using the core library's default strings.

since

10.19.0

loading
boolean
false

If the select is loading

default

false

since

10.19.0

onClear
false | ((event: MouseEvent<HTMLButtonElement, MouseEvent>) => void)
false
since

10.19.0

onScrollBottom
((e: UIEvent<HTMLDivElement, UIEvent>) => void)
false
onSelect
((selection: Selection) => any)
false
optgroupsfalse

Array of available option groups

since

10.19.0

optionsfalse

Array of available options

since

10.19.0

optionsRef
RefObject<HTMLDivElement>
false
since

10.19.0

placeholder
string
false

Renders when the label is blank

since

10.19.0

placementfalse

The placement of the overlay

default

'bottom-left'

since

10.19.0

qa
Partial<QaTags>
false
since

10.19.0

restoreFocusOnHide
boolean | "core-react" | "react-aria-focus-scope"
false

Restore focus to the target after the overlay is hidden. 'core-react' will use internal logic to restore focus, 'react-aria-focus-scope' will use 'FocusScope' component from '@react-aria', true will use both.

default

'core-react'

since

12.11.0

showDelay
number
false
since

10.19.0

tabIndex
number
false

Configurable tabIndex for the select button

default

0

since

10.19.0

getColorfalse

A function returning the display color of an option's Pill (option: unknown) => PillColor

defaultvalue

(option) => (option as PillOption).color

since

10.19.0

getGroupfalse

A function returning group ID for a given option to define a relation to optgroups (option: unknown) => string | number

defaultvalue

(option) => (option as PillOption).groupId

since

10.19.0

getIdfalse

A function returning ID of a given option (option: unknown) => string | number

defaultvalue

(option) => (option as PillOption).id

since

10.19.0

getLabelfalse

A function returning label of an option (option: unknown) => string

defaultvalue

(option) => (option as PillOption).label

since

10.19.0

getSuggestedfalse

A function returning boolean value to suggest this option if nothing is selected. (option: unknown) => boolean

defaultvalue

(option) => (option as PillOption).suggested

since

10.19.0

groupGetIdfalse

A function returning the ID of a group (group: unknown) => string | number

defaultvalue

(group) => (group as PillOptgroup).id

since

10.19.0

groupGetLabelfalse

A function returning label of a group (group: unknown) => string

defaultvalue

(group) => (group as PillOptgroup).label

since

10.19.0

onSearchfalse

Adds a search bar to the select.

since

10.19.0

props. A series of several radio buttons. Similiar to a single select.

NameTypeRequiredDefaultDescription
className
string
false

Additional classNames

fieldtrue
options
Value[]
false
since

10.19.0

style
CSSProperties
false

Additional CSS styles

getIdfalse

The id of an option

since

10.19.0

default

(option: OptionItem) => option.id

getLabelfalse

The display label of an option

(option: OptionItem) => string

Default:

(option: OptionItem) => option.label || option.name

since

10.19.0

isDisabledOptionfalse
since

10.19.0

props and
props.

props and some
props.
has an API closer to
than
. It uses getters and an array of options. Automatic searching of options and the clear icon are enabled by default.

NameTypeRequiredDefaultDescription
afterHide
((e?: Event) => void)
false
afterShow
(() => void)
false
beforeHide
BeforeCallback
false
since

10.19.0

beforeShow
BeforeCallback
false
since

10.19.0

block
boolean
false

Make the Select button 100% width

since

10.19.0

container
HTMLElement | ShadowRoot
false
since

10.19.0

disabled
boolean
false
default

false

since

10.19.0

emptyMessage
string
false

When there are no children this will render

since

10.19.0

fieldtrue
footer
ReactNode
false
since

10.19.0

header
ReactNode
false
since

12.15.0

hideDelay
number
false
since

10.19.0

i18nScope
string
false

The i18n key to use for the select's configurable strings. Defaults to using the core library's default strings.

since

10.19.0

label
ReactNode
false
since

10.19.0

loading
boolean
false

If the select is loading

default

false

since

10.19.0

onClear
false | ((event: MouseEvent<HTMLButtonElement, MouseEvent>) => void)
false

Callback for when cleared. Default enabled, has clear icon.

since

10.19.0

onScrollBottom
((e: UIEvent<HTMLDivElement, UIEvent>) => void)
false
onSearch
false | ((event: ChangeEvent<HTMLInputElement>) => void)
false

Callback for when searching. Default enabled, has seach bar in menu.

since

10.19.0

onSelect
((selection: Selection) => any)
false
optgroups
GroupItem[]
false

Array of available option groups

since

10.19.0

options
OptionItem[]
false
since

10.19.0

optionsRef
RefObject<HTMLDivElement>
false
since

10.19.0

placeholder
string
false

Renders when the label is blank

since

10.19.0

placementfalse

The placement of the overlay

default

'bottom-left'

since

10.19.0

qa
Partial<QaTags>
false
since

10.19.0

restoreFocusOnHide
boolean | "core-react" | "react-aria-focus-scope"
false

Restore focus to the target after the overlay is hidden. 'core-react' will use internal logic to restore focus, 'react-aria-focus-scope' will use 'FocusScope' component from '@react-aria', true will use both.

default

'core-react'

since

12.11.0

showDelay
number
false
since

10.19.0

tabIndex
number
false

Configurable tabIndex for the select button

default

0

since

10.19.0

getGroupfalse

Callback for each entry in options to define relation to group in optgroups (option: OptionItem) => string | number

since

10.19.0

getIdfalse

The id of an option

since

10.19.0

default

(option: OptionItem) => option.id

getLabelfalse

The display label of an option

(option: OptionItem) => string

Default:

(option: OptionItem) => option.label || option.name

since

10.19.0

groupGetIdfalse
since

10.19.0

groupGetLabelfalse

The display label of a group (group: GroupItem) => string

Default: (group: GroupItem) => group.label || group.name

since

10.19.0

groupHeaderRendererfalse

Callback for rendering header for each entry in optgroups (group: GroupItem) => React.ReactNode

since

10.19.0

deprecated

The groupHeaderRenderer prop is deprecated and will be removed in a future version. Use groupRenderer instead to customize the entire group rendering, including the header.

deprecatedsince

12.39.0

groupRendererfalse

Callback for rendering group wrapper for each entry in optgroups (group: GroupItem) => React.ReactNode

since

12.39.0

isSuggestedOptionfalse

If nothing is selected, suggest this option. From Select.Option suggested. (option: OptionItem) => boolean

since

10.19.0

onBlurfalse
since

10.19.0

optionRendererfalse

Callback for rendering each option (option: OptionItem) => React.ReactNode

since

10.19.0

searchComparatorfalse

Customize how search works (query: string, value: string) => boolean

since

10.19.0

API

Type

Based on Formik input. Useful when working with native HTML form elements and accessing the

or
. Core React does not supply the checkbox properties from Formik.

Directly from Formik helpers. Setter methods tied to the field.

Mostly Formik meta with some Core React customization. The

property is when to show the error, it is currently a combination of Formik's
and
. The pending error message will be under
. Added properties like
,
, and
.

From Core React, informational messages about the field. Today it only contains

. It is possible to have a value for
but
be
. This is because the meta is when to notify the user of an error.