# Filter

### Purpose

The Filter component contains all of the complexity for configuring and rendering the supported **@appbaseio/reactivesearch** filter components.

### Usage

Most implementations will pass the filter object directly from the [Filters component](https://search.docs.reactify.com.au/components/filters) as seen in the example below however you could replace that with the useFilter hook for this.

If a render method is not provided a built-in component for that filter will be rendered.

{% tabs %}
{% tab title="Basic" %}

```tsx
import React from "react";
import { Filters } from "@usereactify/search";

import { ExampleFilterList } from "./ExampleFilterList";
import { ExampleFilterRange } from "./ExampleFilterRange";
import { ExampleFilterSlider } from "./ExampleFilterSlider";

export const Component: React.FC = () => {
  return (
    <Filters
      render={(filters) => filters.map((filter) => (
        <Filter
          filter={filter}
          renderFilterList={ExampleFilterList}
          renderFilterRange={ExampleFilterRange}
          renderFilterSlider={ExampleFilterSlider}
        />
      )}
    />
  );
};
```

{% endtab %}

{% tab title="ExampleFilterList" %}

```tsx
import React from "react";
import { FilterProps } from "@usereactify/search";

export type ExampleFilterListProps = React.ComponentProps<
  NonNullable<FilterProps["renderFilterList"]>
>;

export const ExampleFilterList: React.FC<ExampleFilterListProps> = (props) => {
  return (
    <div className="rs__filter">
      <h3 className="rs__filter__name">{props.filter.name}</h3>
      {props.filter.displayView === "list" ? (
        <ExampleFilterListList {...props} />
      ) : null}
      {props.filter.displayType === "single" &&
      props.filter.displayView === "check" ? (
        <ExampleFilterListRadio {...props} />
      ) : null}
      {props.filter.displayType === "multi" &&
      props.filter.displayView === "check" ? (
        <ExampleFilterListCheckbox {...props} />
      ) : null}
      {props.filter.displayView === "swatch" ? (
        <ExampleFilterListSwatch {...props} />
      ) : null}
      {props.filter.displayView === "box" ? (
        <ExampleFilterListBox {...props} />
      ) : null}
    </div>
  );
};

export const ExampleFilterListList: React.FC<ExampleFilterListProps> = (
  props
) => {
  return (
    <ul className="rs__filter__list">
      {props.filterListProps.options.map((option) => (
        <li
          key={option.key}
          className={`rs__filter__list-item ${
            option.checked ? "rs__filter__list-item-active" : ""
          }`}
        >
          <label
            className="rs__filter__list-item-label"
            onClick={() => props.filterListProps.handleChange(option.key)}
          >
            <span className="rs__filter__list-item-key">{option.label}</span>
            <span className="rs__filter__list-item-count">
              ({option.doc_count})
            </span>
          </label>
        </li>
      ))}
    </ul>
  );
};

export const ExampleFilterListRadio: React.FC<ExampleFilterListProps> = (
  props
) => {
  return (
    <ul className="rs__filter__list">
      {props.filterListProps.options.map((option) => (
        <li
          key={option.key}
          className={`rs__filter__list-item ${
            option.checked ? "rs__filter__list-item-active" : ""
          }`}
        >
          <label className="rs__filter__list-item-label">
            <input
              className="rs__filter__list-item-input"
              value={option.key}
              type="radio"
              checked={option.checked}
              onChange={(event) =>
                props.filterListProps.handleChange(event.target.value)
              }
            />
            <span className="rs__filter__list-item-key">{option.label}</span>
            <span className="rs__filter__list-item-count">
              ({option.doc_count})
            </span>
          </label>
        </li>
      ))}
    </ul>
  );
};

export const ExampleFilterListCheckbox: React.FC<ExampleFilterListProps> = (
  props
) => {
  return (
    <ul className="rs__filter__list">
      {props.filterListProps.options.map((option) => (
        <li
          key={option.key}
          className={`rs__filter__list-item ${
            option.checked ? "rs__filter__list-item-active" : ""
          }`}
        >
          <label className="rs__filter__list-item-label">
            <input
              className="rs__filter__list-item-input"
              value={option.key}
              type="checkbox"
              checked={option.checked}
              onChange={(event) =>
                props.filterListProps.handleChange(event.target.value)
              }
            />
            <span className="rs__filter__list-item-key">{option.label}</span>
            <span className="rs__filter__list-item-count">
              ({option.doc_count})
            </span>
          </label>
        </li>
      ))}
    </ul>
  );
};

export const ExampleFilterListSwatch: React.FC<ExampleFilterListProps> = (
  props
) => {
  return (
    <div
      className="rs__filter__list"
      style={{
        display: "flex",
        flexWrap: "wrap",
      }}
    >
      {props.filterListProps.options.map((option) => (
        <div
          key={option.key}
          className={`rs__filter__list-item ${
            option.checked ? "rs__filter__list-item-active" : ""
          }`}
        >
          <div
            className="rs__filter__list-item-label"
            style={{
              display: "inline-block",
              width: "20px",
              height: "20px",
              marginRight: "2px",
              marginBottom: "2px",
              borderRadius: "50%",
              backgroundColor: option.key,
              border: option.checked
                ? "1px solid black"
                : "1px solid transparent",
            }}
            onClick={() => props.filterListProps.handleChange(option.key)}
          />
        </div>
      ))}
    </div>
  );
};

export const ExampleFilterListBox: React.FC<ExampleFilterListProps> = (
  props
) => {
  return (
    <div
      className="rs__filter__list"
      style={{
        display: "flex",
        flexWrap: "wrap",
      }}
    >
      {props.filterListProps.options.map((option) => (
        <div
          key={option.key}
          className={`rs__filter__list-item ${
            option.checked ? "rs__filter__list-item-active" : ""
          }`}
        >
          <div
            className="rs__filter__list-item-label"
            style={{
              display: "flex",
              justifyContent: "center",
              alignItems: "center",
              width: "40px",
              height: "40px",
              marginRight: "2px",
              marginBottom: "2px",
              border: "1px solid black",
              overflow: "hidden",
              cursor: "pointer",
              color: option.checked ? "white" : "black",
              backgroundColor: option.checked ? "black" : "white",
            }}
            onClick={() => props.filterListProps.handleChange(option.key)}
          >
            {option.key}
          </div>
        </div>
      ))}
    </div>
  );
};

```

{% endtab %}

{% tab title="ExampleFilterRange" %}

```tsx
import React from "react";
import { FilterProps } from "@usereactify/search";

export type ExampleFilterRangeProps = React.ComponentProps<
  NonNullable<FilterProps["renderFilterRange"]>
>;

export const ExampleFilterRange: React.FC<ExampleFilterRangeProps> = (
  props
) => {
  return (
    <div className="rs__filter">
      <h3 className="rs__filter__name">{props.filter.name}</h3>
      <ul className="rs__filter__list">
        {props.filterRangeProps.options.map((option) => (
          <li key={option.key} className="rs__filter__list-item">
            <label className="rs__filter__list-item-label">
              <input
                className="rs__filter__list-item-input"
                value={option.key}
                type="radio"
                checked={option.checked}
                onChange={(event) =>
                  props.filterRangeProps.handleChange(event.target.value)
                }
              />
              <span className="rs__filter__list-item-key">{option.label}</span>
            </label>
          </li>
        ))}
      </ul>
    </div>
  );
};

```

{% endtab %}

{% tab title="ExampleFilterSlider" %}

```tsx
import React from "react";
import { FilterProps } from "@usereactify/search";
import ReactSlider from "react-slider";

export type ExampleFilterSliderProps = React.ComponentProps<
  NonNullable<FilterProps["renderFilterSlider"]>
>;

export const ExampleFilterSlider: React.FC<ExampleFilterSliderProps> = (
  props
) => {
  return (
    <div className="rs__filter">
      <h3 className="rs__filter__name">{props.filter.name}</h3>
      <div
        className="rs__filter__slider"
      >
        <ReactSlider
          {...props.filterSliderProps.reactSliderProps}
        />
      </div>
    </div>
  );
};
```

This example uses the **react-slider** package, checkout documentation below.

* **NPM** <https://www.npmjs.com/package/react-slider>
* **Docs** <https://zillow.github.io/react-slider/>
  {% endtab %}
  {% endtabs %}

### Props

```typescript
type FilterProps = {
  /** The filter option being rendered */
  filter: ConfigFilterOption;
  /** Render method for List filters */
  renderFilterList?: React.FC<{
    filter: ConfigFilterOption;
    filterListProps: ReturnType<typeof useFilterListProps>;
  }>;
  /** Render method for Range filters */
  renderFilterRange?: React.FC<{
    filter: ConfigFilterOption;
    filterRangeProps: ReturnType<typeof useFilterRangeProps>;
  }>;
  /** Render method for Slider filters */
  renderFilterSlider?: React.FC<{
    filter: ConfigFilterOption;
    filterSliderProps: ReturnType<typeof useFilterSliderProps>;
    // reactSliderProps: ReturnType<typeof useReactSliderProps>;
  }>;
  /** Show filters even when no options are available */
  showEmptyFilters?: boolean;
};
```
