이렇게 5가지의 버튼이 있을 때, 필요할 때 마다 스타일을 주는 방법도 있지만, 재사용 가능한 버튼 컴포넌트를 하나 만들어서 스타일 별로 재활용할 수 있는 방법도 있다.
1. 타입 프로퍼티를 사용하여 스타일드 컴포넌트에 속성을 전달하기
type ButtonStyleProps = {
state: "normal";
size: "small" | "medium";
colorType: "black" | "white" | "brown";
};
const ButtonStyle = styled.button<ButtonStyleProps>`
border-radius: 5px;
`;
interface BunttonProps extends ButtonStyleProps {
children: React.ReactNode;
onClick?: () => void;
}
const Button = ({ children, onClick, ...styleProps }: BunttonProps) => {
return (
<ButtonStyle {...styleProps} onClick={onClick}>
{children}
</ButtonStyle>
);
};
export default Button;
ButtonStyleProps라는 타입을 선언하고, 이 타입을 가지는 속성들을 받아 Emotion의 컴포넌트의 속성으로 사용하고 있다.
타입 프로퍼티를 사용하는 이유는 코드를 읽거나 유지보수하기 쉽게 하기 위함이다.
나는 small사이즈, medium사이즈, black컬러, white컬러, brown컬로 로 정해두었다.
2. 스타일 적용
buttonSize와 buttonType의 맞게 스타일을 정의할 필요가 있다.
예를 들면, 버튼 사이즈가 small이면 width: 50px
으로 버튼 컬러가 black이면 background-color가 background-color: #000
으로 이런 식으로 줄 수 있다.
2-1. 컬러 별 버튼 스타일
export const backButtonColorOfState = {
normal: css`
background-color: #000;
color: #fff;
&:hover {
background-color: #535050;
}
`,
};
export const whiteButtonColorOfState = {
normal: css`
background-color: #fff;
color: #000;
border: 1px solid #7a7979;
&:hover {
background-color: #f8f8f8;
}
`,
};
export const brownButtonColorOfState = {
normal: css`
background-color: ##4d100f;
color: #fff;
&:hover {
background-color: #5f3837;
}
`,
};
마지막으로 buttonType 이라는 객체로 정리해두자
export const buttonType = {
black: backButtonColorOfState,
white: whiteButtonColorOfState,
brown: brownButtonColorOfState,
};
2-2. 버튼 크기 정하기
small이면 width: 50px
으로 medium이면 width: 150px
으로 사이즈를 다르게 주었다.
export const buttonSize = {
small: css`
width: 50px;
height: 30px;
`,
medium: css`
width: 150px;
height: 30px;
`,
};
3. ButtonStyle에 적용하기
const ButtonStyle = styled.button<ButtonStyleProps>`
border-radius: 5px;
${(props) => buttonSize[props.size]}
${(props) => buttonType[props.colorType]?.[props.state]}
`;
처음에 정의한 ButtonStyle에 buttonSize와 buttonType를 적용시키자.
4. 컴포넌트 사용하기
import Button from "@components/components/button";
return (
<Button size="small" state="normal" colorType="black>
다음
</Button>
<Button size="small" state="normal" colorType="brown">
완료
</Button>
)
컴포넌트를 사용을 할 때 props로 size와 state, colorType을 넘겨주면 위에서 정의한 스타일이 적용이 된다.
전체 코드
import React from "react";
import styled from "@emotion/styled";
import { buttonSize, buttonType } from "./style";
type ButtonStyleProps = {
state: "normal";
size: "small" | "medium";
colorType: "black" | "white" | "brown";
};
const ButtonStyle = styled.button<ButtonStyleProps>`
border-radius: 5px;
${(props) => buttonSize[props.size]}
${(props) => buttonType[props.colorType]?.[props.state]}
`;
interface BunttonProps extends ButtonStyleProps {
children: React.ReactNode;
onClick?: () => void;
}
const Button = ({ children, onClick, ...styleProps }: BunttonProps) => {
return (
<ButtonStyle {...styleProps} onClick={onClick}>
{children}
</ButtonStyle>
);
};
export default Button;
import { css } from "@emotion/react";
import theme from "@components/lib/styles/theme";
export const buttonSize = {
small: css`
width: 50px;
height: 30px;
`,
medium: css`
width: 150px;
height: 30px;
`,
};
export const backButtonColorOfState = {
normal: css`
background-color: ${theme.color.black};
color: ${theme.color.white};
&:hover {
background-color: #535050;
}
`,
};
export const whiteButtonColorOfState = {
normal: css`
background-color: ${theme.color.white};
color: ${theme.color.black};
border: 1px solid #7a7979;
&:hover {
background-color: #f8f8f8;
}
`,
};
export const brownButtonColorOfState = {
normal: css`
background-color: ${theme.color.brown};
color: ${theme.color.white};
&:hover {
background-color: #5f3837;
}
`,
};
export const buttonType = {
black: backButtonColorOfState,
white: whiteButtonColorOfState,
brown: brownButtonColorOfState,
};