Design System
Text Input
Single-line text field with a floating label. eShop platform — the label sits as the placeholder, then floats up once the field is focused or filled. Supports error and info messages, an optional left icon, disabled, and an on-dark surface variant.
Playground
States
Empty (label as placeholder), filled (label floats up), error, info, and disabled. Focus a field to see the label float and the focus ring.
Messages
Pass error for a critical message and red border, or info for neutral helper text. Error takes precedence over info.
On dark surface
Pass onDark when the field sits on a bold or dark surface — it uses the on-dark token variants for the right contrast.
When to Use
Best for
- Collecting short, free-form text — names, emails, search terms
- Form fields that benefit from a persistent label after filling
- Fields that need inline validation or helper text
Consider alternatives when
- Choosing from a fixed set of options — use a select, radio, or checkbox
- Entering long, multi-line text — use a textarea
- Entering a card number or phone — use the dedicated Card / Phone input
Props
| Prop | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Field label — doubles as the floating placeholder |
value | string | No | Value (controlled). Pair with onChange |
defaultValue | string | No | Initial value (uncontrolled) |
onChange | (value: string) => void | No | Change handler — receives the next value |
leftIcon | FC<SVGProps> | No | SVGR icon component shown before the value |
error | string | boolean | No | Error message (string) or error border only (true) |
info | string | No | Helper message (hidden while an error is shown) |
isDisabled | boolean | No | Disable the field (default: false) |
onDark | boolean | No | Use on-dark token variants for dark surfaces (default: false) |
type | string | No | HTML input type (default: "text") |
name | string | No | Form field name |
id | string | No | Element id (autogenerated when omitted) |
Import
import { TextInput } from '@/components/TextInput/eshop';
Wrap the input (or any ancestor) in <div data-platform="eshop"> so the eShop typography classes apply.
Design Tokens
| Purpose | Token |
|---|---|
| Field fill | var(--color-fill-element-field) |
| Border (default) | var(--color-border-element-field) |
| Border (focused) | var(--color-border-element-field-focused) |
| Border (error) | var(--color-border-element-field-error) |
| Value text | var(--color-content-primary) |
| Placeholder label | var(--color-content-secondary) |
| Floated label | var(--color-content-tertiary) |
| Error message | var(--color-content-critical) |
| Disabled content | var(--color-content-disabled) |
| Focus ring | var(--color-border-element-focus-ring) |
| On-dark variants | var(--color-*-on-dark-*) |
| Radius | var(--primitive-radius-12) |
| Typography (value / label) | .body-lg / .body-sm (scoped to [data-platform="eshop"]) |