diff --git a/frontend/package.json b/frontend/package.json
index 358f1fe4b..335158204 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -13,7 +13,7 @@
"test:coverage": "jest --watchAll --coverage"
},
"dependencies": {
- "@fun-eat/design-system": "^0.3.18",
+ "@fun-eat/design-system": "^0.4.1",
"@tanstack/react-query": "^4.32.6",
"@tanstack/react-query-devtools": "^4.32.6",
"browser-image-compression": "^2.0.2",
diff --git a/frontend/src/components/Common/Carousel/Carousel.stories.tsx b/frontend/src/components/Common/Carousel/Carousel.stories.tsx
deleted file mode 100644
index 8d7eccf6f..000000000
--- a/frontend/src/components/Common/Carousel/Carousel.stories.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-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 = {
- title: 'common/Carousel',
- component: Carousel,
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {
- args: {
- carouselList: [
- {
- id: 0,
- children: 1
,
- },
- {
- id: 1,
- children: 2
,
- },
- {
- id: 2,
- children: 3
,
- },
- ],
- },
-};
-
-export const RecipeRanking: Story = {
- args: {
- carouselList: [
- {
- id: 0,
- children: ,
- },
- {
- id: 1,
- children: ,
- },
- {
- id: 2,
- children: ,
- },
- ],
- },
-};
diff --git a/frontend/src/components/Common/Carousel/Carousel.tsx b/frontend/src/components/Common/Carousel/Carousel.tsx
deleted file mode 100644
index 038b5cefa..000000000
--- a/frontend/src/components/Common/Carousel/Carousel.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import { useEffect, useState } from 'react';
-import styled from 'styled-components';
-
-import type { CarouselChildren } from '@/types/common';
-
-interface CarouselProps {
- carouselList: CarouselChildren[];
-}
-
-const Carousel = ({ carouselList }: CarouselProps) => {
- const extendedCarouselList = [...carouselList, carouselList[0]];
- const [currentIndex, setCurrentIndex] = useState(0);
-
- const CAROUSEL_WIDTH = window.innerWidth;
-
- const showNextSlide = () => {
- setCurrentIndex((prev) => (prev === carouselList.length ? 0 : prev + 1));
- };
-
- useEffect(() => {
- const timer = setInterval(showNextSlide, 2000);
-
- return () => clearInterval(timer);
- }, [currentIndex]);
-
- return (
-
-
- {extendedCarouselList.map(({ id, children }, index) => (
-
- {children}
-
- ))}
-
-
- );
-};
-
-export default Carousel;
-
-const CarouselContainer = styled.div`
- display: flex;
- width: 100%;
- border: 1px solid ${({ theme }) => theme.colors.gray2};
- border-radius: 10px;
- overflow: hidden;
-`;
-
-const CarouselWrapper = styled.ul`
- display: flex;
-`;
-
-const CarouselItem = styled.li`
- height: fit-content;
-`;
diff --git a/frontend/src/components/Common/ImageUploader/ImageUploader.tsx b/frontend/src/components/Common/ImageUploader/ImageUploader.tsx
index 9c915081e..b139a1b4c 100644
--- a/frontend/src/components/Common/ImageUploader/ImageUploader.tsx
+++ b/frontend/src/components/Common/ImageUploader/ImageUploader.tsx
@@ -1,10 +1,9 @@
-import { Button } from '@fun-eat/design-system';
+import { Button, useToastActionContext } from '@fun-eat/design-system';
import type { ChangeEventHandler } from 'react';
import styled from 'styled-components';
import { IMAGE_MAX_SIZE } from '@/constants';
import { useEnterKeyDown } from '@/hooks/common';
-import { useToastActionContext } from '@/hooks/context';
interface ReviewImageUploaderProps {
previewImage: string;
diff --git a/frontend/src/components/Common/Input/Input.stories.tsx b/frontend/src/components/Common/Input/Input.stories.tsx
deleted file mode 100644
index 48e8856a3..000000000
--- a/frontend/src/components/Common/Input/Input.stories.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-
-import Input from './Input';
-import SvgIcon from '../Svg/SvgIcon';
-
-const meta: Meta = {
- title: 'common/Input',
- component: Input,
- argTypes: {
- rightIcon: {
- control: { type: 'boolean' },
- mapping: { false: '', true: },
- },
- },
- args: {
- customWidth: '300px',
- isError: false,
- rightIcon: false,
- errorMessage: '',
- },
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {};
-
-export const WithPlaceholder: Story = {
- args: {
- placeholder: '상품 이름을 검색하세요.',
- },
-};
-
-export const WithIcon: Story = {
- args: {
- placeholder: '상품 이름을 검색하세요.',
- rightIcon: true,
- },
-};
-
-export const Error: Story = {
- args: {
- isError: true,
- errorMessage: '10글자 이내로 입력해주세요.',
- },
-};
-
-export const Disabled: Story = {
- render: () => ,
-};
diff --git a/frontend/src/components/Common/Input/Input.tsx b/frontend/src/components/Common/Input/Input.tsx
deleted file mode 100644
index c3b3b40f1..000000000
--- a/frontend/src/components/Common/Input/Input.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-import { Text, theme } from '@fun-eat/design-system';
-import type { ComponentPropsWithRef, ForwardedRef, ReactNode } from 'react';
-import { forwardRef } from 'react';
-import styled from 'styled-components';
-
-interface InputProps extends ComponentPropsWithRef<'input'> {
- /**
- * Input 컴포넌트의 너비값입니다.
- */
- customWidth?: string;
- /**
- * Input 컴포넌트의 최소 너비값입니다.
- */
- minWidth?: string;
- /**
- * Input value에 에러가 있는지 여부입니다.
- */
- isError?: boolean;
- /**
- * Input 컴포넌트 오른쪽에 위치할 아이콘입니다.
- */
- rightIcon?: ReactNode;
- /**
- * isError가 true일 때 보여줄 에러 메시지입니다.
- */
- errorMessage?: string;
-}
-
-const Input = forwardRef(
- (
- { customWidth = '300px', minWidth, isError = false, rightIcon, errorMessage, ...props }: InputProps,
- ref: ForwardedRef
- ) => {
- return (
- <>
-
-
- {rightIcon && {rightIcon}}
-
- {isError && {errorMessage}}
- >
- );
- }
-);
-
-Input.displayName = 'Input';
-
-export default Input;
-
-type InputContainerStyleProps = Pick;
-type CustomInputStyleProps = Pick;
-
-const InputContainer = styled.div`
- position: relative;
- min-width: ${({ minWidth }) => minWidth ?? 0};
- max-width: ${({ customWidth }) => customWidth};
- text-align: center;
-`;
-
-const CustomInput = styled.input`
- width: 100%;
- height: 40px;
- padding: 10px 0 10px 12px;
- color: ${({ isError }) => (isError ? theme.colors.error : theme.textColors.default)};
- border: 1px solid ${({ isError }) => (isError ? theme.colors.error : theme.borderColors.default)};
- border-radius: 5px;
-
- &:focus {
- border: 2px solid ${({ isError }) => (isError ? theme.colors.error : theme.borderColors.strong)};
- outline: none;
- }
-
- &:disabled {
- border: 1px solid ${({ theme }) => theme.borderColors.disabled};
- background: ${({ theme }) => theme.colors.gray1};
- }
-
- &::placeholder {
- color: ${theme.textColors.disabled};
- font-size: ${theme.fontSizes.sm};
- }
-`;
-
-const IconWrapper = styled.div`
- position: absolute;
- top: 0;
- right: 0;
- display: flex;
- align-items: center;
- height: 100%;
- margin-right: 8px;
-`;
-
-const ErrorMessage = styled(Text)`
- color: ${theme.colors.error};
- font-size: ${theme.fontSizes.xs};
-`;
diff --git a/frontend/src/components/Common/Skeleton/Skeleton.stories.tsx b/frontend/src/components/Common/Skeleton/Skeleton.stories.tsx
deleted file mode 100644
index e8952c316..000000000
--- a/frontend/src/components/Common/Skeleton/Skeleton.stories.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-
-import Skeleton from './Skeleton';
-
-const meta: Meta = {
- title: 'common/Skeleton',
- component: Skeleton,
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {
- args: {
- width: 100,
- height: 100,
- },
-};
diff --git a/frontend/src/components/Common/Skeleton/Skeleton.tsx b/frontend/src/components/Common/Skeleton/Skeleton.tsx
deleted file mode 100644
index 857d03079..000000000
--- a/frontend/src/components/Common/Skeleton/Skeleton.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import type { ComponentPropsWithoutRef } from 'react';
-import styled from 'styled-components';
-
-interface SkeletonProps extends ComponentPropsWithoutRef<'div'> {
- width?: string | number;
- height?: string | number;
-}
-
-const Skeleton = ({ width, height }: SkeletonProps) => {
- return ;
-};
-
-export default Skeleton;
-
-export const SkeletonContainer = styled.div`
- position: absolute;
- width: ${({ width }) => (typeof width === 'number' ? width + 'px' : width)};
- height: ${({ height }) => (typeof height === 'number' ? height + 'px' : height)};
- border-radius: 8px;
- background: linear-gradient(-90deg, #dddddd, #f7f7f7, #dddddd, #f7f7f7);
- background-size: 400%;
- overflow: hidden;
- animation: skeleton-gradient 5s infinite ease-out;
-
- @keyframes skeleton-gradient {
- 0% {
- background-position: 0% 50%;
- }
- 50% {
- background-position: 100% 50%;
- }
- 100% {
- background-position: 0% 50%;
- }
- }
-`;
diff --git a/frontend/src/components/Common/Toast/Toast.stories.tsx b/frontend/src/components/Common/Toast/Toast.stories.tsx
deleted file mode 100644
index 383c43751..000000000
--- a/frontend/src/components/Common/Toast/Toast.stories.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-
-import Toast from './Toast';
-
-import ToastProvider from '@/contexts/ToastContext';
-import { useToastActionContext } from '@/hooks/context';
-
-const meta: Meta = {
- title: 'common/Toast',
- component: Toast,
- decorators: [
- (Story) => (
-
-
-
- ),
- ],
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Default: Story = {
- render: () => {
- const { toast } = useToastActionContext();
- const handleClick = () => {
- toast.success('성공');
- };
- return (
-
-
-
- );
- },
-};
-
-export const Error: Story = {
- render: () => {
- const { toast } = useToastActionContext();
- const handleClick = () => {
- toast.error('실패');
- };
- return (
-
-
-
- );
- },
-};
diff --git a/frontend/src/components/Common/Toast/Toast.tsx b/frontend/src/components/Common/Toast/Toast.tsx
deleted file mode 100644
index c9d9dc46f..000000000
--- a/frontend/src/components/Common/Toast/Toast.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Text, useTheme } from '@fun-eat/design-system';
-import styled from 'styled-components';
-
-import { useToast } from '@/hooks/common';
-import { fadeOut, slideIn } from '@/styles/animations';
-
-interface ToastProps {
- id: number;
- message: string;
- isError?: boolean;
-}
-
-const Toast = ({ id, message, isError = false }: ToastProps) => {
- const theme = useTheme();
- const isShown = useToast(id);
-
- return (
-
- {message}
-
- );
-};
-
-export default Toast;
-
-type ToastStyleProps = Pick & { isAnimating?: boolean };
-
-const ToastWrapper = styled.div`
- position: relative;
- width: calc(100% - 20px);
- height: 55px;
- max-width: 560px;
- border-radius: 10px;
- background: ${({ isError, theme }) => (isError ? theme.colors.error : theme.colors.black)};
- animation: ${({ isAnimating }) => (isAnimating ? slideIn : fadeOut)} 0.3s ease-in-out forwards;
-`;
-
-const Message = styled(Text)`
- margin-left: 20px;
- line-height: 55px;
-`;
diff --git a/frontend/src/components/Common/index.ts b/frontend/src/components/Common/index.ts
index 070263f54..f5b218215 100644
--- a/frontend/src/components/Common/index.ts
+++ b/frontend/src/components/Common/index.ts
@@ -10,18 +10,14 @@ export { default as TabMenu } from './TabMenu/TabMenu';
export { default as TagList } from './TagList/TagList';
export { default as SectionTitle } from './SectionTitle/SectionTitle';
export { default as ScrollButton } from './ScrollButton/ScrollButton';
-export { default as Input } from './Input/Input';
export { default as ImageUploader } from './ImageUploader/ImageUploader';
export { default as ErrorBoundary } from './ErrorBoundary/ErrorBoundary';
export { default as ErrorComponent } from './ErrorComponent/ErrorComponent';
export { default as Loading } from './Loading/Loading';
export { default as MarkedText } from './MarkedText/MarkedText';
export { default as NavigableSectionTitle } from './NavigableSectionTitle/NavigableSectionTitle';
-export { default as Carousel } from './Carousel/Carousel';
export { default as RegisterButton } from './RegisterButton/RegisterButton';
-export { default as Toast } from './Toast/Toast';
export { default as CategoryItem } from './CategoryItem/CategoryItem';
export { default as CategoryFoodList } from './CategoryFoodList/CategoryFoodList';
export { default as CategoryStoreList } from './CategoryStoreList/CategoryStoreList';
-export { default as Skeleton } from './Skeleton/Skeleton';
export { default as Banner } from './Banner/Banner';
diff --git a/frontend/src/components/Members/MemberModifyInput/MemberModifyInput.tsx b/frontend/src/components/Members/MemberModifyInput/MemberModifyInput.tsx
index 39a78e6c5..6a03e4507 100644
--- a/frontend/src/components/Members/MemberModifyInput/MemberModifyInput.tsx
+++ b/frontend/src/components/Members/MemberModifyInput/MemberModifyInput.tsx
@@ -1,9 +1,7 @@
-import { Heading, Spacing, Text, useTheme } from '@fun-eat/design-system';
+import { Heading, Spacing, Text, Input, useTheme } from '@fun-eat/design-system';
import type { ChangeEventHandler } from 'react';
import styled from 'styled-components';
-import { Input } from '@/components/Common';
-
const MIN_LENGTH = 1;
const MAX_LENGTH = 10;
diff --git a/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx b/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx
index a631341d4..3856648f5 100644
--- a/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx
+++ b/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.stories.tsx
@@ -2,18 +2,9 @@ import type { Meta, StoryObj } from '@storybook/react';
import MemberReviewItem from './MemberReviewItem';
-import ToastProvider from '@/contexts/ToastContext';
-
const meta: Meta = {
title: 'members/MemberReviewItem',
component: MemberReviewItem,
- decorators: [
- (Story) => (
-
-
-
- ),
- ],
args: {
review: {
reviewId: 1,
diff --git a/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.tsx b/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.tsx
index 1d4503853..3024b982a 100644
--- a/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.tsx
+++ b/frontend/src/components/Members/MemberReviewItem/MemberReviewItem.tsx
@@ -1,9 +1,8 @@
-import { useTheme, Spacing, Text, Button } from '@fun-eat/design-system';
+import { useTheme, Spacing, Text, Button, useToastActionContext } from '@fun-eat/design-system';
import type { MouseEventHandler } from 'react';
import styled from 'styled-components';
import { SvgIcon } from '@/components/Common';
-import { useToastActionContext } from '@/hooks/context';
import { useDeleteReview } from '@/hooks/queries/members';
import type { MemberReview } from '@/types/review';
diff --git a/frontend/src/components/Product/ProductItem/ProductItem.tsx b/frontend/src/components/Product/ProductItem/ProductItem.tsx
index 43dc773e9..d961894d3 100644
--- a/frontend/src/components/Product/ProductItem/ProductItem.tsx
+++ b/frontend/src/components/Product/ProductItem/ProductItem.tsx
@@ -1,11 +1,11 @@
-import { Text, useTheme } from '@fun-eat/design-system';
+import { Text, Skeleton, useTheme } from '@fun-eat/design-system';
import { memo, useState } from 'react';
import { useParams } from 'react-router-dom';
import styled from 'styled-components';
import PreviewImage from '@/assets/characters.svg';
import PBPreviewImage from '@/assets/samgakgimbab.svg';
-import { Skeleton, SvgIcon } from '@/components/Common';
+import { SvgIcon } from '@/components/Common';
import { CATEGORY_TYPE } from '@/constants';
import type { Product } from '@/types/product';
diff --git a/frontend/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx b/frontend/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx
index b887ad10d..308f2d3fd 100644
--- a/frontend/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx
+++ b/frontend/src/components/Rank/RecipeRankingItem/RecipeRankingItem.tsx
@@ -1,9 +1,9 @@
-import { Spacing, Text, useTheme } from '@fun-eat/design-system';
+import { Spacing, Text, Skeleton, useTheme } from '@fun-eat/design-system';
import { useState } from 'react';
import styled from 'styled-components';
import RecipePreviewImage from '@/assets/plate.svg';
-import { Skeleton, SvgIcon } from '@/components/Common';
+import { SvgIcon } from '@/components/Common';
import type { RecipeRanking } from '@/types/ranking';
import { getRelativeDate } from '@/utils/date';
diff --git a/frontend/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx b/frontend/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx
index 76397964d..368bff096 100644
--- a/frontend/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx
+++ b/frontend/src/components/Rank/RecipeRankingList/RecipeRankingList.tsx
@@ -1,9 +1,8 @@
-import { Link, Text } from '@fun-eat/design-system';
+import { Carousel, Link, Text } from '@fun-eat/design-system';
import { Link as RouterLink } from 'react-router-dom';
import RecipeRankingItem from '../RecipeRankingItem/RecipeRankingItem';
-import { Carousel } from '@/components/Common';
import { PATH } from '@/constants/path';
import { useGA } from '@/hooks/common';
import { useRecipeRankingQuery } from '@/hooks/queries/rank';
diff --git a/frontend/src/components/Recipe/CommentForm/CommentForm.tsx b/frontend/src/components/Recipe/CommentForm/CommentForm.tsx
index 104657552..5eb0ac1c7 100644
--- a/frontend/src/components/Recipe/CommentForm/CommentForm.tsx
+++ b/frontend/src/components/Recipe/CommentForm/CommentForm.tsx
@@ -1,11 +1,10 @@
-import { Button, Spacing, Text, Textarea, useTheme } from '@fun-eat/design-system';
+import { Button, Spacing, Text, Textarea, useTheme, useToastActionContext } from '@fun-eat/design-system';
import type { ChangeEventHandler, FormEventHandler, RefObject } from 'react';
import { useState } from 'react';
import styled from 'styled-components';
import { SvgIcon } from '@/components/Common';
import { useScroll } from '@/hooks/common';
-import { useToastActionContext } from '@/hooks/context';
import { useRecipeCommentMutation } from '@/hooks/queries/recipe';
interface CommentFormProps {
diff --git a/frontend/src/components/Recipe/RecipeItem/RecipeItem.tsx b/frontend/src/components/Recipe/RecipeItem/RecipeItem.tsx
index 5846bd872..f7e7f229f 100644
--- a/frontend/src/components/Recipe/RecipeItem/RecipeItem.tsx
+++ b/frontend/src/components/Recipe/RecipeItem/RecipeItem.tsx
@@ -1,9 +1,9 @@
-import { Heading, Text, useTheme } from '@fun-eat/design-system';
+import { Heading, Text, Skeleton, useTheme } from '@fun-eat/design-system';
import { Fragment, memo, useState } from 'react';
import styled from 'styled-components';
import PreviewImage from '@/assets/plate.svg';
-import { Skeleton, SvgIcon } from '@/components/Common';
+import { SvgIcon } from '@/components/Common';
import type { MemberRecipe, Recipe } from '@/types/recipe';
import { getFormattedDate } from '@/utils/date';
diff --git a/frontend/src/components/Recipe/RecipeNameInput/RecipeNameInput.tsx b/frontend/src/components/Recipe/RecipeNameInput/RecipeNameInput.tsx
index 3ab0d8bc8..093f31143 100644
--- a/frontend/src/components/Recipe/RecipeNameInput/RecipeNameInput.tsx
+++ b/frontend/src/components/Recipe/RecipeNameInput/RecipeNameInput.tsx
@@ -1,8 +1,7 @@
-import { Heading, Spacing, Text, useTheme } from '@fun-eat/design-system';
+import { Heading, Input, Spacing, Text, useTheme } from '@fun-eat/design-system';
import type { ChangeEventHandler } from 'react';
import styled from 'styled-components';
-import { Input } from '@/components/Common';
import { useRecipeFormActionContext } from '@/hooks/context';
const MIN_LENGTH = 1;
diff --git a/frontend/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx b/frontend/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx
index e92d894c5..dbc7f5254 100644
--- a/frontend/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx
+++ b/frontend/src/components/Recipe/RecipeRegisterForm/RecipeRegisterForm.tsx
@@ -1,4 +1,4 @@
-import { Button, Divider, Heading, Spacing, Text, useTheme } from '@fun-eat/design-system';
+import { Button, Divider, Heading, Spacing, Text, useTheme, useToastActionContext } from '@fun-eat/design-system';
import type { FormEventHandler } from 'react';
import styled from 'styled-components';
@@ -8,7 +8,7 @@ import RecipeUsedProducts from '../RecipeUsedProducts/RecipeUsedProducts';
import { ImageUploader, SvgIcon } from '@/components/Common';
import { useImageUploader, useFormData } from '@/hooks/common';
-import { useRecipeFormValueContext, useRecipeFormActionContext, useToastActionContext } from '@/hooks/context';
+import { useRecipeFormValueContext, useRecipeFormActionContext } from '@/hooks/context';
import { useRecipeRegisterFormMutation } from '@/hooks/queries/recipe';
import type { RecipeRequest } from '@/types/recipe';
diff --git a/frontend/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx b/frontend/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx
index 8ee6faec4..00739f3fe 100644
--- a/frontend/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx
+++ b/frontend/src/components/Recipe/RecipeUsedProducts/RecipeUsedProducts.tsx
@@ -1,11 +1,11 @@
-import { Badge, Button, Heading, Text, useTheme } from '@fun-eat/design-system';
+import { Badge, Button, Heading, Text, Input, useTheme } from '@fun-eat/design-system';
import { useQueryErrorResetBoundary } from '@tanstack/react-query';
import { Suspense, useState } from 'react';
import styled from 'styled-components';
import SearchedProductList from './SearchedProductList';
-import { ErrorBoundary, ErrorComponent, Input, Loading, SvgIcon } from '@/components/Common';
+import { ErrorBoundary, ErrorComponent, Loading, SvgIcon } from '@/components/Common';
import { useDebounce } from '@/hooks/common';
import { useRecipeFormActionContext } from '@/hooks/context';
import { useSearch } from '@/hooks/search';
diff --git a/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx b/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx
index 6c422c68d..7c3ac6ec1 100644
--- a/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx
+++ b/frontend/src/components/Review/ReviewRegisterForm/ReviewRegisterForm.tsx
@@ -1,4 +1,4 @@
-import { Button, Divider, Heading, Spacing, Text, theme } from '@fun-eat/design-system';
+import { Button, Divider, Heading, Spacing, Text, theme, useToastActionContext } from '@fun-eat/design-system';
import type { FormEventHandler, RefObject } from 'react';
import styled from 'styled-components';
@@ -11,7 +11,7 @@ import { ImageUploader, SvgIcon } from '@/components/Common';
import { ProductOverviewItem } from '@/components/Product';
import { MIN_DISPLAYED_TAGS_LENGTH } from '@/constants';
import { useFormData, useImageUploader, useScroll } from '@/hooks/common';
-import { useReviewFormActionContext, useReviewFormValueContext, useToastActionContext } from '@/hooks/context';
+import { useReviewFormActionContext, useReviewFormValueContext } from '@/hooks/context';
import { useProductDetailQuery } from '@/hooks/queries/product';
import { useReviewRegisterFormMutation } from '@/hooks/queries/review';
import type { ReviewRequest } from '@/types/review';
diff --git a/frontend/src/contexts/ToastContext.tsx b/frontend/src/contexts/ToastContext.tsx
deleted file mode 100644
index f14148646..000000000
--- a/frontend/src/contexts/ToastContext.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import type { PropsWithChildren } from 'react';
-import { createContext, useState } from 'react';
-import { createPortal } from 'react-dom';
-import styled from 'styled-components';
-
-import { Toast } from '@/components/Common';
-
-interface ToastState {
- id: number;
- message: string;
- isError?: boolean;
-}
-
-interface ToastValue {
- toasts: ToastState[];
-}
-interface ToastAction {
- toast: {
- success: (message: string) => void;
- error: (message: string) => void;
- };
- deleteToast: (id: number) => void;
-}
-
-export const ToastValueContext = createContext(null);
-export const ToastActionContext = createContext(null);
-
-const ToastProvider = ({ children }: PropsWithChildren) => {
- const [toasts, setToasts] = useState([]);
-
- const showToast = (id: number, message: string, isError?: boolean) => {
- setToasts([...toasts, { id, message, isError }]);
- };
-
- const deleteToast = (id: number) => {
- setToasts((prevToasts) => prevToasts.filter((toast) => toast.id !== id));
- };
-
- const toast = {
- success: (message: string) => showToast(Number(Date.now()), message),
- error: (message: string) => showToast(Number(Date.now()), message, true),
- };
-
- const toastValue = {
- toasts,
- };
-
- const toastAction = {
- toast,
- deleteToast,
- };
-
- return (
-
-
- {children}
- {createPortal(
-
- {toasts.map(({ id, message, isError }) => (
-
- ))}
- ,
- document.getElementById('toast-container') as HTMLElement
- )}
-
-
- );
-};
-
-export default ToastProvider;
-
-const ToastContainer = styled.div`
- position: fixed;
- z-index: 1000;
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 100%;
- transform: translate(0, -10px);
-`;
diff --git a/frontend/src/hooks/common/index.ts b/frontend/src/hooks/common/index.ts
index 199ae608a..2cbf28c1f 100644
--- a/frontend/src/hooks/common/index.ts
+++ b/frontend/src/hooks/common/index.ts
@@ -10,5 +10,4 @@ export { default as useTimeout } from './useTimeout';
export { default as useRouteChangeTracker } from './useRouteChangeTracker';
export { default as useTabMenu } from './useTabMenu';
export { default as useScrollRestoration } from './useScrollRestoration';
-export { default as useToast } from './useToast';
export { default as useGA } from './useGA';
diff --git a/frontend/src/hooks/common/useImageUploader.ts b/frontend/src/hooks/common/useImageUploader.ts
index cc093517d..1f56a9923 100644
--- a/frontend/src/hooks/common/useImageUploader.ts
+++ b/frontend/src/hooks/common/useImageUploader.ts
@@ -1,8 +1,7 @@
+import { useToastActionContext } from '@fun-eat/design-system';
import imageCompression from 'browser-image-compression';
import { useState } from 'react';
-import { useToastActionContext } from '../context';
-
const isImageFile = (file: File) => file.type !== 'image/png' && file.type !== 'image/jpeg';
const options = {
diff --git a/frontend/src/hooks/common/useToast.ts b/frontend/src/hooks/common/useToast.ts
deleted file mode 100644
index f95f33ef9..000000000
--- a/frontend/src/hooks/common/useToast.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { useEffect, useRef, useState } from 'react';
-
-import { useToastActionContext } from '../context';
-
-const useToast = (id: number) => {
- const { deleteToast } = useToastActionContext();
- const [isShown, setIsShown] = useState(true);
-
- const showTimeoutRef = useRef(null);
- const deleteTimeoutRef = useRef(null);
-
- useEffect(() => {
- showTimeoutRef.current = window.setTimeout(() => setIsShown(false), 2000);
-
- return () => {
- if (showTimeoutRef.current) {
- clearTimeout(showTimeoutRef.current);
- }
- };
- }, []);
-
- useEffect(() => {
- if (!isShown) {
- deleteTimeoutRef.current = window.setTimeout(() => deleteToast(id), 2000);
- }
-
- return () => {
- if (deleteTimeoutRef.current) {
- clearTimeout(deleteTimeoutRef.current);
- }
- };
- }, [isShown]);
-
- return isShown;
-};
-
-export default useToast;
diff --git a/frontend/src/hooks/context/index.ts b/frontend/src/hooks/context/index.ts
index dd03253c9..56470cfbb 100644
--- a/frontend/src/hooks/context/index.ts
+++ b/frontend/src/hooks/context/index.ts
@@ -4,5 +4,3 @@ export { default as useReviewFormActionContext } from './useReviewFormActionCont
export { default as useReviewFormValueContext } from './useReviewFormValueContext';
export { default as useRecipeFormActionContext } from './useRecipeFormActionContext';
export { default as useRecipeFormValueContext } from './useRecipeFormValueContext';
-export { default as useToastActionContext } from './useToastActionContext';
-export { default as useToastValueContext } from './useToastValueContext';
diff --git a/frontend/src/hooks/context/useToastActionContext.ts b/frontend/src/hooks/context/useToastActionContext.ts
deleted file mode 100644
index e0d7e31a2..000000000
--- a/frontend/src/hooks/context/useToastActionContext.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useContext } from 'react';
-
-import { ToastActionContext } from '@/contexts/ToastContext';
-
-const useToastActionContext = () => {
- const toastAction = useContext(ToastActionContext);
- if (toastAction === null || toastAction === undefined) {
- throw new Error('useToastActionContext는 Toast Provider 안에서 사용해야 합니다.');
- }
-
- return toastAction;
-};
-
-export default useToastActionContext;
diff --git a/frontend/src/hooks/context/useToastValueContext.ts b/frontend/src/hooks/context/useToastValueContext.ts
deleted file mode 100644
index ca4b65ca3..000000000
--- a/frontend/src/hooks/context/useToastValueContext.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useContext } from 'react';
-
-import { ToastValueContext } from '@/contexts/ToastContext';
-
-const useToastValueContext = () => {
- const toastValue = useContext(ToastValueContext);
- if (toastValue === null || toastValue === undefined) {
- throw new Error('useToastValueContext는 Toast Provider 안에서 사용해야 합니다.');
- }
-
- return toastValue;
-};
-
-export default useToastValueContext;
diff --git a/frontend/src/hooks/queries/members/useLogoutMutation.ts b/frontend/src/hooks/queries/members/useLogoutMutation.ts
index afc27e2bc..8aed88849 100644
--- a/frontend/src/hooks/queries/members/useLogoutMutation.ts
+++ b/frontend/src/hooks/queries/members/useLogoutMutation.ts
@@ -1,9 +1,9 @@
+import { useToastActionContext } from '@fun-eat/design-system';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { logoutApi } from '@/apis';
import { PATH } from '@/constants/path';
-import { useToastActionContext } from '@/hooks/context';
const useLogoutMutation = () => {
const navigate = useNavigate();
diff --git a/frontend/src/hooks/search/useSearch.ts b/frontend/src/hooks/search/useSearch.ts
index ba9853940..bf0452206 100644
--- a/frontend/src/hooks/search/useSearch.ts
+++ b/frontend/src/hooks/search/useSearch.ts
@@ -1,9 +1,9 @@
+import { useToastActionContext } from '@fun-eat/design-system';
import type { ChangeEventHandler, FormEventHandler, MouseEventHandler } from 'react';
import { useRef, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useGA } from '../common';
-import { useToastActionContext } from '../context';
const useSearch = () => {
const inputRef = useRef(null);
diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx
index 7cb7bc771..0299216de 100644
--- a/frontend/src/index.tsx
+++ b/frontend/src/index.tsx
@@ -8,7 +8,6 @@ import { RouterProvider } from 'react-router-dom';
import { SvgSprite } from './components/Common';
import { ENVIRONMENT } from './constants';
-import ToastProvider from './contexts/ToastContext';
import router from './router';
import GlobalStyle from './styles/globalStyle';
@@ -43,9 +42,7 @@ root.render(
-
- ...loading
} />
-
+ ...loading} />
diff --git a/frontend/src/pages/IntegratedSearchPage.tsx b/frontend/src/pages/IntegratedSearchPage.tsx
index 77f781f32..a74f7a776 100644
--- a/frontend/src/pages/IntegratedSearchPage.tsx
+++ b/frontend/src/pages/IntegratedSearchPage.tsx
@@ -1,9 +1,9 @@
-import { Button, Heading, Spacing, Text } from '@fun-eat/design-system';
+import { Button, Heading, Spacing, Text, Input } from '@fun-eat/design-system';
import { useQueryErrorResetBoundary } from '@tanstack/react-query';
import { Suspense, useEffect, useState } from 'react';
import styled from 'styled-components';
-import { ErrorBoundary, ErrorComponent, Input, Loading, SvgIcon, TabMenu } from '@/components/Common';
+import { ErrorBoundary, ErrorComponent, Loading, SvgIcon, TabMenu } from '@/components/Common';
import { RecommendList, ProductSearchResultList, RecipeSearchResultList } from '@/components/Search';
import { SEARCH_TAB_VARIANTS } from '@/constants';
import { useDebounce, useTabMenu } from '@/hooks/common';
diff --git a/frontend/src/pages/MemberModifyPage.tsx b/frontend/src/pages/MemberModifyPage.tsx
index 6b3031a9e..4e6624e59 100644
--- a/frontend/src/pages/MemberModifyPage.tsx
+++ b/frontend/src/pages/MemberModifyPage.tsx
@@ -1,4 +1,4 @@
-import { Button, Spacing } from '@fun-eat/design-system';
+import { Button, Spacing, useToastActionContext } from '@fun-eat/design-system';
import type { ChangeEventHandler, FormEventHandler } from 'react';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
@@ -8,7 +8,6 @@ import { SectionTitle, SvgIcon } from '@/components/Common';
import { MemberModifyInput } from '@/components/Members';
import { IMAGE_MAX_SIZE } from '@/constants';
import { useFormData, useImageUploader } from '@/hooks/common';
-import { useToastActionContext } from '@/hooks/context';
import { useMemberModifyMutation, useMemberQuery } from '@/hooks/queries/members';
import type { MemberRequest } from '@/types/member';
diff --git a/frontend/src/pages/SearchPage.tsx b/frontend/src/pages/SearchPage.tsx
index b14c4d6a4..be5cf7971 100644
--- a/frontend/src/pages/SearchPage.tsx
+++ b/frontend/src/pages/SearchPage.tsx
@@ -1,10 +1,10 @@
-import { Button, Heading, Spacing, Text, useTheme } from '@fun-eat/design-system';
+import { Button, Heading, Spacing, Text, Input, useTheme } from '@fun-eat/design-system';
import { useQueryErrorResetBoundary } from '@tanstack/react-query';
import { Suspense, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import styled from 'styled-components';
-import { ErrorBoundary, ErrorComponent, Input, Loading, SvgIcon } from '@/components/Common';
+import { ErrorBoundary, ErrorComponent, Loading, SvgIcon } from '@/components/Common';
import { RecommendList, ProductSearchResultList, RecipeSearchResultList } from '@/components/Search';
import { SEARCH_PAGE_VARIANTS } from '@/constants';
import { useDebounce, useRoutePage } from '@/hooks/common';
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 0a59dfb08..b0955c2e1 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -1375,10 +1375,10 @@
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9"
integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==
-"@fun-eat/design-system@^0.3.18":
- version "0.3.18"
- resolved "https://registry.yarnpkg.com/@fun-eat/design-system/-/design-system-0.3.18.tgz#0c930437cd47923a9daffbaec748ef5db3b4d0c1"
- integrity sha512-d1yfTLJLKPakFzf/wiDcLkRi5cit16hDJClH4+Mj6nMtChxMeUu3VU+i4oCJNqaNjZHDw9wOa+7L4kmIcKQnRg==
+"@fun-eat/design-system@^0.4.1":
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/@fun-eat/design-system/-/design-system-0.4.1.tgz#a486b58e9cc4db2535e5ec5370b711cfc5ca78b3"
+ integrity sha512-nmAu+H0qTmR161WrOVUD5pE66W7MtZl26+fASMBLZw7al9khTUwXkiI6vMr3sGaglih0TsB0bRSiMxWKtV4DlA==
"@humanwhocodes/config-array@^0.11.11":
version "0.11.11"