@@ -74,6 +74,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
7474 private currentBreakpoint ?: number ;
7575 private wrapperEl ?: HTMLElement ;
7676 private backdropEl ?: HTMLIonBackdropElement ;
77+ private dragHandleEl ?: HTMLButtonElement ;
7778 private sortedBreakpoints ?: number [ ] ;
7879 private keyboardOpenCallback ?: ( ) => void ;
7980 private moveSheetToBreakpoint ?: ( options : MoveSheetToBreakpointOptions ) => Promise < void > ;
@@ -950,6 +951,18 @@ export class Modal implements ComponentInterface, OverlayInterface {
950951 }
951952 } ;
952953
954+ /**
955+ * When the modal receives focus directly, pass focus to the handle
956+ * if it exists and is focusable, otherwise let the focus trap handle it.
957+ */
958+ private onModalFocus = ( ev : FocusEvent ) => {
959+ const { dragHandleEl, el } = this ;
960+ // Only handle focus if the modal itself was focused (not a child element)
961+ if ( ev . target === el && dragHandleEl && dragHandleEl . tabIndex !== - 1 ) {
962+ dragHandleEl . focus ( ) ;
963+ }
964+ } ;
965+
953966 render ( ) {
954967 const {
955968 handle,
@@ -991,6 +1004,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
9911004 onIonModalWillPresent = { this . onLifecycle }
9921005 onIonModalWillDismiss = { this . onLifecycle }
9931006 onIonModalDidDismiss = { this . onLifecycle }
1007+ onFocus = { this . onModalFocus }
9941008 >
9951009 < ion-backdrop
9961010 ref = { ( el ) => ( this . backdropEl = el ) }
@@ -1023,6 +1037,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
10231037 aria-label = "Activate to adjust the size of the dialog overlaying the screen"
10241038 onClick = { isHandleCycle ? this . onHandleClick : undefined }
10251039 part = "handle"
1040+ ref = { ( el ) => ( this . dragHandleEl = el ) }
10261041 > </ button >
10271042 ) }
10281043 < slot > </ slot >
0 commit comments