ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

bug: conditional appearance of the content of an ion-item prevent click on right and left edge of the ion-item (with checkbox)

Open JulienLecoq opened this issue 1 year ago • 7 comments
trafficstars

Prerequisites

Ionic Framework Version

v8.x

Current Behavior

When putting a ion-checkbox inside of an ion-item, the click on the right and left edge of the ion-item only works at the beginning. Once I hide and show again the checkbox, the click on the right and left edge of the ion-item does not work anymore.

https://github.com/user-attachments/assets/2d3c7e10-3c44-4879-a9c8-e5a5bc6fab0f

Expected Behavior

The ion-item should be clickable after hiding/showing the checkbox.

Steps to Reproduce

  1. Paste the following code in a page:
  <ion-item>
    @if (showCheckbox()) {
      <ion-checkbox (ionChange)="stateChange()">Test checkbox</ion-checkbox>
    } @else {
    <ion-label>
      Test checkbox
    </ion-label>

    <ion-spinner
      slot="end"
      name="lines"
      class="item-spinner">
    </ion-spinner>
    }
  </ion-item>

  <ion-button (click)="toggleDisplay()">Toggle</ion-button>
  showCheckbox = signal(true)

  stateChange() {
    console.log('Checkbox state changed.')
  }

  toggleDisplay() {
    this.showCheckbox.set(!this.showCheckbox())
  }
  1. Try to click on the left or right edge of the ion-item after toggling the display of the checkbox once.
  2. The click should not work after toggling the display.

Code Reproduction URL

https://github.com/JulienLecoq/ion-item_click_bug_after_toggling_display/tree/main

Ionic Info

Ionic:

Ionic CLI : 7.2.0 (/Users/julien_lecoq/.nvm/versions/node/v20.14.0/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 8.2.6 @angular-devkit/build-angular : 18.1.4 @angular-devkit/schematics : 18.1.4 @angular/cli : 18.1.4 @ionic/angular-toolkit : 11.0.1

Capacitor:

Capacitor CLI : 6.1.2 @capacitor/android : not installed @capacitor/core : 6.1.2 @capacitor/ios : not installed

Utility:

cordova-res : not installed globally native-run : 2.0.1

System:

NodeJS : v20.14.0 (/Users/julien_lecoq/.nvm/versions/node/v20.14.0/bin/node) npm : 10.7.0 OS : macOS Unknown

Additional Information

No response

JulienLecoq avatar Aug 11 '24 19:08 JulienLecoq

Bind your checkbox to a state which holds if its checked or unchecked, and it should work just as expected.

I don't believe this to be a problem with ionic

dev-charles15531 avatar Aug 11 '24 21:08 dev-charles15531

It does not change anything, the problem still occurs.

JulienLecoq avatar Aug 12 '24 12:08 JulienLecoq

Please can you try reproducing your code on stackblitz and dropping a link here?

It's easier when people want to help

dev-charles15531 avatar Aug 12 '24 18:08 dev-charles15531

Well, there is the GitHub link as requested by the form to create the issue.

JulienLecoq avatar Aug 12 '24 19:08 JulienLecoq

Hello @JulienLecoq thanks for reporting this issue, I am able to reproduce.

The problem is caused by the ion-item not triggering a re-render when using the control flow syntax to dynamically render the spinner or checkbox as slotted contents.

  • On initial render the item detects an interactive element (checkbox)
  • Clicking toggle flips the state and the item re-renders, it is now not able to detect an interactive element (this is correct)
  • Click toggle flips the state, but the item's render function is not called this time.

Related implementation code: https://github.com/ionic-team/ionic-framework/blob/9c4ba2e30476725c34015a95a92bb14e9ab3d418/core/src/components/item/item.tsx#L276-L310

As a workaround I would recommend using the control flow syntax to render the entire item conditionally. This will guarantee it is rendered in the correct state:

@if (showCheckbox()) {
<ion-item>
  <ion-checkbox (ionChange)="stateChange()">Test checkbox</ion-checkbox>
</ion-item>
} @else {
<ion-item>
  <ion-label> Test checkbox </ion-label>

  <ion-spinner slot="end" name="lines" class="item-spinner"> </ion-spinner>
</ion-item>
}

sean-perkins avatar Aug 13 '24 03:08 sean-perkins

@sean-perkins I am not able to reproduce same problem with vue, so is the problem from the core item component or from the angular package?

dev-charles15531 avatar Aug 14 '24 21:08 dev-charles15531

@dev-charles15531 the problematic behavior is likely caused by Angular's control flow syntax, but the fix can be applied in core to account for it consistently.

I suspect that the control flow syntax rendering will cause a slotchange event to fire on the default slot. We can then use that event to trigger a re-render of the item if the number of interactive elements changes from 0 → 1+ or 1+ → 0.

sean-perkins avatar Aug 16 '24 04:08 sean-perkins

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

ionitron-bot[bot] avatar Aug 14 '25 22:08 ionitron-bot[bot]