안녕하세요! 오늘은 emotion CSS에 대해 다루어보려 합니다.
최근 개발 과제를 진행하면서 코드의 깔끔함을 느끼지 못했다는 피드백을 받은 저는 styled-components 대신 emotion을 공부해보기로 결정했습니다.
 
먼저, emotion을 사용하기 위해서는 npm i @emotion/react 명령어로 설치해야 합니다. styled-components와 마찬가지로 JSX에서 CSS를 작성할 수 있습니다.
 
예를 들어, input 커스터마이징을 하고자 한다면, 기존의 styled-components를 사용하는 방법은 아래와 같을 것입니다.
 
JavaScript
function App() {
  return (
    <div>
      <h2>Styled-components</h2>
      <div>
        <span>ID</span>
        <input style={{color: 'black'}} />
      </div>
      <div>
        <span>PASSWORD</span>
        <input style={{color: 'red'}} />
      </div>
      <div>
        <span>NAME</span>
        <input style={{color: 'blue'}} />
      </div>
      <div>
        <span>phone</span>
        <input style={{color: 'green'}} />
      </div>
    </div>
  );
}
 
하지만 이렇게 작성하다보면, 코드가 길어지고 유지보수가 어렵다는 문제점이 있습니다. 그래서 emotion을 사용하여 공용 Input 컴포넌트를 만들면 코드를 간결하게 작성할 수 있습니다.
 
JavaScript
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";

const backColors = {
  default: 'black',
  warning: 'red',
  success: 'blue',
  info: 'green'
}

function Input({ color = "default", onChange }) {
  return (
    <input onChange={onChange}
      css={{
        outline: 'none',
        color: backColors[color]
      }}
    />
  );
}

export default Input;
 
이렇게 작성하면, Input을 불러 사용할 때 color값을 통해 색상이 들어간 input을 호출할 수 있습니다. 또한, 크기와 폰트 사이즈도 수정 가능합니다.
 
JavaScript
const inputSize = {
  small: {
    fontSize: "1rem",
    padding: "4px 8px"
  },
  middle: {
    fontSize: "1.167rem",
    padding: "6px 10px"
  },
  large: {
    fontSize: "1.333rem",
    padding: "8px 12px"
  },
};

function Input({ size = "middle", color = "default", onChange }) {
  return (
    <input onChange={onChange}
      css={{
        outline: 'none',
        ...inputSize[size],
        color: backColors[color]
      }}
    />
  );
}
 
위의 코드에서 inputSizebackColors라는 객체를 생성하여 입력칸의 크기와 색상을 지정했습니다. 이를 통해 Input 컴포넌트에서는 sizecolor를 입력받아 각각의 값에 맞게 스타일을 적용할 수 있습니다.
 
또한, flex: '1 1 auto'를 적용하여 Input 컴포넌트가 자동으로 컨테이너의 크기에 맞게 늘어나도록 설정했습니다.
 
이렇게 만든 Input 컴포넌트를 App 컴포넌트에서 호출하여 사용할 수 있습니다. 이 때, divCss라는 변수를 통해 App 컴포넌트의 스타일을 설정하였습니다.
 
JavaScript
/** @jsxImportSource @emotion/react */
import { divCss } from "./export";
import Input from "./Input/Input";

function App() {

  return (
    <div css={divCss}>
      <h2>데굴데굴 굴러가유.. emotion!!</h2>
      <div>
        <span>DEFAULT</span>
        <Input />
      </div>
      <div>
        <span>SMALL</span>
        <Input size="small" />
      </div>
      <div>
        <span>MIDDLE</span>
        <Input size="middle" />
      </div>
      <div>
        <span>LARGE</span>
        <Input size="large" />
      </div>
      <div>
        <span>SUCCESS</span>
        <Input color="success" />
      </div>
      <div>
        <span>WARNING</span>
        <Input color="warning" />
      </div>
      <div>
        <span>INFO</span>
        <Input color="info" />
      </div>
    </div>
  );
}

export default App;
 
위와 같이 코드를 작성하면, App 컴포넌트 내에서 Input 컴포넌트를 사용하여 입력칸을 만들 수 있습니다. 이렇게 만든 Input 컴포넌트는 크기와 색상을 다양하게 조합하여 재사용이 가능하며, 코드도 간결해지는 장점이 있습니다.
 
notion image
 
어떤가요? 깔끔하게 사용할 수 있을것만 같죠?
 
이상으로 emotion css를 사용하여 Input 컴포넌트를 만드는 예제를 살펴보았습니다. 감사합니다!