Input
Text inputs and field labels — the foundation of forms.
Input is a single-line text field with leading/trailing icon slots, two sizes, and
focus/error/disabled states. Label is its companion field label. Pair them with a shared
id/htmlFor so clicking the label focuses the field.
Installation
pnpm add @infinitibit_gmbh/ui @infinitibit_gmbh/theme-default
Usage
import '@infinitibit_gmbh/theme-default/theme.css';
import '@infinitibit_gmbh/ui/styles.css';
import { Input, Label } from '@infinitibit_gmbh/ui';
export function Example() {
return (
<>
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="you@example.com" />
</>
);
}
States & sizes
Default, value, error, and disabled, in default and large sizes. The error state shows a
red border (aria-invalid is set for assistive tech). Render your own error message below the
field.
Icons
Pass leadingIcon and/or trailingIcon to place icons inside the field.
<Input leadingIcon={<SearchIcon />} placeholder="Search" />
Textarea
Textarea is the multi-line counterpart — a native <textarea> with the same error and
disabled states, vertically resizable. It carries its own styling (a slightly tighter radius
and softer text) per its design.
import { Label, Textarea } from '@infinitibit_gmbh/ui';
export function Example() {
return (
<>
<Label htmlFor="bio">Bio</Label>
<Textarea id="bio" placeholder="Tell us about yourself" />
</>
);
}
One-time password
InputOTP is a segmented input for verification codes — built on input-otp, with
auto-advance, paste support, and full keyboard handling. Compose one InputOTPSlot per
character.
import { InputOTP, InputOTPSlot } from '@infinitibit_gmbh/ui';
export function Example() {
return (
<InputOTP maxLength={6} aria-label="Verification code">
{Array.from({ length: 6 }, (_, i) => (
<InputOTPSlot key={i} index={i} />
))}
</InputOTP>
);
}
API
Input
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'default' | 'large' | 'default' | Field height + padding |
error | boolean | — | Red border + aria-invalid |
leadingIcon | ReactNode | — | Icon before the field |
trailingIcon | ReactNode | — | Icon after the field |
disabled | boolean | — | Non-interactive, 50% opacity |
All native <input> props (type, value, placeholder, onChange, …) are forwarded.
Label
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'small' | 'medium' | 'large' | 'small' | Label text size |
startIcon | ReactNode | — | Icon before the text |
endIcon | ReactNode | — | Icon after the text |
All native <label> props (htmlFor, …) are forwarded.
Textarea
| Prop | Type | Default | Description |
|---|---|---|---|
error | boolean | — | Red border + aria-invalid |
All native <textarea> props (rows, value, placeholder, onChange, …) are forwarded.
InputOTP
| Prop | Type | Default | Description |
|---|---|---|---|
maxLength | number | 6 | Number of slots / characters |
children | ReactNode | — | One InputOTPSlot per character |
InputOTPSlot takes index (its position) and optional error. All native input-otp
props (value, onChange, onComplete, pattern, …) are forwarded to InputOTP.
Accessibility
Labelassociates with the field viahtmlFor/id— clicking the label focuses the input.- The error state sets
aria-invalid="true"; the focus indicator is the field's border (:focus-within). - Disabled inputs receive the native
disabledattribute.