fix(all): ripple effect is no longer added when scrolling #25352
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Pull request checklist
Please check if your PR fulfills the following requirements:
ionic-docs
repo, in a separate PR. See the contributing guide for details.npm run build
) was run locally and any changes were pushednpm run lint
) has passed locally and any fixes were made for failuresPull request type
Please check the type of change your PR introduces:
What is the current behavior?
Issue URL: resolves #22030
The tap click utility in Ionic ensures that the active state is added to interactives on iOS and Android. On iOS this is an active shade color. On Android this is the ripple effect.
To align with native, the active state should never be added when scrolling. For example, if you begin to scroll by tapping on a button, that button should not receive the ripple effect. See the below example on Android 12:
demo.mp4
Observe that the ripple effect does not appear on items as the user scrolls. However, when tapping/pressing an item when not scrolling shows the ripple effect.
In Ionic, this used to work by listening for the
scroll
event onion-content
. However, this behavior unintentionally changed in fd1b44a. The downside of this approach is that it adds quite a bit of main thread work due to the scroll listener.How this all comes together is on
touchstart
, we create asetTimeout
(https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/tap-click.ts#L103) which, when fired, will add the activated state. When we detect scrolling, thecancelActive
function is invoked (https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/tap-click.ts#L151) which cancels thesetTimeout
.What is the new behavior?
pointercancel
event. This event is dispatched when the pointer is used to pan, zoom, or scroll (among other things): https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/pointercancel_eventWhen tap click was originally built, the PointerEvents API was not supported in all of the browsers Ionic supports. That is no longer true today: https://caniuse.com/mdn-api_pointerevent
When we begin to scroll, the
pointercancel
event is fired which then callscancelActive
which prevents the active state from being added.See a demo below:
main
branch.mp4
fix.mp4
current-ios.mp4
fix-ios.mp4
There is another bug on Android that this change fixes. Currently, when you swipe on an interactive (but don't scroll), the ripple effect is added to the element. However, the browser never dispatches the
click
event, so it looks like you selected the element and nothing happened. Withpointercancel
, this no longer happens.See a demo below
main
header-now.mp4
header-fix.mp4
Note: Safari does not dispatch
pointercancel
in this scenario. However, this bug existed even when we were using the old scroll events method so I am not sure it's worth fixing at the moment.Does this introduce a breaking change?
Other information