Skip to main content

Form Label

Used to display a text label for a form field.

Import

import { Label } from '@pluralsight/react'

Anatomy

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

Usage

To keep your forms accessible, always use a Label for your form fields. This ensures that screen readers can properly read the form field and that users can click on the Label to focus the form field when they are not visually hidden.

Optional Label

function BasicFormLabel() {
  const [email, setEmail] = useState('')

  function handleChange(e) {
    setEmail(e.target.value)
  }

  return (
    <FormControlProvider>
      <Label htmlFor="email">Email</Label>
      <Input
        describedBy="email:help"
        id="email"
        name="email"
        onChange={handleChange}
        placeholder="email@example.com"
        type="email"
        value={email}
      />
      <FieldMessage id="email:help">
        We will never share your email.
      </FieldMessage>
    </FormControlProvider>
  )
}

Required Label

To make a field required, pass the required prop to the FormControlProvider component.

function RequiredFormLabel() {
  const [email, setEmail] = useState('')

  function handleChange(e) {
    setEmail(e.target.value)
  }

  return (
    <FormControlProvider required={true}>
      <Label htmlFor="email">Email</Label>
      <Input
        describedBy="email:help"
        id="email"
        name="email"
        onChange={handleChange}
        placeholder="email@example.com"
        type="email"
        value={email}
      />
      <FieldMessage id="email:help">
        We will never share your email.
      </FieldMessage>
    </FormControlProvider>
  )
}

Hidden Label

To make a label visually hidden, pass a hidden value to the kind prop on the Label component.

function BasicFormLabel() {
  const [search, setSearch] = useState('')

  function handleChange(e) {
    setSearch(e.target.value)
  }

  return (
    <FormControlProvider>
      <Label htmlFor="search" kind="hidden">
        Search
      </Label>
      <Input
        id="search"
        name="search"
        onChange={handleChange}
        placeholder="Search for anything..."
        type="text"
        value={search}
      />
    </FormControlProvider>
  )
}

Customizing

There are 3 ways to customize the Label component.

1. Unused Classes

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

  1. pando-label: The element of the Label.

2. Passing a className prop

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

import customStyles from './customStyles.module.css'

function CustomLabel(props) {
  return <Label className={customStyles.custom} {...props} />
}

3. Ejected Label

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

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

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

Behavior

Patterns

Do stack form fields vertically when displaying a set.

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

Usage

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.

API

Parameters

interface FormLabelProps extends LabelHTMLAttributes<HTMLLabelElement> {
  htmlFor: string
  kind?: 'default' | 'hidden'
}
  1. htmlFor: string - The id of the form field that the label is associated with.
  2. kind: string - The kind of label to render. Defaults to default.

Accessibility

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

  1. The htmlFor prop is required to associate the label with the form field.
  2. The kind prop is required to render the label as a hidden label.
  3. Required fields are indicated with a "(required)" text flag which is a more accessible and obvious pattern than using a "*".