Shadcn/UI คืออะไร? สอนสำหรับผู้เริ่มต้น

Audrey Lopez

Audrey Lopez

14 June 2025

Shadcn/UI คืออะไร? สอนสำหรับผู้เริ่มต้น

สำหรับนักพัฒนาเว็บ การแสวงหา UI toolkit ที่สมบูรณ์แบบเป็นความพยายามอย่างต่อเนื่อง เป็นเวลาหลายปีที่นักพัฒนา React อาศัยไลบรารีคอมโพเนนต์แบบดั้งเดิม เช่น Material-UI (MUI), Ant Design และ Chakra UI ไลบรารีเหล่านี้มีคอมโพเนนต์สำเร็จรูปมากมาย ซึ่งช่วยเร่งการพัฒนา อย่างไรก็ตาม มักจะมีข้อแลกเปลี่ยนคือ การขาดการควบคุม การปรับสไตล์ที่รู้สึกเหมือนเป็นการต่อสู้ และขนาดของ bundle ที่ใหญ่เกินไป

ขอแนะนำ Shadcn UI ซึ่งเป็นแนวทางที่พลิกโฉมวงการและได้รับความนิยมอย่างมากในชุมชน React ไม่ใช่ไลบรารีคอมโพเนนต์ในแบบที่คุณคุ้นเคย แต่เป็นสิ่งที่ดียิ่งกว่า เป็นชุดของคอมโพเนนต์ที่ออกแบบมาอย่างสวยงาม เข้าถึงได้ และนำกลับมาใช้ซ้ำได้อย่างไม่สิ้นสุด ซึ่งคุณไม่ได้ติดตั้งจาก npm เป็น dependency แต่คุณคัดลอกโค้ดโดยตรงลงในโปรเจกต์ของคุณ

บทช่วยสอนฉบับสมบูรณ์ความยาว 4000 คำนี้จะเป็นคู่มือที่ชัดเจนของคุณ โดยจะพาคุณจากผู้เริ่มต้นไปสู่ผู้ใช้งาน Shadcn UI ได้อย่างมั่นใจ เราจะสำรวจปรัชญาพื้นฐานของมัน เดินผ่านการตั้งค่าอย่างละเอียด สร้าง UI ที่ซับซ้อน เชี่ยวชาญการปรับแต่งธีมขั้นสูงและการจัดการฟอร์ม และพูดคุยเกี่ยวกับแนวทางปฏิบัติที่ดีที่สุดสำหรับแอปพลิเคชันขนาดใหญ่ เตรียมพร้อมที่จะคิดใหม่เกี่ยวกับสิ่งที่คุณคาดหวังจาก UI toolkit

💡
ต้องการเครื่องมือทดสอบ API ที่ยอดเยี่ยมซึ่งสร้าง เอกสาร API ที่สวยงาม ใช่ไหม?

ต้องการแพลตฟอร์มแบบ All-in-One ที่ผสานรวมสำหรับทีมพัฒนาของคุณเพื่อทำงานร่วมกันด้วย ประสิทธิภาพสูงสุด ใช่ไหม?

Apidog ตอบสนองทุกความต้องการของคุณ และ มาแทนที่ Postman ในราคาที่เข้าถึงได้ง่ายกว่ามาก!
button

ปรัชญาของ Shadcn UI - วิธีการสร้างแบบใหม่

ก่อนที่จะเขียนโค้ดแม้แต่บรรทัดเดียว สิ่งสำคัญที่สุดคือการทำความเข้าใจว่า ทำไม Shadcn UI จึงมีอยู่และแก้ปัญหาอะไร การเข้าใจปรัชญาหลักนี้คือกุญแจสำคัญในการปลดล็อกศักยภาพสูงสุดของมัน

สิ่งที่ Shadcn UI ไม่ใช่

สิ่งที่ Shadcn UI คือ

ข้อได้เปรียบหลักของโมเดลนี้คือการรวมกันของ ความเร็วและการควบคุม คุณจะได้ความเร็วเริ่มต้นจากการใช้คอมโพเนนต์สำเร็จรูป โดยไม่เสียความยืดหยุ่นและความสามารถในการบำรุงรักษาในระยะยาวที่มาจากการเป็นเจ้าของโค้ดของคุณเอง


