|Kit

Input

The styled input shell the whole form family renders into — bordered or filled box, focus ring, slots, and invalid / disabled states. Label, description, and error live in 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.

import { Input, InputBase } from '@42/ui-react/input';

<Input placeholder="login@student.42.fr" />

Two pieces ship from the module:

  • Input — the common case: 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 exported inputControlClasses.

Playground

Component

Loading preview

Props

Code

<Component size="md" placeholder="login@student.42.fr" />

Variants

Three shells. default is bordered, filled is a soft neutral surface, unstyled strips the chrome but keeps the layout (height + slots) for full-custom inputs.

Code

<Input variant="default" placeholder="Default" /><Input variant="filled" placeholder="Filled" /><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. The end slot can hold interactive controls — a clear button, a reveal toggle, a spinner.

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 regardless of color (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" />

Colors

The shell is palette-independent for fill and text — only the focus ring references --c-solid. So every kit palette (and consumer-defined ones) tints the focus state for free, while the resting input stays neutral. See Colors.

Code

<Input color="brand" placeholder="Focus me" /><Input color="green" placeholder="Focus me" /><Input color="purple" placeholder="Focus me" />

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/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

  • Input is an unlabeled control by design. Pair it with Field (or your own <label htmlFor>) to give it an accessible name, description, and error text — Field wires the aria-* relationships for you.
  • invalid sets aria-invalid on 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 via InputBase.
  • RTL: the shell is a plain flex row, so startSlot / endSlot and padding flip automatically under dir="rtl".

On this page