Skip to main content

FilterList

A comprehensive guide for using the FilterList component from @osdk/react-components.

Prerequisites

Before using FilterList, make sure you have completed the library setup described in the README, including:

  • Installing the required dependencies
  • Wrapping your app with OsdkProvider
  • Adding the CSS imports

Table of Contents

Import

import { FilterList } from "@osdk/react-components/experimental/filter-list";

Basic Usage

About @my/osdk and ./client

@my/osdk is a placeholder for your generated SDK package (e.g. @your-app/sdk). ./client is the file in your app where you exported the OSDK client returned by createClient(...). Replace both with the actual paths in your project.

The simplest way to use FilterList is with an objectSet and a few filter definitions:

import { Employee } from "@my/osdk";
import { FilterList } from "@osdk/react-components/experimental/filter-list";
import client from "./client";

function EmployeeFilters() {
return (
<FilterList
objectSet={client(Employee)}
filterDefinitions={[
{
type: "PROPERTY",
key: "department",
filterComponent: "LISTOGRAM",
},
{
type: "PROPERTY",
key: "jobTitle",
filterComponent: "LISTOGRAM",
},
]}
/>
);
}

Props Reference

Type parameters: Q extends ObjectTypeDefinition

NameTypeDescription
objectTypeQRequired. The object type definition for the objects being filtered. Used for metadata resolution (property types, display names).
objectSetObjectSet<Q>Optional object set to scope aggregation queries. When omitted, aggregations run against the full object type.
filterClauseWhereClause<Q>The current where clause to filter the objectSet. If provided, the filter clause is controlled. LINKED_PROPERTY filters are not included; use onEffectiveObjectSet.
onFilterClauseChanged(newClause: WhereClause<Q>) => voidCalled when the filter clause changes. Required in controlled mode.
titleReactNodeOptional title to display in the filter list header
titleIconReact.ReactNodeOptional icon to display next to the title
filterDefinitionsArray<FilterDefinitionUnion<Q>>The definition for all supported filter items in the list If not supplied, all filterable properties will be available
onFilterStateChanged(definition: FilterDefinitionUnion<Q>, newState: FilterStateType) => voidCalled when filter state changes
onEffectiveObjectSet(objectSet: ObjectSet<Q>) => voidCalled with the narrowed ObjectSet whenever filters change. Requires objectSet to be set.

A linked filter only narrows the set when its definition has reverseLinkName. Linked filters without it are skipped here; read their state from onFilterStateChanged instead.
showFilteredOutValuesbooleanWhen true, facets render greyed-out count=0 rows for values present in the unfiltered data but excluded by other active filters. Defaults to false.
addFilterMode"controlled" | "uncontrolled"Controls how filter visibility (add/remove) is managed.

- "uncontrolled" (default): FilterList manages visibility internally. An "Add filter" popover is rendered for filters with isVisible: false, and each visible filter shows a remove button. - "controlled": The consumer manages which filters are visible via filterDefinitions. Filters with isVisible: false are excluded from the rendered list. Defaults to "uncontrolled".
onFilterAdded(filterKey: FilterKey<Q>, newDefinitions: Array<FilterDefinitionUnion<Q>>) => voidCalled when a filter is added (shown).

In uncontrolled mode, this fires when a user selects a hidden filter from the "Add filter" popover.
onFilterRemoved(filterKey: FilterKey<Q>) => voidCalled when a filter is removed (hidden).

In uncontrolled mode, this fires as a notification after the filter is hidden internally.
onFilterVisibilityChange(newStates: Array<{ filterKey: FilterKey<Q>; isVisible: boolean; }>) => voidCalled when filter visibility or ordering changes, i.e. when filters are reordered, or (in uncontrolled mode) added or removed via the built-in show/remove controls.
enableSortingbooleanEnable drag-and-drop reordering of filters. When true, drag handles are rendered and filters can be reordered. Reorder state is managed internally; consumers who need to track order should use controlled filterDefinitions.
collapsedbooleanWhether the filter list panel is collapsed
onCollapsedChange(collapsed: boolean) => voidCalled when the collapsed state changes
initialFilterStatesMap<string, FilterStateType>Initial filter states for hydrating from external storage. These states are merged over definition defaults on mount. Use onFilterStateChanged to persist state changes externally.
showResetButtonbooleanShow reset filters button in header
onReset() => voidCalled when reset button is clicked
showActiveFilterCountbooleanShow count of active filters in header
classNamestringAdditional CSS class name
renderAddFilterButton() => React.ReactNodeCustom render function for the "Add filter" button.

