Commit 1afc7062 authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Allow notebook to be closed by pressing Esc

parent 1d898d40
import { IconButton, CancelIcon } from '@hypothesis/frontend-shared';
import classnames from 'classnames';
import type { ComponentChildren } from 'preact';
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
import {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'preact/hooks';
import { addConfigFragment } from '../../shared/config-fragment';
import { createAppConfig } from '../config/app';
......@@ -56,9 +62,13 @@ export type NotebookModalProps = {
document_?: Document;
};
type DialogProps = { isHidden: boolean; children: ComponentChildren };
type DialogProps = {
isHidden: boolean;
children: ComponentChildren;
onClose: () => void;
};
const NativeDialog = ({ isHidden, children }: DialogProps) => {
const NativeDialog = ({ isHidden, children, onClose }: DialogProps) => {
const dialogRef = useRef<HTMLDialogElement | null>(null);
useEffect(() => {
......@@ -69,18 +79,14 @@ const NativeDialog = ({ isHidden, children }: DialogProps) => {
}
}, [isHidden]);
// Prevent the dialog from closing when `Esc` is pressed, to keep previous
// behavior
useEffect(() => {
const dialogElement = dialogRef.current;
const listener = (event: Event) => event.preventDefault();
dialogElement?.addEventListener('cancel', listener);
dialogElement?.addEventListener('cancel', onClose);
return () => {
dialogElement?.removeEventListener('cancel', listener);
dialogElement?.removeEventListener('cancel', onClose);
};
}, []);
}, [onClose]);
return (
<dialog
......@@ -171,17 +177,17 @@ export default function NotebookModal({
};
}, [eventBus]);
const onClose = () => {
const onClose = useCallback(() => {
setIsHidden(true);
emitterRef.current?.publish('closeNotebook');
};
}, []);
if (groupId === null) {
return null;
}
return (
<Dialog isHidden={isHidden}>
<Dialog isHidden={isHidden} onClose={onClose}>
<div className="absolute right-0 m-3">
<IconButton
title="Close the Notebook"
......
......@@ -173,17 +173,26 @@ describe('NotebookModal', () => {
assert.isTrue(wrapper.exists('dialog'));
});
it('opens and closes native dialog', () => {
const wrapper = createComponent({});
const isDialogOpen = () => wrapper.find('dialog').getDOMNode().open;
act(() => emitter.publish('openNotebook', 'myGroup'));
wrapper.update();
assert.isTrue(isDialogOpen());
act(() => getCloseButton(wrapper).prop('onClick')());
wrapper.update();
assert.isFalse(isDialogOpen());
[
// Close via clicking close button
wrapper => getCloseButton(wrapper).props().onClick(),
// Close via "cancel" event, like pressing `Esc` key
wrapper =>
wrapper.find('dialog').getDOMNode().dispatchEvent(new Event('cancel')),
].forEach(closeDialog => {
it('opens and closes native dialog', () => {
const wrapper = createComponent({});
const isDialogOpen = () => wrapper.find('dialog').getDOMNode().open;
act(() => emitter.publish('openNotebook', 'myGroup'));
wrapper.update();
assert.isTrue(isDialogOpen());
act(() => closeDialog(wrapper));
wrapper.update();
assert.isFalse(isDialogOpen());
});
});
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment