결과

내용
- 플러스 버튼을 클릭하면 모달창이 나타난다(귓속말, 앨범, 파일)
- 모달창 이외의 공간에 클릭하면 모달창이 사라진다
코드
const modalRef = useRef() as React.MutableRefObject<HTMLDivElement>
useEffect(() => {
document.addEventListener("mousedown", handlePlusBox);
return () => {
document.removeEventListener("mousedown", handlePlusBox);
};
}, [plusButton]);
const handlePlusBox = (e: React.BaseSyntheticEvent | MouseEvent) => {
if (plusButton && !modalRef.current.contains(e.target))
setPlusButton(false);
};
return(
<button className="plusButton"
onClick={() => {setPlusButton(true);}}> ➕ </button>
{plusButton && (
<div className="plusBox" ref={modalRef}>
<ul>
<li>
<select onChange={handleWhisper}>
<option value="">귓속말</option>
{userList
.filter((me) => me !== user?.nick)
.map((user) => (
<option key={user.member_no} value={user}>
{user}
</option>
))}
</select>
</li>
<li>
<label className="imgPlusLabel">
앨범
<input
className="imgPlus"
id="img"
type="file"
accept="image/*"
/>
</label>
</li>
<li>
<label className="filePlusLabel">
파일
<input className="filePlus" id="file" type="file" />
</label>
</li>
</ul>
</div>
)}
)
.plusButton {
font-size: 20px;
margin-right: 8px;
margin-bottom: 5px;
padding: 2px 6px 0 4px;
height: 40px;
}
.plusBox {
position: relative;
left: 0;
top: 0;
select {
border-style: none;
cursor: pointer;
}
ul {
position: absolute;
left: 0;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
width: 150px;
padding-left: 0;
margin-bottom: 0;
background-color: white;
border: 1px solid #336600;
}
li {
padding: 10px 0;
width: 100%;
text-align: center;
white-space: nowrap;
}
}
.imgPlusLabel,
.filePlusLabel {
margin-top: 8px;
cursor: pointer;
}
.imgPlus,
.filePlus {
display: none;
}