fix: #3617499 Follow the design system for the header search icon and box

Issue: https://www.drupal.org/project/vartheme_bs5_horizonaid/issues/3617499

Implements the six header-search designs from the VBNGO Stylesheet — 9641-704 and 9640-614 (the search bar, desktop and mobile), 751-5190 (header desktop) and the three mobile header states 9641-993 / 9641-1107 / 9640-556.

What changed and why

icon-toggle was an older fork of the base vartheme_bs5 component: no panel prop, no expand_in_editor, no Bootstrap Dropdown, and its own show/hide code. It rendered a 384×125 box with no close button where the design draws a 720×42 bar with one. This re-syncs it with base and keeps brand values in this theme's SCSS below a marked divider, so everything above stays re-syncable next time base moves.

The panel would not open — a duplicated library, not a missing one

The component asked for vartheme_bs5/bs-dropdown-script while every other component here asks for the Horizon Aid library. Both themes are on disk, so Bootstrap's dropdown.js was evaluated twice from two theme paths. Each evaluation registers its own document-level click data-API handler over an independent Dropdown class and instance map, so a single click toggled two instances — the measured event sequence was show → shown → hide → hidden, leaving aria-expanded="false".

The lesson worth carrying: when re-syncing a component across themes, the namespace has to be rewritten in the library dependencies, not only in Twig.

Two further defects in this theme's own code

  • The unscoped exposed-filter card skin (views-exposed-filters.scss plus a hook_form_alter() that attaches it to every exposed form) applied its 1.25rem inset inside the header bar, pushing the field off the design's 8px gap.
  • Below lg the band began half a gutter outside the viewport and stood 50px tall instead of 74px: icon-toggle.js resolves its band with closest() over a selector list ending in section, and this theme wraps the header in an edge-to-edge Section, while the header's own .dropdown-menu padding outweighed the band's own.

Both are restated in the brand block. The closest() and padding issues are arguably worth fixing upstream in vartheme_bs5.

Measured against the designs

Design Measured
open panel, desktop 1440 720 × 42 720 × 42
open panel, mobile 375 343 × 42 343 × 42
icon → field gap 8px 8px
placeholder 14px, line-height 1.5 14px / 21px
bottom border 0.5px #0d2c54 0.5px, navy rgb(13,44,84)
focus on open yes yes
Escape / close button / outside click close all close, focus returns to the trigger

Accessibility

The exposed field keeps its label so it has an accessible name, and the bar renders that label visually hidden (Bootstrap's visually-hidden) because the design shows none there. The label is hidden, never removed — measured 1×1, position:absolute, accessible name Search by keyword. On the results page it stays visible, which the six designs do not cover. The recipe half of this (giving the exposed filter a non-empty label) is on #3617244.

Deliberately not in this MR

  • views-view-search is untouched. My working clone was behind c33b469e, so a re-sync there would have replaced this branch's newer five-file version (including its SCSS) with base's three files and dropped the search-results styling.
  • The 17.5px search glyph. This build emits .fs-5{1rem} / .fs-6{0.875rem}, so 17.5px needs a new $font-sizes step in scss/_bootstrap-variables.scss plus an enum change in bootstrap-icon, which mints new component versions. I used the nearest step (16px) rather than add !important or invent a class. That is a token decision for the maintainer.
  • Mobile push vs overlay. Figma pushes the menu down by exactly the 74px band; base uses position: fixed and overlays. Following the design needs the panel to be an in-flow row in the base theme's header structure, so the geometry here is faithful and the positioning is left as base's. The designs make the menu and search mutually exclusive anyway.

Checkpoints

  • File an issue
  • Addition/Change/Update/Fix
  • Reviewed by a human
  • Code review by maintainers

AI-Generated: Yes

Merge request reports

Loading
Loading