A composable and responsive layout component for filters
Basic usage
First, import the components.
import {FiltersLayout, SortSelect} from '@pleo-io/telescope'FiltersLayout places a search field, a group of filters, a sort select and the filter results in a
consistent, responsive layout. Use it with Search,
Filter menu or FilterButton, and
Filter results.
const Example = () => {
const [search, setSearch] = React.useState('')
const [sorting, setSorting] = React.useState('newest')
const [hasAppliedFilters, setHasAppliedFilters] = React.useState(false)
return (
<FiltersLayout>
<FiltersLayout.SearchWrapper>
<Search label="Search expenses" value={search} onValueChange={setSearch} />
</FiltersLayout.SearchWrapper>
<FiltersLayout.FiltersWrapper>
<FiltersLayout.FiltersGroup>
<FilterButton
hasAppliedFilters={hasAppliedFilters}
onClick={() => setHasAppliedFilters((applied) => !applied)}
>
Category
</FilterButton>
<FilterButton>Status</FilterButton>
</FiltersLayout.FiltersGroup>
<SortSelect
options={[
{label: 'Newest first', value: 'newest'},
{label: 'Oldest first', value: 'oldest'},
]}
value={sorting}
onChange={setSorting}
/>
</FiltersLayout.FiltersWrapper>
<FiltersLayout.FiltersResultsWrapper isVisible={hasAppliedFilters}>
<FilterResults>
<FilterResults.Text>1 filter applied</FilterResults.Text>
<FilterResults.Clear onClick={() => setHasAppliedFilters(false)}>
Clear filters
</FilterResults.Clear>
</FilterResults>
</FiltersLayout.FiltersResultsWrapper>
</FiltersLayout>
)
}
render(<Example />)Layout
FiltersLayout.SearchWrappersizes the search field. It takes at least 320px and grows to fill the row. Pass$stackedto give it a full row of its own, or$withoutFiltersto keep it at 320px when there are no filters next to it.FiltersLayout.FiltersWrapperholds the filters. When it has a second child, such as aSortSelect, that child is pushed to the end of the row.FiltersLayout.FiltersGroupwraps a group of filters onto several lines on small screens.FiltersLayout.FiltersResultsWrapperanimates the filter results in and out whenisVisiblechanges, and respects the user's reduced motion setting.
Sorting
SortSelect is a non-searchable Select with a sort
icon. It is controlled: pass the options, the selected value and an onChange handler, which
receives the value of the selected option.
const Example = () => {
const [sorting, setSorting] = React.useState('newest')
return (
<SortSelect
options={[
{label: 'Newest first', value: 'newest'},
{label: 'Oldest first', value: 'oldest'},
]}
value={sorting}
onChange={setSorting}
/>
)
}
render(<Example />)Localisation
SortSelect is named "Sort by:" for assistive technology. The label comes from the
TelescopeProvider translations under FiltersLayout.SortByLabel.
Accessibility
- The parts render in reading order, so keyboard users move from the search field through the filters to the sort select.
SortSelecthas an accessible name from the localisedFiltersLayout.SortByLabeltranslation.FiltersLayout.FiltersResultsWrapperskips its animation when the user prefers reduced motion.
API reference
FiltersLayout
| Prop | Type | Default |
|---|---|---|
testIdNo description available | enumstring | undefined |
FiltersResultsWrapper
| Prop | Type | Default |
|---|---|---|
isVisible (required)No description available | boolean |
SortSelect
| Prop | Type | Default |
|---|---|---|
disabledNo description available | boolean | |
onChange (required)No description available | function(value: string) => void | |
onOpenNo description available | enum() => void | |
options (required)No description available | Record<"label" | "value", string>[]Record<"label" | "value", string>[] | |
testIdNo description available | enumstring | undefined | |
value (required)No description available | string |
Didn't find what you were looking for?
Let us know in #team-design-systems or make a request.
Edit this page