Skip to content

Explorer: unify click semantics — click opens detail card, external link is one-hop-away #226

@rdhyee

Description

@rdhyee

Problem

Two surfaces let you select a sample (map dot, table row), but their click semantics diverge — and the table-row case is internally inconsistent depending on which pixel you hit.

Current behavior (explorer.qmd @ commit a4f1155)

Map dot click (line ~1215): runs updateSampleCard(meta) → side panel updates → map flies to point. Never opens external link. ✅ Already the right model.

Table row click (line 1586-1588): inconsistent based on click target.

tr.addEventListener('click', async (e) => {
    if (e.target.tagName === 'A') return; // ← bleed-through
    // ... else updates side panel + flies map
});

The label is rendered as <a href={sourceUrl(pid)}>{label}</a> (line ~1558). So:

Click target inside the row Result
The title text (it's an <a>) Handler bails → browser follows link → external site opens
Lat cell, lon cell, place column, blank space Handler runs → side panel + map fly

That's not random — it's "click the underlined-blue title = leave the app, click anywhere else = update the app." The most-attractive click target does the least-useful thing.

Hover on map dot (line ~1196): a Cesium label tooltip showing just label || pid. No metadata. No thumbnail. No path to the rest of the record.

Proposed semantics

Click = open detail card. The external link to the source record (OpenContext, SESAR, etc.) is a one-hop-away action inside the card, never the default. This applies uniformly to map-dot click and table-row click.

This matches Hana's Figma mockup (node 222:456, card subnode 225:1700): the card title is the link to the external record — and the card is the click target's destination.

Scope for the companion PR

Two changes ship together:

Change 1 — Fix table-row link bleed-through (5 lines)

Either:

  • Remove the <a href> wrapper from the table title cell (link moves into the card), or
  • Replace if (e.target.tagName === 'A') return; with e.preventDefault(); e.stopPropagation(); so the title click bubbles to the row handler instead of navigating.

Change 2 — Build the in-map anchored detail card (Figma 222:456 / 225:1700)

  • Card anchored near the clicked dot, with viewport-edge collision avoidance.
  • Drop-shadow offset up-left (per Figma) so the card visually "points at" the dot it describes.
  • Title is a link to sourceUrl(pid) (target="_blank").
  • Source badge, material, sample feature, specimen type, lat/lon, thumbnail slot (placeholder when thumbnail_url is null — most samples won't have one yet).
  • Close (×) button. Decision deferred: keep side-panel card too (dual surface, one data source) or retire side-panel card in favor of the floating one as the canonical surface.

Deferred

Hover-card upgrade. Two paths:

  • (a) Keep current 1-line Cesium label — no flicker on dense clusters, works fine alongside click-to-open card.
  • (b) Hover shows a lightweight preview (thumbnail + label, dwell time, stickiness) — richer but introduces flicker/touch-device issues and competes visually with the click card.

Recommendation: (a) for v1; revisit as a separate, opinionated UX decision once the click-card lands.

Related

Acceptance

  • Clicking the title in a table row no longer opens the external site
  • Clicking anywhere in a table row opens the detail card with consistent behavior
  • Clicking a map dot opens the same detail card (in-map, anchored, with close button)
  • Detail card contains a one-click-away link to the original record (OpenContext / SESAR / etc.)
  • Pre-deploy smoke gate (ci: pre-deploy smoke gate (Option C) so a JS-dead render can't reach isamples.org #225) still passes — the new card surface participates in the world-search assertion path

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions