Description
Input captures a single line of user-entered text. It supports a range of HTML input types (text, email, password, number, search, URL) and integrates with form validation, error messaging, and accessibility patterns.
Login forms, registration flows, consultation setup, stakeholder profiles, search bars, filter panels, settings screens. Anywhere a short user response is needed.
A consistent input component ensures that labels, helper text, error states, and focus behaviour work the same way everywhere — reducing the cognitive overhead of learning each form in the product.
Built on Web Awesome wa-input, wrapped in FormControl for label, helper text, and error message association. For multi-line input, use TextArea.
Input types
| Type | HTML type | Notes |
|---|---|---|
| Text | text |
Default. Freeform single-line text entry. |
email |
Mobile keyboard shows @. Browser validates format on submit. |
|
| Password | password |
Characters masked. Always include a show/hide toggle. |
| Number | number |
Numeric keyboard on mobile. Avoid for free-form numeric text (phone, postcodes) — use type="text" with inputmode. |
| Search | search |
Shows clear button natively on some browsers. Pair with role="search" on the parent form. |
| URL | url |
Browser validates URL format. Mobile keyboard shows .com shortcut. |
States
| State | Behaviour |
|---|---|
| Default | Neutral border, warm white background. |
| Focus | Earthy green border (2px) and focus ring. The border colour shift provides a secondary focus indicator beyond the outline. |
| Filled | Has value. No distinct visual treatment beyond default — value is the signal. |
| Error | Red border. Error icon in label area. Error message below field, associated via aria-describedby. aria-invalid="true" on the input. |
| Disabled | 50% opacity. Not interactive. Field value preserved visually. Associated label reads "disabled". |
| Read-only | Value displayed but not editable. Subtly different treatment from disabled — still focusable, still selectable. Use readonly attribute. |
Anatomy
| Part | Required? | Notes |
|---|---|---|
| Label | Required | Always visible. Never use placeholder text as a substitute for a label. |
| Input field | Required | The text entry area. Height 40px (medium), 32px (small). |
| Helper text | Optional | Appears below the field. Adds context the label alone can't provide. Associated via aria-describedby. |
| Error message | Conditional | Replaces helper text when validation fails. Associated via aria-describedby. Prefaced with an error icon. |
| Prefix / suffix | Optional | Icon or text rendered inside the input boundary. Use for affordances like currency symbols, units, or search icons. |
| Clear button | Optional | Appears when the field has a value. Clears the input. Accessible — labelled "Clear". |
| Password toggle | Conditional | Show/hide password button — required for all password inputs. |
Usage guidelines
When to use
- Short, bounded responses: names, emails, references, search terms, URLs.
- Anywhere a single line of user input is sufficient.
When not to use
- Multi-line responses — use
TextArea. - Selecting from a defined list — use
Dropdown,RadioButton, orSelector. - Date and time values — use
DateTimePicker. - Numeric ranges or sliders — use
RangeSlider.
Do / Don't
Do
Always pair an Input with a visible label. Never rely on placeholder text as the label — it disappears when the user starts typing.
Don't
Don't use type="number" for phone numbers, postcodes, or credit card numbers. These are structured text, not quantities — use type="text" with inputmode="numeric".
Do
Show the error message as soon as the user leaves the field (on blur) — not only on form submission.
Don't
Don't mark all fields as required — only mark required fields, and mark them consistently. Required indicators should have a text equivalent, not just a red asterisk.
Do
Use helper text to set expectations before the user types: "Must be at least 8 characters", "Enter the email address associated with your account".
Don't
Don't use helper text to restate the label. It should add context, not repeat it.
Layout & Spacing
Input fields are full-width by default within their container. Label sits above the field with --op-space-8 gap. Helper text and error messages sit below with --op-space-8 gap from the field boundary.
| Element | Spec |
|---|---|
| Field height (medium) | 40px |
| Field height (small) | 32px |
| Horizontal padding | --op-space-16 (1rem) |
| Label gap | --op-space-8 (0.5rem) |
| Helper / error gap | --op-space-8 (0.5rem) |
| Border radius | --op-radius-md (8px) |
| Min touch target | 44×44px |
Tokens
| Part | Token | Value |
|---|---|---|
--op-color-border-default | ||
--op-color-border-brand | ||
--op-color-border-error | ||
--op-color-bg-primary | ||
--op-color-text-primary | ||
--op-color-text-muted | ||
--op-color-status-error | ||
--op-color-neutral-60 | ||
--op-color-interactive-focus | ||
— |
Engineering notes
- Always associate helper text and error messages with the input using
aria-describedby. Web Awesome'shelp-textprop handles this automatically — if building manually, wire it up explicitly. - Validate on blur, not on every keystroke. Instant per-character validation is disruptive, especially for screen reader users who hear the error message read aloud as they type.
- For the error state, add
aria-invalid="true"to the input element. This is separate from visual error styling — both are required. - Use
autocompleteattributes on all fields where relevant. They significantly improve the experience for users with motor impairments who rely on autofill. - Don't constrain input format via
maxlengthalone — explain the constraint in helper text so users aren't surprised.
Keyboard interaction
| Key | Action |
|---|---|
| Tab | Moves focus to the input field. |
| Shift + Tab | Moves focus to the previous focusable element. |
| Type | Enters text into the field. |
| Backspace / Delete | Removes characters. |
| Escape | When a clear button is present: clears the field value. |
| Enter | Submits the form if the input is the only or last field, or if the form has a submit button in scope. |
Why it matters
Many community participants completing surveys or consultation forms on Social Point are using mobile devices, voice control, or switch access. Visible focus on form inputs is not a nice-to-have — it's how those users know where they are in the form. Clear, high-contrast focus indicators directly increase participation rates.
Focus
Focused inputs display a 2px solid border in --op-color-border-brand and the standard --op-color-interactive-focus outline. Both signals together ensure visibility on a range of backgrounds.
The clear button and password toggle inside the field are independently focusable and have accessible labels.
ARIA
| Attribute | When to use | Example |
|---|---|---|
aria-required="true" |
Required fields. Use alongside a visible required indicator. | aria-required="true" |
aria-invalid="true" |
When the field has a validation error. Set after user interaction — not on page load. | aria-invalid="true" |
aria-describedby |
Associates helper text or error messages with the input. Pass the ID of the text element. | aria-describedby="email-helper" |
aria-label |
Inputs without a visible label (rare — prefer visible labels). Also used when the visible label is ambiguous in screen reader context. | aria-label="Search consultations" |
autocomplete |
All inputs where the browser can assist. Reduces burden on users who rely on autofill. | autocomplete="email" |
Watch out
Don't mark fields as aria-invalid="true" on initial page load before the user has interacted. Screen readers announce the invalid state when the field receives focus — marking everything invalid before the user has had a chance to fill the form creates a disorienting experience. Set aria-invalid after the user leaves the field (on blur) or after form submission.
Contrast
| Element | Foreground / Background | Ratio | WCAG AA |
|---|---|---|---|
| Label text | --op-color-text-primary on #FFF6E9 |
≥ 7:1 | Pass (AAA) |
| Input value text | --op-color-text-primary on #FFF6E9 |
≥ 7:1 | Pass (AAA) |
| Placeholder text | --op-color-neutral-60 on #FFF6E9 |
~3.0:1 | Exempt (WCAG 1.4.3 excludes placeholder text) |
| Helper text | --op-color-text-muted on #FFF6E9 |
≥ 4.5:1 | Pass (AA) |
| Error message | --op-color-status-error on #FFF6E9 |
≥ 4.5:1 | Pass (AA) |
| Focus border | --op-color-green-60 on #FFF6E9 |
3.7:1 | Pass for non-text (UI components — WCAG 1.4.11 requires 3:1) |
Touch targets
The medium input height (40px) with full-width layout meets 44×44px minimum when combined with horizontal extent. The label above and helper text below do not contribute to the interactive area — the clickable zone is the input field itself.
On Social Point community-facing forms, consider increasing field size via the size="large" prop in environments where participants are likely using mobile devices.
Spec differences
Open Point uses custom form field components built with Angular Material. Key differences:
- Labels sit inside the field boundary on entry, floating above on focus (Material Design floating label pattern). Orbit uses fixed labels above the field — this is a visual difference requiring DOM changes, not just CSS.
- Error messages are rendered via Angular Material's
mat-errordirective, notaria-describedby. - Focus border is Angular Material's blue underline, not a full-perimeter border.
- No helper text component — helper text is typically inline text elements.
Token differences
| Part | Open Point token | Orbit token |
|---|---|---|
| | |
| | |
| | |
| |
Migration notes
Replacing Angular Material inputs with Web Awesome wa-input requires template changes. The floating label pattern must be replaced with a fixed label above the field — use <label> + <wa-input> or the label prop on wa-input.
Ensure aria-describedby is implemented for error messages — mat-error does not map automatically to this pattern.
Spec differences
Social Point form inputs are Vue 2 components using a custom form library. Key differences:
- Labels are consistently above the field (same as Orbit) — the label pattern migration is simpler than Open Point.
- Error state uses a red bottom border rather than a full-perimeter error border.
- Helper text is passed as a
hintprop but is not programmatically associated with the input viaaria-describedby. - No password toggle component — show/hide must be added during migration.
Token differences
| Part | Social Point token | Orbit token |
|---|---|---|
| | |
| | |
| | |
| |
Migration notes
The main accessibility gap in Social Point inputs is the missing aria-describedby association between the hint/error text and the input element. This must be fixed during migration. Web Awesome's wa-input with the help-text prop handles this automatically.