styles 지정과 React component를 생성을 동시에 함
// Title component 생성 : 스타일이 적용된 <h1> 렌더링
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
// Wrapper component 생성 : 스타일이 적용된 <section> 렌더링
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
// 다른 React component처럼 사용
render(
<Wrapper>
<Title>
Hello World!
</Title>
</Wrapper>
);
render method 밖에서 styled component 정의 : 렌더링할 때마다 생성⇒캐싱X
const Wrapper = ({ message }) => {
// 경고: 매우 매우 좋지 않고 느리다. 절대 이렇게 하지마라!!
const StyledWrapper = styled.div`
/* ... */
`
return <StyledWrapper>{message}</StyledWrapper>
}
props를 기반으로 styles를 지정할 수 있음
const Button = styled.button`
/* Button에 넘겨준 props를 가지고 styled 적용 */
background: ${props => props.primary ? "palevioletred" : "white"};
color: ${props => props.primary ? "white" : "palevioletred"};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
render(
<div>
<Button>Normal</Button>
<Button primary>Primary</Button>
</div>
);
styled( ) 생성자를 사용하여 다른 styled component의 styles를 상속, 확장
const Button = styled.button`
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// Button 컴포넌트의 모든 style 속성을 물려받음
// 같은 속성이면 오버라이드
const TomatoButton = styled(Button)`
color: tomato;
border-color: tomato;
`;
render(
<div>
<Button>Normal Button</Button>
<TomatoButton>Tomato Button</TomatoButton>
</div>
);
as styles는 유지, 다른 HTML tag나 다른 custom component로 렌더링
const Button = styled.button`
display: inline-block;
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
display: block;
`;
const ReversedButton = props => <Button {...props} children={props.children.split('').reverse()} />
render(
<div>
<Button>Normal Button</Button>
<Button as={ReversedButton}>Custom Button with Normal Button styles</Button>
</div>
);
scss 와 같은 syntax 제공. & 는 styled 정의하고 있는 컴포넌트 가리킴
const Wrapper = styled.section`
display: flex;
flex-direction: column;
align-items: center;
padding: 4em;
background: papayawhip;
/* & 없으면 자식 컴포넌트 가리킴 */
.owner {
color: palevioletred;
}
`;
const Title = styled.h1`
font-size: 1.5 em;
color: palevioletred;
`;
const Button = styled.button`
background: ${(props) => (props.primary ? "white" : "palevioletred")};
color: ${(props) => (props.primary ? "palevioletred" : "white")};
font-size: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
/* & 는 Button을 가리킴 */
&:hover {
color: white;
background: palevioletred;
}
&:hover + h1 {
color: white;
}
`;
export default function App() {
return (
<Wrapper>
<Button primary>Primary</Button>
<Title>This is Title</Title>
<span className="owner">@dodose</span>
</Wrapper>
);
}
keyframes 헬퍼를 사용하여 고유한 인스턴스를 생성
// keyframes 생성하기
const rotate = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;
// keyframes 적용
const Rotate = styled.div`
display: inline-block;
animation: ${rotate} 2s linear infinite;
padding: 2rem 1rem;
font-size: 1.2rem;
`;
render(
<Rotate>< 💅🏾 ></Rotate>
);
css 헬퍼 사용도 가능
const rotate = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;
const animation = css`
animation: ${rotate} 2s linear infinite;
`
const Rotate = styled.div`
${animation};
`;
<ThemeProvider> : 모든 컴포넌트에서 공유하는 styles 지정
const Button = styled.button`
color: ${props => props.theme.fg};
border: 2px solid ${props => props.theme.fg};
background: ${props => props.theme.bg};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
`;
// 공유할 styles 지정
const theme = {
fg: "palevioletred",
bg: "white"
};
render(
// ThemeProvider 안에 있는 어떤 컴포넌트들도 theme에 정의한 styles에 접근 가능
<ThemeProvider theme={theme}>
<div>
<Button>Default Theme</Button>
</div>
</ThemeProvider>
);
$ 를 사용하여 다른 컴포넌트를 참조할 수 있다
const Link = styled.a`
display: flex;
align-items: center;
padding: 5px 10px;
background: papayawhip;
color: palevioletred;
`;
const Icon = styled.svg`
flex: none;
transition: fill 0.25s;
width: 48px;
height: 48px;
// Link 태그를 호버했을 때 Icon의 style 적용
${Link}:hover & {
fill: rebeccapurple;
}
`;
const Label = styled.span`
display: flex;
align-items: center;
line-height: 1.2;
&::before {
content: '◀';
margin: 0 10px;
}
`;
render(
<Link href="#">
<Icon viewBox="0 0 20 20">
<path d="M10 15h8c1 0 2-1 2-2V3c0-1-1-2-2-2H2C1 1 0 2 0 3v10c0 1 1 2 2 2h4v4l4-4zM5 7h2v2H5V7zm4 0h2v2H9V7zm4 0h2v2h-2V7z"/>
</Icon>
<Label>Hovering my parent changes my style!</Label>
</Link>
);
styled-components에서 제공하는 것들을 한 눈에 공부할 수 있는 좋은 글이네요 :)