This skill should be used when reviewing shadcn/ui component usage to ensure accessibility, consistency, and proper patterns. Applies when auditing UI code, checking component patterns, reviewing layout structure, identifying component extraction opportunities, or ensuring design system compliance. Trigger terms include audit UI, review components, check shadcn, accessibility audit, component review, UI patterns, design system compliance, layout review, refactor components, extract component.
Audits shadcn/ui components for accessibility, consistency, and proper patterns. Triggers when reviewing UI code, checking component usage, or ensuring design system compliance.
/plugin marketplace add hopeoverture/worldbuilding-app-skills/plugin install ui-library-usage-auditor@worldbuilding-app-skillsThis skill is limited to using the following tools:
references/audit-checklist.mdReview and audit shadcn/ui component usage across the codebase to ensure accessible, consistent, and maintainable UI patterns. This skill identifies issues, suggests improvements, and recommends component extractions or layout optimizations.
Apply this skill when:
Check for:
Check for:
Identify:
Review:
Verify:
Use Glob to identify all component files:
# Find all component files
Glob: **/*.tsx
Glob: app/**/*.tsx
Glob: components/**/*.tsx
Search for common patterns and potential issues:
# Find form implementations
Grep: pattern="<form" output_mode="files_with_matches"
# Find button usage
Grep: pattern="<Button" output_mode="files_with_matches"
# Find ARIA usage
Grep: pattern="aria-" output_mode="content"
# Find inline styles
Grep: pattern='style=' output_mode="files_with_matches"
# Find accessibility issues
Grep: pattern="<img" output_mode="content" # Check for alt text
Grep: pattern="onClick.*<div" output_mode="content" # Div as button antipattern
# Find repeated patterns
Grep: pattern="className=\".*flex.*items-center.*gap" output_mode="count"
Read identified files to perform detailed analysis:
Read: /path/to/component.tsx
Analyze for:
Create structured report with findings organized by:
Problem:
<Input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
Solution:
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
Problem:
<div onClick={handleClick} className="cursor-pointer">
Click me
</div>
Solution:
<Button onClick={handleClick}>
Click me
</Button>
Problem:
<img src="/avatar.jpg" className="rounded-full" />
Solution:
<img
src="/avatar.jpg"
alt="User profile avatar"
className="rounded-full"
/>
Problem:
// File 1
<div className="flex gap-4">
// File 2
<div className="flex gap-2">
// File 3
<div className="flex space-x-3">
Solution:
// Standardize spacing scale
<div className="flex gap-4"> // Use consistent gap values (2, 4, 6, 8)
Problem:
// Repeated in multiple files
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<Avatar>
<AvatarImage src={user.avatar} />
<AvatarFallback>{user.initials}</AvatarFallback>
</Avatar>
<div>
<CardTitle>{user.name}</CardTitle>
<CardDescription>{user.role}</CardDescription>
</div>
</div>
<DropdownMenu>
{/* Menu items */}
</DropdownMenu>
</div>
</CardHeader>
</Card>
Solution: Extract to reusable component:
// components/UserCard.tsx
export function UserCard({ user }: UserCardProps) {
return (
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<Avatar>
<AvatarImage src={user.avatar} alt={user.name} />
<AvatarFallback>{user.initials}</AvatarFallback>
</Avatar>
<div>
<CardTitle>{user.name}</CardTitle>
<CardDescription>{user.role}</CardDescription>
</div>
</div>
<UserMenu user={user} />
</div>
</CardHeader>
</Card>
)
}
Problem:
<div className="page">
<h1>Dashboard</h1>
<div className="section">
<h3>Recent Activity</h3> {/* Skipped h2 */}
</div>
</div>
Solution:
<div className="page">
<h1>Dashboard</h1>
<div className="section">
<h2>Recent Activity</h2> {/* Proper hierarchy */}
</div>
</div>
Problem:
<Button onClick={handleSubmit}>
Submit
</Button>
Solution:
<Button onClick={handleSubmit} disabled={isSubmitting}>
{isSubmitting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Submitting...
</>
) : (
'Submit'
)}
</Button>
Problem:
// Mixing different error patterns
{error && <p className="text-red-500">{error}</p>}
{error && <span style={{ color: 'red' }}>{error}</span>}
{error && <Alert variant="destructive">{error}</Alert>}
Solution:
// Standardize on Alert component
{error && (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertDescription>{error}</AlertDescription>
</Alert>
)}
Generate audit reports using this structure:
# UI Library Usage Audit Report
**Generated:** [Date]
**Scope:** [Files/directories audited]
**Total Components Reviewed:** [Count]
## Executive Summary
[Brief overview of findings and overall code health]
## Critical Issues (Must Fix)
### 1. Accessibility Violations
- **Issue:** Missing alt text on images
- **Files:** `app/characters/[id]/page.tsx:45`, `components/CharacterCard.tsx:23`
- **Fix:** Add descriptive alt attributes to all images
- **Priority:** High
- **Issue:** Form inputs without labels
- **Files:** `app/create-location/page.tsx:78`
- **Fix:** Wrap inputs in FormField with FormLabel
- **Priority:** High
### 2. Broken Patterns
- **Issue:** Divs used as buttons with onClick handlers
- **Files:** `components/Navigation.tsx:34`, `app/timeline/page.tsx:102`
- **Fix:** Replace with Button component
- **Priority:** High
## Warnings (Should Fix)
### 1. Inconsistent Patterns
- **Issue:** Mixed spacing scales (gap-2, gap-3, gap-4, space-x-2)
- **Occurrences:** 47 instances across 23 files
- **Recommendation:** Standardize on gap-{2,4,6,8} scale
- **Priority:** Medium
- **Issue:** Inconsistent loading states
- **Files:** `app/characters/actions.ts`, `app/locations/actions.ts`
- **Recommendation:** Create shared LoadingButton component
- **Priority:** Medium
### 2. Component Duplication
- **Issue:** Character card pattern repeated 5 times
- **Files:** Multiple files listed
- **Recommendation:** Extract CharacterCard component
- **Priority:** Medium
## Suggestions (Consider)
### 1. Component Extraction Opportunities
#### EntityCard Component
**Occurrences:** 8 similar patterns
**Files:**
- `app/characters/page.tsx:67-89`
- `app/locations/page.tsx:54-76`
- `app/items/page.tsx:43-65`
**Proposed Component:**
```tsx
interface EntityCardProps {
title: string
description: string
image?: string
tags?: string[]
actions?: ReactNode
}
export function EntityCard({ ... }: EntityCardProps) {
// Unified card implementation
}
Occurrences: 12 similar patterns Recommendation: Extract reusable form section with heading and fields
Issue: Inconsistent container max-width
Issue: Missing responsive breakpoints
app/timeline/page.tsx, components/WorldMap.tsxOverall Score: 72/100
Immediate (This Week)
Short-term (This Month)
Long-term (This Quarter)
## Automation with Scripts
Use references/audit-checklist.md for comprehensive checklist of items to verify during audit.
## Best Practices for Auditing
1. **Start Broad, Then Focus**: Begin with file scanning, then drill into specific issues
2. **Prioritize by Impact**: Accessibility issues > Broken patterns > Inconsistencies > Optimizations
3. **Provide Context**: Include file paths, line numbers, and code snippets
4. **Suggest Solutions**: Don't just identify problems, provide concrete fixes
5. **Quantify Issues**: Use metrics to show scope and track improvement
6. **Group Related Issues**: Cluster similar problems for efficient fixing
7. **Consider User Impact**: Prioritize issues affecting end-user experience
8. **Balance Perfection vs Pragmatism**: Focus on high-value improvements
## Common Grep Patterns for Auditing
```bash
# Find potential accessibility issues
Grep: pattern="<img(?![^>]*alt=)" output_mode="files_with_matches"
Grep: pattern="onClick.*<(div|span)" output_mode="content"
Grep: pattern="<input(?![^>]*aria-label)" output_mode="content"
# Find inconsistent patterns
Grep: pattern="className=\"[^\"]*gap-[13579]" output_mode="count"
Grep: pattern="style=" output_mode="files_with_matches"
# Find component usage
Grep: pattern="from ['\"]@/components/ui" output_mode="content"
Grep: pattern="<Button" output_mode="count"
Grep: pattern="<Form" output_mode="count"
# Find potential duplications
Grep: pattern="<Card>" -A 10 output_mode="content"
Grep: pattern="className=\".*flex.*items-center.*justify-between" output_mode="count"
# Find error handling patterns
Grep: pattern="(error|Error)" output_mode="content"
Grep: pattern="toast\\." output_mode="content"
# Find loading states
Grep: pattern="(isLoading|loading|isPending)" output_mode="content"
Check for consistent entity card layouts across:
Audit form consistency for:
Review accessibility of:
Use audit findings to:
After implementing fixes: