Skip to content

Commit

Permalink
fixup! Revert "Revert "feat(material/tooltip): add option to open too…
Browse files Browse the repository at this point in the history
…ltip at mouse position (angular#25202)" (angular#25430)"
  • Loading branch information
mmalerba committed Aug 10, 2022
1 parent 6231c16 commit 9e6479f
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 41 deletions.
39 changes: 14 additions & 25 deletions src/material/legacy-tooltip/tooltip.spec.ts
Expand Up @@ -237,7 +237,7 @@ describe('MatTooltip', () => {
TestBed.resetTestingModule()
.configureTestingModule({
imports: [MatLegacyTooltipModule, OverlayModule],
declarations: [WideTooltipDemo]
declarations: [WideTooltipDemo],
})
.compileComponents();

Expand All @@ -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);
}));

Expand Down Expand Up @@ -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.

Expand All @@ -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();
Expand All @@ -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);
Expand All @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -1474,16 +1463,16 @@ 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();
finishCurrentTooltipAnimation(overlayContainerElement, true);
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},
Expand Down
14 changes: 10 additions & 4 deletions src/material/tooltip/tooltip.spec.ts
Expand Up @@ -239,7 +239,7 @@ describe('MDC-based MatTooltip', () => {
TestBed.resetTestingModule()
.configureTestingModule({
imports: [MatTooltipModule, OverlayModule],
declarations: [WideTooltipDemo]
declarations: [WideTooltipDemo],
})
.compileComponents();

Expand All @@ -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(() => {
Expand Down Expand Up @@ -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);
}));

Expand Down
22 changes: 13 additions & 9 deletions src/material/tooltip/tooltip.ts
Expand Up @@ -407,7 +407,7 @@ export abstract class _MatTooltipBase<T extends _TooltipComponentBase>
}

/** 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 ||
Expand Down Expand Up @@ -442,7 +442,7 @@ export abstract class _MatTooltipBase<T extends _TooltipComponentBase>
}

/** 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);
}

Expand All @@ -452,10 +452,10 @@ export abstract class _MatTooltipBase<T extends _TooltipComponentBase>
}

/** 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;
Expand All @@ -471,7 +471,7 @@ export abstract class _MatTooltipBase<T extends _TooltipComponentBase>
// 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)
Expand Down Expand Up @@ -716,7 +716,11 @@ export abstract class _MatTooltipBase<T extends _TooltipComponentBase>
'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') {
Expand All @@ -725,8 +729,8 @@ export abstract class _MatTooltipBase<T extends _TooltipComponentBase>
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();
Expand Down
1 change: 1 addition & 0 deletions tools/public_api_guard/cdk/overlay.md
Expand Up @@ -184,6 +184,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
// (undocumented)
detach(): void;
dispose(): void;
_origin: FlexibleConnectedPositionStrategyOrigin;
positionChanges: Observable<ConnectedOverlayPositionChange>;
get positions(): ConnectionPositionPair[];
_preferredPositions: ConnectionPositionPair[];
Expand Down
16 changes: 13 additions & 3 deletions tools/public_api_guard/material/tooltip.md
Expand Up @@ -107,10 +107,19 @@ export abstract class _MatTooltipBase<T extends _TooltipComponentBase> 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<string> | {
[key: string]: any;
};
Expand All @@ -125,7 +134,7 @@ export abstract class _MatTooltipBase<T extends _TooltipComponentBase> implement
// (undocumented)
protected _viewportMargin: number;
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<_MatTooltipBase<any>, never, never, { "position": "matTooltipPosition"; "disabled": "matTooltipDisabled"; "showDelay": "matTooltipShowDelay"; "hideDelay": "matTooltipHideDelay"; "touchGestures": "matTooltipTouchGestures"; "message": "matTooltip"; "tooltipClass": "matTooltipClass"; }, {}, never, never, false>;
static ɵdir: i0.ɵɵDirectiveDeclaration<_MatTooltipBase<any>, 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<any>, never>;
}
Expand All @@ -135,6 +144,7 @@ export interface MatTooltipDefaultOptions {
disableTooltipInteractivity?: boolean;
hideDelay: number;
position?: TooltipPosition;
positionAtOrigin?: boolean;
showDelay: number;
touchendHideDelay: number;
touchGestures?: TooltipTouchGestures;
Expand Down

0 comments on commit 9e6479f

Please sign in to comment.