ETC -

Tab Slider 기능

  • -

안녕하세요 트리플랩입니다.

오늘은 평소에 자주 보시는 네이버 Tab Slider기능에 관해서 살펴보겠습니다.

아래 GIF를 보시면 사용자가 탭을 클릭할때마다 메뉴들이 좌우로 슬라이드가 되는 것을 확인 할수 있습니다.

네이버 메뉴 탭 모습

이것을 리액트기반으로 만들어서 공유할려고 합니다.!!

코드 공유

import { useRef, useState } from 'react';
import clsx from 'clsx';
import { TabSliderPageStyled } from '@/styles/pageStyled/TabSliderPageStyled';

const items = [
  '쇼핑라이브',
  '징보기',
  '원뿔딜',
  '책방',
  '선물샵',
  '도착보장',
  '패션뷰티',
  '쇼핑',
  '홈',
  '뉴스',
  '스포츠',
  '연예',
  '경제',
  '쇼핑투데이',
  '자동차',
  '게임',
  '클립',
  '건강',
  '웹툰',
  '지식+',
];

export default function TabsSliderPage() {
  const [activeIndex, setActiveIndex] = useState(2);
  const sliderRef = useRef<HTMLDivElement>(null); // 슬라이더를 참조

  const handleClick = (index: number) => {
    setActiveIndex(index);
    const slider = sliderRef.current;
    if (slider) {
      const itemWidth = slider.scrollWidth / items.length;
      const scrollPos = itemWidth * index - slider.offsetWidth / 2 + itemWidth / 2;
      console.log(scrollPos);
      slider.scrollTo({ left: scrollPos, behavior: 'smooth' }); // 스크롤 이동
    }
  };

  return (
    <TabSliderPageStyled className={clsx('TabSliderPage')} ref={sliderRef}> {/* 직접 ref를 div에 연결 */}
        {items.map((item, index) => (
          <div
            key={index}
            className={`slider-item ${index === activeIndex ? 'active' : ''}`}
            onClick={() => handleClick(index)}
          >
            {item}
          </div>
        ))}
    </TabSliderPageStyled>
  );
}
export const TabSliderPageStyled = styled.div<TabSliderPageStyledProps>`
  display: flex;
  gap: 20px;
  min-width: 500px; /* 슬라이더가 스크롤될 수 있도록 충분한 너비 설정 */
  overflow: auto;
`;

Hook 생성

해당 기능을 좀더 범용적으로 씌일수 있도록 훅을 만들어 보겠습니다.
그리고 scrollTo말고 scrollIntoView으로 변경했습니다.
scrollIntoView수평과 수직을 변경할수 있는 옵션을 제공해주고 있어서 유용합니다.!!😃 😃

import { useRef, useState } from 'react';

export const useSlider = (initialIndex: number = 0) => {
  const [activeIndex, setActiveIndex] = useState(initialIndex);
  const sliderRef = useRef<HTMLDivElement>(null);

  const handleClick = (index: number) => {
    setActiveIndex(index);
    const slider = sliderRef.current;
    if (slider) {
      const item = slider.children[index] as HTMLElement;

      item.scrollIntoView({
        behavior: 'smooth',
        block: 'nearest', // 수직 방향 정렬
        inline: 'center', // 수평 방향 중앙 정렬
      });
    }
  };

  return {
    activeIndex,
    sliderRef,
    handleClick,
  };
};
'use client';

import Link from 'next/link';
import clsx from 'clsx';
import { TabSliderPageStyled } from '@/app/tabsSlider/TabSliderPageStyled';
import { useSlider } from '@/hooks/useSlider'; // 훅을 임포트

const items = [
  '쇼핑라이브', '징보기', '원뿔딜', '책방', '선물샵', '도착보장', '패션뷰티',
  '쇼핑', '홈', '뉴스', '스포츠', '연예', '경제', '쇼핑투데이', '자동차',
  '게임', '클립', '건강', '웹툰', '지식+',
];

export default function TabsSliderPage() {
  const { activeIndex, sliderRef, handleClick } = useSlider(0); // 훅 사용

  return (
    <TabSliderPageStyled className={clsx('TabSliderPage')} ref={sliderRef}>
      {items.map((item, index) => (
        <li
          key={index}
          className={`slider-item ${index === activeIndex ? 'active' : ''}`}
          onClick={() => handleClick(index)}
        >
          <Link className="nav_link" href={'#0'} role="tab">
            {item}
          </Link>
        </li>
      ))}
    </TabSliderPageStyled>
  );
}

이렇게해서 좌,우슬라이드와, 탭기능 클릭시 메뉴가 center에 유지하도록 만들어봤습니다!!

감사합니다.👍👍👍

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.