Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tidy-tigers-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hashicorp/design-system-components": patch
---

`Modal` - Reverted changes introduced in [#2846](https://github.com/hashicorp/design-system/pull/2846) and [#2902](https://github.com/hashicorp/design-system/pull/2902) related to the click behaviour outside the modal when dismissing is disabled
2 changes: 1 addition & 1 deletion packages/components/src/components/hds/modal/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{{did-insert this.didInsert}}
{{will-destroy this.willDestroyNode}}
{{! @glint-expect-error - https://github.com/josemarluedke/ember-focus-trap/issues/86 }}
{{focus-trap isActive=this._isOpen focusTrapOptions=(hash onDeactivate=this.onDismiss)}}
{{focus-trap isActive=this._isOpen focusTrapOptions=(hash onDeactivate=this.onDismiss clickOutsideDeactivates=true)}}
>
<:header>
{{yield
Expand Down
72 changes: 24 additions & 48 deletions packages/components/src/components/hds/modal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ import { action } from '@ember/object';
import { assert } from '@ember/debug';
import { getElementId } from '../../../utils/hds-get-element-id.ts';
import { buildWaiter } from '@ember/test-waiters';
import { registerDestructor } from '@ember/destroyable';

import type { WithBoundArgs } from '@glint/template';
import type Owner from '@ember/owner';
import type { HdsModalSizes, HdsModalColors } from './types.ts';

import HdsDialogPrimitiveHeaderComponent from '../dialog-primitive/header.ts';
Expand Down Expand Up @@ -63,15 +61,6 @@ export default class HdsModal extends Component<HdsModalSignature> {
private _element!: HTMLDialogElement;
private _body!: HTMLElement;
private _bodyInitialOverflowValue = '';
private _clickHandler!: (event: MouseEvent) => void;

constructor(owner: Owner, args: HdsModalSignature['Args']) {
super(owner, args);

registerDestructor(this, (): void => {
document.removeEventListener('click', this._clickHandler, true);
});
}

get isDismissDisabled(): boolean {
return this.args.isDismissDisabled ?? false;
Expand Down Expand Up @@ -139,29 +128,6 @@ export default class HdsModal extends Component<HdsModalSignature> {
}
} else {
this._isOpen = false;

// Reset page `overflow` property
if (this._body) {
this._body.style.removeProperty('overflow');
if (this._bodyInitialOverflowValue === '') {
if (this._body.style.length === 0) {
this._body.removeAttribute('style');
}
} else {
this._body.style.setProperty(
'overflow',
this._bodyInitialOverflowValue
);
}
}

// Return focus to a specific element (if provided)
if (this.args.returnFocusTo) {
const initiator = document.getElementById(this.args.returnFocusTo);
if (initiator) {
initiator.focus();
}
}
}
}

Expand All @@ -185,20 +151,6 @@ export default class HdsModal extends Component<HdsModalSignature> {
if (!this._element.open) {
this.open();
}

this._clickHandler = (event: MouseEvent) => {
// check if the click is outside the modal and the modal is open
if (!this._element.contains(event.target as Node) && this._isOpen) {
if (!this.isDismissDisabled) {
void this.onDismiss();
}
}
};

document.addEventListener('click', this._clickHandler, {
capture: true,
passive: false,
});
}

@action
Expand Down Expand Up @@ -233,6 +185,7 @@ export default class HdsModal extends Component<HdsModalSignature> {
async onDismiss(): Promise<void> {
// allow ember test helpers to be aware of when the `close` event fires
// when using `click` or other helpers from '@ember/test-helpers'
// Notice: this code will get stripped out in production builds (DEBUG evaluates to `true` in dev/test builds, but `false` in prod builds)
if (this._element.open) {
const token = waiter.beginAsync();
const listener = () => {
Expand All @@ -244,5 +197,28 @@ export default class HdsModal extends Component<HdsModalSignature> {

// Make modal dialog invisible using the native `close` method
this._element.close();

// Reset page `overflow` property
if (this._body) {
this._body.style.removeProperty('overflow');
if (this._bodyInitialOverflowValue === '') {
if (this._body.style.length === 0) {
this._body.removeAttribute('style');
}
} else {
this._body.style.setProperty(
'overflow',
this._bodyInitialOverflowValue
);
}
}

// Return focus to a specific element (if provided)
if (this.args.returnFocusTo) {
const initiator = document.getElementById(this.args.returnFocusTo);
if (initiator) {
initiator.focus();
}
}
}
}
21 changes: 0 additions & 21 deletions showcase/tests/integration/components/hds/modal/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,27 +169,6 @@ module('Integration | Component | hds/modal/index', function (hooks) {
assert.dom('#test-modal').isNotVisible();
});

test('it should appropriately dismiss the modal when clicking outside the modal', async function (assert) {
this.set('isDismissDisabled', true);
await render(
hbs`<Hds::Modal @isDismissDisabled={{this.isDismissDisabled}} id="test-modal" as |M|>
<M.Header>Title</M.Header>
<M.Footer as |F|>
<Hds::Button id="cancel-button" type="button" @text="Cancel" @color="secondary" {{on "click" F.close}} />
</M.Footer>
</Hds::Modal>`,
);

await click('.hds-modal__overlay');
assert.dom('#test-modal').isVisible();

// now let's check that the state is reset and it can be closed
this.set('isDismissDisabled', false);
await rerender();
await click('.hds-modal__overlay');
assert.dom('#test-modal').isNotVisible();
});

// ACCESSIBILITY

test('it uses the title as name for the dialog', async function (assert) {
Expand Down
Loading