Swiper.js 라이브러리를 사용해서 반응형 슬라이더를 구현해 보았다.
Swiper는 브라우저에서만 동작하는 라이브러리라서,
'use client'를 선언하여 클라이언트 컴포넌트로 지정해야 사용이 가능했다.
// Swipers.tsx
"use client";
import React, { ReactNode } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
import { Pagination, Navigation, Autoplay } from "swiper/modules";
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
interface SwipersProps {
children: ReactNode;
}
const Swipers: React.FC<SwipersProps> = ({ children }) => {
return (
<div className="relative mx-auto w-full overflow-visible">
<Swiper
className="relative flex h-[300px] overflow-visible md:h-[430px]"
slidesPerView={3}
breakpoints={{
0: { slidesPerView: 1 },
540: { slidesPerView: 2 },
769: { slidesPerView: 3 },
}}
modules={[Navigation, Pagination, Autoplay]}
navigation={true}
pagination={{ clickable: true, type: "bullets" }}
autoplay={{ delay: 3000, disableOnInteraction: true }}
>
{React.Children.map(children, (child, index) => (
<SwiperSlide key={index}>
<div className="flex justify-center">{child}</div>
</SwiperSlide>
))}
</Swiper>
</div>
);
};
export default Swipers;
공통 컴포넌트로 분리를 해주고, props로 슬라이더 안에 들어갈 컴포넌트를 지정하는 형태로 만들었다.
interface SwipersProps {
children: ReactNode;
}
SwiperProps 타입을 정의하여 children을 ReactNode (모든 React 요소) 타입으로 받게 했다. (TypeScript)
const Swipers: React.FC<SwipersProps> = ({ children }) => {
React.FC는 React 함수형 컴포넌트 타입을 정의하는 TypeScript의 유틸리티 타입이다.
React.FC<props>
- Props 타입을 자동으로 적용
- children이 기본적으로 포함! (별도로 선언하지 않아도 children 사용 가능)
- React 함수형 컴포넌트임을 명확히 표시
React.FC를 사용하지 않으려면
const Swipers = ({ children }: SwipersProps) => { ... };
요렇게 사용하면 된다.
<Swiper
className="relative flex h-[300px] overflow-visible md:h-[430px]"
slidesPerView={3} // 한 번에 3개 슬라이드 표시
breakpoints={{ // 반응형 슬라이드 개수 조절
0: { slidesPerView: 1 },
540: { slidesPerView: 2 },
769: { slidesPerView: 3 },
}}
modules={[Navigation, Pagination, Autoplay]} // 모듈 추가
navigation={true} // 기본 네비게이션 버튼
pagination={{ clickable: true, type: "bullets" }} // 기본 페이지네이션
autoplay={{ delay: 3000, disableOnInteraction: true }}
// 3초마다 자동 슬라이드, 사용자가 조작하면 멈춤
>
그냥 Swiper에서 제공해주는 옵션들을 그대로 갖다 사용하면 된다.
modules={[Navigation, Pagination, Autoplay]}
이 modules를 꼭 포함시켜줘야 했다. 포함 안 하면 작동을 안 했음.
import { Pagination, Navigation, Autoplay } from "swiper/modules";
import도 필수 . . .
이것 말고도 정말 많은 옵션이 있다.
Swiper - The Most Modern Mobile Touch Slider
Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior.
swiperjs.com
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
여기서 확인 가능!
/* globals.css */
/* 기본 Swiper 네비게이션 버튼 커스텀 */
.swiper-button-prev,
.swiper-button-next {
position: fixed !important;
transform: translateY(-50%);
z-index: 10 !important;
top: 70% !important;
color: #efc071 !important;
}
.swiper-button-prev {
left: -50px !important;
}
.swiper-button-next {
right: -50px !important;
}
.swiper-button-prev:after,
.swiper-button-next:after {
font-size: 20px !important;
font-weight: 600 !important;
}
.swiper-pagination-bullet {
background-color: gray !important;
}
.swiper-pagination-bullet-active {
background-color: #efc071 !important;
}
@media (max-width: 540px) {
.swiper-button-prev {
left: 30px !important;
}
.swiper-button-next {
right: 30px !important;
}
}
@media (max-width: 768px) {
.swiper-pagination-bullet {
width: 6px !important;
height: 6px !important;
}
}
@media (min-width: 769px) {
.swiper-button-prev {
left: -30px !important;
}
.swiper-button-next {
right: -30px !important;
}
.swiper-button-prev:after,
.swiper-button-next:after {
font-size: 35px !important;
}
}
.swiper-button-prev:hover,
.swiper-button-next:hover {
color: #ffd795 !important;
}
.swiper-button-disabled {
opacity: 0.3 !important;
}
그리고 나는 Pagination 색깔이랑 Navigation 버튼 색깔이 맘에 안 들어서 커스텀도 해주었다!
클래스명은 기본으로 제공되기 때문에, 따로 지정해줄 필요는 없다.
원래는 기본 Navigation 버튼이 아니라 완전히 커스텀을 하고 싶었지만,
연결이 안되는 상황이 발생했다. ㅠㅠ
그리고 또 반응형으로 슬라이드 개수를 조절했는데, 메인 페이지를 서버 컴포넌트로 해놔서 그런지,
새로고침을 해야만 반응형이 적용됐다.
근데 이거는 뭐 상관 없을 것 같기도...
하지만 MVP 기능이 다 끝나고 나면 한 번 제대로 알아보려고 한다.
'개발 > 프로젝트' 카테고리의 다른 글
Tailwind CSS + SCSS로 반응형 구현하기 (0) | 2025.02.25 |
---|---|
Material UI를 사용하여 페이지네이션 구현하기 (2) | 2025.02.13 |
자동 로그인 구현하기 (0) | 2025.01.12 |
Next.js에서 RTK Query로 카카오 로그인 구현하기 (1) | 2025.01.09 |
redux-persist로 Redux 상태 유지하기 (0) | 2025.01.08 |