Context
This is the header active-state leaf of epic #19791, graduated from #19786 (contract 5, option H). I reproduced the defect live on dev 5829f5d407 in examples/grid/bigData, with header filters and column menus both on.
The Problem
After checking a value in the Firstname picker and clearing the Firstname header field, the grid stays filtered while its header looks unfiltered. The field is empty, the ▾ trigger is transparent once hover and focus leave, and no class or aria state marks the column. A user sees filtered rows and no reason for them.
The Architectural Reality
- The menu plugin observes
store.filters and the store's events, but scheduleRefresh returns while the surface is closed (src/grid/header/plugin/Menu.mjs:152). Nothing updates the header while the picker is shut.
- The trigger shows only on
:hover / :focus-within (resources/scss/src/grid/header/plugin/Menu.scss:17–19).
- A column with
showHeaderFilter and columnMenu: false has no plugin at all, but can still carry an effective filter.
- A cleared header field keeps its filter with
value: '', which is inert (Filter.mjs:250). "An owned filter exists" is therefore not "the column is filtered"; Filter.effective from the data-contract leaf of this epic answers the second.
- Design authority: the graduated contract in #19786 (body SHA-256
72b90388…).
The Fix
grid.header.Button syncs its active state from the Store's filters and filter events, independently of the menu plugin. When an effective owned contribution (header-inline or header-picker) exists for its dataField, the header:
- adds
neo-grid-column-filtered, which the Menu.scss visibility rule also matches, so the trigger stays visible;
- shows a filled glyph;
- extends the trigger label to "Filter , active". ARIA has no filtered-
columnheader attribute, so the label carries the state.
This leaf builds on the data-contract leaf's Filter.effective. Rebase on the landed #19788 (same file, onClick).
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
neo-grid-column-filtered (new header class) |
#19786 contract 5 |
Present while the column has an effective owned contribution |
Absent otherwise |
Button JSDoc, Menu.scss comment |
e2e: class read back |
Trigger aria-label (Menu.mjs:93) |
#19786 contract 5 |
Adds ", active" while filtered |
Unchanged label when not filtered |
plugin JSDoc |
e2e: label read back |
Menu.scss visibility rule |
#19786 contract 5 |
Also shows the trigger for filtered columns |
Hover and focus behavior unchanged |
scss |
screenshot |
Decision Record impact: none. Decision Record: NOT_NEEDED.
Acceptance Criteria
Out of Scope
The toolbar summary (the epic's toolbar leaf), the header-filter layout (#19786 OQ8), and the Table header (#19790).
Related
#19791 · #19786 · #19788
Live latest-open sweep: newest open issues at 09:47Z, no equivalent. A2A claim sweep: no claim on header active state. MC sweep: "grid header active filter state invisible picker", no prior decision.
unowned-rationale: open for self-selection by the v13.3 pair (Emmy, Grace) or any peer. It touches the Button that #19788 (Emmy) changes, so it waits for that merge.
Origin Session ID: bb2e8968-a6d6-4ef7-a4ed-5ab3157b1ac8
Retrieval Hint: "grid header filtered column active state trigger visible effective contribution"
Context
This is the header active-state leaf of epic #19791, graduated from #19786 (contract 5, option H). I reproduced the defect live on
dev5829f5d407inexamples/grid/bigData, with header filters and column menus both on.The Problem
After checking a value in the Firstname picker and clearing the Firstname header field, the grid stays filtered while its header looks unfiltered. The field is empty, the ▾ trigger is transparent once hover and focus leave, and no class or aria state marks the column. A user sees filtered rows and no reason for them.
The Architectural Reality
store.filtersand the store's events, butscheduleRefreshreturns while the surface is closed (src/grid/header/plugin/Menu.mjs:152). Nothing updates the header while the picker is shut.:hover/:focus-within(resources/scss/src/grid/header/plugin/Menu.scss:17–19).showHeaderFilterandcolumnMenu: falsehas no plugin at all, but can still carry an effective filter.value: '', which is inert (Filter.mjs:250). "An owned filter exists" is therefore not "the column is filtered";Filter.effectivefrom the data-contract leaf of this epic answers the second.72b90388…).The Fix
grid.header.Buttonsyncs its active state from the Store's filters and filter events, independently of the menu plugin. When an effective owned contribution (header-inlineorheader-picker) exists for itsdataField, the header:neo-grid-column-filtered, which the Menu.scss visibility rule also matches, so the trigger stays visible;columnheaderattribute, so the label carries the state.This leaf builds on the data-contract leaf's
Filter.effective. Rebase on the landed#19788(same file,onClick).Contract Ledger
neo-grid-column-filtered(new header class)aria-label(Menu.mjs:93)Menu.scssvisibility ruleDecision Record impact: none. Decision Record: NOT_NEEDED.
Acceptance Criteria
showHeaderFilterson andcolumnMenu: false, an effective inline filter marks its header.#19788's.Out of Scope
The toolbar summary (the epic's toolbar leaf), the header-filter layout (#19786 OQ8), and the Table header (
#19790).Related
#19791 · #19786 · #19788
Live latest-open sweep: newest open issues at 09:47Z, no equivalent. A2A claim sweep: no claim on header active state. MC sweep: "grid header active filter state invisible picker", no prior decision.
unowned-rationale: open for self-selection by the v13.3 pair (Emmy, Grace) or any peer. It touches the Button that
#19788(Emmy) changes, so it waits for that merge.Origin Session ID: bb2e8968-a6d6-4ef7-a4ed-5ab3157b1ac8 Retrieval Hint: "grid header filtered column active state trigger visible effective contribution"