Skip to content

fix: close tooltips with Escape - #119

Open
Arthurk12 wants to merge 6 commits into
bigbluebutton:developfrom
Arthurk12:fix/tooltip-escape
Open

Arthurk12 wants to merge 6 commits into
bigbluebutton:developfrom
Arthurk12:fix/tooltip-escape

Conversation

@Arthurk12

@Arthurk12 Arthurk12 commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

What does this PR do?

Tooltips on BBButton, BBBAccordion and BBBAvatar now close when Escape is pressed, without moving the pointer or focus.

  • Pressing Escape while a tooltip is shown hides it; it shows again on the next hover or focus.
  • Covers the tooltipLabel tooltip of BBButton and BBBAccordion and the name tooltip of BBBAvatar.
  • The Escape key press still reaches the app, so a modal that closes on Escape closes together with the tooltip.

Motivation

A tooltip can cover nearby content, and the only way to close it is to move the pointer or focus away, which falls short of WCAG 1.4.13 (Content on Hover or Focus).

More

@Arthurk12
Arthurk12 changed the base branch from main to develop November 10, 2026 19:40

@germanocaumo germanocaumo 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.

Checked BBButton (default and circle), BBBAccordion and BBBAvatar in Chromium, Firefox and WebKit: Escape hides the tooltip on hover and focus, focus stays, it comes back on the next hover or focus, and the listener is removed on hide and unmount. BBBSlider's value label doesn't close on Escape either; it could join the Checkbox/Toggle follow-up.

Comment thread src/utils/tooltip.ts Resolved
A BBButton tooltip shown on hover or keyboard focus can only be closed
by moving the pointer away or moving focus elsewhere. It can cover
nearby content, and WCAG 1.4.13 (Content on Hover or Focus) requires
such content to be dismissible without moving the pointer or focus.

Add a shared Tippy plugin, `hideOnEsc`, that hides the tooltip when
Escape is pressed, and pass it to the button's Tippy. The `keydown`
listener is added to the document only while the tooltip is shown and
removed when it hides or is destroyed. The tooltip shows again on the
next hover or focus. The plugin lives in `src/utils/tooltip.ts` so
every component with a Tippy tooltip can use it.

The listener runs in the capture phase, so the tooltip also hides
when an Escape is stopped before it reaches the document, as
react-modal does for BBBModal with `shouldCloseOnEsc`, or by a
focused input that handles it. The event itself is not stopped:
stopping it would hide it from the consumer's own handlers while a
tooltip is shown.
The header tooltip of BBBAccordion can only be closed by moving the
pointer away or moving focus elsewhere, which falls short of WCAG
1.4.13 (Content on Hover or Focus).

Pass the shared `hideOnEsc` plugin to its Tippy, as BBButton does, so
Escape hides the tooltip.
The name tooltip of BBBAvatar can only be closed by moving the pointer
away, which falls short of WCAG 1.4.13 (Content on Hover or Focus).

Pass the shared `hideOnEsc` plugin to its Tippy, as BBButton does, so
Escape hides the tooltip.
The tooltip of BBBCheckbox can only be closed by moving the pointer
away or moving focus elsewhere, which falls short of WCAG 1.4.13
(Content on Hover or Focus).

Pass the shared `hideOnEsc` plugin to its Tippy, as BBButton does, so
Escape hides the tooltip.
The tooltip of BBBToggle can only be closed by moving the pointer
away or moving focus elsewhere, which falls short of WCAG 1.4.13
(Content on Hover or Focus).

Pass the shared `hideOnEsc` plugin to its Tippy, as BBButton does, so
Escape hides the tooltip.
The value label of BBBSlider, shown on hover, focus or drag when
`valueLabelDisplay` is 'auto', can only be closed by moving the
pointer away or moving focus elsewhere, which falls short of WCAG
1.4.13 (Content on Hover or Focus).

MUI's Slider renders the label and keeps its open state internal,
with no Escape handling, so the shared `hideOnEsc` Tippy plugin
cannot be used. Render the label through a `valueLabel` slot that
closes it on Escape and opens it again on the next hover or focus.
As in `hideOnEsc`, the listener is added to the document in the
capture phase only while the label is open, and the event is not
stopped. A label shown at all times ('on') is not hover content and
stays. A consumer's own `slots.valueLabel` still takes precedence.

This branch has not been deployed

No deployments
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.

2 participants