Skip to content

Commit

Permalink
swiper 모듈 구현 (#180)
Browse files Browse the repository at this point in the history
* feat: 스와이프 모듈 구현

* fix: 배포에러 해결

---------

Co-authored-by: 이재하 <[email protected]>
  • Loading branch information
ksmfou98 and Leejha authored Oct 16, 2023
1 parent 03bc0fe commit eed43fe
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 123 deletions.
70 changes: 59 additions & 11 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ plugins:
spec: "@yarnpkg/plugin-typescript"

packageExtensions:
follow-redirects@*:
swiper@*:
dependencies:
debug: "*"
debug@*:
dependencies:
supports-color: "*"
"@types/react": "^17"
react: "^17"

yarnPath: .yarn/releases/yarn-3.3.0.cjs
3 changes: 2 additions & 1 deletion apps/jurumarble/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"react-toastify": "^9.1.3",
"sharp": "^0.32.6",
"styled-components": "^5.3.6",
"styled-reset": "^4.5.1"
"styled-reset": "^4.5.1",
"swiper": "9.4.1"
},
"devDependencies": {
"@svgr/cli": "^8.0.1",
Expand Down
3 changes: 3 additions & 0 deletions apps/jurumarble/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { injectStyle } from "react-toastify/dist/inject-style";
import AuthProcess from "components/AuthProcess";
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";

export const metadata: Metadata = {
title: "주루마블",
Expand Down
143 changes: 45 additions & 98 deletions apps/jurumarble/src/app/main/components/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,96 +3,62 @@ import Path from "lib/Path";
import Image from "next/image";
import { useRouter } from "next/navigation";
import styled, { css } from "styled-components";
import { useCallback, useEffect, useRef, useState } from "react";
import { SvgIcPrevious, SvgNext } from "src/assets/icons/components";

const SLIDE_MOVE_COUNT = 1;
const ORIGINAL_IMAGE_LENGTH = 10;
const MOVE_DISTANCE = 300;
import { ContentSwiper } from "@monorepo/ui";
import { Autoplay } from "swiper";
import SwiperCore from "swiper";
import { useRef } from "react";

interface Props {
hotDrinkList: GetHotDrinkResponse[];
}

function Carousel({ hotDrinkList }: Props) {
const router = useRouter();
const slideRef = useRef<HTMLOListElement>(null);
const [currentSlide, setCurrentSlide] = useState(1);
const [isAnimation, setIsAnimation] = useState(true);
const [isFlowing, setIsFlowing] = useState(true);

const onNextSlide = useCallback(() => {
setCurrentSlide((prev) => prev + SLIDE_MOVE_COUNT);
}, [currentSlide]);

const onPrevSlide = useCallback(() => {
setCurrentSlide((prev) => prev - SLIDE_MOVE_COUNT);
}, [currentSlide]);

useEffect(() => {
if (!slideRef.current) return;

if (currentSlide === ORIGINAL_IMAGE_LENGTH + 1) {
setTimeout(() => {
setIsAnimation(false);
slideRef.current!.style.transform = `translateX(-${
MOVE_DISTANCE * ORIGINAL_IMAGE_LENGTH
}px)`;
setCurrentSlide(1);
}, 500);

setTimeout(() => {
setIsAnimation(true);
}, 600);
} else if (currentSlide === 0) {
setTimeout(() => {
setIsAnimation(false);
slideRef.current!.style.transform = `translateX(+${MOVE_DISTANCE}px)`;
setCurrentSlide(ORIGINAL_IMAGE_LENGTH);
}, 500);

setTimeout(() => {
setIsAnimation(true);
}, 600);
}
slideRef.current.style.transform = `translateX(-${MOVE_DISTANCE * (currentSlide - 1)}px)`;
}, [currentSlide]);

useEffect(() => {
let intervalId: NodeJS.Timeout;
if (isFlowing) {
intervalId = setInterval(() => {
setCurrentSlide((prev) => prev + SLIDE_MOVE_COUNT);
}, 3500);
}
return () => clearTimeout(intervalId);
}, [isFlowing, currentSlide]);
const ref = useRef<SwiperCore>(null);

const onNextSlide = () => {
ref.current?.slideNext();
};

const onPrevSlide = () => {
ref.current?.slidePrev();
};

return (
<>
<Container>
<Slides ref={slideRef} isAnimation={isAnimation}>
{hotDrinkList.map((hotDrink: GetHotDrinkResponse, index: number) => {
const { drinkId, image, name, manufactureAddress } = hotDrink;
return (
<Slide
key={drinkId}
onClick={() => router.push(`${Path.DRINK_INFO_PAGE}/${drinkId}`)}
>
<Box>
<DrinkImageWrapper>
<RankginMark>{index + 1}</RankginMark>
<Image alt="전통주" src={image} fill style={{ borderRadius: "10px" }} />
</DrinkImageWrapper>
<DrinkText>
{name}
<AreaName>{manufactureAddress}</AreaName>
</DrinkText>
</Box>
</Slide>
);
})}
</Slides>
<ContentSwiper
data={hotDrinkList}
handler={ref}
slideProps={{
width: "292px",
lazy: true,
}}
swiperProps={{
slidesPerView: "auto",
spaceBetween: 5,
loop: true,
autoplay: {
delay: 2000,
},
modules: [Autoplay],
}}
renderItem={({ drinkId, image, name, manufactureAddress }, index) => (
<Slide key={drinkId} onClick={() => router.push(`${Path.DRINK_INFO_PAGE}/${drinkId}`)}>
<Box>
<DrinkImageWrapper>
<RankginMark>{index + 1}</RankginMark>
<Image alt="전통주" src={image} fill style={{ borderRadius: "10px" }} />
</DrinkImageWrapper>
<DrinkText>
{name}
<AreaName>{manufactureAddress}</AreaName>
</DrinkText>
</Box>
</Slide>
)}
/>
<CarouselControlContainer>
<DivideLine />
<SlideButtonContainer>
Expand All @@ -114,29 +80,10 @@ const Container = styled.div`
overflow: hidden;
`;

const Slides = styled.ol<{ isAnimation: boolean }>`
display: flex;
/* overflow-x: auto;
scroll-snap-type: x mandatory; */
gap: 8px;
transition: transform 0.5s ease-in-out;
${({ isAnimation }) => isAnimation && `transform: translateX(-${MOVE_DISTANCE}px);`}
/**
@Todo 모바일에서는 보이게 하기
**/
-ms-overflow-style: none /* IE and Edge 스크롤바 없애는 css*/;
scrollbar-width: none; /* Firefox 스크롤바 없애는 css */
&::-webkit-scrollbar {
display: none; /* Chrome , Safari , Opera 스크롤바 없애는 css*/
}
`;

const Slide = styled.li`
width: 292px;
height: 120px;
height: 130px;
padding-top: 20px;
/* scroll-snap-align: start; */
cursor: pointer;
`;

Expand Down
1 change: 1 addition & 0 deletions packages/ui/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { default as Input } from "./input/Input";
export { default as FloatComponentTemplate } from "./modal/FloatComponentTemplate";
export { default as DivideLine } from "./divide/DivideLine";
export * from "./selectBox";
export * from "./swiper";
Loading

0 comments on commit eed43fe

Please sign in to comment.