Input

canon

Single-line input in text, email, url, code, number and short widths.

States include read-only (canon since 28 Sep 2026, !4102): --surface-75, full --fg text, cursor: text, focus ring kept; replaces the scoped .finput[readonly]. Registered exceptions from <Input> (AD 28 Sep 2026, !4110) — inline editing in context, a 32px box would break the header or the tool: .nt-bub-url (link field inside the note formatting bubble) and .sgb-th-edit (column rename in the segment table header), both --control-h-sm (24px); .sgb-th-edit carries the focus ring like .rr-edit; on touch (pointer: coarse) .nt-bub-url is 44px. Any other bare <input> with a text-field box class fails the input-raw HARD rule.

Used in 90 files · 37 areas · 271× — components/accounting, components/assistant, components/callwrapup, components/clen-tymu, components/datamart, components/mail …

The single-line text field of the app. React <Input> (packages/ui/src/components/Input.tsx) is a thin wrapper over the native <input> that adds .acrm-input (apps/web/src/ds.css) and passes every prop and the ref through; it is controlled-first (value + onChange). The same box is aliased for the legacy clones .sgb-input, .dlr-input and .nastaveni-page .finput, so there is one definition.

When to use

  • Short free text on one line: name, street, subject.
  • E-mail, URL, code (company ID, VAT ID, postal code) — set the native type (text, email, url, number) and pick the width modifier that matches the expected length.
  • A small number typed by hand (.acrm-input--num); an interval from–to as .acrm-range with two 56px inputs and .acrm-range-dash.

When not to use

  • Several lines of text (description, note) — use Textarea; <textarea class="acrm-input"> is blocked by pnpm ds:validate:usage (HARD).
  • A leading icon or a trailing shortcut — use Input with icon and kbd (.acrm-inputwrap).
  • A date or time — use Date field / Time field (family Date & time); never a native type="date".
  • One value from a closed list — use Select (family Select); with suggestions from an external source — Combobox.
  • Small integers stepped by ±1 — .acrm-stepper (ds/inputs.css §2), not the native type="number" spinner.
  • Free tags — Tag input; references to records — Entity reference / Record select.

Anatomy

  • Box: height: 32px (deliberately not --control-h 30px), padding: 0 var(--sp-3), border: 1px solid var(--border-strong), border-radius: var(--radius-sm), background: var(--surface-100) (--surface-50 in dark), color: var(--fg), font: var(--p) (400 13px/1.5), width: 100%.
  • Placeholder: color: var(--fg-muted).
  • Focus: outline: none, border-color: var(--accent), box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent).
  • Read-only (readOnly): background: var(--surface-75), text stays full var(--fg) (the value is read and copied — AA 4.5:1), border, cursor: text, text selection and the focus ring stay. Use for a value the user may see and copy but not change here (e-mail managed by sign-in, feed URL, CLI command, computed result). Canon state since 28 Sep 2026 (AD) — replaces the scoped .nastaveni-page .finput[readonly].
  • Disabled (:disabled or .is-disabled): background: var(--surface-75), border-color: var(--border), no shadow, color: var(--fg-muted), cursor: default.
  • Error (.is-error): border-color: var(--critical) + 3px ring at 16% --critical; the message itself is <Field error>.
  • Widths: .acrm-input--num 88px, .acrm-input--code 132px, .acrm-input--short 210px, .acrm-input--email 280px (all max-width: 100%); default fills the column.
  • Range (ds/inputs.css §3): .acrm-range inline-flex, gap: var(--sp-2), width: max-content; each child input 56px, padding: 0 var(--sp-2), centred, 500 13px with tabular-nums; .acrm-range-dash in --fg-muted.
  • No resting shadow — fields are flat until focused (shadow removed in MR !198).

Best practices

Do
  • Wrap the input in <Field label>; the hint under the field carries the format ("8 digits").
  • Choose the width by the expected content: number → --num, code → --code, e-mail/URL → --email; long text fills the column.
  • Mark a failed value with .is-error on the input and the message in <Field error> — both, so the frame and the text agree.
  • Use the native type (email, url, number) so the keyboard and validation match the content.
Don’t
  • A bare <input> without .acrm-input or a new .xyz-input — every text field is this one box.
  • Stretching a code or number field to the full column — width is content, not layout.
  • A custom height, radius or border colour; the 32px box, --radius-sm and --border-strong are fixed.
  • Accent colour on anything but focus — a filled or "active" field stays neutral.

Content

  • Label is a short noun in sentence case ("Phone", "Company ID"); no colon, no trailing period.
  • Placeholder is a hint, not an example that looks like data: "Set value…", "Add…" — never "[email protected]".
  • Format and limits go in the hint, not in the placeholder or the label.
  • Error text says what is wrong and what fixes it, one sentence with a period: "Enter a valid e-mail address."
  • Numbers in a range are typed as plain digits; the field renders them with tabular-nums. Dates never go through Input (see Date field for the "26. 8." / "14. 11. 27" convention).
  • field — label, hint and error around the input.
  • textarea — multi-line text.
  • input-with-icon-kbd — the same box with a leading icon or trailing .acrm-kbd.
  • date-field, select, combobox, record-select — when the value is a date or a choice.
  • Stories: components--input--default, components--input--variants, components--input--sizes, components--input--states, components--input--composition; legacy overview components--inputs--fields.

Source: docs/text-field/input.usage.md · GitLab