Filters

Intuitive data filtering components.

Import#

  • FiltersProvider: Context provider that manages active filters.
  • FiltersAddButton: Menu with available filters.
  • ActiveFilter: Active filter component.
  • ActiveFiltersList: A list of active filters.
  • NoFilteredResults: EmptyState used incombination with DataGrid.
  • useDataGridFilter: Hook to enable DataGrid filtering.
import {
FilterMenu,
ActiveFilter,
ActiveFilters,
FiltersProvider,
} from '@saas-ui/pro'

Usage#

The FiltersProvider can be used together with DataGrid to create intuitive data heavy list pages.

Basic#

function ListPage() {
const filters = React.useMemo(
() => [
{
id: 'status',
label: 'Status',
icon: <FiCircle />,
type: 'enum',
items: [
{
id: 'new',
label: 'New',
icon: <StatusBadge bg="blue.400" />,
},
{
id: 'active',
label: 'Active',
icon: <StatusBadge bg="green.400" />,
},
],
},
],
[]
)
return (
<FiltersProvider filters={filters}>
<Page
title="Contacts"
toolbar={
<Toolbar variant="outline">
<FiltersAddButton />
<Spacer />
</Toolbar>
}
>
<ActiveFiltersList />
<PageBody fullWidth></PageBody>
</Page>
</FiltersProvider>
)
}

Usage with DataGrid#

function ListPage() {
const gridRef = useRef()
const filters = React.useMemo(
() => [
{
id: 'status',
label: 'Status',
icon: <FiCircle />,
type: 'enum',
items: [
{
id: 'new',
label: 'New',
icon: <StatusBadge bg="blue.400" />,
},
{
id: 'active',
label: 'Active',
icon: <StatusBadge bg="green.400" />,
},
],
},
{
id: 'isLead',
label: 'Is lead',
type: 'boolean',
icon: <FiUser />,
value: true,
},
],
[]
)
const columns = React.useMemo(() => {
return [
{
accessorKey: 'name',
header: 'Name',
size: 200,
meta: {
href: ({ id }) => `#customers/${id}`,
},
filterFn: useDataGridFilter('string'),
},
{
accessorKey: 'email',
header: 'Email',
filterFn: useDataGridFilter('string'),
},
{
accessorKey: 'company',
header: 'Company',
filterFn: useDataGridFilter('string'),
},
{
accessorKey: 'status',
header: 'Status',
cell: (cell) => {
const value = cell.getValue()
return (
<Tag colorScheme={value === 'new' ? 'orange' : 'green'} size="sm">
{value}
</Tag>
)
},
filterFn: useDataGridFilter('string'),
},
{
accessorKey: 'isLead',
header: 'Lead',
hidden: true,
filterFn: useDataGridFilter('boolean'),
},
{
accessorKey: 'employees',
header: 'Employees',
meta: {
isNumeric: true,
},
},
{
id: 'action',
disableSortBy: true,
disableGlobaFilter: true,
header: '',
cell: () => (
<>
<Button size="xs">Edit</Button>
</>
),
size: 100,
},
]
}, [])
const onFilter = React.useCallback((filters) => {
gridRef.current.setColumnFilters(
filters.map((filter) => {
return {
id: filter.id,
value: {
value: filter.value,
operator: filter.operator || 'is',
},
}
})
)
}, [])
const data = React.useMemo(
() =>
dataTable.data.map((item) => {
return {
...item,
status: 'new',
isLead: true,
}
}),
[]
)
return (
<FiltersProvider filters={filters} onChange={onFilter}>
<Page
title="Contacts"
height="400px"
toolbar={
<Toolbar variant="outline">
<FiltersAddButton />
<Spacer />
</Toolbar>
}
>
<ActiveFiltersList />
<PageBody fullWidth>
<DataGrid
instanceRef={gridRef}
columns={columns}
data={data}
noResults={NoFilteredResults}
initialState={{
columnVisibility: {
isLead: false,
},
}}
/>
</PageBody>
</Page>
</FiltersProvider>
)
}

DataGrid with default filters#

