Skip to main content
In progress

TextInput

A TextInput is a single-line field that allows users to enter short, structured information such as names, email addresses or titles.

Code example
import { TextInput } from '@yleisradio/yds-components-react';

<TextInput label="Label" placeholder="Placeholder"/>

Why to use

TextInputs enable users to quickly provide essential information in forms and other interactive surfaces. They support validation, contextual guidance, and clear feedback, ensuring users can complete tasks efficiently and accurately. Use this component whenever a short textual answer or identifier is needed.

When to use

Use a TextInput when users need to provide short, single-line information such as names, email addresses, titles or identifiers. TextInputs work best for structured or concise responses that fit naturally on one line and benefit from clear validation and guidance.

They are ideal for forms, dialogs, inline edits and search fields where clarity, speed and accuracy are important.

Do
  • Use TextInput for short, single-line answers (e.g., “Etunimi”, “Sähköposti”).
  • Provide a clear, descriptive label for every field.
  • Add helper text when users need extra context or rules.
  • Match field width to expected input length.
  • Use full width on mobile for comfortable typing.
  • Use real-time validation when helpful.
  • Use separate inputs for separate pieces of information (e.g., “Etunimi” + “Sukunimi”).
Don’t
  • Don’t use a TextInput for multi-line answers — use TextArea instead.
  • Don’t use placeholder text as a label.
  • Don’t rely on color alone to indicate validation results.
  • Don’t disable inputs without explaining why.
  • Don’t overload views with excessive fields.

Content Guidelines

TextInput content should clearly communicate what information is required and how to provide it. Labels, placeholders, descriptions and error messages must remain short, direct and scannable.

Do
  • Use short, descriptive labels (e.g., “Sähköposti”, “Otsikko”).
  • Use placeholder text for examples, not instructions (e.g., “esimerkki@osoite.fi”).
  • Add concise helper text for extra context (esim. “3–16 merkkiä”).
  • Write specific error messages that explain the issue (e.g.,“Syötä voimassa oleva sähköpostiosoite”).
  • Keep terminology consistent across similar fields.
Don’t
  • Don’t duplicate label text inside the placeholder.
  • Don’t use vague or generic labels (e.g., “Teksti”).
  • Don’t include long paragraphs in descriptions.
  • Don’t use overly technical wording.
  • Don’t rely solely on placeholder text — it disappears when user types.

Anatomy

TextInput anatomy

  1. Label – Describes the purpose of the field.
  2. Start icon – Decorative or contextual symbol.
  3. Description – Provides additional guidance below the field.
  4. Placeholder – Example or hint text inside the field.
  5. Input field – Area where users enter text.
  6. End icon – Decorative or functional symbol, e.g., visibility toggle.
  7. Optional field indicator – Shows that the field is not required to fill.

Key Props

Use the following props to customize the TextInput component to fit your needs.

type

Supported HTML input types. Invalid values fall back to text.

ValueExampleDescription
text
Generic free-form text.
email
Email address pattern (may trigger native validation/UI).
password
Obscures characters for secrets.
number
Numeric value (spinner / numeric keyboard).
tel
Telephone number (phone keypad on mobile).
search
Search field styling (enables native clear in some browsers).
Code example
<TextInput label="Email" id="email" type="email" placeholder="name@example.com" />
<TextInput label="Password" id="pwd" type="password" />
<TextInput label="Search" id="search" type="search" placeholder="Search" />

label

info

Label can be visually hidden but must remain readable for screen readers.

TypeExampleDescription
string
Provides a clear purpose for the field.
Code example
<TextInput label="Username" id="username" />

description

Helper guidance placed below the field.

TypeExampleDescription
string

3–16 characters

Provides additional guidance below the field.
Code example
<TextInput label="Username" id="username" description="3–16 characters" placeholder="Enter username" />

success

TypeExampleDescription
boolean
Indicates successful validation.
Code example
<TextInput label="Email" id="email-input" type="email" success />

errorMessage

TypeExampleDescription
string
Displays a validation error below the field. Sets aria-invalid.
Code example
<TextInput label="Email" id="email-error" type="email" errorMessage="Invalid email" />

isDisabled

Non-interactive, dimmed styling.

