vwf .

Developer Docs

Quick reference guides with props tables, usage examples, and best practices for rapid development

Input

Form input component with validation and messages

✨ Quick Examples

Interactive examples showing various Input configurations and features:

🔧 Props

All available props for the Input component with their types, defaults, and descriptions:

PropTypeDefaultDescription
idstringauto-generatedUnique identifier for the input
labelstring''Label text above the input
typestring'text'HTML input type
valueState | string''Input value (can be reactive state)
placeholderstring''Placeholder text
messageState<{code, detail}>undefinedValidation message object
requiredbooleanfalseShows red asterisk when true
leftIconElementundefinedIcon on the left side
disabledboolean | StatefalseDisables the input
oninputFunctionundefinedInput event handler
onblurFunctionundefinedBlur event handler

🎨 Input Types

Different HTML input types for various data formats

✅ Validation States

Four validation states with icons and colored borders

Username will be public
Email verified!
Weak password
This field is required

Message Object Structure

// Message States
// Info
message: { code: 'info', detail: 'Use your work email' }

// Success
message: { code: 'success', detail: 'Email verified!' }

// Warning
message: { code: 'warning', detail: 'This will be public' }

// Error
message: { code: 'error', detail: 'This field is required' }

🎯 With Icons

Add icons for better visual context

Example Code

// With Icons
Input({
  leftIcon: span({ class: 'oj-ux-ico-search' }),
  placeholder: 'Search...',
  value: searchQuery
})

Input({
  leftIcon: span({ class: 'oj-ux-ico-email' }),
  type: 'email',
  placeholder: 'Email address'
})

🔄 Real-time Validation

Validate input as the user types

Example Code

// With Real-time Validation
const email = van.state('');
const emailError = van.state({ code: '', detail: '' });

Input({
  id: 'email',
  label: 'Email Address',
  type: 'email',
  placeholder: 'you@example.com',
  value: email,
  message: emailError,
  required: true,
  oninput: (e) => {
    const value = e.target.value;
    email.val = value;

    // Real-time validation
    if (!value) {
      emailError.val = { code: '', detail: '' };
    } else {
      const result = validateEmail(value);
      if (result) {
        emailError.val = result;
      } else {
        emailError.val = {
          code: 'success',
          detail: 'Email looks good!'
        };
      }
    }
  }
})

📱 Phone Input with Country Code

Special integration with ListBox component for country selection

Selected country: +1

Example Code

// Phone Input with Country Code
const countryCode = van.state('+1');

// Create ListBox with country options
const { Listbox: CountrySelector, ListboxList: CountryList } = ListBox({
  options: [
    { value: '+1', text: '🇺🇸', label: span(...) },
    { value: '+44', text: '🇬🇧', label: span(...) },
    { value: '+91', text: '🇮🇳', label: span(...) }
  ],
  value: countryCode,
  class: 'self-center justify-self-end min-w-12...',
  iconClass: 'mr-2'
});

// Use in Input component
div(
  { class: 'space-y-2' },
  Input(
    {
      id: 'phone',
      label: 'Phone Number',
      type: 'tel',
      value: phone,
      placeholder: '555-1234',
      message: phoneError
    },
    CountrySelector()  // ListBox button as child
  ),
  CountryList()  // ListBox dropdown
)

The ListBox component can be passed as a child to Input for special integrations like country code selectors. This pattern preserves the Input structure while adding dropdown functionality.

💻 Basic Usage

Simple example showing basic Input component usage with label and placeholder:

// Basic Input
import { Input } from './components/forms/Input.js';
import { h2Small, h3Small, h4Small, sectionSpacing, tClass } from '../../../../utils/utilityClasses.js';

// Simple usage
Input({
  id: 'username',
  label: 'Username',
  placeholder: 'Enter username',
  value: username,
  oninput: e => username.val = e.target.value
})

🔧 Technical Details

Advanced implementation details explaining how the Input component handles icons, validation, and styling:

⭑Grid Overlay Pattern

Icons are positioned using CSS Grid overlay pattern (no absolute positioning), ensuring perfect alignment and avoiding layout shifts.

⭑ReplaceColor Utility

The component uses the replaceColor utility to change only border colors during validation states while preserving border width and style preferences.

⭑CSS Variable Focus States

Focus ring color is controlled via --vwf-color CSS variable, allowing dynamic theming without JavaScript.

⭑Auto Icon Padding

When leftIcon is provided, the component automatically adds pl-11 class for proper text alignment.

✅ Best Practices

Follow these guidelines for optimal Input component usage:

✓Always provide an id and label for accessibility

✓Use appropriate input types (email, tel, url, etc.)

✓Validate on input for immediate feedback

✓Use onblur for expensive validation or formatting

✓Provide clear, actionable error messages

✓Mark required fields with the required prop

✓Use icons to enhance context and usability

Explore More Components

Browse other component categories