Skip to content

Commit

Permalink
Merge pull request #37 from SOPT-all/feat/#36/Toast
Browse files Browse the repository at this point in the history
[Feat/#36] Toast component
  • Loading branch information
minjeoong authored Jan 15, 2025
2 parents 864a5b8 + b9f9662 commit 0f68118
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 0 deletions.
23 changes: 23 additions & 0 deletions public/svgs/ic_toast_error.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions src/asset/svg/IcToastError.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as React from "react";
import type { SVGProps } from "react";
const SvgIcToastError = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={300}
height={60}
fill="none"
{...props}
>
<g filter="url(#ic_toast_error_svg__a)">
<g clipPath="url(#ic_toast_error_svg__b)">
<path
fill="#FDE9F4"
d="M10 16a8 8 0 0 1 8-8h264a8 8 0 0 1 8 8v24a8 8 0 0 1-8 8H18a8 8 0 0 1-8-8z"
/>
<path
fill="#F53D3D"
d="M12 8a2 2 0 0 1 2 2v36a2 2 0 1 1-4 0V10a2 2 0 0 1 2-2"
/>
</g>
</g>
<defs>
<clipPath id="ic_toast_error_svg__b">
<path
fill="#fff"
d="M10 16a8 8 0 0 1 8-8h264a8 8 0 0 1 8 8v24a8 8 0 0 1-8 8H18a8 8 0 0 1-8-8z"
/>
</clipPath>
<filter
id="ic_toast_error_svg__a"
width={300}
height={60}
x={0}
y={0}
colorInterpolationFilters="sRGB"
filterUnits="userSpaceOnUse"
>
<feFlood floodOpacity={0} result="BackgroundImageFix" />
<feColorMatrix
in="SourceAlpha"
result="hardAlpha"
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
/>
<feOffset dy={2} />
<feGaussianBlur stdDeviation={5} />
<feComposite in2="hardAlpha" operator="out" />
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" />
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_61_103" />
<feBlend
in="SourceGraphic"
in2="effect1_dropShadow_61_103"
result="shape"
/>
</filter>
</defs>
</svg>
);
export default SvgIcToastError;
1 change: 1 addition & 0 deletions src/asset/svg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export { default as IcTest } from "./IcTest";
export { default as IcoMessage } from "./IcoMessage";
export { default as IcoSkeleton } from "./IcoSkeleton";
export { default as Plus } from "./Plus";
export { default as IcToastError } from "./IcToastError";
export { default as React } from "./React";
export { default as Vite } from "./Vite";
64 changes: 64 additions & 0 deletions src/common/component/Toast/Toast.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { recipe, RecipeVariants } from "@vanilla-extract/recipes";
import { color, font } from "@style/styles.css.ts";
import { style } from "@vanilla-extract/css";

export const toast = recipe({
base: [
font.body01,
{
fontWeight: "500",
borderRadius: "0.8rem",
boxShadow: "0px 2px 10px 0px rgba(0, 0, 0, 0.15)",
display: "flex",
padding: "0.8rem 1.6rem",
justifyContent: "space-between",
alignItems: "center",
width: "28rem",
position: "fixed",
top: "4rem",
left: "50%",
transform: "translate(-50%, -50%)",
backgroundSize: "inherit",
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
},
],
variants: {
variant: {
default: {
background: color.gray.gray800,
color: color.gray.gray000,
},
error: {
backgroundImage: `url('/public/svgs/ic_toast_error.svg')`,
color: color.gray.gray900,
},
},
},
defaultVariants: {
variant: "default",
},
});

export const icon = recipe({
base: {
width: "2.1rem",
height: "2.1rem",
},
variants: {
iconColor: {
black: {
color: color.gray.gray900,
},
white: {
color: color.gray.gray000,
},
},
},
defaultVariants: {
iconColor: "black",
},
});

export type ToastVariants = RecipeVariants<typeof icon> &
RecipeVariants<typeof toast>;
60 changes: 60 additions & 0 deletions src/common/component/Toast/Toast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useEffect, useState } from "react";
import {
icon,
toast,
ToastVariants,
} from "@common/component/Toast/Toast.css.ts";
import { IcDelete } from "@asset/svg";

interface ToastProps {
message: string;
onClick?: () => void;
}

type CombinedButtonProps = ToastProps & Exclude<ToastVariants, undefined>;

/**
* Toast 컴포넌트
* @param message 토스트 메세지
* @param variant 종류 (default, error)
* @param iconColor 아이콘 색상 (black, white)
* @param onClick 토스트 삭제 버튼 이벤트
* @constructor
*/

export const Toast = ({
message,
variant,
iconColor,
onClick,
}: CombinedButtonProps) => {
const [isVisible, setIsVisible] = useState(true);

useEffect(() => {
const timer = setTimeout(() => {
setIsVisible(false);
}, 5000);

return () => clearTimeout(timer);
}, [5000]);

const handleDelete = () => {
setIsVisible(false);
if (onClick) {
onClick();
}
};

if (!isVisible) return null;

return (
<div className={toast({ variant })}>
{message}
<IcDelete
className={icon({ iconColor })}
color={iconColor}
onClick={handleDelete}
/>
</div>
);
};

0 comments on commit 0f68118

Please sign in to comment.