Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@

## 89.0.0-SNAPSHOT - unreleased

### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW - grid column filter specs)

* `GridFilterModelConfig.fieldSpecs` is no longer an allow-list. Any `filterable` column it omits
now gets a default filter - set `filterable: false` on columns that should have none.

### 🐞 Bug Fixes

* Fixed `GridFilterModelConfig.fieldSpecs` disabling filters on all other `filterable` columns.
Apps can now pass a spec for just the fields needing custom config, such as a values renderer.
See Breaking Changes above.
* Fixed the desktop `SegmentedControl` rendering 2px taller than adjacent buttons when `outlined`.

## 88.1.0 - 2026-10-01
Expand Down
7 changes: 6 additions & 1 deletion cmp/grid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ new GridModel({
filterModel: true, // Default config
filterModel: {
bind: store, // Filter target (defaults to grid's store)
commitOnChange: true
commitOnChange: true,
fieldSpecs: [{field: 'status', renderer: statusRenderer}] // Optional custom config
},
columns: [
{field: 'status', filterable: true}, // Enable filter on specific columns
Expand All @@ -219,6 +220,10 @@ new GridModel({
});
```

A `filterable` column gets a filter with default config even if `fieldSpecs` omits its field, as
long as that field exists in the bound Store or View.
List only the fields that need custom config. Set `filterable: false` to disable a column's filter.

### Inline Editing

```typescript
Expand Down
4 changes: 4 additions & 0 deletions cmp/grid/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ export interface GridFilterModelConfig {
* Specifies the fields this model supports for filtering. Should be configs for
* {@link GridFilterFieldSpec}, string names to match with Fields in bound Store/View, or
* omitted entirely to indicate that all fields should be filter-enabled.
*
* Any `filterable` column with a field not listed here gets a default spec, so this list only
* needs to include fields that require custom config. Set `filterable: false` on a column to
* disable its filter.
*/
fieldSpecs?: Array<string | GridFilterFieldSpecConfig>;

Expand Down
37 changes: 31 additions & 6 deletions cmp/grid/filter/GridFilterModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ export class GridFilterModel extends HoistModel {
this.commitOnChange = commitOnChange;
this.activeFilterIcon = activeFilterIcon ?? GridFilterModel.defaults.activeFilterIcon;
this.fieldSpecs = this.parseFieldSpecs(fieldSpecs, fieldSpecDefaults);

// Ensure every filterable column has a spec, including columns or View fields added later.
// Columns are typically still empty here - the reaction covers the GridModel's setColumns().
this.addReaction({
track: () => [gridModel.columns, this.bind.fieldNames],
run: () => this.addColumnFieldSpecs(fieldSpecDefaults),
fireImmediately: true
});
}

/**
Expand Down Expand Up @@ -169,12 +177,29 @@ export class GridFilterModel extends HoistModel {

return specs.map(spec => {
if (isString(spec)) spec = {field: spec};
return new GridFilterFieldSpec({
filterModel: this,
source: bind,
...fieldSpecDefaults,
...spec
});
return this.createFieldSpec(spec, fieldSpecDefaults);
});
}

// Add default specs for filterable columns not covered by the configured specs.
private addColumnFieldSpecs(fieldSpecDefaults: Omit<GridFilterFieldSpecConfig, 'field'>) {
const {fieldNames} = this.bind;
this.gridModel.getLeafColumns().forEach(({filterable, field}) => {
if (filterable && fieldNames.includes(field) && !this.getFieldSpec(field)) {
this.fieldSpecs.push(this.createFieldSpec({field}, fieldSpecDefaults));
}
});
}

private createFieldSpec(
spec: GridFilterFieldSpecConfig,
fieldSpecDefaults: Omit<GridFilterFieldSpecConfig, 'field'>
): GridFilterFieldSpec {
return new GridFilterFieldSpec({
filterModel: this,
source: this.bind,
...fieldSpecDefaults,
...spec
});
}

Expand Down
Loading