การเตรียมการ - การตั้งค่าโปรเจกต์และการติดตั้ง

มาเปลี่ยนจากทฤษฎีสู่การปฏิบัติ เราจะตั้งค่าโปรเจกต์ใหม่ตั้งแต่เริ่มต้น สำหรับคู่มือนี้ เราจะใช้ Next.js เป็นหลัก เนื่องจาก Server Components และการกำหนดเส้นทางตามไฟล์ของมันเข้ากันได้ดีกับแนวคิดของ Shadcn UI เราจะกล่าวถึงการตั้งค่าสำหรับ Vite สั้นๆ ด้วย

ขั้นตอนที่ 1: ข้อกำหนดเบื้องต้นของสภาพแวดล้อม

ตรวจสอบให้แน่ใจว่าสภาพแวดล้อมการพัฒนาของคุณพร้อมแล้ว คุณจะต้องมี:

ขั้นตอนที่ 2: การสร้างแอปพลิเคชัน Next.js ใหม่

เปิด Terminal ของคุณและรันคำสั่งต่อไปนี้เพื่อเริ่มต้นโปรเจกต์ Next.js ใหม่Bash

npx create-next-app@latest my-pro-shadcn-app --typescript --tailwind --eslint

คำสั่งนี้จะสร้างแอปพลิเคชันใหม่ในไดเร็กทอรีชื่อ my-pro-shadcn-app เราได้รวม flags ที่สำคัญบางอย่างไว้:

ตัวติดตั้งจะถามคำถามสองสามข้อ นี่คือตัวเลือกที่แนะนำสำหรับการตั้งค่า Next.js 14+ ที่ทันสมัย:

✔ Would you like to use `src/` directory? … No / **Yes**
✔ Would you like to use App Router? (recommended) … No / **Yes**
✔ Would you like to customize the default import alias? … **No** / Yes

การใช้ App Router เป็นแนวทางปฏิบัติมาตรฐาน และไดเร็กทอรี src/ ช่วยในการจัดระเบียบโค้ด เมื่อเสร็จแล้ว ให้เข้าไปในโปรเจกต์ใหม่ของคุณ:Bash

cd my-pro-shadcn-app

ขั้นตอนที่ 3: คำสั่ง init - ทำให้ Shadcn UI มีชีวิตชีวา

นี่คือขั้นตอนที่สำคัญที่สุด Shadcn UI มีเครื่องมือ CLI สำหรับกำหนดค่าโปรเจกต์ของคุณ รันคำสั่งต่อไปนี้จากไดเร็กทอรี root ของโปรเจกต์ของคุณ:Bash

npx shadcn-ui@latest init

สิ่งนี้จะเรียกใช้แบบสอบถามแบบโต้ตอบเพื่อตั้งค่าโปรเจกต์ของคุณ มาทำความเข้าใจแต่ละคำถามและความสำคัญของมัน:

หลังจากที่คุณยืนยัน CLI จะทำงานอย่างมหัศจรรย์:

  1. ติดตั้ง Dependencies: เพิ่มแพ็คเกจที่จำเป็น เช่น tailwindcss-animate และ class-variance-authority
  2. สร้าง components.json: จัดเก็บตัวเลือกการกำหนดค่าของคุณ
  3. อัปเดต tailwind.config.ts: แทรก Shadcn UI plugin และการกำหนดค่าธีม
  4. อัปเดต globals.css: เพิ่มบล็อกใหญ่ของตัวแปร CSS ที่กำหนดชุดสีทั้งหมดของคุณ, border radii, และอื่นๆ
  5. สร้าง lib/utils.ts: ไฟล์นี้ export ฟังก์ชันตัวช่วย cn ซึ่งเป็นยูทิลิตี้ที่ชาญฉลาดสำหรับการรวมคลาส Tailwind CSS แบบมีเงื่อนไข

โปรเจกต์ของคุณได้รับการกำหนดค่าอย่างสมบูรณ์แล้ว

