Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit b39094d

Browse files
allan-chencopybara-github
authored andcommitted
fix(select): debounce click on anchor
PiperOrigin-RevId: 341104682
1 parent ec6b68b commit b39094d

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

packages/mdc-select/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const strings = {
5252
const numbers = {
5353
LABEL_SCALE: 0.75,
5454
UNSET_INDEX: -1,
55+
CLICK_DEBOUNCE_TIMEOUT_MS: 330,
5556
};
5657

5758
export {cssClasses, strings, numbers};

packages/mdc-select/foundation.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ export class MDCSelectFoundation extends MDCFoundation<MDCSelectAdapter> {
104104
private customValidity = true;
105105
private lastSelectedIndex = numbers.UNSET_INDEX;
106106

107+
private clickDebounceTimeout = 0;
108+
private recentlyClicked = false;
109+
107110
/* istanbul ignore next: optional argument is not a branch statement */
108111
/**
109112
* @param adapter
@@ -289,10 +292,12 @@ export class MDCSelectFoundation extends MDCFoundation<MDCSelectAdapter> {
289292
}
290293

291294
handleClick(normalizedX: number) {
292-
if (this.disabled) {
295+
if (this.disabled || this.recentlyClicked) {
293296
return;
294297
}
295298

299+
this.setClickDebounceTimeout();
300+
296301
if (this.isMenuOpen) {
297302
this.adapter.closeMenu();
298303
return;
@@ -476,6 +481,14 @@ export class MDCSelectFoundation extends MDCFoundation<MDCSelectAdapter> {
476481
this.adapter.removeSelectAnchorAttr(strings.ARIA_DESCRIBEDBY);
477482
}
478483
}
484+
485+
private setClickDebounceTimeout() {
486+
clearTimeout(this.clickDebounceTimeout);
487+
this.clickDebounceTimeout = setTimeout(() => {
488+
this.recentlyClicked = false;
489+
}, numbers.CLICK_DEBOUNCE_TIMEOUT_MS);
490+
this.recentlyClicked = true;
491+
}
479492
}
480493

481494
// tslint:disable-next-line:no-default-export Needed for backward compatibility with MDC Web v0.44.0 and earlier.

packages/mdc-select/test/foundation.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@
2222
*/
2323

2424
import {checkNumTimesSpyCalledWithArgs, createMockAdapter, verifyDefaultAdapter} from '../../../testing/helpers/foundation';
25+
import {setUpMdcTestEnvironment} from '../../../testing/helpers/setup';
2526
import {cssClasses, numbers, strings} from '../constants';
2627
import {MDCSelectFoundation} from '../foundation';
2728

2829
const LABEL_WIDTH = 100;
2930

3031
describe('MDCSelectFoundation', () => {
32+
setUpMdcTestEnvironment();
33+
3134
it('exports cssClasses', () => {
3235
expect(MDCSelectFoundation.cssClasses).toEqual(cssClasses);
3336
});
@@ -406,6 +409,19 @@ describe('MDCSelectFoundation', () => {
406409
expect(mockAdapter.addClass).not.toHaveBeenCalled();
407410
});
408411

412+
it('#handleClick debounces clicks', () => {
413+
const {foundation, mockAdapter} = setupTest();
414+
foundation.handleClick(0);
415+
foundation['isMenuOpen'] = false;
416+
foundation.handleClick(0);
417+
expect(mockAdapter.openMenu).toHaveBeenCalledTimes(1);
418+
419+
foundation['isMenuOpen'] = false;
420+
jasmine.clock().tick(numbers.CLICK_DEBOUNCE_TIMEOUT_MS);
421+
foundation.handleClick(0);
422+
expect(mockAdapter.openMenu).toHaveBeenCalledTimes(2);
423+
});
424+
409425
it('#handleClick sets the ripple center if isMenuOpen=false', () => {
410426
const {foundation, mockAdapter} = setupTest();
411427
(foundation as any).isMenuOpen = false;

0 commit comments

Comments
 (0)