/// Inputs
Input
The base single-line text control — a sunken field with optional leading and trailing adornment slots.
import { Input } from "@protocore/pds";Basics
A sunken, sharp-cornered text field whose border turns to --pds-accent on focus. Spread any native <input> attribute (type, value, onChange, placeholder…) straight through.
Lowercase, hyphen-separated.
Sizes
Three heights: sm (32), md (36, default), and lg (40). Match the Input size to the buttons it sits beside.
Adornments
startAdornment and endAdornment render muted slots inside the field — ideal for units, protocols, or currency glyphs. Keep them to short mono labels, not interactive controls.
States
invalid paints the danger border and sets aria-invalid; native disabled mutes the field. Pair invalid with a Field error so the reason is announced.
When to use
Input is the base for single-line free text — names, hostnames, URLs, tokens. Almost always wrap it in a Field for its label, hint, and error wiring.
Reach for a specialised sibling when the shape fits:
- NumberInput — numeric values with a stepper and min/max/step.
- SearchInput — a query box with a magnifier and clear button.
- Textarea — multi-line text.
- Select / Combobox — choosing from a known set rather than typing free text.
Do & don't
Do
- Wrap Input in a Field so it carries a label and hint.
- Use adornments for static units or glyphs ($, ms, https://).
- Set the right native type (email, url, tel) so mobile keyboards adapt.
- Pair invalid with a Field error that explains the problem.
Don't
- Don't ship an Input with no associated label (Field or an explicit <label>).
- Don't put buttons or links inside an adornment slot — they're decorative.
- Don't use Input for numbers that need stepping — use NumberInput.
- Don't convey invalid with the red border alone; add a message.
Accessibility
- Renders a native `<input>`; give it a label via Field or a wrapping `<label>`.
- `invalid` sets `aria-invalid`; describe the error with Field's `error` text.
- The start adornment is `aria-hidden`; put any meaning users need into the label or value.
- Focus is a visible accent border plus the shared focus ring — never suppressed.
Mobile (React Native)
Preview. @protocore/pds-mobile ships the React Native sibling of Input. It mirrors the web API where React Native allows; the package is a preview with no device-level QA yet, so pin it and expect small changes.
Import it from the mobile package (not @protocore/pds), inside a <PdsProvider> — there is no stylesheet, so style (a ViewStyle) replaces className and every value comes from the theme:
import { Input } from "@protocore/pds-mobile";Parity with web. The sunken single-line text control, wrapping RN TextInput (web wraps <input>).
- Use
onChangeText(RN) instead ofonChange. - The border goes
border-ctrl→accenton focus anddangerwheninvalid;invalidalso setsaccessibilityState.invalid. startAdornment/endAdornmentrender muted slots inside the field.
<Input
size="md"
placeholder="Service name"
value={name}
onChangeText={setName}
/>Input props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | |
endAdornment | ReactNode | — | Trailing slot (muted; mono for glyph/unit labels), rendered inside the field. |
invalid | boolean | — | Mark the field invalid — danger border plus `aria-invalid`. |
size | enum | md | Control height: `sm` (32) · `md` (36, default) · `lg` (40). |
startAdornment | ReactNode | — | Leading slot (muted; mono for glyph/unit labels), rendered inside the field. |
style | CSSProperties | — |