Skip to content
Folio

Forms

Input

A single line of text entry.

Usage

TSX
import { Input } from '@misoto22/design'

Notes

A single line of text entry.

Shares CONTROL_BASE with Textarea and Select, so the three cannot drift apart. Pair with Field for the label, hint and error — an input with a placeholder and no label is not labelled, because the placeholder disappears the moment anyone types.

Anatomy

Input anatomy
ElementDescription
Control boxrequiredThe <input>, on the CONTROL_BASE it shares with Textarea and the Select trigger. Its padding is --field-px / --field-py, so a subtree marked data-density="compact" tightens the fields along with the buttons.
Placeholderplaceholder, in --ink-3-aa inside the box — the same slot the value occupies, which is why it cannot also be the name.
Focus borderfocus:border-(--ink) on the border already there, not an added ring. The box does not gain a pixel on focus, so nothing in the row shifts.
Danger borderWhat invalid — or an aria-invalid set by a Field with an error — swaps in. It changes the border colour and nothing else, so the reason has to come from the message below.

Best practices

Do

  • Spell out type and inputMode. An <Input> with no type is type="text", so an email field that never says so gets a phone keyboard with no @ on it and no browser validation at all.
  • Name the field to the browser with autoComplete: a password field without current-password or new-password is one a manager fills with the wrong value and one no browser offers to save.
  • Reach for readOnly rather than disabled when the value is real but not editable — a disabled input is skipped by Tab AND left out of the submitted form data, so the server hears nothing about a field the reader can plainly see.

Don’t

  • readOnly is styled by nothing here: CONTROL_BASE dims on :disabled only, so a read-only input is pixel-identical to an editable one and the first thing a reader learns about it is that typing does nothing.
  • type="number" is for quantities, not for digits. A phone number, a card number or a postcode loses its leading zeros, and a scroll wheel over the focused control changes the value without a keystroke.
  • A Tooltip on a disabled input never opens — disabled:pointer-events-none means the control receives no hover — so the explanation for why it is disabled has to live in the Field’s hint instead.

Examples

default

Resting, invalid, disabled. invalid paints the border with --danger and sets aria-invalid, and that is all it does — the border says something is wrong and never what, so an invalid input outside a Field with an error message is a red box with no reason attached. Each of these carries aria-label because it stands alone here; in a form that is Field's job, and a placeholder is never the name because it leaves the moment anyone types.

types and autofill

type, inputMode and autoComplete, spelled out on every row. An Input that says nothing is type="text": the email field then gets a phone keyboard with no @ on it and no browser validation at all, and a password field that never says current-password is one a manager fills with the wrong value and no browser offers to save. The mobile row is type="tel" rather than type="number" — number is for quantities, and it drops a leading zero and changes value under a scroll wheel.

Australian numbers keep their leading zero.

read only

The same idea locked two ways. readOnly keeps the field in the tab order and in the submitted form data; disabled takes it out of both, so the server hears nothing about a field the reader can plainly see — reach for readOnly whenever the value is real but not editable. Nothing styles readOnly here: the control dims on :disabled only, so a read-only field is pixel-identical to an editable one and the hint has to say so. A Tooltip cannot fill that gap on the disabled row either, because a disabled input receives no hover.

Fixed at sign-up. Copy it, but it cannot be edited here.

Locked while an invoice is outstanding — this one sends nothing on submit.

Accessibility

  • A placeholder is not a label — it disappears the moment anyone types. Pair with Field.