[TIL] 내일배움캠프 React 과정 2024.08.14

김형빈·2024년 8월 19일
0

내일배움캠프

목록 보기
79/81
post-thumbnail
post-custom-banner

오늘의 한 일

  • 프로필 편집, todolist 입력 예외처리
  • 바텀시트 반응형 -> 모달창 기능 추가

absolute와 relative 속성을 이용하여 모달창 디자인 반영하기

문제 상황

디자이너님이 제작해주신 모달창은 input button의 좌측에 생성되어야 하기에 input button의 위치를 알아야 하며, 또한 반응형으로 모바일로 크기가 작아졌을 때에는 bottom sheet로 바뀌어야 한다.
  • 디자이너님의 모달창 요구 사항 1

  • 디자이너님의 모달창 요구 사항 2

  • 디자이너님의 모달창 요구 사항 3

첫 번째 해결 방법

  • 무엇보다 모달 창의 경우 position absolute를 사용하게 되는데 이 때 input button 옆에 어떻게 넣을 것인지를 해결해야 한다.
  • 처음으로 시도한 방법은 element.getBoundingClientRect();으로 버튼의 위치 정보를 불러온다.

첫 번째 해결 방법의 문제점

  • 적응형으로는 동작하지만 반응형으로 동작하지는 않는다.
  • 반응형으로 동작하기 위해서는 useEffect 등으로 값이 변할 때마다 업데이트 되게 해야 하는데 이는 어마어마한 렌더링 낭비로 이어질 수 있다.

두 번째 해결 방법

  • 해당 모달창이 필요한 위치의 부모 element에 relative를 걸고 그 내부에 모달창 컴포넌트를 선언한다.

  • 예시 코드

    • todoaddPage
	return (
      ...
   		<InputCard>
            {isCalendarOpen && (
              <BottomSheetModal>
                <DateModal onClick={handleCalendarClick} selectedDateStr={selectedDateStr} />
              </BottomSheetModal>
            )}
            <button className="flex flex-row w-full gap-[12px]" onClick={handleCalendarClick}>
              <CalendarIcon className="flex-shrink-0 w-[20px] h-[20px] stroke-[#2F323C]" />
              <Typography variant="Subtitle16px" color="grey700Black">
                {date}
              </Typography>
            </button>
          </InputCard>
      ...
      )
  • 예시 코드

    • DateModal
    return (
      <>
        {isOpen2 && <div className="absolute inset-0 bg-black opacity-40 lg:opacity-0 z-[49]" onClick={setClose} />}
        <div className="absolute flex h-full lg:relative z-50">
          <div
            className={`fixed overflow-hidden max-h-[calc(100%-50px)] flex flex-col bottom-0 left-0 right-0 rounded-t-2xl bg-white
            lg:absolute lg:overflow-visible 
            ${isOpen2 ? 'flex' : 'hidden'}`}
          >
            <div className="flex justify-center p-3 lg:hidden" onClick={setClose}>
              <div className="w-20 h-1 bg-grey900 rounded flex-shrink-0" />
            </div>
            <div
              className={`bg-white shadow-md rounded-[6px]
              lg:fixed lg:w-[375px] lg:-translate-x-[calc(100%+24px)] ${isUp && 'lg:-translate-y-[calc(100%-78px)]'}`}
            >
              {children}
            </div>
          </div>
        </div>
      </>
    );
  • 코드에서 핵심은 <div className="absolute flex h-full lg:relative z-50">
  • 반응형일 때 lg:relative를 넣어 해당 위치에 absolute가 걸리게 설계하였다.

결과

  • 결과적으로 원하는 위치에 모달창을 띄울 수 있었고, 추가적으로 반응형 작업을 진행하여 모바일에서는 Bottom sheet로 보이는 작업까지 마무리 할 수 있었다!
profile
The secret of getting ahead is getting started.
post-custom-banner

0개의 댓글