From 39abdee702a158bc29fcbc50672296e6d6f39b64 Mon Sep 17 00:00:00 2001 From: far-fetched Date: Mon, 1 Nov 2021 19:19:04 +0100 Subject: [PATCH 1/3] :heavy_minus_sign: remove click-outside modifier deps --- package.json | 1 - yarn.lock | 9 --------- 2 files changed, 10 deletions(-) diff --git a/package.json b/package.json index 277df095..dfe0efb0 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "ember-cli-babel": "^7.26.3", "ember-cli-htmlbars": "^5.7.1", "ember-cli-typescript": "^4.2.1", - "ember-click-outside-modifier": "^2.0.0", "ember-concurrency": "^2.1.2", "ember-element-helper": "^0.5.5", "ember-set-helper": "^2.0.1", diff --git a/yarn.lock b/yarn.lock index 2a6f3c63..b2adc190 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6218,15 +6218,6 @@ ember-cli@~3.27.0: workerpool "^6.0.3" yam "^1.0.0" -ember-click-outside-modifier@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ember-click-outside-modifier/-/ember-click-outside-modifier-2.0.0.tgz#8417a44db8bafef87e08f3614ad809ad1a6020e1" - integrity sha512-5FkTsSiSoDh4wL0mqJ2niOZH3ykevcRdLxA2pgZ9JqCMpvMqAQon5valAA4mvW6HiP9lnwm+GR/WijtL0dsdcg== - dependencies: - ember-cli-babel "^7.26.6" - ember-cli-htmlbars "^5.7.1" - ember-modifier "^2.1.2" - ember-compatibility-helpers@^1.1.2, ember-compatibility-helpers@^1.2.0, ember-compatibility-helpers@^1.2.1, ember-compatibility-helpers@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/ember-compatibility-helpers/-/ember-compatibility-helpers-1.2.4.tgz#70e0fef7048969141626eed6006f3880df612cd1" From 0550e59d957619d216e8484a49d5263705cfcf22 Mon Sep 17 00:00:00 2001 From: far-fetched Date: Mon, 1 Nov 2021 19:32:19 +0100 Subject: [PATCH 2/3] :sparkles: set return focus on focusable clicked element --- addon/components/dialog.hbs | 11 +++++++---- addon/components/dialog.ts | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/addon/components/dialog.hbs b/addon/components/dialog.hbs index bbf4d2e9..fa670ca4 100644 --- a/addon/components/dialog.hbs +++ b/addon/components/dialog.hbs @@ -7,9 +7,12 @@ aria-modal='true' ...attributes {{headlessui-focus-trap - focusTrapOptions=(hash initialFocus=@initialFocus) + focusTrapOptions=(hash + initialFocus=@initialFocus + allowOutsideClick=this.allowOutsideClick + setReturnFocus=this.setReturnFocus + ) }} - {{click-outside this.onClose event='mouseup'}} {{this.handleEscapeKey @isOpen this.onClose}} {{did-insert (fn this.dialogStackProvider.push this)}} {{will-destroy (fn this.dialogStackProvider.remove this)}} @@ -17,13 +20,13 @@ {{yield (hash isOpen=@isOpen - onClose=@onClose + onClose=this.onClose Overlay=(component 'dialog/-overlay' guid=this.overlayGuid dialogGuid=this.guid isOpen=@isOpen - onClose=@onClose + onClose=this.onClose ) Title=(component 'dialog/-title' diff --git a/addon/components/dialog.ts b/addon/components/dialog.ts index bc7baf42..9bdefea5 100644 --- a/addon/components/dialog.ts +++ b/addon/components/dialog.ts @@ -30,6 +30,7 @@ export default class DialogComponent extends Component { guid = `${guidFor(this)}-headlessui-dialog`; $portalRoot = getPortalRoot(); + outsideClickedElement: HTMLElement | null = null; handleEscapeKey = modifier( (_element, [isOpen, onClose]: [boolean, () => void]) => { @@ -103,6 +104,21 @@ export default class DialogComponent extends Component { return `${this.guid}-description`; } + @action + setReturnFocus(trigger: HTMLElement) { + return this.outsideClickedElement ? this.outsideClickedElement : trigger; + } + + @action + allowOutsideClick(e: MouseEvent) { + let target = e.target as HTMLElement; + if (target && target.tagName !== 'BODY') { + this.outsideClickedElement = target; + } + this.onClose(); + return true + } + @action onClose() { if (this.dialogStackProvider.hasOpenChild(this)) return; From 12f048f5eee3dedd302db43c3b61b25ef25aa50e Mon Sep 17 00:00:00 2001 From: far-fetched Date: Mon, 1 Nov 2021 19:32:48 +0100 Subject: [PATCH 3/3] :white_check_mark: set return focus test --- addon/components/dialog.ts | 5 ++- tests/integration/components/dialog-test.js | 38 +++++++++++++++++---- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/addon/components/dialog.ts b/addon/components/dialog.ts index 9bdefea5..56be143b 100644 --- a/addon/components/dialog.ts +++ b/addon/components/dialog.ts @@ -112,11 +112,14 @@ export default class DialogComponent extends Component { @action allowOutsideClick(e: MouseEvent) { let target = e.target as HTMLElement; + if (target && target.tagName !== 'BODY') { this.outsideClickedElement = target; } + this.onClose(); - return true + + return true; } @action diff --git a/tests/integration/components/dialog-test.js b/tests/integration/components/dialog-test.js index 94202663..e8be2dcd 100644 --- a/tests/integration/components/dialog-test.js +++ b/tests/integration/components/dialog-test.js @@ -405,13 +405,33 @@ module('Integration | Component | ', function (hooks) { assertDialog({ state: DialogState.InvisibleUnmounted }); - assertActiveElement(getByText('Trigger')); + await assertActiveElement(getByText('Trigger')); }); - todo( - 'it should be possible to close the dialog, and keep focus on the focusable element', - async function () {} - ); + test('it should be possible to close the dialog, and keep focus on the focusable element', async function () { + this.set('isOpen', false); + + await render(hbs` + + + + Contents +
+
+ `); + + await click(getByText('Trigger')); + + assertDialog({ state: DialogState.Visible }); + + await click(getByText('Hello')); + + assertDialog({ state: DialogState.InvisibleUnmounted }); + + await assertActiveElement(getByText('Hello')); + }); test('it should stop propagating click events when clicking on the Dialog.Overlay', async function (assert) { this.set('isOpen', true); @@ -768,11 +788,15 @@ module('Integration | Component | ', function (hooks) { //close the top most dialog with ${strategy} await action(); - assert.equal(getDialogs(), 0, 'Verify that we have 0 open dialogs'); + assert.equal( + getDialogs().length, + 0, + 'Verify that we have 0 open dialogs' + ); await assertActiveElement( getByText('Open 1'), - 'Verify that we have 1 open dialog' + 'Verify that the `Open 1` got focused again' ); } );