Skip to main content

An official website of the United States government

Here's how you know

An official website of the United States government

Here's how you know

Theme:

Design system switcher

Version:

Design system switcher

Theme:

Design system switcher

Version:

Design system switcher

Label-Masked Field

A label-masked field is a text-field pattern that provides instant, visual feedback about how inputed data is being interpreted without creating a noisy aural experience.

Examples

This component mirrors user input as formatted "hint text" after the label to provide visual feedback about the data as the user is typing. The text in the input field itself will not be formatted until the field loses focus, which is when we know the user has finished typing.

Because the hinting isn't being applied to the input itself, it's less distracting and obtrusive to screen reader users, providing a quieter and more usable experience for everyone. It is an updated alternative to our Masked Field.

The label-mask currently has five built-in implementations: currency, phone number, Social Security Number, ZIP code, and date. The date mask is implemented by the Calendar Picker and Single-Input Date Field components, while the rest are available for direct use with the Text Field component.

Currency

Loading

Phone number

Loading

Social Security number

Loading

ZIP code

Loading

Code

React

Passing a labelMask prop into a TextField component with a valid masking function will turn it into a label mask. You can either import one of the named, built-in mask functions (SSN_MASK, ZIP_MASK, PHONE_MASK, or CURRENCY_MASK), or you can provide a custom mask function. The following table shows the TextField prop that is specific to label masks:

Preact/React documentation for Storybook

Handling input changes

When tracking state in a parent component, treat the value as a raw input string, which is updated by the onChange handler. Do not try to unmask or clean the value before passing it back to the TextField component instance. The intention with this is to keep the API and behavior of the component as simple as possible. You don't need to handle onBlur separately from onChange. You only need to update your value when onChange is called, and it will be called whenever the value of the input changes, including on blur. A more appropriate place to clean the input would be in your validation code.

// A simplified example of change handling. This is not a recommendation
// for how to structure error messages or validation code but serves only
// to illustrate how to set and get values from the label-masked field.

import { useState } from "react";
import { Button, TextField, SSN_MASK } from '@cmsgov/design-system';

export const MyForm = () => {
  const [value, setValue] = useState('');
  const [error, setError] = useState();

  function validate() {
    if (!isValidSsn(value)) {
      e.preventDefault();
      setError('You have entered an invalid SSN.');
    }
  }

  return (
    <form onSubmit={validate}>
      {error && <Alert variation="error">{error}<Alert>}
      <TextField
        label="Social security number (SSN)"
        labelMask={SSN_MASK}
        name="ssn_example"
        value={value}
        onChange={setValue}
      />
      <Button type="submit">Submit</Button>
    </form>
  )
};

Guidance

When to use

  • In fields with a specific expected format like Social Security Number or ZIP code, a label mask allows you to constrain and shape the information being entered without impairing the user's ability to copy/paste or correct mistyping

When to consider alternatives

  • When the input requires a free-form field that doesn't use a common input pattern, masking is not appropriate.
  • When the pattern is too complicated to allow for a valid label mask. A pattern like email, with many possible scenarios for input, is not a good candidate for masking. Allow the user to enter their email address (or other complicated data) and have your validation library confirm before form submission.

Usage

  • Only show error validation messages or stylings after a user has interacted with a particular field

Accessibility

Learn more

Component maturity

This component meets 100% of our maturity criteria.

What does this mean?

Each component is tested against the following items to gauge the component's maturity. When using incomplete components, consider the unmet criteria as applied to your product.

For more information about how we tested and validated our work for each checklist item, read our component maturity documentation.