스프린트/react-custom-component

React Custom Component Modal

테오구 2021. 11. 1. 00:15
728x90

Modal UI 컴포넌트는 기존의 브라우저 페이지 위에 새로운 윈도우 창이 아닌, 레이어를 까는 것을 말합니다.

 

 

 

 

 

 

import { useEffect, useRef, useState } from 'react'
import styled from 'styled-components'

export const ModalContainer = styled.div`
  // TODO : Modal을 구현하는데 전체적으로 필요한 CSS를 구현합니다.
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  position: relative;
`

export const ModalBackdrop = styled.div`
  // TODO : Modal이 떴을 때의 배경을 깔아주는 CSS를 구현합니다.
  position: fixed;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 1;
`

export const ModalBtn = styled.button`
  background-color: #4000c7;
  text-decoration: none;
  border: none;
  padding: 20px;
  color: white;
  border-radius: 30px;
  cursor: grab;
`

export const ModalView = styled.div.attrs(props => ({
  // attrs 메소드를 이용해서 아래와 같이 div 엘리먼트에 속성을 추가할 수 있습니다.
  role: 'dialog',
}))`
  // TODO : Modal창 CSS를 구현합니다.
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: white;
  width: 200px;
  height: 100px;
  border-radius: 1rem;
  position: relative;
  > .close-btn {
    position: absolute;
    top: 2px;
    right: 7px;
    cursor: pointer;
  }
`

export const Modal = () => {
  const [isOpen, setIsOpen] = useState(false)
  const el = useRef()

  const openModalHandler = e => {
    // TODO : isOpen의 상태를 변경하는 메소드를 구현합니다.
    console.log(e)
    setIsOpen(isOpen === true ? false : true)
  }

  const handleClickOutside = ({ target }) => {
    if (isOpen && !el.current.contains(target)) setIsOpen(false)
  }

  useEffect(() => {
    window.addEventListener('click', handleClickOutside)
    return () => {
      window.removeEventListener('click', handleClickOutside)
    }
  }, [])

  return (
    <>
      <ModalContainer>
      // 버튼을 클릭했을 때 openModalHandler를 클릭합니다.
        <ModalBtn onClick={openModalHandler}>
        // isOpen이 true가 되었을 때는 'Opened!' false일 때는 'Open Modal'
          {isOpen ? 'Opened!' : 'Open Modal'}
        </ModalBtn>

		// isOpen이 true일 때 ModalBackdrop, ModalView를 실행합니다.
        {isOpen ? (
          <ModalBackdrop onClick={openModalHandler}>
            <ModalView
              onClick={event => {
              // 상위 엘리먼트에 이벤트를 전달하는 막기 위해
                event.stopPropagation()
              }}
            >
              <div className="close-btn" onClick={openModalHandler}>
              // x 마크를 보여줍니다.
                &times;
              </div>
              <div>HELLO CODESTATES!</div>
            </ModalView>
          </ModalBackdrop>
        ) : null}
      </ModalContainer>
    </>
  )
}
728x90

'스프린트 > react-custom-component' 카테고리의 다른 글

react-custom-component tag  (0) 2021.11.01
React Custom Component Tag  (0) 2021.11.01
React Custom Component Tab  (0) 2021.11.01