
Toast는 특색있게 만들고싶어서 팀원이랑 열심히 디자인 했는데 완전 마음에 들지는 않는다..ㅋㅋ 그래두 나름 귀여운 것 같다. contained를 먼저 만들었는데 많이 해맸다ㅠㅠ 팀원에게 헬프를 요청해서 겨우 만들었고 outlined는 contained를 기반으로 빠르게 뚝딱 만들었다. 확실히 지금까지보다 난이도 있는 것을 만들어보니 공부가 많이 됐다. 벨로그에 쓸 말도 많아서 좋다ㅎ
const colors = {
green: {
100: '#E9F9DC',
500: '#03A400',
},
red: {
100: '#F9DFDC',
500: '#F44336',
},
blue: {
100: '#DCEBF9',
500: '#2196F3',
},
orange: {
100: '#F9EADC',
500: '#ED6C02',
},
};
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['src/**/*.{js,jsx,ts,tsx}'],
darkMode: 'class',
theme: {
extend: {
colors: {
success: {
...colors.green,
default: colors.green['500'],
},
error: {
...colors.red,
default: colors.red['500'],
},
info: {
...colors.blue,
default: colors.blue['500'],
},
warning: {
...colors.orange,
default: colors.orange['500'],
},
},
fontFamily: {
sans: ['Inter', ...defaultTheme.fontFamily.sans],
},
},
},
plugins: [],
};
먼저 Toast 색 마다 연한 색 하나와 진학색 하나가 필요해서 secondary, primary와 방식으로 tailwind.config.js 파일에 색을 정의해줬다.
interface ToastProps
extends Omit<React.HTMLAttributes<HTMLDivElement>, 'size'> {
variant?: 'contained' | 'outlined';
type?: 'success' | 'error' | 'info' | 'warning';
size?: 'small' | 'medium' | 'large';
open?: boolean;
}
return (
<>
{open && (
토스트
)}
</>
);
Toast는 open이라는 props를 줬는데 기본 값은 false이고 open이 true일 때만 나타나게 해줬다. 이 방식을 사용하기 위해서 상위 div가 필요했기 때문에 <></>로 감싸줬다.
return (
<>
{open && (
<div className={ToastClass} {...props}>
<div className="flex items-center">
{variant === 'contained' ? (
<div className={clsx(🌸containedBaseStyles, borderStyles[type])}>
{🌸containedIconStyles[type]}
</div>
) : (
<div className={clsx(🌸outlinedBaseStyles)}>
{🌸outlinedIconStyles[type]}
</div>
)}
<div className="flex items-center">{children}</div>
{variant === 'outlined' && (
<div className="text-black w-10 flex justify-end cursor-pointer">
x
</div>
)}
</div>
</div>
)}
</>
);
Toast는 contained와 outlined의 왼쪽 아이콘 부분 디자인이 많이 달라서 🌸containedBaseStyles, containedIconStyles, outlinedBaseStyles, outlinedIconStyles 객체를 따로 만들었다.
const containedBaseStyles = 'w-30 h-38 border-r-2 pr-2 mr-2';
const outlinedBaseStyles = 'w-30 h-38 pr-2 mr-2';

contained는 저 진한 녹색 줄을 만들기위해 div의 오른쪽에만 가장자리 선이 생기도록 했다. 나머지는 똑같다.
const outlinedIconStyles = {
success: (
<div className="bg-success-100 rounded-bl-lg rounded-t-full rounded-br-full w-9 h-9 flex justify-center items-center">
<svg
width="29"
height="28"
viewBox="0 0 29 28"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g id="AlertCheckCircle">
<path
id="Vector"
d="M20.0466 8.84331L12.0837 16.5316L7.74574 12.355L6.04199 14L12.0837 19.8333L21.7503 10.5L20.0466 8.84331ZM14.5003 2.33331C7.83033 2.33331 2.41699 7.55998 2.41699 14C2.41699 20.44 7.83033 25.6666 14.5003 25.6666C21.1703 25.6666 26.5837 20.44 26.5837 14C26.5837 7.55998 21.1703 2.33331 14.5003 2.33331ZM14.5003 23.3333C9.15949 23.3333 4.83366 19.1566 4.83366 14C4.83366 8.84331 9.15949 4.66665 14.5003 4.66665C19.8412 4.66665 24.167 8.84331 24.167 14C24.167 19.1566 19.8412 23.3333 14.5003 23.3333Z"
fill="#4CAF50"
/>
</g>
</svg>
</div>
)
}
iconStyles는 코드가 너무 길어서 일부분만 가져왔다. 아이콘은 svg파일을 가져왔는데 처음엔 public에 저장해서 임포트하는 방식으로 하려다가 임포트를 실패해서 그냥 svg 코드를 그대로 복붙했다. 아직도 실패 이유는 찾지못했다ㅠㅠ

SUI만의 특별한 디자인이다..ㅋ 보다보면 귀엽다. 위와 오른쪽 아래는 rounded를 full로 주고 왼쪽 아래만 다르게 해서 만들 수 있다.
const baseStyles =
'font-medium rounded rounded-lg py-3 drop-shadow-md w-fit pl-3 pr-5 🌸z-100';
🌸z인덱스도 Toast에서 처음 써봤는데 z인덱스를 사용하면 아이템들 위에 Toast가 나타난다. 수돌로그에 적용시켜보고 싶은데 솔직히 Toast는 못생겨서 안쓰고싶다...


코드 리뷰라는 거 정말 멋지다😲 위에서 말한 svg 임포트 실패가 바로 저 주석이다ㅠㅠ Toast가 제일 어려울 것 같았는데 끝내서 자신감 max 상태다!! 다음 컴포넌트도 먹어버려야겠다