Filters API
Filter types, operator factories and filter components.
@workspace/active-grid 11.0.0Status unknowncontent differs from the recorded release 11.0.0baseline ce081dc3
The text below is the package's own API reference, included unchanged. The complete list of exports, generated from the source, is on All exports.
Filter discriminated union, operator arrays + factories,
evaluate, advanced, Date, and the built-in
filter components. For tutorial-style how-to see
../.
FilterValue Types#
import {type FilterValue, type FilterOperator} from '@workspace/active-grid';Filter is a discriminated union based on the operator:
type FilterValue = NoValueFilter | SingleValueFilter | RangeFilter;
type NoValueFilter = { operator: 'isEmpty' | 'isNotEmpty';};
type SingleValueFilter = { operator: TextOperator | NumberOperator | DateOperator; value: string | number | boolean;};
type RangeFilter = { operator: 'between' | 'inRange'; value: string | number; valueTo: string | number;};Operator Types#
| Type | Operators |
|---|---|
Text | contains, not, starts, ends, equals, not |
Number | equals, not, greater, greater, less, less |
Date | on, before, after |
Range | between, in |
No | is, is |
Operator Factories#
import { getTextOperators, getNumberOperators, getDateOperators, getBooleanOperators, getOperatorsForType,} from '@workspace/active-grid';Each factory takes a required Grid for the labels; there
is no English default (pass english for English).
type FilterOperatorOption = { value: FilterOperator; label: string; requiresValue: boolean; requiresSecondValue?: boolean;};
const operators: FilterOperatorOption[] = getNumberOperators(t);// → [{value: 'equals', label: t('grid.operators.equals'), requiresValue: true}, …]DateFilterPreset#
import { type DateFilterPreset, DEFAULT_DATE_PRESETS,} from '@workspace/active-grid';interface DateFilterPreset { key: string; // Translation key (e.g., 'grid.filter.datePreset.today') label?: string; // Optional display label — used instead of t(key) when provided type: 'single' | 'range'; getValue: (presentation?: GridPresentation) => {from: Date; to?: Date};}DEFAULT_ provides 8 built-in presets: today, yesterday, last
7 days, last 30 days, this month, last month, this quarter, this year.
Relative presets require an explicit presentation time zone. Their dates carry
calendar days, which the date filter serializes as yyyy-.
Pass a custom array via meta. or false to disable. How to
write a custom preset without reading the browser's time zone:
../ § Date Filter Configuration.
evaluateFilter / advancedFilterFn / evaluateFilterExpression#
import { evaluateFilter, evaluateFilterExpression, advancedFilterFn,} from '@workspace/active-grid';| Function | Description |
|---|---|
evaluate | Evaluate a Filter against a cell value. |
evaluate | Evaluate a Filter tree (AND/OR groups) against a full row. |
advanced | Filter function for the engine that supports operator-based filtering. |
createLocaleSortFn#
import {createLocaleSortFn} from '@workspace/active-grid';Factory that produces a sort function using Intl. for
locale-aware string sorting. Default sort uses ASCII codepoints; for
locale-correct ordering pass sort on
relevant columns.
createLocaleSortFn(locale: string, options?: Intl.CollatorOptions)localeis required and must be a non-empty string; there is no host default. An empty or missing locale throws a TypeError.The collator defaults to
{numeric: true, sensitivity: 'base'};optionsare merged over those defaults.The returned function compares
row.of two rows and returns a negative number, zero or a positive number. A string is compared as written, a finite number as its string form, and every other value (absent,get Value(column Id) Na,N ±Infinity, boolean, date, object) as the empty string.
Filter Components#
For custom filter UIs, the package exports the five built-in filter components plus a set of popover primitives.
import { TextFilter, NumberFilter, DateFilter, SelectFilter, BooleanFilter, FilterPopover, FilterPopoverTrigger, FilterPopoverContent, FilterPopoverHeader, FilterPopoverBody, FilterIcon, FilterClearButton, FilterCheckboxItem, FilterDateInput, FilterNumberInput, FilterOperatorSelect, FilterSearchInput, FilterTextInput, FilterWrapper,} from '@workspace/active-grid';In most cases the built-in filter row handles everything automatically
based on meta. — these exports are for custom filter-builder
UIs and advanced consumers.
The layout contract of the filter row#
All six built-in filters share one internal anatomy, with one rule: the value gives way, the controls never do. That anatomy is an internal component and not a public export -- consumers do not compose it and do not need to know it.
[ value / input ][ clear 24px ][ menu 24px ] min-w-0, shrinks to zero shrink-0 shrink-0| What | Behaviour |
|---|---|
| Value area | shrinks first, down to zero; text truncates with an ellipsis |
| Clear button (X) | only with an active filter; 24x24 target; does not shrink; never disappears on width |
| Filter menu button (funnel) | always present; 24x24 target; does not shrink |
| Right-aligned column | meta. mirrors the controls to the left; the slots stay the same |
| Full value | is in the rendered content, so screen readers get it untruncated |
A filterable column automatically gets an effective minimum width of 80px. That floor is derived from the cell padding, the two targets and the gaps between them, and protects only the CONTROLS. It deliberately does not keep translated values readable: the same state needs 122px in English and 161px in Spanish, and the count in it is dynamic, so a floor that guarantees text does not exist.
The floor only RAISES. A column with a larger min of its own, or a grid
with a larger default, is left alone; with
settings. it does not apply.
A consumer does not need to declare anything for this. There is no prop,
no opt-in and no migration, and there is no reason to add an own min or
a local CSS workaround for the clear button. A meta. deliberately
falls outside the shell and owns its own anatomy.
Grounds and trade-off: DECISIONS. ADR-027.
Filter Expression Tree#
For the AND/OR composite-filter UI, the package exports a small typed tree:
import { type FilterExpression, type FilterCondition, type FilterGroup, type FilterExpressionNode, isFilterGroup, evaluateFilterExpression,} from '@workspace/active-grid';| Symbol | Type | Description |
|---|---|---|
Filter | { id: string; field: string; operator: Filter | A single filter condition on a column. |
Filter | { id: string; combinator: 'and' | 'or'; children: Filter | A group with AND/OR logic combining children. |
Filter | Filter | A node in the tree — either a condition leaf or a group. |
Filter | Filter | Root of the tree — always a group. |
is | (node: Filter | Type guard. Returns true when the node has a combinator field. |
evaluate | <TData>(row: TData, expr: Filter | Client-side row evaluator. Returns true if the row matches the expression. |
evaluate ignores an incomplete condition: one without an
operator, or without a value its operator reads (undefined, null, '' or a
non-finite number; 0 and false are values; a range needs both ends).
is and is need no value. A group judges only its complete
children, and a group without any matches every row.
Tutorial: ../.
Server-mode filtering#
active- does not build database queries. In mode="server" the filter
and global-search state is forwarded verbatim in Server, and the
resource view in @workspace/ translates it into a query
server-side (see ./). The
evaluate / advanced helpers above apply only to
mode="client" in-memory filtering.