[React] React Component Styling

2022. 6. 23. 09:16·Stack/React

https://classic.yarnpkg.com/lang/en/

 

Yarn

Fast, reliable, and secure dependency management.

classic.yarnpkg.com

 

 

 

npm -> yarn

yarn을 설치한 이후 yarn start = npm start

 

리액트 컴포넌트 스타일링하기

1. scss 사용하기

yarn add node-sass (터미널 열어서 이거 치면 설치됨)

yarn add node-sass@4.14.1

npm install --save-dev sass sass-loader mini-css-extract-plugin

 

 

 

2. CSS Module

css 클래스 중첩되는 것을 방지

.module.css

style.module.css

.box{

            background: green;

}

main.module.css

.box {

            background: blue;

}

 

3. styled - components / emotion / styled-jsx

Css in JS

 

yarn add classname (터미널 열어서 이거 치면 설치됨)

<div className = "button small">

classname라이브러리 문자열, 배열, 객체들을 전달하여 문자열을 조함

classNames("button", "small") => "button small"

classNames(['button', 'large']) => "button large"

classNames({ button: true }) => "button"

classNames({ button: false }) => ""

classNames('button', {bar: true, duck: false}, 'abc') => "button bar abc"

 

yarn add styled-components  (터미널 열어서 이거 치면 설치됨)


 

Styled-react

app.js

import './App.css';
import Button from './components/Buttons.js';

function App() {
  return (
    <div className="App">
      <div>
        <Button size="large" color="blue">BUTTON</Button>
        <Button size="medium"  color="blue">BUTTON</Button>
        <Button size="small"  color="blue">BUTTON</Button>
      </div>
      <div>
        <Button size="large" color="gray">BUTTON</Button>
        <Button size="medium" color="gray">BUTTON</Button>
        <Button size="small" color="gray">BUTTON</Button>
      </div>
      <div>
        <Button size="large" color="pink">BUTTON</Button>
        <Button size="medium" color="pink">BUTTON</Button>
        <Button size="small" color="pink">BUTTON</Button>
      </div>
      <div>
        <Button size="large" color="blue" outline>BUTTON</Button>
        <Button size="medium" color="gray" outline>BUTTON</Button>
        <Button size="small" color="pink" outline>BUTTON</Button>
      </div>
      <div>
        <Button size="large" color="blue" fullWidth>BUTTON</Button>
        <Button size="large" color="gray" fullWidth>BUTTON</Button>
        <Button size="large" color="pink" fullWidth>BUTTON</Button>
      </div>
    </div>
  );
}

export default App;

 

button.js

import React from 'react';
import './Button.scss';
import classNames from 'classname';

const Buttons = ({children, size, color, outline, fullWidth}) => {
    return (
        // <button className={`button ${size}`}>{children}</button>
        <button className={classNames('Button', size, color, {outline, fullWidth})}>{children}</button>
    );
};

export default Buttons;

 

button.scss

$blue : #228be6;
$gray: #495059;
$pink: #f06595;
@mixin button-color($color) {
    background: $color;
    &:hover {
        background: darken($color, 10%);
    }
    &.outline {
        color: $color;
        background: none;
        border: 1px solid $color;
        &:hover {
            background-color: $color;
            color: #fff;
        }
    }
}
.Button {
    color: white;
    font-weight: bold;
    outline: none;
    border-radius: 6px;
    border: none;
    cursor: pointer;
    font-size: 18px;
    & + & {
        margin-left: 10px;
    }
    // 사이즈 관리
    &.large {
        padding: 20px 30px;
    }
    &.medium {
        padding: 10px 40px;
    }
    &.small {
        padding: 5px 30px;
    }

    // 색상관리
    &.blue {
        @include button-color($blue);
    }
    &.pink {
        @include button-color($pink);
    }
    &.gray {
        @include button-color($gray);
    }
    &.fullWidth {
        width: 100%;
        & + & {
            margin-left: 0;
            margin-top: 10px;
        }
    }
}

 


 

StyledComponent-react

app.js

import './App.css';
import styled from 'styled-components';
import Button from './components/Button.js';
import Dialog from './components/Dialog.js';
import { useState } from 'react';

const AppBlock  = styled.div`
  width: 512px;
  margin: 0 auto;
  margin-top: 50px;
  border: 1px solid black;
  padding: 10px;
`

const Circle = styled.section`
  width: 100px;
  height: 100px;
  background: ${props=> props.color || 'black'};
  border-radius: 50%;
`;

