๐ ํ๋ก์ ํธ - ๋กค๋ง
ํ๋ก์ ํธ์์ Button ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๋ ์ค
Tailwind, cva, clsx, twMerge๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ ๊ณผ์ ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
1๏ธโฃ ๋ฌธ์ ์ํฉ
import { cva } from 'class-variance-authority';
import { cn } from '@/utils/style';
const Button = ({
children,
type = 'button',
style = 'primary',
size,
full = false,
...props
}) => {
const buttonVariants = cva(
'flex items-center justify-center rounded-md cursor-pointer',
{
variants: {
style: {
primary: 'bg-purple-600 text-white',
secondary:
'bg-white border border-solid border-purple-600 text-purple-700',
outlined:
'bg-white border border-solid border-gray-300 text-gray-900',
},
size: {
s: 'h-[28px]',
m: 'h-[36px]',
l: 'h-[40px]',
xl: 'w-[280px] h-[56px] rounded-2xl text-18-bold',
},
full: {
true: 'w-full',
},
},
}
);
return (
<button
className={cn(buttonVariants({ size, full, style }))}
type={type}
{...props}>
{children}
</button>
);
};
export default Button;
text-18-bold→ ์ปค์คํ ํฐํธ ์ ํธ๋ฆฌํฐtext-purple-700→ Tailwind ์์ ์ ํธ๋ฆฌํฐcn()→ ๋ด๋ถ์ ์ผ๋กclsx + twMerge์กฐํฉ ์ฌ์ฉ
์์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๋๋ฐ, ํ๋ฉด์์ ํฐํธ ํฌ๊ธฐ๋ ์ ์ฉ๋์ง๋ง ์์์ด ์ ์ฉ๋์ง ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์๋ค.
2๏ธโฃ ์์ธ ๋ถ์
์ด ๋ฌธ์ ๋ cn ์ ํธ ํจ์ ๋ด๋ถ์์ ์ฌ์ฉ ์ค์ธ twMerge() ๋๋ฌธ์ด์๋ค.
์ปฌ๋ฌ์ ์ปค์คํ
์ ํธ๋ฆฌํฐ๊ฐ ๋ชจ๋ text๋ผ๋ ์ ๋์ฌ๋ฅผ ์ฌ์ฉํ๊ณ ์์๊ธฐ ๋๋ฌธ์,
๋ง์ง๋ง์ ์ ์ฉ๋ text-18-bold๊ฐ text-purple-700์ ๋ฎ์ด์จ๋ฒ๋ฆฐ ๊ฒ์ด ์์ธ์ด์๋ค.
3๏ธโฃ ํด๊ฒฐ ๋ฐฉ๋ฒ
์ปค์คํ
์ ํธ๋ฆฌํฐ์ ์ ๋์ฌ๋ฅผ text ๋์ font๋ก ๋ณ๊ฒฝํ์๋ค.
@utility font-28-bold {
font-size: var(--text-28);
line-height: var(--leading-28);
font-weight: 700;
}
๋ณ๊ฒฝ ํ์ Button ์ปดํฌ๋ํธ๋ ์๋์ ๊ฐ๋ค.
import { cva } from 'class-variance-authority';
import { cn } from '@/utils/style';
const Button = ({
children,
type = 'button',
style = 'primary',
size,
full = false,
...props
}) => {
const buttonVariants = cva(
'flex items-center justify-center rounded-md cursor-pointer',
{
variants: {
style: {
primary: 'bg-purple-600 text-white',
secondary:
'bg-white border border-solid border-purple-600 text-purple-700',
outlined:
'bg-white border border-solid border-gray-300 text-gray-900',
},
size: {
s: 'h-[28px] font-14-regular',
m: 'h-[36px] font-16-medium',
l: 'h-[40px] font-16-regular',
xl: 'w-[280px] h-[56px] rounded-2xl text-18-bold',
},
full: {
true: 'w-full',
},
},
}
);
return (
<button
className={cn(buttonVariants({ size, full, style }))}
type={type}
{...props}>
{children}
</button>
);
};
export default Button;
์ด์ ๋ ์ํ๋ ๋๋ก ์คํ์ผ์ด ์ ์ ์ฉ๋์๋ค. ๐
4๏ธโฃ ์ ๋ฆฌ
clsx + twMerge์กฐํฉ์ ์ฌ์ฉํ ๋ ์ปค์คํ ์ ํธ๋ฆฌํฐ ์ ๋์ฌ๊ฐ Tailwind ๊ธฐ๋ณธ ํด๋์ค์ ๊ฒน์น๋ฉด ์์์น ๋ชปํ ๋ฎ์ด์ฐ๊ธฐ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.