Input
The styled input shell the whole form family renders into — bordered box, focus ring, slots, and invalid / disabled states. Label, description, and error live in TextInput or Field.
Input is the lowest layer of the form family — the shell that Select, Combobox, Autocomplete, and PillsInput all render into. It draws the box, the focus-within ring, the slots, and the invalid / disabled states, and nothing else. Labels, descriptions, and errors are the job of Field, so an Input stays composable.
Use TextInput — it's this component with label /
description / error / required built in, like every other control in the
family. Input is for composing the shell yourself: inside a Field you
already control, or for a field with no visible label of its own.
import { Input, InputBase } from '@42-central/ui-react/input';
<Input placeholder="login@student.42.fr" />Two pieces ship from the module:
Input— a real<input>wrapped in the shell. Native input props (value,onChange,name,type,ref, …) forward straight through.InputBase— the bare shell around an arbitrary control child. It's how the rest of the family mounts a<button>trigger or a<div>of pills inside the same box. Style your control with the exportedinputControlClasses.
Playground
Component
Dir
Presets
Props
Code
<Component size="md" placeholder="login@student.42.fr" />Variants
Two shells. default is bordered; unstyled strips the chrome but keeps the layout (height + slots) for full-custom inputs.
Code
<Input variant="default" placeholder="Default" />
<Input variant="unstyled" placeholder="Unstyled" />Sizes
Five heights — xs through xl. The control font, padding, and any slot icons scale to match.
Code
<Input size="xs" placeholder="xs" />
<Input size="sm" placeholder="sm" />
<Input size="md" placeholder="md" />
<Input size="lg" placeholder="lg" />
<Input size="xl" placeholder="xl" />Slots
startSlot and endSlot are RTL-aware (start = left in LTR, right in RTL). Icons placed in them are auto-sized to the input's size.
Both slots are decorative: their wrapper spans are aria-hidden, so an interactive control placed in one is invisible to assistive tech. Mount a real button — a clear button, a reveal toggle — as a direct child of InputBase instead, the way PasswordInput mounts its own.
Code
<Input startSlot={<Search />} placeholder="Search" />
<Input startSlot={<Mail />} endSlot={<CircleX />} placeholder="login@student.42.fr" />States
invalid swaps the border and focus ring to red (and sets aria-invalid). disabled dims the shell and blocks input; readOnly keeps full contrast and stays focusable but rejects edits.
Code
<Input invalid defaultValue="not-an-email" />
<Input disabled defaultValue="Locked" />
<Input readOnly defaultValue="Read-only" />InputBase — custom controls
InputBase renders the shell around any control child. This is how a Select trigger (a <button>) or a PillsInput (a <div>) get the exact same box. Apply inputControlClasses to your control so it inherits the shell's font and fills the row.
import { InputBase, inputControlClasses } from '@42-central/ui-react/input';
<InputBase pointer endSlot={<ChevronDown />}>
<button type="button" className={inputControlClasses}>
{value ?? <span className="text-gray-light-500">Pick a value</span>}
</button>
</InputBase>API
Prop
Type
Input forwards every other prop to the underlying <input> (value, defaultValue, onChange, name, type, placeholder, ref, …). className styles the shell root. InputBase takes the same shell props and renders its children as the control.
Accessibility
Inputis an unlabeled control by design. Pair it withField(or your own<label htmlFor>) to give it an accessible name, description, and error text —Fieldwires thearia-*relationships for you.invalidsetsaria-invalidon the input so assistive tech announces the error state.- The focus ring is
focus-within, so it appears whenever the nested control is focused — including the<button>/<div>controls mounted viaInputBase. - RTL: the shell is a plain flex row, so
startSlot/endSlotand padding flip automatically underdir="rtl".
Changelog
- #294
asChildis a compile error onCircularProgress,Progress,Rating,Slider,Divider,Field,InputBaseandPillsInput
- #145
Declare the
refprop the docs already promised
- #96
Inputs drop the
filledvariant and thecolorprop
- #57
Wire the field's description and error to the control with
aria-describedbyandaria-errormessage
- #37
The input shell's translucent fill gets a matching translucent border
- #35
Show the focus ring on shells that are themselves focusable: TreeSelect, TreeMultiSelect and PinInput
Input,Field,PillsInputandPill: the shared input shell, label/help/error wrapper and chips
TextInput
A single-line text field with its label, description, and error built in — Input plus Field, the way every other control in the form family already works.
Textarea
The multi-line sibling of Input — a native textarea in the shared input shell, with bordered box, focus ring, and invalid / disabled states, plus a built-in label, description, and error.