๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

WINK-(Web & App)/React.js ์Šคํ„ฐ๋””

[2025 1ํ•™๊ธฐ React.js ์Šคํ„ฐ๋””] ์ด์ƒ๋ž˜ #5์ฃผ์ฐจ

๋ฐ˜์‘ํ˜•

ใ…‹ใ…‹

๐Ÿ”  Sass

Sass (Syntactically Awesome Style Sheets)

 

  • CSS pre-processor ๋กœ์„œ, ๋ณต์žกํ•œ ์ž‘์—…์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ
  • ์ฝ”๋“œ์˜ ์žฌํ™œ์šฉ์„ฑ์„ ๋†’์ž„
  • ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์—ฌ์ฃผ์–ด ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์‰ฝ๊ฒŒํ•จ
  • ๋‘๊ฐ€์ง€์˜ ํ™•์žฅ์ž ์ง€์›(.scss/ .sass)

๐Ÿ‘€ sass

$font-stack:    Helvetica, sans-serif
$primary-color: #333

body
  font: 100% $font-stack
  color: $primary-color

 

๐Ÿ‘€ scss

$font-stack:    Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

 

์ฐจ์ด์ 

  1. ๋ฌธ๋ฒ•
    • { }; ์˜ ์œ ๋ฌด scss์—์„œ๋Š” {};๋ฅผ ์‚ฌ์šฉํ•จ
    • ํ™•์žฅ์ž
    • ๋ณดํ†ต scss๊ฐ€ ๋” ๋งŽ์ด ์‚ฌ์šฉ๋จ
  2. ํ™•์žฅ์ž

์˜ˆ์ œ๋กœ scss๋ฅผ ํ•ด๋ดค๋Š”๋ฐ์š”

css๋ž‘์€ ์กฐ๊ธˆ ๋‹ค๋ฅธ ๋ฌธ๋ฒ•

  • $blue: #228be6 
  • lighten() darken() ๊ฐ™์€๊ฑด ์—†์—ˆ๋Š”๋ฐ ์กฐ๊ธˆ ๋‹ค๋ฅด๋„ค์š”

์š”๊ฑฐ๋ฅผ ์˜ˆ์ œ๋กœ ์—ด์‹ฌํžˆ ๊ณต๋ถ€ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค !!!

๐Ÿ‘€  ๋ฒ„ํŠผ ์‚ฌ์ด์ฆˆ ์กฐ์ •ํ•˜๊ธฐ

์ด๋Ÿฐ์‹์œผ๋กœ

