Atomic Habits

React. Part2. ch2. 02-2. styled-components 본문

IT/React

React. Part2. ch2. 02-2. styled-components

체계성 2021. 11. 11. 08:33

https://styled-components.com/docs/basics#getting-started

Attaching additional props 

Overriding .attrs

Animations

import styled, { keyframes } from "styled-components";

import "./styles.css";
import React from "react";
import StyledComponentsExample from "./components/StyledComponentsExample";
import styled, { keyframes } from "styled-components";

const Input = styled.input.attrs((props) => ({
  type: "text",
  size: props.size || "1em" // pros에 size가 있으면 그 값을 쓰고, 아니면 1em 쓴다.
}))`
  border: 2px solid palevioletred;
  margin: ${(props) => props.size};
  padding: ${(props) => props.size};
`;

// Input's attrs will be applied first, and then this attrs obj
const PasswordInput = styled(Input).attrs({
  type: "password"
})`
  // similarly, border will override Input's border
  border: 20px solid aqua;
`;

// Create the keyframes
const rotate = keyframes`
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
`;

// Here we create a component that will rotate everything we pass in over two seconds
const Rotate = styled.div`
  display: inline-block;
  animation: ${rotate} 5s linear infinite; 
  padding: 2rem 1rem;
  font-size: 1.2rem;
`;

export default function App() {
  return (
    <div>
      <Input placeholder="A bigger text input" size="2em" />
      <br />
      {/* Notice we can still use the size attr from Input */}
      <PasswordInput placeholder="A bigger password input" size="2em" />
      <br />
      <Rotate>&lt; 💅🏾 &gt;</Rotate>
    </div>
  );
}

 

 

○ ThemeProvider

import "./styles.css";
import React from "react";
import styled, { ThemeProvider } from "styled-components";

const Button = styled.button`
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border-radius: 3px;

  /* Color the border and text with theme.main */
  color: ${(props) => props.theme.color};
  border: 2px solid ${(props) => props.theme.borderColor};
`;

// We are passing a default theme for Buttons that arent wrapped in the ThemeProvider
Button.defaultProps = {
  theme: {
    color: "red",
    borderColor: "blue"
  }
};

// Define what props.theme will look like
const theme = {
  color: "green",
  borderColor: "red"
};

export default function App() {
  return (
    <div>
      <Button>Normal</Button>

      <ThemeProvider theme={theme}>
        {/* ThemeProvider로 둘러싸면 자식 요소에 theme가 props로 주입된다 */}
        <Button>Themed</Button>
      </ThemeProvider>
    </div>
  );
}

 

○ onClick - theme

import "./styles.css";
import React, { useState } from "react";
import styled, { ThemeProvider, createGlobalStyle } from "styled-components";

const Button = styled.button`
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border-radius: 3px;

  /* Color the border and text with theme.main */
  color: ${(props) => props.theme.color};
  border: 2px solid ${(props) => props.theme.borderColor};
`;

// We are passing a default theme for Buttons that arent wrapped in the ThemeProvider
// defaultProps 없어도 무방함
Button.defaultProps = {
  theme: {
    color: "red",
    borderColor: "red"
  }
};

// Define what props.theme will look like
const theme = {
  color: "green",
  borderColor: "red"
};
const defaultTheme = {
  color: "green",
  borderColor: "green"
};
const redTheme = {
  color: "red",
  borderColor: "red"
};
////////////////////////////////////////////////////////////////
const GlobalStyle = createGlobalStyle`
  button {
    background-color:yellow;
  }
`;
////////////////////////////////////////////////////////////////

export default function App() {
  const [theme2, setTheme2] = useState(defaultTheme);
  return (
    <>
      <div>
        {/* GlobalStyle:  div 안에 있지만, 프로젝트 전체에 우선 적용되는 스타일 */}
        <GlobalStyle />
        <Button onClick={() => setTheme2(redTheme)}>Red</Button>
        <Button onClick={() => setTheme2(defaultTheme)}>Green</Button>

        <ThemeProvider theme={theme2}>
          {/* ThemeProvider로 둘러싸면 자식 요소에 theme가 props로 주입된다 */}
          <Button>Themed</Button>
        </ThemeProvider>
      </div>
      <div>
        <button>Other</button>
      </div>
    </>
  );
}

 

// import styled from 'styled-components'

const Input = styled.input.attrs(props => ({
  type: 'text',
  size: props.small ? 5 : undefined,
}))`
  border-radius: 3px;
  border: 1px solid palevioletred;
  display: block;
  margin: 0 0 1em;
  padding: ${props => props.padding};

  ::placeholder {
    color: palevioletred;
  }
`

render(
  <>
    <Input small placeholder="Small" />
    <Input placeholder="Normal" />
    <Input padding="2em" placeholder="Padded" />
  </>
)

 

// import styled from "styled-components";

const Component = styled.div`
  color: red;
`;

render(
  <Component
    as="button"
    onClick={() => alert('It works!')}
  >
    Hello World!
  </Component>
)

 

 

Comments