appAutoFocus causes modal to freeze on presentation
VincenzoManto opened this issue · 0 comments
Ionic version:
[x] 7.x
[ ] 6.x
[ ] 5.x
[ ] 4.x
on Angular
I'm submitting a ...
[x] bug report
[ ] feature request
Current behavior:
When using the appAutoFocus
directive on an ion-input
in the calling page (not the modal), presenting a modal using modalController.present()
causes the app to freeze or become unresponsive. The issue appears to stem from the appAutoFocus
directive repeatedly requesting focus for the ion-input
in the calling page, leading to a conflict with the modal's lifecycle.
Expected behavior:
The modal should present smoothly without being affected by directives or inputs in the calling page. The appAutoFocus
directive should not interfere with the modal's focus management.
Steps to reproduce:
- Create a page with an
ion-input
using theappAutoFocus
directive. - Add a button on the page to open a modal using
modalController
. - Present the modal.
- Observe the app freezing or becoming unresponsive.
Related code:
Calling Page:
<ion-app>
<ion-content>
<ion-input appAutoFocus placeholder="Focus me"></ion-input>
<ion-button expand="block" (click)="presentModal()">Open Modal</ion-button>
</ion-content>
</ion-app>
Component Code:
import { Component } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { SearchResultPage } from './search-result.page';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss'],
})
export class AppComponent {
constructor(private modalController: ModalController) {}
async presentModal() {
const modal = await this.modalController.create({
component: SearchResultPage, // the behaviour is indipendent from modal content
backdropDismiss: false,
});
await modal.present();
}
}
@Directive({
selector: '[appAutofocus]',
})
/**
* direttiva per impostare AutoFocus su campo di input
*/
export class AutofocusDirective implements AfterContentChecked {
constructor(private element: IonInput) {
}
ngAfterContentChecked(): void {
this.element.setFocus();
}
}
Other information:
This issue can be temporarily avoided by disabling the appAutoFocus
directive before presenting the modal and re-enabling it after the modal is dismissed, as shown below:
async presentModal() {
const input = document.querySelector('ion-input[appAutoFocus]');
if (input) {
input.removeAttribute('appAutoFocus');
}
const modal = await this.modalController.create({
component: SearchResultPage,
backdropDismiss: false,
});
await modal.present();
await modal.onDidDismiss();
if (input) {
input.setAttribute('appAutoFocus', '');
}
}
It seems that the appAutoFocus
directive is not paused or detached from the calling page when the modal takes focus. This leads to a conflict where both the modal and the calling page attempt to manage focus.
The appAutoFocus
directive should detect when its parent component loses focus (e.g., when a modal is presented) and temporarily stop requesting focus until the parent regains visibility.