(ทางเลือก: การตั้งค่า Vite)

หากคุณใช้ Vite กับ React กระบวนการจะคล้ายกันมาก หลังจากตั้งค่าโปรเจกต์ Vite + React + TS แล้ว คุณจะต้องติดตั้ง Tailwind CSS ด้วยตนเอง จากนั้นรัน npx shadcn-ui@latest init CLI ฉลาดพอที่จะตรวจจับการตั้งค่า Vite และจะถามคำถามที่แตกต่างกันเล็กน้อยเกี่ยวกับตำแหน่งไฟล์ (เช่น index.css แทน globals.css)


การสร้าง UI - จากคอมโพเนนต์ง่ายๆ ไปจนถึงเลย์เอาต์ที่ซับซ้อน

เมื่อตั้งค่าเสร็จแล้ว มาเริ่มสร้างกันเลย เวิร์กโฟลว์หลักคือ: ระบุความต้องการ, เพิ่มคอมโพเนนต์, ใช้มัน

ขั้นตอนที่ 4: การเพิ่มและใช้คอมโพเนนต์แรกของคุณ

มาทำความสะอาด boilerplate เริ่มต้นของ Next.js และสร้างอินเทอร์เฟซง่ายๆ

1. เพิ่มปุ่ม:Bash

npx shadcn-ui@latest add button

สังเกตสิ่งที่เกิดขึ้น: ไฟล์ใหม่ src/components/ui/button.tsx ถูกสร้างขึ้น นี่คือปุ่มของคุณ คุณเป็นเจ้าของมัน

2. เพิ่ม Card:Bashnpx shadcn-ui@latest add card

คำสั่งนี้น่าสนใจกว่า สร้าง src/components/ui/card.tsx หากคุณตรวจสอบไฟล์นี้ คุณจะเห็นว่ามัน export คอมโพเนนต์หลายรายการ: Card, CardHeader, CardTitle, CardDescription, CardContent, และ CardFooter นี่เป็นรูปแบบทั่วไปสำหรับ compound components

3. สร้าง UI:

ตอนนี้ เปิด src/app/page.tsx และแทนที่เนื้อหาด้วยโค้ดต่อไปนี้:TypeScript

import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input"; // เราจะเพิ่มอันนี้ต่อไป
import { Label } from "@/components/ui/label";   // และอันนี้

export default function Home() {
  return (
    <main className="flex min-h-screen items-center justify-center bg-background p-8">
      <Card className="w-full max-w-md">
        <CardHeader>
          <CardTitle className="text-2xl">Create Project</CardTitle>
          <CardDescription>
            Deploy your new project in one-click.
          </CardDescription>
        </CardHeader>
        <CardContent className="grid gap-4">
          <div className="grid gap-2">
            <Label htmlFor="name">Name</Label>
            <Input id="name" placeholder="Name of your project" />
          </div>
          <div className="grid gap-2">
            <Label htmlFor="framework">Framework</Label>
            {/* เราจะแทนที่ด้วยคอมโพเนนต์ Select ในภายหลัง */}
            <Input id="framework" placeholder="e.g. Next.js" />
          </div>
        </CardContent>
        <CardFooter>
          <Button className="w-full">Deploy</Button>
        </CardFooter>
      </Card>
    </main>
  );
}

โค้ดของเรายังไม่สามารถรันได้เนื่องจากเราขาดคอมโพเนนต์ Input และ Label มาเพิ่มกัน:Bash

npx shadcn-ui@latest add input
npx shadcn-ui@latest add label

ตอนนี้ รัน development server ของคุณ:Bash

npm run dev

ไปที่ http://localhost:3000 คุณจะเห็นฟอร์มที่ดูสะอาดตาและเป็นมืออาชีพภายใน card สังเกตว่าเราใช้ utility classes เช่น w-full, max-w-md, และ grid โดยตรงใน JSX ของเราเพื่อควบคุมเลย์เอาต์ นี่คือพลังของการรวม Shadcn และ Tailwind CSS

ขั้นตอนที่ 5: การแนะนำคอมโพเนนต์ที่ซับซ้อนมากขึ้น