TypeExampleDescription
boolean
Temporarily prevents user interaction.
Code example
<TextInput label="Disabled input" id="disabled-input" isDisabled />

isRequired

TypeExampleDescription
boolean
Marks field mandatory for submission.
Code example
<TextInput label="First name" id="name" isRequired />

showLoadingIndicator

Shows a spinner inside the input (left side) while async work occurs (e.g. validating, fetching suggestions).

TypeExampleDescription
boolean
Renders spinner and adjusts padding.
Code example
<TextInput label="Search" id="search-loading" showLoadingIndicator value="Searching" />

Icons

Decorative or actionable icons. Provide meaningful ariaLabel for interactive ones.

PropsExampleDescription
iconBefore
Static or clickable icon before text.
icon
Static or clickable icon after text.
Code example
import { Eye, Search } from '@yleisradio/yds-icons-react';

<TextInput
label="Search"
id="search-x"
type="search"
iconBefore={{ componentFn: Search, ariaLabel: 'Search icon' }}
/>

<TextInput
label="Password"
id="pwd"
type="password"
icon={{ componentFn: Eye, ariaLabel: 'Toggle password visibility', onClick: () => {} }}
/>

autocomplete

Pass through native browser autocomplete hint (e.g. email, username, current-password).

PropExampleDescription
autocomplete
Helps browsers suggest stored values / show suitable keyboard.
Code example
<TextInput label="Email" id="email-ac" type="email" autocomplete="email" />

See MDN Autocomplete attribute for all possible values.

Behavior

  • The label always appears above the input field.
  • Focused input shows a visible focus ring.
  • Validation feedback appears as success or error states.
  • Disabled inputs are non-editable and visually dimmed.
  • Icons can be decorative or functional; functional icons must be accessible.
  • Placeholder text disappears once typing begins.

Accessibility

Implementation examples

Phone number

How to use placeholder, description and optional label in TextInput.

Enter phone number in international format

Code example
import { TextInput } from '@yleisradio/yds-components-react';
<TextInput label="Phone number" labelOptions={{ optionalLabel: '(Optional)' }} placeholder="+358" description="Enter phone number in international format" type="tel" />

With error

Error state provides a clear indication that went wrong and error message tells how to fix it.

Code example
import { TextInput } from '@yleisradio/yds-components-react';
<TextInput label="Email" value="Invalid value" type="email" errorMessage="Please enter a valid email address" />

API Reference

Props

The TextInput component accepts all standard HTML <input> attributes in addition to the following props:

PropTypeRequiredDefaultDescription
labelstringYes
labelOptionsFormElementLabelPropsNo{}
idstringNo
valuestringNo
onChangeReact.ChangeEventHandler<HTMLInputElement>No
placeholderstringNo
descriptionstringNo
errorMessagestringNo
autocompletestringNo
type'text' | 'email' | 'password' | 'number' | 'tel' | 'search'No'text'
successbooleanNofalse
isRequiredbooleanNofalse
isDisabledbooleanNofalse
childrenReactNodeNo
iconInputIconPropsNo
submitButtonReactNodeNo
iconBeforeInputIconPropsNo
iconClearInputIconPropsNo
showLoadingIndicatorbooleanNofalse

Type Definitions

export type InputIconProps = {
componentFn: (props: SVGProps<SVGSVGElement>) => JSX.Element;
ariaLabel: string;
onClick?: () => void;
props?: ButtonHTMLAttributes<HTMLButtonElement>;
};

export type TextInputDSProps = {
label: string;
labelOptions?: FormElementLabelProps;
id?: string;
value?: string;
onChange?: React.ChangeEventHandler<HTMLInputElement>;
placeholder?: string;
description?: string;
errorMessage?: string;
autocomplete?: string;
type?: 'text' | 'email' | 'password' | 'number' | 'tel' | 'search';
success?: boolean;
isRequired?: boolean;
isDisabled?: boolean;
children?: ReactNode;
icon?: InputIconProps;
submitButton?: ReactNode;
iconBefore?: InputIconProps;
iconClear?: InputIconProps;
showLoadingIndicator?: boolean;
};

export type TextInputProps = InputHTMLAttributes<HTMLInputElement> & TextInputDSProps;