Button 컴포넌트에게 outline, fullWidth props를 추가로 전달한다.
outline : 내부 배경색을 지우고, 지정된 color값으로 텍스트 색을 변경하낟.
fullWidth : 컴포넌트의 width를 100% 까지 증가시킨다.
App.js
에 outline,fullWidth props를 추가한 컴퍼넌트를 생성한다
<ButtonGroup>
<Button outline>BUTTON</Button>
<Button color="pink" outline> BUTTON</Button>
<Button color="gray" outline>
BUTTON
</Button>
</ButtonGroup>
<ButtonGroup>
<Button size="large" fullWidth>BUTTON</Button>
<Button size="large"color="pink" fullWidth> BUTTON</Button>
<Button size="large"color="gray" fullWidth>
BUTTON
</Button>
</ButtonGroup>
App.js
로부터 outline, fullWidth prop를 받아온다.
function Button({ children, color, size, outline, fullWidth, ...rest }) {
return (
<StyledButton color={color} size={size} outline={outline} {...rest}>
{children}
</StyledButton>
);
}
outline이 true값이 될 경우에 바뀌는 색관련 스타일 props 이므로 전에 밖으로 따로 작성한 colorStyles에 작성해준다.
${(props) =>
props.outline &&
css`
color: ${selected};
background: none;
border: 1px solid ${selected};
&:hover {
background: ${selected};
color: white;
}
`}
fullWidth의 경우는 변수로 따로 지정한 다음 StyledButtons내부에 삽입한다.
const fullWidthStyle = css`
${(props) =>
props.fullWidth &&
css`
width: 100%;
justify-content: center;
&:not(:first-child){
margin-left: 0;
margin-top: 1rem;
}
`}
`;
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;
/*기타 */
&:not(:first-child){
margin-left: 1rem;
}
${colorStyles}
${sizeStyles}
${fullWidthStyle}
`;
결과
원래는 서로 같은 요소들끼리 붙어있을 때 옆의 요소에만 스타일을 적용하고 싶을 때 사용하는 것이지만, 모든 버튼에 동일한 마진값이 적용되는 모습을 볼수 있는데,
(&:&으로 마진값을 지정한 경우)
나는 버튼의 사이 간격을 띄우기 위해 margin-left
값을 지정해줬는데도 불구하고 서로 붙어있는 모습이 나타났다. 그리고 margin-top
값 또한 전역으로 적용된 모습이다.
styled-components의 버전이 5.1.1까지는 발생하지 않았는데, 5.2.0부터는 발생하고 있다고 한다. 필자의 버전은 현재 5.3.3이므로 이와같은 현상이 발생하고 있으며, 이를 대신할 방법으로 &:not()방법을 사용하고 있다.
&:not(:first-child){
margin-left: 1rem;
}