- In uncontrolled mode: customizes the trigger element for the built-in add-filter popover. The popover behavior is handled automatically. - In controlled mode: replaces the entire add-filter button area. The consumer is responsible for all add-filter behavior.

Filter Definitions

Filter Definition Types

TypeDescription
PROPERTYFilter on a direct property of the object type
KEYWORD_SEARCHFull-text keyword search across objects
CUSTOMCustom filter with user-provided render function
HAS_LINKToggle filter for whether a link exists
LINKED_PROPERTYFilter on a property of a linked object type
STATIC_VALUESFilter on a fixed list of values (no OSDK fetching)

Each filter definition type's fields are documented below.

Property Filter Definition

When using type: "PROPERTY", the definition supports:

Type parameters: Q extends ObjectTypeDefinition, K extends PropertyKeys<Q> = PropertyKeys<Q>, C extends ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>> = ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>>

NameTypeDescription
searchFieldbooleanWhen false, the header monocle (search-values icon) is hidden even for filter components that ordinarily support in-filter search. Useful for MULTI_SELECT, which already has its own inline search field. Defaults to true.
type"PROPERTY"Required. Discriminator for filter definition type
idstringOptional unique identifier for stable keying across filter reorders.
keyKRequired. The property key to filter on
labelstringDisplay label for the filter
filterComponentCRequired. The filter component type to render Must be compatible with the property type derived from the key, see ValidComponentsForPropertyType
filterStateFilterStateByComponentType[C]Required. The current state of the filter. If provided, the filter is controlled.
colorMapRecord<string, string>Maps filter values to colors for visual differentiation. Used by LISTOGRAM (per-row bar colors).
listogramConfig{ displayMode?: "full" | "count" | "minimal"; maxVisibleItems?: number; }Configuration for LISTOGRAM display mode. Only applies when filterComponent is "LISTOGRAM".
renderValue(value: string) => ReactNodeCustom display function for filter values. Replaces the default string display in dropdown items, chips, and listogram rows. When the function returns a string, that string is also used for search matching within filter dropdowns. When it returns a non-string ReactNode, search falls back to the raw value.
showCountbooleanShow aggregation counts next to filter option values. Applies to LISTOGRAM, SINGLE_SELECT, and MULTI_SELECT components. Defaults to true for LISTOGRAM and MULTI_SELECT, false for SINGLE_SELECT.
clickToFilterbooleanWhen true, clicking a bar in the histogram replaces the filter range with that bucket's [min, max]. Only applies to histogram-rendering filter components (NUMBER_RANGE and DATE_RANGE); ignored on other component types.

Click replaces the current range — clicking a second bar discards the previous selection. Multi-bucket selection / shift+click union is NOT supported in v1. Defaults to false.
isVisiblebooleanControls whether this filter is rendered. When false, the filter is hidden but its state is preserved. Defaults to true.

Listogram Configuration

FieldTypeDefaultDescription
displayMode"full" | "count" | "minimal""full"full: bar + count, count: count only, minimal: label only
maxVisibleItemsnumber5Number of items shown before "View all" link appears

Keyword Search Filter Definition

When using type: "KEYWORD_SEARCH", the definition supports:

Type parameters: Q extends ObjectTypeDefinition, K extends StringPropertyKeys<Q> = StringPropertyKeys<Q>

NameTypeDescription
searchFieldbooleanWhen false, the header monocle (search-values icon) is hidden even for filter components that ordinarily support in-filter search. Useful for MULTI_SELECT, which already has its own inline search field. Defaults to true.
type"KEYWORD_SEARCH"Required.
idstringOptional unique identifier for stable keying across filter reorders.
properties"all" | K[]Required. Properties to search within - "all": Search all string properties - K[]: Search specific string properties
labelstring
filterStateKeywordSearchFilterStateControlled state for the filter. When provided, the filter becomes controlled and changes should be handled via onFilterStateChanged callback.
defaultFilterStateKeywordSearchFilterStateDefault state for uncontrolled mode. Used when filterState is not provided.
isVisiblebooleanControls whether this filter is rendered. When false, the filter is hidden but its state is preserved. Defaults to true.

When using type: "HAS_LINK", the definition supports:

