primitives

Input

Single-line text input with built-in theme styling, three sizes, and leading / trailing slots.


Input is the text input primitive. Controlled or uncontrolled, three sizes, optional leading + trailing slots for icons / clear buttons / unit labels.

API

<Input
  value={email}
  onChange={(v) => setEmail(v)}
  placeholder="you@example.com"
  type="email"
/>

<Input
  size="lg"
  leading={<Icon name="search" />}
  placeholder="Search…"
/>

<Input
  size="md"
  invalid={!!errors.password}
  trailing={
    <button onClick={() => setShow((s) => !s)}>
      <Icon name={show ? "eye-off" : "eye"} />
    </button>
  }
  type={show ? "text" : "password"}
/>

Props

PropTypeDefault
valuestring (controlled)-
defaultValuestring (uncontrolled)""
onChange(value, event) => void-
placeholderstring-
size"sm" | "md" | "lg""md"
type"text" | "email" | "password" | "search" | "tel" | "url" | "number""text"
invalidboolean (red border + aria-invalid)false
disabledbooleanfalse
leadingReactNode-
trailingReactNode-
autoFocusbooleanfalse
name, idstring-
aria-labelstring-

Size scale

SizeWeb heightNative heightFont size
sm283213
md364014
lg444816

(Web is denser than native because mobile touch targets need extra height.)

Field integration

Input automatically picks up the invalid state from a parent <Field /> (via @plyxui/forms). No prop drilling.

<Field label="Email" error={errors.email}>
  <Input value={email} onChange={(v) => setEmail(v)} />
</Field>