Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Build React UIs using shadcn/ui components with Tailwind CSS, Radix primitives, and proper accessibility patterns.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/customization.md
1# shadcn/ui - Customization23## Theming with CSS Variables45shadcn/ui uses CSS variables for theming. Customize in `globals.css`:67```css8@layer base {9:root {10--background: 0 0% 100%;11--foreground: 222.2 84% 4.9%;12--primary: 222.2 47.4% 11.2%;13--primary-foreground: 210 40% 98%;14--secondary: 210 40% 96.1%;15--secondary-foreground: 222.2 47.4% 11.2%;16--muted: 210 40% 96.1%;17--muted-foreground: 215.4 16.3% 46.9%;18--accent: 210 40% 96.1%;19--accent-foreground: 222.2 47.4% 11.2%;20--destructive: 0 84.2% 60.2%;21--destructive-foreground: 210 40% 98%;22--border: 214.3 31.8% 91.4%;23--input: 214.3 31.8% 91.4%;24--ring: 222.2 84% 4.9%;25--radius: 0.5rem;26}2728.dark {29--background: 222.2 84% 4.9%;30--foreground: 210 40% 98%;31--primary: 210 40% 98%;32--primary-foreground: 222.2 47.4% 11.2%;33/* ... other dark mode variables */34}35}36```3738## Adding Custom Variants to Button3940Since you own the code, extend components directly:4142```tsx43// components/ui/button.tsx44import * as React from "react"45import { Slot } from "@radix-ui/react-slot"46import { cva, type VariantProps } from "class-variance-authority"47import { cn } from "@/lib/utils"4849const buttonVariants = cva(50"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",51{52variants: {53variant: {54default: "bg-primary text-primary-foreground hover:bg-primary/90",55destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",56outline: "border border-input bg-background hover:bg-accent",57// Add custom variant58custom: "bg-gradient-to-r from-purple-500 to-pink-500 text-white",59},60size: {61default: "h-10 px-4 py-2",62sm: "h-9 rounded-md px-3",63lg: "h-11 rounded-md px-8",64// Add custom size65xl: "h-14 rounded-md px-10 text-lg",66},67},68defaultVariants: {69variant: "default",70size: "default",71},72}73)7475export interface ButtonProps76extends React.ButtonHTMLAttributes<HTMLButtonElement>,77VariantProps<typeof buttonVariants> {78asChild?: boolean79}8081const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(82({ className, variant, size, asChild = false, ...props }, ref) => {83const Comp = asChild ? Slot : "button"84return (85<Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />86)87}88)89Button.displayName = "Button"9091export { Button, buttonVariants }92```9394## Custom Color Themes9596To use a custom brand color as primary:9798```css99@layer base {100:root {101/* Custom brand color (blue) */102--primary: 217 91% 60%;103--primary-foreground: 0 0% 100%;104105/* Custom accent (purple) */106--accent: 270 67% 47%;107--accent-foreground: 0 0% 100%;108}109}110```111112## cn() Utility Function113114The `cn()` utility combines `clsx` and `tailwind-merge` for conditional class names:115116```tsx117// lib/utils.ts118import { type ClassValue, clsx } from "clsx"119import { twMerge } from "tailwind-merge"120121export function cn(...inputs: ClassValue[]) {122return twMerge(clsx(inputs))123}124125// Usage examples126cn("px-4 py-2", isActive && "bg-primary text-white")127cn("text-sm", size === "lg" && "text-lg", className)128```129130## Extending a Component131132Create wrapper components to add functionality without modifying the base:133134```tsx135// components/ui/loading-button.tsx136"use client"137import { Button, ButtonProps } from "@/components/ui/button"138import { Loader2 } from "lucide-react"139140interface LoadingButtonProps extends ButtonProps {141loading?: boolean142}143144export function LoadingButton({ loading, children, disabled, ...props }: LoadingButtonProps) {145return (146<Button disabled={loading || disabled} {...props}>147{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}148{children}149</Button>150)151}152153// Usage154<LoadingButton loading={isSubmitting} type="submit">155Save Changes156</LoadingButton>157```158159## components.json Configuration160161The `components.json` file controls CLI behavior:162163```json164{165"$schema": "https://ui.shadcn.com/schema.json",166"style": "default",167"rsc": true,168"tsx": true,169"tailwind": {170"config": "tailwind.config.js",171"css": "app/globals.css",172"baseColor": "slate",173"cssVariables": true,174"prefix": ""175},176"aliases": {177"components": "@/components",178"utils": "@/lib/utils",179"ui": "@/components/ui",180"lib": "@/lib",181"hooks": "@/hooks"182}183}184```185186> **Security**: Only use trusted registry URLs in `components.json`. Never point to untrusted third-party registry endpoints.187