@@ -8,21 +8,40 @@ type Props = {
88 defaultOpen ?: boolean ;
99} ;
1010
11- // export function ToggleFrame({ label, children, defaultOpen = true }: Props) {
12- export function ToggleFrame ( { label, children, defaultOpen = false } : Props ) {
11+ export function ToggleFrame ( { label, children, defaultOpen = true } : Props ) {
12+ // export function ToggleFrame({ label, children, defaultOpen = false }: Props) {
1313 const [ isOpen , setIsOpen ] = useState ( defaultOpen ) ;
1414 const ref = useRef < HTMLDivElement > ( null ) ;
1515
1616 const handleToggle = ( ) => {
1717 setIsOpen ( ( prev ) => ! prev ) ;
1818 } ;
1919
20- // Scroll into view when opened
20+ // Scroll into view when ESC is pressed
2121 useEffect ( ( ) => {
22- if ( isOpen && ref . current ) {
23- setTimeout ( ( ) => {
24- ref . current ?. scrollIntoView ( { behavior : "smooth" , block : "start" } ) ;
25- } , 50 ) ;
22+ const onKeyDown = ( e : KeyboardEvent ) => {
23+ if (
24+ e . key === "Escape" &&
25+ isOpen &&
26+ document . activeElement === ref . current
27+ ) {
28+ scrollToTopAndClose ( ) ;
29+ }
30+ } ;
31+
32+ window . addEventListener ( "keydown" , onKeyDown ) ;
33+ return ( ) => window . removeEventListener ( "keydown" , onKeyDown ) ;
34+ } , [ isOpen ] ) ;
35+
36+ // Scroll COLLAPSED frame to center when ESC or [COLLAPSE] button is pressed
37+ useEffect ( ( ) => {
38+ if ( ! isOpen && ref . current ) {
39+ requestAnimationFrame ( ( ) => {
40+ ref . current ?. scrollIntoView ( {
41+ behavior : "smooth" ,
42+ block : "center" ,
43+ } ) ;
44+ } ) ;
2645 }
2746 } , [ isOpen ] ) ;
2847
@@ -34,6 +53,7 @@ export function ToggleFrame({ label, children, defaultOpen = false }: Props) {
3453 return (
3554 < div
3655 ref = { ref }
56+ tabIndex = { - 1 }
3757 className = "shadow-sm hover:shadow-sm hover:shadow-blue-900/85 dark:shadow-sky-900/50 hover:dark:shadow-yellow-100/85 py-3 px-4"
3858 >
3959 < hr className = "my-0 w-full border-zinc-200 dark:border-zinc-800" />
0 commit comments