Input แบบ static ก็ดี แต่แอปพลิเคชันจริงต้องการองค์ประกอบแบบโต้ตอบ มาปรับปรุงฟอร์มของเรากัน

1. เพิ่มคอมโพเนนต์ Select: ช่อง input "Framework" ควรเป็น dropdown มาเพิ่มคอมโพเนนต์ Select อันนี้ซับซ้อนกว่าและมี dependencies กับคอมโพเนนต์อื่น:Bash

npx shadcn-ui@latest add select

CLI ฉลาด มันจะเห็นว่า Select ต้องการคอมโพเนนต์ Popover เพื่อทำงาน และจะขออนุญาตคุณในการติดตั้งมันและ dependencies ของมันด้วย นี่เป็นคุณสมบัติที่ยอดเยี่ยมที่ช่วยให้คุณไม่ต้องติดตาม dependencies ด้วยตนเอง

2. รวมคอมโพเนนต์ Select: แทนที่ Input สำหรับ "Framework" ใน src/app/page.tsx ด้วยคอมโพเนนต์ Select ใหม่:TypeScript

// เพิ่ม imports เหล่านี้ที่ด้านบน
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

// ... ภายใน CardContent
<div className="grid gap-2">
  <Label htmlFor="framework">Framework</Label>
  <Select>
    <SelectTrigger id="framework">
      <SelectValue placeholder="Select a framework" />
    </SelectTrigger>
    <SelectContent>
      <SelectItem value="nextjs">Next.js</SelectItem>
      <SelectItem value="sveltekit">SvelteKit</SelectItem>
      <SelectItem value="astro">Astro</SelectItem>
      <SelectItem value="nuxt">Nuxt.js</SelectItem>
    </SelectContent>
  </Select>
</div>

รีเฟรชเบราว์เซอร์ของคุณ ตอนนี้คุณมี dropdown select ที่ใช้งานได้เต็มรูปแบบและเข้าถึงได้ พร้อมแอนิเมชันและการนำทางด้วยคีย์บอร์ดที่ถูกต้อง ทั้งหมดนี้ต้องขอบคุณ Radix UI ที่ทำงานอยู่เบื้องหลัง

3. การเพิ่ม User Feedback ด้วย Toast: จะเกิดอะไรขึ้นเมื่อผู้ใช้คลิก "Deploy"? เราควรให้ feedback แก่พวกเขา คอมโพเนนต์ Toast เหมาะสำหรับสิ่งนี้

ขั้นแรก เพิ่มมัน:Bash

npx shadcn-ui@latest add toast

ถัดไป ในการใช้ toasts คุณต้องเพิ่มคอมโพเนนต์ <Toaster /> ไปยัง root layout ของคุณเพื่อให้สามารถแสดงผลได้ทุกที่ในแอป เปิด src/app/layout.tsx และแก้ไขมัน:TypeScript

import { Toaster } from "@/components/ui/toaster" // Import the Toaster

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Toaster /> {/* เพิ่มที่นี่ ก่อนปิด body */}
      </body>
    </html>
  )
}

ตอนนี้ เราต้องการวิธี เรียก toast เราจะใช้ hook useToast มาอัปเดต src/app/page.tsx เพื่อให้เป็น client component และจัดการการคลิกปุ่ม:TypeScript

'use client'; // <-- เพิ่มที่ด้านบนสุดของไฟล์

// ... imports อื่นๆ
import { useToast } from "@/components/ui/use-toast";

export default function Home() {
  const { toast } = useToast(); // รับฟังก์ชัน toast จาก hook

  function handleDeploy() {
    toast({
      title: "Deployment Scheduled!",
      description: "Your project 'Name of your project' is being deployed.",
      duration: 5000,
    });
  }

  return (
    <main className="flex min-h-screen items-center justify-center bg-background p-8">
      <Card className="w-full max-w-md">
        {/* ... CardHeader และ CardContent ... */}
        <CardFooter>
          <Button className="w-full" onClick={handleDeploy}> {/* เพิ่ม onClick handler */}
            Deploy
          </Button>
        </CardFooter>
      </Card>
    </main>
  );
}

ตอนนี้ เมื่อคุณคลิกปุ่ม "Deploy" การแจ้งเตือนที่ดูดีจะปรากฏขึ้นที่มุมหน้าจอของคุณ


การสร้างฟอร์มระดับมืออาชีพพร้อมการตรวจสอบข้อมูล (Validation)

แอปพลิเคชันจริงส่วนใหญ่ต้องการการจัดการฟอร์มที่แข็งแกร่ง รวมถึงการตรวจสอบข้อมูลฝั่ง client วิธีการอย่างเป็นทางการในการจัดการสิ่งนี้ด้วย Shadcn UI คือการรวมมันเข้ากับ react-hook-form สำหรับการจัดการสถานะ และ zod สำหรับการตรวจสอบ schema มาสร้างกัน

ขั้นตอนที่ 6: การติดตั้ง Dependencies สำหรับฟอร์ม

ขั้นแรก มาติดตั้งไลบรารีที่จำเป็น:Bash

npm install react-hook-form zod @hookform/resolvers

ขั้นตอนที่ 7: การเพิ่มคอมโพเนนต์ Form ของ Shadcn

Shadcn UI มีคอมโพเนนต์ Form พิเศษที่ทำหน้าที่เป็น wrapper เพื่อเชื่อมต่อ react-hook-form กับคอมโพเนนต์ UI ของคุณได้อย่างราบรื่น:Bash

npx shadcn-ui@latest add form

สิ่งนี้จะเพิ่ม src/components/ui/form.tsx ไฟล์นี้มีชุดของคอมโพเนนต์ที่รับรู้ context (Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage) ซึ่งช่วยลด boilerplate ได้อย่างมาก

ขั้นตอนที่ 8: การสร้าง Validation Schema

ในไฟล์ src/app/page.tsx ของคุณ มากำหนดรูปแบบและกฎของข้อมูลฟอร์มของเราโดยใช้ zod:TypeScript

// เพิ่ม imports เหล่านี้ที่ด้านบน
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";

ตอนนี้ มาสร้าง schema เหนือคอมโพเนนต์ Home ของเราเล็กน้อย:TypeScript

const formSchema = z.object({
  projectName: z.string().min(2, {
    message: "Project name must be at least 2 characters.",
  }).max(50, {
    message: "Project name must not exceed 50 characters.",
  }),
  framework: z.string({
    required_error: "Please select a framework to display.",
  }),
});

schema นี้กำหนดสองฟิลด์: projectName ต้องเป็น string ที่มีความยาวระหว่าง 2 ถึง 50 ตัวอักษร และ framework เป็น string ที่ต้องระบุ

ขั้นตอนที่ 9: การเชื่อมต่อฟอร์ม

ตอนนี้ มาปรับโครงสร้างคอมโพเนนต์ Home ของเราเพื่อใช้เครื่องมือใหม่ทั้งหมดเหล่านี้:TypeScript

export default function Home() {
  const { toast } = useToast();

  // 1. กำหนดฟอร์มของคุณ
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      projectName: "",
    },
  });

  // 2. กำหนด submit handler
  function onSubmit(values: z.infer<typeof formSchema>) {
    // ทำอะไรบางอย่างกับค่าฟอร์ม
    // ✅ สิ่งนี้จะ type-safe และถูกตรวจสอบแล้ว
    console.log(values);
    toast({
      title: "You submitted the following values:",
      description: (
        <pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
          <code className="text-white">{JSON.stringify(values, null, 2)}</code>
        </pre>
      ),
    });
  }

  // 3. สร้าง JSX ด้วยคอมโพเนนต์ Form ของ Shadcn
  return (
    <main className="flex min-h-screen items-center justify-center bg-background p-8">
      <Card className="w-full max-w-md">
        <CardHeader>
          <CardTitle className="text-2xl">Create Project</CardTitle>
          <CardDescription>
            Deploy your new project in one-click.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <Form {...form}>
            <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
              <FormField
                control={form.control}
                name="projectName"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Name</FormLabel>
                    <FormControl>
                      <Input placeholder="Name of your project" {...field} />
                    </FormControl>
                    <FormDescription>
                      This is your public display name.
                    </FormDescription>
                    <FormMessage /> {/* แสดงข้อผิดพลาดในการตรวจสอบข้อมูล */}
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name="framework"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Framework</FormLabel>
                    <Select onValueChange={field.onChange} defaultValue={field.value}>
                      <FormControl>
                        <SelectTrigger>
                          <SelectValue placeholder="Select a framework" />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        <SelectItem value="nextjs">Next.js</SelectItem>
                        <SelectItem value="sveltekit">SvelteKit</SelectItem>
                        <SelectItem value="astro">Astro</SelectItem>
                        <SelectItem value="nuxt">Nuxt.js</SelectItem>
                      </SelectContent>
                    </Select>
                    <FormDescription>
                      The framework you want to deploy.
                    </FormDescription>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <Button type="submit" className="w-full">Deploy</Button>
            </form>
          </Form>
        </CardContent>
      </Card>
    </main>
  );
}

