Use Cases (अपडेट: 2/6/2026)

Claude Code के साथ shadcn/ui: React के लिए व्यावहारिक गाइड

Claude Code से shadcn/ui सेटअप करें: Button/Card/Form/Dialog/Table, design tokens और Playwright visual checks।

Claude Code के साथ shadcn/ui: React के लिए व्यावहारिक गाइड

shadcn/ui सामान्य component library नहीं है जिसे install करके हमेशा node_modules से import किया जाए। इसकी CLI component source code को आपके project में copy करती है, आम तौर पर src/components/ui में। इसलिए Button, Card, Dialog और Table आपकी codebase का हिस्सा बन जाते हैं। आप उन्हें customize कर सकते हैं, लेकिन उनकी maintenance भी आपकी team की जिम्मेदारी होती है।

Claude Code इस model के साथ अच्छा काम करता है, क्योंकि वह generated files पढ़ सकता है, Tailwind classes समझ सकता है, form wiring कर सकता है और Playwright tests जोड़ सकता है। लेकिन अगर prompt बहुत vague हो, जैसे “dashboard बना दो”, तो वह duplicate Button बना सकता है, पुराना Tailwind config जोड़ सकता है या Dialog की accessibility तोड़ सकता है।

यह लेख Vite + React + TypeScript project के लिए practical workflow देता है: shadcn/ui install करना, Button/Card/Form/Dialog/Table जोड़ना, design tokens व्यवस्थित करना, copy-paste drift रोकना और Playwright से visual check करना। Claude Code की basics के लिए पहले Claude Code getting started guide देख लें।

पहले official docs देखें

Claude Code को काम शुरू करने से पहले official sources दें। shadcn/ui का Vite setup shadcn@latest दिखाता है, Tailwind CSS v4 @theme से theme variables समझाता है, Radix UI Dialog के focus और screen reader behavior को document करता है, और Playwright toHaveScreenshot() से visual comparison करता है।

flowchart LR
  A["Claude Code project पढ़ता है"] --> B["shadcn/ui init"]
  B --> C["components add"]
  C --> D["design tokens centralize"]
  D --> E["app components बनाना"]
  E --> F["Playwright visual check"]

Installation और init

यह example Vite पर है ताकि setup छोटा रहे। Next.js में भी यही सोच चलेगी, लेकिन beginners के लिए routing और Server Components को बाद में जोड़ना बेहतर है।

pnpm create vite@latest shadcn-claude-demo -- --template react-ts
cd shadcn-claude-demo
pnpm install
pnpm add tailwindcss @tailwindcss/vite
pnpm add -D @types/node

vite.config.ts में Tailwind plugin और @ alias जोड़ें।

import path from "node:path"
import react from "@vitejs/plugin-react"
import tailwindcss from "@tailwindcss/vite"
import { defineConfig } from "vite"

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

TypeScript में भी वही alias रखें।

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

Claude Code को पहले inspect करने को कहें।

इस Vite + React + TypeScript project में shadcn/ui जोड़ना है।
पहले package.json, vite.config.ts, tsconfig*.json और src/index.css पढ़ें।
केवल missing setup बताएं। मेरी approval के बाद shadcn@latest init
और needed components add करें।

फिर commands चलाएं।

pnpm dlx shadcn@latest init
pnpm dlx shadcn@latest add button card field input label dialog table
pnpm add react-hook-form zod @hookform/resolvers

आज के shadcn/ui form docs React Hook Form, Zod और Field component का pattern दिखाते हैं। पुराने blog से मिला Form snippet सीधे paste न करें।

Button और Card से शुरुआत

पहले छोटा component बनाएं। shadcn-generated files src/components/ui में रहें, और product-specific UI src/components/app में जाए।

import { Button } from "@/components/ui/button"
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"

type ProjectSummaryCardProps = {
  name: string
  openIssues: number
  onCreateTask: () => void
}

export function ProjectSummaryCard({
  name,
  openIssues,
  onCreateTask,
}: ProjectSummaryCardProps) {
  return (
    <Card className="max-w-md">
      <CardHeader>
        <CardTitle>{name}</CardTitle>
        <CardDescription>
          Review open UI issues before starting the next task.
        </CardDescription>
      </CardHeader>
      <CardContent>
        <p className="text-3xl font-semibold">{openIssues}</p>
        <p className="text-muted-foreground text-sm">open issues</p>
      </CardContent>
      <CardFooter>
        <Button onClick={onCreateTask}>Add task</Button>
      </CardFooter>
    </Card>
  )
}

Review prompt को narrow रखें।

