Input
Core text input component for PyColors UI, with labels, helper text, validation, icons, and accessibility built in.
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
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.
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.
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
Search
Validation
error to show field-level validation feedback clearly.Validation errorLink to section
When error is provided:
- error styles are applied
aria-invalidis set- error text is connected to the field
- screen readers can access the validation message
Invalid email address
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
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
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.
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
| Size | Purpose |
|---|---|
sm | Dense UIs, tables, filters, compact toolbars |
md | Default input size |
lg | Onboarding, 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
| Situation | Use |
|---|---|
| Short text value | Input |
| Email, name, slug, URL | Input |
| Password with reveal toggle | PasswordInput |
| Long free-form content | Textarea or custom field |
| Search field | Input with leading icon |
| Numeric or currency input | Input with domain-specific formatting |
| Select one from fixed options | Select, 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
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Accessible label above the field |
helperText | string | — | Helper text below the field |
error | string | — | Validation error message |
leftIcon | React.ReactNode | — | Icon rendered on the left |
rightIcon | React.ReactNode | — | Icon rendered on the right |
size | "sm" | "md" | "lg" | "md" | Visual density |
className | string | — | Tailwind override |
Input extends standard input props, excluding the native size attribute.
React.InputHTMLAttributes<HTMLInputElement>TypeScript typesLink to section
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
labelwhen the field needs context - do not rely on placeholder text as the only label
errorshould setaria-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
typevalues, such asemail,url,tel, orsearch - use
autoCompletevalues 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.