Skip to content

feat(ui): display region's countries in pill tooltip - #895

Merged
AlexAxthelm merged 7 commits into
mainfrom
feat/geography-ui
Aug 18, 2026
Merged

feat(ui): display region's countries in pill tooltip#895
AlexAxthelm merged 7 commits into
mainfrom
feat/geography-ui

Conversation

@AlexAxthelm

@AlexAxthelm AlexAxthelm commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Closes #799: "hovering a multi-country region shows its mapped ISO codes."

Region badges on the detail page showed a bare label with no way to see what the publication actually put in the region. flattenGeography carries region labels only and discards membership, so nothing in the UI read geography.regions[label] — this adds regionMemberCodes(geo, label) in geographyUtils.ts to look it back up, alongside flattenGeography / pathwayISOCoverage.

RegionMembersTooltip renders the body: a count line, then member country names (via the existing countryNameFromISO2), capped at 12 with a +N more tail. It plugs into the geography BadgeArray through the tooltipGetter prop — the one badge family that wasn't passing it, while sectors and metrics already did. No new tooltip machinery; it renders into the existing TextWithTooltip.

Details worth flagging:

  • Mappings come from the pathway's own data file, never filterRegions.ts — the publication's mapping, not ours.
  • Members are capped because the tooltip panel is max-w-xs with pointer-events: none, so it can neither widen nor scroll. IEA's "Africa" has 54 members.
  • Ordering reuses sortGeographiesForDetails (A→Z by ISO2, same as country badges); prioritizeGeographies floats search matches to the front when a search term is supplied.
  • Unmapped regions (the NGFS shape — declared label, empty member array) read "No country mapping published for this region." rather than showing an empty box.
  • Badge.tooltip widened from string to React.ReactNode. BadgeArray.tooltipGetter already promised ReactNode and TextWithTooltip.tooltip already accepted it — Badge was the one narrow link in the chain.

Global and country badges are unchanged and get no tooltip.

Part of #799 (scope box) / #783 / epic #860.

Testing

npm ci && npm test -- --run && npm run lint && npm run format:check

433 tests pass. New coverage: 8 tests for regionMemberCodes, 7 for RegionMembersTooltip (names not codes, count line, the 12-item cap, the empty case), and a new PathwayDetailPage.test.tsx — the page had no test file — which focuses a region badge and asserts the portaled tooltip lists the member country names.

Manually, with npm run dev:

  • /pathway/IEA-APS-2024 — 8 regions, overlapping ("Southeast Asia" ⊂ "Asia Pacific"). Hover Africa (54) and Asia Pacific (40) for the +N more cap; North America (3) for a short list.
  • /pathway/TZ-REGI-2024 — a single 10-member "South East Asia": full list, no cap.
  • /pathway/NGFS-NZ2050-2024 — region labels with no published mapping: should read "No country mapping published for this region.", never an empty box.
  • Hover Global and any country badge — no tooltip, no hover target.

Note for reviewers

Independent of #894 and mergeable in either order — verified by test-merging both directions (clean, identical result tree, merged combination passes suite and lint).

Copilot AI lite review requested due to automatic review settings August 13, 2026 09:43
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

Expected version change and release notes:

1.16.0-dev.11 (v1.16.0-dev.10...feat/geography-ui ) (2026-08-17T13:29 UTC)

Features

  • ui: display region's countries in pill tooltip (62e8a6f)

Other

@github-actions

Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://proud-glacier-0f640931e-895.westus2.2.azurestaticapps.net

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a detail-view tooltip for region geography badges so users can see which countries a pathway’s author-defined regions map to, leveraging the structured { global, regions, country } geography shape introduced previously.

Changes:

  • Introduces regionMemberCodes() utility to retrieve and normalize a pathway region’s member ISO2 codes.
  • Adds RegionMembersTooltip component and wires it into PathwayDetailPage region badges via BadgeArray.tooltipGetter.
  • Adds unit and page-level tests covering mapped regions, unmapped regions, and non-region badges.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/utils/geographyUtils.ts Adds regionMemberCodes() to look up and normalize region member ISO2 codes.
