Skip to content

Commit 236762f

Browse files
authored
fix(material/tooltip): allow hover detection logic to be customized (#33018)
Expands the type of `detectHoverCapability` to allow users to customize the logic.
1 parent 43320d4 commit 236762f

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

goldens/material/tooltip/index.api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
9292

9393
// @public
9494
export interface MatTooltipDefaultOptions {
95-
detectHoverCapability?: boolean;
95+
detectHoverCapability?: boolean | (() => boolean);
9696
disableTooltipInteractivity?: boolean;
9797
hideDelay: number;
9898
position?: TooltipPosition;

src/material/tooltip/tooltip.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,23 @@ export interface MatTooltipDefaultOptions {
140140
tooltipClass?: string | string[];
141141

142142
/**
143-
* Whether the tooltip should use a media query to detect if the device is able to hover.
144-
* Note that this may affect tests that run in a headless browser which reports that it's
145-
* unable to hover. In such cases you may need to include an additional timeout, because
146-
* the tooltip will fall back to treating the device as a touch screen.
143+
* By default the tooltip attempts to detect whether the user's device is able to hover by
144+
* consulting the `Platform` provider that was created a long time ago and is based on
145+
* some data points that may not be entirely accurate anymore (e.g. user agent string and
146+
* Android/iOS-specific APIs), however changing them will break existing users. You can use this
147+
* config property to opt into a more modern detection mechanism.
148+
*
149+
* The supported values include:
150+
*
151+
* - `false` - Default value. Detection is based on the `Platform` provider.
152+
* - `true` - The tooltip will use the `any-hover` media query for more accurate detection.
153+
* Note that this may break existing unit tests running in a headless browser.
154+
* - `() => boolean` - If the automatic detection doesn't work properly in your case (e.g. the
155+
* `any-hover` media query isn't supported) and you're able to detect more accurately, you can
156+
* pass in a function that will be used for detection instead. It should return `true` if the
157+
* device **has the ability to hover**, or `false` if it cannot.
147158
*/
148-
detectHoverCapability?: boolean;
159+
detectHoverCapability?: boolean | (() => boolean);
149160
}
150161

151162
/**
@@ -855,6 +866,12 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
855866
}
856867

857868
private _isTouchPlatform(): boolean {
869+
const detectHoverCapability = this._defaultOptions?.detectHoverCapability;
870+
871+
if (typeof detectHoverCapability === 'function') {
872+
return !detectHoverCapability();
873+
}
874+
858875
if (this._platform.IOS || this._platform.ANDROID) {
859876
// If we detected iOS or Android, it's definitely supported.
860877
return true;
@@ -863,10 +880,7 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
863880
return false;
864881
}
865882

866-
return (
867-
!!this._defaultOptions?.detectHoverCapability &&
868-
this._mediaMatcher.matchMedia('(any-hover: none)').matches
869-
);
883+
return !!detectHoverCapability && this._mediaMatcher.matchMedia('(any-hover: none)').matches;
870884
}
871885

872886
/** Disables the native browser gestures, based on how the tooltip has been configured. */

0 commit comments

Comments
 (0)