Type parameters: Q extends ObjectTypeDefinition, L extends LinkNames<Q> = LinkNames<Q>

NameTypeDescription
searchFieldbooleanWhen false, the header monocle (search-values icon) is hidden even for filter components that ordinarily support in-filter search. Useful for MULTI_SELECT, which already has its own inline search field. Defaults to true.
type"HAS_LINK"Required.
idstringOptional unique identifier for stable keying across filter reorders.
linkNameLRequired.
labelstring
filterStateHasLinkFilterStateRequired.
defaultFilterStateHasLinkFilterState
isVisiblebooleanControls whether this filter is rendered. When false, the filter is hidden but its state is preserved. Defaults to true.

Linked Property Filter Definition

When using type: "LINKED_PROPERTY", the definition supports:

Type parameters: Q extends ObjectTypeDefinition, L extends LinkNames<Q>, LinkedQ extends ObjectTypeDefinition = LinkedType<Q, L>, LinkedK extends PropertyKeys<LinkedQ> = PropertyKeys<LinkedQ>, LinkedC extends ValidComponentsForPropertyType<PropertyTypeFromKey<LinkedQ, LinkedK>> = ValidComponentsForPropertyType<PropertyTypeFromKey<LinkedQ, LinkedK>>

NameTypeDescription
searchFieldbooleanWhen false, the header monocle (search-values icon) is hidden even for filter components that ordinarily support in-filter search. Useful for MULTI_SELECT, which already has its own inline search field. Defaults to true.
type"LINKED_PROPERTY"Required.
idstringOptional unique identifier for stable keying across filter reorders.
linkNameLRequired.
reverseLinkNameLinkNames<LinkedQ>Set this to make the filter narrow objectSet; the result is emitted via onEffectiveObjectSet. The value names the link on the linked object type that points back to Q (the inverse of linkName).

Leave unset to keep the filter UI-only. It still renders and fires onFilterStateChanged, but FilterList won't narrow on it.
linkedPropertyKeyLinkedKRequired.
linkedFilterComponentLinkedCRequired.
linkedFilterStateFilterStateByComponentType[LinkedC]Required.
defaultLinkedFilterStateFilterStateByComponentType[LinkedC]
filterStateLinkedPropertyFilterState<FilterStateByComponentType[LinkedC]>Required.
labelstring
showCountbooleanShow aggregation counts next to filter option values. Applies to LISTOGRAM, SINGLE_SELECT, and MULTI_SELECT linked components. Defaults to true for LISTOGRAM and MULTI_SELECT, false for SINGLE_SELECT.
renderValue(value: string) => ReactNodeCustom display function for filter values. Replaces the default string display in dropdown items, chips, and listogram rows. When the function returns a string, that string is also used for search matching within filter dropdowns. When it returns a non-string ReactNode, search falls back to the raw value.
isVisiblebooleanControls whether this filter is rendered. When false, the filter is hidden but its state is preserved. Defaults to true.

Two modes for LINKED_PROPERTY

Auto-narrowing — set reverseLinkName. FilterList composes pivotTo(linkName).where(...).pivotTo(reverseLinkName) and emits the narrowed set via onEffectiveObjectSet:

{
type: "LINKED_PROPERTY",
linkName: "manager", // Employee → Manager
reverseLinkName: "directReports", // Manager → Employee (back-link)
linkedPropertyKey: "fullName",
linkedFilterComponent: "MULTI_SELECT",
linkedFilterState: { type: "SELECT", selectedValues: [] },
filterState: { type: "linkedProperty", linkedFilterState: { type: "SELECT", selectedValues: [] } },
}

UI-only — omit reverseLinkName. The filter still renders and fires onFilterStateChanged; downstream narrowing is up to the consumer:

{
type: "LINKED_PROPERTY",
linkName: "manager",
// no reverseLinkName — FilterList won't narrow objectSet on this filter
linkedPropertyKey: "fullName",
linkedFilterComponent: "MULTI_SELECT",
linkedFilterState: { type: "SELECT", selectedValues: [] },
filterState: { type: "linkedProperty", linkedFilterState: { type: "SELECT", selectedValues: [] } },
}

Custom Filter Definition

When using type: "CUSTOM", the definition supports:

Type parameters: Q extends ObjectTypeDefinition, State extends BaseFilterState = CustomFilterState

