Text Input
betaTextInput is a low-level native input for collecting a short, single-line text value. It supports common text-entry types and native input attributes while providing consistent UluBit styling and states.
TextInput represents only the input control. The consuming interface remains responsible for providing its visible label and, when needed, associated instructions, hint text, and validation messages.
Enter an email address in the correct format.
Basic usage
Associate every TextInput with a visible label using matching for and id values. Do not use placeholder text as a replacement for a label.
---
import { TextInput } from "@ulubit/ui";
---
<label for="full-name">
Full name
</label>
<TextInput
id="full-name"
name="fullName"
autocomplete="name"
/>Types
The component supports text-entry input types:
textemailpasswordsearchtelurl
Use the type that best matches the value being collected.
<TextInput
id="email"
name="email"
type="email"
autocomplete="email"
/>Autocomplete
Provide an appropriate autocomplete token when the field collects information
that browsers can safely reuse.
<TextInput
id="name"
name="name"
autocomplete="name"
/>The autocomplete value describes the purpose of the information, which may differ from the input type.
Invalid state
Set aria-invalid="true" after the field has failed validation.
Connect the written error message using aria-describedby.
<TextInput
id="email"
name="email"
type="email"
aria-invalid="true"
aria-describedby="email-error"
/>
<p id="email-error">
Enter an email address in the correct format.
</p>Do not rely on the invalid border alone to explain the error.
When an invalid input receives focus, the invalid border remains visible while the focus outline continues to use the shared focus color.
Disabled and read-only
Use disabled when the control is unavailable.
Use readonly when users may inspect or copy the value but cannot change it.
Disabled and read-only inputs use the disabled input background. Disabled inputs also use reduced opacity and cannot be interacted with.
Width
TextInput fills the available inline space of its containing element.
The parent layout should constrain fields that should not span the full page.
<div class="name-field">
<TextInput
id="name"
name="name"
/>
</div>Color tokens
TextInput uses component-level color tokens from the UluBit color system for its background, text, placeholder, border, and interaction states.
The tokens below show the default values provided by @ulubit/foundations.
--color-input-bg: var(--color-bg);
--color-input-bg-disabled: var(--color-bg-dark);
--color-input-text: var(--color-text);
--color-input-placeholder: var(--color-text-muted);
--color-input-border: var(--color-neutral-500);
--color-input-border-hover: light-dark(
var(--color-neutral-600),
var(--color-neutral-400)
);
--color-input-border-focus: var(--color-focus);
--color-input-border-invalid: var(--color-danger);The default input border is intentionally stronger than the general --color-border token because the boundary identifies the interactive control.
The hover border becomes stronger according to the active color scheme.
The focus border and outline use --color-input-border-focus, which resolves to the shared semantic --color-focus token by default.
Invalid inputs use --color-input-border-invalid, which resolves to the semantic --color-danger token.
Overriding color tokens
Override only the tokens that need to change. Set them globally to change all text inputs, or scope them to a class or parent element for a local customization.
For example:
.custom-input {
--color-input-border: var(--color-brand-600);
--color-input-border-hover: var(--color-brand-700);
--color-input-border-focus: var(--color-brand-800);
}<TextInput
id="project-name"
name="projectName"
class="custom-input"
/>Tokens that are not overridden continue to use their defaults.
When overriding border or focus colors, verify that the resulting control boundary and focus indicator remain clearly visible against the surrounding background.
API
| Property | Type | Default | Description |
|---|---|---|---|
type |
"text" | "email" | "password" | "search" | "tel" | "url" |
"text" |
Defines the text-entry input type. |
id |
string |
— | Identifies the input and connects its label and descriptions. |
name |
string |
— | Defines the submitted form field name. |
autocomplete |
string |
— | Identifies the input purpose for browser autofill. |
disabled |
boolean |
false |
Makes the control unavailable and excludes it from submission. |
readonly |
boolean |
false |
Prevents editing while retaining the value as form data. |
aria-invalid |
"true" | "false" |
— | Communicates whether the current value is invalid. |
aria-describedby |
string |
— | Connects hint or error content to the input. |
class |
string |
— | Adds a consumer class to the native input. |
Other valid native input attributes, including required, value,
placeholder, inputmode, minlength, maxlength, pattern, form,
aria-*, and data-*, are forwarded to the underlying input.
Current limitations
The component does not render:
- Labels
- Hint text
- Error messages
- Prefixes or suffixes
- Leading or trailing icons
- Password visibility controls
- Validation logic