@k2b/ui
TextInput
Text, search, password, multiline, Markdown, and AI-marked field modes.
Accessor-controlled text, password, multiline, and AI-marked fields with shared labels, help, errors, native input hints, a shell-wide text cursor, and shell-wide browser autofill.
The package owns the reveal control.
TSX
Copy<TextInput label="Project" value={project} onValueChange={setProject} clearable icon="ti ti-folder" /><TextInput label="Token" description="The package owns the reveal control." value={token} onValueChange={setToken} password icon="ti ti-lock" autocomplete="current-password" /><TextInput label="Notes" value={notes} onValueChange={setNotes} multiline lines={3} icon="ti ti-notes" /><TextInput label="AI prompt" value={prompt} onValueChange={setPrompt} variant="ai" /><TextInput label="Expiry (placeholder)" value={expiresAt} onValueChange={setExpiresAt} placeholder="2027-01-01T00:00:00Z" icon="ti ti-calendar" /><TextInput label="Expiry (entered value)" value="2027-01-01T00:00:00Z" icon="ti ti-calendar" /><TextInput label="Amount text" value={amountText} onValueChange={setAmountText} icon="ti ti-number" suffix="EUR" inputMode="decimal" /><TextInput label="Clearable amount text" value={amountText} onValueChange={setAmountText} icon="ti ti-number" suffix="EUR" inputMode="decimal" clearable />TextInput is the standard labeled text field for portable application forms.
The parent owns the value, validation, persistence, and form submission.
Use TextInput
Use it for short text, search terms, email addresses, URLs, telephone numbers, passwords, and small multiline fields.
Use MarkdownEditor for a standalone document editor. Use AutocompleteEditor when completion behavior is the main interaction rather than ordinary form input.
Import
import { TextInput } from "@k2b/ui";Value and events
Pass value directly or as a Solid accessor. onValueChange receives every
edit. onValueCommit receives the committed string, normally when the field
loses focus.
clearable adds a clear button to a single-line field. Without onClear,
clearing emits an empty string through both value callbacks.
Input modes
typesupports text, search, email, URL, and telephone input.multilinerenders a plain textarea.markdownrenders the sharedMarkdownEditorand implies multiline input.passwordadds a show or hide control.variant="ai"changes the field treatment and default icon. It does not add AI behavior.- Without
icon, the field shows a text-cursor icon that turns into a pencil while focused. A customiconstays while focused unlessactiveIconsets a different one. monospace,prefix, andsuffixadapt the field to code-like values and short units.
Enter calls onSubmit in single-line fields and in plain multiline mode, where Shift+Enter inserts a newline. In markdown mode, Ctrl/Cmd + Enter calls onSubmit; bare Enter stays available for writing.
Field state
label, description, required, and error form one field. disabled
disables the input and its controls.
The complete visible input shell keeps the text cursor across leading icons, affixes, and padding. Prefixes and suffixes keep space from the field edges, including when no clear or password control is present. Clear and password controls retain their action cursor.
spellcheck and maxLength pass through in every mode, including markdown. autocomplete and autocapitalize reach the native input and textarea only, not the markdown editor. inputMode applies to the single-line input.
Browser autofill remains enabled for native single-line inputs. While the
browser reports an autofilled value, TextInput extends one semantic surface
across the input, leading icon, affixes, and clear or password control. Editing
the value returns the field to its regular visual state.
Touch devices
On a device whose primary pointer is coarse, such as a phone, the editable text
of every @k2b/ui field renders at 16 px instead of the compact desktop size.
This covers TextInput in every mode, number, tag, PIN, and combobox fields,
the search fields inside selects and prompts, the time field of the date
pickers, the editors, and the chat composer. iOS Safari zooms the page when a
focused field uses smaller text and leaves it zoomed afterwards.
Only the text grows. The field, its label, and the surrounding layout keep
their size and position, and devices with a mouse or trackpad keep the compact
text. Do not set maximum-scale or user-scalable=no on the viewport to
prevent the zoom; that takes pinch zoom away from people who need it. Give a
field that an application builds itself at least 16 px of text on coarse
pointers for the same reason.
A single-line field for a user name, an address, or a password is typed
exactly. When password is set, type is email or url, or
autocomplete names username, email, or url, the input defaults to
autocapitalize="none", autocorrect="off", and spellcheck={false}, so
phone and tablet keyboards do not capitalize the first letter or replace the
word. An explicit prop wins over the default.
API reference
See shared field props for FieldProps, ValueFieldProps<T> and MaybeAccessor<T>.
type TextInputProps = Omit<
JSX.InputHTMLAttributes<HTMLInputElement>,
"onChange" | "onInput" | "prefix" | "suffix" | "type" | "value" | keyof ValueFieldProps<string>
> &
ValueFieldProps<string> & {
minLength?: number;
maxLength?: number;
type?: "text" | "search" | "email" | "url" | "tel";
variant?: "default" | "ai";
icon?: string;
activeIcon?: string;
prefix?: JSX.Element;
suffix?: JSX.Element;
clearable?: boolean;
onClear?: () => void;
clearLabel?: string;
multiline?: boolean;
monospace?: boolean;
password?: boolean;
markdown?: boolean;
onSubmit?: () => void;
lines?: number;
abbreviations?: Record<string, string>;
completions?: readonly Completion[];
};type="text", variant="default" and lines=3 are the defaults. Boolean modes are off unless enabled. completions and abbreviations apply to Markdown mode; see completion data. Native input attributes apply to the ordinary input; Markdown mode uses the editor contract.
Accessibility
Prefer a visible label. When the surrounding layout cannot render one, pass
"aria-label"; a placeholder is not a persistent label.
Descriptions and errors are connected to the input. The error message is announced as a live alert. Clear and password controls have accessible names.
Runtime
The field renders in server HTML. Editing, clearing, password visibility, markdown behavior, and callbacks require browser code.
Example
const [query, setQuery] = createSignal("");
<TextInput
type="search"
label="Search projects"
description="Search by name or owner."
icon="ti ti-search"
value={query}
onValueChange={setQuery}
clearable
/>;