본문 바로가기
React

React(47) div영역에 mouseover 시 버튼 보이기

by 새발개발JA 2021. 9. 12.
반응형

 

Jira 에서는 메뉴가 열렸을 때, 마우스오버 시 메뉴를 접을 수 있는 화살표 버튼이 보인다. 

이걸 모티브삼아 똑같은 기능을 리액트에서 개발해보려고 한다.

 


React(47) div영역에 mouseover 시 버튼 보이기

 

결과화면 미리보기

지금보는 화면은 Jira 의 보드이다. 오른쪽에는 메뉴가 보인다. 

이 메뉴에 마우스 오버해보자.

그럼 보시는 것처럼 빨간박스 안의 '<' 접기 버튼이 생긴다. 이걸 리액트로 구현해볼 것이다.

 

List.tsx

여기서 핵심은,

메뉴를 접는 close마우스 이벤트일때만 접기버튼이 보이는 hide 변수이다. 

close 를 통해 메뉴를 접었다 폈다 하고 hide 를 통해 마우스 오버시 버튼이 보이게 되는 스위치 역할을 하게된다.

 

onMouseEnter() 와 onMouseLeave() 이벤트를 통해,

마우스가 해당 div 영역에 놓여있을 때와 없을 때 hide 의 상태를 변경해준다.

또한 부차적으로 css를 통해서 hide 일때와 close 일때 display 상태를 지정해준다.

import { ReactElement, useState } from 'react';
import 'src/css/List.css'

const List = (): ReactElement => {
  const [close, setClose] = useState<boolean>(false);	// 메뉴닫기 상태 
  const [hide, setHide] = useState<boolean>(true);	// 메뉴접기 상태
  
  return (
    <div
      className={`list ${close ? 'close' : 'open'}`}  // close 상태이면 close가 된다. 아니면 open이다.
      onMouseEnter={() => {setHide(false)}} 	      // 마우스엔터 이벤트이면 hide가 false가 된다.
      onMouseLeave={() => {setHide(true)}}  	      // 마우스리브 이벤트이면 hide가 true가 된다.
    >
      <button					      // 버튼을 누르면 
        className={				      // 클래스 네임이
          `hover-close 				      // hover-close 와
          ${close ? '' : 'open'} 		      // close 상태가 아니면 open이 되고
          ${hide ? 'hide' : '' }`  		      // hide 상태이면 hide 된다.
        }
        onClick={() => {setClose(!close)}}    	      // 클릭하면 close 상태가 반대로 변한다.
      >
        <img src={icoArrowLeft} alt="" />
      </button>

      {!close && (				      // close가 아니면 하위 메뉴가 보인다.
        <div className="content">
          <div className="menu">전체글보기</div>
          <div className="menu">리액트</div>
          <div className="menu">리덕스</div>     
        </div>
      )}
    </div>
  );
};

export default List;

 

List.css

.list.close {
  animation-duration: 0.2s;
  animation-name: slide-out;
  min-width: 30px;
  width: 30px;
}
.list.open {
  animation-duration: 0.2s;
  animation-name: slide-in;
  min-width: 382px;
  width: 382px;
}
.list .hover-close {
  align-items: center;
  background-color: #aab1bc;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  height: 32px;
  justify-content: center;
  position: absolute;
  right: -13px;
  top: 50%;
  transition: 0.2;
  width: 32px;
  z-index: 100;
}
.hover-close.open.hide {
  display: none;
}
.hover-close img {
  height: 16px;
  transform: rotate(180deg);	// 접기버튼을 열기버튼으로 돌려준다.
  width: 16px;
}
.hover-close.open img {
  transform: none;
}
.list .content {
  height: calc(100% - 50px);
  overflow-y: auto;
  width: 100%;
}

 

 

 

 

 

반응형

댓글