프론트엔드/React 연습과제 해답

리액트 기초이론 5 - 컴포넌트 스타일링 3 - Styled Components 해답

syleemomo 2022. 3. 7. 21:56
728x90

 

* 연습과제 1

import './App.css';
import React from 'react'
import styled, { css } from 'styled-components'

const Button = styled.button`
    all: unset;
    color: white;
    cursor: pointer;
    border-radius: 5px;
    font-weight: bold;
    margin-left: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;

    &:hover{
      opacity: 0.7;
    }

    /* 버튼의 크기 설정 */
    ${props => {
      const size = props.size || 'medium'
      switch(size){
        case 'large':
          return css`
            height: 70px;
            padding-left: 15px;
            padding-right: 15px;
            font-size: 1.2rem;
          `
        case 'medium':
          return css`
            height: 50px;
            padding-left: 10px;
            padding-right: 10px;
            font-size: 1rem;
          `
        case 'small':
          return css`
            height: 30px;
            padding-left: 5px;
            padding-right: 5px;
            font-size: 0.8rem;
          `
      }
    }}

    /* 버튼의 배경색 설정 */
    ${props => {
        const color = props.color || 'tomato'
        switch(color){
          case 'blue':
            return css`
              background:blue;
              &:hover{
                background: skyblue;
              }
            `
          case 'tomato':
            return css`
              background:tomato;
              &:hover{
                background: lightsalmon;
              }
            `
          case 'grey':
            return css`
              background:grey;
              &:hover{
                background: lightgray;
              }
            `
        }
      }
    }
    /* 전체 너비를 차지하는 버튼 */
    ${props => props.width === 'fullWidth' && css`
      width: 100%;
      margin-left: 0px;
      margin-top: 10px;
      margin-bottom: 10px;
    `}
`

function App() {
  const handleClick = () => alert('clicked button') // 이벤트핸들러 함수
  return (
    <div className="App">
     <Button size="small" color="blue" onClick={handleClick}>Add Todo</Button>
     <Button size="medium" color="tomato">
       <img src="http://simpleicon.com/wp-content/uploads/rocket.png" width="30px" height="30px"></img>
       Add Todo
     </Button>
     <Button size="large" color="grey">Add todo</Button>
    </div>
  );
}

export default App;

 

* 연습과제 2

import './App.css';
import Button from './Button';
import { Component } from 'react';
import styled, { css } from 'styled-components'

const Modal = styled.div`
  width: 500px;
  margin: 100px auto;
  border: 1px solid tan;
  padding: 10px;
  text-align: center;

  ${props => {
    const state = props.open || false
    return state ? css`display: block;` : css`display: none;`
  }}
`
const Header = styled.div`
  padding: 5px;
  font-size: 1.2rem;
  font-weight: bold;
`
const Body = styled.div`
  padding: 5px;
  font-size: 0.9rem;
  margin: 20px;

  input{
    width: 60%;
    height: 30px;
    border: 1px solid lightgray;
    border-radius: 5px;
    margin-bottom: 10px;
  }
`
const Footer = styled.div`
  padding: 5px;
  display: flex;
  justify-content: flex-end;
  align-items: center;
`

class App extends Component {
  state = {
    open: false
  }
  openModal = () => {
    this.setState({ open: true })
  }
  closeModal = () => {
    this.setState({ open: false })
  }
  render(){
    const { open } = this.state
    const { openModal, closeModal} = this
    return (
      <div className="App">
        <Button handleClick={openModal}>Add Todo</Button>
        <Modal open={open}>
          <Header>You want to add new todo ?</Header>
          <Body>
            <label>todo name: <input type="text"></input></label><br/>
            <label>todo description: <input type="text"></input></label>
          </Body>
          <Footer>
            <Button size="small">Add</Button>
            <Button size="small" handleClick={closeModal}>Close</Button>
          </Footer> 
        </Modal>
      </div>
    );
  }
}

export default App;
728x90