kopia lustrzana https://github.com/wagtail/wagtail
Add confirm() method to DialogController
Like hide(), but dispatches an event to indicate that the dialog was 'confirmed'pull/12185/head
rodzic
1c2616623d
commit
3e6e4f2ee3
|
@ -103,6 +103,70 @@ describe('DialogController', () => {
|
|||
expect(document.documentElement.style.overflowY).toBe('');
|
||||
});
|
||||
|
||||
it('should support the ability to confirm the dialog with an event to indicate the confirmation', async () => {
|
||||
const hiddenListener = jest.fn();
|
||||
document.addEventListener('w-dialog:hidden', hiddenListener);
|
||||
|
||||
const confirmedListener = jest.fn();
|
||||
document.addEventListener('w-dialog:confirmed', confirmedListener);
|
||||
|
||||
// Add a confirm button to the dialog
|
||||
const dialogBody = document.getElementById('dialog-body');
|
||||
const confirmButton = document.createElement('button');
|
||||
confirmButton.type = 'button';
|
||||
confirmButton.setAttribute('data-action', 'w-dialog#confirm');
|
||||
dialogBody.appendChild(confirmButton);
|
||||
|
||||
application.start();
|
||||
|
||||
await Promise.resolve();
|
||||
|
||||
expect(hiddenListener).not.toHaveBeenCalled();
|
||||
expect(confirmedListener).not.toHaveBeenCalled();
|
||||
|
||||
const dialog = document.getElementById('dialog-container');
|
||||
|
||||
// closed by default
|
||||
expect(dialog.getAttribute('aria-hidden')).toEqual('true');
|
||||
expect(document.documentElement.style.overflowY).toBe('');
|
||||
|
||||
// show the dialog manually
|
||||
dialog.dispatchEvent(new CustomEvent('w-dialog:show'));
|
||||
|
||||
expect(dialog.getAttribute('aria-hidden')).toEqual(null);
|
||||
expect(hiddenListener).not.toHaveBeenCalled();
|
||||
expect(confirmedListener).not.toHaveBeenCalled();
|
||||
// add style to root element on shown by default
|
||||
expect(document.documentElement.style.overflowY).toBe('hidden');
|
||||
|
||||
// hide the dialog using the confirm button
|
||||
confirmButton.click();
|
||||
|
||||
expect(dialog.getAttribute('aria-hidden')).toEqual('true');
|
||||
|
||||
// w-dialog:hide event should still be dispatched
|
||||
expect(hiddenListener).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
detail: expect.objectContaining({
|
||||
body: dialogBody,
|
||||
dialog: expect.any(Object),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
// reset style on root element when hidden by default
|
||||
expect(document.documentElement.style.overflowY).toBe('');
|
||||
|
||||
// w-dialog:confirmed event should be dispatched
|
||||
expect(confirmedListener).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
detail: expect.objectContaining({
|
||||
body: dialogBody,
|
||||
dialog: expect.any(Object),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should support the ability use a theme to avoid document style change', async () => {
|
||||
const dialog = document.getElementById('dialog-container');
|
||||
|
||||
|
|
|
@ -29,14 +29,17 @@ export class DialogController extends Controller<HTMLElement> {
|
|||
/** Optional targets that will be dispatched events for key dialog events. */
|
||||
declare readonly notifyTargets: HTMLElement[];
|
||||
|
||||
get eventDetail() {
|
||||
return { body: this.bodyTarget, dialog: this.dialog };
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.dialog = new A11yDialog(this.element);
|
||||
const detail = { body: this.bodyTarget, dialog: this.dialog };
|
||||
const isFloating = this.themeValue === FLOATING;
|
||||
this.dialog
|
||||
.on('show', () => {
|
||||
if (!isFloating) document.documentElement.style.overflowY = 'hidden';
|
||||
this.dispatch('shown', { detail, cancelable: false });
|
||||
this.dispatch('shown', { detail: this.eventDetail, cancelable: false });
|
||||
this.notifyTargets.forEach((target) => {
|
||||
this.dispatch('shown', {
|
||||
target,
|
||||
|
@ -47,7 +50,10 @@ export class DialogController extends Controller<HTMLElement> {
|
|||
})
|
||||
.on('hide', () => {
|
||||
if (!isFloating) document.documentElement.style.overflowY = '';
|
||||
this.dispatch('hidden', { detail, cancelable: false });
|
||||
this.dispatch('hidden', {
|
||||
detail: this.eventDetail,
|
||||
cancelable: false,
|
||||
});
|
||||
this.notifyTargets.forEach((target) => {
|
||||
this.dispatch('hidden', {
|
||||
target,
|
||||
|
@ -56,7 +62,7 @@ export class DialogController extends Controller<HTMLElement> {
|
|||
});
|
||||
});
|
||||
});
|
||||
this.dispatch('ready', { detail });
|
||||
this.dispatch('ready', { detail: this.eventDetail });
|
||||
if (this.notifyTargets && Array.isArray(this.notifyTargets)) {
|
||||
this.notifyTargets.forEach((target) => {
|
||||
this.dispatch('ready', { target, bubbles: false, cancelable: false });
|
||||
|
@ -72,4 +78,9 @@ export class DialogController extends Controller<HTMLElement> {
|
|||
show() {
|
||||
this.dialog.show();
|
||||
}
|
||||
|
||||
confirm() {
|
||||
this.hide();
|
||||
this.dispatch('confirmed', { detail: this.eventDetail, cancelable: false });
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue