Components / Input

InputPrimitive

Text input primitive. Three variants, three sizes, prefix/suffix slots for icons or inline controls. Accessible labels and aria-describedby wired for hint + error.

Section: Components

Examples

Default

usage.astro | astro
<InputPrimitive
  label="Email"
  name="email"
  type="email"
  placeholder="[email protected]"
/>

With hint

Lowercase letters and dashes only.

usage.astro | astro
<InputPrimitive
  label="Username"
  name="username"
  placeholder="ada-lovelace"
  hint="Lowercase letters and dashes only."
/>

With prefix icon

usage.astro | astro
<InputPrimitive label="Search" name="search" placeholder="Search the design system…">
  <svg slot="prefix" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
    <circle cx="11" cy="11" r="8"></circle>
    <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
  </svg>
</InputPrimitive>

Error state

usage.astro | astro
<InputPrimitive
  label="Password"
  name="password"
  type="password"
  value="abc"
  error="Must be at least 12 characters."
/>

Success state

Valid! 50% off applied.

usage.astro | astro
<InputPrimitive
  label="Coupon code"
  name="coupon"
  value="DESIGN50"
  variant="success"
  hint="Valid! 50% off applied."
/>

Sizes

usage.astro | astro
<InputPrimitive label="Small"            name="size-sm" size="sm" placeholder="sm" />
<InputPrimitive label="Medium (default)" name="size-md" size="md" placeholder="md" />
<InputPrimitive label="Large"            name="size-lg" size="lg" placeholder="lg" />

Disabled

usage.astro | astro
<InputPrimitive label="Locked" name="locked" value="Read-only value" disabled />

Anatomy

Property Behavior
Label Renders above the container as a real `<label for>`.
Container Outer wrapper that holds prefix / input / suffix on a single baseline.
Prefix Optional 16px visual at the start (search glass, currency mark).
Input The native `<input>`. Picks up density tokens for height + padding.
Suffix Optional icon or button at the end (clear, reveal-password).
Hint Plain helper text below the container — `aria-describedby` is wired automatically.
Error Replaces the hint when the `error` prop is set; sets `aria-invalid="true"` and switches role.

Accessibility

  • Every input is a real <input> — native focus, autofill, and validation work for free.
  • The label prop renders a <label for={inputId}>, so click-to-focus and SR association are wired by default.
  • The hint and error props are both registered via aria-describedby, so assistive tech reads them as the field's description.
  • Setting the error prop also sets aria-invalid="true" on the input.
  • Focus uses the system focus ring (--ds-shadow-focus-ring), visible against every surface — keyboard tabbing is never ambiguous.
  • Disabled inputs still expose their label to the accessibility tree (we never aria-hidden them).

Do / Don't

Property Do Don't
Permanent labels Use the `label` prop so the field is always identified. Use `placeholder` as a stand-in label — it disappears on focus.
Error signalling Pair the `error` prop with iconography and a copy that explains the fix. Rely on red border alone — fails users with red/green color blindness.
Helper text Use `hint` for static guidance (formatting, examples). Stuff `hint` with marketing copy or compliance disclaimers — break into a paragraph instead.
Sizing Pick one size (`sm`/`md`/`lg`) per surface and stick with it. Mix sizes inside a single form group — the rhythm breaks.
Prefix slot Reserve the prefix for a 16px icon that hints at the field type. Use the prefix for interactive buttons — put those in `suffix`.
Disabled state Disable only when the user CAN re-enable it (later in the flow). Disable to hide functionality — remove the field instead.

Props

Property Type Default
label string required
name string required
type text | email | password | tel | url | number | search 'text'
value string -
placeholder string -
hint string -
error string -
variant default | error | success 'default'
size sm | md | lg 'md'
required boolean false
disabled boolean false
autocomplete string -
className string ''
InputPrimitive props

Slots

Property Purpose
prefix Left-aligned visual, typically a 16px icon.
suffix Right-aligned visual or interactive control (e.g. clear button).

Source

InputPrimitive.astro | astro
<InputPrimitive
  label="Email"
  name="email"
  type="email"
  placeholder="[email protected]"
  hint="We'll never share it."
/>

<InputPrimitive label="Search" name="q" placeholder="Search…">
  <svg slot="prefix" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
    <circle cx="11" cy="11" r="8"></circle>
    <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
  </svg>
</InputPrimitive>

<InputPrimitive
  label="Password"
  name="password"
  type="password"
  error="Must be at least 12 characters."
/>