TailwindCSS + React 모범 사례: 깔끔한 방법

저는 오랫동안 Tailwind를 사용해 왔으며 코드가 완전히 엉망인 것을 보는 데 너무 많은 고통과 불편한 느낌을 받았습니다. 그동안 Tailwind를 작성하기 위한 전략을 세웠고 더 복잡한 구성 요소를 구축하기 위한 좋은 패턴을 생각해 냈습니다.

이 패턴은 CSS 모듈, Talwind @apply 및 tailwind-merge를 사용합니다. 버튼을 만들고 싶다고 가정해 보겠습니다. 폴더 구조는 다음과 같습니다.

|
|-button
|--Button.tsx
|--Button.module.css
|--index.ts
|


그리고 다음과 같은 코드:

버튼 /button/Button.tsx




import s from './Button.module.css'
import React from 'react'
import cn from 'classnames'
import Spinner from 'components/spinner'

type ButtonProps = {
  children: React.ReactNode
  fullWidth?: boolean
  loading?: boolean
  variant?: 'filled' | 'outlined'
  color?: 'primary' | 'secondary'
  size?: 'base' | 'lg'
} & Omit<React.ComponentProps<'button'>, 'className'>

const Button = ({
  children,
  variant = 'filled',
  color = 'primary',
  size = 'base',
  fullWidth,
  loading,
  disabled,
  ...props
}: ButtonProps) => {
  const classes = cn(s.root, s[variant], s[color], s[size], {
    [s.fullWidth]: fullWidth,
  })

  return (
    <button className={classes} disabled={disabled || loading} {...props}>
      {children}
      {loading && (
        <span className="ml-1.5">
          <Spinner className={s.spinner} />
        </span>
      )}
    </button>
  )
}

export default Button


스타일 /button/Button.module.css




.root {
  @apply inline-flex items-center justify-center rounded-full font-semibold duration-150 disabled:pointer-events-none disabled:opacity-75;
}

.fullWidth {
  @apply w-full;
}

/*
 * SIZES
 */
.base {
  @apply px-8 py-3;
}

.lg {
  @apply px-12 py-5;
}

/*
 * VARIANTS & COLORS
 */
.filled.primary {
  @apply bg-[#FAA806] text-[#FFFFFF] hover:bg-[#EE9F04];
}

.filled.secondary {
  @apply bg-[#373E4B] text-[#97A3B7] hover:bg-[#343A47];
}

.outlined.primary {
  @apply border-[#FAA806] text-[#FAA806];
}

.outlined.secondary {
  @apply border-[#373E4B] text-[#373E4B];
}

/*
 * LOADING INDICATOR
 */
.primary .spinner {
  @apply fill-[#bc7e03] text-white;
}

.secondary .spinner {
  @apply fill-[#292e38] text-white;
}


사용법(NextJS 링크 사용)




<NextLink href="/signin" passHref>
  <Button fullWidth {...{ disabled, loading }}>
    Register
  </Button>
</NextLink>


소스 코드(Stackblitz)

좋은 웹페이지 즐겨찾기