feat: Qoder rule (#70)

Co-authored-by: kyle.jiang@dbappsecurity.com.cn <kyle.jiang@dbappsecurity.com.cn>
This commit is contained in:
xiaocaiji
2026-01-16 09:05:16 +08:00
committed by GitHub
parent 408df90766
commit 1d5659bd77
20 changed files with 1298 additions and 0 deletions

66
.qoder/rules/shadcn.md Normal file
View File

@@ -0,0 +1,66 @@
---
trigger: always_on
---
| No | Category | Guideline | Description | Do | Don't | Code Good | Code Bad | Severity | Docs URL |
|----|------------|----------------------------------|--------------------------------------------------|--------------------------------------------------------------------|--------------------------------------------------------------|--------------------------------------------------------------------------|--------------------------------------------------------------------------|------------|-------------------------------------------------------------------------|
| 1 | Setup | Use CLI for installation | Install components via shadcn CLI for proper setup | npx shadcn@latest add component-name | Manual copy-paste from docs | npx shadcn@latest add button | Copy component code manually | High | [shadcn CLI](https://ui.shadcn.com/docs/cli) |
| 2 | Setup | Initialize project properly | Run init command to set up components.json and globals.css | npx shadcn@latest init before adding components | Skip init and add components directly | npx shadcn@latest init | npx shadcn@latest add button (without init) | High | [shadcn Installation](https://ui.shadcn.com/docs/installation) |
| 3 | Setup | Configure path aliases | Set up proper import aliases in tsconfig and components.json | Use @/components/ui path aliases | Relative imports like ../../components | import { Button } from "@/components/ui/button" | import { Button } from "../../components/ui/button" | Medium | [shadcn Installation](https://ui.shadcn.com/docs/installation) |
| 4 | Theming | Use CSS variables for colors | Define colors as CSS variables in globals.css for theming | CSS variables in :root and .dark | Hardcoded color values in components | bg-primary text-primary-foreground | bg-blue-500 text-white | High | [shadcn Theming](https://ui.shadcn.com/docs/theming) |
| 5 | Theming | Follow naming convention | Use semantic color names with foreground pattern | primary/primary-foreground secondary/secondary-foreground | Generic color names | --primary --primary-foreground | --blue --light-blue | Medium | [shadcn Theming](https://ui.shadcn.com/docs/theming) |
| 6 | Theming | Support dark mode | Include .dark class styles for all custom CSS | Define both :root and .dark color schemes | Only light mode colors | .dark { --background: 240 10% 3.9%; } | No .dark class styles | High | [shadcn Dark Mode](https://ui.shadcn.com/docs/dark-mode) |
| 7 | Components | Use component variants | Leverage cva variants for consistent styling | Use variant prop for different styles | Inline conditional classes | <Button variant="destructive"> | <Button className={isError ? "bg-red-500" : "bg-blue-500"}> | Medium | [shadcn Button](https://ui.shadcn.com/docs/components/button) |
| 8 | Components | Compose with className | Add custom classes via className prop for overrides | Extend with className for one-off customizations | Modify component source directly | <Button className="w-full"> | Edit button.tsx to add w-full | Medium | [shadcn Button](https://ui.shadcn.com/docs/components/button) |
| 9 | Components | Use size variants consistently | Apply size prop for consistent sizing across components | size="sm" size="lg" for sizing | Mix size classes inconsistently | <Button size="lg"> | <Button className="text-lg px-8 py-4"> | Medium | [shadcn Button](https://ui.shadcn.com/docs/components/button) |
| 10 | Components | Prefer compound components | Use provided sub-components for complex UI | Card + CardHeader + CardContent pattern | Single component with many props | <Card><CardHeader><CardTitle> | <Card title="x" content="y" footer="z"> | Medium | [shadcn Card](https://ui.shadcn.com/docs/components/card) |
| 11 | Dialog | Use Dialog for modal content | Dialog component for overlay modal windows | Dialog for confirmations forms details | Alert for modal content | <Dialog><DialogContent> | <Alert> styled as modal | High | [shadcn Dialog](https://ui.shadcn.com/docs/components/dialog) |
| 12 | Dialog | Handle dialog state properly | Use open and onOpenChange for controlled dialogs | Controlled state with useState | Uncontrolled with default open only | <Dialog open={open} onOpenChange={setOpen}> | <Dialog defaultOpen={true}> | Medium | [shadcn Dialog](https://ui.shadcn.com/docs/components/dialog) |
| 13 | Dialog | Include proper dialog structure | Use DialogHeader DialogTitle DialogDescription | Complete semantic structure | Missing title or description | <DialogHeader><DialogTitle><DialogDescription> | <DialogContent><p>Content</p></DialogContent> | High | [shadcn Dialog](https://ui.shadcn.com/docs/components/dialog) |
| 14 | Sheet | Use Sheet for side panels | Sheet component for slide-out panels and drawers | Sheet for navigation filters settings | Dialog for side content | <Sheet side="right"> | <Dialog> with slide animation | Medium | [shadcn Sheet](https://ui.shadcn.com/docs/components/sheet) |
| 15 | Sheet | Specify sheet side | Set side prop for sheet slide direction | Explicit side="left" or side="right" | Default side without consideration | <Sheet><SheetContent side="left"> | <Sheet><SheetContent> | Low | [shadcn Sheet](https://ui.shadcn.com/docs/components/sheet) |
| 16 | Form | Use Form with react-hook-form | Integrate Form component with react-hook-form for validation | useForm + Form + FormField pattern | Custom form handling without Form | <Form {...form}><FormField control={form.control}> | <form onSubmit={handleSubmit}> | High | [shadcn Form](https://ui.shadcn.com/docs/components/form) |
| 17 | Form | Use FormField for inputs | Wrap inputs in FormField for proper labeling and errors | FormField + FormItem + FormLabel + FormControl | Input without FormField wrapper | <FormField><FormItem><FormLabel><FormControl><Input> | <Input onChange={...}> | High | [shadcn Form](https://ui.shadcn.com/docs/components/form) |
| 18 | Form | Display form messages | Use FormMessage for validation error display | FormMessage after FormControl | Custom error text without FormMessage | <FormControl><Input/></FormControl><FormMessage/> | <Input/>{error && <span>{error}</span>} | Medium | [shadcn Form](https://ui.shadcn.com/docs/components/form) |
| 19 | Form | Use Zod for validation | Define form schema with Zod for type-safe validation | zodResolver with form schema | Manual validation logic | zodResolver(formSchema) | validate: (values) => { if (!values.email) } | Medium | [shadcn Form](https://ui.shadcn.com/docs/components/form) |
| 20 | Select | Use Select for dropdowns | Select component for option selection | Select for choosing from list | Native select element | <Select><SelectTrigger><SelectContent> | <select><option> | Medium | [shadcn Select](https://ui.shadcn.com/docs/components/select) |
| 21 | Select | Structure Select properly | Include Trigger Value Content and Items | Complete Select structure | Missing SelectValue or SelectContent | <SelectTrigger><SelectValue/></SelectTrigger><SelectContent><SelectItem> | <Select><option> | High | [shadcn Select](https://ui.shadcn.com/docs/components/select) |
| 22 | Command | Use Command for search | Command component for searchable lists and palettes | Command for command palette search | Input with custom dropdown | <Command><CommandInput><CommandList> | <Input><div className="dropdown"> | Medium | [shadcn Command](https://ui.shadcn.com/docs/components/command) |
| 23 | Command | Group command items | Use CommandGroup for categorized items | CommandGroup with heading for sections | Flat list without grouping | <CommandGroup heading="Suggestions"><CommandItem> | <CommandItem> without groups | Low | [shadcn Command](https://ui.shadcn.com/docs/components/command) |
| 24 | Table | Use Table for data display | Table component for structured data | Table for tabular data display | Div grid for table-like layouts | <Table><TableHeader><TableBody><TableRow> | <div className="grid"> | Medium | [shadcn Table](https://ui.shadcn.com/docs/components/table) |
| 25 | Table | Include proper table structure | Use TableHeader TableBody TableRow TableCell | Semantic table structure | Missing thead or tbody | <TableHeader><TableRow><TableHead> | <Table><TableRow> without header | High | [shadcn Table](https://ui.shadcn.com/docs/components/table) |
| 26 | DataTable | Use DataTable for complex tables | Combine Table with TanStack Table for features | DataTable pattern for sorting filtering pagination | Custom table implementation | useReactTable + Table components | Custom sort filter pagination logic | Medium | [shadcn DataTable](https://ui.shadcn.com/docs/components/data-table) |
| 27 | Tabs | Use Tabs for content switching | Tabs component for tabbed interfaces | Tabs for related content sections | Custom tab implementation | <Tabs><TabsList><TabsTrigger><TabsContent> | <div onClick={() => setTab(...)} | Medium | [shadcn Tabs](https://ui.shadcn.com/docs/components/tabs) |
| 28 | Tabs | Set default tab value | Specify defaultValue for initial tab | defaultValue on Tabs component | No default leaving first tab | <Tabs defaultValue="account"> | <Tabs> without defaultValue | Low | [shadcn Tabs](https://ui.shadcn.com/docs/components/tabs) |
| 29 | Accordion | Use Accordion for collapsible | Accordion for expandable content sections | Accordion for FAQ settings panels | Custom collapse implementation | <Accordion><AccordionItem><AccordionTrigger> | <div onClick={() => setOpen(!open)}> | Medium | [shadcn Accordion](https://ui.shadcn.com/docs/components/accordion) |
| 30 | Accordion | Choose accordion type | Use type="single" or type="multiple" appropriately | type="single" for one open type="multiple" for many | Default type without consideration | <Accordion type="single" collapsible> | <Accordion> without type | Low | [shadcn Accordion](https://ui.shadcn.com/docs/components/accordion) |
| 31 | Toast | Use Sonner for toasts | Sonner integration for toast notifications | toast() from sonner for notifications | Custom toast implementation | toast("Event created") | setShowToast(true) | Medium | [shadcn Sonner](https://ui.shadcn.com/docs/components/sonner) |
| 32 | Toast | Add Toaster to layout | Include Toaster component in root layout | <Toaster /> in app layout | Toaster in individual pages | app/layout.tsx: <Toaster /> | page.tsx: <Toaster /> | High | [shadcn Sonner](https://ui.shadcn.com/docs/components/sonner) |
| 33 | Toast | Use toast variants | Apply toast.success toast.error for context | Semantic toast methods | Generic toast for all messages | toast.success("Saved!") toast.error("Failed") | toast("Saved!") toast("Failed") | Medium | [shadcn Sonner](https://ui.shadcn.com/docs/components/sonner) |
| 34 | Popover | Use Popover for floating content | Popover for dropdown menus and floating panels | Popover for contextual actions | Absolute positioned divs | <Popover><PopoverTrigger><PopoverContent> | <div className="relative"><div className="absolute"> | Medium | [shadcn Popover](https://ui.shadcn.com/docs/components/popover) |
| 35 | Popover | Handle popover alignment | Use align and side props for positioning | Explicit alignment configuration | Default alignment for all | <PopoverContent align="start" side="bottom"> | <PopoverContent> | Low | [shadcn Popover](https://ui.shadcn.com/docs/components/popover) |
| 36 | DropdownMenu| Use DropdownMenu for actions | DropdownMenu for action lists and context menus | DropdownMenu for user menu actions | Popover for action lists | <DropdownMenu><DropdownMenuTrigger><DropdownMenuContent> | <Popover> for menu actions | Medium | [shadcn DropdownMenu](https://ui.shadcn.com/docs/components/dropdown-menu) |
| 37 | DropdownMenu| Group menu items | Use DropdownMenuGroup and DropdownMenuSeparator | Organized menu with separators | Flat list of items | <DropdownMenuGroup><DropdownMenuItem><DropdownMenuSeparator> | <DropdownMenuItem> without organization | Low | [shadcn DropdownMenu](https://ui.shadcn.com/docs/components/dropdown-menu) |
| 38 | Tooltip | Use Tooltip for hints | Tooltip for icon buttons and truncated text | Tooltip for additional context | Title attribute for tooltips | <Tooltip><TooltipTrigger><TooltipContent> | <button title="Delete"> | Medium | [shadcn Tooltip](https://ui.shadcn.com/docs/components/tooltip) |
| 39 | Tooltip | Add TooltipProvider | Wrap app or section in TooltipProvider | TooltipProvider at app level | TooltipProvider per tooltip | <TooltipProvider><App/></TooltipProvider> | <Tooltip><TooltipProvider> | High | [shadcn Tooltip](https://ui.shadcn.com/docs/components/tooltip) |
| 40 | Skeleton | Use Skeleton for loading | Skeleton component for loading placeholders | Skeleton matching content layout | Spinner for content loading | <Skeleton className="h-4 w-[200px]"/> | <Spinner/> for card loading | Medium | [shadcn Skeleton](https://ui.shadcn.com/docs/components/skeleton) |
| 41 | Skeleton | Match skeleton dimensions | Size skeleton to match loaded content | Skeleton same size as expected content | Generic skeleton size | <Skeleton className="h-12 w-12 rounded-full"/> | <Skeleton/> without sizing | Medium | [shadcn Skeleton](https://ui.shadcn.com/docs/components/skeleton) |
| 42 | AlertDialog| Use AlertDialog for confirms | AlertDialog for destructive action confirmation | AlertDialog for delete confirmations | Dialog for confirmations | <AlertDialog><AlertDialogTrigger><AlertDialogContent> | <Dialog> for delete confirmation | High | [shadcn AlertDialog](https://ui.shadcn.com/docs/components/alert-dialog) |
| 43 | AlertDialog| Include action buttons | Use AlertDialogAction and AlertDialogCancel | Standard confirm/cancel pattern | Custom buttons in AlertDialog | <AlertDialogCancel>Cancel</AlertDialogCancel><AlertDialogAction> | <Button>Cancel</Button><Button>Confirm</Button> | Medium | [shadcn AlertDialog](https://ui.shadcn.com/docs/components/alert-dialog) |
| 44 | Sidebar | Use Sidebar for navigation | Sidebar component for app navigation | Sidebar for main app navigation | Custom sidebar implementation | <SidebarProvider><Sidebar><SidebarContent> | <div className="w-64 fixed"> | Medium | [shadcn Sidebar](https://ui.shadcn.com/docs/components/sidebar) |
| 45 | Sidebar | Wrap in SidebarProvider | Use SidebarProvider for sidebar state management | SidebarProvider at layout level | Sidebar without provider | <SidebarProvider><Sidebar></SidebarProvider> | <Sidebar> without provider | High | [shadcn Sidebar](https://ui.shadcn.com/docs/components/sidebar) |
| 46 | Sidebar | Use SidebarTrigger | Include SidebarTrigger for mobile toggle | SidebarTrigger for responsive toggle | Custom toggle button | <SidebarTrigger/> | <Button onClick={() => toggleSidebar()}> | Medium | [shadcn Sidebar](https://ui.shadcn.com/docs/components/sidebar) |
| 47 | Chart | Use Chart for data viz | Chart component with Recharts integration | Chart component for dashboards | Direct Recharts without wrapper | <ChartContainer config={chartConfig}> | <ResponsiveContainer><BarChart> | Medium | [shadcn Chart](https://ui.shadcn.com/docs/components/chart) |
| 48 | Chart | Define chart config | Create chartConfig for consistent theming | chartConfig with color definitions | Inline colors in charts | { desktop: { label: "Desktop", color: "#2563eb" } } | <Bar fill="#2563eb"/> | Medium | [shadcn Chart](https://ui.shadcn.com/docs/components/chart) |
| 49 | Chart | Use ChartTooltip | Apply ChartTooltip for interactive charts | ChartTooltip with ChartTooltipContent | Recharts Tooltip directly | <ChartTooltip content={<ChartTooltipContent/>}/> | <Tooltip/> from recharts | Low | [shadcn Chart](https://ui.shadcn.com/docs/components/chart) |
| 50 | Blocks | Use blocks for scaffolding | Start from shadcn blocks for common layouts | npx shadcn@latest add dashboard-01 | Build dashboard from scratch | npx shadcn@latest add login-01 | Custom login page from scratch | Medium | [shadcn Blocks](https://ui.shadcn.com/blocks) |
| 51 | Blocks | Customize block components | Modify copied block code to fit needs | Edit block files after installation | Use blocks without modification | Customize dashboard-01 layout | Use dashboard-01 as-is | Low | [shadcn Blocks](https://ui.shadcn.com/blocks) |
| 52 | A11y | Use semantic components | Shadcn components have built-in ARIA | Rely on component accessibility | Override ARIA attributes | <Button> has button role | <div role="button"> | High | [shadcn Button](https://ui.shadcn.com/docs/components/button) |
| 53 | A11y | Maintain focus management | Dialog Sheet handle focus automatically | Let components manage focus | Custom focus handling | <Dialog> traps focus | document.querySelector().focus() | High | [shadcn Dialog](https://ui.shadcn.com/docs/components/dialog) |
| 54 | A11y | Provide labels | Use FormLabel and aria-label appropriately | FormLabel for form inputs | Placeholder as only label | <FormLabel>Email</FormLabel><Input/> | <Input placeholder="Email"/> | High | [shadcn Form](https://ui.shadcn.com/docs/components/form) |
| 55 | Performance| Import components individually | Import only needed components | Named imports from component files | Import all from index | import { Button } from "@/components/ui/button" | import { Button Card Dialog } from "@/components/ui" | Medium | - |
| 56 | Performance| Lazy load dialogs | Dynamic import for heavy dialog content | React.lazy for dialog content | Import all dialogs upfront | const HeavyContent = lazy(() => import('./Heavy')) | import HeavyContent from './Heavy' | Medium | - |
| 57 | Customization| Extend variants with cva | Add new variants using class-variance-authority | Extend buttonVariants for new styles | Inline classes for variants | variants: { size: { xl: "h-14 px-8" } } | className="h-14 px-8" | Medium | [shadcn Button](https://ui.shadcn.com/docs/components/button) |
| 58 | Customization| Create custom components | Build new components following shadcn patterns | Use cn() and cva for custom components | Different patterns for custom | const Custom = ({ className }) => <div className={cn("base", className)}> | const Custom = ({ style }) => <div style={style}> | Medium | - |
| 59 | Patterns | Use asChild for composition | asChild prop for component composition | Slot pattern with asChild | Wrapper divs for composition | <Button asChild><Link href="/"> | <Button><Link href="/"></Link></Button> | Medium | [shadcn Button](https://ui.shadcn.com/docs/components/button) |
| 60 | Patterns | Combine with React Hook Form | Form + useForm for complete forms | RHF Controller with shadcn inputs | Custom form state management | <FormField control={form.control} name="email"> | <Input value={email} onChange={(e) => setEmail(e.target.value)} | High | [shadcn Form](https://ui.shadcn.com/docs/components/form) |