Why
Filter and search controls had drifted apart. The code page kept its branch picker in the header actions and had no tag picker. Search inputs ranged from 10rem to 18rem. Some filter dropdowns had visible labels and some did not. Text searches submitted through a “Filter” button, a “Search” button, or Enter alone, while selects sometimes waited for an explicit click.
What
- One filter row.
.filtersis the only row component: issues, requests, activity, code search, and the code page all use it. The code page’s one-off.code-filtersis gone. - One search width.
--search-w: 18remis shared by page filter rows and the global bar, so the field does not resize when moving between surfaces. - Labels. Every filter
<select>carries a visible.filter-label(Label,Assignee,Actor,Branch,Tag). - Submission. Selects apply on change via
data-autosubmit; the stand-alone “Filter” buttons are removed. Text search always ends with the same icon-and-“Search” button (the compact global search keeps the icon with an accessible name). - Code page. Search, branch selection and the new tag selection sit on the shared row under the page header. The tag picker lists tags newest first and leaves the branch picker unclaimed when a tag (or commit) is open.
- HTMX.
[data-autosubmit]now callsrequestSubmit()instead ofsubmit(), so htmx intercepts the submit and swaps the filtered pane instead of forcing a full page load. - Mobile. Filter rows stack at 720px, with labels above their controls instead of an 18rem control overflowing a narrow row.
Tests
TestFilterRowsShareOneShapepins the shared class, labeled selects, auto-apply, no per-page Filter buttons, and the uniform Search button.TestCodeBrowserRefPickerscovers the code page row, tag listing, and the unclaimed branch picker on a tag page.
Checks
./vole workflow check./vole workflow run verify(format, vet, build, packaging, link checks, race tests)go test ./...