mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-24 18:32:41 +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:
@@ -1,5 +1,5 @@
|
||||
require('./anchoredBox.less');
|
||||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import React, { useState, useRef, useEffect, forwardRef } from 'react';
|
||||
import './anchoredBox.less';
|
||||
|
||||
const AnchoredBox = ({ anchorPoint = 'center', className, children, ...props })=>{
|
||||
const [visible, setVisible] = useState(false);
|
||||
@@ -8,10 +8,12 @@ const AnchoredBox = ({ anchorPoint = 'center', className, children, ...props })=
|
||||
|
||||
useEffect(()=>{
|
||||
const handleClickOutside = (evt)=>{
|
||||
if(boxRef.current &&
|
||||
!boxRef.current.contains(evt.target) &&
|
||||
triggerRef.current &&
|
||||
!triggerRef.current.contains(evt.target)){
|
||||
if(
|
||||
boxRef.current &&
|
||||
!boxRef.current.contains(evt.target) &&
|
||||
triggerRef.current &&
|
||||
!triggerRef.current.contains(evt.target)
|
||||
) {
|
||||
setVisible(false);
|
||||
}
|
||||
};
|
||||
@@ -33,18 +35,32 @@ const AnchoredBox = ({ anchorPoint = 'center', className, children, ...props })=
|
||||
iframe.contentWindow.document.removeEventListener('click', handleClickOutside);
|
||||
}
|
||||
};
|
||||
}, []); // Empty dependency array to run effect on mount only
|
||||
}, []);
|
||||
|
||||
const handleClick = ()=>{
|
||||
setVisible(!visible);
|
||||
triggerRef.current?.focus();
|
||||
};
|
||||
|
||||
const handleKeyDown = (evt)=>{
|
||||
if(evt.key === 'Escape') {
|
||||
setVisible(false);
|
||||
triggerRef.current?.focus();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<button className={`${className} anchored-trigger${visible ? ' active' : ''}`} onClick={handleClick} ref={triggerRef}>
|
||||
<i className='fas fa-gear' />
|
||||
</button>
|
||||
<div className={`anchored-box${visible ? ' active' : ''}`} ref={boxRef}>
|
||||
<TriggerButton
|
||||
className={`${className} anchored-trigger${visible ? ' active' : ''}`}
|
||||
onClick={handleClick}
|
||||
ref={triggerRef}
|
||||
/>
|
||||
<div
|
||||
className={`anchored-box${visible ? ' active' : ''}`}
|
||||
ref={boxRef}
|
||||
onKeyDown={(evt)=>handleKeyDown(evt)}
|
||||
>
|
||||
<h1>{props.title}</h1>
|
||||
{children}
|
||||
</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;
|
||||
|
||||
Reference in New Issue
Block a user