# Destructive Confirmation Input

Type-to-confirm field for destructive actions that keeps the verification phrase exactly as written.

---

## Default

Renders the `To confirm, type …` prompt above an input. The verification phrase is shown verbatim: the prompt is never title cased, and neither the prompt nor the typed value is rewritten by browser translation, autocorrect, autocapitalization, spellcheck, or autocomplete.

```tsx
import { DestructiveConfirmationInput } from '@vercel/geistcn/components';
import { useState, type JSX } from 'react';

export function Component(): JSX.Element {
  const [value, setValue] = useState('');

  return (
    <div className="w-full max-w-[420px]">
      <DestructiveConfirmationInput
        onChange={(e) => setValue(e.target.value)}
        value={value}
        verificationLabel="domain name"
        verificationPhrase="vercel-site.com"
      />
    </div>
  );
}
```

## With error

The caller owns the value and the mismatch rule. Pass `error` to surface a message below the input.

```tsx
import { DestructiveConfirmationInput } from '@vercel/geistcn/components';
import { useState, type JSX } from 'react';

const VERIFICATION_PHRASE = 'next-year-boilerplate';

export function Component(): JSX.Element {
  const [value, setValue] = useState('next-year');
  const [touched, setTouched] = useState(true);
  const mismatch = touched && value !== '' && value !== VERIFICATION_PHRASE;

  return (
    <div className="w-full max-w-[420px]">
      <DestructiveConfirmationInput
        error={mismatch ? 'The project name must match exactly.' : null}
        onBlur={() => setTouched(true)}
        onChange={(e) => {
          setValue(e.target.value);
          setTouched(false);
        }}
        value={value}
        verificationLabel="project name"
        verificationPhrase={VERIFICATION_PHRASE}
      />
    </div>
  );
}
```

## Best Practices

### When to use

* Use `DestructiveActionModal` when the confirmation fits its fixed layout. Reach for this component only when a destructive flow needs content that modal can't render, such as a list of affected resources, a refund breakdown, or a sheet instead of a modal.
* Use it for every type-to-confirm gate. Don't hand-roll the prompt with an `Input` `label`: `Label` title cases its text, which changes the phrase the user is asked to type.

### Behavior

* The caller decides when the gate opens. Compare the value to `verificationPhrase` with `===` and keep the destructive button disabled until it matches.
* The ref is forwarded to the `<input>`, so it works with `react-hook-form`'s `register` and with manual focus management.

### Content

* `verificationPhrase`: for entity deletes, use the **resource name itself** (`my-project`) and pair it with `verificationLabel="project name"` so the prompt reads `To confirm, type the project name "my-project"`. Fall back to a lowercase verb phrase (`disable vercel authentication`) only when there's no entity to name.
* Name the noun in mismatch errors: `The project name must match exactly.`.

### Accessibility

* The input is associated with its prompt via `aria-labelledby` and `htmlFor`, so screen readers announce the full prompt, including the phrase, on focus. Don't pass a separate `aria-label`.
