Taxonomy Filter Modal — Variant B Visual Hardening¶
Motivation¶
The new split-panel TaxonomyModal (Variant B mockup) had two ship-blocking defects
when validated end-to-end in the browser at /blast/submit:
- State-reset bug — Selecting a row from the results list flashed back to the empty placeholder. The detail panel never hydrated.
- Detail panel rendered centered — Even though the parent column resolved to
text-align: left, every text element inside.taxonomy-modal__detailcomputed tocenter, leaving the lineage / metadata grid visually broken.
The image, scroll behaviour, backdrop tint, and empty-state padding also needed polish before the modal looked acceptable on a 1366×768 laptop.
User-facing change¶
- The detail panel now hydrates on the first click and persists across re-renders.
- Detail panel text (name, common-name line, Wikipedia link, lineage, metadata grid) is consistently left-aligned.
- Lineage block caps at
88pxand exposes a thin custom scrollbar instead of pushing the metadata grid off-screen. - Wikipedia thumbnail rail is
108pxtall withflex-shrink: 0so the layout stops jumping when the image loads. - Backdrop darkened to
rgba(2, 4, 10, 0.62)with a2pxblur so the modal feels modal-grade against the dashboard underneath. - Recent chips, exclude/include toggle, and the footer command preview were
re-verified in the browser (recent persists,
-taxids↔-negative_taxidsupdates immediately).
Code diff summary¶
web/src/pages/blastSubmit/TaxonomyModal.tsx- Hydration
useEffectdeps switched from[open, initial](object identity flipped every parent render) to primitive field deps:[open, initial.taxid, initial.taxid_label, initial.taxid_rank, initial.is_inclusive], with a singlereact-hooks/exhaustive-depssuppression because the lint rule cannot see through the destructure. web/src/theme/glass.css(taxonomy-modal block).taxonomy-modal__backdrop: darker tint +backdrop-filter: blur(2px)..taxonomy-modal: clampedmax-height: min(calc(100vh - 32px), 680px)and explicittext-align: left..taxonomy-modal__detail: explicittext-align: left !importantplus a compound:not(.taxonomy-modal__detail--empty)override on direct children. The!importantis intentional — the cascade was producingcenterfrom no matching rule on this exact host, so we force the safe alignment..taxonomy-modal__detail-image: height140px → 108px,flex-shrink: 0..taxonomy-modal__detail--empty: tightened padding/gap,min-height: 160px..taxonomy-modal__detail-lineage:max-height: 88px; overflow-y: auto;plus thin custom scrollbar (Firefox + WebKit).@media (max-width: 760px): image100px, modalmax-heightcalc(100vh - 32px).
No API, IaC, or Bicep changes.
Validation evidence¶
cd web && npm test -- --run→ 12 files, 87 tests passed (includes the 17useRecentTaxonomy.test.tscases that already covered the hook).cd web && npx eslint src/pages/blastSubmit/TaxonomyModal.tsx src/pages/blastSubmit/useRecentTaxonomy.ts→ clean. (The two pre-existingreact-hooks/exhaustive-depswarnings inEndpointCard.tsx:36anduseDbWithWarmupPlan.ts:96are onmainand not introduced by this change.)cd web && npm run build→ vite build green in 8.40s.- Browser smoke at
http://127.0.0.1:8090/blast/submit: - Searched
Homo sapiens→ first row click hydrated the detail panel (getComputedStyle('.taxonomy-modal__detail').textAlign === 'left'). - Toggled
Exclude→ footer preview updated-taxids 9606→-negative_taxids 9606. - Clicked
Apply, re-opened the modal →Recentchip showedHomo sapiens 9606, exclude mode persisted, detail auto-hydrated from the recent. - Lineage block scrolls inside the detail card without spilling.