Input (Origin)

A validated input field with an optional leading icon and three visual validation states: idle, success, and error. Built on top of the base Input and Label components.

Anatomy

A flex column with an optional Label above and a relative-positioned input wrapper below. The leading icon sits at the left; a validation icon (check or alert circle) appears at the right when the state is success or error. A feedback message appears below the input.

Validation States

The validationState prop controls the icon color, input ring, and feedback message visibility.

Idle

Success

Email is available

Error

Icon Variants

The icon prop is optional. Without it, the input renders with standard padding. The icon color changes with the validation state.

Form Example

Multiple validated inputs in a form layout.

Looks good!

Valid phone number

Design Guidelines

Do

  • Show validation feedback inline. Placing success and error messages directly below the input avoids scroll and form-level confusion.
  • Use icons that match the field type. A mail icon on an email field, user icon on a name field — the icon reinforces context.
  • Validate on blur, not on every keystroke. Real-time error messages while typing are frustrating; wait until the user leaves the field.

Don't

  • Don't show error state before the user interacts. Pre-emptive error states on empty fields create a hostile first impression.
  • Don't use vague error messages. "Invalid input" is unhelpful — tell the user exactly what's wrong and how to fix it.
  • Don't use success state for every valid field. Reserve it for fields where confirmation adds value (email availability, username uniqueness).

Developer Reference

Props

  • label (optional) — renders a <Label> linked to the input via a generated or provided id.
  • icon (optional) — a LucideIcon absolutely positioned at the left edge. Color adapts to the validationState.
  • validationState(optional, default: "idle") — "idle" | "success" | "error".
  • errorMessage (optional) — shown below the input only when validationState === "error".
  • successMessage (optional) — shown below the input only when validationState === "success".
  • All other Input props are forwarded (e.g. value, onChange, disabled).

Usage

import { OriginInputComponent } from "@/components/branding/origin-ui-input"
import { Mail, User } from "lucide-react"

// Idle state
<OriginInputComponent
  label="Username"
  icon={User}
  placeholder="Enter your username"
  validationState="idle"
/>

// Success state
<OriginInputComponent
  label="Email"
  icon={Mail}
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  validationState="success"
  successMessage="Email is available"
/>

// Error state
<OriginInputComponent
  label="Email"
  icon={Mail}
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  validationState="error"
  errorMessage="Please enter a valid email address"
/>