이야기는 Select 컴포넌트에서 출발한다.
HTML Select가 아닌 일반 Tags와 Button 컴포넌트를 이용해 커스텀하게 만든 녀석이고,
UI 관련 아래 variant, size, placement 정도의 props를 가지고 있다.
*각각 형태(appearance), 크기, 방향
<div class="root">
<Button class="select">선택</Button>
<div class="dropdown">
<ul class="list">
<li class="item">
<Button class="option">항목 1</Button>
</li>
...
</ul>
</div>
</div>
마크업은 대략 위와 같고,
root
기준으로(relative) dropdown
영역의 위치를 잡아주었다(absolute).
size prop에 따라 select
와 각 option
의 높이값을 md/lg/xl 40/48/60으로 잡아주고,
placement prop은 드롭다운이 펼쳐지는 방향으로
"bottom"일 경우 top값, "top"일 경우 bottom값으로 사이 간격(8px)을 더한 calc(100% + 8px)
을 주어 구현했다.
🚨근데 이제? 이슈 발생..
Select 컴포넌트는(*내가 만든) 다양한 환경과 위치에 자리하게 되는데,
overflow
안에서 절대 자유로울 수 없다..
드롭다운 레이어가 absolute임에도 불구하고, 부모 영역에 스크롤이 생기거나, 댕강 허리가 잘려버림 🥲
사실 이건 Select 컴포넌트에만 국한된 이슈가 아니고,
컴포넌트 내 최상위(root) 영역을 기준으로 하위 레이어의 위치를 잡는 모든 것이 그러하다.
Date(Range), Tooltip, Context, Popover 등등..
자, 해결 방법은? ⛏️
간단하다. 웹뷰 전체에서 자유로우면 된다.!
남들은 어케 했는지 레퍼런스를 살펴보자.
Select, Popover, Modal 등의 컴포넌트를 살펴보면, 레이어 마크업(MuiPaper)이
버튼(MuiBox)과는 별개로 body가 닫히기 직전 위치에 추가/제거 되는 것을 확인할 수 있다.
overflow: hidden
, 레이어를 감싼 영역에 position: fixed; inset: 0
Select 컴포넌트를 살펴봤을 때, MUI와 마찬가지로 컴포넌트 레이어 마크업이
body가 닫히기 직전 위치에 추가 되는 것을 확인할 수 있다.
*다만, hidden 클래스를 가진 채로 추가된 후, toggle class 해주는 방식.
.ant-select-dropdown-hidden {display: none}
일반적으로 방법 1) 을 사용하는 경향.
레퍼런스는 충분히 봤지만,
하나의 컴포넌트의 마크업이 웹문서 내 여러 곳에 흩어져있는 걸 선호하지 않는 상태(?).
*고집불통
초기에 컴포넌트를 설계할 때, 컴포넌트 간의 조합은 최소화하고 컴포넌트와 모듈 CSS를 1:1로 두어 해당 컴포넌트의 모든 스타일링을 한곳(Select.module.scss
)에서 관리하고 있기 때문에
레이어 마크업을 외부에 만드는 개념이 아직 생소하다. *관리(control)가 제대로 될까?😟
2) 를 밀고 나가 보자! 고정 위치(fixed position) 📌
position: fixed
를 준다. 👉 뷰포트 기준getBoundingClientRect()
메소드를 통해top, left, minWidth
적용.transform
적용.추가 UX 정책(rules)이 필요하다.
🎉 ta-da!
멋지게 자기 주장을 하는 요녀석