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
Argument | Type | Required? | Description |
---|---|---|---|
options | Options | true | Required options object |
Options
Option | Type | Required? | Description |
---|---|---|---|
filter | ListFilter | true | The ListFilter you would like to act on |
Result
Property | Type | Description |
---|---|---|
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 | () => void | Clears 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>
);
}