> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SearchInput

> Controlled search text with an optional filter popup.

export const StoryEmbed = ({storyId, title, height = 240}) => <>
    <Tabs>
      <Tab title="Light">
        <iframe title={`${title} (light)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:light`} width="100%" height={height} loading="lazy" style={{
  border: 0
}} />
      </Tab>
      <Tab title="Dark">
        <iframe title={`${title} (dark)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:dark`} width="100%" height={height} loading="lazy" style={{
  border: 0
}} />
      </Tab>
    </Tabs>
    <a href={`https://storybook.twenty.com/?path=/story/${storyId}`}>
      Open in Storybook
    </a>
  </>;

`SearchInput` supplies a search icon and text input. `onChange` receives the new string. Filtering, fetching, and debouncing belong to your application.

```tsx theme={null}
import { useState } from 'react';
import { SearchInput } from 'twenty-ui/components';

export const PeopleSearch = () => {
  const [search, setSearch] = useState('');

  return (
    <SearchInput
      aria-label="Search people"
      placeholder="Name or email"
      value={search}
      onChange={setSearch}
    />
  );
};
```

Use `aria-label` or `aria-labelledby` for an accessible name. `filterDropdown` receives a filter button that you can compose with a [Dropdown](/ui/components/dropdown) trigger using `render`. Supply `filterButtonAriaLabel` to name that action. `disabled` disables the text input; configure the optional filter controls separately.

<StoryEmbed storyId="ui-input-searchinput--default" title="SearchInput example" height={280} />

## Props

<ParamField body="aria-label" type="string">
  Accessible name when aria-labelledby is absent.
</ParamField>

<ParamField body="aria-labelledby" type="string">
  ID of the element that labels the input. Takes precedence over aria-label.
</ParamField>

<ParamField body="autoFocus" type="boolean">
  Focuses the input when mounted.
</ParamField>

<ParamField body="className" type="string">
  Class applied to the wrapper.
</ParamField>

<ParamField body="disabled" type="boolean">
  Disables the text input. Configure filter popup controls separately.
</ParamField>

<ParamField body="filterButtonAriaLabel" type="string" default="Filter">
  Accessible label for the optional filter button.
</ParamField>

<ParamField body="filterDropdown" type="((filterButton: ReactElement<unknown, string | JSXElementConstructor<any>>) => ReactNode)">
  Renders a filter popup around the supplied filter button.
</ParamField>

<ParamField body="id" type="string">
  Input ID, generated when omitted.
</ParamField>

<ParamField body="onChange" type="(value: string) => void" required>
  Called with the new text, not a DOM change event. The application owns filtering.
</ParamField>

<ParamField body="placeholder" type="string">
  Hint shown when the input is empty. Also used as the accessible name if no explicit label is supplied.
</ParamField>

<ParamField body="value" type="string" required>
  Current search text.
</ParamField>
