Components/Input

Forms component

Input

Ink-bordered text field. Lifts with a hard offset shadow on focus. Optional label, hint, error message, prefix and suffix slots. Always use inside a <form> with a label.

FormControlledPrefix / SuffixValidationFocus motion
components/forms/Input.jsx
Anatomy
Click any field to see focus lift
States
All input states
Do / Don't
✓ Do

Always pair an input with a visible label and hint. Don't rely on placeholder as the label.

✕ Don't

Don't override border-radius or thin the border. SLAB inputs are chunky and square — that's the system.

Props
PropTypeDefaultDescription
labelstringnullMono uppercase label rendered above the field.
hintstringnullHelper text below. Turns coral when invalid=true.
prefixReactNodenullContent in a bordered left-attached cell (e.g. "$", "https://").
suffixReactNodenullContent in a bordered right-attached cell (e.g. "kg", "%", "USD").
invalidbooleanfalseSwitches border and hint text to coral error color.
styleCSSProperties{}Applied to the outer wrapper — use for width, margin.
inputStyleCSSProperties{}Applied to the inner <input> element only.
...restInputHTMLAttributesAll native input props: type, placeholder, value, onChange, disabled, etc.
Usage
import { Input } from "components/forms/Input";

// Basic
<Input label="Campaign name" placeholder="e.g. Summer Sale" />

// With prefix + hint
<Input
  label="Website"
  prefix="https://"
  hint="Your public campaign URL"
  placeholder="yourdomain.com"
/>

// With suffix
<Input
  label="Weight"
  suffix="kg"
  type="number"
  placeholder="0"
/>

// Prefix + suffix
<Input
  label="Price"
  prefix="$"
  suffix="USD"
  type="number"
/>

// Validation state
<Input
  label="Email"
  type="email"
  invalid={!isValidEmail}
  hint={!isValidEmail ? "Enter a valid email." : ""}
  value={email}
  onChange={e => setEmail(e.target.value)}
/>