Filter Builder
A filter bar of sentence chips (Status is any of Active), an add-filter picker and an editor for each part; it reports a plain JSON filter tree.
c2-filter-builder is the filter bar of Linear, Airtable and Polaris IndexFilters. Each condition is a chip that reads as a sentence, Status | is any of | In progress, In review. Clicking the operator or the value opens its editor under that part. The Filter button opens a field picker, and typing in it also finds values, so “Ana” offers “Assignee is Ana Ng” in one step. Picking a field opens its value editor straight away. A condition with no value yet shows as a dashed chip and is dropped if its editor closes empty.
The component filters nothing itself. fields describes what can be filtered: each field has an id, a label and a type (enum, person, multi, text, number, date, boolean or custom), and the type picks the operators and the editor. value is the filter tree, { op: 'and', rules: [{ field, operator, value }] }. It holds option values only, never labels or colours, so you can store it as a saved view and send it to a server. Every change fires filter-change with the new tree. On enum and person fields the operator follows the number of values: one value is is (eq), several are is any of (in).
How values look is data on each option: color draws a dot, icon names an icon element such as c2-feather-flag, avatar is a picture (person fields fall back to initials), and description and count add a second line and a number. For anything else, a field’s renderOption, renderValue and renderEditor replace a row, the chip’s value or the whole editor. loadOptions(query, signal) fetches options from a server as the user types, and resolveOptions(values, signal) labels the values of a saved tree. labels translates every piece of text. Below compact-below pixels (480 by default) the bar becomes a Filters button and a scrolling row of chips. The button opens a bottom sheet where each condition is edited in place.
Import
import '@c2n/components/filter-builder'Usage
Listen to filter-change and apply the tree yourself:
const filters = document.querySelector('c2-filter-builder')!
filters.fields = [
{ id: 'status', label: 'Status', type: 'enum', options: [{ value: 'doing', label: 'In progress', color: '#0265dc' }] },
{ id: 'assignee', label: 'Assignee', type: 'person', loadOptions: (query, signal) => api.people(query, { signal }) },
]
filters.addEventListener('filter-change', (event) => {
table.rows = applyMyFilter(allRows, event.detail.value)
})