Skip to content

Commit

Permalink
Merge pull request #1853 from exadel-inc/fix/incorrect-activator-on-c…
Browse files Browse the repository at this point in the history
…lose

fix(esl-toggleable): fix activator when close-on inner trigger click handled (#1852)
  • Loading branch information
ala-n committed Aug 10, 2023
2 parents eb9bf74 + 829c2b6 commit dde458e
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/modules/esl-toggleable/core/esl-toggleable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {DeviceDetector} from '../../esl-utils/environment/device-detector';
import {DelayedTask} from '../../esl-utils/async/delayed-task';
import {ESLBaseElement} from '../../esl-base-element/core';
import {findParent, isMatches} from '../../esl-utils/dom/traversing';
import type {DelegatedEvent} from '../../esl-event-listener/core/types';

/** Default Toggleable action params type definition */
export interface ESLToggleableActionParams {
Expand Down Expand Up @@ -304,12 +305,13 @@ export class ESLToggleable extends ESLBaseElement {
return !(e instanceof KeyboardEvent && SYSTEM_KEYS.includes(e.key));
}

@listen({
event: 'click',
selector: (el: ESLToggleable) => el.closeTrigger || ''
})
protected _onCloseClick(e: MouseEvent): void {
this.hide({initiator: 'close', activator: e.target as HTMLElement, event: e});
@listen({event: 'click', selector: (el: ESLToggleable) => el.closeTrigger || ''})
protected _onCloseClick(e: DelegatedEvent<MouseEvent>): void {
this.hide({
initiator: 'close',
activator: e.$delegate as HTMLElement,
event: e
});
}

@listen({
Expand Down
102 changes: 102 additions & 0 deletions src/modules/esl-toggleable/test/toggleable.close-on.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import {ESLToggleable} from '../core/esl-toggleable';

describe('ESLToggleable: close-on trigger handler', () => {
const $template = document.createElement('template');
$template.innerHTML = `
<esl-toggleable class='toggleable-close-on-test' close-on='.trigger-close' defaultParams='{delay: -1}'>
<button type='button' class='trigger trigger-close'><span>Close<span></button>
<button type='button' class='trigger trigger-additional'><span>Trigger<span></button>
</esl-toggleable>
<button type='button' class='trigger-close trigger-outside toggleable-close-on-test'>
<span>Close<span>
</button>
`;
const elements = {
get $el() {
return document.querySelector('esl-toggleable.toggleable-close-on-test') as ESLToggleable;
},
get $trigger() {
return document.querySelector('.trigger-close') as HTMLElement;
},
get $triggerOutside() {
return document.querySelector('.trigger-outside') as HTMLElement;
},
get $triggerAdditional() {
return document.querySelector('.trigger-additional') as HTMLElement;
}
};

beforeAll(() => ESLToggleable.register());
beforeEach(() => document.body.appendChild($template.content.cloneNode(true)));
afterEach(() => [...document.querySelectorAll('.toggleable-close-on-test')].forEach(($el) => $el.remove()));

test('Close-on trigger click leads to toggleable hide', () => {
const {$el, $trigger} = elements;

$el.show();
expect($el.open).toBe(true);

$trigger.click();
expect($el.open).toBe(false);
});

test('Click on inner trigger content leads to toggleable hide', () => {
const {$el, $trigger} = elements;

$el.show();
expect($el.open).toBe(true);

$trigger.querySelector('span')?.click();
expect($el.open).toBe(false);
});

test('Close-on trigger click outside toggleable does not leads to toggleable hide', () => {
const {$el, $triggerOutside} = elements;

$el.show();
expect($el.open).toBe(true);

$triggerOutside.click();
expect($el.open).toBe(true);
});

test('Close-on trigger click on additional trigger does not leads to toggleable hide', () => {
const {$el, $triggerAdditional} = elements;

$el.show();
expect($el.open).toBe(true);

$triggerAdditional.click();
expect($el.open).toBe(true);
});

test('Dynamic change of close-on attribute processed correctly', () => {
const {$el, $triggerAdditional} = elements;

$el.show();
$el.setAttribute('close-on', '.trigger');

$triggerAdditional.click();
expect($el.open).toBe(false);
});

test('ESLToggleableActionParams contains correct activator details', () => {
const {$el, $trigger} = elements;

const $fn = jest.fn((e) => console.log(e));

$el.show();
$el.addEventListener('esl:hide', $fn);
$trigger.querySelector('span')?.click();

expect($fn).lastCalledWith(expect.objectContaining({
type: 'esl:hide',
detail: expect.objectContaining({
params: expect.objectContaining({
initiator: 'close',
activator: $trigger
})
})
}));
});
});

0 comments on commit dde458e

Please sign in to comment.