@@ -11,7 +11,7 @@ import { registerComponent } from '../common/definitions/register.js';
1111import type { Constructor } from '../common/mixins/constructor.js' ;
1212import { EventEmitterMixin } from '../common/mixins/event-emitter.js' ;
1313import { partMap } from '../common/part-map.js' ;
14- import { numberInRangeInclusive } from '../common/util.js' ;
14+ import { bindIf , numberInRangeInclusive } from '../common/util.js' ;
1515import { styles } from './themes/dialog.base.css.js' ;
1616import { styles as shared } from './themes/shared/dialog.common.css.js' ;
1717import { all } from './themes/themes.js' ;
@@ -163,6 +163,10 @@ export default class IgcDialogComponent extends EventEmitterMixin<
163163 return true ;
164164 }
165165
166+ private _closeWithEvent ( ) : void {
167+ this . _hide ( true ) ;
168+ }
169+
166170 protected _handleFormSubmit ( event : SubmitEvent ) : void {
167171 const form = event . target as HTMLFormElement ;
168172
@@ -172,7 +176,7 @@ export default class IgcDialogComponent extends EventEmitterMixin<
172176 }
173177
174178 if ( ! event . defaultPrevented ) {
175- this . _hide ( true ) ;
179+ this . _closeWithEvent ( ) ;
176180 }
177181 }
178182 }
@@ -181,7 +185,16 @@ export default class IgcDialogComponent extends EventEmitterMixin<
181185 event . preventDefault ( ) ;
182186
183187 if ( ! this . keepOpenOnEscape ) {
184- this . _hide ( true ) ;
188+ this . _closeWithEvent ( ) ;
189+ }
190+ }
191+
192+ private _handleClose ( ) : void {
193+ // When a non-cancelable close event is fired (e.g., from repeated Escape presses),
194+ // reopen the dialog to prevent the broken state with visible backdrop.
195+ // Note that this handler is invoked only when `keepOpenOnEscape` is true.
196+ if ( this . open ) {
197+ this . _dialog . showModal ( ) ;
185198 }
186199 }
187200
@@ -192,7 +205,7 @@ export default class IgcDialogComponent extends EventEmitterMixin<
192205 const inY = numberInRangeInclusive ( clientY , rect . top , rect . bottom ) ;
193206
194207 if ( ! ( inX && inY ) ) {
195- this . _hide ( true ) ;
208+ this . _closeWithEvent ( ) ;
196209 }
197210 }
198211 }
@@ -262,7 +275,7 @@ export default class IgcDialogComponent extends EventEmitterMixin<
262275 ${ this . hideDefaultAction
263276 ? nothing
264277 : html `
265- < igc-button variant ="flat " @click =${ ( ) => this . _hide ( true ) } >
278+ < igc-button variant ="flat " @click =${ this . _closeWithEvent } >
266279 OK
267280 </ igc-button >
268281 ` }
@@ -283,10 +296,11 @@ export default class IgcDialogComponent extends EventEmitterMixin<
283296 ${ ref ( this . _dialogRef ) }
284297 part =${ partMap ( { base : true , titled : hasTitle , footed : hasFooter } ) }
285298 role ="dialog"
286- aria-label=${ this . ariaLabel || nothing }
287- aria-labelledby=${ labelledBy || nothing }
299+ aria-label=${ bindIf ( this . ariaLabel , this . ariaLabel ) }
300+ aria-labelledby=${ bindIf ( labelledBy , labelledBy ) }
288301 @click=${ this . _handleClick }
289302 @cancel=${ this . _handleCancel }
303+ @close=${ bindIf ( this . keepOpenOnEscape , this . _handleClose ) }
290304 >
291305 ${ this . _renderHeader ( ) } ${ this . _renderContent ( ) } ${ this . _renderFooter ( ) }
292306 </ dialog >
0 commit comments