# SingleSelectFilter

**Category:** Features/Filter/Components

## Design

### Overview

Renders a [Dropdown](https://www.docs.wixdesignsystem.com/?path=/story/components-form--dropdown) filter that shows a list of items fetched from a server.

Use [useFilterCollection](./?path=/story/features-filter-hooks--usefiltercollection) to create the collection state object for fetching the list of items.

Use [useStaticListFilterCollection](./?path=/story/features-filter-hooks--usestaticlistfiltercollection) to create the collection state object for a list of static items.

Note that the server should return sections in a strict order.

```tsx
import { SingleSelectFilter } from '@wix/patterns';
```

---

### Variations

### Server Data

```tsx
import React from 'react';
import {
  idNameArrayFilter,
  SingleSelectFilter,
  useFilterCollection,
} from '@wix/patterns';
import { useHttpClient } from '@wix/yoshi-flow-bm';
import { Cell, Layout } from '@wix/design-system';

interface User {
  id: string;
  name: string;
}

function SingleSelectFilterServerData() {
  const [filter] = React.useState(() => idNameArrayFilter());

  const httpClient = useHttpClient();

  const collection = useFilterCollection(filter, {
    queryName: 'SingleSelectFilter-ServerData',
    paginationMode: 'cursor',
    fetchData: (query) => {
      const { limit, cursor, search } = query;
      return httpClient
        .request<{ total: number; items: User[]; cursor?: string }>({
          url: '/api/users',
          data: {
            query: {
              limit,
              cursor,
              search,
            },
          },
        })
        .then(({ data: { items, total, cursor } }) => ({
          items,
          total,
          cursor,
        }));
    },
    limit: 50,
    filters: {},
  });

  return (
    <Layout>
      <Cell span={4}>
        <SingleSelectFilter filter={filter} collection={collection} />
      </Cell>
    </Layout>
  );
}
```

### Static Data

```tsx
import React from 'react';
import {
  idNameArrayFilter,
  SingleSelectFilter,
  useStaticListFilterCollection,
} from '@wix/patterns';
import { Cell, Layout } from '@wix/design-system';

function SingleSelectFilterStaticData() {
  const [filter] = React.useState(() => idNameArrayFilter());

  const collection = useStaticListFilterCollection(filter, [
    { id: '1', name: 'First' },
    { id: '2', name: 'Second' },
    { id: '3', name: 'Third' },
  ]);

  return (
    <Layout>
      <Cell span={4}>
        <SingleSelectFilter filter={filter} collection={collection} />
      </Cell>
    </Layout>
  );
}
```

### Empty State

```tsx
import React from 'react';
import {
  idNameArrayFilter,
  SingleSelectFilter,
  useFilterCollection,
} from '@wix/patterns';
import { Layout, Cell } from '@wix/design-system';

interface User {
  id: string;
  name: string;
}

function SingleSelectFilterEmptyState() {
  const [filter] = React.useState(() => idNameArrayFilter());

  const collection = useFilterCollection<User>(filter, {
    queryName: 'SingleSelectFilter-EmptyState',
    fetchData: async () => {
      return { items: [], total: 0 };
    },
    limit: 50,
    filters: {},
  });

  return (
    <Layout>
      <Cell span={4}>
        <SingleSelectFilter filter={filter} collection={collection} />
      </Cell>
    </Layout>
  );
}
```

### Sections

```tsx
import React from 'react';
import {
  idNameArrayFilter,
  SingleSelectFilter,
  useFilterCollection,
} from '@wix/patterns';
import { useHttpClient } from '@wix/yoshi-flow-bm';
import { Cell, Layout } from '@wix/design-system';

interface User {
  id: string;
  name: string;
}

function SingleSelectFilterSections() {
  const [filter] = React.useState(() => idNameArrayFilter());

  const httpClient = useHttpClient();

  const collection = useFilterCollection(filter, {
    queryName: 'SingleSelectFilter-Sections-Users',
    paginationMode: 'cursor',
    fetchData: (query) => {
      const { limit, cursor, search } = query;
      return httpClient
        .request<{ total: number; items: User[]; cursor?: string }>({
          url: '/api/users',
          data: {
            query: {
              limit,
              cursor,
              search,
            },
          },
        })
        .then(({ data: { items, total, cursor } }) => ({
          items,
          total,
          cursor,
        }));
    },
    limit: 20,
    filters: {},
  });

  return (
    <Layout>
      <Cell span={4}>
        <SingleSelectFilter
          filter={filter}
          collection={collection}
          renderSection={(sectionId) => {
            return {
              id: sectionId,
              title: sectionId,
            };
          }}
          renderItem={(item, index) => {
            return {
              id: item.id,
              title: item.name,
              sectionId: `User's generation #${Math.floor(index / 10)}`,
            };
          }}
        />
      </Cell>
    </Layout>
  );
}
```

### Custom render items

The default behavior uses the itemName for rendering the option value. Use renderItem to override it.

```tsx
import React from 'react';
import {
  idNameArrayFilter,
  SingleSelectFilter,
  useFilterCollection,
} from '@wix/patterns';
import { useHttpClient } from '@wix/yoshi-flow-bm';
import { Cell, Layout } from '@wix/design-system';

