Let a tooltip linger, and tell the screen reader what it says

A plain tooltip vanished the instant the pointer left, where M3 keeps one for
1.5s and shows only one at a time — these are popover="manual", so nothing was
closing the last one. A rich tooltip's bubble was never associated with its
trigger at all, so the explanation it exists to give was never announced; the
script now writes aria-describedby (and aria-haspopup/aria-expanded when it is
persistent) onto the focusable control in the trigger slot, and again after a
morph. Plan step 18, actions.md ACT-22, ACT-25.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold
2026-09-14 06:13:14 +02:00
co-authored by Claude Opus 5
parent 56d82b71f3
commit 05236ecb3a
5 changed files with 77 additions and 19 deletions
@@ -15,6 +15,12 @@
action's `wire:click` too and resources/js/rich-tooltip.js keeps showing and hiding the
element on the page rather than one the morph took away.
resources/js/rich-tooltip.js points the trigger at the bubble with `aria-describedby`, and a
`persistent` one also carries `aria-haspopup="dialog"` and `aria-expanded`: the explanation is
the whole point of a rich tooltip, and without the association a screen reader reads only the
trigger's own label. The trigger arrives in a slot, so only script can find the element in it
that takes the focus.
RichTooltipTokens (androidx Compose Material 3, Apache-2.0): title-small subhead and body-medium
text in on-surface-variant, label-large actions in primary. --}}