Skip to content

Type‐Safety한 Tailwind Props 타입 관리

진예원 edited this page Nov 12, 2024 · 1 revision

공용 컴포넌트나 레이아웃 컴포넌트의 스타일을 커스텀하고 싶을 때 cn 함수를 이용했다.

import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

clsx : 조건부 클래스 네임을 쉽게 조합할 수 있게 도와준다.

tailwind-merge : TailwindCSS 클래스 테임을 병합하고 중복되거나 불필요한 클래스를 제거하여 최적화된 결과를 제공한다.

아래와 같이 cn 함수를 사용할 수 있다.

import { cn } from "@/lib/utils";

interface HorizontalDividerProps {
  className?: string;
}

export default function HorizontalDivider({
  className,
}: HorizontalDividerProps) {
  return <div className={cn("bg-divider h-0.5 rounded-sm", className)}></div>;
}

하지만 cn 함수와 props로 전달받은 className 로 스타일을 사용하면 공용 컴포넌트를 만들 이유가 없다.

어떤 값이 컴포넌트에서 중요한 역할?을 한다면 그 값을 props로 전달하는 것이 의미적으로 좋다.

ex) <ScrollWrapper /> 컴포넌트는 너비와 높이를 전달 받은 width ,height 값으로 제한하고, 스크롤을 할 수 있게 해주는 레이아웃 컴포넌트이다.

import { cn } from "@/lib/utils";

type ScrollWrapperProps = {
  width?: string;
  height?: string;
  children: React.ReactNode;
};

export default function ScrollWrapper({
  width,
  height,
  children,
}: ScrollWrapperProps) {
  return <div className={cn("overflow-auto", width, height)}>{children}</div>;
}

props로 전달 받은 width, height는 cn 함수로 className에 추가되어 스타일링이 된다.

하지만 위와 같이 width와 height의 타입을 string으로 설정하면, 이 컴포넌트를 사용하는 입장에서 어떤 값을 전달해야 할지 잘 모를 수 있다.

ex) “w-10”?, "10"? 10px?

그래서 tailwindest라는 라이브러리를 이용하여 tailwind의 타입을 제공 받기로 했다.

import { type Tailwindest } from "tailwindest";
import { cn } from "@/lib/utils";

type ScrollWrapperProps = {
  width?: Tailwindest["width"];
  height?: Tailwindest["height"];
  children: React.ReactNode;
};

export default function ScrollWrapper({
  width,
  height,
  children,
}: ScrollWrapperProps) {
  return <div className={cn("overflow-auto", width, height)}>{children}</div>;
}

이렇게 Tailwindest의 타입을 사용하면 아래와 같이 이 컴포넌트를 안전하게 사용할 수 있다.

스크린샷

개발 문서

⚓️ 사용자 피드백과 버그 기록
👷🏻 기술적 도전
📖 위키와 학습정리
🚧 트러블슈팅

팀 문화

🧸 팀원 소개
⛺️ 그라운드 룰
🍞 커밋 컨벤션
🧈 이슈, PR 컨벤션
🥞 브랜치 전략

그룹 기록

📢 발표 자료
🌤️ 데일리 스크럼
📑 회의록
🏖️ 그룹 회고
🚸 멘토링 일지
Clone this wiki locally