const scrollToCenter = (index: number) => {
const container = containerRef.current;
const button = buttonRefs.current[index];
if (container && button) {
const scrollLeft =
button.offsetLeft + button.offsetWidth / 2 - container.offsetWidth / 2;
container.scrollTo({ left: Math.max(0, scrollLeft), behavior: 'smooth' });
}
};
📘 설명
- ①
scrollToCenter: 특정 인덱스의 버튼을 컨테이너 중앙으로 스크롤하는 함수.
- ② 버튼의 중심 위치와 컨테이너 중심 위치의 차이로 스크롤 이동값 계산.
- ③ 실제 스크롤 이동 수행 (
smooth 옵션으로 애니메이션 적용).
const isButtonCentered = (index: number) => {
const container = containerRef.current;
const button = buttonRefs.current[index];
if (!container || !button) return false;
const buttonCenter = button.offsetLeft + button.offsetWidth / 2;
const containerCenter = container.scrollLeft + container.offsetWidth / 2;
return Math.abs(buttonCenter - containerCenter) < 4;
};
📘 설명
- ④ 현재 버튼이 화면 중심에 위치했는지 확인하는 함수.
- ⑤ 버튼과 컨테이너 중심 좌표를 구해서
- ⑥ 두 값의 차이가 4px 이하일 경우, "가운데에 있다"고 판단.
handleClick
const handleClick = (e: React.MouseEvent<HTMLButtonElement>, index: number) => {
if (isButtonCentered(index)) {
setCalendarAnchorEl(e.currentTarget);
} else {
onSelect(index, dates[index]);
scrollToCenter(index);
}
};
📘 설명
- ⑦ 버튼 클릭 시 동작 처리 함수.
- ⑧ 이미 가운데인 경우 → 달력 팝업 열기.
- ⑨ 아니라면 선택 상태 변경 (
onSelect() 콜백 호출).
- ⑩ 선택된 버튼을 가운데로 정렬.
Popover 달력
<Popover
open={Boolean(calendarAnchorEl)}
anchorEl={calendarAnchorEl}
onClose={() => setCalendarAnchorEl(null)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<StaticDatePicker
displayStaticWrapperAs="desktop"
value={new Date()}
onChange={(newValue) => {
console.log('선택된 날짜:', newValue);
setCalendarAnchorEl(null);
}}
slotProps={{ actionBar: { actions: ['today'] } }}
/>
</LocalizationProvider>
</Popover>
📘 설명
- ⑪ 선택된 버튼 클릭 시 열리는 팝업 달력 UI
- ⑫ 팝업의 위치를 버튼 하단 중앙에 정렬
- ⑬ 현재 날짜를 기본 선택값으로 설정 (실제 날짜 연동은 추후 확장 가능)
- ⑭ 날짜 선택 시 팝업 닫기