mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 17:42:15 +08:00
fix(scroll-assist): allow focus on input's siblings (#30409)
Co-authored-by: Shane <shane@shanessite.net>
This commit is contained in:
@ -868,15 +868,6 @@ export class Input implements ComponentInterface {
|
||||
*/
|
||||
ev.preventDefault();
|
||||
}}
|
||||
onFocusin={(ev) => {
|
||||
/**
|
||||
* Prevent the focusin event from bubbling otherwise it will cause the focusin
|
||||
* event listener in scroll assist to fire. When this fires, focus will be moved
|
||||
* back to the input even if the clear button was never tapped. This poses issues
|
||||
* for screen readers as it means users would be unable to swipe past the clear button.
|
||||
*/
|
||||
ev.stopPropagation();
|
||||
}}
|
||||
onClick={this.clearTextInput}
|
||||
>
|
||||
<ion-icon aria-hidden="true" icon={clearIconData}></ion-icon>
|
||||
|
@ -181,6 +181,30 @@ const setManualFocus = (el: HTMLElement) => {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimization for scenarios where the currently focused element is a sibling
|
||||
* of the target element. In such cases, we avoid setting `SKIP_SCROLL_ASSIST`.
|
||||
*
|
||||
* This is crucial for accessibility: input elements can now contain focusable
|
||||
* siblings (e.g., clear buttons, slotted elements). If we didn't skip setting
|
||||
* the attribute here, screen readers would be unable to navigate to and interact
|
||||
* with these sibling elements.
|
||||
*
|
||||
* Without this check, we would need to call `ev.stopPropagation()` on the
|
||||
* 'focusin' event of each focusable sibling to prevent the scroll assist
|
||||
* listener from incorrectly moving focus back to the input. That approach
|
||||
* would be less maintainable and more error-prone.
|
||||
*/
|
||||
const inputId = el.getAttribute('id');
|
||||
const label = el.closest(`label[for="${inputId}"]`);
|
||||
const activeElLabel = document.activeElement?.closest(`label[for="${inputId}"]`);
|
||||
|
||||
if (label !== null && label === activeElLabel) {
|
||||
// If the label is the same as the active element label, then
|
||||
// we don't need to set the `SKIP_SCROLL_ASSIST` and reset focus.
|
||||
return;
|
||||
}
|
||||
|
||||
el.setAttribute(SKIP_SCROLL_ASSIST, 'true');
|
||||
el.focus();
|
||||
};
|
||||
|
Reference in New Issue
Block a user