Skip to main content

useScrollTo

스크롤 기능을 제공하는 커스텀 훅입니다.

useScrollTo 훅이 반환하는 containerRef를 특정 엘리먼트에 할당하면 해당 요소를 스크롤 합니다. containerRef를 할당하지 않으면 window를 스크롤합니다.

scrollToPosition 함수는 top, left와 같은 position을 기준으로 스크롤합니다.

scrollToElement 함수는 인자로 넣은 타겟 요소를 기준으로 스크롤 합니다. offsetY/X 값을 옵션으로 받아올 수 있습니다.

const { containerRef } = useScrollTo();
// containerRef: Window | null
const { containerRef } = useScrollTo<HTMLDivElement>();
// containerRef: HTMLDivElement | null

<div ref={containerRef} />

Code

🔗 실제 구현 코드 확인

Interface

typescript
type ScrollBehavior = "auto" | "instant" | "smooth";
type Align = 'start' | 'center' | 'end';

interface ScrollOptions {
behavior?: ScrollBehavior; // default: 'auto'
}

interface ScrollToOptions extends ScrollOptions {
left?: number; // default: 0
top?: number; // default: 0
}

interface ScrollToElementOptions {
offsetX?: number; // default: 0
offsetY?: number; // default: 0
behavior?: ScrollBehavior; // default: 'auto'
alignY?: Align; // default: 'start'
alignX?: Align; // default: 'start'
}
typescript
// 함수 오버로딩
function useScrollTo(): {
containerRef: React.MutableRefObject<Window | null>;
scrollToPosition: (scrollToOptions?: ScrollToOptions) => void;
scrollToElement: <E extends HTMLElement>(
target: E,
scrollToElementOptions?: ScrollToElementOptions
) => void;
};

function useScrollTo<T extends HTMLElement>(): {
containerRef: React.RefObject<T>;
scrollToPosition: (scrollToOptions?: ScrollToOptions) => void;
scrollToElement: <E extends HTMLElement>(
target: E,
scrollToElementOptions?: ScrollToElementOptions
) => void;
};

Usage

typescript
import { useScrollTo } from '@modern-kit/react';

const Example = () => {
const { containerRef, scrollToPosition, scrollToElement } = useScrollTo<HTMLDivElement>();
const targetRef = useRef<HTMLDivElement | null>(null);

const handleScrollToPosition = () => {
scrollToPosition({
behavior: 'smooth',
top: 400,
});
};

const handleScrollToElement = () => {
scrollToElement(targetRef.current, {
behavior: 'smooth',
});
};

const handleScrollToElementOffset = (offset: number) => {
scrollToElement(targetRef.current, {
behavior: 'smooth',
offsetY: offset,
});
};

const handleScrollToElementAlign = (type: Align) => {
scrollToElement(targetRef.current, {
behavior: 'smooth',
alignY: type,
});
};
return (
<div>
<div>
<button onClick={handleScrollToPosition}>포지션 스크롤</button>
<button onClick={handleScrollToElement}>타겟 요소 스크롤</button>
<button onClick={() => handleScrollToElementOffset(200)}>
타겟 요소 스크롤 offset 200
</button>
<button onClick={() => handleScrollToElementOffset(-200)}>
타겟 요소 스크롤 offset -200
</button>
</div>

<div>
<button onClick={() => handleScrollToElementAlign('start')}>
타겟 요소 스크롤 align start
</button>
<button onClick={() => handleScrollToElementAlign('center')}>
타겟 요소 스크롤 align center
</button>
<button onClick={() => handleScrollToElementAlign('end')}>
타겟 요소 스크롤 align end
</button>
</div>

<div
ref={containerRef}
style={{ width: '500px', height: '800px', overflow: 'scroll' }}>
<div style={{ height: '400px', background: 'green' }}>InnerBox1</div>
<div style={{ height: '400px', background: 'red' }}>InnerBox2</div>
<div ref={targetRef} style={{ height: '400px', background: 'coral', fontSize: '24px' }}>
target Box
</div>
<div style={{ height: '400px', background: 'aqua' }}>InnerBox4</div>
<div style={{ height: '400px', background: 'black' }}>InnerBox4</div>
</div>
</div>
);
};

Example

InnerBox1
InnerBox2
target Box
InnerBox4
InnerBox4