📖styled-components와 tailwindcss를 통합하여 사용할 수 있도록 지원하는 라이브러리
import styled from 'styled-components';
// styled-components 정의
const TestDiv = styled.div`
color: white;
width: 100%;
height: 50%;
...
`;
// 사용
const TestComponent = () => {
...
return (
...
// tailwindcss 적용
<TestDiv className='bg-blue-950'>테스트</TestDiv>
);
};
import tw from 'twin.macro';
import styled from 'styled-components';
// 통합하여 styled-components 정의
const TestDiv = styled.div`
${tw`
text-white
bg-blue-950
w-full
`}
...css 작성
`;
// 사용
const TestComponent = () => {
...
return (
...
<TestDiv>테스트</TestDiv>
);
};
twin.macro
의 이점은 styled-components
와 tailwindcss
를 통합하여 가독성이 좋고, 유연성이 뛰어난 컴포넌트를 생성할 수 있으며 조건부 스타일링 적용을 통한 다양한 시도를 할 수 있다는 점이다. 또한, 개발자의 피로도를 줄여주고 스타일링에 소모되는 에너지를 줄이는데 도움을 준다.
npm install -D styled-components @types/styled-components tailwindcss
// tailwind.config.js 생성
npx tailwindcss init
npm install -D babel-plugin-macros twin.macro
// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
};
// babel-plugin-macros.config.js
module.exports = {
twin: {
preset: "styled-components",
},
};
...다른설정
"babelMacros": {
"twin": {
"preset": "styled-components"
}
},
...
// index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
index.css
파일을 제외한 3개의 파일은 root 디렉토리(src 상위)에 위치시키면 된다.
import tw from 'twin.macro';
import styled from 'styeld-components';
// 일반적 사용
const TestDiv = styled.div`
${tw`
bg-blue-200
`}
`;
import tw from 'twin.macro';
import styled from 'styeld-components';
// 조건부 스타일링
// 1. 백틱
const TestDiv = styled.div`
${({hasColor}) => hasColor ? tw`bg-red-300` : tw`bg-blue-300`}
${tw`
....다른 클래스
}
`;
// 2. 배열
const TestDiv = styled.div(({hasColor}) => [
hasColor ? tw`bg-red-300` : tw`bg-blue-300`,
tw`
text-white
`
]);
// typescript 사용
// 1. 백틱
interface DivProps {
test?: boolean // ?를 사용하지 않을 경우 'test'라는 props을 무조건 전달해야함.
};
const TestDiv = styled.div<DivProps>`
${({ test }) => (test ? tw`bg-blue-200` : tw`bg-red-300`)}
`;
// 2. 배열
const TestDiv = styled.div<DivProps>(({ test = false }) => [
test ? tw`bg-blue-200` : tw`bg-red-300`,
]);
import tw from 'twin.macro';
import styled from 'styeld-components';
const TestDiv = styled.div<DivProps>`
${({ test }) => (test ? tw`bg-blue-200` : tw`bg-red-300`)}
`;
const TestBox = styled(TestDiv)`
${tw`text-orange-500`}
`;
Argument of type '({ test }: { test: boolean; }) => TwStyle[]' is not assignable to parameter of type 'Styles<FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>'. Type '({ test }: { test: boolean; }) => TwStyle[]' is not assignable to type 'StyleFunction<FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>'. Types of parameters '__0' and 'executionContext' are incompatible. Property 'test' is missing in type 'ExecutionContext & FastOmit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>' but required in type '{ test: boolean; }'.
위와 같이 에러가 발생하는 경우는 다음과 같이 코드를 작성했을 가능성이 높다.
const TestDiv = styled.div(({test}: {test: boolean}) => [
...style code
]);
//or
const TestDiv = styled.div(({test}: {test: boolean})`
...style code
`);
위 코드에서 에러가 발생하는 원인은 다음과 같다.
styled-components
의 스타일 함수가 받아들일 수 있는 인자의 타입과 일치하지 않다.styled-components
에서 스타일 함수로 전달되는 실행 컨텍스트와 사용자가 정의한 객체 타입 간의 호환성이 없다. styled-components
는 props를 포함한 executionContext
객체를 전달해야하는데 위에서 전달한 props는 executionContext
에 존재하지 않는다.// props 타입 선언
interface DivProps {
test?: boolean // ?를 사용하지 않을 경우 'test'라는 props을 무조건 전달해야함.
};
// 백틱
const TestDiv = styled.div<DivProps>`
${({ test }) => (test ? tw`bg-blue-200` : tw`bg-red-300`)}
`;
// 배열
const TestDiv = styled.div<DivProps>(({ test = false }) => [
test ? tw`bg-blue-200` : tw`bg-red-300`,
]);