본문으로 건너뛰기

객체 스타일을 템플릿 리터럴로 변환 — Numio

css({...})와 styled.x({...}) 객체 스타일을 styled-components, Emotion, Linaria용 태그드 템플릿 리터럴로 다시 씁니다. camelCase 키는 kebab-case가 되고, 숫자에는 단위 없는 속성을 제외하고 px가 붙으며, JS 표현식은 ${} 보간이 됩니다.

Emotion이나 Glamor의 객체 스타일을 템플릿 리터럴 CSS를 쓰는 styled-components나 Linaria로 마이그레이션할 때.

Object Styles

Template Literal

이럴 때 사용하세요

  • Emotion이나 Glamor의 객체 스타일을 템플릿 리터럴 CSS를 쓰는 styled-components나 Linaria로 마이그레이션할 때.
  • styled(Component)({...}) 정의를 템플릿 구문으로 바꿔 일반 CSS처럼 읽고 편집할 때.

사용 방법

  1. css({...}), styled.tag({...}), styled(Component)({...})를 호출하는 JavaScript나 TypeScript(JSX/TSX 가능)를 Object Styles 편집기에 붙여 넣습니다.
  2. 설정에서 "Transpile css tags"와 "Transpile styled tags"를 켠 채로 두거나, 하나를 꺼서 해당 호출을 그대로 둡니다. 하나가 꺼져 있으면 경고 배너가 표시됩니다.
  3. Template Literal 패널을 복사합니다. 변환된 호출 밖의 코드는 유지되지만 Prettier로 다시 포맷됩니다.

객체 스타일(JavaScript 또는 TypeScript)

const Button = styled.button({
  padding: 8,
  fontSize: '14px',
  backgroundColor: theme.primary,
  '&:hover': {
    opacity: 0.8,
  },
})

const card = css({
  display: 'flex',
  marginTop: 16,
})

태그드 템플릿 리터럴

const Button = styled.button`
  padding: 8px;
  font-size: 14px;
  background-color: ${theme.primary};

  &:hover {
    opacity: 0.8;
  }
`
const card = css`
  display: flex;
  margin-top: 16px;
`

세부 정보 및 제한 사항

변환은 브라우저에서 실행됩니다. Web Worker가 Babel standalone으로 babel-plugin-object-styles-to-template을 적용하고(일반 JavaScript 파싱이 실패하면 TypeScript 구문으로 파싱), 결과는 세미콜론 없이 Prettier로 포맷됩니다.

인자가 하나의 일반 객체인 호출만 변환됩니다. 함수나 여러 인자를 받는 styled("div")(obj, props => ...)와 css([...]) 배열은 그대로 남습니다.

zIndex, lineHeight, opacity 같은 단위 없는 속성은 숫자 그대로 두고, 다른 숫자에는 px가 붙습니다. 배열 값은 펼쳐지지 않고 ${[0, 4]} 같은 보간이 됩니다.

Prettier는 손대지 않은 코드도 정규화합니다. 예를 들어 작은따옴표가 큰따옴표로 바뀝니다.

FAQ

어떤 호출 이름을 인식하나요?

플러그인은 css(...)와 styled 호출, 즉 styled.button(...), styled("div")(...), styled(Link)(...)를 변환합니다. someFn({ color: 'red' })처럼 객체 인자를 받는 다른 함수는 바뀌지 않습니다.

변수와 테마 값은 어떻게 처리되나요?

theme.primary나 colors.white처럼 리터럴이 아닌 값은 템플릿의 ${...} 안에 JavaScript 표현식으로 유지되므로 런타임에 그대로 평가됩니다.

&:hover 같은 중첩 선택자를 지원하나요?

네. '&:hover' 같은 키 아래의 중첩 객체는 템플릿 안의 중첩 블록이 되며, 부모 선언과는 빈 줄로 구분됩니다.

TypeScript에서도 동작하나요?

네. 코드가 JavaScript로 파싱되지 않으면 Babel의 TypeScript 구문으로 다시 파싱합니다. 타입은 유지되어 interface는 그대로 남고, styled.button<Props>({...})는 styled.button<Props>`...`가 됩니다.

사양 및 참고 자료