--- name: shadcn-framer description: ShadCN UI + Framer Motion patterns. --- # ShadCN + Framer Motion ## ShadCN Setup ```bash pnpm dlx shadcn@latest init pnpm dlx shadcn@latest add button card dialog ``` ## Component Usage ```typescript import { Button } from '@/components/ui/button'; import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, } from '@/components/ui/card'; export function UserCard({ user }: { user: User }) { return ( {user.name} {user.email}

{user.bio}

); } ``` ## Framer Motion Basics ```typescript 'use client'; import { motion } from 'framer-motion'; export function FadeIn({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` ## Animated List ```typescript 'use client'; import { motion, AnimatePresence } from 'framer-motion'; const container = { hidden: { opacity: 0 }, show: { opacity: 1, transition: { staggerChildren: 0.1 }, }, }; const item = { hidden: { opacity: 0, x: -20 }, show: { opacity: 1, x: 0 }, }; export function AnimatedList({ items }: { items: Item[] }) { return ( {items.map((i) => ( {i.name} ))} ); } ``` ## Page Transitions ```typescript // components/page-transition.tsx 'use client'; import { motion } from 'framer-motion'; export function PageTransition({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` ## Animated Dialog ```typescript 'use client'; import { motion, AnimatePresence } from 'framer-motion'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; export function AnimatedDialog({ open, onOpenChange, children, }: { open: boolean; onOpenChange: (open: boolean) => void; children: React.ReactNode; }) { return ( {open && ( {children} )} ); } ``` ## Hover Effects ```typescript 'use client'; import { motion } from 'framer-motion'; import { Card } from '@/components/ui/card'; export function HoverCard({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` ## Loading Skeleton with Pulse ```typescript 'use client'; import { motion } from 'framer-motion'; export function Skeleton({ className }: { className?: string }) { return ( ); } ```