개발 공부 기록

나는 무엇을 하는가?

프로젝트/chat-app

shadcn/ui 도입하기

진!!!!! 2024. 12. 6. 19:00

클라이언트에서 ui를 만들어볼건데, 이번 프로젝트는 프론트보다는 백 공부의 목적이 크고, ui 라이브러리도 한번 사용해보고 싶었어서 shadn/ui를 이용해 볼 예정이다.

shadn/ui란?

react에서 사용할 수 있는 ui 라이브러리이다.

npm으로 전체를 다운로드하는게 아니라 원하는 컴포넌트만 따로 다운받고, 직접 수정할 수 있기 때문에 디자인 변경이 쉽다.

shadcn/ui

 

shadcn/ui

Beautifully designed components that you can copy and paste into your apps. Accessible. Customizable. Open Source.

ui.shadcn.com

그리고 디자인이 무척 깔끔하고 예쁘다 ㅎㅎ

ui 컴포넌트 외에 그래프, 채팅 등도 가능하므로.. 좋아보인다

 

Vite에서 설치하기

리액트 프로젝트를 vite로 설치했으므로 shadcn/ui도 vite로 설치하는 방법을 따라가보자.

Vite

 

Vite

Install and configure Vite.

ui.shadcn.com

 

1. tailwind와 config 추가

종속성 설치

npm install -D tailwindcss postcss autoprefixer
 
npx tailwindcss init -p
  • npm install -D tailwindcss postcss autoprefixer
    • D 플래그는 "devDependencies"로 패키지들을 설치한다는 의미
    • 설치되는 패키지들:
      • tailwindcss: CSS 프레임워크
      • postcss: CSS 전처리기
      • autoprefixer: 브라우저 호환성을 위한 CSS 벤더 프리픽스 자동 추가 도구
  • npx tailwindcss init -p
    • tailwind.config.js와 postcss.config.js 두 개의 설정 파일을 생성
    • p 플래그는 postcss.config.js 파일도 함께 생성하라는 의미
    • tailwind.config.js: Tailwind CSS의 설정을 커스터마이즈할 수 있는 파일
    • postcss.config.js: PostCSS 플러그인 설정 파일

index.css 수정

//src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;

tailwind.config.js 수정

/** @type {import('tailwindcss').Config} */
export default {
  content: ["./index.html", "./src/**/*.{ts,tsx,js,jsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

2. Edit tsconfig.json file

//tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

3. Edit tsconfig.app.json file

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "./src/*"
      ]
    }
    // ...
  }
}

4. Update vite.config.ts

# (so you can import "path" without error)
npm i -D @types/node
import path from "path"
import react from "@vitejs/plugin-react"
import { defineConfig } from "vite"

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
})

5. CLI로 shadcn-ui init

npx shadcn@latest init

6. components.json 구성

Which style would you like to use? › New York
Which color would you like to use as base color? › Zinc
Do you want to use CSS variables for colors? › no / yes

 

style NewYork과 Default 중에 고를 수 있는데 별 차이 없고 NewYork이 헤더 글자 크기가 좀 더 작다.

base color 정하는건 Gray할건지 Zinc할건지 여러개가 있는데 그냥 쿨그레이 할건지 웜그레이할건지 차이다. Zinc가 기본 세팅인데 제일 이뻐보여서 Zinc로 설치했고, 다른 색깔은 뭐있는지 확인해보고 싶으면 아래 링크 확인!

shadcn/ui

 

shadcn/ui

Beautifully designed components that you can copy and paste into your apps. Accessible. Customizable. Open Source.

ui.shadcn.com

 

CSS variables이 뭔가 했는데 직접 테마 정하는 기능인 것 같다. 일단 yes 누름

Theming

 

Theming

Using CSS Variables or Tailwind CSS for theming.

ui.shadcn.com

 

7. 버튼 ui 설치해보기

npx shadcn@latest add button

src/components/ui에 버튼 컴포넌트가 생겼다.

import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"

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

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
  {
    variants: {
      variant: {
        default:
          "bg-primary text-primary-foreground shadow hover:bg-primary/90",
        destructive:
          "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
        outline:
          "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
        secondary:
          "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-9 px-4 py-2",
        sm: "h-8 rounded-md px-3 text-xs",
        lg: "h-10 rounded-md px-8",
        icon: "h-9 w-9",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  asChild?: boolean
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, asChild = false, ...props }, ref) => {
    const Comp = asChild ? Slot : "button"
    return (
      <Comp
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    )
  }
)
Button.displayName = "Button"

export { Button, buttonVariants }

만들어 둔 페이지 위에 버튼만 추가해보았다.

<Button>버튼이 생겼다!</Button>

컴포넌트마다 사용 방법이 다르지만 onClick 이벤트가 없으므로 내부에 글자만 넣었다.

hover하면 색이 연하게 바뀐다.