Last updated

List Filters

List filters are the most common type of filter.

A list filter consists of a name and an array of items (ListFilterItem). Each item has an id, resultCount, text, and value.

It is possible for more than one ListFilterItem to be active at once. ListFilterItems are additive, meaning if the 'Blue' and 'Black' ListFilterItems are selected, only products that match both 'Blue' and 'Black' will be returned.

A query for list filters looks like this:

... on ListFilter {
  hasActiveItems @client
  items {
    id
    text
    value
    resultCount
    isActive @client
  }
}

Notice the @client directives. Those are not returned by the API, but are added by the Flight framework. These fields are added to make it more convenient for you to display an indication of which items are selected when rendering list filters.

useListFilter

The useListFilter hook can be used to update list filters. It will update the state of the above client directives, and will also update the URL params with the selected filter.

const { apply, clear } = useListFilter({ filter });

Arguments

ArgumentTypeRequired?Description
optionsOptionstrueRequired options object

Options

OptionTypeRequired?Description
filterListFiltertrueThe ListFilter you would like to act on

Result

PropertyTypeDescription
apply({ value }: { value: string }) => Promise<ExecutionResult<ListFilter>>Applies the given value to the list filter. Returns a promise that will resolve with the list filter.
clear() => voidClears the selected list filter values

Example

function ListFilter({ filter }) {
  const { apply, clear } = useListFilter({ filter });

  return (
    <FilterDropdownMenu>
      <Button>
        <span>{filter.name}</span>
        {filter.hasActiveItems ? <Check /> : <Carot className="carot" />}
      </Button>
      <Items as="ul">
        {filter.items.map((item) => (
          <DropdownMenuItem
            key={item.id}
            onSelect={() => {
              item.resultCount > 0 && apply({ value: item.value });
            }}
            style={
              item.resultCount === 0
                ? {
                    opacity: 0.4,
                    cursor: "not-allowed",
                  }
                : {}
            }
          >
            <span>{item.text}</span>
            {item.isActive ? <Check /> : <span>{item.resultCount}</span>}
          </DropdownMenuItem>
        ))}
        <>
          {filter.hasActiveItems && (
            <DropdownMenuItem
              onSelect={({ setIsOpen }) => {
                setIsOpen(false);
                clear();
              }}
            >
              Clear filter
            </DropdownMenuItem>
          )}
        </>
      </Items>
    </FilterDropdownMenu>
  );
}