Skip to content

Commit 66797d6

Browse files
author
shleewhite
committed
it # This is a combination of 2 commits.
fix: bug with click outside to dismiss for modal
1 parent 175a047 commit 66797d6

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

packages/components/src/components/hds/modal/index.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
aria-labelledby={{this.id}}
99
{{this._registerDialog}}
1010
{{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}
11-
{{focus-trap isActive=this._isOpen focusTrapOptions=(hash onDeactivate=this.onDismiss clickOutsideDeactivates=true)}}
11+
{{focus-trap isActive=this._isOpen focusTrapOptions=(hash onDeactivate=this.onDismiss)}}
1212
>
1313
<:header>
1414
{{yield

packages/components/src/components/hds/modal/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export default class HdsModal extends Component<HdsModalSignature> {
6262
private _element!: HTMLDialogElement;
6363
private _body!: HTMLElement;
6464
private _bodyInitialOverflowValue = '';
65+
private _clickOutsideToDismissHandler!: (event: MouseEvent) => void;
6566

6667
get isDismissDisabled(): boolean {
6768
return this.args.isDismissDisabled ?? false;
@@ -175,6 +176,22 @@ export default class HdsModal extends Component<HdsModalSignature> {
175176
this.open();
176177
}
177178

179+
// Note: because the Modal has the `@isDismissedDisabled` argument, we need to add our own click outside to dismiss logic. This is because `ember-focus-trap` treats the `focusTrapOptions` as static, so we can't update it dynamically if `@isDismissDisabled` changes.
180+
this._clickOutsideToDismissHandler = (event: MouseEvent) => {
181+
// check if the click is outside the modal and the modal is open
182+
if (!this._element.contains(event.target as Node) && this._isOpen) {
183+
if (!this.isDismissDisabled) {
184+
// here we use `void` because `onDismiss` is an async function, but in reality we don't need to handle the result or wait for its completion
185+
void this.onDismiss();
186+
}
187+
}
188+
};
189+
190+
document.addEventListener('click', this._clickOutsideToDismissHandler, {
191+
capture: true,
192+
passive: false,
193+
});
194+
178195
return () => {
179196
// if the <dialog> is removed from the dom while open we emulate the close event
180197
if (this._isOpen) {
@@ -187,6 +204,12 @@ export default class HdsModal extends Component<HdsModalSignature> {
187204
this.registerOnCloseCallback,
188205
true
189206
);
207+
208+
document.removeEventListener(
209+
'click',
210+
this._clickOutsideToDismissHandler,
211+
true
212+
);
190213
};
191214
});
192215

0 commit comments

Comments
 (0)