Skip to content

[Bug] Timestamp's hover-card popup attributes sit on the Text span, not the focusable <time> #5497

Description

@cixzhang

Found while fixing the release-blocking aria-allowed-attr regression in #5501. Split out because it is not a regression — it predates that change and is a different defect.

What happens

A Timestamp with a hover card puts its tab stop on the inner <time> (Timestamp.tsx:550, added so keyboard users can reveal the card at all), but the HoverCard trigger — and therefore every ARIA attribute expressing the popup relationship — is the Text <span> wrapping that <time>.

HoverCard takes wrapper.firstElementChild as its trigger (HoverCard.tsx:254), and Timestamp's HoverCard child is <Text>, which renders a <span> (Text.tsx:240). So the DOM is:

<span class="astryx-text … astryx-timestamp" aria-haspopup="dialog" aria-controls="">  ← trigger
  <time datetime="" tabindex="0" aria-label="">2 hours ago</time>                     ← tab stop
</span>

A screen-reader user who tabs to a timestamp lands on the <time>. The <time> says nothing about a dialog; the element that does is its parent, which the user never lands on. So the card is reachable by keyboard but its existence is never announced.

Why it is not new

Before #5419 the same span carried aria-describedby instead, with exactly the same mismatch. This has been true since the <time> tab stop was introduced.

Possible directions

Neither is obviously right, hence an issue rather than a PR:

  1. Make the <time> the HoverCard's first element child — nest the HoverCard inside Text instead of outside it. HoverCard's wrapper is display: contents, so this should be layout-neutral, but it moves the positioning anchor from the span to the <time> and wants a visual check.
  2. Teach HoverCard to prefer a focusable descendant as its trigger when the first element child is not focusable. Correct for every consumer at once, but a much wider blast radius.

Worth noting Timestamp is currently the only component in the repo that passes label to a HoverCard, so today this affects Timestamp alone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions