Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(modal): keep focus trap between stack modals
- Loading branch information
Showing
9 changed files
with
145 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<h3>Modal nesting tests</h3> | ||
|
||
<ng-template #t let-modal> | ||
<div class="modal-header"> | ||
<h4 class="modal-title">Modal with nested popups</h4> | ||
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss()"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
<div class="modal-body"> | ||
<!-- modal --> | ||
<button id="open-inner-modal" class="btn btn-lg btn-outline-primary" (click)="openSecondModal()">Open stack modal</button> | ||
</div> | ||
</ng-template> | ||
|
||
<button class="btn btn-outline-secondary ml-2" type="button" id="open-modal" (click)="openModal(t)">Open Modal</button> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import {Component, TemplateRef} from '@angular/core'; | ||
import {NgbActiveModal, NgbModal} from '@ng-bootstrap/ng-bootstrap'; | ||
import {Observable} from 'rxjs'; | ||
import {map} from 'rxjs/operators'; | ||
|
||
@Component({templateUrl: './modal-stack.component.html'}) | ||
export class ModalStackComponent { | ||
constructor(private modalService: NgbModal) {} | ||
|
||
openModal(content: TemplateRef<any>) { this.modalService.open(content); } | ||
|
||
search = (text$: Observable<string>) => text$.pipe(map(() => ['one', 'two', 'three'])); | ||
|
||
openSecondModal() { this.modalService.open(NgbdStackedModal); } | ||
} | ||
|
||
@Component({ | ||
template: ` | ||
<div class="modal-header"> | ||
<h4 class="modal-title">Stacked modal</h4> | ||
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
<div class="modal-body"></div> | ||
<div class="modal-footer"> | ||
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button> | ||
</div> | ||
` | ||
}) | ||
export class NgbdStackedModal { | ||
constructor(public activeModal: NgbActiveModal) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import {Key, browser} from 'protractor'; | ||
import {expectFocused, expectNoOpenModals, openUrl, sendKey} from '../../tools.po'; | ||
import {ModalStackPage} from './modal-stack.po'; | ||
import {DatepickerPage} from '../../datepicker/datepicker.po'; | ||
import {DropdownPage} from '../../dropdown/dropdown.po'; | ||
import {TypeaheadPage} from '../../typeahead/typeahead.po'; | ||
|
||
describe('Modal stacked', () => { | ||
let page: ModalStackPage; | ||
let datepickerPage: DatepickerPage; | ||
let dropdownPage: DropdownPage; | ||
let typeaheadPage: TypeaheadPage; | ||
|
||
beforeAll(() => { | ||
page = new ModalStackPage(); | ||
datepickerPage = new DatepickerPage(); | ||
dropdownPage = new DropdownPage(); | ||
typeaheadPage = new TypeaheadPage(); | ||
}); | ||
|
||
beforeEach(async() => await openUrl('modal/stack')); | ||
|
||
afterEach(async() => { await expectNoOpenModals(); }); | ||
|
||
it('should keep tab on the first modal after the second modal has closed', async() => { | ||
await page.openModal(); | ||
await page.openStackModal(); | ||
|
||
// close the stack modal | ||
await sendKey(Key.ESCAPE); | ||
|
||
// Check that the button is focused again | ||
await expectFocused(page.getStackModalButton(), 'Button element not focused'); | ||
await sendKey(Key.TAB); | ||
|
||
await expectFocused(page.getCoseIcon(), 'Close icon not focused'); | ||
|
||
// close the main modal | ||
await sendKey(Key.ESCAPE); | ||
|
||
}); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import {$, $$} from 'protractor'; | ||
|
||
export class ModalStackPage { | ||
getModal(index) { return $$('ngb-modal-window').get(index); } | ||
|
||
getModalButton() { return $('#open-modal'); } | ||
|
||
getStackModalButton() { return $('#open-inner-modal'); } | ||
|
||
getCoseIcon() { return $('button.close'); } | ||
|
||
async openModal() { | ||
await this.getModalButton().click(); | ||
const modal = this.getModal(0); | ||
expect(await modal.isPresent()).toBeTruthy(`A modal should have been opened`); | ||
return modal; | ||
} | ||
|
||
async openStackModal() { | ||
await this.getStackModalButton().click(); | ||
const modal = this.getModal(1); | ||
expect(await modal.isPresent()).toBeTruthy(`A second modal should have been opened`); | ||
return modal; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters