Skip to content

Commit bd62f98

Browse files
crisbetojelbourn
authored andcommitted
fix(tabs): don't start auto-scroll when right clicking on buttons (#18033)
Currently we use `mousedown` to figure out when to start auto-scrolling the tab header, but the event is also dispatched for right clicks. This can be weird, because accidental right clicks that open the system dropdown can start scrolling without being able to stop it easily. These changes make it so we only start for left button clicks.
1 parent 8d57d32 commit bd62f98

File tree

7 files changed

+37
-9
lines changed

7 files changed

+37
-9
lines changed

src/material-experimental/mdc-tabs/tab-header.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[matRippleDisabled]="_disableScrollBefore || disableRipple"
77
[class.mat-mdc-tab-header-pagination-disabled]="_disableScrollBefore"
88
(click)="_handlePaginatorClick('before')"
9-
(mousedown)="_handlePaginatorPress('before')"
9+
(mousedown)="_handlePaginatorPress('before', $event)"
1010
(touchend)="_stopInterval()">
1111
<div class="mat-mdc-tab-header-pagination-chevron"></div>
1212
</div>
@@ -31,7 +31,7 @@
3131
mat-ripple
3232
[matRippleDisabled]="_disableScrollAfter || disableRipple"
3333
[class.mat-mdc-tab-header-pagination-disabled]="_disableScrollAfter"
34-
(mousedown)="_handlePaginatorPress('after')"
34+
(mousedown)="_handlePaginatorPress('after', $event)"
3535
(click)="_handlePaginatorClick('after')"
3636
(touchend)="_stopInterval()">
3737
<div class="mat-mdc-tab-header-pagination-chevron"></div>

src/material-experimental/mdc-tabs/tab-header.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
dispatchKeyboardEvent,
88
createKeyboardEvent,
99
dispatchEvent,
10+
createMouseEvent,
1011
} from '@angular/cdk/testing/private';
1112
import {CommonModule} from '@angular/common';
1213
import {Component, ViewChild} from '@angular/core';
@@ -458,6 +459,16 @@ describe('MDC-based MatTabHeader', () => {
458459
expect(header.scrollDistance).toBe(previousDistance);
459460
}));
460461

462+
it('should not scroll when pressing the right mouse button', fakeAsync(() => {
463+
expect(header.scrollDistance).toBe(0, 'Expected to start off not scrolled.');
464+
465+
dispatchEvent(nextButton, createMouseEvent('mousedown', undefined, undefined, 2));
466+
fixture.detectChanges();
467+
tick(3000);
468+
469+
expect(header.scrollDistance).toBe(0, 'Expected not to have scrolled after a while.');
470+
}));
471+
461472
/**
462473
* Asserts that auto scrolling using the next button works.
463474
* @param startEventName Name of the event that is supposed to start the scrolling.

src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
mat-ripple [matRippleDisabled]="_disableScrollBefore || disableRipple"
66
[class.mat-mdc-tab-header-pagination-disabled]="_disableScrollBefore"
77
(click)="_handlePaginatorClick('before')"
8-
(mousedown)="_handlePaginatorPress('before')"
8+
(mousedown)="_handlePaginatorPress('before', $event)"
99
(touchend)="_stopInterval()">
1010
<div class="mat-mdc-tab-header-pagination-chevron"></div>
1111
</div>
@@ -24,7 +24,7 @@
2424
aria-hidden="true"
2525
mat-ripple [matRippleDisabled]="_disableScrollAfter || disableRipple"
2626
[class.mat-mdc-tab-header-pagination-disabled]="_disableScrollAfter"
27-
(mousedown)="_handlePaginatorPress('after')"
27+
(mousedown)="_handlePaginatorPress('after', $event)"
2828
(click)="_handlePaginatorClick('after')"
2929
(touchend)="_stopInterval()">
3030
<div class="mat-mdc-tab-header-pagination-chevron"></div>

src/material/tabs/paginated-tab-header.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,13 @@ export abstract class MatPaginatedTabHeader implements AfterContentChecked, Afte
549549
* Starts scrolling the header after a certain amount of time.
550550
* @param direction In which direction the paginator should be scrolled.
551551
*/
552-
_handlePaginatorPress(direction: ScrollDirection) {
552+
_handlePaginatorPress(direction: ScrollDirection, mouseEvent?: MouseEvent) {
553+
// Don't start auto scrolling for right mouse button clicks. Note that we shouldn't have to
554+
// null check the `button`, but we do it so we don't break tests that use fake events.
555+
if (mouseEvent && mouseEvent.button != null && mouseEvent.button !== 0) {
556+
return;
557+
}
558+
553559
// Avoid overlapping timers.
554560
this._stopInterval();
555561

src/material/tabs/tab-header.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
mat-ripple [matRippleDisabled]="_disableScrollBefore || disableRipple"
55
[class.mat-tab-header-pagination-disabled]="_disableScrollBefore"
66
(click)="_handlePaginatorClick('before')"
7-
(mousedown)="_handlePaginatorPress('before')"
7+
(mousedown)="_handlePaginatorPress('before', $event)"
88
(touchend)="_stopInterval()">
99
<div class="mat-tab-header-pagination-chevron"></div>
1010
</div>
@@ -28,7 +28,7 @@
2828
aria-hidden="true"
2929
mat-ripple [matRippleDisabled]="_disableScrollAfter || disableRipple"
3030
[class.mat-tab-header-pagination-disabled]="_disableScrollAfter"
31-
(mousedown)="_handlePaginatorPress('after')"
31+
(mousedown)="_handlePaginatorPress('after', $event)"
3232
(click)="_handlePaginatorClick('after')"
3333
(touchend)="_stopInterval()">
3434
<div class="mat-tab-header-pagination-chevron"></div>

src/material/tabs/tab-header.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
dispatchKeyboardEvent,
88
createKeyboardEvent,
99
dispatchEvent,
10+
createMouseEvent,
1011
} from '@angular/cdk/testing/private';
1112
import {CommonModule} from '@angular/common';
1213
import {Component, ViewChild} from '@angular/core';
@@ -458,6 +459,16 @@ describe('MatTabHeader', () => {
458459
expect(header.scrollDistance).toBe(previousDistance);
459460
}));
460461

462+
it('should not scroll when pressing the right mouse button', fakeAsync(() => {
463+
expect(header.scrollDistance).toBe(0, 'Expected to start off not scrolled.');
464+
465+
dispatchEvent(nextButton, createMouseEvent('mousedown', undefined, undefined, 2));
466+
fixture.detectChanges();
467+
tick(3000);
468+
469+
expect(header.scrollDistance).toBe(0, 'Expected not to have scrolled after a while.');
470+
}));
471+
461472
/**
462473
* Asserts that auto scrolling using the next button works.
463474
* @param startEventName Name of the event that is supposed to start the scrolling.

src/material/tabs/tab-nav-bar/tab-nav-bar.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
mat-ripple [matRippleDisabled]="_disableScrollBefore || disableRipple"
55
[class.mat-tab-header-pagination-disabled]="_disableScrollBefore"
66
(click)="_handlePaginatorClick('before')"
7-
(mousedown)="_handlePaginatorPress('before')"
7+
(mousedown)="_handlePaginatorPress('before', $event)"
88
(touchend)="_stopInterval()">
99
<div class="mat-tab-header-pagination-chevron"></div>
1010
</div>
@@ -23,7 +23,7 @@
2323
aria-hidden="true"
2424
mat-ripple [matRippleDisabled]="_disableScrollAfter || disableRipple"
2525
[class.mat-tab-header-pagination-disabled]="_disableScrollAfter"
26-
(mousedown)="_handlePaginatorPress('after')"
26+
(mousedown)="_handlePaginatorPress('after', $event)"
2727
(click)="_handlePaginatorClick('after')"
2828
(touchend)="_stopInterval()">
2929
<div class="mat-tab-header-pagination-chevron"></div>

0 commit comments

Comments
 (0)