interface User {
  id: string;
  name: string;
}

function CustomRenderItem() {
  const [filter] = React.useState(() => idNameArrayFilter());

  const httpClient = useHttpClient();

  const collection = useFilterCollection(filter, {
    queryName: 'SingleSelectFilter-CustomRenderItem',
    paginationMode: 'cursor',
    fetchData: (query) => {
      const { limit, cursor, search } = query;
      return httpClient
        .request<{ total: number; items: User[]; cursor?: string }>({
          url: '/api/users',
          data: {
            query: {
              limit,
              cursor,
              search,
            },
          },
        })
        .then(({ data: { items, total, cursor } }) => ({
          items,
          total,
          cursor,
        }));
    },
    limit: 50,
    filters: {},
  });

  return (
    <Layout>
      <Cell span={4}>
        <SingleSelectFilter
          filter={filter}
          collection={collection}
          renderItem={(item) => ({ title: 'The name is: ' + item.name })}
        />
      </Cell>
    </Layout>
  );
}
```

## API

### Extends

[DropdownProps](https://www.docs.wixdesignsystem.com/?activeTab=API&path=/story/components-form--dropdown)

### Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `collection` | `CollectionState<V, F>` | Yes | - | Collection state object to fetch the items for the dropdown list.<br> Create using [useFilterCollection](./?path=/story/features-filter-hooks--usefiltercollection) or [useStaticListFilterCollection](./?path=/story/features-filter-hooks--usestaticlistfiltercollection). |
| `renderItem` | `((item: V, index: number) => ListItem)` | No | - | A function that returns a [ListItemSelectProps](https://www.docs.wixdesignsystem.com/?path=/story/components-form-dropdownlistitems--listitemselect) extended by `{sectionId?: string}`<br/> (Optional) |
| `renderSection` | `((sectionId: string) => ListItemSelectionBuilderParams)` | No | - | A function that returns [ListItemSectionProps](https://www.docs.wixdesignsystem.com/?path=/story/components-form-dropdownlistitems--listitemsection) <br/> According to make it works you need return `sectionId` in `renderItem` method. <br/> ⚠️ Server should return section items sorted by sections in strict order. Otherwise, when using infinite scrolling the behavior of the sections will be unexpected (see sections example). <br/> (Optional) |
| `size` | `"small" \| "tiny" \| "medium" \| "large"` | No | - | Controls the size of the input. Default value: `medium` |
| `dataHook` | `string` | No | - | Applies a data-hook HTML attribute that can be used in the tests |
| `className` | `string` | No | - | Specifies a CSS class name to be appended to the component's root element. |
| `dropDirectionUp` | `boolean` | No | - | @deprecated |
| `focusOnSelectedOption` | `boolean` | No | - | Scroll view to the selected option on opening the dropdown |
| `onClose` | `(() => void)` | No | - | Callback function called whenever the user press the `Escape` keyboard. |
| `onOptionMarked` | `((option: DropdownLayoutValueOption \| null, optionElementId?: string) => void)` | No | - | Callback function called whenever an option becomes focused (hovered/active). Receives the relevant option object from the original props.options array. |
| `onOptionsNavigate` | `((option: DropdownLayoutValueOption \| null) => void)` | No | - | Callback function called whenever the user navigates to an option (via keyboard or mouse). Receives the relevant option object from the original props.options array, or null when navigation is cleared. |
| `visible` | `boolean` | No | - | Should show or hide the component |
| `selectedId` | `string \| number` | No | - | Specifies selected option by its id. |
| `tabIndex` | `number` | No | - | Indicates that element can be focused and where it participates in sequential keyboard navigation |
| `onClickOutside` | `((e: TouchEvent \| MouseEvent) => void)` | No | - | @deprecated Do not use this prop. |
| `fixedHeader` | `ReactNode` | No | - | A fixed header to the list |
| `fixedFooter` | `ReactNode` | No | - | A fixed footer to the list |
| `maxHeightPixels` | `string \| number` | No | - | Set the max height of the dropdownLayout in pixels |
| `minWidthPixels` | `string \| number` | No | - | Set the min width of the dropdownLayout in pixels |
| `withArrow` | `boolean` | No | - | @deprecated Do not use this prop. |
| `closeOnSelect` | `boolean` | No | `true` | Closes DropdownLayout on option selection |
| `onMouseEnter` | `MouseEventHandler<HTMLElement>` | No | - | Callback function called whenever the user entered with the mouse to the dropdown layout. |
| `onMouseLeave` | `MouseEventHandler<HTMLElement>` | No | - | Callback function called whenever the user exited with the mouse from the dropdown layout. |
| `onMouseDown` | `MouseEventHandler<HTMLElement>` | No | - | Callback function called whenever the user clicks the dropdown layout. |
| `itemHeight` | `"big" \| "small"` | No | - | @deprecated Do not use this prop. |
| `selectedHighlight` | `boolean` | No | `true` | Whether the selected option will be highlighted when dropdown reopened. |
| `inContainer` | `boolean` | No | - | Whether the `<DropdownLayout/>` is in a container component. If `true`, some styles such as shadows, positioning and padding will be added the the component contentContainer. |
| `infiniteScroll` | `boolean` | No | - | Set this prop for lazy loading of the dropdown layout items. |
| `loadMore` | `((page: number) => void)` | No | - | A callback called when more items are requested to be rendered. |
| `hasMore` | `boolean` | No | - | Whether there are more items to be loaded. |
| `markedOption` | `string \| number \| boolean` | No | - | Sets the default hover behavior when: 1. `false` means no default 2. `true` means to hover the first selectable option 3. Any number/string represents the id of option to hover |
| `overflow` | `"visible" \| "hidden" \| "scroll" \| "auto"` | No | - | Set overflow of container |
| `focusOnOption` | `string \| number` | No | - | Marks (not selects) and scrolls view to the option on opening the dropdown by option id |
| `scrollToOption` | `string \| number` | No | - | Scrolls to the specified option when dropdown is opened without marking it |
| `listType` | `"action" \| "select"` | No | - | Defines type of behavior applied in list |
| `autoFocus` | `boolean` | No | - | Focus the element on mount (standard React input autoFocus) |
| `scrollbar` | `"fixed" \| "overlay"` | No | - | Controls which type of scrollbar to render |
| `listboxId` | `string` | No | - | Defines the id for the listbox |
| `onDrillIn` | `((option: DropdownLayoutValueOption) => void)` | No | - | Called when the user presses ArrowRight on a hovered option. Use to move focus into an interactive child element (e.g. an actions menu). |
| `onDrillOut` | `(() => void)` | No | - | Called when the user navigates back from a drilled-in child element (e.g. via ArrowLeft or Escape). Use to restore focus to the trigger input. |
| `autocomplete` | `string` | No | `'off'` | Sets the value of native autocomplete attribute (check the [HTML spec](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete) for possible values |
| `inputElement` | `ReactElement<any, string \| JSXElementConstructor<any>>` | No | - | Use a customized input component instead of the default @wix/design-system `<Input/>` component |
| `onManuallyInput` | `ManualInputFnSignature` | No | - | A callback which is called when the user performs a Submit-Action. Submit-Action triggers are: "Enter", "Tab", [typing any defined delimiters], Paste action. `onManuallyInput(values: Array<string>): void - The array of strings is the result of splitting the input value by the given delimiters |
| `valueParser` | `((option: DropdownLayoutValueOption) => ReactNode \| RenderOptionFn)` | No | - | Function that receives an option, and should return the value to be displayed. |
| `dropdownWidth` | `string` | No | `null` | Sets the width of the dropdown |
| `dropdownOffsetLeft` | `string` | No | `'0'` | Sets the offset of the dropdown from the left |
| `showOptionsIfEmptyInput` | `boolean` | No | `true` | Controls whether to show options if input is empty |
| `highlight` | `boolean` | No | - | Mark in bold word parts based on search pattern |
| `native` | `boolean` | No | `false` | Indicates whether to render using the native select element |
| `popoverProps` | `PopoverCommonProps` | No | - | common popover props |
| `onOptionsShow` | `(() => void)` | No | - | A callback which is called when options dropdown is shown |
| `onOptionsHide` | `(() => void)` | No | - | A callback which is called when options dropdown is hidden |
| `showDrawerOnMobile` | `boolean` | No | `true` | Controls whether to show drawer on mobile devices |
| `id` | `string` | No | - | Assigns a unique identifier for the root element |
| `role` | `string` | No | - | Specifies the role of the input element for accessibility |
| `ariaControls` | `string` | No | - | Associate a control with the regions that it controls |
| `ariaDescribedby` | `string` | No | - | Associate a region with its descriptions. Similar to aria-controls but instead associating descriptions to the region and description identifiers are separated with a space. |
| `ariaLabel` | `string` | No | - | Define a string that labels the current element in case where a text label is not visible on the screen |
| `autoSelect` | `boolean` | No | - | Automatically selects the entire input text |
| `defaultValue` | `InputValue` | No | - | Defines the initial value of an input |
| `disabled` | `boolean` | No | - | Specifies whether input should be disabled or not |
| `status` | `"error" \| "warning" \| "loading"` | No | - | Specify the status of a field |
| `statusMessage` | `ReactNode` | No | - | Defines the message to display on status icon hover. If not given or empty there will be no tooltip. |
| `statusMessageTooltipProps` | `TooltipCommonProps` | No | - | Status message tooltip props |
| `hideStatusSuffix` | `boolean` | No | - | Specifies whether status suffix should be hidden |
| `forceFocus` | `boolean` | No | - | USED FOR TESTING - forces focus state on the input |
| `forceHover` | `boolean` | No | - | USED FOR TESTING - forces hover state on the input |
| `maxLength` | `number` | No | - | Sets the maximum number of characters that can be inserted to a field |
| `menuArrow` | `boolean` | No | - | Specifies whether input should have a dropdown menu arrow on the right side |
| `clearButton` | `boolean` | No | - | Displays clear button (X) on a non-empty input |
| `focusOnClearClick` | `boolean` | No | - | Specifies whether to focus the field when clear button is clicked |
| `name` | `string` | No | - | Reference element data when a form is submitted |
| `border` | `"standard" \| "round" \| "bottomLine" \| "none"` | No | - | Control the border style of input |
| `noLeftBorderRadius` | `boolean` | No | - | Specifies whether input shouldn't have rounded corners on its left |
| `noRightBorderRadius` | `boolean` | No | - | Specifies whether input shouldn't have rounded corners on its right |
| `onBlur` | `FocusEventHandler<HTMLInputElement>` | No | - | Defines a standard input onBlur callback |
| `onChange` | `ChangeEventHandler<HTMLInputElement>` | No | - | Defines a standard input onChange callback |
| `onCompositionChange` | `((isComposing: boolean) => void)` | No | - | Defines a callback function called on compositionstart/compositionend events |
| `onEnterPressed` | `KeyboardEventHandler<HTMLInputElement>` | No | - | Defines a callback handler that is called when the user presses -enter- |
| `onEscapePressed` | `KeyboardEventHandler<HTMLInputElement>` | No | - | Defines a callback handler that is called when the user presses -escape- |
| `onFocus` | `FocusEventHandler<HTMLInputElement>` | No | - | Defines a standard input onFocus callback |
| `onInputClicked` | `MouseEventHandler<HTMLInputElement \| HTMLDivElement>` | No | - | Defines a standard input onClick callback |
| `onKeyDown` | `KeyboardEventHandler<HTMLInputElement>` | No | - | Defines a standard input onKeyDown callback |
| `onKeyUp` | `KeyboardEventHandler<HTMLInputElement>` | No | - | Defines a standard input onKeyUp callback |
| `onPaste` | `ClipboardEventHandler<HTMLInputElement>` | No | - | Defines a callback handler that is called when user pastes text from a clipboard (using a mouse or keyboard shortcut) |
| `onCopy` | `ClipboardEventHandler<HTMLInputElement>` | No | - | Defines a callback handler that is called when user copies text to a clipboard (using a mouse or keyboard shortcut) |
| `placeholder` | `string` | No | - | Sets a placeholder message to display |
| `prefix` | `ReactNode` | No | - | Pass a component you want to show as the prefix of the input, e.g., text, icon |
| `readOnly` | `boolean` | No | - | Specifies whether input is read only |
| `disableEditing` | `boolean` | No | - | Restricts input editing |
| `rtl` | `boolean` | No | - | Specifies text direction. If true, the text will be displayed from right to left |
| `suffix` | `ReactNode` | No | - | Pass a component you want to show as the suffix of the input, e.g., text, icon |
| `textOverflow` | `"clip" \| "ellipsis"` | No | - | Handles text overflow behavior. It can either `clip` (default) or display `ellipsis`. |
| `tooltipPlacement` | `"auto" \| "auto-start" \| "auto-end" \| "top-start" \| "top" \| "top-end" \| "right-start" \| "right" \| "right-end" \| "bottom-end" \| "bottom" \| "bottom-start" \| "left-end" \| "left" \| "left-start"` | No | - | Controls placement of a status tooltip @deprecated use tooltipProps instead |
| `type` | `string` | No | - | Specifies the type of `<input/>` element to display. Default is text. |
| `value` | `string \| number` | No | - | Specifies the current value of the element |
| `required` | `boolean` | No | - | Specifies whether input is mandatory |
| `min` | `MinValue` | No | - | Sets a minimum value of an input. Similar to HTML5 min attribute. |
| `max` | `MaxValue` | No | - | Sets a maximum value of an input. Similar to html5 max attribute. |
| `step` | `number` | No | - | Specifies the interval between number values |
| `customInput` | `Function \| ReactNode` | No | - | Render a custom input instead of the default html input tag |
| `pattern` | `string` | No | - | Sets a pattern that typed value must match to be valid (regex) |
| `inputRef` | `Ref<HTMLInputElement>` | No | - | Ref to the underlying `<input>` DOM element. Accepts callback and object refs. Use for input masking libraries such as `use-mask-input`. Memoize callback refs to avoid reattaching on every render. |
| `clearButtonTooltipContent` | `ReactNode` | No | - | When provided hover will display a tooltip with content |
| `clearButtonTooltipProps` | `TooltipCommonProps` | No | - | Clear button tooltip props |
| `clearButtonAriaLabel` | `string` | No | - | Aria label for the clear button |
| `inputElementRef` | `any` | No | - | Specifies reference of the input element |
| `filter` | `Filter<V[]>` | Yes | - | A filter state object such as [ArrayFilter](./?path=/story/features-filter-factories--arrayfilter) |
| `fieldType` | `"SHORT_TEXT" \| "LONG_TEXT" \| "NUMBER" \| "BOOLEAN" \| "DATE" \| "DATE_TIME" \| "DATETIME" \| "TIME" \| "URL" \| "EMAIL" \| "IMAGE" \| "MEDIA_GALLERY" \| "AUDIO" \| "DOCUMENT" \| "MULTI_DOCUMENT" \| "RICH_TEXT" \| "RICH_CONTENT" \| "REFERENCE" \| "MULTI_REFERENCE" \| "OBJECT" \| "ARRAY" \| "ADDRESS" \| "COLOR" \| "INTEGER" \| "DECIMAL" \| "CHECKBOX" \| "DROPDOWN" \| "FILES" \| "MULTI_SELECT"` | No | - | The field type string used to resolve a prefix icon for the filter. Cairo maps this to the appropriate icon internally. |
| `layout` | `"button"` | No | - | Padding settings. If this prop it omitted, padding will exist on the sides of the filter.<br> <br> Supported values: <br> - `"button"`: Removes padding from the sides of the filter. |
| `toolbarItemProps` | `{ label?: ReactNode; }` | No | - | Customizes the filter in the toolbar.<br> <br> Supported properties: <br> - `label`: [string] Prefix for the filter element. |
| `toolbarTagProps` | `{ label?: string; }` | No | - | Customizes the filter tag in the toolbar.<br> <br> Supported properties: <br> - `label`: [string] Overrides the default filter name when filtered tag is shown. |
| `initiallyOpen` | `boolean` | No | - | Indicates whether the filter should be visible by default in the filters panel |
| `accordionItemProps` | `(AccordionItemType & { label?: string; })` | No | - | Customizes the filter [accordion](https://www.docs.wixdesignsystem.com/?path=/story/components-lists--accordion).<br> <br> Supported properties: <br> - `label`: [string] Accordion item title. You can also use `AccordionProps['items'][number].title` for more flexibility. <br> - Extends [AccordionProps['items'[number]](https://www.docs.wixdesignsystem.com/?path=/story/components-lists--accordion). |
| `onAppliedFilterTagRemove` | `((item: V) => unknown)` | No | - | Callback that's run when a filter is removed by a visitor from the sub-toolbar. @param item |
| `renderToolbarTag` | `((item: V) => Partial<TagListTag>)` | No | - | Customizes how the tag list in the sub-toolbar is rendered. <br><br> Extends [`TagListProps['tags'][number]`](https://www.docs.wixdesignsystem.com/?path=/story/components-lists-table--taglist). |
| `sectionTitle` | `string` | No | - | Title for the section in the accordion. |
| `initialSelectedId` | `undefined` | No | - | An initial selected option id. (Implies Uncontrolled mode) |
| `allowTextSelection` | `boolean` | No | `true` | Controls whether a user can select a text of a selected value. |
| `initialFetchTiming` | `"focus"` | No | `undefined - on component mount` | At which point the initial fetch of the filter collection data takes place. If this prop is omitted, it will take place on component mount.<br> <br> Supported values: <br> - `focus`: On the first visitor interaction with the filter component. |

