Replace native title tooltips with nldd-tooltip #259
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "tooltips-replace-native-title"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #197.
A native
titlenever fires on keyboard focus, is unreachable on touch and isannounced inconsistently, so every hint sitting on one was mouse-only.
I re-measured rather than working from the issue's inventory, which was written
before the big NLDD/retention merge and no longer matches the tree.
titleturns out to be three different things here, and only one of them is a tooltip.
What changed
Nine controls now wrap in
nldd-tooltip- it shows on hover and focus,suppresses itself on touch, renders in the top layer (so
overflow: hiddennolonger clips it) and sets
aria-describedbyitself:QueuedRowretry / restoreSendButtonprimarySendButtonchevronBubbleMenuButtonCardRowbubble tagAttachmentPreviewdownloadAttachmentChipListDevUserSwitcherSixteen titles are dropped, not restyled. They repeated the accessible name
(
aria-label/accessible-label) or the visible label. A descriptionidentical to the name makes a screen reader say the same thing twice, so
re-adding it as a tooltip would have been a regression, not a fix.
Four titles stay native on purpose, each with a comment so a later sweep
does not "finish the job":
<iframe title>s are accessible names (WCAG 4.1.2), not tooltips.Deleting them would have been the one genuinely harmful edit in this diff.
MmSourceBreadcrumbchannel names only reveal CSS ellipsis overflowof a string that is already the link's accessible name. A keyboard or screen
reader user loses nothing, and a tooltip per card row costs a custom element
per row for a purely visual reveal.
Two things worth a second opinion
SendButtongave up its hand-rolledaria-describedby. It had avisually-hidden span +
useIdcarrying the disabled reason.nldd-tooltipoverwrites
aria-describedbyon its trigger and removes the attribute whenthe text empties (
tooltip.js:163-202), so the two cannot coexist - it wouldhave silently deleted the existing wiring. The component now owns it. The cost:
the unit test can no longer verify the wiring end to end (the tag is a bare stub
in happy-dom), so it asserts we hand the right text to the tooltip and that it
wraps the chevron specifically. Verified in a real browser instead.
nldd-tooltipparks its description span ondocument.body, one perinstance, outside every landmark. That tripped the axe
regionrule inlandmarks.spec.ts, which now excludes those spans (the selector was checked tomatch only body-level tooltip spans and nothing inside
<main>). On a fullinbox this is ~46 spans, one per card's bubble-up button. Worth a short note
upstream to MinBZK/storybook - happy to file it if you agree.
Verification
npm run typecheck,npm run build, eslint: cleanand fixed, not waved through)
and that
aria-describedbyresolves to the right textNot verified by eye: the
CardRowbubble-up tag tooltip - the seed has nobubbled card and I could not cheaply reach that state. It is the same mechanism
proven on the other eight.
Three follow-up commits on this branch, after review feedback.
c4107ba- the send hint names the key your platform actually uses."⌘/Ctrl + Enter" was a menu of possibilities rather than an instruction.
ShortcutHelpalready resolved the real modifier, so that moved tolib/platform.tsand both use it: Cmd on Apple platforms, Ctrl on Windows andLinux. On a touch device the hint is dropped entirely - a phone cannot act on a
key combination, and an empty text is what makes
nldd-tooltipsuppress thepopover and its
aria-describedbytogether (checked in the browser: thedescription span is removed, not orphaned). Same
(pointer: coarse)query thecomponent uses to suppress itself, so the visual and the announced stay in step.
Nine unit tests, including Linux and the Android "Linux armv8l" platform string
that must not match
/mac/.a7ecefc- two more tooltips, and ten deliberate refusals.Swept all 62 hand-rolled
<button>/<a>elements. Twelve are icon-only with anaria-label. Two got a tooltip: the breadcrumb ellipsis and thesmiling-face-with-plus that adds a reaction - glyphs nobody can be expected to
read. The other ten are close crosses, lightbox arrows and image thumbnails,
where the glyph is conventional or the thumbnail is its own label, and where a
description identical to the accessible name only makes a screen reader repeat
itself. Three of those ten are the very titles this branch removed for that
reason.
Worth knowing for anything similar later:
nldd-icon-buttondoes not facethat trade. It renders the same tooltip from
accessible-label(
icon-button.template.js:37), but itsaria-describedbycannot cross its ownshadow boundary, so the duplication never reaches assistive tech. That makes
converting the remaining hand-rolled close buttons to
nldd-icon-buttonabetter move than wrapping them - it buys the visual tooltip without the double
announcement. Not done here; it is a refactor, not a tooltip change.
One thing that surfaced while checking: several
nldd-icon-buttons carry adescription inside their name, e.g.
accessible-label="Bewerken (annuleert planning + zet als concept klaar in de kaart)". A screen reader announces that whole parenthetical as the button'sname, and the component has no separate tooltip prop to split them. Shortening
it trades the explanation for a clean name - a copy decision, so it is left
alone.
Gates after all three: typecheck, build, eslint 0 errors, vitest 711, e2e 67
passed / 0 failed.
1fb9ac2295f9a8c65d56f9a8c65d568e253a6651