fix: #3617499 Give the search results page a heading and keep its filter bar on one line

Issue: #3617499 Search results have no page heading, show the result count above the search box, and wrap the Search button

What this changes

A views-view-search organism. It takes the same template_preprocess_views_view() variables as the shared Views view component and prints them in the order a results page reads: the view title as the page h1, then the exposed filter bar, then the result summary, then the rows. A thin templates/views/views-view--search--page.html.twig includes it, so only the search page display changes and every other view keeps the shared component untouched.

A view-empty--notice panel for the empty state, built from --bs-secondary-bg-subtle and --bs-border-color. --bs-tertiary-bg is #212529 in this theme, so a notice built on that token would put body-coloured text on a dark surface; the light neutral measures 14.61:1.

A views-exposed-form--search modifier on the exposed filters component. The listing filter card puts its actions on their own full-width line, which is right for a row of filters and wrong for a form with one keyword field and no reset. The modifier keeps the field and the Search button on one line at every width, drops the doubled bottom margin, and gives the field the magnifier. The magnifier moves into a mixin so the listing filters and the search form share one definition instead of two copies of the same inline SVG. The field's flex basis is 0 rather than auto, because the field's own width: 100% would otherwise be its basis and push the button onto a second line in a narrow panel.

The modifier class is attached from hook_form_alter(), matched on the form-ID prefix, the way the events and blog filter rows already are, so a search form gets it wherever it renders — the results page and a header panel alike.

Conventions

.scss is the source and .css is webpack output (webpack.config.components.js gains the new entry); no .css was hand-edited. Sizes are in rem off $spacer, values come from Bootstrap tokens, and the component keeps its styles in its own directory rather than in the global stylesheets.

The submit keeps this theme's filled primary pill rather than a ghost button, because that is the treatment every other exposed form here already uses; navy on the brand yellow measures 8.94:1.

Verified

Clean install from a dropped database, then a real browser at 1440px and 390px:

  • exactly one h1, reading "Search", on results, empty, no-query and paged states;
  • order is heading, filter bar, summary, rows;
  • field and button on one line — 1142x47 and 102x42 at the same y on desktop, 212x47 and 102x42 at 390px, 196x47 and 102x42 inside a 384px header panel with no overflow;
  • empty-state notice at 14.61:1, 20px radius, 24px padding;
  • 0 console errors, and no horizontal overflow introduced (the 402px document width at a 390px viewport is present on pages this change does not touch).

The full local pipeline passes: theme build, ESLint, Stylelint, Cspell and PHPStan, 0 errors.

AI-Generated: Yes

Checkpoints:

  • File an issue
  • Addition/Change/Update/Fix
  • Testing to ensure no regression
  • Automated unit testing coverage
  • Automated functional testing coverage
  • UX/UI designer responsibilities
  • Readability
  • Accessibility
  • Performance
  • Security
  • Developer Documentation
  • User Guide Documentation
  • Reviewed by human
  • Code review by maintainers
  • Full testing and approval
  • Credit contributors
  • Review with the product owner
  • Release notes snippet
  • Release
Edited by Rajab Natshah

Merge request reports

Loading
Loading