참고 : VELOPERT Sass , Sass Guidelines
> npm i sass
// components/Button.js
import React from "react";
import "./Button.scss";
function Button({ children }) {
return <button className="Button">{children}</button>;
}
export default Button;
// components/Button.js
$blue: #228be6; // 주석 선언
.Button {
color: white;
font-weight: bold;
outline: none;
border-radius: 4px;
border: none;
cursor: pointer;
height: 2.25rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1rem;
background: $blue; // 주석 사용
&:hover {
background: lighten($blue, 10%); // 색상 10% 밝게
}
&:active {
background: darken($blue, 10%); // 색상 10% 어둡게
}
}
// App.js
import React from "react";
import "./App.scss";
import Button from "./components/Button";
function App() {
return (
<div className="App">
<div className="buttons">
<Button>BUTTON</Button>
</div>
</div>
);
}
export default App;
// App.scss
.App {
width: 512px;
margin: 0 auto;
margin-top: 4rem;
border: 1px solid black;
padding: 1rem;
}
large
, medium
, small
을 설정해줄 수 있도록 구현// components/Button.js
import React from "react";
import "./Button.scss";
function Button({ children, size }) {
return <button className={["Button", size].join(" ")}>{children}</button>;
}
Button.defaultProps = {
size: "medium",
};
export default Button;
className={['Button', size].join(' ')};
// or
className={`Button ${size}`};
classNames("foo", "bar"); // => 'foo bar'
classNames("foo", { bar: true }); // => 'foo bar'
classNames({ "foo-bar": true }); // => 'foo-bar'
classNames({ "foo-bar": false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
classNames(["foo", "bar"]); // => 'foo bar'
// 동시에 여러개의 타입으로 받아올 수 도 있습니다.
classNames("foo", { bar: true, duck: false }, "baz", { quux: true }); // => 'foo bar baz quux'
// false, null, 0, undefined 는 무시됩니다.
classNames(null, false, "bar", undefined, 0, 1, { baz: null }, ""); // => 'bar 1'
> npm i classnames
// components/Button.js
import React from "react";
import classNames from "classnames";
import "./Button.scss";
function Button({ children, size }) {
return <button className={classNames("Button", size)}>{children}</button>;
}
Button.defaultProps = {
size: "medium",
};
export default Button;
// components/Button.scss
$blue: #228be6;
.Button {
color: white;
font-weight: bold;
outline: none;
border-radius: 4px;
border: none;
cursor: pointer;
// 사이즈 관리
&.large {
height: 3rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1.25rem;
}
&.medium {
height: 2.25rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1rem;
}
&.small {
height: 1.75rem;
font-size: 0.875rem;
padding-left: 1rem;
padding-right: 1rem;
}
background: $blue;
&:hover {
background: lighten($blue, 10%);
}
&:active {
background: darken($blue, 10%);
}
// .Button + .Button
// 만약 함께 있다면 우측에 있는 버튼에 여백을 설정
& + & {
margin-left: 1rem;
}
}
// App.js
import React from "react";
import "./App.scss";
import Button from "./components/Button";
function App() {
return (
<div className="App">
<div className="buttons">
<Button size="large">BUTTON</Button>
<Button>BUTTON</Button>
<Button size="small">BUTTON</Button>
</div>
</div>
);
}
export default App;
// components/Button.js
import React from "react";
import classNames from "classnames";
import "./Button.scss";
function Button({ children, size, color }) {
return (
<button className={classNames("Button", size, color)}>{children}</button>
);
}
Button.defaultProps = {
size: "medium",
color: "blue",
};
export default Button;
// components/Button.scss
$blue: #228be6;
$gray: #495057;
$pink: #f06595;
.Button {
color: white;
font-weight: bold;
outline: none;
border-radius: 4px;
border: none;
cursor: pointer;
// 사이즈 관리
&.large {
height: 3rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1.25rem;
}
&.medium {
height: 2.25rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1rem;
}
&.small {
height: 1.75rem;
font-size: 0.875rem;
padding-left: 1rem;
padding-right: 1rem;
}
// 색상 관리
&.blue {
background: $blue;
&:hover {
background: lighten($blue, 10%);
}
&:active {
background: darken($blue, 10%);
}
}
&.gray {
background: $gray;
&:hover {
background: lighten($gray, 10%);
}
&:active {
background: darken($gray, 10%);
}
}
&.pink {
background: $pink;
&:hover {
background: lighten($pink, 10%);
}
&:active {
background: darken($pink, 10%);
}
}
& + & {
margin-left: 1rem;
}
}
mixin()
을 통해 재사용 가능// components/Button.scss
$blue: #228be6;
$gray: #495057;
$pink: #f06595;
@mixin button-color($color) {
background: $color;
&:hover {
background: lighten($color, 10%);
}
&:active {
background: darken($color, 10%);
}
}
.Button {
color: white;
font-weight: bold;
outline: none;
border-radius: 4px;
border: none;
cursor: pointer;
// 사이즈 관리
&.large {
height: 3rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1.25rem;
}
&.medium {
height: 2.25rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1rem;
}
&.small {
height: 1.75rem;
font-size: 0.875rem;
padding-left: 1rem;
padding-right: 1rem;
}
// 색상 관리
&.blue {
@include button-color($blue);
}
&.gray {
@include button-color($gray);
}
&.pink {
@include button-color($pink);
}
& + & {
margin-left: 1rem;
}
}
// App.js
import React from "react";
import "./App.scss";
import Button from "./components/Button";
function App() {
return (
<div className="App">
<div className="buttons">
<Button size="large">BUTTON</Button>
<Button>BUTTON</Button>
<Button size="small">BUTTON</Button>
</div>
<div className="buttons">
<Button size="large" color="gray">
BUTTON
</Button>
<Button color="gray">BUTTON</Button>
<Button size="small" color="gray">
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" color="pink">
BUTTON
</Button>
<Button color="pink">BUTTON</Button>
<Button size="small" color="pink">
BUTTON
</Button>
</div>
</div>
);
}
export default App;
// App.scss
.App {
width: 512px;
margin: 0 auto;
margin-top: 4rem;
border: 1px solid black;
padding: 1rem;
.buttons + .buttons {
margin-top: 1rem;
}
}
// components/Button.js
import React from "react";
import classNames from "classnames";
import "./Button.scss";
function Button({ children, size, color, outline }) {
return (
<button className={classNames("Button", size, color, { outline })}>
{children}
</button>
);
}
Button.defaultProps = {
size: "medium",
color: "blue",
};
export default Button;
outline 값을 props 로 받아와서 객체 안에 집어 넣은 다음에 classNames() 에 포함시켜줌,
이렇게 하면 outline 값이 true 일 때에만 button 에 outline CSS 클래스가 적용
만약 outline CSS 클래스가 있다면, 테두리만 보여지도록 수정
// components/Button.scss
$blue: #228be6;
$gray: #495057;
$pink: #f06595;
@mixin button-color($color) {
background: $color;
&:hover {
background: lighten($color, 10%);
}
&:active {
background: darken($color, 10%);
}
&.outline {
color: $color;
background: none;
border: 1px solid $color;
&:hover {
background: $color;
color: white;
}
}
}
.Button {
color: white;
font-weight: bold;
outline: none;
border-radius: 4px;
border: none;
cursor: pointer;
// 사이즈 관리
&.large {
height: 3rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1.25rem;
}
&.medium {
height: 2.25rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1rem;
}
&.small {
height: 1.75rem;
font-size: 0.875rem;
padding-left: 1rem;
padding-right: 1rem;
}
// 색상 관리
&.blue {
@include button-color($blue);
}
&.gray {
@include button-color($gray);
}
&.pink {
@include button-color($pink);
}
& + & {
margin-left: 1rem;
}
}
// App.js
import React from "react";
import "./App.scss";
import Button from "./components/Button";
function App() {
return (
<div className="App">
<div className="buttons">
<Button size="large">BUTTON</Button>
<Button>BUTTON</Button>
<Button size="small">BUTTON</Button>
</div>
<div className="buttons">
<Button size="large" color="gray">
BUTTON
</Button>
<Button color="gray">BUTTON</Button>
<Button size="small" color="gray">
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" color="pink">
BUTTON
</Button>
<Button color="pink">BUTTON</Button>
<Button size="small" color="pink">
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" color="blue" outline>
BUTTON
</Button>
<Button color="gray" outline>
BUTTON
</Button>
<Button size="small" color="pink" outline>
BUTTON
</Button>
</div>
</div>
);
}
export default App;
// components/Button.js
import React from "react";
import classNames from "classnames";
import "./Button.scss";
function Button({ children, size, color, outline, fullWidth }) {
return (
<button
className={classNames("Button", size, color, { outline, fullWidth })}
>
{children}
</button>
);
}
Button.defaultProps = {
size: "medium",
color: "blue",
};
export default Button;
// components/Button.scss
$blue: #228be6;
$gray: #495057;
$pink: #f06595;
@mixin button-color($color) {
background: $color;
&:hover {
background: lighten($color, 10%);
}
&:active {
background: darken($color, 10%);
}
&.outline {
color: $color;
background: none;
border: 1px solid $color;
&:hover {
background: $color;
color: white;
}
}
}
.Button {
color: white;
font-weight: bold;
outline: none;
border-radius: 4px;
border: none;
cursor: pointer;
// 사이즈 관리
&.large {
height: 3rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1.25rem;
}
&.medium {
height: 2.25rem;
padding-left: 1rem;
padding-right: 1rem;
font-size: 1rem;
}
&.small {
height: 1.75rem;
font-size: 0.875rem;
padding-left: 1rem;
padding-right: 1rem;
}
// 색상 관리
&.blue {
@include button-color($blue);
}
&.gray {
@include button-color($gray);
}
&.pink {
@include button-color($pink);
}
& + & {
margin-left: 1rem;
}
&.fullWidth {
width: 100%;
justify-content: center;
& + & {
margin-left: 0;
margin-top: 1rem;
}
}
}
// App.js
import React from "react";
import "./App.scss";
import Button from "./components/Button";
function App() {
return (
<div className="App">
<div className="buttons">
<Button size="large">BUTTON</Button>
<Button>BUTTON</Button>
<Button size="small">BUTTON</Button>
</div>
<div className="buttons">
<Button size="large" color="gray">
BUTTON
</Button>
<Button color="gray">BUTTON</Button>
<Button size="small" color="gray">
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" color="pink">
BUTTON
</Button>
<Button color="pink">BUTTON</Button>
<Button size="small" color="pink">
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" color="blue" outline>
BUTTON
</Button>
<Button color="gray" outline>
BUTTON
</Button>
<Button size="small" color="pink" outline>
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" fullWidth>
BUTTON
</Button>
<Button size="large" fullWidth color="gray">
BUTTON
</Button>
<Button size="large" fullWidth color="pink">
BUTTON
</Button>
</div>
</div>
);
}
export default App;
// components/Button.js
import React from "react";
import classNames from "classnames";
import "./Button.scss";
function Button({ children, size, color, outline, fullWidth, onClick }) {
return (
<button
className={classNames("Button", size, color, { outline, fullWidth })}
onClick={onClick}
>
{children}
</button>
);
}
Button.defaultProps = {
size: "medium",
color: "blue",
};
export default Button;
// components/Button.js
import React from "react";
import classNames from "classnames";
import "./Button.scss";
function Button({
children,
size,
color,
outline,
fullWidth,
onClick,
onMouseMove,
}) {
return (
<button
className={classNames("Button", size, color, { outline, fullWidth })}
onClick={onClick}
onMouseMove={onMouseMove}
>
{children}
</button>
);
}
Button.defaultProps = {
size: "medium",
color: "blue",
};
export default Button;
// components/Button.js
import React from "react";
import classNames from "classnames";
import "./Button.scss";
function Button({ children, size, color, outline, fullWidth, ...rest }) {
return (
<button
className={classNames("Button", size, color, { outline, fullWidth })}
{...rest}
>
{children}
</button>
);
}
Button.defaultProps = {
size: "medium",
color: "blue",
};
export default Button;
이렇게 ...rest
를 사용해서 우리가 지정한 props 를 제외한 값들을 rest 라는 객체에 모아주고, <button>
태그에 {...rest}
를 해주면, rest 안에 있는 객체안에 있는 값들을 모두 <button>
태그에 설정
App.js 에서 사용한 가장 첫번째 버튼에 onClick 을 설정
// App.js
import React from "react";
import "./App.scss";
import Button from "./components/Button";
function App() {
return (
<div className="App">
<div className="buttons">
<Button size="large" onClick={() => console.log("클릭됐다!")}>
BUTTON
</Button>
<Button>BUTTON</Button>
<Button size="small">BUTTON</Button>
</div>
<div className="buttons">
<Button size="large" color="gray">
BUTTON
</Button>
<Button color="gray">BUTTON</Button>
<Button size="small" color="gray">
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" color="pink">
BUTTON
</Button>
<Button color="pink">BUTTON</Button>
<Button size="small" color="pink">
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" color="blue" outline>
BUTTON
</Button>
<Button color="gray" outline>
BUTTON
</Button>
<Button size="small" color="pink" outline>
BUTTON
</Button>
</div>
<div className="buttons">
<Button size="large" fullWidth>
BUTTON
</Button>
<Button size="large" color="gray" fullWidth>
BUTTON
</Button>
<Button size="large" color="pink" fullWidth>
BUTTON
</Button>
</div>
</div>
);
}
export default App;