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();
|
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}
|
onClick={this.clearTextInput}
|
||||||
>
|
>
|
||||||
<ion-icon aria-hidden="true" icon={clearIconData}></ion-icon>
|
<ion-icon aria-hidden="true" icon={clearIconData}></ion-icon>
|
||||||
|
@ -181,6 +181,30 @@ const setManualFocus = (el: HTMLElement) => {
|
|||||||
return;
|
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.setAttribute(SKIP_SCROLL_ASSIST, 'true');
|
||||||
el.focus();
|
el.focus();
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user