diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index cf9f73f78a9..c9eef2d2feb 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -1687,6 +1687,10 @@ export namespace Components { * This internal property, managed by a containing calcite-shell, is used to inform the component if special configuration or styles are needed */ "embedded": boolean; + /** + * When `true`, disables the default close on escape behavior. By default, an open dialog can be dismissed by pressing the Esc key. Depending on what the dialog represents, it may not be desired for this behavior. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog#accessibility + */ + "escapeDisabled": boolean; /** * The component header text. */ @@ -9687,6 +9691,10 @@ declare namespace LocalJSX { * This internal property, managed by a containing calcite-shell, is used to inform the component if special configuration or styles are needed */ "embedded"?: boolean; + /** + * When `true`, disables the default close on escape behavior. By default, an open dialog can be dismissed by pressing the Esc key. Depending on what the dialog represents, it may not be desired for this behavior. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog#accessibility + */ + "escapeDisabled"?: boolean; /** * The component header text. */ diff --git a/packages/calcite-components/src/components/dialog/dialog.e2e.ts b/packages/calcite-components/src/components/dialog/dialog.e2e.ts index 22a38708876..3e88c10a5cb 100644 --- a/packages/calcite-components/src/components/dialog/dialog.e2e.ts +++ b/packages/calcite-components/src/components/dialog/dialog.e2e.ts @@ -52,6 +52,10 @@ describe("calcite-dialog", () => { propertyName: "closeDisabled", value: true, }, + { + propertyName: "escapeDisabled", + value: true, + }, { propertyName: "placement", value: "center", @@ -109,6 +113,10 @@ describe("calcite-dialog", () => { propertyName: "description", defaultValue: undefined, }, + { + propertyName: "escapeDisabled", + defaultValue: false, + }, { propertyName: "closeDisabled", defaultValue: false, @@ -315,6 +323,29 @@ describe("calcite-dialog", () => { expect(style.height).toEqual("800px"); }); + it("escapeDisabled", async () => { + const page = await newE2EPage(); + await page.setContent(html`Some content`); + await skipAnimations(page); + await page.waitForChanges(); + + const dialog = await page.find("calcite-dialog"); + expect(await dialog.getProperty("open")).toBe(true); + + await page.keyboard.press("Escape"); + await page.waitForChanges(); + + expect(await dialog.getProperty("open")).toBe(true); + + dialog.setProperty("escapeDisabled", false); + await page.waitForChanges(); + + await page.keyboard.press("Escape"); + await page.waitForChanges(); + + expect(await dialog.getProperty("open")).toBe(false); + }); + describe("beforeClose()", () => { it("calls the beforeClose method prior to closing via click", async () => { const page = await newE2EPage(); diff --git a/packages/calcite-components/src/components/dialog/dialog.stories.ts b/packages/calcite-components/src/components/dialog/dialog.stories.ts index 0160e0481ba..d89822b27da 100644 --- a/packages/calcite-components/src/components/dialog/dialog.stories.ts +++ b/packages/calcite-components/src/components/dialog/dialog.stories.ts @@ -13,6 +13,7 @@ type DialogStoryArgs = Pick< | "widthScale" | "heading" | "description" + | "escapeDisabled" | "closeDisabled" | "placement" | "loading" @@ -27,6 +28,7 @@ export default { args: { open: true, kind: "", + escapeDisabled: false, scale: scale.defaultValue, widthScale: scale.values[0], placement: "center", @@ -92,6 +94,7 @@ export const simple = (args: DialogStoryArgs): string => html` ${boolean("menu-open", args.menuOpen)} ${boolean("loading", args.loading)} ${boolean("close-disabled", args.closeDisabled)} + ${boolean("escape-disabled", args.escapeDisabled)} ${boolean("outside-close-disabled", args.outsideCloseDisabled)} kind="${args.kind}" scale="${args.scale}" diff --git a/packages/calcite-components/src/components/dialog/dialog.tsx b/packages/calcite-components/src/components/dialog/dialog.tsx index 020714e44e1..b2f8765ee11 100644 --- a/packages/calcite-components/src/components/dialog/dialog.tsx +++ b/packages/calcite-components/src/components/dialog/dialog.tsx @@ -103,6 +103,15 @@ export class Dialog */ @Prop({ mutable: true }) embedded = false; + /** + * When `true`, disables the default close on escape behavior. + * + * By default, an open dialog can be dismissed by pressing the Esc key. + * + * @see [Dialog Accessibility](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog#accessibility) + */ + @Prop({ reflect: true }) escapeDisabled = false; + /** * The component header text. */ @@ -323,7 +332,7 @@ export class Dialog @Listen("keydown", { target: "window" }) handleEscape(event: KeyboardEvent): void { - if (this.open && event.key === "Escape" && !event.defaultPrevented) { + if (this.open && !this.escapeDisabled && event.key === "Escape" && !event.defaultPrevented) { this.open = false; event.preventDefault(); }