Skip to content
Components

Filter menu

A component used to apply category-specific filters for a dataset.

Features

  • Flexible and composable API.
  • Unopinionated about form elements within the filter menu.
  • Display a "count" for the number of applied filters.
  • Provides a companion component for grouping filter toggles.

When to use

See our filtering guidelines to learn why and when you should use this component.

Examples

Complete example

We only provide presentational components for filtering, so you'll need to:

  • Keep track of interim filters.
  • Apply filters (and fetch data) when appropriate.
  • Indicate that filters are applied.
  • Enable "Clear" and "Apply" actions when applicable.
  • Persist applied filters in the URL.
Information:

Please refer to our Filtering guidelines for more details.

Show code
const initialFilters = {a: false, b: false}
const Example = () => {
    const [interimFilters, setInterimFilters] = React.useState(initialFilters)
    const [appliedFilters, setAppliedFilters] = React.useState(initialFilters)


    const onToggleFilter = (name) =>
        setInterimFilters({...interimFilters, [name]: !interimFilters[name]})
    const onClose = () => setAppliedFilters(interimFilters)
    const onClearFilters = () => setInterimFilters(initialFilters)


    const numAppliedFilters = Object.values(appliedFilters).filter((item) => !!item).length


    return (
        <FilterMenu onClose={onClose}>
            <FilterMenu.Trigger>
                <FilterMenu.Toggle
                    numAppliedFilters={numAppliedFilters}
                    hasAppliedFilters={!isEqual(initialFilters, appliedFilters)}
                >
                    Status
                </FilterMenu.Toggle>
            </FilterMenu.Trigger>
            <FilterMenu.Content>
                <Stack p={20} space={10}>
                    <Checkbox checked={interimFilters.a} onChange={() => onToggleFilter('a')}>
                        Ready for payment
                    </Checkbox>
                    <Checkbox checked={interimFilters.b} onChange={() => onToggleFilter('b')}>
                        Awaiting approval
                    </Checkbox>
                </Stack>
                <FilterMenu.Actions>
                    <FilterMenu.Apply disabled={isEqual(interimFilters, appliedFilters)}>
                        Apply
                    </FilterMenu.Apply>
                    <FilterMenu.Clear
                        disabled={isEqual(initialFilters, interimFilters)}
                        onClick={onClearFilters}
                    >
                        Clear
                    </FilterMenu.Clear>
                </FilterMenu.Actions>
            </FilterMenu.Content>
        </FilterMenu>
    )
}


render(<Example />)

Grouped example

Show code
const initialFilters = {a: false, b: false}
const GroupedExample = () => {
    const [interimFilters, setInterimFilters] = React.useState(initialFilters)
    const [appliedFilters, setAppliedFilters] = React.useState(initialFilters)


    const onToggleFilter = (name) =>
        setInterimFilters({...interimFilters, [name]: !interimFilters[name]})
    const onClose = () => setAppliedFilters(interimFilters)
    const onClearFilters = () => setInterimFilters(initialFilters)
    const onSelectAll = () => setInterimFilters({a: true, b: true})


    const numAppliedFilters = Object.values(appliedFilters).filter((item) => !!item).length
    const isAllSelected = Object.values(interimFilters).every((item) => item)


    return (
        <FilterMenu onClose={onClose}>
            <FilterMenu.Trigger>
                <FilterMenu.Toggle
                    numAppliedFilters={numAppliedFilters}
                    hasAppliedFilters={!isEqual(initialFilters, appliedFilters)}
                >
                    Status
                </FilterMenu.Toggle>
            </FilterMenu.Trigger>
            <FilterMenu.Content>
                <Stack p={20} space={10}>
                    <Checkbox checked={interimFilters.a} onChange={() => onToggleFilter('a')}>
                        Ready for payment
                    </Checkbox>
                    <Checkbox checked={interimFilters.b} onChange={() => onToggleFilter('b')}>
                        Awaiting approval
                    </Checkbox>
                </Stack>
                <FilterMenu.Actions>
                    <FilterMenu.Apply disabled={isEqual(interimFilters, appliedFilters)}>
                        Apply
                    </FilterMenu.Apply>
                    <FilterMenu.ActionsGroup>
                        <FilterMenu.Clear
                            disabled={isEqual(initialFilters, interimFilters)}
                            onClick={onClearFilters}
                        >
                            Clear
                        </FilterMenu.Clear>
                        <FilterMenu.Button disabled={isAllSelected} onClick={onSelectAll}>
                            Select all
                        </FilterMenu.Button>
                    </FilterMenu.ActionsGroup>
                </FilterMenu.Actions>
            </FilterMenu.Content>
        </FilterMenu>
    )
}


render(<GroupedExample />)

Specific layout for grouping filters

The Toggle component supports a moreFilters prop that will display a chevron on the right-hand side. Use it when you need to group multiple filtering options within the same filter menu. See our Filtering layout guidelines for more details.

Show code
<FilterMenu>
    <FilterMenu.Trigger>
        <FilterMenu.Toggle moreFilters>More filters</FilterMenu.Toggle>
    </FilterMenu.Trigger>
</FilterMenu>

Toggle loading state

Toggle component supports loading state via loading prop. Use it when applied filters are being fetched. See our Filtering guidelines for more details.

Show code
<FilterMenu>
    <FilterMenu.Trigger>
        <FilterMenu.Toggle loading>Category</FilterMenu.Toggle>
    </FilterMenu.Trigger>
</FilterMenu>

Trigger element skeleton state

Use a "skeleton" version of this component to display a loading state while data is being fetched. It provides a visual placeholder, giving users a preview of the UI structure before the actual content is loaded. This enhances the user experience by offering a more accurate representation of the final layout during data retrieval.

Show code
<FilterMenu>
    <FilterMenu.Trigger>
        <FilterMenu.Toggle skeleton>Category</FilterMenu.Toggle>
    </FilterMenu.Trigger>
</FilterMenu>
  • Filter results: Used to reflect the amount of results given a set of applied filters. It's also used to allow users to clear all filters.
  • Listbox: A listbox provides a way to select or reorder options in a predefined list and a selected option can then be made to perform a single action.
  • Popover: A small overlay that opens on demand. Popovers allow users to access additional content and actions without cluttering the page.
Didn't find what you were looking for?
Edit this page