[TIL] 230623

이세령·2023년 6월 23일
0

TIL

목록 보기
36/118

심화과제 Lv3 2일

Modal.jsx

export const ModalBackground = styled.div`
  width: 100%;
  height: 100vh;
  inset: 0px;
  position: fixed;
  opacity: 0.8;
  background-color: rgb(221, 221, 221);
`;

export const FisrtModal = styled.div`
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-radius: 12px;
  box-sizing: border-box;
  padding: 24px;
  background-color: rgb(255, 255, 255);
  width: 500px;
  height: 300px;
  position: absolute;
`;

export const SecondModal = styled.div`
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-radius: 12px;
  box-sizing: border-box;
  padding: 24px;
  background-color: rgb(255, 255, 255);
  width: 300px;
  height: 200px;
  position: absolute;
`;

App.js 에서 반환

const [modalOpen1, setModalOpen1] = useState(false);
  const [modalOpen2, setModalOpen2] = useState(false);
  const modalRef = useRef();
  const showModal1 = () => {
    setModalOpen1(true);
  };

  const showModal2 = () => {
    setModalOpen2(true);
  };

  const closeModal = () => {
    setModalOpen1(false);
  };

  const closeModa2 = () => {
    setModalOpen2(false);
  };
------------------------------------------------
<div id="modal">
        {modalOpen1 && (
          <div>
            <ModalBackground />
            <FisrtModal>
              <div>
                닫기와 확인 버튼 2개가 있고, 외부 영역을 눌러도 모달이 닫히지
                않아요.
              </div>
              <ButtonMarginBox
                style={{
                  position: "absolute",
                  bottom: "12px",
                  right: "12px",
                }}
              >
                <SmallButton color="#d63031" onClick={closeModal}>
                  닫기
                </SmallButton>
                <SmallButton color="#000000">확인</SmallButton>
              </ButtonMarginBox>
            </FisrtModal>
          </div>
        )}
        {modalOpen2 && (
          <div ref={modalRef}>
            <ModalBackground onClick={closeModa2} />
            <SecondModal>
              닫기 버튼 1개가 있고, <br />
              외부 영역을 누르면 모달이 닫혀요.
              <CloseButton onClick={closeModa2}>X</CloseButton>
            </SecondModal>
          </div>
        )}
      </div>

모달 상태를 관리해주는 것을 2개 선언하고 상태가 true일 때에만 보여주게 설정해주었다.
배경과 모달을 같은 구간에 두었기 때문에 이벤트 버블링이 일어나지 않아 바깥을 클릭하면 닫히게 된다.
물론 모달창을 클릭하면 닫히지 않는다.

새로 알게된 css 지식

  • 이벤트 버블링
    태그 안에 태그2, 태그2 안에 태그3 이렇게 되어있으면 태그 2를 눌렀을 때 태그가 선택되는 현상 event.target: 클릭한 것
    event.currenttarget : 이벤트 등록한 것
  • position: absolute;
    위치를 임의로 지정할 수 있다.
    보통 특정 창 안에 있는 버튼을 만들 때 사용한다.

Select

Selects.jsx

export const Select = styled.button`
  border: 1px solid rgb(221, 221, 221);
  height: 40px;
  width: 300px;
  background-color: rgb(255, 255, 255);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0px 28px;
  cursor: pointer;
`;

export const OptionList = styled.ul`
  position: absolute;
  top: 655px;
  left: 18px;
  z-index: 100px;
  width: 290px;
  background: rgb(255, 255, 255);
  border: 1px solid rgb(221, 221, 221);
  color: black;
  list-style-type: none;
  padding: 0;
  border-radius: 6px;
  align-items: center;
  transition: 0.3s ease-in;
  &:active {
    max-height: 500px;
  }
`;

export const DetailList = styled.li`
  font-size: 12px;
  padding: 10px;
  &:hover {
    background-color: #c0c0c0;
  }
`;

App.js

 const selectRef = useRef();
  const handleClick = (event) => {
    if (Boolean(selectRef.current) && event.target !== selectRef.current) {
      hideSelect();
    }
  };
.
.
.
<SelectBox>
            <h1>Select</h1>
            <div
              style={{
                display: "flex",
                gap: "10px",
              }}
            >
              <div style={{ position: "relative" }}>
                <Select onClick={showSelect}>
                  <div>{selectValue}</div>
                  <div></div>
                </Select>
              </div>
              <div style={{ position: "relative" }}>
                <Select onClick={showSelect2}>
                  <div>{selectValue2}</div>
                  <div></div>
                </Select>
                {selectState2 && (
                  <div>
                    <OptionList
                      style={{
                        top: "28px",
                        left: "6px",
                      }}
                      ref={selectRef}
                    >
                      <DetailList onClick={selectedValue2}>리액트</DetailList>
                      <DetailList onClick={selectedValue2}>자바</DetailList>
                      <DetailList onClick={selectedValue2}>스프링</DetailList>
                      <DetailList onClick={selectedValue2}>
                        리액트네이티브
                      </DetailList>
                    </OptionList>
                  </div>
                )}
              </div>
            </div>
          </SelectBox>

.
.
.
{selectState && (
        <div>
          <OptionList ref={selectRef}>
            <DetailList onClick={selectedValue}>리액트</DetailList>
            <DetailList onClick={selectedValue}>자바</DetailList>
            <DetailList onClick={selectedValue}>스프링</DetailList>
            <DetailList onClick={selectedValue}>리액트네이티브</DetailList>
          </OptionList>
        </div>
      )}

모달과 동일하게 이벤트 처리를 해주었다. overflow: hidden;으로 인해 두번째 select는 클릭하면 잘리게 보인다.

selectref가 true이면서, 외부를 클릭했을 때 hideSelect()가 동작하게 만든다.
handleClick을 메인 페이지에 이벤트를 등록해주고 토글목록이 보여져있고 토글 이외의 것을 클릭했을 때 이벤트동작이 이루어진다.

  • 아이콘 사이트
    1) React Icons
    설치하고 import해서 스타일 컴포넌트로 적용하기만 하면 되기 때문에 사용하기 쉽다.
    2) Font Awesome

  • overflow: hidden;
    해당 구간 외로 나가면 안보이게 만들어준다.

태그가 어디에 위치하느냐에 따라 style이 변하거나 target이 가리키는 것이 다를 수 있다는 점을 인지하고 스타일링 해야한다.
시간이 될 때 readme를 정리하고 리팩토링을 하면 좋을 것 같다.

profile
https://github.com/Hediar?tab=repositories

0개의 댓글