Inputs
catnip-input is the single-value field control: text, email, password, or textarea, with modelValue as string or number. catnip-input-date selects or types single dates, datetimes, and ranges. catnip-input-number binds modelValue as number | null with stepper controls and optional digit grouping. catnip-range-input binds modelValue as a number selected within min / max bounds. catnip-input-phone binds modelValue as { countryCode, countryIsoCode, phoneNumber } | null with a searchable country-code picker. catnip-input-chip collects modelValue as string[] (committed chips). catnip-dropdown selects one or many values from a list. catnip-checkbox is a single boolean option (box + label text, optional supporting text per row); catnip-checklist binds modelValue as an array of selected values via the options prop. The chip draft line is separate — see Chip Input — Specs — Draft line for the default (setDraftValue()) vs custom slot (.draftValue) APIs. Field controls that use a composite label reuse the same label and supporting-text patterns summarised below.
See the full catalogue pages:
- Input — Overview — modes, playgrounds, accessibility
- Date Input — Overview — date, datetime, range, calendar panel
- Number Input — Overview — steppers, min/max/step, grouping
- Range Input — Overview — bounded slider, min/max labels, optional value input
- Phone Input — Overview — country picker, dial code, form JSON
- Chip Input — Overview — chips, Add control, draft behaviour
- Dropdown — Overview — single/multi select, filterable lists
- Checkbox — Overview — one option, indeterminate, form submit
- Checklist — Overview — labelled group of checkboxes
- Field Label — Overview — standalone label for custom controls
Everything else (type, modelValue shape, placeholder, size, disabled, icons, textarea layout, Tag-only add controls, …) lives on each component’s Specs and Guidelines tabs. On Chip Input, draft-field-only Input props live under catnipInput.
Shared label props
These components flatten the same label API into <catnip-field-label> embedded in the composite (or catnip-checklist for checkbox groups). html-for / id wiring is handled from the active control—you do not set htmlFor manually on catnip-input, catnip-input-date, catnip-input-number, catnip-range-input, catnip-input-phone, catnip-input-chip, or catnip-checklist.
| Prop | Type | Shared notes |
|---|---|---|
| label | string | Fallback text when the label slot is empty. |
| alignment | string | left | center | right — horizontal alignment of the label block. |
| required | boolean | Shows the visual required marker when true; pair with required on the control (required appears in specs as a control-level prop too). |
| requiredMarker | string | Visual marker when required (default asterisk); HTML required-marker. |
| requiredScreenReaderText | string | Optional screen-reader-only supplement for required fields — rare; HTML required-screen-reader-text. |
| optional | boolean | When true and not required, shows the optional hint. |
| optionalText | string | Overrides the default optional hint copy; HTML optional-text. |
| info | string | Tooltip via info wins over the label.suffix slot when both are set. |
Additional behaviour (for example label testSelectors overrides) is documented on each component — see Input — Specs, Date Input — Specs, Number Input — Specs, Range Input — Specs, Phone Input — Specs, and Chip Input — Specs. For patterns when a parent embeds several children (roles vs repeated rows, nested forwarding), see Component API — Test selectors — Multiple subcomponents of the same type.
For custom controls (native <select>, third-party widgets, bespoke layouts), mount Field Label standalone and wire html-for / id yourself instead of flattening label props onto a composite input.
Shared supporting props
Supporting text renders below Input alongside the native control (or textarea). Date Input, Number Input, Range Input, and Phone Input follow the same field-level placement. Chip Input renders it below the chip list while still attaching the supporting-text id into aria-describedby on the draft field so announcements stay coherent. Checkbox renders it below the option row (outside the clickable label). Checklist renders group-level copy below all options with aria-describedby on the role="group" container.
| Prop | Type | Shared notes |
|---|---|---|
| intent | string | neutral | warning | danger | success — drives borders, focus rings, and supporting tint. danger sets aria-invalid on the control. |
| supportingText | string | string[] | { text, intent?, icon? } | { text, intent?, icon? }[] | Helper/error copy below the field. Omit to hide supporting text. See Multiple supporting messages. |
| ariaDescribedby | string | Extra id values merged into aria-describedby on the interactive control alongside generated supporting ids. |
Multiple supporting messages
Pass a string for a single line (unchanged), a string array for several lines of the same status (typical for validation rules), a message object for one line with its own intent / icon, or an object array when lines differ:
<!-- multiple errors (Vue SFC — arrays must use .supportingText, not a string attribute) -->
<catnip-input
intent="danger"
.supportingText="['Must be at least 8 characters', 'Must include a number']"
/>
<!-- persistent hint + error -->
<catnip-input
intent="danger"
.supportingText="[
{ text: 'Use your work email.', intent: 'neutral' },
{ text: 'Email is required.', intent: 'danger', icon: 'error' }
]"
/>
<!-- single message object -->
<catnip-input
intent="danger"
.supportingText="{ text: 'This field is required.', intent: 'danger', icon: 'error' }"
/>
<!-- password rule checklist (per-line pass / fail + icon) -->
<catnip-input
type="password"
intent="danger"
.supportingText="[
{ text: 'At least 8 characters', intent: 'success', icon: 'tick' },
{ text: 'One uppercase letter', intent: 'danger', icon: 'x' }
]"
/>In plain HTML, pass JSON on supporting-text (object or array); automatic type conversion (enabled by default) coerces it to a real value.
- Field
intentdrives control chrome (border, focus ring,aria-invalid) and default supporting-text colour. - Per-line
intent(object form) affects text colour; lines withoutintentinherit fieldintent. Mixsuccess,warning,danger, andneutralas needed. - Per-line
icon(CatnipIconName, object form only) renders beside that line when set.
Validation and :invalid
Catnip does not mirror native constraint validation (:invalid on the host or inner control, or form-associated validity from ElementInternals) into danger styling. When your validation logic reports an error, set intent="danger" and supporting-text yourself; danger sets aria-invalid on the control.
Why: intent is the single contract for error visuals and accessibility across Input, Date Input, Number Input, Phone Input, and Chip Input. Native :invalid timing is browser-driven (often before the user has interacted), while most products show errors on submit or blur. Auto-styling from validity would also be incomplete—error copy still comes from supporting-text—and inconsistent on variants where rules live in component logic (Date Input min/max/disabled dates, Number Input min/max/step, Phone Input country/default handling, Chip Input draft + chips, Input password masking) rather than on native HTML constraints.
Shared slots (label row)
These elements support the same light-DOM projection for the integrated label strip:
| Name | Purpose |
|---|---|
| label | Replaces label prop content; use for richer markup inside the label element. |
| label.action | Trailing action cell (slot action on the label row), e.g. catnip-link. |
| label.suffix | Custom suffix in the suffix slot — e.g. custom tooltip anchor. info takes precedence when non-empty. |
For events, modelValue, steppers, grouping, control-only icons, showAddButton, catnipInput, … see each component’s specs.