Commit 57c4cc11 authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Replace useElementShouldClose with usePopoverShouldClose

parent b57fc1f9
import { useElementShouldClose } from '@hypothesis/frontend-shared'; import { usePopoverShouldClose } from '@hypothesis/frontend-shared';
import { import {
Card, Card,
IconButton, IconButton,
...@@ -62,8 +62,8 @@ function AnnotationShareControl({ ...@@ -62,8 +62,8 @@ function AnnotationShareControl({
const toggleSharePanel = () => setOpen(!isOpen); const toggleSharePanel = () => setOpen(!isOpen);
const closePanel = () => setOpen(false); const closePanel = () => setOpen(false);
// Interactions outside of the component when it is open should close it // Interactions outside the component when it is open should close it
useElementShouldClose(shareRef, isOpen, closePanel); usePopoverShouldClose(shareRef, closePanel, { enabled: isOpen });
useEffect(() => { useEffect(() => {
if (wasOpen.current !== isOpen) { if (wasOpen.current !== isOpen) {
...@@ -130,7 +130,7 @@ function AnnotationShareControl({ ...@@ -130,7 +130,7 @@ function AnnotationShareControl({
// Make the container div focusable by setting a non-null `tabIndex`. // Make the container div focusable by setting a non-null `tabIndex`.
// This prevents clicks on non-focusable contents from "leaking out" and // This prevents clicks on non-focusable contents from "leaking out" and
// focusing a focusable ancester. If something outside of the panel gains // focusing a focusable ancester. If something outside of the panel gains
// focus, `useElementShouldClose`'s focus listener will close the panel. // focus, `usePopoverShouldClose`'s focus listener will close the panel.
// "Catch focus" here to prevent this. // "Catch focus" here to prevent this.
// See https://github.com/hypothesis/client/issues/5196 // See https://github.com/hypothesis/client/issues/5196
<div className="relative" ref={shareRef} tabIndex={-1}> <div className="relative" ref={shareRef} tabIndex={-1}>
......
...@@ -88,7 +88,7 @@ describe('AnnotationShareControl', () => { ...@@ -88,7 +88,7 @@ describe('AnnotationShareControl', () => {
$imports.$mock(mockImportedComponents()); $imports.$mock(mockImportedComponents());
$imports.$mock({ $imports.$mock({
'@hypothesis/frontend-shared': { '@hypothesis/frontend-shared': {
useElementShouldClose: sinon.stub(), usePopoverShouldClose: sinon.stub(),
}, },
'../../helpers/annotation-sharing': { '../../helpers/annotation-sharing': {
isShareableURI: fakeIsShareableURI, isShareableURI: fakeIsShareableURI,
......
import { useElementShouldClose } from '@hypothesis/frontend-shared'; import { usePopoverShouldClose } from '@hypothesis/frontend-shared';
import { MenuExpandIcon } from '@hypothesis/frontend-shared'; import { MenuExpandIcon } from '@hypothesis/frontend-shared';
import classnames from 'classnames'; import classnames from 'classnames';
import type { ComponentChildren } from 'preact'; import type { ComponentChildren } from 'preact';
...@@ -145,7 +145,7 @@ export default function Menu({ ...@@ -145,7 +145,7 @@ export default function Menu({
// Menu element should close via `closeMenu` whenever it's open and there // Menu element should close via `closeMenu` whenever it's open and there
// are user interactions outside of it (e.g. clicks) in the document // are user interactions outside of it (e.g. clicks) in the document
useElementShouldClose(menuRef, isOpen, closeMenu); usePopoverShouldClose(menuRef, closeMenu, { enabled: isOpen });
const stopPropagation = (e: Event) => e.stopPropagation(); const stopPropagation = (e: Event) => e.stopPropagation();
......
import { useElementShouldClose } from '@hypothesis/frontend-shared'; import { usePopoverShouldClose } from '@hypothesis/frontend-shared';
import { Input } from '@hypothesis/frontend-shared'; import { Input } from '@hypothesis/frontend-shared';
import classnames from 'classnames'; import classnames from 'classnames';
import { useRef, useState } from 'preact/hooks'; import { useRef, useState } from 'preact/hooks';
...@@ -45,8 +45,8 @@ function TagEditor({ ...@@ -45,8 +45,8 @@ function TagEditor({
// Set up callback to monitor outside click events to close the AutocompleteList // Set up callback to monitor outside click events to close the AutocompleteList
const closeWrapperRef = useRef<HTMLDivElement>(null); const closeWrapperRef = useRef<HTMLDivElement>(null);
useElementShouldClose(closeWrapperRef, suggestionsListOpen, () => { usePopoverShouldClose(closeWrapperRef, () => setSuggestionsListOpen(false), {
setSuggestionsListOpen(false); enabled: suggestionsListOpen,
}); });
/** /**
......
...@@ -112,7 +112,6 @@ describe('Menu', () => { ...@@ -112,7 +112,6 @@ describe('Menu', () => {
new Event('mousedown'), new Event('mousedown'),
new Event('click'), new Event('click'),
((e = new Event('keydown')), (e.key = 'Escape'), e), ((e = new Event('keydown')), (e.key = 'Escape'), e),
new Event('focus'),
].forEach(event => { ].forEach(event => {
it(`closes when the user clicks or presses the mouse outside (${event.type})`, () => { it(`closes when the user clicks or presses the mouse outside (${event.type})`, () => {
const wrapper = createMenu({ defaultOpen: true }); const wrapper = createMenu({ defaultOpen: true });
...@@ -126,6 +125,20 @@ describe('Menu', () => { ...@@ -126,6 +125,20 @@ describe('Menu', () => {
}); });
}); });
it('closes when menu loses focus', () => {
const wrapper = createMenu({ defaultOpen: true });
act(() => {
wrapper
.find(menuSelector)
.getDOMNode()
.dispatchEvent(new Event('focusout'));
});
wrapper.update();
assert.isFalse(isOpen(wrapper));
});
it('does not close when user presses non-Escape key outside', () => { it('does not close when user presses non-Escape key outside', () => {
const wrapper = createMenu({ defaultOpen: true }); const wrapper = createMenu({ defaultOpen: true });
......
...@@ -224,7 +224,10 @@ describe('TagEditor', () => { ...@@ -224,7 +224,10 @@ describe('TagEditor', () => {
wrapper.find('input').instance().value = 'non-empty'; wrapper.find('input').instance().value = 'non-empty';
typeInput(wrapper); typeInput(wrapper);
assert.equal(wrapper.find('AutocompleteList').prop('open'), true); assert.equal(wrapper.find('AutocompleteList').prop('open'), true);
document.body.dispatchEvent(new Event('focus')); wrapper
.find('[data-testid="combobox-container"]')
.getDOMNode()
.dispatchEvent(new Event('focusout'));
wrapper.update(); wrapper.update();
assert.equal(wrapper.find('AutocompleteList').prop('open'), false); assert.equal(wrapper.find('AutocompleteList').prop('open'), false);
}); });
......
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