diff --git a/addon/components/basic-dropdown-content.ts b/addon/components/basic-dropdown-content.ts index 4f747592..84193251 100644 --- a/addon/components/basic-dropdown-content.ts +++ b/addon/components/basic-dropdown-content.ts @@ -46,17 +46,13 @@ export default class BasicDropdownContent extends Component { private handleRootMouseDown?: RootMouseDownHandler private scrollableAncestors: Element[] = [] private mutationObserver?: MutationObserver - @tracked animationClass = this.animationEnabled ? this.transitioningInClass : '' + @tracked animationClass = this.transitioningInClass get destinationElement(): Element | null { return document.getElementById(this.args.destination); } - get animationEnabled(): boolean { - return !isTesting(); - } - /** * Allows similair behaviour to `ember-composable-helpers`' `optional` helper. * Avoids adding extra dependencies. @@ -116,7 +112,6 @@ export default class BasicDropdownContent extends Component { @action animateIn(dropdownElement: Element): void { - if (!this.animationEnabled) return; waitForAnimations(dropdownElement, () => { this.animationClass = this.transitionedInClass; }); @@ -124,11 +119,14 @@ export default class BasicDropdownContent extends Component { @action animateOut(dropdownElement: Element): void { - if (!this.animationEnabled) return; let parentElement = dropdownElement.parentElement; if (parentElement === null) return; if (this.args.renderInPlace) { parentElement = parentElement.parentElement + + if (isTesting() && parentElement === null) { + parentElement = document.querySelector('.ember-basic-dropdown'); + } } if (parentElement === null) return; let clone = dropdownElement.cloneNode(true) as Element; @@ -136,7 +134,7 @@ export default class BasicDropdownContent extends Component { clone.classList.remove(...this.transitioningInClass.split(' ')); clone.classList.add(...this.transitioningOutClass.split(' ')); parentElement.appendChild(clone); - this.animationClass = this.transitionedInClass; + this.animationClass = this.transitioningInClass; waitForAnimations(clone, function() { (parentElement as HTMLElement).removeChild(clone); }); diff --git a/tests/integration/components/basic-dropdown-test.js b/tests/integration/components/basic-dropdown-test.js index 304a88e7..e80a400d 100644 --- a/tests/integration/components/basic-dropdown-test.js +++ b/tests/integration/components/basic-dropdown-test.js @@ -3,7 +3,7 @@ import { registerDeprecationHandler } from '@ember/debug'; import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { hbs } from 'ember-cli-htmlbars'; -import { render, click, focus, triggerEvent } from '@ember/test-helpers'; +import { render, click, focus, triggerEvent, waitUntil, find } from '@ember/test-helpers'; let deprecations = []; @@ -1004,4 +1004,83 @@ module('Integration | Component | basic-dropdown', function (hooks) { .dom('.ember-basic-dropdown-content') .hasAttribute('style', /max-height: 500px; overflow-y: auto/); }); + + /** + * Tests related to https://github.com/cibernox/ember-basic-dropdown/issues/615 + */ + + test('[BUGFIX] Dropdowns rendered in place have correct animation flow', async function (assert) { + assert.expect(4); + + const basicDropdownContentClass = 'ember-basic-dropdown-content'; + const transitioningInClass = 'ember-basic-dropdown--transitioning-in'; + const transitionedInClass = 'ember-basic-dropdown--transitioned-in'; + const transitioningOutClass = 'ember-basic-dropdown--transitioning-out'; + + document.head.insertAdjacentHTML( + 'beforeend', + ` + ` + ); + + await render(hbs` + + + + + `); + + await click('.ember-basic-dropdown-trigger'); + + assert + .dom(`.${basicDropdownContentClass}`) + .hasClass( + transitioningInClass, + `The dropdown content has .${transitioningInClass} class` + ); + + await waitUntil(() => + find('.ember-basic-dropdown-content').classList.contains( + transitionedInClass + ) + ); + + await click('.ember-basic-dropdown-trigger'); + + assert + .dom(`.${basicDropdownContentClass}`) + .hasClass( + transitioningOutClass, + `The dropdown content has .${transitioningOutClass} class` + ); + + await click('.ember-basic-dropdown-trigger'); + + assert + .dom(`.${basicDropdownContentClass}`) + .hasClass( + transitioningInClass, + `After closing dropdown, the dropdown content has .${transitioningInClass} class again as initial value` + ); + + await waitUntil(() => + find('.ember-basic-dropdown-content').classList.contains( + transitionedInClass + ) + ); + + await click('.ember-basic-dropdown-trigger'); + + assert + .dom(`.${basicDropdownContentClass}`) + .hasClass( + transitioningOutClass, + `The dropdown content has .${transitioningOutClass} class` + ); + }); });