Skip to content

[tooltip] Fix disabled prop on Triggers - #4049

Merged
michaldudak merged 5 commits into
mui:masterfrom
michaldudak:disabled-tooltips-fix
Feb 12, 2026
Merged

[tooltip] Fix disabled prop on Triggers#4049
michaldudak merged 5 commits into
mui:masterfrom
michaldudak:disabled-tooltips-fix

Conversation

@michaldudak

@michaldudak michaldudak commented Feb 11, 2026

Copy link
Copy Markdown
Member

This PR fixes tooltip behavior for detached triggers when moving between enabled/disabled triggers, and unifies the logic across hover and focus interactions.

What changed

  • Introduced a shared enabled-trigger check (isTargetInsideEnabledTrigger) used by hover and focus logic.
  • Updated hover handling so switching to a trigger marked with data-trigger-disabled no longer keeps the previous popup open.
  • Updated focus handling with the same rule, so focusing a disabled trigger closes an already-open tooltip.
  • Kept support for rendered native disabled buttons as valid triggers when the trigger itself is enabled.

Tests

Added tooltip detached-trigger regressions for:

  • hover to disabled trigger closes,
  • focus to disabled trigger closes,
  • rendered disabled button still switches/opens when trigger hover is enabled.

Result

Detached trigger behavior is now consistent and predictable:

  • Disabled triggers do not participate in hover/focus switching.
  • Enabled triggers rendered as disabled buttons still behave correctly.

Closes #3468

Preview

https://deploy-preview-4049--base-ui.netlify.app/experiments/tooltip/disabled

@michaldudak michaldudak added type: bug It doesn't behave as expected. component: tooltip Changes related to the tooltip component. labels Feb 11, 2026
@pkg-pr-new

pkg-pr-new Bot commented Feb 11, 2026

Copy link
Copy Markdown

commit: 078fced

@mui-bot

mui-bot commented Feb 11, 2026

Copy link
Copy Markdown

Bundle size report

Bundle Parsed size Gzip size
@base-ui/react 🔺+199B(+0.05%) 🔺+76B(+0.06%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@greptile-apps

greptile-apps Bot commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Overview

Greptile Summary

This PR fixes tooltip behavior for detached triggers by ensuring disabled triggers don't participate in hover/focus switching. The implementation introduces a shared isTargetInsideEnabledTrigger helper that checks for the data-trigger-disabled attribute, unifying the logic across hover and focus interactions.

Key changes:

  • Added data-trigger-disabled attribute to disabled triggers
  • Refactored useFocus, useHoverReferenceInteraction, and useHoverFloatingInteraction to use the new helper
  • Disabled triggers now properly close tooltips when focused/hovered instead of keeping them open
  • Enabled triggers rendered as disabled buttons still work correctly
  • Added comprehensive test coverage for all scenarios

The implementation is clean and well-tested. The logic correctly distinguishes between the trigger's disabled state (controlled by the disabled prop) and the rendered element's disabled state (e.g., a native disabled button).

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The implementation is well-designed with a clean separation of concerns. The new isTargetInsideEnabledTrigger helper centralizes the logic for checking enabled triggers, and all three interaction hooks consistently use it. The PR includes comprehensive test coverage for all scenarios (focus to disabled, hover to disabled, and rendered disabled buttons), and the logic correctly handles the distinction between trigger disabled state and rendered element disabled state. No issues found.
  • No files require special attention

Important Files Changed

Filename Overview
packages/react/src/floating-ui-react/utils/element.ts Adds isTargetInsideEnabledTrigger helper function to check if target is within enabled trigger, distinguishing between enabled and disabled triggers using data-trigger-disabled attribute
packages/react/src/tooltip/trigger/TooltipTrigger.tsx Adds data-trigger-disabled attribute to trigger elements when disabled, enabling the new enabled-trigger check logic
packages/react/src/floating-ui-react/hooks/useFocus.ts Refactors focus logic to use isTargetInsideEnabledTrigger instead of simple trigger checks, ensuring disabled triggers don't participate in focus switching
packages/react/src/floating-ui-react/hooks/useHoverReferenceInteraction.ts Refactors hover logic to use isTargetInsideEnabledTrigger, adds early return when enabled is false, ensuring disabled triggers don't participate in hover switching
packages/react/src/floating-ui-react/hooks/useHoverFloatingInteraction.ts Refactors floating element hover logic to use isTargetInsideEnabledTrigger for consistency with reference interaction
packages/react/src/tooltip/root/TooltipRoot.detached-triggers.test.tsx Adds comprehensive test coverage for disabled trigger behavior including focus, hover, and native disabled button scenarios

@netlify

netlify Bot commented Feb 11, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 078fced
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/698db34ddbf02a000821410e
😎 Deploy Preview https://deploy-preview-4049--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

"disabled": {
"type": "boolean",
"default": "false",
"description": "Whether the trigger is disabled. If `true`, the tooltip will not open when interacting with this trigger.\nNote that this doesn't apply the `disabled` attribute to the trigger element.\nIf you want to disable the trigger element itself, you can pass the `disabled` prop to the trigger element via the `render` prop.",

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.

"Whether the trigger is disabled" should probably be updated

Comment on lines +57 to +61
for (const [, trigger] of triggerElements.entries()) {
if (contains(trigger, targetElement)) {
return !trigger.hasAttribute('data-trigger-disabled');
}
}

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.

triggerElements.values()?

@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Feb 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: tooltip Changes related to the tooltip component. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[tooltip] Allow disabling a Tooltip.Trigger when using detached triggers

3 participants