A complete, controlled single-line text field: label, the input (with optional addons/inline elements), and helper/error text, wired together via FormComponent. Built on the Input primitive.
Use @uxf/form/text-input inside a @uxf/form form — it wires up react-hook-form (registers the field, runs required/email/phone/url validation, and reads the form context). For a standalone, controlled text field outside a form, use @uxf/ui/text-input.
For full control over the field's internal layout, drop down to the Input primitive.
import { TextInput } from "@uxf/ui/text-input";
import { useState } from "react";
function Example() {
const [value, setValue] = useState("");
return (
<TextInput
helperText="Helper text"
label="Website"
leftAddon="https://"
name="website"
onChange={setValue}
placeholder="Some beautiful placeholder..."
rightAddon=".cz"
value={value}
/>
);
}
onChange receives the new value first, then the change event: (value: string, event?) => void.
Extends FormControlProps<string> and picks size / variant from Input.
| Prop | Type | Default | Description |
|---|---|---|---|
value * | string | — | Current value. |
onChange * | (value: string, event?) => void | — | Called with the new value. |
name * | string | — | Field name. |
label | ReactNode | — | Label text (rendered above the field). |
hiddenLabel | boolean | false | Visually hides the label (kept for screen readers). |
helperText | ReactNode | — | Helper/error text below the field. Styled as an error when isInvalid. |
placeholder | string | — | Placeholder text. |
type | "email" | "number" | "password" | "search" | "tel" | "text" | "url" | "time" | — | Native input type. |
leftAddon / rightAddon | ReactNode | — | Content attached outside the field border. |
leftElement / rightElement | ReactNode | — | Content rendered inside the field. |
isInvalid | boolean | false | Invalid state (error styling, aria-invalid, links aria-describedby to the helper text). |
isDisabled | boolean | false | Disabled state. |
isReadOnly | boolean | false | Read-only state. |
isRequired | boolean | false | Marks the field required (label marker). |
isFocused | boolean | — | Forces the focused visual state. |
size | InputGroupSize | "default" | "small", "default", or "large". |
variant | InputGroupVariant | "default" | Input group variant. |
autoComplete | string | — | Native autocomplete. |
autoFocus | boolean | false | Focus on mount. |
enterKeyHint | "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | — | Virtual keyboard enter-key hint. |
inputMode | "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | — | Virtual keyboard hint. |
id, form | string | — | Native attributes. id is auto-generated if omitted. |
maxLength, minLength | number | — | For text-like types. |
min, max, step, pattern | number | string | — | For type="number". |
onBlur, onFocus | FocusEventHandler<HTMLInputElement> | — | Focus handlers. |
onKeyDown, onPaste, onBeforeInput | event handler | — | Native events. |
className | string | — | Extra class on the root element. |
style | CSSProperties | — | Inline style on the input wrapper. |
* required
The forwarded ref points to the underlying <input>.
| Group | Values |
|---|---|
variant | default |
size | small, default, large |
Behavioural states are set via isInvalid, isDisabled, isReadOnly, isRequired, and isFocused.
Import the component stylesheets once in your global CSS:
@import url("@uxf/ui/css/input-basic.css");
@import url("@uxf/ui/css/input.css");
@import url("@uxf/ui/css/form-component.css");
@import url("@uxf/ui/css/label.css");
Also requires the global @uxf/ui token layer, set up once per app — see @uxf/ui setup.
If an addon or inline element renders an Icon, also import @uxf/ui/css/icon.css.