0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-01 10:52:46 +00:00

refactor anchoredBox to handle focus

Refactoring the AnchoredBox component because I wanted to set focus on the trigger button when the expanded box was closed.  Wrapping the trigger into it's own component, with forwardRef, allows for passing the `ref` to the actual DOM node.  Then the `.focus()` method will work on it.
This commit is contained in:
Gazook89
2024-10-11 22:34:40 -05:00
parent 835305bcf6
commit a3dbaf9e6a

View File

@@ -1,5 +1,5 @@
require('./anchoredBox.less'); import React, { useState, useRef, useEffect, forwardRef } from 'react';
import React, { useState, useRef, useEffect } from 'react'; import './anchoredBox.less';
const AnchoredBox = ({ anchorPoint = 'center', className, children, ...props })=>{ const AnchoredBox = ({ anchorPoint = 'center', className, children, ...props })=>{
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
@@ -8,10 +8,12 @@ const AnchoredBox = ({ anchorPoint = 'center', className, children, ...props })=
useEffect(()=>{ useEffect(()=>{
const handleClickOutside = (evt)=>{ const handleClickOutside = (evt)=>{
if(boxRef.current && if(
!boxRef.current.contains(evt.target) && boxRef.current &&
triggerRef.current && !boxRef.current.contains(evt.target) &&
!triggerRef.current.contains(evt.target)){ triggerRef.current &&
!triggerRef.current.contains(evt.target)
) {
setVisible(false); setVisible(false);
} }
}; };
@@ -33,18 +35,32 @@ const AnchoredBox = ({ anchorPoint = 'center', className, children, ...props })=
iframe.contentWindow.document.removeEventListener('click', handleClickOutside); iframe.contentWindow.document.removeEventListener('click', handleClickOutside);
} }
}; };
}, []); // Empty dependency array to run effect on mount only }, []);
const handleClick = ()=>{ const handleClick = ()=>{
setVisible(!visible); setVisible(!visible);
triggerRef.current?.focus();
};
const handleKeyDown = (evt)=>{
if(evt.key === 'Escape') {
setVisible(false);
triggerRef.current?.focus();
}
}; };
return ( return (
<> <>
<button className={`${className} anchored-trigger${visible ? ' active' : ''}`} onClick={handleClick} ref={triggerRef}> <TriggerButton
<i className='fas fa-gear' /> className={`${className} anchored-trigger${visible ? ' active' : ''}`}
</button> onClick={handleClick}
<div className={`anchored-box${visible ? ' active' : ''}`} ref={boxRef}> ref={triggerRef}
/>
<div
className={`anchored-box${visible ? ' active' : ''}`}
ref={boxRef}
onKeyDown={(evt)=>handleKeyDown(evt)}
>
<h1>{props.title}</h1> <h1>{props.title}</h1>
{children} {children}
</div> </div>
@@ -52,4 +68,10 @@ const AnchoredBox = ({ anchorPoint = 'center', className, children, ...props })=
); );
}; };
const TriggerButton = forwardRef((props, ref)=>(
<button ref={ref} {...props}>
<i className='fas fa-gear' />
</button>
));
export default AnchoredBox; export default AnchoredBox;