- className์— CSS ํด๋ž˜์Šค ์ด๋ฆ„์„ ๋™์ ์œผ๋กœ ๋„ฃ์–ด์ฃผ๊ณ  ์‹ถ์„๋•Œ (className={['Button', size].join(' ')} ๋˜๋Š”

- className={'Button ${size}'}

 

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๋ณด๋‹ค classNames ๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ? ๋” ํŽธํ•˜๋‹ค!

classNames - ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง์„ ํ•  ๋•Œ ํ•จ์ˆ˜์˜ ์ธ์ž์— ๋ฌธ์ž์—ด, ๋ฐฐ์—ด, ๊ฐ์ฒด ๋“ฑ์„ ์ „๋‹ฌํ•˜์—ฌ ์†์‰ฝ๊ฒŒ ๋ฌธ์ž์—ด์„ ์กฐํ•ฉ ํ•  ์ˆ˜ ์žˆ์Œ
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'

 

scss ์‚ดํŽด๋ณด๊ธฐ

์—ฌ๊ธฐ ๋ณด์‹œ๋ฉด

.Button {
  &.large {

  }
} //์ด๊ฑฐ๋ž‘

.Button.large {

} //์ด๊ฑฐ๋ž‘ ๊ฐ™๋‹ค~

 

๊ฒฐ๊ตญ, Button ๊ณผ large CSS ํด๋ž˜์Šค๊ฐ€ ํ•จ๊ป˜ ์ ์šฉ๋˜์–ด ์žˆ์œผ๋ฉด ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๊ฒ ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธ.

 

๋žœ๋”๋ง ํ•ด์ฃผ๋ฉด ํ™”๋ฉด์— ์ด๋ ‡๊ฒŒ ๋œจ๋„ค์š” ๊ทผ๋ฐ small์ด ๊ธฐ๋ณธ๋ณด๋‹ค ํฌ๋„ค

 

๋งˆ์ง€๋ง‰์— ์ด๊ฑธ ์ถ”๊ฐ€ํ•˜๋Š”๋ฐ

๋‚œ์ƒ ์ฒ˜์Œ๋ด…๋‹ˆ๋‹ค ์ด๋Ÿฐ๊ฑด ใ…‹ใ…‹

& + & = .Button + .Button์ด๋ผ๊ณ  ํ•˜๋„ค์š”... ๊ทธ๋ž˜์„œ ์—ฌ๋ฐฑ์„ ์ค€๊ฑฐ๋ž‘ ๊ฐ™์•„์„œ ์ €๋ ‡๊ฒŒ ๋ฐ”๋€Œ๋„ค์š”


 

๐Ÿ‘€  ๋ฒ„ํŠผ ์ƒ‰์ƒ ์„ค์ •ํ•˜๊ธฐ

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ƒ‰๋งˆ๋‹ค ํ•˜๋‚˜ํ•˜๋‚˜ ์ฝ”๋“œ๋ฅผ ์ณ์ค˜์•ผ ํ•ด์„œ ์ด๋Ÿฐ์‹์œผ๋กœ ํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๊น”๋”ํ•ด์ง‘๋‹ˆ๋‹ค !

 

์ด๋Ÿฐ์‹์œผ๋กœ ๋ Œ๋”๋ง๊นŒ์ง€ ํ•ด์ฃผ๋ฉด ์ด๋ ‡๊ฒŒ ์ƒ‰์„ ์„ค์ • ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
์œ„์—์„œ ์ฒ˜๋Ÿผ ๋ฒ„ํŠผ ๊ฐ„๊ฒฉ๋„ ๋–ผ์คฌ์Šต๋‹ˆ๋‹ค


๐Ÿ‘€  outline ์˜ต์…˜ ๋งŒ๋“ค๊ธฐ

outline์„ props๋กœ ๋ฐ›์•„์™€์„œ ๋ Œ๋”๋ง ํ•ด์ฃผ๋ฉด outline์ด ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ‘€  ์ „์ฒด ๋„ˆ๋น„ ์ฐจ์ง€ํ•˜๋Š” ์˜ต์…˜

๊ทผ๋ฐ ์ด๊ฒŒ ์˜ˆ์ œ ๋”ฐ๋ผํ•˜๋‹ค๊ฐ€ ๋ฐœ๊ฒฌํ•œ๊ฑด๋ฐ defaultProps๋กœ color: blue๋ฅผ ํ•ด๋†จ๋‹จ ๋ง์ด์ฃ 

๊ทผ๋ฐ default๊ฐ€ ํŒŒ๋ž€์ƒ‰์ด ์•„๋‹ˆ๋ผ ์ €๋ ‡๊ฒŒ ์—ฐํ•œ ํšŒ์ƒ‰์œผ๋กœ ๋œจ๋”๋ผ๊ณ ์š”

์Œ.. ์›์ธ์„ ์ฐพ์•„๋ณด๋‹ˆ๊นŒ

โ“defaultProps x ํ•จ์ˆ˜์—์„œ ๋ฐ”๋กœ ์ •์˜

์ด๊ฑฐ ์ „์— ํ–ˆ๋˜ ์Šคํ„ฐ๋””์—์„œ๋„ ํ–ˆ๋˜๊ฑด๋ฐ ์—ฌ๊ธฐ์„œ๋„ ์ด๊ฑฐ ๋•Œ๋ฌธ!!

 

์ด๊ฑฐ ๋Œ€์‹ ์— -> ํ•จ์ˆ˜์—์„œ ๋ฐ”๋กœ ์„ ์–ธ์„ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
์ด๋ ‡๊ฒŒ ํ–ˆ๋”๋‹ˆ ํŒŒ๋ž€์ƒ‰์ด ์ž˜ ๋– ์š”


๐Ÿ‘€  ...rest props ์ „๋‹ฌํ•˜๊ธฐ

์ด์ œ ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ์— onClick์„ ์„ค์ •ํ•˜๋ ค๋ฉด??

 

spread์™€ rest์‚ฌ์šฉํ•˜๊ธฐ

์™ผ์ชฝ์ฒ˜๋Ÿผ ํ•˜๋‚˜ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ด์ฃผ๋Š” ๊ฒƒ๋ณด๋‹ค ์˜ค๋ฅธ์ชฝ์ฒ˜๋Ÿผ ...rest๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง‘๋‹ˆ๋‹ค !

  • props์— ์ง€์ •ํ•˜์ง€ ์•Š์€ ๊ฐ’๋“ค์„ rest๋ผ๋Š” ๊ฐ์ฒด์— ๋ชจ์•„์คŒ
  • buttonํƒœ๊ทธ์— {...rest}๋ฅผ ํ•ด์ฃผ๋ฉด rest ๊ฐ์ฒด์•ˆ์— ์žˆ๋Š” ๊ฐ’๋“ค์„ ๋ชจ๋‘ buttonํƒœ๊ทธ์— ์„ค์ •ํ•ด์คŒ

์ด๋ ‡๊ฒŒ onClick์„ ์„ค์ •ํ•˜๋ฉด ๋ˆŒ๋ €์„๋•Œ ์ฝ˜์†”์ด ๋œจ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค !!


๐Ÿ”  CSS Module

  • CSS ํด๋ž˜์Šค๊ฐ€ ์ค‘์ฒฉ๋˜๋Š” ๊ฒƒ์„ ์™„๋ฒฝํžˆ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ์ˆ 
  • CRA๋กœ ๋งŒ๋“  ํ”„๋กœ์ ํŠธ์—์„œ CSS Module๋ฅผ ์‚ฌ์šฉ ํ•  ๋•Œ์—๋Š” CSS ํŒŒ์ผ์˜ ํ™•์žฅ์ž๋ฅผ .module.css๋กœ ์„ค์ •
  • ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ์—์„œ ํ•ด๋‹น CSS ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ CSS ํŒŒ์ผ์— ์„ ์–ธํ•œ ํด๋ž˜์Šค ์ด๋ฆ„๋“ค์ด ๋ชจ๋‘ ๊ณ ์œ ํ•ด์ง
  • className ์„ ์„ค์ • ํ•  ๋•Œ์—๋Š” styles.Box ์ด๋ ‡๊ฒŒ import๋กœ ๋ถˆ๋Ÿฌ์˜จ styles ๊ฐ์ฒด ์•ˆ์— ์žˆ๋Š” ๊ฐ’์„ ์ฐธ์กฐํ•ด์•ผ ํ•จ
.Box {
  background: black;
  color: white;
  padding: 2rem;
}

//js
import React from "react";
import styles from "./Box.module.css";

function Box() {
  return <div className={styles.Box}>{styles.Box}</div>;
}

export default Box;

 

์ผ๋ฐ˜ CSS์™€ ์ฐจ์ด์ 

 

์ผ๋ฐ˜ CSS

/* styles.css */
.button {
  background-color: blue;
  color: white;
}


// App.jsx
import './styles.css';

function App() {
  return <button className="button">Click me</button>;
}

 

- ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ๋„ ๊ฐ™์€ ์ด๋ฆ„์˜ ํด๋ž˜์Šค๊ฐ€ ์žˆ์œผ๋ฉด ์Šคํƒ€์ผ ์ถฉ๋Œ์ด ๋ฐœ์ƒ

 

CSS Module

/* Button.module.css */
.button {
  background-color: blue;
  color: white;
}

// App.jsx
import styles from './Button.module.css';

function App() {
  return <button className={styles.button}>Click me</button>;
}

 

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ณ ์œ ์˜ ํ•ด์‹œ๊ฐ’์„ ํฌํ•จํ•œ ์ด๋ฆ„์œผ๋กœ ๋ฐ”๋€๋‹ˆ๋‹ค !! => ์ค‘๋ณต ์•ˆ์ผ์–ด๋‚จ

 

์ด์ œ ์˜ˆ์ œ๋กœ ๊ณต๋ถ€๋ฅผ ํ•ด๋ณผ๊ฑด๋ฐ ~

 

์ด๋ ‡๊ฒŒ ์ฒดํฌ๋ฐ•์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๋ Œ๋”๋ง ํ•ด์ฃผ๋ฉด

์ด๋ ‡๊ฒŒ ๋˜๋Š”๋ฐ ์ฒดํฌ๋ฐ•์Šค๋‚˜ "์ฒดํฌ๋จ/์•ˆ๋จ" ํ…์ŠคํŠธ๋ฅผ ๋ˆ„๋ฅด๋ฉด check์ƒํƒœ๊ฐ€ ๋ณ€ํ•จ => ํ•ด๋‹น ๊ณต๊ฐ„์„ labelํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์„œ

์–ด์จŒ๋“  ์ด ์˜ˆ์ œ๋กœ ๊ณต๋ถ€๋ฅผ ํ•ด๋ณด์ž!!!

 

Checkbox ์ปดํฌ๋„ŒํŠธ Md๋จธ์‹œ๊ธฐ ์จ์„œ ๋งŒ๋“ค๊ณ  ๋ Œ๋”๋ง ํ•ด์ฃผ๊ณ 
์ด๋Ÿฐ์‹์œผ๋กœ ๊ณ ์œ ํ•œ ํด๋ž˜์Šค ์ด๋ฆ„์ด ๋งŒ๋“ค์–ด์ง !

styles.icon ์ด๋ ‡๊ฒŒ ๊ฐ์ฒด์•ˆ์— ์žˆ๋Š” ๊ฐ’์„ ์กฐํšŒํ•ด์•ผํ•˜๋Š”๋ฐ ์ด๋ฆ„์— -๊ฐ€ ๋“ค์–ด๊ฐ€ ์žˆ๋‹ค๋ฉด? :

  • styles['my-class'] ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉ!
  • ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ์žˆ๋‹ค๋ฉด? ${styles.one} ${styles.two}
  • ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง : ${styles.one} ${condition ? styles.two : ''}

์ด๋Ÿฐ์‹์œผ๋กœ classNames์— bind๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด cx('ํด๋ž˜์Šค์ด๋ฆ„')๊ฐ™์€ ํ˜•์‹์œผ๋กœ ํŽธํ•˜๊ฒŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ !

  • ์—ฌ๋Ÿฌ๊ฐœ์˜ CSS ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ• ๋•Œ
  • ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง์„ ํ•ด์•ผ ํ• ๋•Œ 
cx('one', 'two')
cx('my-component', {
  condition: true
})
cx('my-component', ['another', 'classnames'])

 

๐Ÿ’ ๊ธฐํƒ€ ์ถ”๊ฐ€ ๋‚ด์šฉ

  • CSS Module์€ Sass์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ํ™•์žฅ์ž๋ฅผ .module.scss๋กœ
  • CSS Module์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํŒŒ์ผ์—์„œ ํด๋ž˜์Šค ์ด๋ฆ„ ๊ณ ์œ ํ™” x ์ „์—ญ์  ํด๋ž˜์Šค ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„๋•Œ
:global .my-global-name {

}

//Sass

:global {
  .my-global-name {

  }
}

 

  • CSS Module ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ณณ์—์„œ ํŠน์ • ํด๋ž˜์Šค์—์„œ๋งŒ ๊ณ ์œ  ์ด๋ฆ„์„ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„๋•Œ
:local .make-this-local {

}

//Sass

:local {
  .make-this-local {

  }
}

 


๐Ÿ”  styled- components : CSS in JS

Tagged Template Literal

  • Template Literal 
    • `์œผ๋กœ ๊ฐ์‹ธ์•ผ ํ•จ 
    • ${} ์•ˆ์— ๋ณ€์ˆ˜, ์—ฐ์‚ฐ์‹, ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋“ฑ ๋‹ค์–‘ํ•œ ํ‘œํ˜„์„ ๋„ฃ์„ ์ˆ˜ ์žˆ์Œ
const name = "์ƒ๋ž˜";
const age = 22;

// ๊ธฐ์กด ๋ฐฉ์‹
console.log("์•ˆ๋…•ํ•˜์„ธ์š”, ์ œ ์ด๋ฆ„์€ " + name + "์ด๊ณ , ๋‚˜์ด๋Š” " + age + "์‚ด์ž…๋‹ˆ๋‹ค.");

// Template Literal
console.log(`์•ˆ๋…•ํ•˜์„ธ์š”, ์ œ ์ด๋ฆ„์€ ${name}์ด๊ณ , ๋‚˜์ด๋Š” ${age}์‚ด์ž…๋‹ˆ๋‹ค.`);

 

 

  • Tagged Template Literal
    • Template Literal ์•ž์— ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๋ถ™์ž„
    • ๊ทธ ํ•จ์ˆ˜๊ฐ€ ๋ฌธ์ž์—ด๊ณผ ํ‘œํ˜„์‹์„ ๋ถ„๋ฆฌํ•ด์„œ ์ง์ ‘ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
    • tagFunction`๋ฌธ์ž์—ด ${ํ‘œํ˜„์‹1} ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ž์—ด ${ํ‘œํ˜„์‹2}`
function emphasize(strings, ...values) {
	// strings: ๋ฌธ์ž์—ด ๋ฐฐ์—ด
 	// values: ${}๋กœ ๋“ค์–ด์˜จ ๊ฐ’๋“ค
  return strings.reduce((result, str, i) => {
    return result + str + (values[i] ? `**${values[i]}**` : "");
  }, "");
}

const name = "์ƒ๋ž˜";
const age = 22;

const result = emphasize`์•ˆ๋…•ํ•˜์„ธ์š”, ${name}! ๋‹น์‹ ์€ ${age}์‚ด์ž…๋‹ˆ๋‹ค.`;
console.log(result);
// ์ถœ๋ ฅ: ์•ˆ๋…•ํ•˜์„ธ์š”, **์ƒ๋ž˜**! ๋‹น์‹ ์€ **22**์‚ด์ž…๋‹ˆ๋‹ค.

 

++ ์ด๋Ÿฐ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•จ

const StyledDiv = styled`
  background: ${props => props.color};
`;

 

์ด์ œ ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด์„œ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค 

์™ผ์ชฝ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ ํ•ด์คฌ์–ด์š”

 

color๋ฅผ props๋กœ ์ฃผ๋ฉด ์ƒ‰์„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค~
์ด๋ ‡๊ฒŒ huge๋ผ๋Š”๊ฑฐ์— ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•ด์„œ ์“ฐ๋ฉด ํฌ๊ธฐ๋„ ์ปค์ง€๋„ค์š”

์Œ ์†”์งํžˆ ์ฒ˜์Œ ๋ณด๋Š”๊ฑฐ๋ผ ์ข€ ์–ด๋ ค์›Œ์š”;;

๊ทผ๋ฐ ์ด๋ ‡๊ฒŒ ์—ฌ๋Ÿฌ ์ค„์˜ CSS ์ฝ”๋“œ๋ฅผ ์กฐ๊ฑด๋ถ€๋กœ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด css๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š”๋ฐ...

๊ทธ๋ž˜์•ผ ๊ทธ ์Šคํƒ€์ผ ๋‚ด๋ถ€์—์„œ๋„ ๋‹ค๋ฅธ props๋ฅผ ์กฐํšŒ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š”๋ฐ... ํ—ˆํ—ˆ ์–ด๋ ต๋‹ค


๐Ÿ‘€  Button ๋งŒ๋“ค๊ธฐ

์—ฌ๊ธฐ ๋ถ€ํ„ด styled-components ๋‹จ์ข…์ด์Šˆ๋กœ Emotion์œผ๋กœ ํ• ๊ฒŒ์š” ๋ฌธ๋ฒ•์€ ๊ฐ™์œผ๋‹ˆ๊นŒ..

@emotion/react @emotion/styled๋ฅผ ์„ค์น˜/import ํ•ด์ฃผ๊ณ  ๋ Œ๋”๋ง ํ•ด์คฌ์Šต๋‹ˆ๋‹ค. - ๋ฒ„ํŠผ 2๊ฐœ ๋งŒ๋“ค์–ด๋ดค์–ด์š”
๋ฌธ๋ฒ•์ด ๊ฐ™์•„์„œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค!!

๐Ÿ‘€  polished์˜ ์Šคํƒ€์ผ ๊ด€๋ จ ์œ ํ‹ธ ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ

Sass๋ฅผ ์‚ฌ์šฉ ํ•  ๋•Œ lighten() ์ด๋‚˜ darken() ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ CSS in JS์—์„œ๋„ polished๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋จ

์ด๋ ‡๊ฒŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด

:hover๋ฅผ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งˆ์šฐ์Šค ์ปค์„œ๋ฅผ ๊ฐ€์ ธ๊ฐ€๋ฉด ํ™”๋ฉด์ด ํ๋ ค์ง€๊ณ  ํด๋ฆญํ•˜๋ฉด ์–ด๋‘์›Œ์ง€๊ฒŒ ๋จ

 

ThemeProvider : emotion/styled-components ๋กœ ๋งŒ๋“œ๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ์กฐํšŒ/์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ค์ •

 

์ด๋ ‡๊ฒŒ theme๊ฐ์ฒด ์•ˆ์— palette๊ฐ์ฒด๋กœ ์„ ์–ธ์„ ํ•ด๋†“๊ณ  ๊ฑฐ๊ธฐ์„œ ์„ ํƒํ•ด์ฃผ๋ฉด
์ด๋ ‡๊ฒŒ ์ž˜ ๋œ๋‹ค !

 

  • color๋ฅผ ์ง€์ •ํ•˜์ง€๋ง๊ณ  ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๋„๋ก
  • defaultprops๊ฐ€ ์ž˜ ์•ˆ๋˜์„œ ์˜ˆ์ œ๋ž‘ ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ??์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉ => ๊ธฐ๋ณธ๊ฐ’ ์ง€์ •๋จ
  • +๊ทผ๋ฐ ์—ฌ๊ธฐ์„œ ๊ทธ & + & ๊ฐ€ ์•ˆ๋จน๋Š”๋ฐ ์™œ์ธ์ง€๋Š” ๋ชจ๋ฅด๊ฒ ๋„ค์š” :not๊ฑฐ๋‚˜ ์ธ๋ผ์ธ ์Šคํƒ€์ผ๋กœ ํ•ด๊ฒฐ์€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค
const colorStyles = css`
  ${({ theme, color }) => {
    const selected = theme.palette[color];
    return css`
      background: ${selected};
      &:hover {
        background: ${lighten(0.1, selected)};
      }
      &:active {
        background: ${darken(0.1, selected)};
      }
    `;
  }}
`;

์›๋ž˜๋Š” ์ด๋ ‡๊ฒŒ ์ƒ‰์ƒ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•ด์„œ ์‚ฌ์šฉ ํ•  ์ˆ˜

 

์ด๋ ‡๊ฒŒ ํ•ด๋ดค๋Š”๋ฐ์š”

const colorStyles = css`
  ${({ theme, color }) => {
    const selected = theme.palette[color];
    return css`
      background: ${selected};
      &:hover {
        background: ${lighten(0.1, selected)};
      }
      &:active {
        background: ${darken(0.1, selected)};
      }
    `;
  }}
`;

์›๋ž˜ ์˜ˆ์ œ๋Š” ์ด๊ฑฐ์˜€๋Š”๋ฐ ์ด๊ฒŒ ๊ณ„์† ์—๋Ÿฌ๊ฐ€ ๋‚˜์„œ

const colorStyles = ({ theme, color }) => {
  const selected = theme?.palette?.[color] ?? "#228be6";
  return css`
    background: ${selected};
    &:hover {
      background: ${lighten(0.1, selected)};
    }
    &:active {
      background: ${darken(0.1, selected)};
    }
  `;
};

์ด๋ ‡๊ฒŒ ํ–ˆ์–ด์š” gpt๋ง๋กœ๋Š”

css\`` ์•ˆ์— ํ•จ์ˆ˜๋ฅผ ๋„ฃ๊ณ , ๋˜ ๊ทธ ํ•จ์ˆ˜ ์•ˆ์—์„œ props`๋ฅผ ์“ฐ๊ณ  ์žˆ์–ด์„œ ๋ฌธ๋ฒ•์ด ๊ผฌ์—ฌ ์žˆ์—ˆ๋˜ ๊ฑฐ์˜ˆ์š”.

`css`` ์•ˆ์—์„œ๋Š” ๋ฐ”๋กœ ์Šคํƒ€์ผ ๋ฌธ์ž์—ด์„ ์จ์•ผ์ง€, JS ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๋„ฃ์œผ๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

๋ผ๋„ค์š” ํ•œ ์ˆ˜ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค;

 

์ž˜ ๋˜๋„ค์š”

โ“์—„ ๊ทผ๋ฐ size๊ฐ€ ์ž‘๋™์„ ์•ˆํ•ด์š”;;;;;

๊ทธ๋ž˜์„œ ์–˜๋„ ํ•จ์ˆ˜๋กœ ๋ฐ”๊ฟ”์คฌ๋Š”๋ฐ => ์ด๋ฒˆ์—” ๊ฐ„๊ฒฉ์ด ์ž‘๋™ ์•ˆํ•จ

๋Œ€ํ™˜์žฅ ํŒŒํ‹ฐ ใ…‹ใ…‹ ๊ทธ๋ž˜๋„ ํ•œ๊ฑฐ์— ์˜๋ฏธ๋ฅผ ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค + ๋’ค์— outline์ด๋ž‘ fullWidth๋Š” ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๊ฐ™์œผ๋‹ˆ ๋„˜์–ด๊ฐˆ๊ฒŒ์š” ใ…Ž


๐Ÿ‘€  Dialog ๋งŒ๋“ค๊ธฐ

Dialog ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ณ  ๋žœ๋”๋ง
์กฐ๊ธˆ ๋‹ค๋ฅด์ง€๋งŒ ์„ฑ๊ณต~
onConfirm,onCancel,visible์„ prpos๋กœ ์ฃผ๊ณ  useState๋กœ onClick์ฒ˜๋ฆฌ ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ ์‚ญ์ œ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด dialog๊ฐ€ ๋œจ๊ฒŒ ๋œ๋‹ค !

๐Ÿ‘€  ํŠธ๋žœ์ง€์…˜ ๊ตฌํ˜„ํ•˜๊ธฐ

transform์„ ์ฃผ๊ณ ์š”

 

ํ•˜๋ฉด dialog๊ฐ€ ๋œฐ๋•Œ/๋‚ด๋ ค๊ฐˆ๋•Œ ๋‹ค ํŠธ๋ Œ์ง€์…˜์ด ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค..

 

์ด๋ ‡๊ฒŒ ๋์ธ๋ฐ์š” ๋ญ”๊ฐ€ ์ƒˆ๋กœ์šด๊ฑด๋ฐ ๋‚ด์šฉ์ด ์ข€ ๋งŽ์•„์„œ ๋‹ค์‹œ ์ฒœ์ฒœํžˆ ๋ด๋ณผ๊ฒŒ์š”

๋ฐ˜์‘ํ˜•