23 KiB
23 KiB
| 1 | No | Category | Guideline | Description | Do | Don't | Code Good | Code Bad | Severity | Docs URL | Applies To | Status | Verified At |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 1 | Setup | Use CLI for installation | Use CLI v4 to resolve the selected base dependencies and registry items | npx shadcn@latest add component-name | Bypass CLI resolution with stale copied code | npx shadcn@latest add button | Copy an old component implementation | High | https://ui.shadcn.com/docs/cli | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 3 | 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 | https://ui.shadcn.com/docs/installation | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 4 | 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 | https://ui.shadcn.com/docs/installation | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 5 | 4 | Theming | Use CSS variables for colors | Define semantic OKLCH variables in globals.css and expose them to Tailwind v4 with @theme inline | :root and .dark variables plus @theme inline mappings | Hardcode palette colors in components | @theme inline { --color-primary: var(--primary); } | bg-blue-500 text-white | High | https://ui.shadcn.com/docs/theming | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 6 | 5 | Theming | Follow semantic color pairs | Pair each semantic surface token with its foreground token | primary and primary-foreground; secondary and secondary-foreground | Use generic visual names that hide intent | --primary and --primary-foreground | --blue and --light-blue | Medium | https://ui.shadcn.com/docs/theming | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 7 | 6 | Theming | Support dark mode | Override semantic OKLCH variables under .dark for every custom theme token | Define complete :root and .dark semantic schemes | Keep legacy space-separated HSL snippets or omit dark tokens | .dark { --background: oklch(0.145 0 0); } | .dark { --background: 240 10% 3.9%; } | High | https://ui.shadcn.com/docs/dark-mode | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 8 | 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 | https://ui.shadcn.com/docs/components/button | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 9 | 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 | https://ui.shadcn.com/docs/components/button | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 10 | 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 | https://ui.shadcn.com/docs/components/button | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 11 | 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 | https://ui.shadcn.com/docs/components/card | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 12 | 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 | https://ui.shadcn.com/docs/components/dialog | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 13 | 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 | https://ui.shadcn.com/docs/components/dialog | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 14 | 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 | https://ui.shadcn.com/docs/components/dialog | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 15 | 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 | https://ui.shadcn.com/docs/components/sheet | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 16 | 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 | https://ui.shadcn.com/docs/components/sheet | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 17 | 16 | Form | React Hook Form integration | Use a native form with React Hook Form Controller and shadcn Field primitives | useForm + Controller + Field | Depend on the retired FormField-only abstraction | <Controller render={({ field }) => <Field><Input {...field}/></Field>}/> | <FormField control={form.control}> | High | https://ui.shadcn.com/docs/forms/react-hook-form | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 18 | 17 | Form | Use Field for input structure | Compose Field Label and Control for accessible form structure | Field + FieldLabel + Input | Unlabeled input or stale FormItem wrapper | <Field><FieldLabel htmlFor='email'>Email</FieldLabel><Input id='email'/></Field> | <Input placeholder='Email'/> | High | https://ui.shadcn.com/docs/components/field | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 19 | 18 | Form | Display field errors | Render validation messages with FieldError | FieldError with controller fieldState errors | Unassociated custom error text | <FieldError errors={[fieldState.error]}/> | <span>{error.message}</span> | Medium | https://ui.shadcn.com/docs/components/field | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 20 | 19 | Form | Use schema validation | Use a Standard Schema compatible validator such as Zod where it adds value | Zod schema with resolver or form adapter | Assume Zod is the only supported validator | zodResolver(formSchema) | Hand-written divergent client rules | Medium | https://ui.shadcn.com/docs/forms | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 21 | 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 | https://ui.shadcn.com/docs/components/select | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 22 | 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 | https://ui.shadcn.com/docs/components/select | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 23 | 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 | https://ui.shadcn.com/docs/components/command | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 24 | 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 | https://ui.shadcn.com/docs/components/command | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 25 | 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 | https://ui.shadcn.com/docs/components/table | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 26 | 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 | https://ui.shadcn.com/docs/components/table | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 27 | 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 | https://ui.shadcn.com/docs/components/data-table | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 28 | 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 | https://ui.shadcn.com/docs/components/tabs | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 29 | 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 | https://ui.shadcn.com/docs/components/tabs | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 30 | 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 | https://ui.shadcn.com/docs/components/accordion | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 31 | 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 | https://ui.shadcn.com/docs/components/accordion | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 32 | 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 | https://ui.shadcn.com/docs/components/sonner | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 33 | 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 | https://ui.shadcn.com/docs/components/sonner | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 34 | 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 | https://ui.shadcn.com/docs/components/sonner | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 35 | 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 | https://ui.shadcn.com/docs/components/popover | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 36 | 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 | https://ui.shadcn.com/docs/components/popover | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 37 | 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 | https://ui.shadcn.com/docs/components/dropdown-menu | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 38 | 37 | DropdownMenu | Group menu items | Use DropdownMenuGroup and DropdownMenuSeparator | Organized menu with separators | Flat list of items | <DropdownMenuGroup><DropdownMenuItem><DropdownMenuSeparator> | <DropdownMenuItem> without organization | Low | https://ui.shadcn.com/docs/components/dropdown-menu | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 39 | 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 | https://ui.shadcn.com/docs/components/tooltip | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 40 | 39 | Tooltip | Add TooltipProvider | Wrap app or section in TooltipProvider | TooltipProvider at app level | TooltipProvider per tooltip | <TooltipProvider><App/></TooltipProvider> | <Tooltip><TooltipProvider> | High | https://ui.shadcn.com/docs/components/tooltip | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 41 | 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 | https://ui.shadcn.com/docs/components/skeleton | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 42 | 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 | https://ui.shadcn.com/docs/components/skeleton | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 43 | 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 | https://ui.shadcn.com/docs/components/alert-dialog | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 44 | 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 | https://ui.shadcn.com/docs/components/alert-dialog | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 45 | 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 | https://ui.shadcn.com/docs/components/sidebar | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 46 | 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 | https://ui.shadcn.com/docs/components/sidebar | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 47 | 46 | Sidebar | Use SidebarTrigger | Include SidebarTrigger for mobile toggle | SidebarTrigger for responsive toggle | Custom toggle button | <SidebarTrigger/> | <Button onClick={() => toggleSidebar()}> | Medium | https://ui.shadcn.com/docs/components/sidebar | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 48 | 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 | https://ui.shadcn.com/docs/components/chart | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 49 | 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 | https://ui.shadcn.com/docs/components/chart | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 50 | 49 | Chart | Use ChartTooltip | Apply ChartTooltip for interactive charts | ChartTooltip with ChartTooltipContent | Recharts Tooltip directly | <ChartTooltip content={<ChartTooltipContent/>}/> | <Tooltip/> from recharts | Low | https://ui.shadcn.com/docs/components/chart | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 51 | 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 | https://ui.shadcn.com/blocks | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 52 | 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 | https://ui.shadcn.com/blocks | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 53 | 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 | https://ui.shadcn.com/docs/components/button | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 54 | 53 | A11y | Maintain focus management | Dialog Sheet handle focus automatically | Let components manage focus | Custom focus handling | <Dialog> traps focus | document.querySelector().focus() | High | https://ui.shadcn.com/docs/components/dialog | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 55 | 54 | A11y | Provide labels | Use FieldLabel or an explicit accessible name | Associate visible labels with form controls | Placeholder as only label | <FieldLabel htmlFor='email'>Email</FieldLabel><Input id='email'/> | <Input placeholder="Email"/> | High | https://ui.shadcn.com/docs/components/field | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 56 | 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 | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 | |
| 57 | 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 | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 | |
| 58 | 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 | https://ui.shadcn.com/docs/components/button | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 59 | 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 | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 | |
| 60 | 59 | Patterns | Use asChild for Radix composition | Radix-based components support asChild for polymorphic composition | Use asChild only when the installed Radix component exposes it | Assume Base UI or React Aria components share the Radix API | <Button asChild><Link href="/"> | <Button><Link href="/"></Link></Button> | Medium | https://ui.shadcn.com/docs/components/radix/button | shadcn cli 4; base=radix | active | 2026-08-13 |
| 61 | 60 | Form | TanStack Form integration | Use TanStack Form field adapters with shadcn Field primitives when that form library is selected | form.Field + Field + FieldError | Apply React Hook Form Controller APIs to TanStack Form | <form.Field name='email'>{field => <Field><Input value={field.state.value}/></Field>}</form.Field> | <Controller control={form.control}/> | High | https://ui.shadcn.com/docs/forms/tanstack-form | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 62 | 61 | Setup | Select an explicit component base | CLI v4 supports base radix and aria; Base UI is the new-project default while existing projects retain their base | Pin --base in non-interactive automation | Infer that an existing Radix project must migrate | npx shadcn@latest init --base aria | Assume every base supports asChild | High | https://ui.shadcn.com/docs/cli#init | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 63 | 62 | Registry | Use base and font registry item types | Publish base primitives as registry:base and fonts as registry:font so CLI v4 applies them correctly | Explicit registry item types | Publish every artifact as registry:ui | type: 'registry:base' or type: 'registry:font' | type: 'registry:ui' for a base definition | Medium | https://ui.shadcn.com/docs/registry/registry-item-json | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 64 | 63 | Registry | Inspect CLI changes before writing | Use CLI v4 dry-run diff and view plus info and docs to inspect project and registry state | npx shadcn@latest add button --dry-run | Blindly overwrite customized components | npx shadcn@latest add button --diff | npx shadcn@latest add button without review | High | https://ui.shadcn.com/docs/cli#add | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 65 | 64 | Registry | Install public GitHub registries directly | A public repository with root registry.json can be addressed as owner/repo/item | npx shadcn@latest add owner/repo/item | Require a separately hosted generated registry | npx shadcn@latest add acme/ui/button | Copy raw GitHub source files | Medium | https://ui.shadcn.com/docs/registry/getting-started | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 66 | 65 | Setup | Use CLI presets and apply workflows | Use CLI v4 preset and apply for repeatable project configuration | npx shadcn@latest preset then apply | Manually reproduce a saved project setup | npx shadcn@latest apply <preset> | Copy configuration by hand | Medium | https://ui.shadcn.com/docs/cli | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 67 | 66 | Registry | Keep registry source declarations | Configure namespaced registry URLs and required headers in components.json | Use registries map with environment variables | Hardcode private registry secrets in source | registries: { '@acme': { url: '${REGISTRY_URL}/{name}.json' } } | Commit bearer tokens | High | https://ui.shadcn.com/docs/registry/namespace | shadcn cli 4; base=base|radix|aria | active | 2026-08-13 |
| 68 | 67 | Patterns | Preserve React Aria link semantics | Style a semantic anchor with buttonVariants when navigation is intended | Use an anchor for a link and a button for an action | Render a React Aria Button that masquerades as a link | <a href="/docs" className={buttonVariants()}>Docs</a> | <Button onPress={() => navigate('/docs')}>Docs</Button> | High | https://ui.shadcn.com/docs/components/aria/button | shadcn cli 4; base=aria | active | 2026-08-13 |
| 69 | 68 | Patterns | Use render for Base UI composition | Base UI components compose another element through the render prop rather than Radix asChild | Use render with the intended semantic element | Pass the Radix-only asChild prop to a Base UI component | <Button render={<a href="/docs" />}>Docs</Button> | <Button asChild><a href="/docs">Docs</a></Button> | High | https://ui.shadcn.com/docs/components/base/button | shadcn cli 4; base=base | active | 2026-08-13 |