728x90
이번 글에서는 Material-UI의 Popover
컴포넌트 사용 중 겪었던 시행착오와, 위치 보정 및 자연스러운 애니메이션을 적용하기까지의 해결 과정을 기록합니다.
1. 문제 상황
처음에는 Material-UI의 Popover
를 사용하여 특정 버튼을 클릭하면 팝업이 열리도록 구현하였습니다. 하지만 팝업 내부의 내용이 확장될 때 다음과 같은 문제가 발생했습니다.
- 내용이 확장되면 Popover가 화면 밖으로 벗어나는 현상
- Popover 위치가 자동으로 보정되지 않아 부자연스러운 UI
- 위치 보정이 되어도 움직임이 너무 딱딱해서 UX가 나쁨
2. 처음 시도한 방법 (실패)
처음에는 Popover를 Popper로 변경하여 popperRef
를 사용해 위치를 직접 업데이트하려고 했습니다.
<Popper
open={open}
anchorEl={anchorEl}
placement="bottom-start"
popperRef={popperRef}
>
{/* 내용 */}
</Popper>
문제점:
- 기존 Popover에서 잘 동작하던
ClickAwayListener
나 자동 위치 보정 기능이 제대로 동작하지 않음. - 키보드 이벤트나 focus 문제가 발생하여 복잡도가 증가함.
3. 두 번째 시도 (실패)
Popover
를 유지하면서 내용이 확장된 후 popperRef.current.update()
를 사용해 보정을 시도했지만, Popover
에서는 popperRef
를 지원하지 않아 TypeScript 오류가 발생했습니다.
4. 최종 해결 방법
결국 Popover를 유지하면서, 내용이 확장된 직후 window.dispatchEvent(new Event('resize'))
를 호출하여 위치 보정을 유도하고, 보정 시 transition 효과를 주어 부드럽게 처리하는 방법을 사용했습니다.
코드 예제
import React, { useState } from 'react';
import Popover from '@mui/material/Popover';
import Button from '@mui/material/Button';
function MyPopover({ setAdobeFile }) {
const [anchorEl, setAnchorEl] = useState(null);
const [expanded, setExpanded] = useState(false);
const handleOpen = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
if (setAdobeFile) {
setAdobeFile(null);
}
};
const handleExpand = () => {
setExpanded(true);
// 내용 확장 후 resize 이벤트 발생 → 위치 재계산 유도
window.dispatchEvent(new Event('resize'));
};
const open = Boolean(anchorEl);
return (
<div>
<Button onClick={handleOpen}>열기</Button>
<Popover
open={open}
anchorEl={anchorEl}
onClose={handleClose}
marginThreshold={16}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
PaperProps={{
style: {
transition: 'transform 0.3s ease-in-out' // 위치 이동 애니메이션 효과
}
}}
>
<div style={{ width: 200, height: expanded ? 300 : 100, padding: 16 }}>
내용 영역
{!expanded && (
<Button onClick={handleExpand}>확장하기</Button>
)}
</div>
</Popover>
</div>
);
}
export default MyPopover;
주요 포인트
- 자동 위치 보정: 내용이 확장된 후
window.dispatchEvent(new Event('resize'))
를 호출하여 Popover 내부의 Popper.js가 위치를 재계산하도록 유도했습니다. - 부드러운 애니메이션 효과:
Popover
의PaperProps
를 통해transition: 'transform 0.3s ease-in-out'
을 적용하여, 위치가 재조정될 때 자연스럽게 이동하도록 처리했습니다.
5. 시행착오에서 얻은 교훈
- Material-UI의
Popover
는 Popper.js를 내부적으로 사용하지만, 직접 업데이트를 컨트롤하기 어렵다. - 브라우저의
resize
이벤트는 Popper.js가 위치를 재계산하도록 유도하는 유용한 트릭이다. - 애니메이션 효과를 위해서는 Popover의
PaperProps
에transform
관련 CSS를 적용하는 것이 가장 자연스럽다.
6. 마무리
Popover에서 발생하는 위치 보정 문제를 해결하기 위해 여러 가지 방법을 시도했지만, 결국 가장 단순하면서도 확실한 방법은 resize 이벤트를 활용하는 것이었습니다. 그리고 transition 효과를 적용하여 UX를 개선할 수 있었습니다.
앞으로도 비슷한 UI 문제를 겪게 된다면, 이러한 경험이 도움이 되길 바랍니다.
728x90
'React > React 실습' 카테고리의 다른 글
[SSO] 네이버 소셜 로그인 연동 및 보안 고려사항, (팝업 기반 소셜 로그인 처리 방식) (0) | 2025.04.10 |
---|---|
[OAuth2] 기존 시스템에 네이버 소셜 로그인 기능 연동하기 (JWT + 팝업 방식) (0) | 2025.04.02 |
[React] Material-UI Popover에서 Popper로 전환한 시행착오 (0) | 2025.03.14 |
[React] Drawer와 Tab, Accordian - Console 콘솔에러 제거하기 (0) | 2025.02.04 |
[React] Drawer와 Tab, Accordian으로 FAQ 구현하기 (0) | 2025.02.03 |
댓글