Skip to content
Tier

Confirm field

Pro

A second entry that has to equal the first: a new password, an email typed twice, a name typed to confirm. It says "Matches" or "Doesn't match yet" under the field once the person stops typing (600 ms after the last key) or leaves the field, never per key, so nothing nags while they type. The words are in a polite live region that is there from the start, so each judgement is read once. Nothing is said while the field is empty. A standing "Matches" is withdrawn at once when either entry changes, so it is never shown for entries that no longer match.

Whether a mismatch stops a submit is the app's: onMatchChange tells it each time the judgement changes, and false at once when a match is withdrawn, including by the field going while it stood.

The second entry is the field's own, starting at defaultValue, unless you control it with entry and onEntryChange: then setting entry="" resets it, and its judgement goes with it (a key resets an uncontrolled one). An entry you set yourself is judged at once. The two entries are compared as Unicode text, after normalize("NFC"), so a name typed with a combining accent matches the same name typed with an accented letter; case and spacing still count, since the first entry is the one to type.

Markdown
Version 5.2.0· other versions

This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).

Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2, 4.1.0, 4.2.0 and 4.3.0: the page came later, or had another name then.

Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.

Preview

Loading the preview

Install

With the Candor CLI

First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/confirm-field

Brings in: input, label, locale, motion, tokens, utils

Usage

TSX · The example above
"use client"

import * as React from "react"
import { Field } from "@/components/candor/ui/field"
import { Input } from "@/components/candor/ui/input"
import { ConfirmField } from "@/components/candor/ui/confirm-field"

// The second entry is judged once the person pauses or leaves the field, never per key. Whether a mismatch stops the
// submit is the app's.
export default function Example() {
  const [password, setPassword] = React.useState("")
  const [matches, setMatches] = React.useState<boolean | null>(null)
  return (
    <div className="flex w-full max-w-sm flex-col gap-4">
      <Field label="New password">
        <Input type="password" autoComplete="new-password" value={password} onChange={(e) => setPassword(e.target.value)} />
      </Field>
      <ConfirmField label="Confirm new password" type="password" autoComplete="new-password" value={password} onMatchChange={setMatches} />
      <p className="text-xs text-muted-foreground">The app can save: {matches === null ? "not judged yet" : matches ? "yes" : "no"}</p>
    </div>
  )
}

<ConfirmField>

PropTypeDefaultDescription
valuerequiredstring—The first entry, which this one has to equal.
labelrequiredstring—The field's name: "Confirm password".
onMatchChange((matches: boolean) => void) | undefined—Called with whether the entries match, each time the judgement changes (after a pause or on leaving the field), and with `false` at once when a standing match is withdrawn because either entry changed, or because the field went (a `key` reset it, or it unmounted).
entrystring | undefined—The second entry, what the person has typed, when you control it. Set it to `""` to reset the field: nothing is then said. Left out, the field keeps its own, starting at `defaultValue`.
onEntryChange((entry: string) => void) | undefined—Called with the second entry as the person types.

Also takes the props of Omit<React.ComponentProps<typeof Input>, "value">.

Strings

The fixed words, in English by default. Change any of them under confirmField in <LocaleProvider strings={{ … }}>; the table is exported as confirmFieldStrings.

KeyEnglish
matchesMatches
noMatchDoesn't match yet

Motion

MomentFamilyWhat it does
matchmark, drawA tick draws beside "Matches" when the entries first match after the person pauses or leaves the field; never per key.

Set with --cd-motion-confirm-field-<moment>-* in your brand file; the families are in the design reference.