ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
50.93k stars 13.51k forks source link

bug: ion-item-sliding, updating options async while item is open should trigger item to move to accommodate new option set #28662

Open john-bunyan opened 9 months ago

john-bunyan commented 9 months ago

Prerequisites

Ionic Framework Version

v7.x

Current Behavior

I’m porting an app from ionic 6/cordova to ionic 7/capacitor and something that used to work on the old app is not functioning in the new one.

The scenario is that I’m using an ion-list of ion-item-sliding and I want to be able to dynamically add extra options into an open sliding row.

When I add an option to the row, it appears OK, but the ion-item-sliding text may now fully/partially cover it. So to get around this, I programmatically close() and open() the ion-item-sliding and the options are now fully visible.

Only problem now is that they are no longer clickable and the sliding item itself can’t be manually closed.

I’ve recreated the issue in this app based on the blank example…

Slide the item open. Click on the button to add extra option. Options appears OK… but no events.

Expected Behavior

After the close()/open() sequence the ion-item-sliding options should be enabled and actionable.

Steps to Reproduce

Slide the item open. Click on the button to add extra option. Options appears OK… but tapping/clicking on the options do not generate any events, they appear disabled..

Code Reproduction URL

https://github.com/john-bunyan/ion-item-sliding

Ionic Info

ionic info
[WARN] Error loading @ionic/angular package.json: Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './package' is not defined by "exports" in /Users/iss/Development/Slider/Slider/node_modules/@ionic/angular/package.json [WARN] Error loading @capacitor/ios package.json: Error: Cannot find module '@capacitor/ios/package'

   Require stack:
   - /usr/local/lib/node_modules/@ionic/cli/lib/project/index.js
   - /usr/local/lib/node_modules/@ionic/cli/lib/index.js
   - /usr/local/lib/node_modules/@ionic/cli/index.js
   - /usr/local/lib/node_modules/@ionic/cli/bin/ionic

[WARN] Error loading @capacitor/android package.json: Error: Cannot find module '@capacitor/android/package'

   Require stack:
   - /usr/local/lib/node_modules/@ionic/cli/lib/project/index.js
   - /usr/local/lib/node_modules/@ionic/cli/lib/index.js
   - /usr/local/lib/node_modules/@ionic/cli/index.js
   - /usr/local/lib/node_modules/@ionic/cli/bin/ionic

Ionic:

Ionic CLI : 6.19.1 (/usr/local/lib/node_modules/@ionic/cli) Ionic Framework : not installed @angular-devkit/build-angular : 17.0.5 @angular-devkit/schematics : 17.0.5 @angular/cli : 17.0.5 @ionic/angular-toolkit : 9.0.0

Capacitor:

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

Utility:

cordova-res : not installed globally native-run (update available: 2.0.0) : 1.7.4

System:

NodeJS : v18.16.1 (/Users/iss/.nvm/versions/node/v18.16.1/bin/node) npm : 9.5.1 OS : macOS

Additional Information

No response

averyjohnston commented 9 months ago

Thank you for the issue, I can replicate the reported behavior. The problem is that when calling the close() and open() methods rapidly like this, open doesn't wait for close to finish, so the item gets stuck in a weird in-between state where it is visually open but the option buttons aren't interactable. This also occurs in Ionic core. If you comment out the close/open calls, and instead call them manually in the dev console (waiting for the animation to finish each time), the problem does not occur.

The two methods currently return Promises, but awaiting them does nothing because they aren't actually waiting for the animation to finish before resolving.

However, even if we adjusted the methods to resolve at the proper time, this would not solve your use case since your workaround of calling close() and open() back to back would start displaying extra animations. Instead, we should get at the root problem, which is that when updating the options async, the item does not move to handle the new options, and may cover up options or leave empty space.

To summarize, there are three separate issues here:

  1. Adding or removing options async while the item is open does not trigger the item to move again to accommodate the updated option set.
  2. The open and close methods do not wait for any other active animations to finish before running.
  3. Despite returning Promises, the open and close methods do not wait for their own animations to finish before resolving.

If we fix issue 1, 2 and 3 will become redundant as it pertains to your use case, but we should still look into them regardless.

john-bunyan commented 9 months ago

Thanks for investigating this issue. I've reworked my UX to work around this for now, I hope this helps anybody else that encounters this behaviour.