CwInput
All input types, validation states, icon slots, clear button, numeric stepping with arrow-key support, native color picking, and DevEUI/credit-card formatting.
<CwInput
label="Email"
type="email"
placeholder="user@example.com"
bind:value={email}
clearable
/>
Max Length & Clear Button
The clear button appears when clearable is set and the input has a value.
Validation States
Validation icons auto-render on the right side.
Documentation Upgrade
Start here
CwInput is a single component that covers standard text fields plus CropWatch-specific formatting helpers like DevEUI, credit card, and expiry input. The parent still owns the value through normal binding.
How to think about it
- Choose the input type deliberately Use the specialized types only when you want the built-in formatting behavior. Otherwise stay with plain `text`, `email`, or `password`.
- Tune numeric stepping when precision matters `numeric` fields render inline up/down controls, respond to `ArrowUp` and `ArrowDown` while focused, and optionally respect `step`, `min`, and `max`.
- Use validation props for field-level feedback `error` and `valid` control the right-side validation icon and the helper message under the field.
- Reach for slots before custom wrappers `leftSlot` and `rightSlot` are the intended extension points for icons and inline actions.
Props and callbacks
Standard input attributes such as `name`, `required`, `autocomplete`, `aria-*`, and `class` pass through to the real `<input>`.
| API | Type | Details |
|---|
type Default: text | 'text' | 'numeric' | 'email' | 'password' | 'color' | 'devEui' | 'creditCard' | 'cardExpiry' | Input behavior and optional formatting mode. |
value Default: '' | string | Current field value. |
label | string | Field label text. |
placeholder | string | Prompt shown when the field is empty. |
error | string | Validation message shown under the field. |
valid Default: false | boolean | Shows the success state when there is no error. |
disabled Default: false | boolean | Disables typing and interactive affordances. |
maxlength | number | Character cap applied after formatting. |
min / max | number | string | Optional numeric bounds used by the inline stepper and keyboard increment/decrement. |
step | number | string | Optional numeric increment for `type="numeric"`. When omitted, the field infers precision from the current value. |
clearable Default: false | boolean | Shows the clear button when the field has a value. |
leftSlot / rightSlot | Snippet | Custom inline icon or action content. |
oninput / onchange / onkeydown / onblur / onfocus | callback | Standard input lifecycle callbacks forwarded from the field. |
Copy-paste examples
These snippets intentionally show the full public API surface the live demo relies on.
Clearable email field
A standard text field with form-friendly attributes and built-in clear behavior.
<script lang="ts">
let email = $state('');
</script>
<CwInput
label="Email"
type="email"
name="email"
required
placeholder="grower@example.com"
autocomplete="email"
clearable
bind:value={email}
/>
Color picker plus formatted inputs
Use the native color control or the specialized formatted types when you need them.
<script lang="ts">
let devEui = $state('');
let accentColor = $state('#2f8f5b');
let threshold = $state('18.5');
let cardNumber = $state('');
let expiry = $state('');
</script>
<CwInput
label="Threshold"
type="numeric"
step={0.5}
min={0}
max={40}
bind:value={threshold}
/>
<CwInput
label="Accent color"
type="color"
bind:value={accentColor}
/>
<CwInput
label="Device EUI"
type="devEui"
placeholder="AA:BB:CC:DD:EE:FF:00:11"
bind:value={devEui}
/>
<CwInput
label="Card number"
type="creditCard"
maxlength={19}
clearable
bind:value={cardNumber}
/>
<CwInput label="Expiry" type="cardExpiry" bind:value={expiry} />
Icon slots and validation feedback
Slots are the extension point for search icons, units, and inline actions.
<CwInput label="Search plots" clearable error="Pick an existing plot">
{#snippet leftSlot()}
<svg viewBox="0 0 16 16" fill="none" style="width:1rem;height:1rem">
<path d="M7 3a4 4 0 110 8 4 4 0 010-8zm4.5 7.5L14 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
</svg>
{/snippet}
{#snippet rightSlot()}
<span style="font-size:0.75rem;color:var(--cw-text-muted)">Ctrl+K</span>
{/snippet}
</CwInput>