Text field
ListensTextField@listenssoft/speechui-reactA single-line input users can type into — or dictate into: “name Jane Doe”.
Say the command and keep talking: the field claims the phrase and streams the remainder into its value as you speak, filtered by type — emails lose their spaces and gain an @, numbers parse from words, names capitalize. When listening stops, onMatch fires once with the final value.
Basic dictation
Loading the React kit…
Hold anywhere and say:“name jane doe”“name arthur dent”
Props
- default command
- not set
import { ListensTextField } from "@listenssoft/speechui-react";import { useState } from "react";
function Demo() { const [name, setName] = useState(""); return ( <ListensTextField label="Name" command="name" type="name" placeholder="Jane Doe" value={name} onChange={(e) => setName(e.target.value)} onMatch={setName} /> );}Value types filter the dictation
type shapes what lands in the value: email converts a spoken “at” to @ and strips spaces (“email jane at example dot com” — say “dot” as “.” is up to the recognizer); number parses spoken numbers (“age forty two” → 42); letters drops digits; name capitalizes each word; url strips spaces.
Loading the React kit…
Hold anywhere and say:“email jane at example.com”“age forty two”
import { ListensTextField } from "@listenssoft/speechui-react";import { useState } from "react";
function Demo() { const [email, setEmail] = useState(""); const [age, setAge] = useState(""); return ( <div style={{ display: "grid", gap: 12 }}> <ListensTextField label="Email" command="email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} onMatch={setEmail} /> <ListensTextField label="Age" command="age" type="number" value={age} onChange={(e) => setAge(e.target.value)} onMatch={setAge} /> </div> );}What you can say
| Say | Effect |
|---|---|
| “name jane doe” | Starts-with match: claims the phrase and streams “jane doe” into the value as you speak (filtered by type). |
| “the name is jane doe” | Contains fallback: if no other control claimed the phrase, sets the value to the words after the command (“is jane doe”). The command with nothing after it leaves the value unchanged. |
| “f i v e” | Spelled-out runs collapse to words before filtering (“five”). |
While you keep speaking, interim results keep updating the value — dictation feels live, not batched. onMatch fires exactly once, when listening stops, with the final accumulated value.
API reference
React props for @listenssoft/speechui-react.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | "text" | "email" | "number" | "letters" | "date" | "url" | "name" | "text" | Filters dictated text (see the types demo) and sets the input's behavior where it maps to a real HTML type. |
listeningContent | ReactNode | command | Content shown as the label above the input while the mic is open — a place for a hint like “say: volume to seventy”. |
Extra props
| Prop | Type | Default | Description |
|---|---|---|---|
command | string | label | The spoken prefix that starts dictation. Falls back to label. |
label | string | — | Label text shown above the input; the command fallback. |
onMatch | (value: string) => void | — | Fires once when listening stops, with the final accumulated value. The place to commit dictation. |
…InputHTMLAttributes (minus type) | input props | — | value, onChange, placeholder, disabled, name, id and the rest are forwarded to the native <input>. |
classNames | ListensTextFieldClassNames | — | Per-part class overrides (label, listeningLabel, input). Each is appended after the component's own classes, so your rules win without extra specificity. |
Styling hooks
classNames parts and CSS classes
| Hook | Type | Default | Description |
|---|---|---|---|
classNames.label / .listens-text-field-label | class | — | The label. listeningLabel is added alongside while the mic is open. |
classNames.input / .listens-text-field-input | class | — | The native input. |
.listens-text-field | class | — | Root wrapper. Defaults live in @layer listens — your CSS wins unlayered. |
Behavior notes
- All frameworks: A starts-with match claims the transcript, so a field named “name” won't also trigger a button whose command appears later in the same phrase.