NameTypeDescription
searchFieldbooleanWhen false, the header monocle (search-values icon) is hidden even for filter components that ordinarily support in-filter search. Useful for MULTI_SELECT, which already has its own inline search field. Defaults to true.
type"CUSTOM"Required.
idstringOptional unique identifier for stable keying across filter reorders. If provided, takes precedence over key for state keying.
keystringRequired. Unique key for this custom filter
labelstring
filterComponent"CUSTOM"Required.
filterStateStateRequired.
defaultFilterStateState
renderInput(props: CustomFilterInputRendererProps<Q, State>) => ReactNodeRender the input portion of the filter Used when rendering within a filter item wrapper
renderItem(props: CustomFilterItemRendererProps<Q, State>) => ReactNodeRender the complete filter item Used when you need full control over the item appearance
toWhereClause(state: State) => WhereClause<Q> | undefinedRequired. Convert filter state to a WhereClause for filtering Required for the filter to affect the object set
isVisiblebooleanControls whether this filter is rendered. When false, the filter is hidden but its state is preserved. Defaults to true.

Static Values Filter Definition

When using type: "STATIC_VALUES", the definition supports:

Type parameters: Q extends ObjectTypeDefinition, C extends StaticValuesComponentType = StaticValuesComponentType

NameTypeDescription
searchFieldbooleanWhen false, the header monocle (search-values icon) is hidden even for filter components that ordinarily support in-filter search. Useful for MULTI_SELECT, which already has its own inline search field. Defaults to true.
type"STATIC_VALUES"Required.
idstringOptional unique identifier for stable keying across filter reorders. If provided, takes precedence over key for state keying.
keystringRequired. Key used for state management and auto WHERE clause generation. When toWhereClause is not provided, this is used as the property key in the generated WHERE clause.
labelstringDisplay label for the filter
filterComponentCRequired. The filter component type to render
filterStateFilterStateByComponentType[C]Required. The current state of the filter
valuesstring[]Required. The static list of values to display in the filter component. These are rendered directly without OSDK aggregation.
renderValue(value: string) => ReactNodeCustom display function for filter values. Replaces the default string display in dropdown items, chips, and listogram rows. When the function returns a string, that string is also used for search matching within filter dropdowns. When it returns a non-string ReactNode, search falls back to the raw value.
showCountbooleanShow aggregation counts next to filter option values. Applies to LISTOGRAM, SINGLE_SELECT, and MULTI_SELECT components. Defaults to true for LISTOGRAM and MULTI_SELECT, false for SINGLE_SELECT.
colorMapRecord<string, string>Maps filter values to colors for visual differentiation. Used by LISTOGRAM (per-row bar colors).
listogramConfig{ displayMode?: "full" | "count" | "minimal"; maxVisibleItems?: number; }Configuration for LISTOGRAM display mode. Only applies when filterComponent is "LISTOGRAM".
toWhereClause(state: FilterState) => WhereClause<Q> | undefinedOptional custom WHERE clause generator. When provided, this is used instead of auto-generating a WHERE clause from the key and filter state.
isVisiblebooleanControls whether this filter is rendered. When false, the filter is hidden but its state is preserved. Defaults to true.

Filter Components

When using type: "PROPERTY" or type: "LINKED_PROPERTY", specify a filterComponent:

ComponentBest ForState Type
LISTOGRAMCategorical data with bar chartEXACT_MATCH
SINGLE_SELECTSingle value dropdownSELECT
MULTI_SELECTMulti-select dropdown with searchSELECT
TEXT_TAGSTag-based input with suggestionsEXACT_MATCH
CONTAINS_TEXTFree-text search on a propertyCONTAINS_TEXT
NUMBER_RANGEMin/max range slider for numbersNUMBER_RANGE
DATE_RANGEDate range pickerDATE_RANGE
TOGGLEBoolean on/off toggleTOGGLE
SINGLE_DATESingle date pickerSELECT
MULTI_DATEMultiple date pickerSELECT
TIMELINEDate range with start/endTIMELINE

Examples

Combining with ObjectTable

Use controlled filterClause to connect FilterList and ObjectTable:

import { Employee } from "@my/osdk";
import type { WhereClause } from "@osdk/api";
import { FilterList } from "@osdk/react-components/experimental/filter-list";
import { ObjectTable } from "@osdk/react-components/experimental/object-table";
import { useMemo, useState } from "react";
import client from "./client";

