vwf .

Production Patterns

Production-ready patterns with live, editable code examples

Form with Validation

Forms

Real-time validation with error states and success feedback

// Simple Form Pattern

const { div, h3, p, form } = van.tags;

// Form state
const email = van.state('');
const password = van.state('');
const emailError = van.state('');
const passwordError = van.state('');
const submitStatus = van.state('');

// Validation function
const validateForm = () => {
  let isValid = true;

  if (!email.val) {
    emailError.val = 'Email is required';
    isValid = false;
  } else if (!email.val.includes('@')) {
    emailError.val = 'Please enter a valid email';
    isValid = false;
  } else {
    emailError.val = '';
  }

  if (!password.val) {
    passwordError.val = 'Password is required';
    isValid = false;
  } else if (password.val.length < 8) {
    passwordError.val = 'Password must be at least 8 characters';
    isValid = false;
  } else {
    passwordError.val = '';
  }

  return isValid;
};

// Form submission
const handleSubmit = (e) => {
  e.preventDefault();

  if (validateForm()) {
    submitStatus.val = 'Form submitted successfully!';
    // Reset form
    setTimeout(() => {
      email.val = '';
      password.val = '';
      submitStatus.val = '';
    }, 2000);
  }
};

return div(
  { class: 'space-y-4' },

  h3({ class: 'text-lg font-semibold mb-2' }, 'Simple Form Pattern'),

  form(
    {
      class: 'space-y-4',
      onsubmit: handleSubmit
    },

    Input({
      id: 'simple-form-email',
      label: 'Email',
      type: 'email',
      value: email,
      message: () => emailError.val ? { code: 'error', detail: emailError.val } : null,
      placeholder: 'you@example.com',
      required: true,
      oninput: e => {
        email.val = e.target.value;
        emailError.val = '';
      }
    }),

    Input({
      id: 'simple-form-password',
      label: 'Password',
      type: 'password',
      value: password,
      message: () => passwordError.val ? { code: 'error', detail: passwordError.val } : null,
      placeholder: 'Enter password',
      required: true,
      oninput: e => {
        password.val = e.target.value;
        passwordError.val = '';
      }
    }),

    Button({
      type: 'submit',
      class: 'vwfcolor-sky solid vwfsize-md w-full'
    }, 'Submit'),

    () => submitStatus.val ? p({ class: 'text-success text-sm' }, submitStatus.val) : ''
  )
);

▶️ Live Preview

Simple Form Pattern

💡 Click "Edit Code" to modify the example

🔄 Click "Apply Changes" to see your modifications

↩️ Click "Reset" to restore original code

📋 Best Practices

State Management

• Use individual van.state() for each value

• Keep state close to where it's used

• Update arrays immutably with spread operator

• Use arrow functions for reactive values

Performance

• Debounce expensive operations

• Use keys for list items

• Avoid complex computations in render

• Clean up timers and listeners

Component Design

• Accept both props and children

• Use parseArgs for flexibility

• Provide sensible defaults

• Keep components focused

User Experience

• Show loading states

• Provide immediate feedback

• Handle errors gracefully

• Add smooth transitions