Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] feat: 꿀조합 랭킹 컴포넌트 추가 #478

Merged
merged 10 commits into from
Aug 17, 2023
52 changes: 52 additions & 0 deletions frontend/src/components/Common/Carousel/Carousel.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { Meta, StoryObj } from '@storybook/react';

import Carousel from './Carousel';

import { RecipeItem } from '@/components/Recipe';
import mockRecipe from '@/mocks/data/recipes.json';

const meta: Meta<typeof Carousel> = {
title: 'common/Carousel',
component: Carousel,
};

export default meta;
type Story = StoryObj<typeof Carousel>;

export const Default: Story = {
args: {
carouselList: [
{
id: 0,
children: <div>1</div>,
},
{
id: 1,
children: <div>2</div>,
},
{
id: 2,
children: <div>3</div>,
},
],
},
};

export const RecipeRanking: Story = {
args: {
carouselList: [
{
id: 0,
children: <RecipeItem recipe={mockRecipe.recipes[0]} />,
},
{
id: 1,
children: <RecipeItem recipe={mockRecipe.recipes[1]} />,
},
{
id: 2,
children: <RecipeItem recipe={mockRecipe.recipes[2]} />,
},
],
},
};
56 changes: 56 additions & 0 deletions frontend/src/components/Common/Carousel/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { ReactNode } from 'react';
import { useEffect, useState } from 'react';
import styled from 'styled-components';

interface CarouselProps {
carouselList: {
id: number;
children: ReactNode;
}[];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

따로 타입으로 빼는게 좋아보여요!

}

const CAROUSEL_WIDTH = 374;

const Carousel = ({ carouselList }: CarouselProps) => {
const extendedCarouselList = [...carouselList, carouselList[0]];
const [currentIndex, setCurrentIndex] = useState(0);

const showNextSlide = () => {
setCurrentIndex((prev) => (prev === carouselList.length ? 0 : prev + 1));
};

useEffect(() => {
const timer = setInterval(showNextSlide, 2000);

return () => clearInterval(timer);
}, [currentIndex]);

return (
<CarouselContainer>
<CarouselWrapper currentIndex={currentIndex}>
{extendedCarouselList.map(({ id, children }) => (
<CarouselItem key={id}>{children}</CarouselItem>
))}
</CarouselWrapper>
</CarouselContainer>
);
};

export default Carousel;

const CarouselContainer = styled.div`
display: flex;
width: ${CAROUSEL_WIDTH}px;
overflow: hidden;
`;

const CarouselWrapper = styled.ul<{ currentIndex: number }>`
display: flex;
transition: ${({ currentIndex }) => (currentIndex === length ? '' : 'all 0.5s ease-in-out')};
transform: ${({ currentIndex }) => 'translateX(-' + currentIndex * CAROUSEL_WIDTH + 'px)'};
`;

const CarouselItem = styled.li`
width: ${CAROUSEL_WIDTH}px;
height: fit-content;
`;
1 change: 1 addition & 0 deletions frontend/src/components/Common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export { default as Loading } from './Loading/Loading';
export { default as MarkedText } from './MarkedText/MarkedText';
export { default as MoreButton } from './MoreButton/MoreButton';
export { default as NavigableSectionTitle } from './NavigableSectionTitle/NavigableSectionTitle';
export { default as Carousel } from './Carousel/Carousel';
export { default as RegisterButton } from './RegisterButton/RegisterButton';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Meta, StoryObj } from '@storybook/react';

import RecipeRankingList from './RecipeRankingList';

const meta: Meta<typeof RecipeRankingList> = {
title: 'recipe/RecipeRankingList',
component: RecipeRankingList,
};

export default meta;
type Story = StoryObj<typeof RecipeRankingList>;

export const Default: Story = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import RecipeItem from '../RecipeItem/RecipeItem';

import { Carousel } from '@/components/Common';
import mockRecipeList from '@/mocks/data/recipes.json';

const RecipeRankingList = () => {
const carouselList = mockRecipeList.recipes.map((recipe, index) => ({
id: index,
children: <RecipeItem recipe={recipe} />,
}));

return <Carousel carouselList={carouselList} />;
};

export default RecipeRankingList;
1 change: 1 addition & 0 deletions frontend/src/components/Recipe/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export { default as RecipeItem } from './RecipeItem/RecipeItem';
export { default as RecipeList } from './RecipeList/RecipeList';
export { default as RecipeRegisterForm } from './RecipeRegisterForm/RecipeRegisterForm';
export { default as RecipeFavorite } from './RecipeFavorite/RecipeFavorite';
export { default as RecipeRankingList } from './RecipeRankingList/RecipeRankingList';
Loading