shadcn-ui
shadcn/ui component patterns for Next.js 16 applications. This skill should be used when adding UI components, customizing component styles, composing primitives, or integrating forms with react-hook-form. Covers installation, customization, composition patterns, and Atlas-specific conventions using Tailwind CSS v4.
Install
mkdir -p .claude/skills/shadcn-ui && curl -L -o skill.zip "https://mcp.directory/api/skills/download/278" && unzip -o skill.zip -d .claude/skills/shadcn-ui && rm skill.zipInstalls to .claude/skills/shadcn-ui
About this skill
shadcn/ui Component Usage
Purpose
Provide comprehensive patterns for implementing shadcn/ui components in Next.js 16 applications with Atlas-specific conventions. Focus on composition over props, accessibility-first design, and type-safe integration with tRPC and react-hook-form.
When To Use This Skill
Component Implementation:
- Adding new shadcn/ui components to the project
- Customizing component variants and styles
- Building composite components from primitives (Dialog, Form, Table)
- Implementing responsive mobile/desktop patterns
Form Integration:
- Integrating react-hook-form with shadcn Form components
- Validating forms with Zod schemas
- Connecting forms to tRPC mutations
- Handling form state and errors
Data Display:
- Creating data tables with sorting and filtering
- Building card layouts and list views
- Implementing skeleton loading states
Interactive Patterns:
- Building modal dialogs and drawers (sheets)
- Implementing toast notifications
- Creating dropdown menus and popovers
- Adding tooltips and hover states
Accessibility:
- Ensuring keyboard navigation works correctly
- Adding proper ARIA labels (especially icon buttons)
- Implementing focus management
- Meeting WCAG 2.1 AAA standards (44px minimum touch targets)
Core Principles
1. Copy-Not-Import Philosophy
shadcn/ui components are copied into the project, not imported as dependencies. Customize directly in src/components/ui/.
// ✅ Customize directly
// src/components/ui/button.tsx
const buttonVariants = cva("...", {
variants: {
variant: {
default: "bg-primary text-primary-foreground",
// Add your custom variant
atlas: "bg-blue-600 text-white hover:bg-blue-700",
},
},
});
2. Composition Over Props
Build complex components by composing primitives rather than adding props:
// ❌ Avoid: Too many props
<Dialog
title="Delete Item"
description="Are you sure?"
showCloseButton={true}
size="lg"
/>
// ✅ Prefer: Composition
<Dialog>
<DialogContent>
<DialogHeader>
<DialogTitle>Delete Item</DialogTitle>
<DialogDescription>Are you sure?</DialogDescription>
</DialogHeader>
</DialogContent>
</Dialog>
3. className Customization
Extend styles via className prop using Tailwind utilities:
<Button variant="default" className="w-full sm:w-auto shadow-lg">
Submit
</Button>
4. Accessibility First
All components are accessible by default (built on Radix UI):
- Keyboard navigation
- Screen reader support
- ARIA attributes
- Focus management
Icon buttons require labels for accessibility:
// ❌ Inaccessible
<Button size="icon">
<TrashIcon />
</Button>
// ✅ Accessible
<Button size="icon" aria-label="Delete item">
<TrashIcon />
</Button>
Quick Reference
Common Components
| Component | Use Case | Key Features |
|---|---|---|
Button | Actions, triggers | Variants, sizes, loading state |
Input | Text entry | Types, validation states |
Form | Form validation | react-hook-form integration |
Dialog | Modals | Portal, overlay, animations |
Sheet | Side panels | Mobile-friendly drawers |
Table | Data display | Semantic HTML, responsive |
Select | Dropdowns | Searchable, keyboard nav |
Checkbox | Boolean input | Indeterminate state |
Label | Form labels | Auto-linked to inputs |
Textarea | Multi-line input | Auto-resize support |
Tabs | Navigation | Keyboard accessible |
Card | Content containers | Header, content, footer |
Badge | Status labels | Variants for states |
Skeleton | Loading states | Placeholder UI |
Separator | Visual dividers | Horizontal/vertical |
Dropdown Menu | Actions menu | Nested menus, shortcuts |
Alert | Notifications | Info, warning, error |
Progress | Loading indicators | Determinate/indeterminate |
Tooltip | Hover hints | Delay, positioning |
Button Variants & Sizes
<Button variant="default">Primary Action</Button>
<Button variant="secondary">Secondary Action</Button>
<Button variant="outline">Outlined</Button>
<Button variant="ghost">Subtle</Button>
<Button variant="destructive">Delete</Button>
<Button variant="link">Link Style</Button>
<Button size="sm">Small</Button> {/* 32px mobile, 40px desktop */}
<Button size="default">Default</Button> {/* 44px mobile, 36px desktop */}
<Button size="lg">Large</Button> {/* 48px mobile, 40px desktop */}
<Button size="icon" aria-label="Add"> {/* 44x44px - WCAG 2.1 AAA */}
<PlusIcon />
</Button>
Loading States
<Button loading={isPending} loadingText="Saving...">
Save Changes
</Button>
// Or manually:
<Button disabled={isPending}>
{isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
Save Changes
</Button>
Form Integration
Basic Form Pattern
"use client";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
const schema = z.object({
email: z.string().email(),
name: z.string().min(2),
});
type FormValues = z.infer<typeof schema>;
export function MyFormClient() {
const form = useForm<FormValues>({
resolver: zodResolver(schema),
defaultValues: { email: "", name: "" },
});
const onSubmit = form.handleSubmit(async (data) => {
// Handle submission
});
return (
<Form {...form}>
<form onSubmit={onSubmit} className="space-y-4">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" placeholder="[email protected]" {...field} />
</FormControl>
<FormDescription>We'll never share your email.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit" loading={form.formState.isSubmitting}>
Submit
</Button>
</form>
</Form>
);
}
Form with tRPC Mutation
"use client";
import { api } from "@/lib/api/react";
import { toast } from "sonner";
export function CreateStackFormClient() {
const form = useForm<FormValues>({
resolver: zodResolver(schema),
defaultValues: {
/* ... */
},
});
const utils = api.useUtils();
const createMutation = api.stacks.create.useMutation({
onSuccess: () => {
toast.success("Stack created successfully");
utils.stacks.list.invalidate(); // Refetch list
form.reset();
},
onError: (error) => {
toast.error(error.message);
},
});
const onSubmit = form.handleSubmit((data) => {
createMutation.mutate(data);
});
return (
<Form {...form}>
<form onSubmit={onSubmit} className="space-y-4">
{/* Form fields */}
<Button
type="submit"
loading={createMutation.isPending}
disabled={createMutation.isPending}
>
Create Stack
</Button>
</form>
</Form>
);
}
Common Form Field Patterns
Number Input:
<FormField
control={form.control}
name="quantity"
render={({ field }) => (
<FormItem>
<FormLabel>Quantity</FormLabel>
<FormControl>
<Input
type="number"
inputMode="numeric"
placeholder="100"
{...field}
onChange={(e) => field.onChange(e.target.valueAsNumber)}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
Date Input:
<FormField
control={form.control}
name="scheduledFor"
render={({ field: { value, onChange, ...field } }) => (
<FormItem>
<FormLabel>Scheduled Date</FormLabel>
<FormControl>
<Input
type="date"
{...field}
value={value instanceof Date ? value.toISOString().split("T")[0] : ""}
onChange={(e) => {
const dateStr = e.target.value;
if (dateStr) onChange(new Date(dateStr));
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
Select/Dropdown:
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
<FormField
control={form.control}
name="status"
render={({ field }) => (
<FormItem>
<FormLabel>Status</FormLabel>
<Select onValueChange={field.onChange} defaultValue={field.value}>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Select a status" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="active">Active</SelectItem>
<SelectItem value="inactive">Inactive</SelectItem>
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>;
Textarea:
import { Textarea } from "@/components/ui/textarea";
<FormField
control={form.control}
name="notes"
render={({ field }) => (
<FormItem>
<FormLabel>Notes</FormLabel>
<FormControl>
<Textarea placeholder="Optional notes..." maxLength={1000} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>;
Content truncated.
You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
pdf-to-markdown
aliceisjustplaying
Convert entire PDF documents to clean, structured Markdown for full context loading. Use this skill when the user wants to extract ALL text from a PDF into context (not grep/search), when discussing or analyzing PDF content in full, when the user mentions "load the whole PDF", "bring the PDF into context", "read the entire PDF", or when partial extraction/grepping would miss important context. This is the preferred method for PDF text extraction over page-by-page or grep approaches.
Related MCP Servers
Browse all serversMCP server connects Claude and AI coding tools to shadcn/ui components. Accurate TypeScript props and React component da
Explore Magic UI, a React UI library offering structured component access, code suggestions, and installation guides for
Quickly rp prototype web apps with Scaffold Generator: create consistent scaffolding using templates, variable substitut
Access 135+ animated React UI components from ReactBits.dev with intelligent caching, dependency detection, and quality
Search Vaadin docs and get component usage guidance for Vaadin Java and React apps—fast, accurate answers and examples.
Browse, retrieve, and install e-commerce React UI components from Stackzero Labs’ react component library. Easy integrat
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.