(schema: T) {
const { toast } = useToast()
const form = useForm({
resolver: zodResolver(schema),
})
const handleSubmit = form.handleSubmit(async (data) => {
try {
// Submit logic
toast({ title: "Success!" })
} catch (error) {
toast({ title: "Error", variant: "destructive" })
}
})
return { form, handleSubmit }
}
```
### Responsive Design
```tsx
// Mobile-first responsive components
Mobile: 1 col, Tablet: 2 col, Desktop: 3 col
// Responsive dialog (sheet on mobile, dialog on desktop)
import { useMediaQuery } from "@/hooks/use-media-query"
import { Dialog, DialogContent } from "@/components/ui/dialog"
import { Sheet, SheetContent } from "@/components/ui/sheet"
function ResponsiveModal({ children, ...props }) {
const isDesktop = useMediaQuery("(min-width: 768px)")
if (isDesktop) {
return (
)
}
return (
{children}
)
}
```
### Animation Variants
```tsx
// Using Framer Motion with shadcn/ui
import { motion } from "framer-motion"
import { Card } from "@/components/ui/card"
const MotionCard = motion(Card)
Animated Card
// Staggered list animation
const container = {
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
staggerChildren: 0.1
}
}
}
const item = {
hidden: { opacity: 0, y: 20 },
show: { opacity: 1, y: 0 }
}
{items.map((item) => (
{item.content}
))}
```
## Best Practices
**Code Organization**:
- Keep shadcn/ui components in `components/ui/` (don't mix with app components)
- Create custom compositions in `components/` (outside ui/)
- Use `lib/utils.ts` for shared utilities
**Customization**:
- Modify components directly in your project (you own the code)
- Use CSS variables for theme-wide changes
- Extend variants with CVA for new styles
- Don't edit `components.json` manually (use CLI)
**Performance**:
- Tree-shaking automatic (only imports what you use)
- Use `asChild` to avoid unnecessary wrapper elements
- Lazy load heavy components (Calendar, Command)
- Prefer Server Components when possible (Next.js)
**Accessibility**:
- Don't remove ARIA attributes from components
- Test keyboard navigation for custom compositions
- Maintain focus management in dialogs/modals
- Use semantic HTML with `asChild` when applicable
**TypeScript**:
- Leverage exported types (ButtonProps, CardProps, etc.)
- Use VariantProps for variant type safety
- Add strict null checks for form validation
## Troubleshooting
**Import errors**:
```bash
# Check path aliases in tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
```
**Tailwind classes not applying**:
```ts
// Ensure content paths include your components
// tailwind.config.ts
content: [
'./src/components/**/*.{ts,tsx}', // Add this
'./src/app/**/*.{ts,tsx}',
]
```
**Dark mode not working**:
```tsx
// Add suppressHydrationWarning to
```
**Form validation not triggering**:
```tsx
// Ensure FormMessage is included in FormField
...
{/* Required for errors */}
```
## Resources
- **Official Docs**: https://ui.shadcn.com
- **Component Source**: https://github.com/shadcn-ui/ui
- **Radix UI Docs**: https://www.radix-ui.com
- **Tailwind CSS**: https://tailwindcss.com
- **CVA Docs**: https://cva.style/docs
- **Examples**: https://ui.shadcn.com/examples
- **Community**: https://discord.gg/shadcn-ui