Match Field

Shows which character a confirmation stops matching at, without revealing either value, so a mistyped password or account number is caught.

StopsMistyped confirm password or account number

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/match-field.json

The files land in your project. They're yours to edit.

Usage

match-field-usage.tsx
import { MatchField } from "@/components/ui/match-field"

<MatchField
  kind="account"
  defaultValue="50100234567812"
  defaultConfirmValue="50100234567182"
  hint="Digits only. It's hidden once you move on."
  onMatchChange={setReady}
/>

What it catches

  • Confirmation that differs from the first entry, with the mismatch position
  • Paste into the confirm box copied from the first box
  • Match state reported through onMatchChange

Props

MatchField props
PropTypeDefault
kind

`password` masks both entries; `account` is for bank account numbers (digits only, masked once you leave the field).

"password" | "account""password"
label

Label for the first entry.

stringkind === "account" ? "Account number" : "New password"
confirmLabel

Label for the confirmation entry.

stringkind === "account" ? "Re-enter account number" : "Confirm…
hint

Helper text under the first entry.

string—
value

Controlled value of the first entry.

string—
defaultValue

Initial value of the first entry when uncontrolled.

string""
defaultConfirmValue

Initial value of the confirmation entry, e.g. when restoring a draft form.

string""
onValueChange

Called with the first entry on every change.

(value: string) => void—
onMatchChange

Called whenever the two entries start or stop matching.

(matches: boolean) => void—
maskFirst

When to mask the first entry. Defaults to `always` for passwords and `blur` for accounts.

"always" | "blur" | "never"kind === "account" ? "blur" : "always"
blockPaste

`"copied"` (default) refuses paste or drop into the confirm field only when it is a copy of the first entry, so a typo can't be copied across while password managers and pasting from a saved source keep working (NIST…

boolean | "copied""copied"
name

Name of the first input, for native form submission.

string—
messages

Override any of the status texts.

Partial<MatchFieldMessages>—

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Both inputs have visible labels; the confirm box has aria-invalid on mismatch and is described by the status
  • Match status and paste notices are polite live regions
  • The position marker is aria-hidden; the status text says where it differs

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: Validate the account number or password again on the server; the match check is client-side only.

  • Only compares the two entries; it can't know the first one is what the user meant
  • Doesn't validate password strength or account-number checksums

What it stops

Mistyped confirm password or account number

Also known as

confirm password · re-enter · confirm account number · verify · signup · bank details · beneficiary · repeat field

Dependencies

Pairs well with