From 3463bd72798f66902424c7061e33c1f2550f95ca Mon Sep 17 00:00:00 2001 From: johnlcos Date: Mon, 4 May 2026 11:12:33 -0400 Subject: [PATCH 1/3] fix: modal closing behavior with a file input --- dev/main.ts | 1 + package.json | 2 +- src/components/modal/modal.ts | 24 +++++++++++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/dev/main.ts b/dev/main.ts index e35ca93..e2c07ac 100644 --- a/dev/main.ts +++ b/dev/main.ts @@ -689,6 +689,7 @@ class DevApp extends LitElement { label="Modal Text Input" placeholder="Type something..." > +
(this.modalOpen = false)} diff --git a/package.json b/package.json index 9c3e4e4..6c7f8e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@krumio/trailhand-ui", - "version": "1.9.20", + "version": "1.9.21", "type": "module", "description": "Reusable web components built with Lit Element", "main": "./dist/index.js", diff --git a/src/components/modal/modal.ts b/src/components/modal/modal.ts index 681f463..5e6defa 100644 --- a/src/components/modal/modal.ts +++ b/src/components/modal/modal.ts @@ -163,6 +163,28 @@ export class Modal extends LitElement { this.open = false; } + private handleCancel(e: Event) { + e.preventDefault(); + } + + private handleKeydown = (e: KeyboardEvent) => { + if (!this.open) return; + + if (e.key === 'Escape' && this.dismissible) { + this.handleClose(); + } + }; + + connectedCallback() { + super.connectedCallback(); + window.addEventListener('keydown', this.handleKeydown); + } + + disconnectedCallback() { + window.removeEventListener('keydown', this.handleKeydown); + super.disconnectedCallback(); + } + private handleBackdropClick(e: MouseEvent) { if (!this.dismissible) return; const rect = this.dialog.getBoundingClientRect(); @@ -178,7 +200,7 @@ export class Modal extends LitElement { return html` Date: Mon, 4 May 2026 11:19:52 -0400 Subject: [PATCH 2/3] chore: update storybook test --- src/components/modal/modal.stories.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/modal/modal.stories.ts b/src/components/modal/modal.stories.ts index cfb4d96..36750e3 100644 --- a/src/components/modal/modal.stories.ts +++ b/src/components/modal/modal.stories.ts @@ -225,6 +225,7 @@ export const DispatchesCloseEventOnEscape: Story = { }, args: { open: true, + dismissible: true, }, play: async ({ canvasElement }) => { const modal = canvasElement.querySelector('trailhand-modal') as Modal; From 6056a8595b39bff4b56b81d80db590edd0edae1e Mon Sep 17 00:00:00 2001 From: johnlcos Date: Mon, 4 May 2026 11:26:23 -0400 Subject: [PATCH 3/3] chore: update storybook test --- src/components/modal/modal.stories.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/modal/modal.stories.ts b/src/components/modal/modal.stories.ts index 36750e3..a39c529 100644 --- a/src/components/modal/modal.stories.ts +++ b/src/components/modal/modal.stories.ts @@ -229,15 +229,12 @@ export const DispatchesCloseEventOnEscape: Story = { }, play: async ({ canvasElement }) => { const modal = canvasElement.querySelector('trailhand-modal') as Modal; - const dialog = modal.shadowRoot?.querySelector( - 'dialog', - ) as HTMLDialogElement; const onCloseMock = fn(); modal.addEventListener('modal-close', onCloseMock); - const cancelEvent = new Event('cancel', { bubbles: true, composed: true }); - dialog.dispatchEvent(cancelEvent); + // simulate ESC key + window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' })); await expect(modal.open).toBe(false); await expect(onCloseMock).toHaveBeenCalled();