| name | component-audit |
| description | Audit of existing Vue components in the project. Use when reviewing Vue design system consistency, identifying duplicate patterns, evaluating legacy components (Options API), or before implementing something new.
|
Skill: Component Audit — Vue 3
Audit protocol
1. Inventory
find components/ src/components/ -name "*.vue" | grep -v node_modules | sort
ls components/ui/ 2>/dev/null || ls src/components/ui/ 2>/dev/null
find composables/ src/composables/ -name "*.ts" 2>/dev/null | sort
2. Identify problematic patterns
grep -rl "export default {" components/ --include="*.vue" 2>/dev/null
grep -rL "script setup" components/ --include="*.vue" 2>/dev/null | grep -v ui/
grep -rl "script setup>" components/ --include="*.vue" 2>/dev/null | \
grep -v "lang=\"ts\""
grep -rn "#[0-9A-Fa-f]\{6\}" components/ --include="*.vue" 2>/dev/null | \
grep -v "ui/"
grep -rn "style=\"" components/ --include="*.vue" 2>/dev/null | grep -v "ui/"
grep -rn ": any" components/ --include="*.vue" 2>/dev/null | grep -v "ui/"
3. Quality checklist per SFC
Vue 3 Structure
Design System
States
Minimum accessibility
4. Output → .planning/ui/component-log.md
## Component Audit — [date]
### Inventory
| Component | File | shadcn-vue base | Issues |
|---|---|---|---|
| UserCard | components/user/UserCard.vue | Card | No Skeleton, Options API |
### Legacy components (Options API)
[list for gradual migration]
### Duplicate patterns
- Pattern "Header with avatar + title" in 4 files → extract component
### Hardcoded tokens found
- UserCard.vue:45 — `color: #6B7280` → use `text-muted-foreground`
### Missing states
- UserList.vue — no `<Empty>` state
- OrderCard.vue — no loading skeleton
### Recommendations
1. [specific and actionable]
Problematic patterns in Vue + shadcn-vue
Options API → Composition API
<!-- ❌ Legacy Options API -->
<script>
export default {
data() { return { count: 0 } },
methods: { increment() { this.count++ } }
}
</script>
<!-- ✅ Composition API with script setup -->
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
const increment = () => count.value++
</script>
Conditional classes without cn()
<!-- ❌ Template literal — does not merge Tailwind correctly -->
<div :class="`base-class ${isActive ? 'active' : ''}`" />
<!-- ✅ cn() with tailwind-merge -->
<div :class="cn('base-class', isActive && 'bg-primary text-primary-foreground')" />
Missing :class prop
<!-- ❌ Not extensible -->
<div class="flex gap-4">
<!-- ✅ Always accept external class -->
<script setup lang="ts">
const props = defineProps<{ class?: string }>()
</script>
<template>
<div :class="cn('flex gap-4', props.class)">
</template>
Skeleton with wrong dimensions
<!-- ❌ Generic skeleton — causes layout shift -->
<Skeleton class="h-4 w-full" /> <!-- but the content is h-32 -->
<!-- ✅ Skeleton mirrors the actual content -->
<Card v-if="isLoading">
<CardHeader>
<Skeleton class="h-5 w-3/4" />
<Skeleton class="h-4 w-1/2 mt-2" />
</CardHeader>
<CardContent>
<Skeleton class="h-32 w-full" />
</CardContent>
</Card>