ViraStack
  • Academy
  • About
  • Support
HomeGet StartedExamples

Getting started

  • Introduction
  • Upgrade from 1.0
  • llms.txt
  • llms-full.txt

Usage

  • useViraPassword()
  • Strength
  • Confirm password
  • React Hook Form
  • Accessibility
  • Customization

Server

  • Server validation
  • Leaked passwords

Reference

  • Helpers
  • Types
  • UI libraries
  • Comparison

Confirm password

Repeat-password fields with the same hook and matchWith.

Basic usage

There is no separate hook. Give the confirm field matchWith: matches is true, false, or null while the field is empty. Both values are compared after NFKC, like on the server.

Repeat the password.

// components/new-password-fields.tsx
"use client";
 
import { useState } from "react";
 
import { useViraPassword } from "@virastack/password";
 
export function NewPasswordFields() {
  const [password, setPassword] = useState("");
 
  const { inputProps, btnProps } = useViraPassword({
    inputProps: { value: password, onChange: (event) => setPassword(event.target.value) },
  });
  // Same hook with matchWith. Each field keeps its own show/hide button.
  const {
    inputProps: confirmProps,
    btnProps: confirmButton,
    matches,
  } = useViraPassword({ matchWith: password });
 
  return (
    <>
      <label htmlFor={inputProps.id}>New password</label>
      <div>
        <input {...inputProps} />
        <button {...btnProps} />
      </div>
 
      <label htmlFor={confirmProps.id}>Confirm password</label>
      <div>
        <input {...confirmProps} />
        <button {...confirmButton} />
      </div>
 
      <p aria-live="polite">
        {matches === null && "Repeat the password."}
        {matches === true && "Passwords match."}
        {matches === false && "Passwords don't match."}
      </p>
    </>
  );
}

rule

rule.validate always reads the latest matchWith, so the same object can go into register(). To re-check the confirm field when the password changes, see deps.

const password = useWatch({ control: form.control, name: "password" })
const { inputProps, rule } = useViraPassword({ matchWith: password })
 
<input {...inputProps} {...form.register("confirm", rule)} />
// "password.mismatch" when the values differ (an empty confirm fails too)

Shared visibility

Each field has its own toggle. To show both at once, control them with one state:

const [visible, setVisible] = useState(false)
 
const shared = { visible, onVisibleChange: setVisible }
 
const passwordField = useViraPassword(shared)
const confirmField = useViraPassword({ ...shared, matchWith: password })
PreviousStrengthNextReact Hook Form

On this page

  • Basic usage
  • rule
  • Shared visibility
Something wrong? Fix it