VoiceConsentCheck
StableA live check that the person whose voice or likeness is being copied is present and agrees, by reading prompted lines aloud.
Also known as voice consent, voice verification, consent check
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
The whole check
Confirm this is your voice
- Agree, current
- Check
- Read lines
- Result
Before you start
What it is for: reading your own articles aloud in the Reader app.
Who can use it: only you. Nobody else in your team can pick it.
How to remove it: Settings, then Voices, then Delete. It stops working at once.
Next you will read 3 short lines out loud. Nothing is recorded until you press Start.
<VoiceConsentCheck step={step} lines={lines} currentLine={line} consentText={terms}
recording={recording} level={level} noise={noise} manualReviewHref="/help/manual-review"
onAgree={() => setStep("micCheck")} onCheckAgain={checkMic} onContinue={() => setStep("reading")}
onStartLine={startRecording} onStopLine={stopRecordingAndAdvance}
onCancel={cancel} onDone={close} />Agree, check the mic (the first check is noisy here; Check again clears it), read three lines, then checking and verified. Timers stand in for the app.
When to use it
Makes cloning a voice or a likeness need the person's own live participation and informed agreement, not just a checkbox.
Made of: Title · Step bar and step name · Step heading · Step body (terms, level, line, result) · Manual review link · Actions
Use it for
- Verifying a voice before it is cloned.
- Verifying a person's face and voice before their likeness is used in video (subject="likeness").
- Re-checking consent after a failed or expired verification.
Not for
- Approving a single action an agent wants to take: use ApprovalPrompt.
- Asking for mic or camera permission alone: use PermissionPrompt.
- Picking a voice that is already verified: use VoicePicker.
Do and avoid
Confirm this is your voice
- Agree, done
- Check, done
- Read lines, current
- Result
Read line 1 of 2
Read this once, then press Stop.
The orange boat drifted past the quiet harbour at noon.
Space also starts and stops.
Line 1 of 2: The orange boat drifted past the quiet harbour at noon.
Do
- Say plainly what the voice or likeness is for, who can use it and how to remove it, before anything is recorded.
- Use fresh lines for each attempt so a saved recording cannot pass.
- Keep the samples after a failed check, and say so.
- Give an exact retry time when locked out, and a way to reach a person.
Avoid
- Do not let a checkbox alone stand in for consent. The live reading is the check.
- Do not colour the person's level meter lime. It is their voice, not the AI.
- Do not use amber for the Recording label. Amber is only for the noisy room, where the person must act.
- Do not offer to clone a famous or someone else's voice.
On a phone
- Fills the width. Put it in a full-screen Sheet on a phone.
- Lines are set large (22px, 26px from 640px wide) so they are easy to read at arm's length.
- Action buttons share the row equally on a phone, and checkboxes are 44px tall on touch.
- Recording stops if the page goes to the background, and a note asks the person to read the line again.
Seen in products
- ElevenLabs voice cloning uses a voice captcha: the speaker reads prompted lines live, with a limited number of attempts and a 24-hour lockout.
- ElevenLabs advises reading each line once and offers manual verification for people who fail or cannot do the live check.
- Apple Personal Voice checks for background noise and offers Check Again or Continue, and lets people choose whether apps may use the voice.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| steprequired | "explain" | "micCheck" | "reading" | "checking" | "verified" | "failed" | "lockedOut" | none | The step to show. |
| linesrequired | string[] | none | Lines to read aloud, one at a time. |
| currentLinerequired | number | none | Index of the line being read. |
| subject | "voice" | "likeness" | "voice" | Likeness changes the copy to cover the camera as well as the mic. |
| consentTextrequired | ReactNode | none | What it will be used for, who can use it and how to remove it. Shown first, and again on success. |
| recording | boolean | false | True while the current line is being recorded. |
| level | number | 0 | Input level from 0 to 1, shown as quiet, speaking or loud. |
| noise | "ok" | "noisy" | none | Mic check result. Leave out while listening. |
| attemptsLeft | number | none | Tries left, shown after a failed check. At 0, Try again is hidden. |
| retryAt | string | none | When the person may try again, written out by your code. |
| onAgreerequired | () => void | none | The box is ticked and Agree and continue pressed. |
| onContinue | () => void | none | Continue, or Continue anyway when noisy. |
| onCheckAgain | () => void | none | Check again after a noisy result. |
| onStartLinerequired | () => void | none | Start recording the current line. |
| onStopLinerequired | () => void | none | Stop recording. Also called when the page goes to the background. |
| onRetry | () => void | none | Try again after a failed check. |
| onCancelrequired | () => void | none | Cancel, or Close when locked out. |
| onDone | () => void | none | Done after success. |
| manualReviewHref | string | none | Link to a check by a person, for anyone who cannot read aloud. |
| supportHref | string | none | Support link, shown when locked out. |
| headingLevel | 2 | 3 | 4 | 5 | 6 | 2 | Level of the step heading. |
| className | string | none | Extra classes for the panel. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one VoiceConsentCheck switches all of this from its properties panel, across 56 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Step | step | Explain, MicCheck, Reading, Checking, Verified, Failed, LockedOut |
| Subject | subject | Voice, Likeness |
| Recording | recording | On or off |
| Noise | noise | OK, Noisy |
States
States this part has beyond its default look. Build each one your screen can reach. States set by a property are in the Code tab.
- explain
- What will happen and why, the terms, and a tick box. Continue without ticking shows an error in words.
- mic check
- A three-step level reading, quiet, speaking or loud. A noisy room shows an amber note with Check again and Continue anyway.
- reading
- One line to read aloud, large. Recording is marked in red with the word Recording; Space starts and stops it when focus is not on a control.
- checking
- The recording is being compared. A spinner and the word Checking; focus stays on the step heading.
- verified
- The voice or likeness is confirmed: a plain success message and what happens next.
- failed
- The check did not match. The samples are kept, and the number of tries left is shown.
- locked out
- After too many tries: the exact time to try again, from your code, and a link to support. No retry button.
Tokens
Change one of these and every part that uses it follows.
--surface--surface-sunken--border--fg--fg-muted--warning-soft--warning-fg--success-fg--danger--danger-fg--radius-card--dur-base--dur-fast
Built in
- The panel is a section named by the step heading. When the step changes, focus moves to the new heading.
- One polite status message per change. While reading, it carries the line itself, so each line is read out once.
- Space starts and stops recording from anywhere in the panel that is not a control or a field. On the Start or Stop button Space works as usual.
- The steps are an ordered list with the current one marked and "done" or "current" written for screen readers.
- The level meter has a value in words (quiet, speaking, loud) and three still steps, never a moving wave.
- Recording and Not recording are written in words. The new line slides in only when motion is allowed.
- The agreement box shows an error in words if Continue is pressed without it.
What you need to do
- Always pass manualReviewHref, so people who cannot read aloud or use a camera have another way in.
- Work out retryAt in code and write it in full, such as "14:20 tomorrow". The model must never make up the time.
- On a phone, show it in a full-screen Sheet or Dialog.
- Make the lines new for each attempt, short, and free of words that are hard to say.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide