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 |