mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 10:41:13 +08:00
fix(accordion-group): only allow keyboard interaction if header is focused (#25091)
This commit is contained in:
@ -101,6 +101,17 @@ export class AccordionGroup implements ComponentInterface {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure focus is in the header, not the body, of the accordion. This ensures
|
||||||
|
* that if there are any interactable elements in the body, their keyboard
|
||||||
|
* interaction doesn't get stolen by the accordion. Example: using up/down keys
|
||||||
|
* in ion-textarea.
|
||||||
|
*/
|
||||||
|
const activeAccordionHeader = activeElement.closest('ion-accordion [slot="header"]');
|
||||||
|
if (!activeAccordionHeader) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const accordionEl =
|
const accordionEl =
|
||||||
activeElement.tagName === 'ION-ACCORDION' ? activeElement : activeElement.closest('ion-accordion');
|
activeElement.tagName === 'ION-ACCORDION' ? activeElement : activeElement.closest('ion-accordion');
|
||||||
if (!accordionEl) {
|
if (!accordionEl) {
|
||||||
|
@ -5,6 +5,11 @@ const getActiveElementText = async (page) => {
|
|||||||
return page.evaluate((el) => el?.innerText, activeElement);
|
return page.evaluate((el) => el?.innerText, activeElement);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getActiveInputID = async (page) => {
|
||||||
|
const activeElement = await page.evaluateHandle(() => document.activeElement);
|
||||||
|
return page.evaluate((el) => el?.closest('ion-input')?.id, activeElement);
|
||||||
|
};
|
||||||
|
|
||||||
test('accordion: a11y', async () => {
|
test('accordion: a11y', async () => {
|
||||||
const page = await newE2EPage({
|
const page = await newE2EPage({
|
||||||
url: '/src/components/accordion/test/a11y?ionic:_testing=true',
|
url: '/src/components/accordion/test/a11y?ionic:_testing=true',
|
||||||
@ -42,4 +47,17 @@ test('accordion: keyboard navigation', async () => {
|
|||||||
|
|
||||||
await page.keyboard.press('ArrowUp');
|
await page.keyboard.press('ArrowUp');
|
||||||
expect(await getActiveElementText(page)).toEqual('Shipping Address');
|
expect(await getActiveElementText(page)).toEqual('Shipping Address');
|
||||||
|
|
||||||
|
// open Shipping Address accordion and move focus to the input inside it
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
|
await page.waitForChanges();
|
||||||
|
await page.keyboard.press('Tab');
|
||||||
|
|
||||||
|
const activeID = await getActiveInputID(page);
|
||||||
|
expect(activeID).toEqual('address1');
|
||||||
|
|
||||||
|
// ensure keyboard interaction doesn't move focus from body
|
||||||
|
await page.keyboard.press('ArrowDown');
|
||||||
|
const activeIDAgain = await getActiveInputID(page);
|
||||||
|
expect(activeIDAgain).toEqual('address1');
|
||||||
});
|
});
|
||||||
|
@ -86,7 +86,7 @@
|
|||||||
<ion-list slot="content">
|
<ion-list slot="content">
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label>Address 1</ion-label>
|
<ion-label>Address 1</ion-label>
|
||||||
<ion-input type="text"></ion-input>
|
<ion-input id="address1" type="text"></ion-input>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label>Address 2</ion-label>
|
<ion-label>Address 2</ion-label>
|
||||||
|
Reference in New Issue
Block a user