diff --git a/src/material/legacy-tooltip/tooltip.spec.ts b/src/material/legacy-tooltip/tooltip.spec.ts index e64798260154..b8c90ea7a4c0 100644 --- a/src/material/legacy-tooltip/tooltip.spec.ts +++ b/src/material/legacy-tooltip/tooltip.spec.ts @@ -237,7 +237,7 @@ describe('MatTooltip', () => { TestBed.resetTestingModule() .configureTestingModule({ imports: [MatLegacyTooltipModule, OverlayModule], - declarations: [WideTooltipDemo] + declarations: [WideTooltipDemo], }) .compileComponents(); @@ -254,8 +254,12 @@ describe('MatTooltip', () => { tick(); expect(tooltipDirective._isTooltipVisible()).toBe(true); - expect(tooltipDirective._overlayRef!.overlayElement.offsetLeft).toBeGreaterThan(triggerRect.left + 200); - expect(tooltipDirective._overlayRef!.overlayElement.offsetLeft).toBeLessThan(triggerRect.left + 300); + expect(tooltipDirective._overlayRef!.overlayElement.offsetLeft).toBeGreaterThan( + triggerRect.left + 200, + ); + expect(tooltipDirective._overlayRef!.overlayElement.offsetLeft).toBeLessThan( + triggerRect.left + 300, + ); expect(tooltipDirective._overlayRef!.overlayElement.offsetTop).toBe(triggerRect.bottom); })); @@ -1227,10 +1231,7 @@ describe('MatTooltip', () => { fixture.detectChanges(); const button: HTMLButtonElement = fixture.nativeElement.querySelector('button'); - const triggerRect = button.getBoundingClientRect(); - const offsetX = triggerRect.right - 10; - const offsetY = triggerRect.top + 10; - dispatchTouchEvent(button, 'touchstart', offsetX, offsetY, offsetX, offsetY); + dispatchFakeEvent(button, 'touchstart'); fixture.detectChanges(); tick(250); // Halfway through the delay. @@ -1249,10 +1250,7 @@ describe('MatTooltip', () => { fixture.detectChanges(); const button: HTMLButtonElement = fixture.nativeElement.querySelector('button'); - const triggerRect = button.getBoundingClientRect(); - const offsetX = triggerRect.right - 10; - const offsetY = triggerRect.top + 10; - dispatchTouchEvent(button, 'touchstart', offsetX, offsetY, offsetX, offsetY); + dispatchFakeEvent(button, 'touchstart'); fixture.detectChanges(); tick(500); // Finish the delay. fixture.detectChanges(); @@ -1265,10 +1263,7 @@ describe('MatTooltip', () => { const fixture = TestBed.createComponent(BasicTooltipDemo); fixture.detectChanges(); const button: HTMLButtonElement = fixture.nativeElement.querySelector('button'); - const triggerRect = button.getBoundingClientRect(); - const offsetX = triggerRect.right - 10; - const offsetY = triggerRect.top + 10; - const event = dispatchTouchEvent(button, 'touchstart', offsetX, offsetY, offsetX, offsetY); + const event = dispatchFakeEvent(button, 'touchstart'); fixture.detectChanges(); expect(event.defaultPrevented).toBe(false); @@ -1279,10 +1274,7 @@ describe('MatTooltip', () => { fixture.detectChanges(); const button: HTMLButtonElement = fixture.nativeElement.querySelector('button'); - const triggerRect = button.getBoundingClientRect(); - const offsetX = triggerRect.right - 10; - const offsetY = triggerRect.top + 10; - dispatchTouchEvent(button, 'touchstart', offsetX, offsetY, offsetX, offsetY); + dispatchFakeEvent(button, 'touchstart'); fixture.detectChanges(); tick(500); // Finish the open delay. fixture.detectChanges(); @@ -1306,10 +1298,7 @@ describe('MatTooltip', () => { fixture.detectChanges(); const button: HTMLButtonElement = fixture.nativeElement.querySelector('button'); - const triggerRect = button.getBoundingClientRect(); - const offsetX = triggerRect.right - 10; - const offsetY = triggerRect.top + 10; - dispatchTouchEvent(button, 'touchstart', offsetX, offsetY, offsetX, offsetY); + dispatchFakeEvent(button, 'touchstart'); fixture.detectChanges(); tick(500); // Finish the open delay. fixture.detectChanges(); @@ -1474,9 +1463,8 @@ describe('MatTooltip', () => { const fixture = TestBed.createComponent(BasicTooltipDemo); fixture.detectChanges(); const button: HTMLButtonElement = fixture.nativeElement.querySelector('button'); - const triggerRect = button.getBoundingClientRect(); - dispatchMouseEvent(button, 'mouseenter', triggerRect.right - 10, triggerRect.top + 10); + dispatchFakeEvent(button, 'mouseenter'); fixture.detectChanges(); tick(500); // Finish the open delay. fixture.detectChanges(); @@ -1484,6 +1472,7 @@ describe('MatTooltip', () => { assertTooltipInstance(fixture.componentInstance.tooltip, true); // Simulate the pointer over the trigger. + const triggerRect = button.getBoundingClientRect(); const wheelEvent = createFakeEvent('wheel'); Object.defineProperties(wheelEvent, { clientX: {get: () => triggerRect.left + 1}, diff --git a/src/material/tooltip/tooltip.spec.ts b/src/material/tooltip/tooltip.spec.ts index c44feb0266ce..d2b88c27cb9b 100644 --- a/src/material/tooltip/tooltip.spec.ts +++ b/src/material/tooltip/tooltip.spec.ts @@ -239,7 +239,7 @@ describe('MDC-based MatTooltip', () => { TestBed.resetTestingModule() .configureTestingModule({ imports: [MatTooltipModule, OverlayModule], - declarations: [WideTooltipDemo] + declarations: [WideTooltipDemo], }) .compileComponents(); @@ -256,8 +256,12 @@ describe('MDC-based MatTooltip', () => { tick(); expect(tooltipDirective._isTooltipVisible()).toBe(true); - expect(tooltipDirective._overlayRef!.overlayElement.offsetLeft).toBeLessThan(triggerRect.right - 250); - expect(tooltipDirective._overlayRef!.overlayElement.offsetTop).toBeGreaterThanOrEqual(triggerRect.bottom); + expect(tooltipDirective._overlayRef!.overlayElement.offsetLeft).toBeLessThan( + triggerRect.right - 250, + ); + expect(tooltipDirective._overlayRef!.overlayElement.offsetTop).toBeGreaterThanOrEqual( + triggerRect.bottom, + ); })); it('should be able to override the default positionAtOrigin', fakeAsync(() => { @@ -287,7 +291,9 @@ describe('MDC-based MatTooltip', () => { tick(); expect(tooltipDirective._isTooltipVisible()).toBe(true); - expect(tooltipDirective._overlayRef!.overlayElement.offsetLeft).toBe(triggerRect.right - 100 - 20); + expect(tooltipDirective._overlayRef!.overlayElement.offsetLeft).toBe( + triggerRect.right - 100 - 20, + ); expect(tooltipDirective._overlayRef!.overlayElement.offsetTop).toBe(triggerRect.top + 100); })); diff --git a/src/material/tooltip/tooltip.ts b/src/material/tooltip/tooltip.ts index c0dfeda735c0..806e8b181675 100644 --- a/src/material/tooltip/tooltip.ts +++ b/src/material/tooltip/tooltip.ts @@ -407,7 +407,7 @@ export abstract class _MatTooltipBase } /** Shows the tooltip after the delay in ms, defaults to tooltip-delay-show or 0ms if no input */ - show(delay: number = this.showDelay, origin?: { x: number, y: number }): void { + show(delay: number = this.showDelay, origin?: {x: number; y: number}): void { if ( this.disabled || !this.message || @@ -442,7 +442,7 @@ export abstract class _MatTooltipBase } /** Shows/hides the tooltip */ - toggle(origin?: { x: number; y: number; }): void { + toggle(origin?: {x: number; y: number}): void { this._isTooltipVisible() ? this.hide() : this.show(undefined, origin); } @@ -452,10 +452,10 @@ export abstract class _MatTooltipBase } /** Create the overlay config and position strategy */ - private _createOverlay(origin?: { x: number; y: number; }): OverlayRef { + private _createOverlay(origin?: {x: number; y: number}): OverlayRef { if (this._overlayRef) { - const existingStrategy = - this._overlayRef.getConfig().positionStrategy as FlexibleConnectedPositionStrategy; + const existingStrategy = this._overlayRef.getConfig() + .positionStrategy as FlexibleConnectedPositionStrategy; if ((!this.positionAtOrigin || !origin) && existingStrategy._origin instanceof ElementRef) { return this._overlayRef; @@ -471,7 +471,7 @@ export abstract class _MatTooltipBase // Create connected position strategy that listens for scroll events to reposition. const strategy = this._overlay .position() - .flexibleConnectedTo(this.positionAtOrigin ? (origin || this._elementRef) : this._elementRef) + .flexibleConnectedTo(this.positionAtOrigin ? origin || this._elementRef : this._elementRef) .withTransformOriginOn(`.${this._cssClassPrefix}-tooltip`) .withFlexibleDimensions(false) .withViewportMargin(this._viewportMargin) @@ -716,7 +716,11 @@ export abstract class _MatTooltipBase 'mouseenter', event => { this._setupPointerExitEventsIfNeeded(); - this.show(undefined, { x: (event as MouseEvent).x, y: (event as MouseEvent).y }); + let point = undefined; + if ((event as MouseEvent).x !== undefined && (event as MouseEvent).y !== undefined) { + point = event as MouseEvent; + } + this.show(undefined, point); }, ]); } else if (this.touchGestures !== 'off') { @@ -725,8 +729,8 @@ export abstract class _MatTooltipBase this._passiveListeners.push([ 'touchstart', event => { - const touch = (event as TouchEvent).targetTouches[0]; - const origin = touch ? { x: touch.clientX, y: touch.clientY } : undefined; + const touch = (event as TouchEvent).targetTouches?.[0]; + const origin = touch ? {x: touch.clientX, y: touch.clientY} : undefined; // Note that it's important that we don't `preventDefault` here, // because it can prevent click events from firing on the element. this._setupPointerExitEventsIfNeeded(); diff --git a/tools/public_api_guard/cdk/overlay.md b/tools/public_api_guard/cdk/overlay.md index a2ccaee9a40d..31371ac3d2db 100644 --- a/tools/public_api_guard/cdk/overlay.md +++ b/tools/public_api_guard/cdk/overlay.md @@ -184,6 +184,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy { // (undocumented) detach(): void; dispose(): void; + _origin: FlexibleConnectedPositionStrategyOrigin; positionChanges: Observable; get positions(): ConnectionPositionPair[]; _preferredPositions: ConnectionPositionPair[]; diff --git a/tools/public_api_guard/material/tooltip.md b/tools/public_api_guard/material/tooltip.md index 531b85e0e7ea..7dba5dde8140 100644 --- a/tools/public_api_guard/material/tooltip.md +++ b/tools/public_api_guard/material/tooltip.md @@ -107,10 +107,19 @@ export abstract class _MatTooltipBase implement _overlayRef: OverlayRef | null; get position(): TooltipPosition; set position(value: TooltipPosition); - show(delay?: number): void; + // (undocumented) + get positionAtOrigin(): boolean; + set positionAtOrigin(value: BooleanInput); + show(delay?: number, origin?: { + x: number; + y: number; + }): void; get showDelay(): number; set showDelay(value: NumberInput); - toggle(): void; + toggle(origin?: { + x: number; + y: number; + }): void; get tooltipClass(): string | string[] | Set | { [key: string]: any; }; @@ -125,7 +134,7 @@ export abstract class _MatTooltipBase implement // (undocumented) protected _viewportMargin: number; // (undocumented) - static ɵdir: i0.ɵɵDirectiveDeclaration<_MatTooltipBase, never, never, { "position": "matTooltipPosition"; "disabled": "matTooltipDisabled"; "showDelay": "matTooltipShowDelay"; "hideDelay": "matTooltipHideDelay"; "touchGestures": "matTooltipTouchGestures"; "message": "matTooltip"; "tooltipClass": "matTooltipClass"; }, {}, never, never, false>; + static ɵdir: i0.ɵɵDirectiveDeclaration<_MatTooltipBase, never, never, { "position": "matTooltipPosition"; "positionAtOrigin": "matTooltipPositionAtOrigin"; "disabled": "matTooltipDisabled"; "showDelay": "matTooltipShowDelay"; "hideDelay": "matTooltipHideDelay"; "touchGestures": "matTooltipTouchGestures"; "message": "matTooltip"; "tooltipClass": "matTooltipClass"; }, {}, never, never, false>; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration<_MatTooltipBase, never>; } @@ -135,6 +144,7 @@ export interface MatTooltipDefaultOptions { disableTooltipInteractivity?: boolean; hideDelay: number; position?: TooltipPosition; + positionAtOrigin?: boolean; showDelay: number; touchendHideDelay: number; touchGestures?: TooltipTouchGestures;