0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】shadcn/ui やってみたメモ

Posted at

shadcn/ui って何?

以下の記事に全てのっています

  • コピペ方式で自由にカスタマイズ可能
  • Radix UIベースで堅牢なアクセシビリティを提供
  • Tailwindとの相性抜群で開発効率良し

なところが推しです。まだやったことないですが

やってみる

Vite + React環境の準備

pnpm create vite shadcn-hello-world --template react-ts
> pnpm create vite shadcn-hello-world --template react-ts
.../193e78272f7-4154                     |   +1 +
.../193e78272f7-4154                     | Progress: resolved 1, reused 0, downloaded 1, added 1, 
done

Scaffolding project in C:\work\repo\shadcn-hello-world...

Done. Now run:

  cd shadcn-hello-world
  pnpm install
  pnpm run dev
  cd shadcn-hello-world
  pnpm install
  pnpm run dev
  pnpm run dev

いつものやつが表示されたらOK

TailwindCSSの準備

shadcn/uiはtailwindに依存しているので、tailwindをインストールします。

pnpm install -D tailwindcss postcss autoprefixer
pnpm exec tailwindcss init
>pnpm install -D tailwindcss postcss autoprefixer

Progress: resolved 291, reused 243, downloaded 6, added 79, done

devDependencies:
+ autoprefixer 10.4.20
devDependencies:
+ autoprefixer 10.4.20
+ autoprefixer 10.4.20
+ postcss 8.4.49
+ tailwindcss 3.4.17

Done in 16.9s
>pnpm exec tailwindcss init

Created Tailwind CSS config file: tailwind.config.js

設定ファイルが必要なので、作成していく。

存在しないので、以下の内容で新規作成する。
ドキュメントだとmodules.exportとCoomonJsの記載になっているが、
ESModule形式で定義する。

// postcss.config.js

+ export default {
+     plugins: {
+         tailwindcss: {},
+         autoprefixer: {},
+     },
+ }
// tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
-  content: [],
+  content: ["./src/**/*.tsx"],
  theme: {
    extend: {},
  },
  plugins: [],
}
// src/index.css

+ @tailwind base;
+ @tailwind components;
+ @tailwind utilities;

tailwindが適応され、画面が崩れたらOK

cap2.PNG

shadcnのインストール

ここからが本番!!

pnpm add tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react
> pnpm add tailwindcss-animate class-variance-authority clsx tailwind-merge lucide-react
Packages: +5
+++++
Progress: resolved 296, reused 250, downloaded 4, added 5, done

dependencies:
+ class-variance-authority 0.7.1
+ clsx 2.1.1
+ lucide-react 0.469.0
+ tailwind-merge 2.5.5
+ tailwindcss-animate 1.0.7

Done in 1m 15.7s

設定ファイルに追記していく。

// tsconfig.app.json
    ...
    "module": "ESNext",
    "skipLibCheck": true,
    "baseUrl": ".",
+    "paths": {
+      "@/*": [
+        "./*"
+      ]
+    },
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    ...

nextjs準拠だから?
@がsrcじゃなくrootを指している。
まぁいいけど。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ["class"],
  content: ["./src/**/*.tsx"],
  theme: {
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        secondary: {
          DEFAULT: "hsl(var(--secondary))",
          foreground: "hsl(var(--secondary-foreground))",
        },
        destructive: {
          DEFAULT: "hsl(var(--destructive))",
          foreground: "hsl(var(--destructive-foreground))",
        },
        muted: {
          DEFAULT: "hsl(var(--muted))",
          foreground: "hsl(var(--muted-foreground))",
        },
        accent: {
          DEFAULT: "hsl(var(--accent))",
          foreground: "hsl(var(--accent-foreground))",
        },
        popover: {
          DEFAULT: "hsl(var(--popover))",
          foreground: "hsl(var(--popover-foreground))",
        },
        card: {
          DEFAULT: "hsl(var(--card))",
          foreground: "hsl(var(--card-foreground))",
        },
      },
      borderRadius: {
        lg: `var(--radius)`,
        md: `calc(var(--radius) - 2px)`,
        sm: "calc(var(--radius) - 4px)",
      },
    },
  },
  plugins: [require("tailwindcss-animate")],
}

ここらへんはコピペ
一部だけ変更している。NextjsのApp Routerっぽい。Reactなので注意

-  content: ["app/**/*.{ts,tsx}", "components/**/*.{ts,tsx}"],
+  content: ["./src/**/*.tsx"],

とりあえずデフォルトの黒いやつをコピペ

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

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 47.4% 11.2%;
    --muted: 210 40% 96.1%;
    --muted-foreground: 215.4 16.3% 46.9%;
    --popover: 0 0% 100%;
    --popover-foreground: 222.2 47.4% 11.2%;
    --border: 214.3 31.8% 91.4%;
    --input: 214.3 31.8% 91.4%;
    --card: 0 0% 100%;
    --card-foreground: 222.2 47.4% 11.2%;
    --primary: 222.2 47.4% 11.2%;
    --primary-foreground: 210 40% 98%;
    --secondary: 210 40% 96.1%;
    --secondary-foreground: 222.2 47.4% 11.2%;
    --accent: 210 40% 96.1%;
    --accent-foreground: 222.2 47.4% 11.2%;
    --destructive: 0 100% 50%;
    --destructive-foreground: 210 40% 98%;
    --ring: 215 20.2% 65.1%;
    --radius: 0.5rem;
  }

  .dark {
    --background: 224 71% 4%;
    --foreground: 213 31% 91%;
    --muted: 223 47% 11%;
    --muted-foreground: 215.4 16.3% 56.9%;
    --accent: 216 34% 17%;
    --accent-foreground: 210 40% 98%;
    --popover: 224 71% 4%;
    --popover-foreground: 215 20.2% 65.1%;
    --border: 216 34% 17%;
    --input: 216 34% 17%;
    --card: 224 71% 4%;
    --card-foreground: 213 31% 91%;
    --primary: 210 40% 98%;
    --primary-foreground: 222.2 47.4% 1.2%;
    --secondary: 222.2 47.4% 11.2%;
    --secondary-foreground: 210 40% 98%;
    --destructive: 0 63% 31%;
    --destructive-foreground: 210 40% 98%;
    --ring: 216 34% 17%;
  }
}

@layer base {
  * {
    @apply border-border;
  }
  body {
    @apply font-sans antialiased bg-background text-foreground;
  }
}

ないので作成

lib/utils.ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

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

同様に作成

components.json
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": false,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.js",
    "css": "src/index.css",
    "baseColor": "zinc",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  },
  "iconLibrary": "lucide"
}

やってみる!

無害そうなButtonを作成してみる

pnpm dlx shadcn@latest add button

いってこーい

> pnpm dlx shadcn@latest add button
✔ Checking registry.
✔ Installing dependencies.
✔ Created 1 file:
  - @\components\ui\button.tsx

cap1.PNG

・・・だいぶ残念な場所に作成されたw

まだどこか設定が漏れてるのかも?ただ、ファイル出力されたのは嬉しいので、移動させて使ってみる

src/App.tsx
import './App.css'
import { Button } from '@/src/components/ui/button'

function App() {

  return (
    <>
      {/* 用意された複数のvariantが利用できる */}
      <Button>Button</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="destructive">destructive</Button>
      <Button variant="ghost">ghost</Button>
      <Button variant="link">link</Button>
      <Button variant="outline">outline</Button>

      {/* 既に指定されているclassNameでも上書き可能 */}
      <Button className='p-20'>outline</Button>
    </>
  )
}

export default App

cap3.PNG

良い感じ!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?