UIUpdated April 28, 2026

Input

Core text input component for PyColors UI, with labels, helper text, validation, icons, and accessibility built in.

UIInput

Reliable text fields for product formsLink to section

The Input component is a foundational form control in PyColors UI.

Use it for:

  • login forms
  • search fields
  • settings forms
  • billing details
  • profile fields
  • admin filters
  • product creation flows
  • validation-driven forms

Input is designed to be accessible by default, theme-aware, and flexible enough for simple fields or production form layouts.

It supports:

  • labels
  • helper text
  • validation errors
  • left and right icons
  • size variants
  • keyboard and screen-reader support

Core idea

Input collects user data. Validation rules should live in your form or schema layer, not inside the visual primitive.

ImportLink to section

input-import.tsx
import {
  Input,
  type InputProps,
  type InputSize,
} from "@pycolors/ui";

Basic usageLink to section

Use Input when the field is simple and the surrounding context already provides a label.

basic-input.tsx
import { Input } from "@pycolors/ui";

export function BasicInput() {
  return <Input placeholder="Type something…" />;
}

Label rule

Placeholder text is not a replacement for a label. Use label when the field needs to stand alone.

With label and helper textLink to section

Use label and helperText to make the field self-explanatory.

We’ll never share your email.

input-with-label.tsx
import { Input } from "@pycolors/ui";

export function InputWithLabel() {
  return (
    <Input
      label="Email"
      placeholder="you@domain.com"
      helperText="We’ll never share your email."
    />
  );
}

When to use InputLink to section

Use Input when the user needs to provide or edit short text-based data.

Forms

Use for account, profile, billing, organization, and setup forms.

Search

Use with a leading icon for search, filters, and quick lookup fields.

Validation

Use error to show field-level validation feedback clearly.

Validation errorLink to section

When error is provided:

  • error styles are applied
  • aria-invalid is set
  • error text is connected to the field
  • screen readers can access the validation message

Invalid email address

input-error.tsx
import { Input } from "@pycolors/ui";

export function InputError() {
  return (
    <Input
      label="Email"
      placeholder="you@domain.com"
      error="Invalid email address"
    />
  );
}

Validation rule

Keep errors short and specific. The user should immediately understand what to fix.

With iconsLink to section

Use icons when they clarify the field purpose.

Left iconLink to section

input-left-icon.tsx
import { Input } from "@pycolors/ui";
import { SearchIcon } from "lucide-react";

export function InputLeftIcon() {
  return (
    <Input
      placeholder="Search…"
      leftIcon={<SearchIcon className="size-4" aria-hidden="true" />}
    />
  );
}

Right iconLink to section

input-right-icon.tsx
import { Input } from "@pycolors/ui";
import { FileText } from "lucide-react";

export function InputRightIcon() {
  return (
    <Input
      label="Project"
      placeholder="Project name"
      rightIcon={<FileText className="size-4" aria-hidden="true" />}
    />
  );
}

Icon rule

Icons should support meaning. Do not rely on an icon as the only label.

SizesLink to section

Use size to adapt density across product surfaces.

input-sizes.tsx
import { Input } from "@pycolors/ui";

export function InputSizes() {
  return (
    <div className="flex w-80 flex-col gap-3">
      <Input size="sm" placeholder="Small" />
      <Input size="md" placeholder="Medium" />
      <Input size="lg" placeholder="Large" />
    </div>
  );
}

Available sizesLink to section

SizePurpose
smDense UIs, tables, filters, compact toolbars
mdDefault input size
lgOnboarding, auth, marketing-like forms, prominent flows

Density rule

Use md by default. Use sm for dense product surfaces and lg when the form needs stronger emphasis.

Usage patternsLink to section

Start with the field purpose

Use a clear label when the field must stand alone. Do not rely on placeholder text.

Add helper text only when useful

Helper text should reduce uncertainty, not explain obvious fields.

Keep validation close to the field

Field-level errors should appear directly below the affected input.

Use icons sparingly

Icons work well for search, URL, currency, or domain-specific signals.

Keep business rules outside the primitive

Use Zod, React Hook Form, server validation, or your domain layer for validation logic.

Input vs PasswordInput vs TextareaLink to section

SituationUse
Short text valueInput
Email, name, slug, URLInput
Password with reveal togglePasswordInput
Long free-form contentTextarea or custom field
Search fieldInput with leading icon
Numeric or currency inputInput with domain-specific formatting
Select one from fixed optionsSelect, RadioGroup, or Tabs depending on UX

Decision rule

Use Input for short text. Use PasswordInput for secrets. Use a larger field for long content.

APILink to section

Props

PropTypeDefaultDescription
labelstringAccessible label above the field
helperTextstringHelper text below the field
errorstringValidation error message
leftIconReact.ReactNodeIcon rendered on the left
rightIconReact.ReactNodeIcon rendered on the right
size"sm" | "md" | "lg""md"Visual density
classNamestringTailwind override

Input extends standard input props, excluding the native size attribute.

input-props.ts
React.InputHTMLAttributes<HTMLInputElement>

TypeScript typesLink to section

input-types.ts
export type InputSize = "sm" | "md" | "lg";

export interface InputProps
  extends Omit<
    React.InputHTMLAttributes<HTMLInputElement>,
    "size"
  > {
  label?: string;
  helperText?: string;
  error?: string;
  leftIcon?: React.ReactNode;
  rightIcon?: React.ReactNode;
  size?: InputSize;
}

AccessibilityLink to section

Input is designed to support accessible form composition.

Guidelines:

  • use a visible label when the field needs context
  • do not rely on placeholder text as the only label
  • error should set aria-invalid
  • helper and error text should be connected through aria-describedby
  • decorative icons should use aria-hidden="true"
  • keep focus rings visible
  • use appropriate native type values, such as email, url, tel, or search
  • use autoComplete values where relevant

Accessibility rule

Every input needs an accessible name. A visible label is usually the safest choice.

Prefer / avoidLink to section

Prefer

  • visible labels for important fields
  • short helper text
  • specific validation messages
  • semantic input types
  • consistent sizes inside one form

Avoid

  • placeholder-only fields
  • vague errors like “Invalid”
  • too many icons in one field
  • mixing input sizes randomly
  • putting validation rules inside the UI primitive

Product copy guidelinesLink to section

Labels, placeholders, helper text, and errors each have a different job.

Label examples

Email, Project name, Company, Website, Billing email, Workspace name.

Placeholder examples

you@domain.com, acme-inc, https://example.com, Search projects…

Error examples

Enter a valid email address. Project name must be at least 3 characters.

Common questionsLink to section