diff --git a/README.md b/README.md index 0357878b..17e95dd7 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,9 @@ this.modals.open( // optional: a hook that is called when the closing animation of // the modal (so not the backdrop) has finished. onAnimationModalOutEnd: () => {}, + // optional: a hook that is called when the opening animation of + // the modal (so not the backdrop) has finished. + onAnimationModalInEnd: () => {}, }, ); ``` diff --git a/addon/components/modal.js b/addon/components/modal.js index 5fc92242..588adaa0 100644 --- a/addon/components/modal.js +++ b/addon/components/modal.js @@ -74,7 +74,11 @@ export default Component.extend({ if (isOutAninmation) { this.removeModal(); + + return; } + + this.modal.onAnimationModalInEnd(animationName); }; this.modals._onModalAnimationStart(); diff --git a/addon/modal.js b/addon/modal.js index 32ff0b16..d2f7bc60 100644 --- a/addon/modal.js +++ b/addon/modal.js @@ -27,6 +27,7 @@ export default class Modal { this._options = { className: '', onAnimationModalOutEnd: undefined, + onAnimationModalInEnd: undefined, ...options, }; this._result = undefined; @@ -39,6 +40,14 @@ export default class Modal { return this._result; } + onAnimationModalInEnd() { + if (!this._options.onAnimationModalInEnd) { + return; + } + + return this._options.onAnimationModalInEnd(...arguments); + } + @computed('_deferredOutAnimation') get isClosing() { return Boolean(this._deferredOutAnimation); diff --git a/tests/application/basics-test.js b/tests/application/basics-test.js index 2fe5839e..146c07df 100644 --- a/tests/application/basics-test.js +++ b/tests/application/basics-test.js @@ -2,6 +2,8 @@ import { visit, click, triggerKeyEvent, waitUntil } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import { module, test } from 'qunit'; +import Modal1 from 'dummy/components/modal1'; + import { setupPromiseModals } from 'ember-promise-modals/test-support'; module('Application | basics', function (hooks) { @@ -69,6 +71,45 @@ module('Application | basics', function (hooks) { assert.dom('body', document).hasStyle({ overflow: 'visible' }); }); + test('opening a modal calls onAnimationModal*End once the animation ends', async function (assert) { + await visit('/'); + + assert.dom('.epm-backdrop').doesNotExist(); + assert.dom('.epm-modal').doesNotExist(); + + const applicationController = this.owner.lookup('controller:application'); + const modalsService = applicationController.modals; + const showModal = applicationController.actions.showModal; + + applicationController.actions.showModal = () => { + assert.step('open'); + + modalsService.open( + Modal1, + {}, + { + onAnimationModalInEnd: () => { + assert.step('onAnimationModalInEnd'); + }, + onAnimationModalOutEnd: () => { + assert.step('onAnimationModalOutEnd'); + }, + }, + ); + }; + + await click('[data-test-show-modal]'); + await waitUntil(() => !document.body.classList.contains('epm-animating')); + await click('.epm-backdrop'); + + assert.dom('.epm-backdrop').doesNotExist(); + assert.dom('.epm-modal').doesNotExist(); + + assert.verifySteps(['open', 'onAnimationModalInEnd', 'onAnimationModalOutEnd']); + + applicationController.actions.showModal = showModal; + }); + test('pressing the Escape keyboard button closes the modal', async function (assert) { await visit('/');