Skip to content

Form Control

The Form Control component is a utility that lets you associate a form input with auxiliary components, such as labels, error indicators, or helper text.


Form Control is a utility that wraps an input component with other associated components in order to make the state of the input available to those components.

For instance, you may want to show an additional element asking the user to enter a value if the input is empty, or display a warning icon if the entered value is incorrect.


import { FormControl } from '@mui/base/FormControl';

Form Control wraps around the elements of a form that need access to the state of an <input>. For instance, if the form's Submit button needs to change states after the user enters information, then the component will be structured like this:


The following demo shows how to create and style a form that uses Form Control to wrap the elements of the form. Note that it also uses the useFormControlContext hook in order to pass props to the custom Input—see the Hook section below for more details.

Name *

Press Enter to start editing

Usage with TypeScript

In TypeScript, you can specify the custom component type used in the slots.root as a generic parameter of the unstyled component. This way, you can safely provide the custom root's props directly on the component:

<FormControl<typeof CustomComponent> slots={{ root: CustomComponent }} customProp />

The same applies for props specific to custom primitive elements:

<FormControl<'button'> slots={{ root: 'button' }} onClick={() => {}} />


import { useFormControlContext } from '@mui/base/FormControl';

The useFormControlContext hook reads the context provided by Form Control. This hook lets you work with custom input components inside of the Form Control. You can also use it to read the form control's state and react to its changes in a custom component.

Hooks do not support slot props, but they do support customization props.

The demo below shows how to integrate this hook with its component counterpart:

  • CustomInput is a wrapper around a native HTML <input> that adds Form Control integration.
  • ControlStateDisplay reads the state of the form control and displays it as text.

empty | not focused

Note that even though Form Control supports both controlled and uncontrolled-style APIs (i.e. it accepts value and defaultValue props), useFormControlContext returns only the controlled value. This way, you don't have to implement both in your custom input—Form Control does this for you.


Accessing the form control state

You can access the state of the Form Control by providing a function as a child. The state will be provided as a parameter to this function.

The following demo shows how to access the state of the Form Control in an Input component nested inside:

Press Enter to start editing