function EmployeeDashboard() {
const [filterClause, setFilterClause] = useState<
WhereClause<typeof Employee>
>({});
const objectSet = useMemo(() => client(Employee), []);

return (
<div style={{ display: "flex", gap: 16, height: 600 }}>
<div style={{ width: 320, flexShrink: 0 }}>
<FilterList
objectSet={objectSet}
filterDefinitions={[
{
type: "PROPERTY",
key: "department",
filterComponent: "LISTOGRAM",
},
{ type: "PROPERTY", key: "team", filterComponent: "LISTOGRAM" },
{
type: "PROPERTY",
key: "fullName",
filterComponent: "CONTAINS_TEXT",
},
]}
title="Employee Filters"
showResetButton={true}
showActiveFilterCount={true}
enableSorting={true}
filterClause={filterClause}
onFilterClauseChanged={setFilterClause}
/>
</div>
<div style={{ flex: 1 }}>
<ObjectTable objectType={Employee} filter={filterClause} />
</div>
</div>
);
}

Add/Remove Filters (Uncontrolled Mode)

Use addFilterMode="uncontrolled" with isVisible: false on some filters to let users add and remove filters dynamically:

const filterDefinitions = [
{
type: "PROPERTY",
key: "department",
label: "Department",
filterComponent: "LISTOGRAM",
filterState: { type: "EXACT_MATCH", values: [] },
},
{
type: "PROPERTY",
key: "team",
label: "Team",
filterComponent: "LISTOGRAM",
filterState: { type: "EXACT_MATCH", values: [] },
},
{
type: "PROPERTY",
key: "fullName",
label: "Full Name",
filterComponent: "CONTAINS_TEXT",
filterState: { type: "CONTAINS_TEXT" },
isVisible: false,
},
{
type: "PROPERTY",
key: "startDate",
label: "Start Date",
filterComponent: "DATE_RANGE",
filterState: { type: "DATE_RANGE" },
isVisible: false,
},
];

<FilterList
objectSet={client(Employee)}
filterDefinitions={filterDefinitions}
addFilterMode="uncontrolled"
showResetButton={true}
/>;

Filters marked isVisible: false appear in the "Add filter" popover. Users can add them to the list and remove visible filters via the close button. Reset restores the original visibility.

Removable Filters (Controlled Mode)

When addFilterMode="controlled" and onFilterRemoved is provided, each filter shows a remove button on hover. The consumer manages the definitions array:

const [definitions, setDefinitions] = useState(filterDefinitions);

const handleFilterRemoved = (filterKey) => {
setDefinitions(prev => prev.filter(def => def.key !== filterKey));
};

<FilterList
objectSet={client(Employee)}
filterDefinitions={definitions}
addFilterMode="controlled"
onFilterRemoved={handleFilterRemoved}
title="Removable Filters"
/>;

Prefiltered ObjectSet

Pass a .where() objectSet to scope filter dropdown values. For example, to only show Engineering employees:

import { Employee } from "@my/osdk";
import { FilterList } from "@osdk/react-components/experimental/filter-list";
import { useMemo } from "react";
import client from "./client";

function EngineeringFilters() {
const engineeringSet = useMemo(
() => client(Employee).where({ department: "Engineering" }),
[],
);

return (
<FilterList
objectSet={engineeringSet}
filterDefinitions={[
{ type: "PROPERTY", key: "jobTitle", filterComponent: "LISTOGRAM" },
{ type: "PROPERTY", key: "location", filterComponent: "LISTOGRAM" },
]}
/>
);
}

The filter dropdowns will only show job titles and locations that exist within the Engineering department.

Keyword Search Filter

Add a full-text search filter that searches across multiple properties:

const filterDefinitions = [
{
type: "KEYWORD_SEARCH",
properties: ["fullName", "department", "jobTitle", "locationCity"],
label: "Search",
},
{ type: "PROPERTY", key: "department", filterComponent: "LISTOGRAM" },
{ type: "PROPERTY", key: "locationCity", filterComponent: "LISTOGRAM" },
];

<FilterList
objectSet={client(Employee)}
filterDefinitions={filterDefinitions}
/>;

Custom Listogram Colors

Assign colors to specific values in a listogram:

<FilterList
objectSet={client(Employee)}
filterDefinitions={[
{
type: "PROPERTY",
key: "department",
filterComponent: "LISTOGRAM",
colorMap: {
Engineering: "#3b82f6",
Marketing: "#f59e0b",
Sales: "#10b981",
Design: "#8b5cf6",
},
},
]}
/>;