केवल src/components/app/ProjectSummaryCard.tsx review करें।
props types, shadcn/ui imports, Tailwind class readability और accessibility देखें।
दूसरी files पर suggestion तभी दें जब जरूरी हो।

Form: Field, React Hook Form और Zod

Form सिर्फ Input दिखाने का काम नहीं है। Production form में validation, error text, aria-invalid, submit के दौरान disabled state, autocomplete और server errors की जगह चाहिए।

"use client"

import { zodResolver } from "@hookform/resolvers/zod"
import { Controller, useForm } from "react-hook-form"
import * as z from "zod"

import { Button } from "@/components/ui/button"
import {
  Field,
  FieldDescription,
  FieldError,
  FieldGroup,
  FieldLabel,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"

const contactSchema = z.object({
  email: z.string().email("Enter a valid email address"),
  topic: z.string().min(4, "Use at least 4 characters"),
})

type ContactFormValues = z.infer<typeof contactSchema>

export function ContactForm() {
  const form = useForm<ContactFormValues>({
    resolver: zodResolver(contactSchema),
    defaultValues: {
      email: "",
      topic: "",
    },
  })

  function onSubmit(values: ContactFormValues) {
    console.log("submit", values)
  }

  return (
    <form className="max-w-md space-y-4" onSubmit={form.handleSubmit(onSubmit)}>
      <FieldGroup>
        <Controller
          name="email"
          control={form.control}
          render={({ field, fieldState }) => (
            <Field data-invalid={fieldState.invalid}>
              <FieldLabel htmlFor={field.name}>Email</FieldLabel>
              <Input
                {...field}
                id={field.name}
                type="email"
                aria-invalid={fieldState.invalid}
                autoComplete="email"
              />
              <FieldDescription>We will use this address to reply.</FieldDescription>
              {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
            </Field>
          )}
        />
      </FieldGroup>

      <Button type="submit" disabled={form.formState.isSubmitting}>
        Send
      </Button>
    </form>
  )
}

छोटे form में schema और component साथ रख सकते हैं। बड़ा form हो तो Claude Code से schema.ts, ContactForm.tsx और server action को साफ अलग करवाएं।

Dialog और Table को safe रखना

Dialog सिर्फ popup नहीं है। Radix UI modal mode, focus trap, Escape close और Title/Description से screen reader announcement संभालता है। shadcn/ui styling देता है, लेकिन structure हटाना सही नहीं है।

import { useState } from "react"

import { Button } from "@/components/ui/button"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"

type Customer = {
  id: string
  name: string
  plan: "Free" | "Pro" | "Team"
}

const customers: Customer[] = [
  { id: "cus_001", name: "Aoi Tanaka", plan: "Pro" },
  { id: "cus_002", name: "Mika Sato", plan: "Team" },
]

export function CustomerTable() {
  const [selectedCustomer, setSelectedCustomer] = useState<Customer | null>(null)

  return (
    <>
      <Table>
        <TableHeader>
          <TableRow>
            <TableHead>Customer</TableHead>
            <TableHead>Plan</TableHead>
            <TableHead className="text-right">Actions</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {customers.map((customer) => (
            <TableRow key={customer.id}>
              <TableCell className="font-medium">{customer.name}</TableCell>
              <TableCell>{customer.plan}</TableCell>
              <TableCell className="text-right">
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => setSelectedCustomer(customer)}
                >
                  Edit
                </Button>
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>

      <Dialog open={selectedCustomer !== null} onOpenChange={() => setSelectedCustomer(null)}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Edit customer</DialogTitle>
            <DialogDescription>
              Review the contract plan for {selectedCustomer?.name}.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setSelectedCustomer(null)}>
              Close
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  )
}

Real app में data loading page layer पर रखें और Table को customers तथा onEdit दें। इससे UI बदलाव के दौरान data layer खराब होने का खतरा कम होता है।

Design tokens और Tailwind config

Design tokens color, spacing, radius, shadow और font जैसे values के named source होते हैं। Tailwind v4 में @theme utilities को प्रभावित करता है। shadcn/ui components --background, --primary, --border जैसी CSS variables भी use करते हैं।

@import "tailwindcss";

@theme {
  --font-sans: Inter, system-ui, sans-serif;
  --radius-card: 0.75rem;
  --color-brand-500: oklch(0.62 0.18 250);
}

:root {
  --radius: 0.625rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
}

अगर project Tailwind v3 पर है, Claude Code से दो अलग plans मांगें: v4 migration और v3-compatible minimal patch। दोनों को एक साथ मिलाना debugging को कठिन बना देता है।

Copy-paste drift रोकना

shadcn/ui source code देता है। Rule न हों तो team जल्दी ही कई मिलते-जुलते Button और Card बना देती है।

Ruleक्यों
src/components/ui में shadcn/ui primitives रखेंgenerated code से diff समझना आसान
product UI src/components/app में रखेंbusiness logic base layer में नहीं जाती
components.json alias बिना कारण न बदलेंimports stable रहते हैं
Claude Code को target files देंduplicate components कम होते हैं
src/components/ui shadcn/ui से आए components हैं।
नया Button या Card न बनाएं।
existing imports use करें और product UI src/components/app में रखें।
बाद में rg "function .*Button|export .*Button" src/components चलाकर
बताएं कि duplicate बना या नहीं।
git diff -- src/components/ui
git diff -- src/components/app
pnpm lint
pnpm build

Workflow को और मजबूत करने के लिए Claude Code productivity tips भी देखें।

Playwright visual checks

Playwright पहले baseline screenshot बनाता है, फिर future runs से compare करता है। OS, browser, fonts और viewport CI जैसे हों तो false failures कम होते हैं।

pnpm create playwright
pnpm playwright install
pnpm dev
pnpm playwright test
import { expect, test } from "@playwright/test"

test("customer table dialog visual state", async ({ page }) => {
  await page.goto("/customers")
  await page.getByRole("button", { name: "Edit" }).first().click()

  await expect(page).toHaveScreenshot("customers-dialog.png", {
    maxDiffPixels: 120,
  })
})

Snapshot तभी update करें जब visual change intended हो।

pnpm playwright test --update-snapshots

Failure पर Claude Code को specific problem दें।

Playwright customers-dialog.png fail हुआ।
Mobile में Dialog footer buttons बहुत पास हैं।
केवल src/components/app/CustomerTable.tsx और related CSS पढ़ें।
Spacing fix करें, DialogTitle और DialogDescription न हटाएं।

तीन उपयोगी use cases

पहला use case नया admin dashboard है। Button, Card, Table और Dialog से list, detail, edit और confirmation flow बन जाता है। पहले static data वाली UI बनवाएं, API बाद में जोड़ें।

दूसरा use case existing product को standardize करना है। पूरी redesign के बजाय search form, settings Dialog या empty-state Card जैसे छोटे हिस्से बदलें।

तीसरा use case paid prototype या client demo है। Mock data ठीक है, लेकिन component boundaries production जैसी रखें ताकि demo code आगे काम आए।

Accessibility review के लिए इस workflow को Claude Code accessibility practices के साथ जोड़ें। Labels, keyboard behavior, Dialog structure और error messages खास तौर पर देखें।

आम pitfalls

सबसे आम गलती Tailwind v4 project में v3 config paste करना है। पहले version और build pipeline check करें।

दूसरी गलती product logic को components/ui में डालना है। Payment plan वाला Button variant app wrapper में होना चाहिए, base Button में नहीं।

तीसरी गलती DialogTitle हटाना है। अगर title visually नहीं चाहिए, उसे intentionally hide करें, जानकारी delete न करें।

चौथी गलती सिर्फ HTML required पर भरोसा करना है। Real forms में translated errors, async validation और server errors चाहिए।

पांचवीं गलती Playwright baseline अलग environment में बनाना है। Fonts और viewport भी screenshot difference बना सकते हैं।

Prompt template और tested result

Goal: Vite + React + TypeScript admin screen में shadcn/ui जोड़ना।
Button, Card, Field-based Form, Dialog और Table use करना।

Constraints:
- current official docs follow करें
- src/components/ui केवल shadcn/ui primitives के लिए रखें
- app-specific components src/components/app में रखें
- forms React Hook Form + Zod + Field से बनाएं
- DialogTitle और DialogDescription रखें
- Tailwind v4 @theme और CSS variable changes explain करें
- एक Playwright toHaveScreenshot test add करें

Process:
1. existing setup inspect
2. change plan propose
3. approval के बाद implement
4. pnpm build और pnpm playwright test run
5. changed files और risks summarize

Tested result: minimal Vite app में इस flow से component install, @theme brand color, Field-based form, Table row से Dialog open और Playwright screenshot check reproduce हुआ। दूसरी pass सिर्फ form error rendering पर लगी; aria-invalid और FieldError साफ लिखने के बाद diff review आसान हो गया।

Team use के लिए इस prompt को CLAUDE.md में रखें। ClaudeCodeLab ऐसे UI rules, review checklists और Claude Code prompts को paid templates के रूप में भी देता है, ताकि हर sprint में वही guidance दोहरानी न पड़े।

#Claude Code #shadcn/ui #React #Tailwind CSS #UI Library
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

लेखक के बारे में

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.