beecomci / today_i_learned

0 stars 0 forks source link

[React JS 마스터클래스] Chapter #2 Styled Components #25

Open beecomci opened 2 years ago

beecomci commented 2 years ago

📌 CSS를 적용하는 다양한 방법

1. global css

import "./styles.css";

2. inline style

<div style={{backgroundColor: "red"}}></div>

3. module css

import styles from "./Movie.module.css";

<div className={styles.title}></div>

📌 Styled Components

import styled from "styled-components";

const Father = styled.div`
  width: 100px;
  height: 100px;
  background-color: red;
`;

<Father />

image

props

1. 설정 변경 가능한 컴포넌트

// AS-IS
// BoxOne과 BoxTwo는 background-color 속성값만 다름
const BoxOne = styled.div`
  background-color: teal;
  width: 100px;
  height: 100px;
`;
const BoxTwo = styled.div`
  background-color: tomato;
  width: 100px;
  height: 100px;
`;
// To-BE
const Box = styled.div`
  background-color: ${props => props.bgColor};
  width: 100px;
  height: 100px;
`;

<Box bgColor="teal"/>
<Box bgColor="tomato"/>

image

2. 확장 가능한 컴포넌트

// AS-IS
// Box와 Circle은 border-radius 이외의 css가 모두 동일해서 중복되는 코드 
const Box = styled.div`
  background-color: ${props => props.bgColor};
  width: 100px;
  height: 100px;
`;
const Circle = styled.div`
  background-color: ${props => props.bgColor};
  width: 100px;
  height: 100px;
  border-radius: 50px;
`;
// To-BE
const Box = styled.div`
  background-color: ${props => props.bgColor};
  width: 100px;
  height: 100px;
`;
const Circle = styled(Box)`
  border-radius: 50px;
`;

as

// button 요소가 아니라 모종의 이유로 a 요소지만 모든 스타일은 같도록 사용하고 싶다면 ? 
const Btn = styled.button`
  color: white;
  background-color: tomato;
  border-radius: 15px;
  border: 0;
`;

// Link 컴포넌트로 확장해서 만들어도 button 요소는 그대로며 같은 스타일을 사용하고 싶은거지 확장하고 싶은게 아님
const Link = styled(Btn)``;
<Btn>Log in</Btn>
<Btn as="a" href="#">Log in</Btn>

image

attrs

// AS-IS
<Input required />
// TO-BE
const Input = styled.input.attrs({ required: true })`
  background-color: yellow;
`;

<Input />
<Input />
<Input />

image

애니메이션

const rotationAnimation = keyframes`
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
`;

const Box = styled.div`
  width: 200px;
  height: 200px;
  background-color: tomato;
  animation: ${rotationAnimation} 1s linear infinite;
`;

selector

1. Styled 컴포넌트 내의 요소 select

// span 태그는 styled 컴포넌트가 아님, Box 컴포넌트 안에 위치해있을 뿐
<Box>
  <span>happy</span>
</Box>

// 그럼 Box 안에서 span을 select해서 사용하면 됨
// hover과 같은 psuedo selectors는 마치 sass처럼 &로 사용 가능 
const Box = styled.div`
  display: flex;
  width: 200px;
  height: 200px;
  background-color: tomato;
  justify-content: center;
  align-items: center;
  animation: ${rotationAnimation} 1s linear infinite;

  span {
    font-size: 30px;

    &:hover {
      color: yellow;
    }
  }
`;

2. Styled 컴포넌트 내의 Styled 컴포넌트 select

const Text = styled.span`
  font-size: 30px;
`;

const Box = styled.div`
  display: flex;
  width: 200px;
  height: 200px;
  background-color: tomato;
  justify-content: center;
  align-items: center;
  animation: ${rotationAnimation} 1s linear infinite;

  ${Text} {
    &:hover {
      color: yellow;
    }
  }
`;

<Text as="p">happy</Text>

📌 Themes

// index.js
import { ThemeProvider } from "styled-components";

// darkmode & lightmode 스위칭을 위해 속성명 동일하게 맞춤
// 그래야 theme을 사용하는 하위 styled 컴포넌트에서 모드 변경시 속성명까지 변경할 일이 없음 
const darkTheme = {
  textColor: "whitesmoke",
  backgroundColor: "#111"
};

const lightTheme = {
  textColor: "#111",
  backgroundColor: "whitesmoke"
};

ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={darkTheme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")
);
// App.js
const Wrapper = styled.div`
  display: flex;
  height: 100vh;
  width: 100vw;
  justify-content: center;
  align-items: center;
  background-color: ${props => props.theme.backgroundColor};
`;

const Title = styled.h1`
  color: ${props => props.theme.textColor};
`;