function App() {
  const [ dialog, setDialog ] = useState(false);
  const onClick = () => {
    setDialog(true);
  }
  const onCancel = () => {
    setDialog(false);
    console.log('취소');
  }
  const onConfirm = () => {
    setDialog(false);
    console.log('확인');
  }
  return (
    <div className="App">
      <Circle color="blue"/>
      <Circle/>
      <Circle color='pink'/>
      <AppBlock>
        <Button>button1</Button>
        <Button>button2</Button>
        <Button onClick={onClick}>button3</Button>
      </AppBlock>
      <Dialog title="정말로 삭제하시겠습니까?"
      confirmText="삭제" cancelText="취소"
      visible={dialog}
      onCancel={onCancel} onConfirm={onConfirm}>
        데이터를 삭제하시겠습니까?
      </Dialog>
    </div>
  );
}

export default App;

 

Button.js

import React from 'react';
import styled from 'styled-components';

const StyleButton = styled.button`
    /*공통스타일*/
    display: inline-flex;
    outline: none;
    border: none;
    border-radius: 4px;
    color: white;
    font-weight: bold;
    padding: 0 16px;
    line-height: 40px;
    font-size: 16px;
    background: #339af0;
    &:hover {
        background: #1c7ed6;
    }
    &+& {
        margin-left: 10px;
    }
`
const Button = ({children, onClick}) => {
    return (
            <StyleButton onClick={onClick}>{children}</StyleButton>
    );
};

export default Button;

 

Dialog.js

import React from 'react';
import styled, {keyframes} from 'styled-components';
import Button from './Button';

// 트랜지션 설정
const fadeIn = keyframes`
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
`
const slideUp = keyframes`
    from {
        transform: translateY(200px);
    }
    to {
        transform: translateY(0);
    }
`;
// 어두운배경 div
const DarkBackground = styled.div`
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0,0,0,0.7);

    animation: ${fadeIn} 0.25s;
    animation-fill-mode: forwards;
`;
// 컨텐츠 블럭
const DialogBlock = styled.div`
    width: 320px;
    padding: 20px;
    border-radius: 6px;
    background: #fff;
    h3 {
        margin: 0;
        font-size: 24px;
    }
    p {
        font-size: 18px;
    }
    animation: ${slideUp} 0.25s;
    animation-fill-mode: forwards;
`
// 버튼그룹
const ButtonGroup = styled.div`
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
`
const Dialog = ({title, children, confirmText, cancelText, visible, onCancel, onConfirm}) => {
    if(!visible) return null;
    return (
        <div>
            <DarkBackground>
                <DialogBlock>
                    <h3>{title}</h3>
                    <p>{children}</p>
                    <ButtonGroup>
                        <Button onClick={onCancel}>{cancelText}</Button>
                        <Button onClick={onConfirm}>{confirmText}</Button>
                    </ButtonGroup>
                </DialogBlock>
            </DarkBackground>          
        </div>
    );
};

export default Dialog;

 

Box.js

import React from 'react';
import styles from './Box.module.css';

const Box = (props) => {
    return (
        <div className={styles.Box}>
            나는 박스입니다.
        </div>
    );
};

export default Box;

 

Box.module.css

.Box {
    background: blue;
    color: #fff;
    padding: 20px;
}

'Stack > React' 카테고리의 다른 글

[React] Context API  (0) 2022.06.27
[React] 상태관리 (useState / useReducer)  (0) 2022.06.24
[React] to-do list  (0) 2022.06.22
[React] 라이프 사이클 메서드(Life Cycle Method)  (0) 2022.06.21
[React] event-react(Event / ref)  (0) 2022.06.21
'Stack/React' 카테고리의 다른 글
  • [React] Context API
  • [React] 상태관리 (useState / useReducer)
  • [React] to-do list
  • [React] 라이프 사이클 메서드(Life Cycle Method)
7ingout
7ingout
  • 7ingout
    Hello, 7ingout world!
    7ingout
  • 전체
    오늘
    어제
    • 분류 전체보기 (205)
      • Project (5)
      • Stack (173)
        • React (40)
        • JavaScript (50)
        • TypeScript (14)
        • HTML (11)
        • CSS (31)
        • Spring (9)
        • PHP (15)
        • SQL (3)
        • Python (0)
      • ETC (9)
      • Design (13)
        • Illustrator (6)
        • Photoshop (7)
      • Articloid (4)
        • 7ingout (4)
  • 공지사항

    • ☻
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
7ingout
[React] React Component Styling
상단으로

티스토리툴바