Experience System
Components

Input

Single-line text control with shared field sizing, default or filled appearance, read-only, and error styling aligned with Select and InputGroup.

Installation

The component is exported from @by/experience-system. Add the package with your package manager:

pnpm add @by/experience-system

In this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.

Composition

Use a single Input for one-line text, passwords, numbers (when type allows), and similar native input modes:

Input

In forms, associate a visible label and optional helper or error copy (Label, Field, or your app’s field primitive) via id / htmlFor and aria-describedby. For leading icons, affixes, or clear actions, prefer InputGroup (see registry search) instead of stacking arbitrary elements on top of Input.

Sizing, appearance, readOnly, and aria-invalid styling use the same field-control surface as the Select trigger in @by/experience-system, so controls line up in toolbars and dense forms.

Usage

import { Input, Label } from '@by/experience-system';

Input is a client component ('use client' in the package). Use it inside a Client Component or a dynamic import when using the Next.js App Router.

<Label htmlFor="email">Email</Label>
<Input id="email" name="email" type="email" autoComplete="email" placeholder="you@example.com" />

When to use

  • Short free-form values: names, search queries, codes, quantities (with the right type / inputMode).
  • Controlled or uncontrolled text entry where a native input meets accessibility and platform expectations.

When not to use

  • Multi-line text—use Textarea (or your rich-text editor) instead.
  • Pickers and structured dates/times—use Calendar, registry date/time recipes, or segment-input patterns.
  • Display-only values—use read-only Input only when copying is useful; otherwise plain text or Item may be clearer.

Full attribute reference: MDN — <input>.

Examples

Sizes

size controls height and typography: sm, md (default), lg.

With label

Wire Label with htmlFor to the input id for accessible naming.

Filled appearance

appearance="filled" uses a soft background fill and transparent default border (still shows focus and error borders).

Error state

Set aria-invalid={true} when validation fails; styles follow the shared invalid field tokens.

Read-only

readOnly locks the value, sets aria-readonly, and applies muted field styling.

API Reference

Input renders a native <input>. Design-system props extend the shared field surface; all other props are forwarded to the DOM. For the full native attribute and behavior matrix, use MDN — <input>.

Input

PropTypeDefault
sizesm | md | lgmd
appearancedefault | filleddefault
readOnlyboolean
refReact.Ref<HTMLInputElement>

Also accepts standard input attributes (type, name, value, defaultValue, placeholder, disabled, min, max, pattern, autoComplete, inputMode, event handlers, …). The size HTML attribute is omitted from typings in favor of the Experience System size prop above.

aria-invalid: when true, invalid (error) field styles are applied. There is no separate invalid boolean on this component.

Data attributeValues
data-slotinput
data-sizemirrors size when set
data-readonlypresent when readOnly is true

Accessibility

Associate every input with a visible Label (or equivalent aria-label when a visible label is truly not possible). Surface validation with aria-invalid and describe errors with Field / aria-describedby so assistive tech reads the message after the control name. Do not rely on placeholder alone for the accessible name. Respect disabled versus readOnly semantics: disabled controls are skipped in tab order; read-only controls remain focusable for copy. See MDN — Input accessibility concerns and your product form guidelines.

Source in the repo: packages/experience-system/src/components/Input/Input.tsx. Agent-oriented contracts: packages/experience-system/src/components/Input/Input.instructions.md.

Registry examples

These @by-es items are registry-only composites — live previews, installation steps, and source live on the dedicated pages. See Registry for components.json setup and REGISTRY_TOKEN.

Search input with clear button using InputGroup from @by/experience-system.

→ See /system/components/search.

Phone Input

Phone number input using Input from @by/experience-system and phone icon from @by/icons.

→ See /system/components/phone-input.