fix(overlays): trap focus inside overlay components except toast (#21716)

fixes #21647
This commit is contained in:
Liam DeBeasi
2020-07-22 12:09:31 -04:00
committed by GitHub
parent eb592b8917
commit fff4aec6cf
15 changed files with 377 additions and 30 deletions

View File

@ -26,6 +26,7 @@ import { mdLeaveAnimation } from './animations/md.leave';
export class ActionSheet implements ComponentInterface, OverlayInterface {
presented = false;
lastFocus?: HTMLElement;
animation?: any;
private wrapperEl?: HTMLElement;
private groupEl?: HTMLElement;
@ -250,7 +251,10 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
onIonBackdropTap={this.onBackdropTap}
>
<ion-backdrop tappable={this.backdropDismiss}/>
<div class="action-sheet-wrapper" role="dialog" ref={el => this.wrapperEl = el}>
<div tabindex="0"></div>
<div class="action-sheet-wrapper ion-overlay-wrapper" role="dialog" ref={el => this.wrapperEl = el}>
<div class="action-sheet-container">
<div class="action-sheet-group" ref={el => this.groupEl = el}>
{this.header !== undefined &&
@ -292,6 +296,8 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
}
</div>
</div>
<div tabindex="0"></div>
</Host>
);
}

View File

@ -1,6 +1,40 @@
import { testActionSheet, testActionSheetAlert, testActionSheetBackdrop } from '../test.utils';
import { newE2EPage } from '@stencil/core/testing';
const DIRECTORY = 'basic';
const getActiveElementText = async (page) => {
const activeElement = await page.evaluateHandle(() => document.activeElement);
return await page.evaluate(el => el && el.textContent, activeElement);
}
test('action-sheet: focus trap', async () => {
const page = await newE2EPage({ url: '/src/components/action-sheet/test/basic?ionic:_testing=true' });
await page.click('#basic');
await page.waitForSelector('#basic');
let actionSheet = await page.find('ion-action-sheet');
expect(actionSheet).not.toBe(null);
await actionSheet.waitForVisible();
await page.keyboard.press('Tab');
const activeElementText = await getActiveElementText(page);
expect(activeElementText).toEqual('Delete');
await page.keyboard.down('Shift');
await page.keyboard.press('Tab');
await page.keyboard.up('Shift');
const activeElementTextTwo = await getActiveElementText(page);
expect(activeElementTextTwo).toEqual('Cancel');
await page.keyboard.press('Tab');
const activeElementTextThree = await getActiveElementText(page);
expect(activeElementTextThree).toEqual('Delete');
});
test('action-sheet: basic', async () => {
await testActionSheet(DIRECTORY, '#basic');