Custom Value Rendering

Use renderValue to customize how filter values are displayed and searched. The returned string replaces the raw value for both display and search matching. This is useful for showing human-readable names instead of IDs:

const USER_NAMES: Record<string, string> = {
"abc-123": "Alice Smith",
"def-456": "Bob Jones",
};

<FilterList
objectSet={client(Task)}
filterDefinitions={[
{
type: "PROPERTY",
key: "assigneeUserId",
filterComponent: "LISTOGRAM",
renderValue: (userId) => USER_NAMES[userId] ?? userId,
},
]}
/>;

renderValue works with LISTOGRAM, SINGLE_SELECT, and MULTI_SELECT filter components. For MULTI_SELECT, it applies to both dropdown items and selected chips. Searching within a filter dropdown matches against the renderValue output.

For best performance, memoize renderValue with useCallback to avoid unnecessary re-renders:

Listogram Display Modes

Control how much detail each listogram row shows:

// "full" (default): checkbox + label + colored bar + count number
// "count": checkbox + label + count number (no bar)
// "minimal": checkbox + label only

<FilterList
objectSet={client(Employee)}
filterDefinitions={[
{
type: "PROPERTY",
key: "department",
filterComponent: "LISTOGRAM",
listogramConfig: { displayMode: "count" },
},
]}
/>;

Limiting Visible Items

By default, LISTOGRAM filters show at most 5 items with a "View all" link. Override with maxVisibleItems:

<FilterList
objectSet={client(Employee)}
filterDefinitions={[
{
type: "PROPERTY",
key: "department",
filterComponent: "LISTOGRAM",
listogramConfig: { maxVisibleItems: 10 },
},
]}
/>;

Collapsible Panel

Make the filter list collapsible:

import { useState } from "react";

function CollapsibleFilters() {
const [collapsed, setCollapsed] = useState(false);

return (
<FilterList
objectSet={client(Employee)}
title="Filters"
collapsed={collapsed}
onCollapsedChange={setCollapsed}
showActiveFilterCount={true}
filterDefinitions={[
{ type: "PROPERTY", key: "department", filterComponent: "LISTOGRAM" },
]}
/>
);
}

Drag-and-Drop Sorting

Enable reordering of filters via drag and drop:

<FilterList
objectSet={client(Employee)}
filterDefinitions={filterDefinitions}
enableSorting={true}
/>;

Exclude Toggle

LISTOGRAM and TEXT_TAGS filters support an exclude/include toggle. Hover a filter item and click the three-dot menu to toggle between "Keeping" and "Excluding" modes. When excluding, selected values are excluded from results and appear with a strikethrough.

// Exclude mode is built into LISTOGRAM filters automatically.
// Users access it via the overflow menu (three dots) on each filter item.
<FilterList
objectSet={client(Employee)}
filterDefinitions={[
{
type: "PROPERTY",
key: "department",
filterComponent: "LISTOGRAM",
filterState: { type: "EXACT_MATCH", values: [] },
},
]}
/>;

Styling

FilterList uses CSS custom properties included in @osdk/react-components/styles.css for theming. Override --osdk-* tokens to customize FilterList without affecting other components, or override --bp-* tokens for global theming.

@layer osdk.styles, user.theme;

@import "@osdk/react-components/styles.css" layer(osdk.styles);

@layer user.theme {
:root {
--osdk-intent-primary-rest: #2563eb;
--osdk-intent-primary-hover: #1d4ed8;
}
}

Use the className prop for scoped styling:

<FilterList
objectSet={client(Employee)}
className="my-custom-filters"
filterDefinitions={[...]}
/>

For a full reference of CSS tokens, see the CSS Variables documentation.

Best Practices

  • Memoize filterDefinitions -- define the array outside the component or wrap in useMemo to avoid unnecessary re-renders
  • Use controlled mode for persistence -- provide filterClause and onFilterClauseChanged to persist filter state across navigation
  • Use objectSet constraints to scope filter values -- pass a prefiltered objectSet (e.g. client(Employee).where(...)) so filter dropdowns only show relevant values
  • Keep filter lists focused -- show 3-8 filters; too many filters overwhelm users
  • Use addFilterMode="uncontrolled" for progressive disclosure -- start with a few visible filters and let users add more as needed