Skip to main content

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 ComboboxSingleSelect.
  • 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;