# React Input Mask

A React input mask for AdminKit PRO: MaskedInput formats dates, amounts, license plates and IP addresses as you type, with Inputmask on an uncontrolled input.

> This component is only available in **AdminKit PRO**. [Learn more](/pricing/#react).

An input mask helps people type a value in the right format, such as a date or an amount. `MaskedInput` is a text input that only accepts that format. It applies [Inputmask](https://github.com/RobinHerbots/Inputmask) 5 to a plain `<input type="text">`, and it is part of the PRO version of [AdminKit for React](/react/).

Inputmask loads only when a page needs it. The first `MaskedInput` imports it with a dynamic `import()` when it appears on the page. Vite then puts Inputmask in its own chunk, and pages without a masked input never load it.

## Example

Give `mask` a mask string, or an object with Inputmask's options, such as an `alias`:

```html
<div class="mb-3">
  <label class="form-label" for="maskDate">Date</label>
  <input type="text" class="form-control" id="maskDate" data-inputmask-alias="datetime" data-inputmask-inputformat="dd/mm/yyyy" aria-describedby="maskDateHelp">
  <div class="form-text" id="maskDateHelp">e.g "DD/MM/YYYY"</div>
</div>
<div>
  <label class="form-label" for="maskPlate">License plate</label>
  <input type="text" class="form-control" id="maskPlate" data-inputmask-mask="[9-]AAA-999" aria-describedby="maskPlateHelp">
  <div class="form-text" id="maskPlateHelp">e.g "9-ABC-123"</div>
</div>
```
```tsx code
import { MaskedInput } from "@/components/plugins/masked-input";

export function VehicleFields() {
  return (
    <>
      <div className="mb-3">
        <label className="form-label" htmlFor="maskDate">Date</label>
        <MaskedInput
          className="form-control"
          id="maskDate"
          mask={{ alias: "datetime", inputFormat: "dd/mm/yyyy" }}
          aria-describedby="maskDateHelp"
        />
        <div className="form-text" id="maskDateHelp">e.g "DD/MM/YYYY"</div>
      </div>
      <div>
        <label className="form-label" htmlFor="maskPlate">License plate</label>
        <MaskedInput
          className="form-control"
          id="maskPlate"
          mask="[9-]AAA-999"
          aria-describedby="maskPlateHelp"
        />
        <div className="form-text" id="maskPlateHelp">e.g "9-ABC-123"</div>
      </div>
    </>
  );
}
```

In a mask string, `9` is a digit, `A` a letter (shown in upper case) and the part in `[ ]` is optional.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `mask` | `string \| MaskOptions` | | A mask string, or Inputmask's options (`mask`, `alias`, `regex` and any other option); read once, when the input mounts |
| `ref` | `Ref<HTMLInputElement>` | | The input element, merged with the ref the component uses itself |

Other props, such as `className`, `id`, `name`, `placeholder` and `defaultValue`, go to the `<input>`. `type` is `"text"` unless you pass another one. The component is in `src/components/plugins/masked-input.tsx`.

## Aliases

Inputmask has aliases: ready-made masks for common formats. The Advanced Inputs demo uses these masks:

| Field | `mask` | Example |
| --- | --- | --- |
| Date | `{ alias: "datetime", inputFormat: "dd/mm/yyyy" }` | 31/12/2026 |
| Date | `{ alias: "datetime", inputFormat: "mm/dd/yyyy" }` | 12/31/2026 |
| Currency | `{ alias: "numeric", groupSeparator: ",", digits: 2, digitsOptional: false, prefix: "€ ", placeholder: "0" }` | € 9.95 |
| Decimal | `{ alias: "decimal", groupSeparator: "," }` | 123,456,789 |
| IP address | `{ alias: "ip" }` | 123.123.123.123 |
| Email | `{ alias: "email" }` | support@adminkit.io |

```html
<label class="form-label" for="maskCurrency">Amount</label>
<input type="text" class="form-control" id="maskCurrency" data-inputmask="'alias': 'numeric', 'groupSeparator': ',', 'digits': 2, 'digitsOptional': false, 'prefix': '$ ', 'placeholder': '0'">
```
```tsx code
<label className="form-label" htmlFor="maskCurrency">Amount</label>
<MaskedInput
  className="form-control"
  id="maskCurrency"
  mask={{
    alias: "numeric",
    groupSeparator: ",",
    digits: 2,
    digitsOptional: false,
    prefix: "$ ",
    placeholder: "0",
  }}
/>
```

The [Inputmask README](https://github.com/RobinHerbots/Inputmask) lists every option.

## Reading the value

`MaskedInput` is uncontrolled. Inputmask writes the input's value itself, so do not pass `value`. Give the input a `name` and read it from the form when it is submitted, or keep a `ref`:

```tsx
import { type FormEvent, useRef } from "react";
import { MaskedInput } from "@/components/plugins/masked-input";

export function PhoneForm() {
  const phone = useRef<HTMLInputElement>(null);

  const onSubmit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    console.log(phone.current?.value); // "(555) 123-4567"
  };

  return (
    <form onSubmit={onSubmit}>
      <label className="form-label" htmlFor="phone">Phone</label>
      <MaskedInput ref={phone} className="form-control mb-3" id="phone" name="phone" mask="(999) 999-9999" />
      <button type="submit" className="btn btn-primary">Save</button>
    </form>
  );
}
```

The value includes the mask's literal characters. The `mask` is read once. To change it, render a new input with a different `key`.

## Accessibility

- Label the input with `<label htmlFor>` and its `id`, as with any text field.
- The mask is not announced. Put the expected format in visible help text and link it with `aria-describedby`, as the examples do.
- Set `inputMode` (`"numeric"`, `"decimal"`, `"email"`) where it fits, so mobile keyboards show the right keys.

## Related

- [Next.js input mask](/nextjs/docs/forms/input-mask/): the same component in AdminKit for Next.js
- [Bootstrap 5 input mask](/bootstrap/docs/forms/input-mask/): the input mask of the HTML version
- [Form controls](/react/docs/forms/form-control/): plain inputs and textareas
- [Advanced Inputs demo](https://react-demo.adminkit.io/forms-advanced-inputs)

---

Canonical HTML page: https://adminkit.io/react/docs/forms/input-mask/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
