Skip to content

Input & Textarea Component Documentation

A comprehensive input and textarea system built with Tailwind CSS utility classes, providing various variants, states, and styling options for form elements.

Table of Contents


Base Input & Textarea

All inputs and textareas come with default styling that includes borders, transitions, focus states, and disabled states.

Base Features

  • White background
  • Border with hover and focus states
  • 30px height for inputs (min/max constrained)
  • Smooth transitions on state changes
  • Disabled state with reduced opacity
  • Gray placeholder text
  • Auto-resizable textarea (vertical only)

Basic Usage

html
<!-- Standard Input -->
<input type="text" placeholder="Enter text..." />

<!-- Textarea -->
<textarea placeholder="Enter multiple lines..."></textarea>

<!-- Disabled Input -->
<input type="text" value="Disabled" disabled />

<!-- Readonly Input -->
<input type="text" value="Readonly" readonly />

Text Alignment

Control text alignment within inputs and textareas.

Available Classes

ClassDescriptionUse Case
.input-leftLeft-aligned text (default)Standard text input
.input-centerCenter-aligned textNumeric codes, OTP
.input-rightRight-aligned textCurrency, numbers

Usage

html
<input type="text" value="Left Aligned" class="input-left" />
<input type="text" value="Centered" class="input-center" />
<input type="number" value="100.00" class="input-right" />

Input States

Visual feedback for validation and status indication.

Available States

ClassColorUse Case
.input-errorRed borderInvalid/error state
.input-successGreen borderValid/success state
.input-warningYellow borderWarning state
.input-infoCyan borderInformational state

Usage

html
<!-- Error State -->
<input type="text" value="Invalid" class="input-error" />

<!-- Success State -->
<input type="text" value="Valid" class="input-success" />

<!-- Warning State -->
<input type="text" value="Warning" class="input-warning" />

<!-- Info State -->
<input type="text" value="Info" class="input-info" />

Input with Icons

Add icons to enhance visual clarity and provide interactive elements.

Icon Positions

Left Icon:

html
<div class="input-icon-wrapper">
  <input type="text" placeholder="Search..." />
  <svg class="input-icon-left w-4 h-4"><!-- icon --></svg>
</div>

Right Icon:

html
<div class="input-icon-wrapper has-icon-right">
  <input type="email" placeholder="Email..." />
  <svg class="input-icon-right w-4 h-4"><!-- icon --></svg>
</div>

Both Icons:

html
<div class="input-icon-wrapper has-icon-both">
  <input type="text" placeholder="Username..." />
  <svg class="input-icon-left w-4 h-4"><!-- icon --></svg>
  <svg class="input-icon-right w-4 h-4"><!-- icon --></svg>
</div>

Clickable Icon:

html
<div class="input-icon-wrapper has-icon-right">
  <input type="password" placeholder="Password..." />
  <svg class="input-icon-right input-icon-clickable w-4 h-4" 
       onclick="togglePassword()">
    <!-- icon -->
  </svg>
</div>

Icon Classes

  • .input-icon-left - Positions icon on the left
  • .input-icon-right - Positions icon on the right
  • .input-icon-clickable - Makes icon interactive (cursor pointer, hover effect)
  • .has-icon-right - Adjusts input padding for right icon
  • .has-icon-both - Adjusts input padding for both icons

Input with Buttons

Combine inputs with buttons for enhanced functionality.

Right Button

html
<div class="input-side-btn">
  <input type="text" placeholder="Search..." class="flex-1" />
  <button class="btn btn-primary">Search</button>
</div>

Left Button

html
<div class="input-side-btn-left">
  <button class="btn btn-secondary">$</button>
  <input type="number" placeholder="0.00" class="flex-1 input-right" />
</div>

Both Sides Buttons

html
<div class="input-both-btn">
  <button class="btn btn-outline-secondary">-</button>
  <input type="number" value="5" class="flex-1 input-center" readonly />
  <button class="btn btn-outline-secondary">+</button>
</div>

Available Classes

  • .input-side-btn - Input with button on the right
  • .input-side-btn-left - Input with button on the left
  • .input-both-btn - Input with buttons on both sides

Input Groups

Group multiple related inputs together with shared borders.

Multiple Inputs

html
<div class="input-group">
  <input type="text" placeholder="First name" class="flex-1" />
  <input type="text" placeholder="Last name" class="flex-1" />
</div>

With Text Addons

html
<div class="flex">
  <span class="input-addon-left">https://</span>
  <input type="text" placeholder="example.com" class="flex-1 rounded-none border-x-0" />
  <span class="input-addon-right">.com</span>
</div>

