From 09d94e513e0d5fbaee33ae0e7c0b29ff64a76e1a Mon Sep 17 00:00:00 2001 From: Tudor Date: Wed, 22 Jul 2026 15:30:40 +0100 Subject: [PATCH] docs(compare): design for unified InfoPopover metric-help affordance Co-Authored-By: Claude Opus 4.8 --- .../specs/2026-07-22-info-popover-design.md | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-22-info-popover-design.md diff --git a/docs/superpowers/specs/2026-07-22-info-popover-design.md b/docs/superpowers/specs/2026-07-22-info-popover-design.md new file mode 100644 index 0000000..5222ec2 --- /dev/null +++ b/docs/superpowers/specs/2026-07-22-info-popover-design.md @@ -0,0 +1,125 @@ +# Info Popover — unified metric-help affordance + +**Date:** 2026-07-22 +**Status:** Approved (design) + +## Problem + +Two different "info affordance" patterns explain metrics across the app, and both are broken: + +1. **`MetricTooltip` (ⓘ)** — used on the two detail pages (`SchoolDetailView`, + `SecondarySchoolDetailView`). Its bubble is `position: absolute` with a fixed + `220px` width and no viewport-collision detection. Near a screen edge on + mobile the bubble renders **partly or wholly off-viewport with no way to + scroll to it** — effectively unusable. A `left: -12px` mobile hack only + shifts the problem, it doesn't solve it. + +2. **Compare-section `?` help** — every compare section funnels through + `RowLabel` in `components/compare/sectionShared.tsx`, which uses the **native + `title=` attribute**. On desktop the native tooltip has a long, unconfigurable + hover delay; on touch it barely surfaces at all. + +We want a single component that positions itself correctly in any viewport and +shows a custom (non-native) tooltip on desktop. + +## Decisions + +- **Positioning: `@floating-ui/react`** (industry standard, ~10KB gzipped, React + 19 compatible). Chosen over a hand-rolled portal + JS positioning because the + current hand-rolled approach is exactly what failed, and Floating UI already + solves flip/shift/portal/interactions/ARIA. +- **Mobile presentation: repositioning popover** (not a bottom-sheet). Same small + bubble as desktop; Floating UI's `shift`/`flip` keep it fully on-screen. One + presentation to build and maintain, consistent across platforms. +- **Glyph: standardise on the circled `?`** everywhere (replaces ⓘ on the detail + pages). Matches the common "help" convention. +- **Bundle:** adding `@floating-ui/react` as a runtime dependency is accepted. + +## Architecture + +One shared engine, two thin adapters — **no call-site churn**. + +### `InfoPopover` (new — `components/InfoPopover.tsx`) + +Owns all behaviour via `@floating-ui/react`. + +- **Trigger:** a real `