Commit 5f369a0b authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Make sure sidebar panels are focused when open, and focus is restored when closed

parent 1b476206
import { Panel } from '@hypothesis/frontend-shared/lib/next';
import { Dialog } from '@hypothesis/frontend-shared/lib/next';
import type { IconComponent } from '@hypothesis/frontend-shared/lib/types';
import type { ComponentChildren } from 'preact';
import { useCallback, useEffect, useRef } from 'preact/hooks';
......@@ -47,9 +47,7 @@ export default function SidebarPanel({
if (panelIsActive && panelElement.current) {
scrollIntoView(panelElement.current);
}
if (typeof onActiveChanged === 'function') {
onActiveChanged(panelIsActive);
}
onActiveChanged?.(panelIsActive);
}
}, [panelIsActive, onActiveChanged]);
......@@ -58,12 +56,20 @@ export default function SidebarPanel({
}, [store, panelName]);
return (
<Slider visible={panelIsActive}>
<div ref={panelElement} className="mb-4">
<Panel title={title} icon={icon} onClose={closePanel}>
<>
{panelIsActive && (
<Dialog
restoreFocus
ref={panelElement}
classes="mb-4"
title={title}
icon={icon}
onClose={closePanel}
transitionComponent={Slider}
>
{children}
</Panel>
</div>
</Slider>
</Dialog>
)}
</>
);
}
......@@ -7,6 +7,9 @@ export type SliderProps = {
/** Whether the content should be visible or not. */
visible: boolean;
/** Invoked once the open/close transitions have finished */
onTransitionEnd?: (direction: 'in' | 'out') => void;
};
/**
......@@ -17,9 +20,13 @@ export type SliderProps = {
* DOM using `display: none` so it does not appear in the keyboard navigation
* order.
*
* Currently the only reveal/expand direction supported is top-down.
* Currently, the only reveal/expand direction supported is top-down.
*/
export default function Slider({ children, visible }: SliderProps) {
export default function Slider({
children,
visible,
onTransitionEnd,
}: SliderProps) {
const containerRef = useRef<HTMLDivElement | null>(null);
const [containerHeight, setContainerHeight] = useState(visible ? 'auto' : 0);
......@@ -68,13 +75,15 @@ export default function Slider({ children, visible }: SliderProps) {
const handleTransitionEnd = useCallback(() => {
if (visible) {
setContainerHeight('auto');
onTransitionEnd?.('in');
} else {
// When the collapse animation completes, stop rendering the content so
// that the browser has fewer nodes to render and the content is removed
// from keyboard navigation.
setContentVisible(false);
onTransitionEnd?.('out');
}
}, [setContainerHeight, visible]);
}, [setContainerHeight, visible, onTransitionEnd]);
const isFullyVisible = containerHeight === 'auto';
......
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