Available Classes

  • .input-group - Groups multiple inputs
  • .input-addon-left - Text addon on the left
  • .input-addon-right - Text addon on the right

Floating Labels

Material Design-style floating labels that animate on focus.

Features

  • Label floats up when input is focused or filled
  • Smooth transition animation
  • Works with both input and textarea

Usage

html
<!-- Input with Floating Label -->
<div class="input-floating-wrapper">
  <input type="text" placeholder=" " class="input-full" />
  <label>Full Name</label>
</div>

<!-- Textarea with Floating Label -->
<div class="input-floating-wrapper">
  <textarea placeholder=" " class="input-full"></textarea>
  <label>Your Message</label>
</div>

Important: The placeholder=" " (single space) is required for the floating label to work properly with the :placeholder-shown pseudo-class.


Special Input Types

Styled variants for specific HTML5 input types.

Number Input (No Spinner)

Hide the default browser spinner for number inputs:

html
<input type="number" class="input-no-spinner" placeholder="Enter number" />

File Upload

Styled file input with custom button:

html
<input type="file" class="input-file" />

Checkbox & Radio

Styled with custom sizing:

html
<!-- Small -->
<input type="checkbox" class="input-sm" />

<!-- Default -->
<input type="checkbox" />

<!-- Large -->
<input type="checkbox" class="input-lg" />

<!-- Radio Button -->
<input type="radio" name="option" value="1" />

Range Slider

html
<input type="range" min="0" max="100" value="50" />

Color Picker

html
<input type="color" value="#3b82f6" />

Search Input

html
<input type="search" class="input-search" placeholder="Search..." />

Readonly & Disabled States

Readonly

Readonly inputs have a light gray background and cannot be edited but can still be focused:

html
<input type="text" value="Readonly value" readonly />

Disabled

Disabled inputs have reduced opacity, special cursor, and cannot be interacted with:

html
<input type="text" value="Disabled value" disabled />

Loading State

Display a loading spinner inside the input during async operations.

Usage

html
<input type="text" value="Processing..." class="input-loading" readonly />
<textarea class="input-loading" readonly>Loading content...</textarea>

Features

  • Animated spinning loader on the right side
  • Prevents pointer events
  • Works with both input and textarea

Clearable Input

Input with an auto-hiding clear button.

Usage

html
<div class="input-clearable-wrapper">
  <input type="text" placeholder="Type something..." class="input-full" />
  <svg class="input-clear-btn w-4 h-4" onclick="clearInput()">
    <!-- X icon -->
  </svg>
</div>

Features

  • Clear button automatically hides when input is empty
  • Positioned on the right side
  • Clickable with hover effect

Textarea Variants

Control textarea resizing behavior.

Available Classes

ClassDescription
.textarea-no-resizePrevents resizing
.textarea-resize-xAllows horizontal resize only
.textarea-auto-growAuto-grows with content (prevents scrollbar)

Usage

html
<!-- No Resize -->
<textarea class="textarea-no-resize"></textarea>

<!-- Horizontal Resize Only -->
<textarea class="textarea-resize-x"></textarea>

<!-- Auto-grow -->
<textarea class="textarea-auto-grow"></textarea>

Form Field Wrapper

Complete form field with label, input, hints, and error messages.

Basic Structure

html
<div class="form-field">
  <label>Field Label</label>
  <input type="text" placeholder="Enter value..." class="input-full" />
  <span class="field-hint">Helper text goes here</span>
</div>

With Error State

html
<div class="form-field">
  <label>Username</label>
  <input type="text" class="input-full input-error" />
  <span class="field-error">This field is required</span>
</div>

Required Field

html
<div class="form-field field-required">
  <label>Email</label>
  <input type="email" class="input-full" />
  <span class="field-hint">We'll never share your email</span>
</div>

Available Classes

  • .form-field - Wrapper for complete field structure
  • .field-error - Error message text (red)
  • .field-hint - Helper/hint text (gray)
  • .field-required - Adds red asterisk (*) to label

Utility Classes

Additional helper classes for common use cases.

Width Control

ClassDescription
.input-fullFull width (100%)
.input-inlineInline display with auto width

Style Variants

ClassDescriptionUse Case
.input-borderlessNo bordersMinimalist design
.input-underlineBottom border onlyMaterial design style

Usage

html
<!-- Full Width -->
<input type="text" class="input-full" />

<!-- Inline -->
<input type="text" class="input-inline" />

<!-- Borderless -->
<input type="text" class="input-borderless bg-gray-50" />

<!-- Underline -->
<input type="text" class="input-underline" />

Complete Examples

Login Form

html
<div class="space-y-4">
  <div class="form-field field-required">
    <label>Email Address</label>
    <div class="input-icon-wrapper has-icon-right">
      <input type="email" placeholder="[email protected]" class="input-full" />
      <svg class="input-icon-right w-4 h-4"><!-- email icon --></svg>
    </div>
    <span class="field-hint">We'll never share your email</span>
  </div>

  <div class="form-field field-required">
    <label>Password</label>
    <div class="input-icon-wrapper has-icon-right">
      <input type="password" placeholder="••••••••" class="input-full" />
      <svg class="input-icon-right input-icon-clickable w-4 h-4">
        <!-- eye icon -->
      </svg>
    </div>
    <span class="field-hint">Must be at least 8 characters</span>
  </div>

  <button class="btn btn-primary w-full">Sign In</button>
</div>

Search with Button

html
<div class="form-field">
  <label>Search Products</label>
  <div class="input-side-btn">
    <input type="text" placeholder="Enter keywords..." class="flex-1" />
    <button class="btn btn-primary">
      <svg class="w-4 h-4"><!-- search icon --></svg>
      Search
    </button>
  </div>
</div>

Price Input with Currency

html
<div class="form-field">
  <label>Product Price</label>
  <div class="input-side-btn-left">
    <button class="btn btn-secondary">$</button>
    <input type="number" step="0.01" placeholder="0.00" 
           class="flex-1 input-right input-no-spinner" />
  </div>
</div>

Quantity Selector

html
<div class="form-field">
  <label>Quantity</label>
  <div class="input-both-btn">
    <button class="btn btn-outline-secondary" onclick="decrease()">-</button>
    <input type="number" value="1" class="flex-1 input-center" readonly />
    <button class="btn btn-outline-secondary" onclick="increase()">+</button>
  </div>
</div>

Best Practices

  1. Always use labels: Provide clear labels for accessibility
  2. Use appropriate input types: HTML5 input types provide better UX (email, tel, number, etc.)
  3. Provide validation feedback: Use error/success states with clear messages
  4. Show hints when needed: Help users understand what's expected
  5. Mark required fields: Use .field-required to indicate mandatory fields
  6. Disable during processing: Use disabled state during form submission
  7. Use loading state: Show .input-loading for async operations
  8. Consider mobile: Input sizes should be touch-friendly
  9. Test keyboard navigation: Ensure proper tab order and focus states
  10. Provide clear placeholder text: Short, descriptive placeholders help users

Accessibility Considerations

  • Always associate labels with inputs using for attribute or wrapping
  • Provide descriptive error messages
  • Use appropriate aria-* attributes when needed
  • Ensure sufficient color contrast for text and borders
  • Support keyboard navigation (Tab, Enter, Escape)
  • Don't rely solely on color to convey information
  • Test with screen readers

Browser Support

Works in all modern browsers that support:

  • CSS custom properties (Tailwind)
  • Flexbox
  • CSS Grid
  • CSS transitions and animations
  • HTML5 input types

Customization

The input system uses Tailwind's @apply directive. To customize:

  1. Colors: Modify border, background, and text colors in the base styles
  2. Sizing: Adjust height, padding, and font sizes
  3. Transitions: Change transition duration and easing
  4. Border Radius: Update rounded-default value
  5. Focus States: Customize focus:border-input-focus color
  6. Disabled Styles: Adjust opacity and background colors

Example customization in your CSS:

css
input {
    @apply text-base; /* Change font size */
    @apply py-2 px-4; /* Adjust padding */
    @apply rounded-lg; /* Modify border radius */
}

Integration with Vue.js

All input components work seamlessly with Vue 3:

vue
<template>
  <div class="form-field" v-input-error="errorMessage">
    <label>Username</label>
    <input 
      v-model="username"
      type="text"
      placeholder="Enter username"
      class="input-full"
    />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const username = ref('');
const hasError = computed(() => username.value.length < 3);
const errorMessage = computed(() => 
  hasError.value ? 'Username must be at least 3 characters' : ''
);
</script>

Common Issues & Solutions

Issue: Floating label doesn't work

Solution: Make sure to include placeholder=" " (single space) on the input

Issue: Icon overlaps with text

Solution: Use the appropriate wrapper class (has-icon-right, has-icon-both)

Issue: Input group borders not connecting

Solution: Ensure proper order and use border-x-0 on middle elements when needed

Issue: Loading spinner not centered in textarea

Solution: The spinner is positioned at the top-right, use custom CSS if centering is needed

Issue: Clear button always visible

Solution: The button auto-hides when using :placeholder-shown, ensure input has no value