function ListPage() {
const gridRef = useRef()
const filters = React.useMemo(
() => [
{
id: 'status',
label: 'Status',
icon: <FiCircle />,
type: 'enum',
items: [
{
id: 'new',
label: 'New',
icon: <StatusBadge bg="blue.400" />,
},
{
id: 'active',
label: 'Active',
icon: <StatusBadge bg="green.400" />,
},
],
},
{
id: 'isLead',
label: 'Is lead',
type: 'boolean',
icon: <FiUser />,
value: true,
},
],
[]
)
const columns = React.useMemo(() => {
return [
{
accessorKey: 'name',
header: 'Name',
size: 200,
meta: {
href: ({ id }) => `#customers/${id}`,
},
filterFn: useDataGridFilter('string'),
},
{
accessorKey: 'email',
header: 'Email',
filterFn: useDataGridFilter('string'),
},
{
accessorKey: 'company',
header: 'Company',
filterFn: useDataGridFilter('string'),
},
{
accessorKey: 'status',
header: 'Status',
cell: (cell) => {
const value = cell.getValue()
return (
<Tag colorScheme={value === 'new' ? 'orange' : 'green'} size="sm">
{value}
</Tag>
)
},
filterFn: useDataGridFilter('string'),
},
{
accessorKey: 'isLead',
header: 'Lead',
hidden: true,
filterFn: useDataGridFilter('boolean'),
},
{
accessorKey: 'employees',
header: 'Employees',
meta: {
isNumeric: true,
},
},
{
id: 'action',
disableSortBy: true,
disableGlobaFilter: true,
header: '',
cell: () => (
<>
<Button size="xs">Edit</Button>
</>
),
size: 100,
},
]
}, [])
const onFilter = React.useCallback((filters) => {
gridRef.current.setColumnFilters(
filters.map((filter) => {
return {
id: filter.id,
value: {
value: filter.value,
operator: filter.operator || 'is',
},
}
})
)
}, [])
const data = React.useMemo(
() =>
dataTable.data.map((item) => {
return {
...item,
status: 'new',
isLead: true,
}
}),
[]
)
const defaultFilters = [{ id: 'status', operator: 'isNot', value: 'new' }]
return (
<FiltersProvider
filters={filters}
onChange={onFilter}
defaultFilters={defaultFilters}
>
<Page
title="Contacts"
height="400px"
toolbar={
<Toolbar variant="outline">
<FiltersAddButton />
<Spacer />
</Toolbar>
}
>
<ActiveFiltersList />
<PageBody fullWidth>
<DataGrid
instanceRef={gridRef}
columns={columns}
data={data}
noResults={NoFilteredResults}
initialState={{
columnVisibility: {
isLead: false,
},
filters: defaultFilters.map(({ id, value, operator }) => ({
id,
value: {
value,
operator,
},
})),
}}
/>
</PageBody>
</Page>
</FiltersProvider>
)
}

Props#

FiltersProvider Props#

defaultFilters

Type
Filter[]

filters

Type
FilterItem[]

onBeforeEnableFilter

Type
((filter: Filter, filterItem?: FilterItem) => Promise<Filter>)

onChange

Type
((activeFilters: Filter[]) => void)

operators

Type
FilterOperators

FiltersAddButton Props#

buttonProps

Type
ButtonProps

command

Type
string

icon

Type
ReactNode

label

Type
ReactNode

onSelect

Type
((item: FilterItem) => void)

placeholder

Type
string

ActiveFilter Props#

idrequired

Type
string

defaultOperator

Type
string

defaultValue

Type
FilterValue

formatLabel

Type
((label?: string) => string)

formatValue

Type
((value: FilterValue) => string)

icon

Type
ReactNode

items

Type
FilterItem[]

label

Type
string

onChange

Type
((filter: Filter) => void)

onOperatorChange

Type
((id: string) => void)

onRemove

Type
(() => void)

onValueChange

Type
((value: FilterValue) => void)

operator

Type
string

operators

Type
FilterItem[]

value

Type
FilterValue

ActiveFiltersList Props#

formatValue

Type
((value: FilterValue) => string)

NoFilteredResults Props#

clearLabel

Type
string

onReset

Type
(() => void)

resource

Type
string

spacing

Type
ResponsiveValue<Union<number | "px" | (string & {}) | "inherit" | "-moz-initial" | "initial" | "revert" | "revert-layer" | "unset" | "auto" | "1" | "-1" | "2" | "-2" | "3" | "-3" | "4" | "-4" | "5" | ... 55 more ... | "-3.5">>

title

Type
string

Was this helpful?