ShaneK · GitHub

Issue number: resolves #30412


What is the current behavior?

When a user listener bound to ion-input or ion-item receives a tap that requires scroll assist to scroll the input into view, the click handler fires twice. Programmatic setFocus() and keyboard focus into an offscreen input also dispatch a phantom click event the developer didn't request.

The cause is scroll-assist.ts: after relocateInput moves the native input, a RAF-scheduled componentEl.click() re-emits a click on the host. That recovery was added in #22845 (Feb 2021) to fix #21871, when scroll assist drove focus from its own touchstart/touchend listeners and relocateInput ran during the in-flight click event's lifecycle.

What is the new behavior?

The RAF recovery click is removed. #25848 (Sep 2022) restructured scroll assist to react to focusin rather than drive focus from touch events, so relocateInput now runs strictly after the click event has finished propagating. Combined with ion-input's click capture handler and ion-item's click-on-padding handler from #30373 (April 2025), the click is always dispatched on the component host before scroll assist runs. Re-firing it produced duplicate clicks for user interactions and phantom clicks for programmatic and keyboard focus.

Does this introduce a breaking change?

  • Yes
  • No

Other information

Regression coverage in core/src/components/input/test/item/scroll-assist-double-click.e2e.ts covers four cases on iOS Mobile Safari and Mobile Chrome: padding click, direct input click, programmatic setFocus(), and keyboard focus. The first two assert one click event; the last two assert zero. All four fail without this change and pass with it.

Preview:

Read the original on github.com ↗