นี่เป็นโค้ดส่วนใหญ่ แต่เป็นรูปแบบที่ทรงพลังและปรับขนาดได้สูง คอมโพเนนต์ FormField จัดการการเชื่อมต่อสถานะทั้งหมด และ FormMessage จะแสดงข้อผิดพลาดในการตรวจสอบข้อมูลที่ถูกต้องจาก schema zod ของคุณโดยอัตโนมัติเมื่อผู้ใช้โต้ตอบกับฟิลด์ ลองส่งฟอร์มโดยเว้นชื่อโปรเจกต์ว่างไว้เพื่อดูการตรวจสอบข้อมูลทำงาน


การเชี่ยวชาญการปรับแต่งธีมและการปรับแต่ง

พลังที่แท้จริงของ Shadcn UI จะถูกปลดปล่อยเมื่อคุณเริ่มปรับให้เป็นของคุณเอง

ขั้นตอนที่ 10: การปรับแต่งธีมขั้นสูงด้วยตัวแปร CSS

ธีมทั้งหมดของคุณถูกกำหนดโดยตัวแปร CSS ในไฟล์ src/app/globals.css เปิดไฟล์นี้และมองหาบล็อก :root และ .dark:CSS

/* ตัวอย่างจาก globals.css */
:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 98%;
  /* ... และอื่นๆ อีกมากมาย */
  --radius: 0.5rem;
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 98%;
  --primary: 210 40% 98%;
  --primary-foreground: 222.2 47.4% 11.2%;
  /* ... */
}

การใช้งาน Dark Mode:

Shadcn ได้รับการกำหนดค่าล่วงหน้าสำหรับ dark mode ต้องขอบคุณบล็อกคลาส .dark และกลยุทธ์ darkMode: "class" ของ Tailwind ใน tailwind.config.ts สิ่งที่คุณต้องมีคือวิธีสลับคลาส dark บนองค์ประกอบ <html> ไลบรารียอดนิยมสำหรับสิ่งนี้คือ next-themes

  1. ติดตั้ง: npm install next-themes
  2. สร้างคอมโพเนนต์ ThemeProvider (src/components/theme-provider.tsx): TypeScript
"use client"
import * as React from "react"
import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}
  1. ครอบ RootLayout ของคุณด้วย provider นี้ (src/app/layout.tsx): TypeScript
import { ThemeProvider } from "@/components/theme-provider"

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider
          attribute="class"
          defaultTheme="system"
          enableSystem
          disableTransitionOnChange
        >
          {children}
          <Toaster />
        </ThemeProvider>
      </body>
    </html>
  )
}
  1. สุดท้าย สร้างปุ่มสลับ (เช่น src/components/mode-toggle.tsx): TypeScript
"use client"
import * as React from "react"
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { Button } from "@/components/ui/button"

export function ModeToggle() {
  const { theme, setTheme } = useTheme()

  return (
    <Button
      variant="outline"
      size="icon"
      onClick={() => setTheme(theme === "light" ? "dark" : "light")}
    >
      <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
      <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
      <span className="sr-only">Toggle theme</span>
    </Button>
  )
}

