Polished 라이브러리에 있는 lightn(색깔 밝게 조정)과 darken(색깔 어둡게 조정)을 사용할 것이다.
yarn add polished
입력해서 polished 라이브러리 설치한다.
import {darken, lighten} from 'polished';
polished
라이브러리 내부에 있는 darken
과 lighten
를 불러와서 사용한다.
버튼에 마우스를 올렸을때(hover)와 클릭했을때(active)의 색상 변경을 위해 사용할 것이다.
&:hover{
background: ${lighten(0.1, '#228be6')};
}
&:active{
background: ${darken(0.1, '#228be6')};
}
결과
마우스를 올리고 클릭했을때 색깔의 밝기가 조절된다.
회색과 분홍색 버튼도 제작해보자.
색깔 코드를 하나한 적는 대신에 App.js
에서 선언을 하고, 다른 컴포넌트들이 그 색깔을 조회해서 사용하게끔 만들 것이다.
이를 위해서는 themeProvider를 import해야한다.
import styled, { ThemeProvider } from "styled-components";
그리고 palette
(작명은 자유)내부에 색깔과 그에대한 코드값을 선언했다.
const palette = {
blue: '#228be6',
gray: '#adb5bd',
pink: '#f06595'
}
App
함수 return 하는 요소를 themeProvider내부로 옮긴다.
function App() {
return (
<ThemeProvider theme={{
palette
}}>
<AppBlock>
<Button>BUTTON</Button>
</AppBlock>
</ThemeProvider>
);
}
이제 palette
를 Button
컴포넌트에도 사용해보자.
${(props) => {
const color = props.theme.palette.blue;
return css`
&:hover {
background: ${lighten(0.1, color)};
}
&:active {
background: ${darken(0.1, color)};
}
`;
}}
{css}
를 import 하여 사용해야지 외부의 props를 받아와서 사용할 수 있다고 전에도 언급 했었다. props에서 theme의 palette중 blue의 색상을 color로 선언하였고, 경우에 따른 색상의 변경을 간단히 작성할수 있다.
이렇게 안하면. 다른 방법으로 작성하는데, 아래와 같다.
background: ${props => props.theme.palette.blue};
&:hover {
background: ${props => lighten(0.1, props.theme.palette.blue)};
}
&:active {
background: ${props => darken(0.1, props.theme.palette.blue)};
}
세상 번거롭게 하나하나 색상의 값을 props.theme.palette.blue
라고 작성해야한다. 이렇게 쓰기 싫어서 처음의 방법을 사용한 것이다.
다시 돌아와서, 다른 색상의 버튼을 생성하기 위해서 Button의 props에 color를 추가해서 App.js
로부터 color 값을 받아오고, 그 color 값에 해당하는 버튼을 생성할 것이다.
App.js
에 버튼을 추가로 생성
<Button>BUTTON</Button>
<Button color='pink'>BUTTON</Button>
<Button color='gray'>BUTTON</Button>
color
값을 받지 않은 경우의 defaultProps
값 설정
Button.defaultProps = {
color: 'blue'
}
props의 color 값을 App.js
에서 받아온 color props
로 설정한다.
${props => {const color = props.theme.palette[props.color];
background
의 color
값으로 지정한다.
background: ${color};
props의 color 값을 더 간략하게 표현해보자.
props 대신 비구조화 할당을 통해 {theme, color}로 바꾸면 color와 theme 앞에 붙어있는 props 제거가 가능하다.
이 때, props로부터 받아오는 color 값을 할당받는 변수의 이름을 변경해야한다. (이미 color는 선언되어있으므로, color변수를 한번 더 사용하면 오류가 발생할수 있다.)
${({theme, color}) => {
const selected = theme.palette[color];
return css`
background: ${selected};
&:hover {
background: ${lighten(0.1, selected)};
}
&:active {
background: ${darken(0.1, selected)};
}
`;
}}
색상을 styledButton 바깥으로 빼낼 수 있는데, 방법은 css를 할당받는 변수 하나를 선언해서 그 안에 위의 내용을 집어넣어준다.
const colorStyles = css`
/*색상 */
${({theme, color}) => {
const selected = theme.palette[color];
return css`
background: ${selected};
&:hover {
background: ${lighten(0.1, selected)};
}
&:active {
background: ${darken(0.1, selected)};
}
`;
}}
`
요런식으로 만들어놓으면 styledButton 내부에는
${colorStyles}
라고 이렇게만 적어도 똑같이 적용된다.
const StyledButton = styled.button`
/*공통 스타일*/
display: inline-flex;
align-items: center;
outline: none;
border: none;
border-radius: 4px;
color: white;
font-weight: bold;
cursor: pointer;
padding-left: 1rem;
padding-right: 1rem;
/*크기*/
height: 2.25rem;
font-size: 1rem;
${colorStyles} // 딸랑 한문장
/*기타 */
& + & {
margin-left: 1rem;
}
`;
function Button({ children,color, ...rest }) {
return <StyledButton color={color} {...rest}>{children}</StyledButton>;
}
Button.defaultProps = {
color: 'blue'
}
export default Button;
이렇게 하면 색상 관련 스타일을 완전히 분리해서 관리할수 있게 된다.