Components · Inputs
Input
BetaA single-line text field, such as a client's name.
- Source
components/ui/input.tsx - shadcn/ui Input
- Figma: not linked yet (Q13)
We send the program invite to this address.
When to use
- For short free text and numbers: a client's name, an email, a target weight.
- Always with a visible label.
When not to use
- For long text such as coach notes: use a textarea.
- To pick from a known list: use a Select, or a combobox when the list is long.
- For dates: use the date picker.
Anatomy
In kilograms
- 1. Label: always visible, above the field
- 2. Field: border, background and focus ring
- 3. Help or error text, linked with aria-describedby
Variants
Inputs have one style. Combine them with an icon or a unit for common cases.
kcal
- Search: a search icon at the start; the label can be visually hidden because the icon and placeholder make the purpose clear, but it stays in the markup.
- With unit: kg, kcal, reps or a currency at the end, outside the value, announced through
aria-describedby.
States
Enter at least 1 set.
| State | What changes | Token |
|---|---|---|
| Focus-visible | Border and a 3px ring | border-ring, ring-ring/50 |
| Disabled | Half opacity, not editable | opacity-(--opacity-disabled) |
| Invalid | Red border and ring, error text below | border-destructive, ring-destructive/20, text-destructive-text |
| Placeholder | Lighter text | text-muted-foreground |
Usage guidelines
- Size the field for the expected value: a weight field doesn't need full width.
- Show the error after the coach leaves the field or submits, not on every keystroke.
Content guidelines
- Labels are short nouns in sentence case: "Client email", not "Please enter the client's email".
- Help text says what the value is used for or its format: "In kilograms".
- Error text says how to fix it: "Enter at least 1 set", not "Invalid value".
- Emails, URLs and phone numbers are typed left to right in Arabic too: set
dir="ltr"on those inputs.
Accessibility
| Key | Does |
|---|---|
| Tab | Moves focus into the field |
| Shift+Tab | Moves focus out |
- Every input has a
<Label htmlFor>. A screen reader announces "Client email, edit text, We send the program invite to this address". - Errors set
aria-invalid="true"and are linked witharia-describedby, so they are read with the field. - Use the right
typeandinputMode(email,numeric) so phones show the right keyboard.
RTL
- Text aligns to the start and the caret starts on the right.
- Icons and units use
start-3andend-3withps-9andpe-14, so they swap sides automatically. - Fields for emails, links and phone numbers stay left to right (
dir="ltr").
Tokens used
Read from components/ui/input.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.
| Token | Utilities | SuperCoach | Coach |
|---|---|---|---|
| --destructive | border-destructive ring-destructive/20 | red-600 | red-600 |
| --foreground | text-foreground | neutral-950 | neutral-950 |
| --input | border-input | neutral-200 | neutral-200 |
| --muted-foreground | text-muted-foreground | neutral-600 | neutral-600 |
| --primary | bg-primary | brand-600 | orange-500 |
| --primary-foreground | text-primary-foreground | white | white |
| --ring | border-ring ring-ring/50 | brand-600 | orange-500 |
- Opacity
opacity-(--opacity-disabled) - Radius
rounded-md - Shadow
shadow-xs - Type
text-base - Type
font-medium - Type
text-sm
Props
<Input>
Also takes every prop of <input>
No props of its own.
Replaces in coach-admin
From the read-only audit of coach-admin: 66 style values, 97 uses.
Classes and selectors
.form-control5.form-control:focus4.form-control[disabled]2.form-control, .form-select2.form-control-dark:focus2.form-control:disabled1.form-control:disabled, .form-control[readonly]1.form-control:disabled, .form-control[readonly], .rw-widget-1.form-control-dark1.form-control:focus, .form-select:focus1
Files
src/reusableComponents/formComponents/input/input.scss50src/reusableComponents/formComponents/input-with-unit/input-with-unit.scss32
The inventory lists the first 12 locations of each value, so file counts are a lower bound.
SCSS variables in these styles
$border-color→--border$light-primary-colornot a color: spacing, size or layout