VayuUI

TextInput

A comprehensive input component with support for text, password, search, numbers, validation states, and icons.

Installation

npx vayu-ui init #one time only
npx vayu-ui add textinput
npx vayu-ui add -t textinput #with test case needs

Usage

TextInput Examples

Basic Input

We'll never share your email.

Required & Optional Fields
Password (with visibility toggle)

Must be at least 8 characters.

Search (with clear button)
Number Inputs

Value constrained between 0 and 10 on blur.

Validation States

Password is weak. Consider adding special characters.

Username is available!

Character Count

0 / 50

Sizes
States
With Form Actions

Choose a unique name for your project.

<TextInput>
  <TextInput.Label>Email Address</TextInput.Label>
  <TextInput.Field>
    <TextInput.Icon>
      <Mail className="w-4 h-4" />
    </TextInput.Icon>
    <TextInput.Input placeholder="Enter your email" />
  </TextInput.Field>
  <TextInput.Description>We'll never share your email.</TextInput.Description>
</TextInput>
// Password Input
<TextInput inputType="password">
  <TextInput.Label>Password</TextInput.Label>
  <TextInput.Field>
    <TextInput.Icon>
      <Lock className="w-4 h-4" />
    </TextInput.Icon>
    <TextInput.PasswordInput placeholder="Enter password" />
  </TextInput.Field>
</TextInput>
// Search Input
<TextInput value={searchValue} onChange={setSearchValue}>
  <TextInput.Label>Search</TextInput.Label>
  <TextInput.Field>
    <TextInput.SearchInput placeholder="Search users..." />
    <TextInput.ClearButton />
  </TextInput.Field>
</TextInput>
// Number Input
<TextInput inputType="number">
  <TextInput.Label>Quantity (0-10)</TextInput.Label>
  <TextInput.Field>
    <TextInput.NumberInput numberType="natural" min={0} max={10} />
  </TextInput.Field>
</TextInput>
// Validation States
<TextInput validationState="error" defaultValue="invalid-email">
  <TextInput.Label>Email</TextInput.Label>
  <TextInput.Field>
    <TextInput.Input />
  </TextInput.Field>
  <TextInput.ErrorMessage>Please enter a valid email address.</TextInput.ErrorMessage>
</TextInput>
// Character Count
<TextInput>
  <TextInput.Label>Bio</TextInput.Label>
  <TextInput.Field>
    <TextInput.Input placeholder="Tell us about yourself" maxLength={50} />
  </TextInput.Field>
  <TextInput.CharacterCount maxLength={50} showCount="always" />
</TextInput>

Anatomy

import { TextInput } from 'vayu-ui';

<TextInput>
  <TextInput.Label />
  <TextInput.Field>
    <TextInput.Icon />
    <TextInput.Input /> {/* Standard Input */}
    <TextInput.PasswordInput /> {/* OR Password Input */}
    <TextInput.SearchInput /> {/* OR Search Input */}
    <TextInput.NumberInput /> {/* OR Number Input */}
    <TextInput.ClearButton />
    <TextInput.LoadingSpinner />
  </TextInput.Field>
  <TextInput.Description />
  <TextInput.ErrorMessage />
  <TextInput.WarningMessage />
  <TextInput.SuccessMessage />
  <TextInput.CharacterCount />
</TextInput>;

Accessibility

  • Keyboard support: Full keyboard navigation. Input fields are accessible via Tab. The internal clear button and password toggle button can be fully operated using Space or Enter.
  • ARIA attributes: Uses aria-invalid for validation states. The label, description, and error messages are programmatically tied to the inputs using aria-labelledby and aria-describedby, correctly mapping compound components behind the scenes.
  • Focus behavior: Clear visual focus indicates the active field based on the internal Field container, not just the Input.

Screen reader behavior

Screen readers will announce the input's label, its current value or a placeholder, any help descriptions, and the validation state error message. For example, a missing required field might be announced as "Email, required, edit text, invalid entry, Email is required."

Component Folder Structure

packages/ui/src/components/ui/TextInput/
├── Input.tsx
├── README.md
├── TextInput.tsx
├── TextInputCharacterCount.tsx
├── TextInputClearButton.tsx
├── TextInputDescription.tsx
├── TextInputErrorMessage.tsx
├── TextInputField.tsx
├── TextInputIcon.tsx
├── TextInputLabel.tsx
├── TextInputLoadingSpinner.tsx
├── TextInputNumberInput.tsx
├── TextInputPasswordInput.tsx
├── TextInputSearchInput.tsx
├── TextInputSuccessMessage.tsx
├── TextInputWarningMessage.tsx
├── index.ts
└── types.ts

Props

TextInput

PropTypeDefaultDescription
valuestring-The controlled state component value.
defaultValuestring""The uncontrolled starting value.
onChange(value: string) => void-Handler that is called when the value changes.
inputType"text" | "email" | "password" | "number" | "tel" | "url" | "search""text"Specifies the primary input style format.
size"sm" | "md" | "lg""md"The size of the input elements.
validationState"default" | "error" | "warning" | "success""default"Defines the current validation styling.
disabledbooleanfalseWhether the input is completely disabled.
readOnlybooleanfalseWhether the input value is read only.
requiredbooleanfalseMarks the field as required.
loadingbooleanfalseVisually marks the input as loading.
classNamestring-Additional class names for styling.

TextInput.Label

PropTypeDefaultDescription
optionalbooleanfalseDisplays an internal "Optional" hint next to the label.
classNamestring-Additional class names for styling.

TextInput.Input

PropTypeDefaultDescription
leftIconReactNode-Deprecated/Alternative icon passing.
rightIconReactNode-Deprecated/Alternative icon passing.
typeInputType-Overrides context's inputType if needed.
...InputHTMLAttributes<HTMLInputElement>-Supports any standard native input attributes. Avoid value and onChange.

TextInput.PasswordInput

PropTypeDefaultDescription
...InputProps-Inherits all properties from normal inputs. Includes toggle action built-in.

TextInput.NumberInput

PropTypeDefaultDescription
numberType"integer" | "decimal" | "positive" | "natural"-Sets constraints format parameters on input values.
minnumber-Minimum value allowed visually / bound.
maxnumber-Maximum value allowed visually / bound.
stepnumber-Step intervals.

TextInput.CharacterCount

PropTypeDefaultDescription
maxLengthnumber-Re-define the overall max character total for display (used purely for text display).
showCount"always" | "focus" | "near-limit"-Dictates when the counter is visible.
thresholdnumber-Triggers display change based upon 'near-limit'.
classNamestring-Additional class names for styling.

On this page