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

bug: clicking non-focusable part of certain components inside ion-accordion will focus accordion header, triggering scroll

Open DevonStern opened this issue 2 years ago • 5 comments

Prerequisites

Ionic Framework Version

  • [ ] v4.x
  • [ ] v5.x
  • [X] v6.x

Current Behavior

When clicking on an IonIcon inside an IonItemOption inside an IonAccordian, it scrolls (or jumps, rather) to the top of the page. The click event for the IonItemOption is also not triggered.

Expected Behavior

The click event for the IonItemOption should be triggered and it should not scroll/jump to the top.

Steps to Reproduce

I have upgraded to the latest version of the Ionic CLI and created a minimum reproducible example of this in a new Ionic project. The project is using @Ionic/react 6.0.14.

Given the following conditions:

  • You have an IonAccordion with IonItemSliding components in it and those have an IonItemOption that has an IonIcon in it
  • You are not scrolled to the top of the page
  • You slide open an item and click on the icon (not on another part of the button, on the icon itself)

Then instead of triggering a normal click event on the option button, it takes you to the top of the page.

The issue does NOT occur under the following circumstances:

  • If you click on another part of any option button first and then click on the icon
  • If you are at the top of the page already

The issue still occurs regardless of the slot used for the IonIcon element, or if no slot is given. It also occurs regardless of whether or not there is text in the option, as well.

Code Reproduction URL

https://github.com/DevonStern/ionic-bug-ion-icon-in-ion-item-option/blob/master/src/pages/Home.tsx

Ionic Info

Ionic:

Ionic CLI : 6.19.0 (C:\Users\DevonStern\AppData\Roaming\npm\node_modules@ionic\cli) Ionic Framework : @ionic/react 6.0.14

Capacitor:

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

Utility:

cordova-res : 0.15.4 native-run : 1.5.0

System:

NodeJS : v16.13.2 (C:\Program Files\nodejs\node.exe) npm : 8.3.2 OS : Windows 10

Additional Information

In the code reproduction, check out src/pages/Home.tsx (the link takes you straight there).

DevonStern avatar Apr 06 '22 18:04 DevonStern

Thanks for the issue, I'm able to replicate this. It also happens in core. It looks like there's an odd interaction with focusing, somewhere between ion-accordion and ion-item-sliding. The page scrolls to the top because the accordion's header is being focused (and the header is at the top of the page).

Some other things I noticed:

  • The ion-icon isn't necessary; you can also trigger the issue by sliding the item open and then clicking on the item's white space, to the left of the buttons.
  • The item has to be slid open first; it doesn't trigger if you just click a closed item. Regular ion-items also don't trigger it.
  • Clicking the button first causes it to be focused, so when you click the item, focus instead moves to the ion-item-option.
  • I tried just having an ion-button with the ion-list below it, no accordion, and focus instead moved to the <body>. The same happened with wrapping the list in an ion-card with button="true".

averyjohnston avatar Apr 13 '22 16:04 averyjohnston

For others who are looking for a workaround for this, we found that calling preventDefault on the mouseDown event for ion-item-sliding did the trick.

For React:

onMouseDown={(event) => event.preventDefault()}

This is because the focus is blurred as a result of the mouseDown on ion-item-sliding, which allows it to later be taken by the accordion's header. We couldn't find any negative effects to this workaround, at least in our case.

DevonStern avatar May 13 '22 22:05 DevonStern

This can also occur with ion-card, as shown in https://github.com/ionic-team/ionic-framework/issues/28230.

averyjohnston avatar Sep 25 '23 14:09 averyjohnston

This can also occur with ion-card, as shown in #28230.

Still occurs. Any workaround ?

F-r-e-d avatar Dec 18 '23 08:12 F-r-e-d

In angular, we can use

<ion-list (mousedown)="preventFocus($event)">

and

preventFocus(event: MouseEvent) {
 event.preventDefault();
}

Renny1 avatar Jan 20 '24 00:01 Renny1