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-systemIn 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:
InputIn 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
inputmeets 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, orsegment-inputpatterns. - Display-only values—use read-only
Inputonly when copying is useful; otherwise plain text orItemmay 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
| Prop | Type | Default |
|---|---|---|
size | sm | md | lg | md |
appearance | default | filled | default |
readOnly | boolean | — |
ref | React.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 attribute | Values |
|---|---|
data-slot | input |
data-size | mirrors size when set |
data-readonly | present 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
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.