Input Components
Proton provides a comprehensive set of input components for forms and data entry, including text inputs, checkboxes, radio buttons, and specialized inputs.
The base text input component.
Location: components/input/Input.tsx
This component is deprecated. Consider using Input from @proton/atoms or InputFieldTwo for new code.
Basic Usage
import Input from '@proton/components/components/input/Input';
import { useState } from 'react';
const MyForm = () => {
const [value, setValue] = useState('');
return (
<Input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Enter text"
/>
);
};
Props
Extends InputHTMLAttributes<HTMLInputElement>
onChange
(e: ChangeEvent) => void
required
Change event handler
Error message to display below the input
Icon element to display on the right side
Shows loading state and disables input. Default: false
Makes input take full width. Default: true
Marks field as required. Default: false
Handler called when Enter key is pressed
Examples
Specialized input for search functionality with built-in magnifier icon.
Location: components/input/SearchInput.tsx
Usage
import SearchInput from '@proton/components/components/input/SearchInput';
const MySearch = () => {
const [query, setQuery] = useState('');
return (
<SearchInput
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search..."
/>
);
};
Input with show/hide password toggle.
Location: components/input/PasswordInput.tsx
This component is deprecated. Use PasswordInputTwo instead.
Usage
import PasswordInput from '@proton/components/components/input/PasswordInput';
const MyLoginForm = () => {
const [password, setPassword] = useState('');
return (
<PasswordInput
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
);
};
Checkbox
Checkbox input with label support.
Location: components/input/Checkbox.tsx
Usage
import Checkbox from '@proton/components/components/input/Checkbox';
const MyForm = () => {
const [agreed, setAgreed] = useState(false);
return (
<Checkbox
checked={agreed}
onChange={(e) => setAgreed(e.target.checked)}
>
I agree to the terms and conditions
</Checkbox>
);
};
Props
Whether checkbox is checked
Display a third state [–]. Default: false
Shows loading state. Interactions blocked. Default: false
Custom background color (CSS color value)
Custom border color (CSS color value)
Custom checkmark color (CSS color value)
Gap between checkbox and label. Default: gap-2
Examples
Basic Checkbox
Indeterminate State
Custom Colors
<Checkbox checked={isChecked} onChange={handleChange}>
Enable notifications
</Checkbox>
<Checkbox
checked={someChecked}
indeterminate={!allChecked && someChecked}
onChange={handleSelectAll}
>
Select all
</Checkbox>
<Checkbox
checked={isChecked}
backgroundColor="#ff0000"
borderColor="#cc0000"
color="#ffffff"
>
Custom styled checkbox
</Checkbox>
Radio & RadioGroup
Radio button inputs with group management.
Location: components/input/Radio.tsx, components/input/RadioGroup.tsx
Usage
import Radio from '@proton/components/components/input/Radio';
import RadioGroup from '@proton/components/components/input/RadioGroup';
const MyForm = () => {
const [selected, setSelected] = useState('option1');
return (
<RadioGroup
name="my-options"
value={selected}
onChange={setSelected}
options={[
{ value: 'option1', label: 'Option 1' },
{ value: 'option2', label: 'Option 2' },
{ value: 'option3', label: 'Option 3' },
]}
/>
);
};
TextArea
Multi-line text input.
Location: components/input/TextArea.tsx
Usage
import TextArea from '@proton/components/components/input/TextArea';
const MyForm = () => {
const [message, setMessage] = useState('');
return (
<TextArea
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Enter your message"
rows={5}
/>
);
};
Date picker input component.
Location: components/input/DateInput.tsx
Usage
import DateInput from '@proton/components/components/input/DateInput';
const MyForm = () => {
const [date, setDate] = useState<Date>(new Date());
return (
<DateInput
value={date}
onChange={setDate}
placeholder="Select date"
/>
);
};
Time picker input component.
Location: components/input/TimeInput.tsx
Usage
import TimeInput from '@proton/components/components/input/TimeInput';
const MyForm = () => {
const [time, setTime] = useState('12:00');
return (
<TimeInput
value={time}
onChange={setTime}
placeholder="Select time"
/>
);
};
Email input with validation.
Location: components/input/EmailInput.tsx
Usage
import EmailInput from '@proton/components/components/input/EmailInput';
const MyForm = () => {
const [email, setEmail] = useState('');
return (
<EmailInput
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="[email protected]"
/>
);
};
Numeric input restricted to integers.
Location: components/input/IntegerInput.tsx
Usage
import IntegerInput from '@proton/components/components/input/IntegerInput';
const MyForm = () => {
const [count, setCount] = useState(0);
return (
<IntegerInput
value={count}
onChange={setCount}
min={0}
max={100}
/>
);
};
File upload input component.
Location: components/input/FileInput.tsx
Usage
import FileInput from '@proton/components/components/input/FileInput';
const MyUpload = () => {
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
const files = e.target.files;
console.log('Selected files:', files);
};
return (
<FileInput
onChange={handleFileChange}
accept="image/*"
multiple
>
Choose files
</FileInput>
);
};
Best Practices
const [email, setEmail] = useState('');
const [error, setError] = useState('');
const validateEmail = (value: string) => {
if (!value) {
setError('Email is required');
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
setError('Invalid email format');
} else {
setError('');
}
};
<Input
type="email"
value={email}
onChange={(e) => {
setEmail(e.target.value);
validateEmail(e.target.value);
}}
error={error}
required
/>
Accessibility
// Provide proper labels
<label htmlFor="username">Username</label>
<Input
id="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
aria-describedby="username-help"
/>
<span id="username-help" className="text-sm color-weak">
Choose a unique username
</span>
Controlled Components
Always use controlled components with state:
const [value, setValue] = useState('');
<Input
value={value}
onChange={(e) => setValue(e.target.value)}
/>
Source Code
View source:
- Input:
packages/components/components/input/Input.tsx:1
- Checkbox:
packages/components/components/input/Checkbox.tsx:1
- PasswordInput:
packages/components/components/input/PasswordInput.tsx:1