ตอนนี้คุณสามารถวาง <ModeToggle /> นี้ได้ทุกที่ในแอปของคุณเพื่อรับปุ่มสลับ dark mode ที่รับรู้ระบบและผู้ใช้สามารถ override ได้

ขั้นตอนที่ 11: การปรับแต่งโค้ดต้นฉบับของคอมโพเนนต์

นี่คือสุดยอดพลังพิเศษ สมมติว่าคุณต้องการ variant ใหม่สำหรับปุ่มของคุณที่พื้นหลังเป็นสีเขียว

เปิด src/components/ui/button.tsx ค้นหาการกำหนด buttonVariants ใช้ cva (Class Variance Authority) เพียงแค่เพิ่ม variant ใหม่:TypeScript

const buttonVariants = cva(
  // ... base styles
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
        secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
        success: "bg-green-600 text-white hover:bg-green-600/90", // variant ใหม่ของเรา
      },
      // ... size variants
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)

แค่นั้นเอง ตอนนี้คุณสามารถใช้มันในโค้ดของคุณได้: <Button variant="success">Success</Button> คุณไม่จำเป็นต้องเขียน CSS overrides ที่ซับซ้อน คุณเพียงแค่แก้ไขโค้ดต้นฉบับของคอมโพเนนต์เอง เวิร์กโฟลว์นี้เรียบง่าย คาดเดาได้ และทรงพลังอย่างเหลือเชื่อ


ส่วนที่ 6: แนวทางปฏิบัติที่ดีที่สุดและเส้นทางข้างหน้า

เมื่อแอปพลิเคชันของคุณเติบโตขึ้น นี่คือแนวทางปฏิบัติที่ดีที่สุดบางประการที่ควรจำไว้

สรุป: คุณคือผู้เขียนไลบรารี

ตอนนี้คุณได้เดินทางจากปรัชญาหลักของ Shadcn UI ไปสู่การนำรูปแบบขั้นสูงในโลกแห่งความเป็นจริงไปใช้ คุณได้เห็นแล้วว่านวัตกรรมที่แท้จริงของมันไม่ใช่แค่คอมโพเนนต์เท่านั้น แต่เป็นการเปลี่ยนแปลงกระบวนทัศน์ที่มันนำเสนอ มันเปลี่ยนนักพัฒนาจากการเป็นเพียง ผู้บริโภค ไลบรารีไปสู่การเป็น ผู้ดูแล และ เจ้าของ UI toolkit ของตนเอง

ด้วยการมอบโค้ดต้นฉบับให้คุณ การสร้างบนรากฐานที่แข็งแกร่งของ Tailwind CSS และ Radix UI และการมอบประสบการณ์ CLI ที่ราบรื่น Shadcn UI จึงสร้างสมดุลที่สมบูรณ์แบบระหว่างความเร็วในการพัฒนาเริ่มต้นและความสามารถในการบำรุงรักษาในระยะยาวและอิสระในการสร้างสรรค์ คุณไม่ถูกจำกัดด้วยระบบการออกแบบของคนอื่นอีกต่อไป คอมโพเนนต์ในโปรเจกต์ของคุณคือของคุณเอง—ที่จะแก้ไข ขยาย และทำให้สมบูรณ์แบบ

อนาคตของ UI แอปพลิเคชันของคุณไม่ได้อยู่ในมือของ dependency บุคคลที่สามอีกต่อไป มันอยู่ที่นั่นในโฟลเดอร์ components ของคุณ ขอให้มีความสุขกับการสร้างสรรค์

💡
ต้องการเครื่องมือทดสอบ API ที่ยอดเยี่ยมซึ่งสร้าง เอกสาร API ที่สวยงาม ใช่ไหม?

ต้องการแพลตฟอร์มแบบ All-in-One ที่ผสานรวมสำหรับทีมพัฒนาของคุณเพื่อทำงานร่วมกันด้วย ประสิทธิภาพสูงสุด ใช่ไหม?

Apidog ตอบสนองทุกความต้องการของคุณ และ มาแทนที่ Postman ในราคาที่เข้าถึงได้ง่ายกว่ามาก!
button

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API