src/utils/geographyUtils.test.tsx Adds unit tests for regionMemberCodes() behavior and edge cases.
src/pages/PathwayDetailPage.tsx Attaches region-only tooltips to geography badges on the detail page.
src/pages/PathwayDetailPage.test.tsx Adds integration tests asserting tooltip presence/absence and rendered content.
src/components/RegionMembersTooltip.tsx New tooltip body component rendering member country list (with truncation).
src/components/RegionMembersTooltip.test.tsx Adds component tests for ordering, truncation, search prioritization, and empty mappings.
src/components/Badge.tsx Broadens tooltip prop type from string to ReactNode to support rich tooltip content.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/utils/geographyUtils.ts Outdated
Comment thread src/components/RegionMembersTooltip.tsx
Copilot AI review requested due to automatic review settings August 13, 2026 10:04
@github-actions

Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://proud-glacier-0f640931e-895.westus2.2.azurestaticapps.net

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/components/Badge.tsx:6

  • BadgeProps.children is typed as string | number, but callers can (and do) pass React elements via BadgeMaybeAbsent/BadgeArray (e.g. highlighted search matches). This makes the component’s public typing inconsistent with its actual usage and can cause TS friction when passing non-scalar children.
interface BadgeProps {
  children: string | number;

Copilot AI review requested due to automatic review settings August 13, 2026 10:09
@AlexAxthelm
AlexAxthelm marked this pull request as ready for review August 13, 2026 10:10
@AlexAxthelm
AlexAxthelm requested a review from jacobvjk August 13, 2026 10:10
@github-actions

Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://proud-glacier-0f640931e-895.westus2.2.azurestaticapps.net

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 13, 2026 11:28
@github-actions

Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://proud-glacier-0f640931e-895.westus2.2.azurestaticapps.net

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

@jacobvjk jacobvjk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionally great, but I would adjust the "no mapping" message a little

Comment thread src/components/RegionMembersTooltip.tsx Outdated
Copilot AI review requested due to automatic review settings August 17, 2026 09:13
@github-actions

Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://proud-glacier-0f640931e-895.westus2.2.azurestaticapps.net

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Comment thread src/components/RegionMembersTooltip.tsx
Copilot AI review requested due to automatic review settings August 17, 2026 09:20
@jacobvjk

Copy link
Copy Markdown
Collaborator

updated the "mapping not available" message

@github-actions

Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://proud-glacier-0f640931e-895.westus2.2.azurestaticapps.net

@jacobvjk
jacobvjk self-requested a review August 17, 2026 09:22
jacobvjk
jacobvjk previously approved these changes Aug 17, 2026

@jacobvjk jacobvjk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/utils/geographyUtils.ts:80

  • regionMemberCodes always scans Object.keys(geo.regions) to find a normalized match. If there is an exact key equal to the normalized label (the common case), it’s cheaper and more deterministic to use it directly first; it also avoids accidentally selecting a different key when multiple region keys normalize to the same value (e.g. both "Europe" and " Europe ").
  const key = Object.keys(geo.regions).find(
    (k) => normalizeGeography(k) === wanted,
  );
  if (key === undefined) return [];
  const members = geo.regions[key];

Copilot AI review requested due to automatic review settings August 17, 2026 13:27
@AlexAxthelm
AlexAxthelm requested a review from jacobvjk August 17, 2026 13:28
@github-actions

Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://proud-glacier-0f640931e-895.westus2.2.azurestaticapps.net

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/components/RegionMembersTooltip.tsx:18

  • The PR description (and earlier discussion) says unmapped regions should read “No country mapping published for this region.”, but the UI constant currently uses “available…”. If the “published” wording is intentional, this string (and the related assertions in tests) should be updated to match so reviewers/users see the same copy that’s documented for #799.
export const NO_REGION_MAPPING_TEXT =
  "No country mapping available for this region.";

@AlexAxthelm
AlexAxthelm merged commit 9d29ffa into main Aug 18, 2026
13 checks passed
@AlexAxthelm
AlexAxthelm deleted the feat/geography-ui branch August 18, 2026 09:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add pathway regions

3 participants