This is the toolbar leaf of epic #19791, graduated from #19786 (contracts 4, 5 summary part and 6; options A2, I and J). The operator put the optional toolbar into v13.3 on 2026-10-16. The issues showcase has no text path to Title and Summary, which carry columnMenu: false, and a reset means clearing each menu in turn.
The Problem
A grid cannot offer record search. Nothing shows the filters that have no column header (the search itself, Title and Summary), and nothing clears the grid's own filters in one step.
The Architectural Reality
grid.Container has no toolbar slot above the header. footerToolbar_ is a descriptor config that becomes a container item (src/grid/Container.mjs:151–155, :340–342); it is the precedent.
form.field.Search exists.
The search contribution, its settings and its validation come from the data-contract leaf of this epic. The toolbar only projects them and writes settings.
Grid columns declare no hidden config, so a "visible columns" scope has no meaning yet. Body.visibleColumns is the horizontal viewport range and must never feed the scope.
Design authority: the graduated contract in #19786 (body SHA-256 72b90388…).
The Fix
searchToolbar_ descriptor config on grid.Container, mirroring footerToolbar_, placed before headerWrapper, null by default.
Search field, a scope selector and a case toggle; clear empties the field. The scope choices are this grid's columns with locked ones included (the default), all record fields, or one column. Labels use the columns' text, never field names. A stored field with no column in this grid reads "Record field: ", and only then. A column whose values are neither plain text nor hooked through fieldText stays listed as not searchable. "All record fields" says it searches values no column shows. The selector shows the stored field list, so a second toolbar on the same Store shows the same list. (Default set by the author after the operator's design challenge, D#19786: contract 4 left it open.)
Summary strip: one removable entry per effective header contribution (header-inline, header-picker). The search has no entry: its field shows the query, and its clear button empties it while keeping scope and case. Non-removable notes name any restriction the toolbar does not own, a disabled query, an empty resolved scope and a refusal. (Contract 5 delta, ratified on D#19786 by the author and Emmy.)
"Clear filters" removes header-inline, header-picker and grid-search by enumeration, never every non-null role and never unowned predicates.
The issues showcase turns the toolbar on.
Contract Ledger
Target Surface
Source of Authority
Proposed Behavior
Fallback
Docs
Evidence
grid.Container.searchToolbar_ (new descriptor config)
grid.SearchToolbar.fieldText_ (new descriptor config)
#19792 / #19796: Store#getSearchRefusal and the SearchFilterfieldText contract
Optional per-field (value, item) => String hooks, passed with an explicit search write; hooks the Store's search filter already holds are kept. No new producer API, no conversion through column renderers
null: only the plain-text field types the producer supports are searchable
config JSDoc, Grids.md section
unit: a Date column is a disabled choice without a hook, and enabled and matching with one
Decision Record impact: none. Decision Record: NOT_NEEDED.
Acceptance Criteria
searchToolbar_ is null by default, and a grid without it renders unchanged.
The scope selector writes the resolved field list, and a second toolbar on the same Store shows that list.
The scope defaults to this grid's columns, labelled by column text. A stored field with no column in this grid reads "Record field: ". "All record fields" states that it searches values no column shows, and a column without searchable text is listed as not searchable.
The summary has no entry for the search; clearing the field keeps scope and case. Header contributions keep removable entries, and a disabled, empty-scope or refused search gets a note.
Clear removes only the three UI roles. An independent application predicate survives, and the summary names it.
On a narrow grid, the summary exposes every removable state and the reset without widening the grid.
The issues showcase reaches Title and Summary through the toolbar in a real browser.
A receipt with numbers covers per-keystroke input and row-response latency for literal terms on the 100k bigData grid.
Grid lifecycle (moved from #19792, which needs no grid): a Store swap, grid destroy and recreate, and two grids on one Store keep or retire the search intent deterministically. Recreating either grid leaves the other's results unchanged.
The toolbar writes through Store#getSearchRefusal() first and shows its reason instead of writing.
Out of Scope
Regex (#19786 OQ4), the header active state (the epic's header leaf), the display-policy menu, and the header-filter layout (OQ8).
Live latest-open sweep: newest open issues at 09:47Z, no equivalent. A2A claim sweep: no claim on the toolbar. MC sweep: "grid record search toolbar", clear miss beyond #19786.
unowned-rationale: open for self-selection by the v13.3 pair (Emmy, Grace) or any peer. It builds on the data-contract leaf, so it starts once that leaf's API is stable. The release-notes epic (#19712) gains a line when this lands.
Context
This is the toolbar leaf of epic #19791, graduated from #19786 (contracts 4, 5 summary part and 6; options A2, I and J). The operator put the optional toolbar into v13.3 on 2026-10-16. The issues showcase has no text path to Title and Summary, which carry
columnMenu: false, and a reset means clearing each menu in turn.The Problem
A grid cannot offer record search. Nothing shows the filters that have no column header (the search itself, Title and Summary), and nothing clears the grid's own filters in one step.
The Architectural Reality
grid.Containerhas no toolbar slot above the header.footerToolbar_is a descriptor config that becomes a container item (src/grid/Container.mjs:151–155,:340–342); it is the precedent.form.field.Searchexists.hiddenconfig, so a "visible columns" scope has no meaning yet.Body.visibleColumnsis the horizontal viewport range and must never feed the scope.72b90388…).The Fix
searchToolbar_descriptor config ongrid.Container, mirroringfooterToolbar_, placed beforeheaderWrapper, null by default.fieldTextstays listed as not searchable. "All record fields" says it searches values no column shows. The selector shows the stored field list, so a second toolbar on the same Store shows the same list. (Default set by the author after the operator's design challenge, D#19786: contract 4 left it open.)header-inline,header-picker). The search has no entry: its field shows the query, and its clear button empties it while keeping scope and case. Non-removable notes name any restriction the toolbar does not own, a disabled query, an empty resolved scope and a refusal. (Contract 5 delta, ratified on D#19786 by the author and Emmy.)header-inline,header-pickerandgrid-searchby enumeration, never every non-null role and never unowned predicates.Contract Ledger
grid.Container.searchToolbar_(new descriptor config)null: the grid renders unchangedGrids.mdsectiongrid.SearchToolbar.fieldText_(new descriptor config)Store#getSearchRefusaland theSearchFilterfieldTextcontract(value, item) => Stringhooks, passed with an explicit search write; hooks the Store's search filter already holds are kept. No new producer API, no conversion through column renderersnull: only the plain-text field types the producer supports are searchableGrids.mdsectionexamples/grid/issuesDecision Record impact: none. Decision Record: NOT_NEEDED.
Acceptance Criteria
searchToolbar_is null by default, and a grid without it renders unchanged.bigDatagrid.Store#getSearchRefusal()first and shows its reason instead of writing.Out of Scope
Regex (#19786 OQ4), the header active state (the epic's header leaf), the display-policy menu, and the header-filter layout (OQ8).
Related
#19791 · #19786 · #19712
Live latest-open sweep: newest open issues at 09:47Z, no equivalent. A2A claim sweep: no claim on the toolbar. MC sweep: "grid record search toolbar", clear miss beyond #19786.
unowned-rationale: open for self-selection by the v13.3 pair (Emmy, Grace) or any peer. It builds on the data-contract leaf, so it starts once that leaf's API is stable. The release-notes epic (#19712) gains a line when this lands.
Origin Session ID: bb2e8968-a6d6-4ef7-a4ed-5ab3157b1ac8 Retrieval Hint: "grid searchToolbar summary strip clear filters issues showcase"