Skip to main content
In progress

SearchInput

A Search Input allows users to find the content they need from a service by entering keywords, supporting those who may not be able to locate the desired content through navigation alone.

Code example
import { SearchInput, SearchSubmitButton } from '@yleisradio/yds-components-react';
import { CloseSmall } from '@yleisradio/yds-icons-react';

<SearchInput
id="search-basic"
label="Search"
placeholder="Search articles"
name="q"
submitButton={<SearchSubmitButton aria-label="Search" />}
iconClear={{ componentFn: CloseSmall, ariaLabel: 'Clear search', onClick: () => {} }}
/>

Why to use

The Search Input helps users quickly locate specific content when navigation alone is not sufficient. It enhances usability and supports accessibility by allowing users to find information using familiar search interaction patterns. It provides users with a direct way to find content on a page, application, or service, offers an alternative to browsing for those who may not know where to look, and improves efficiency for returning users who already know what they want to find.

When to use

Use SearchInput when users need to search a content set by typing keywords and triggering a dedicated search action.

Do
  • Use SearchInput for services with large content sets where users may not find content by browsing.
  • Use it for global search (e.g., header search) or scoped search within a page or section.
  • Use it when the search is triggered by submitting (button or Enter), not instant filtering.
  • Use it when users are likely to know what they want to search for (keywords, titles, names).
Don’t
  • Don’t use SearchInput for choosing from predefined options — use Select or Combobox.
  • Don’t use it for instant filtering of small lists — use a filter field / TextInput pattern instead.
  • Don’t place SearchInput where search is not relevant or expected.
  • Don’t use it without an accessible label (visible or visually hidden).

Content Guidelines

SearchInput text should help users understand what they can search and how. Keep labels and placeholders short, familiar, and specific to the search scope.

Do
  • Use a clear label that describes the search scope (e.g., “Hae”, “Hae artikkeleita”, “Hae ohjelmia”).
  • Use placeholder text as an example (e.g., “Kirjoita hakusana”, “Hae artikkeleita”).
  • If the scope is not obvious, add helper text nearby (e.g., “Hakee vain ohjelmista”).
  • Use explicit accessible labels for icon buttons (e.g., submit and clear).
Don’t
  • Don’t rely on placeholder text alone to explain purpose.
  • Don’t duplicate the label in the placeholder.
  • Don’t use long instructional placeholders or rules — put constraints in helper text instead.
  • Don’t use jargon or unclear labels that don’t indicate what is being searched.

Anatomy

SearchInput anatomy

  1. Search text – Example text inside the field.
  2. Search field (input) – Area where the user types the query.
  3. Clear button – Appears when text is present; clears the field.
  4. Search button – Always visible; triggers the search action.

Key Props

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

SearchInput extends TextInput, so it also supports all TextInput props.

submitButton

Provides an explicit search action. Use the supplied <SearchSubmitButton /> or a custom button.

TypeExampleDescription
ReactNode
Renders actionable search trigger at end of field.
Code example
<SearchInput
id="submit-button"
label="Search"
placeholder="Search articles"
submitButton={<SearchSubmitButton aria-label="Search" />}
/>

iconClear

Shows a clickable icon to clear the current value when present.

TypeExampleDescription
InputIconProps
Clears the input.
Code example
<SearchInput
id="s-clear"
label="Search"
value="term"
submitButton={<SearchSubmitButton aria-label="Search" />}
iconClear={{ componentFn: CloseSmall, ariaLabel: 'Clear search', onClick: () => {} }}
/>

SearchSubmitButton component

Helper button that displays a search icon or spinner.

PropTypeDefaultDescription
isDisabledbooleanfalseNon-interactive state; sets aria-disabled.
loadingbooleanfalseShows spinner instead of icon; adds aria-busy.
Code example
<SearchSubmitButton aria-label="Search" />
<SearchSubmitButton loading aria-label="Searching" />
<SearchSubmitButton isDisabled aria-label="Search" />

Behavior

  • The search is triggered by pressing Enter or activating the submit button.
  • The submit button is always available as the explicit action.
  • The clear button (if provided) clears the current value and should be available when text exists.
  • The component can show a loading state (e.g., while fetching results).
  • Disabled state prevents interaction but keeps the field visible.
  • All interactive elements (input, submit, clear) must be keyboard operable.

Accessibility

  • Always provide a label — it may be hidden visually, but it must remain accessible. This ensures users of assistive technologies know what the field is for.
    (WCAG 3.3.2 — Labels or Instructions).
  • Submit and clear controls must have descriptive accessible names (e.g., “Search”, “Clear search”).
    (WCAG 2.1.1 — Keyboard).
  • Keyboard support: Tab/Shift+Tab moves focus; Enter submits; buttons are operable with keyboard.
  • Pressing Enter or clicking the search button performs the search. The user is taken to a search results page or results are displayed dynamically on the same page.
    (WCAG 2.1.1 — Keyboard).
  • The magnifying glass icon is a widely recognized symbol and doesn’t need to include the word “search” visually. However, it must have an accessible label for screen readers.
    (WCAG 3.3.2 — Labels or Instructions).

Implementation examples

Basic search inside a form

Code example
<form action="https://haku.yle.fi" method="get" role="search">
<SearchInput
id="ex-form"
name="q"
label="Search site"
placeholder="Search site"
submitButton={<SearchSubmitButton aria-label="Search" />}
/>
</form>

Without form (manual handler)

Code example
<SearchInput
id="ex-nf"
label="Search"
placeholder="Type term"
submitButton={<SearchSubmitButton aria-label="Search" type="button" onClick={() => alert('Search triggered')} />}
onKeyDown={(e) => { if (e.key === 'Enter') alert('Search triggered'); }}
/>

With clear button

Code example
<SearchInput
id="ex-clear"
label="Search"
value="Initial term"
placeholder="Search"
submitButton={<SearchSubmitButton aria-label="Search" />}
iconClear={{ componentFn: CloseSmall, ariaLabel: 'Clear search', onClick: () => {/* clearing logic */} }}
onChange={() => {}}
/>

Loading state

Code example
<SearchInput
id="ex-loading"
label="Search"
value="query"
submitButton={<SearchSubmitButton aria-label="Searching" loading />}
/>

Disabled

Code example
<SearchInput
id="ex-disabled"
label="Search"
placeholder="Search disabled"
isDisabled
submitButton={<SearchSubmitButton aria-label="Search" isDisabled />}
/>

API Reference

Props

SearchInput

The SearchInput component accepts all standard HTML <input> attributes in addition to the following props. SearchInput extends TextInput, so it supports all TextInput props except icon:

PropTypeRequiredDefaultDescription
submitButtonReactNodeNo

SearchSubmitButton

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

PropTypeRequiredDefaultDescription
isDisabledbooleanNofalse
loadingbooleanNofalse

Type Definitions

SearchInput

export type SearchInputDSProps = Omit<TextInputDSProps, 'icon'>;

export type SearchSubmitButtonDSProps = {
isDisabled?: boolean;
loading?: boolean;
};

SearchSubmitButton

export type SearchInputProps = InputHTMLAttributes<HTMLInputElement> & SearchInputDSProps;

export type SearchSubmitButtonProps = ButtonHTMLAttributes<HTMLButtonElement> &
SearchSubmitButtonDSProps;