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
Must be at least 12 characters.
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
labelprop renders a<label for={inputId}>, so click-to-focus and SR association are wired by default. - The
hintanderrorprops are both registered viaaria-describedby, so assistive tech reads them as the field's description. - Setting the
errorprop also setsaria-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-hiddenthem).
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 | '' |
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."
/>