Skip to content

Commit

Permalink
chore(dropdown): use HostListener to handle to click event
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinbuhmann committed Dec 14, 2022
1 parent 6906ee9 commit 9b40679
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 32 deletions.
8 changes: 2 additions & 6 deletions projects/angular/clarity.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2240,9 +2240,9 @@ export class ClrDropdown implements OnDestroy {
}

// @public (undocumented)
export class ClrDropdownItem implements AfterViewInit {
export class ClrDropdownItem {
// Warning: (ae-forgotten-export) The symbol "FocusableItem" needs to be exported by the entry point index.d.ts
constructor(dropdown: ClrDropdown, el: ElementRef<HTMLElement>, _dropdownService: RootDropdownService, renderer: Renderer2, focusableItem: FocusableItem);
constructor(dropdown: ClrDropdown, _dropdownService: RootDropdownService, focusableItem: FocusableItem);
set disabled(value: boolean | string);
// (undocumented)
get disabled(): boolean | string;
Expand All @@ -2253,10 +2253,6 @@ export class ClrDropdownItem implements AfterViewInit {
// (undocumented)
get dropdownItemId(): string;
// (undocumented)
ngAfterViewInit(): void;
// (undocumented)
ngOnDestroy(): void;
// (undocumented)
setByDeprecatedDisabled: boolean;
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<ClrDropdownItem, "[clrDropdownItem]", never, { "disabled": "clrDisabled"; "disabledDeprecated": "disabled"; "dropdownItemId": "id"; }, {}, never>;
Expand Down
27 changes: 9 additions & 18 deletions projects/angular/src/popover/dropdown/dropdown-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* The full license information can be found in LICENSE in the root directory of this project.
*/

import { AfterViewInit, Directive, ElementRef, Input, Renderer2 } from '@angular/core';
import { Directive, HostListener, Input } from '@angular/core';

import { BASIC_FOCUSABLE_ITEM_PROVIDER } from '../../utils/focus/focusable-item/basic-focusable-item.service';
import { FocusableItem } from '../../utils/focus/focusable-item/focusable-item';
Expand All @@ -23,16 +23,13 @@ import { RootDropdownService } from './providers/dropdown.service';
},
providers: [BASIC_FOCUSABLE_ITEM_PROVIDER],
})
export class ClrDropdownItem implements AfterViewInit {
export class ClrDropdownItem {
constructor(
private dropdown: ClrDropdown,
private el: ElementRef<HTMLElement>,
private _dropdownService: RootDropdownService,
private renderer: Renderer2,
private focusableItem: FocusableItem
) {}

private unlisten: () => void;
setByDeprecatedDisabled = false;

@Input('clrDisabled')
Expand Down Expand Up @@ -70,19 +67,13 @@ export class ClrDropdownItem implements AfterViewInit {
return this.focusableItem.id;
}

ngAfterViewInit() {
this.unlisten = this.renderer.listen(this.el.nativeElement, 'click', () => this.onDropdownItemClick());
}

@HostListener('click')
private onDropdownItemClick(): void {
if (this.dropdown.isMenuClosable && !this.disabled) {
this._dropdownService.closeMenus();
}
}

ngOnDestroy() {
if (this.unlisten) {
this.unlisten();
}
// Ensure that the dropdown is closed after custom dropdown item click event handlers have run.
setTimeout(() => {
if (this.dropdown.isMenuClosable && !this.disabled) {
this._dropdownService.closeMenus();
}
});
}
}
22 changes: 14 additions & 8 deletions projects/angular/src/popover/dropdown/dropdown.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,15 @@ export default function (): void {
expect(compiled.querySelector('.dropdown-item')).toBeNull();
}));

it('supports clrMenuClosable option. Closes the dropdown menu when clrMenuClosable is set to true', () => {
it('supports clrMenuClosable option. Closes the dropdown menu when clrMenuClosable is set to true', fakeAsync(() => {
const dropdownToggle: HTMLElement = compiled.querySelector('.dropdown-toggle');
dropdownToggle.click();
fixture.detectChanges();

const dropdownItem: HTMLElement = compiled.querySelector('.dropdown-item');

dropdownItem.click();
tick();
fixture.detectChanges();
expect(compiled.querySelector('.dropdown-item')).toBeNull();

Expand All @@ -146,11 +147,12 @@ export default function (): void {
expect(compiled.querySelector('.dropdown-item')).not.toBeNull();

dropdownItem.click();
tick();
fixture.detectChanges();
expect(compiled.querySelector('.dropdown-item')).not.toBeNull();
});
}));

it('closes all dropdown menus when clrMenuClosable is true', () => {
it('closes all dropdown menus when clrMenuClosable is true', fakeAsync(() => {
const dropdownToggle: HTMLElement = compiled.querySelector('.dropdown-toggle');
dropdownToggle.click();
fixture.detectChanges();
Expand All @@ -162,14 +164,15 @@ export default function (): void {

const nestedItem: HTMLElement = compiled.querySelector('.nested-item');
nestedItem.click();
tick();

fixture.detectChanges();

const items: HTMLElement = compiled.querySelector('.dropdown-item');
expect(items).toBeNull();
});
}));

it('does not close the menu when a disabled item is clicked', () => {
it('does not close the menu when a disabled item is clicked', fakeAsync(() => {
const dropdownToggle: HTMLElement = compiled.querySelector('.dropdown-toggle');
dropdownToggle.click();
fixture.detectChanges();
Expand All @@ -178,15 +181,17 @@ export default function (): void {
const dropdownItem: HTMLElement = compiled.querySelector('.dropdown-item');

disabledDropdownItem.click();
tick();
fixture.detectChanges();
expect(compiled.querySelector('.dropdown-item')).not.toBeNull();

dropdownItem.click();
tick();
fixture.detectChanges();
expect(compiled.querySelector('.dropdown-item')).toBeNull();
});
}));

it("doesn't close before custom click events have triggered", function () {
it("doesn't close before custom click events have triggered", fakeAsync(function () {
const toggleService = fixture.debugElement.query(By.directive(ClrDropdown)).injector.get(ClrPopoverToggleService);

const dropdownToggle: HTMLElement = compiled.querySelector('.dropdown-toggle');
Expand All @@ -203,11 +208,12 @@ export default function (): void {

const nestedItem: HTMLElement = compiled.querySelector('.nested-item');
nestedItem.click();
tick();
fixture.detectChanges();

// Make sure the dropdown correctly closed, otherwise our expect() in the subscription might not have run.
expect(toggleService.open).toBe(false);
});
}));

it('declares a FocusService provider', () => {
const focusService = fixture.debugElement.query(By.directive(ClrDropdown)).injector.get(FocusService, null);
Expand Down

0 comments on commit 9b40679

Please sign in to comment.