Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core/modal): ensure that key down listener gets called #870

Merged
merged 6 commits into from
Nov 13, 2023
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
4 changes: 2 additions & 2 deletions packages/angular/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1521,15 +1521,15 @@ export declare interface IxMessageBar extends Components.IxMessageBar {


@ProxyCmp({
inputs: ['animation', 'backdrop', 'beforeDismiss', 'centered', 'closeOnBackdropClick', 'keyboard', 'size'],
inputs: ['animation', 'backdrop', 'beforeDismiss', 'centered', 'closeOnBackdropClick', 'closeOnEscape', 'keyboard', 'size'],
methods: ['showModal', 'dismissModal', 'closeModal']
})
@Component({
selector: 'ix-modal',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['animation', 'backdrop', 'beforeDismiss', 'centered', 'closeOnBackdropClick', 'keyboard', 'size'],
inputs: ['animation', 'backdrop', 'beforeDismiss', 'centered', 'closeOnBackdropClick', 'closeOnEscape', 'keyboard', 'size'],
})
export class IxModal {
protected el: HTMLElement;
Expand Down
25 changes: 24 additions & 1 deletion packages/core/component-doc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7825,15 +7825,38 @@
"optional": false,
"required": false
},
{
"name": "closeOnEscape",
"type": "boolean",
"mutable": false,
"attr": "close-on-escape",
"reflectToAttr": false,
"docs": "If set to true the modal can be closed by pressing the Escape key",
"docsTags": [],
"default": "true",
"values": [
{
"type": "boolean"
}
],
"optional": false,
"required": false
},
{
"name": "keyboard",
"type": "boolean",
"mutable": false,
"attr": "keyboard",
"reflectToAttr": false,
"docs": "Use ESC to dismiss the modal",
"docsTags": [],
"docsTags": [
{
"name": "deprecated",
"text": "- Use closeOnEscape instead"
}
],
"default": "true",
"deprecation": "- Use closeOnEscape instead",
"values": [
{
"type": "boolean"
Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1407,12 +1407,17 @@ export namespace Components {
* @since 2.0.0
*/
"closeOnBackdropClick": boolean;
/**
* If set to true the modal can be closed by pressing the Escape key
*/
"closeOnEscape": boolean;
/**
* Dismiss the dialog
*/
"dismissModal": <T = any>(reason?: T) => Promise<void>;
/**
* Use ESC to dismiss the modal
* @deprecated - Use closeOnEscape instead
*/
"keyboard": boolean;
/**
Expand Down Expand Up @@ -4575,8 +4580,13 @@ declare namespace LocalJSX {
* @since 2.0.0
*/
"closeOnBackdropClick"?: boolean;
/**
* If set to true the modal can be closed by pressing the Escape key
*/
"closeOnEscape"?: boolean;
/**
* Use ESC to dismiss the modal
* @deprecated - Use closeOnEscape instead
*/
"keyboard"?: boolean;
/**
Expand Down
19 changes: 14 additions & 5 deletions packages/core/src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import anime from 'animejs';
import { A11yAttributes, a11yBoolean, a11yHostAttributes } from '../utils/a11y';
import Animation from '../utils/animation';
import { OnListener } from '../utils/listener';

export type IxModalFixedSize = '360' | '480' | '600' | '720' | '840';
export type IxModalDynamicSize = 'full-width' | 'full-screen';
Expand Down Expand Up @@ -73,9 +74,15 @@ export class Modal {

/**
* Use ESC to dismiss the modal
* @deprecated - Use closeOnEscape instead
*/
@Prop() keyboard = true;

/**
* If set to true the modal can be closed by pressing the Escape key
*/
@Prop() closeOnEscape = true;

/**
* Dialog close
*/
Expand All @@ -86,6 +93,13 @@ export class Modal {
*/
@Event() dialogDismiss: EventEmitter;

@OnListener<Modal>('keydown', (self) => !self.closeOnEscape || !self.keyboard)
onKey(e: KeyboardEvent) {
if (e.key === 'Escape') {
e.preventDefault();
}
}

get dialog() {
return this.hostElement.shadowRoot.querySelector('dialog');
}
Expand Down Expand Up @@ -221,11 +235,6 @@ export class Modal {
modal: true,
[`modal-size-${this.size}`]: true,
}}
onKeyDown={(e) => {
if (e.key === 'Escape' && this.keyboard === false) {
e.preventDefault();
}
}}
onClick={(event) => this.onModalClick(event)}
onCancel={(e) => {
e.preventDefault();
Expand Down
52 changes: 52 additions & 0 deletions packages/core/src/components/modal/test/modal.ct.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* SPDX-FileCopyrightText: 2023 Siemens AG
*
* SPDX-License-Identifier: MIT
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { expect } from '@playwright/test';
import { test } from '@utils/test';

declare global {
interface Window {
showModal: any;
}
}

test('closes on Escape key down', async ({ mount, page }) => {
await mount(``);

await page.evaluate(() => {
return new Promise<void>((resolve) => {
const script = document.createElement('script');
script.type = 'module';
script.innerHTML = `
import * as ix from 'http://127.0.0.1:8080/www/build/index.esm.js';
window.showModal = ix.showModal;
`;
document.body.appendChild(script);
resolve();
});
});

await page.waitForTimeout(1000);

await page.evaluate(() => {
const elm = document.createElement('ix-modal');
elm.innerHTML = `
<ix-modal-header>Title</ix-modal-header>
<ix-modal-content>Content</ix-modal-header>
`;
window.showModal({
content: elm,
});
});
const dialog = page.locator('ix-modal dialog');
await expect(dialog).toBeVisible();
await page.locator('ix-modal-content').click();
await page.keyboard.down('Escape');

await expect(dialog).not.toBeVisible();
});
1 change: 1 addition & 0 deletions packages/vue/src/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ export const IxModal = /*@__PURE__*/ defineContainer<JSX.IxModal>('ix-modal', de
'beforeDismiss',
'centered',
'keyboard',
'closeOnEscape',
'dialogClose',
'dialogDismiss'
]);
Expand Down