Skip to content

appAutoFocus causes modal to freeze on presentation #30046

Closed
@VincenzoManto

Description

@VincenzoManto

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:

  1. Create a page with an ion-input using the appAutoFocus directive.
  2. Add a button on the page to open a modal using modalController.
  3. Present the modal.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions