Skip to main content


Used to collect form field information.


import { Input } from '@pluralsight/react'


  1. Form Control
  2. Label
  3. Input
  4. Message


Valid Example

Live Editor

Invalid Example

For invalid form fields, add the invalid prop to the FormControlProvider component and add an ErrorMessage component.

Easy form field states

Since the FormControlProvider manages the validity state of each form field, you don't have to worry about managing the child components as they will automatically update to reflect the current state.

Live Editor

Date Picker

When you need to collect a known date, combine the Input with the useAutoFormatDate custom hook.

Calendar Pickers are not accessible

Calendar Pickers should only be used when the UX requires choosing a date that is unknown to the user.

Check out the Maybe You Don't Need a Date Picker article for more information.

What about type="date"?

Contrary to the rest of the HTML element APIs, the type="date" option for an input is not accessible. This is a known issue in the community and forces fully accessible applications to use the text value instead.

Live Editor

Password Input

Live Editor


Live Editor


There are 3 ways to customize the Input component.

1. Unused Classes

Each component layer of the Input has a unused class name that can be utilized in your local CSS to customize the Input at any level.

  1. pando-input: The element of the Input.
  2. pando-input-wrapper: The wrapper element of the Input.
  3. pando-input-start-icon: The start icon element of the Input.
  4. pando-input-invalid-icon: The invalid icon element of the Input.

2. Passing a className prop

You can pass a className prop to the Input component to customize the Input. This is useful if your project uses CSS Modules or a CSS-in-JS library like Emotion.

Example of using CSS Modules to customize the Input.
import customStyles from './customStyles.module.css'

function CustomInput(props) {
return <Input className={customStyles.custom} {...props} />

3. Ejected Input

For a low-level "ejected" approach, you can use the Headless-styles API to customize the Input however you prefer while keeping the accessibility behavior.

import {
} from '@pluralsight/headless-styles'

To learn more about the Headless-styles API, check out the Headless-styles documentation.



Do use the WarningTriangleFilled Icon for all invalid input fields.

Don't use any other Icon to represent an invalid input field.

Do stack form fields vertically when displaying a set.

Don't use more than one form field within the same row.


Do use the "(required)" text flag on all required form field labels.

Don't use a "*" to represent a required field; this pattern is not accessible.



interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
describedBy?: string
id: string
name: string
size?: 'm' | 'l'
startIcon?: ElementType
  1. describedBy - The id of the FieldMessage or ErrorMessage that describes the input.
  2. id - The id of the input.
  3. name - The name of the input.
  4. size - The size of the input.
  5. startIcon - The icon to display at the start of the input.

Size Mapping

Input size rules.
m: 'Use in condensed areas where the default size is too large.',
l: 'Should be used in most, if not all cases.'


The Pando Input is fully accessible and screen-readable through the following features:

  1. The aria-invalid attribute is set to true when the input is invalid.
  2. The aria-describedby attribute is set to the id of the FieldMessage or ErrorMessage that describes the input.
  3. The aria-required attribute is set to true when the input is required.