This skill provides best practices for using Shadcn Vue components in the fitness app. Use when working with UI components, forms, dialogs, or implementing component patterns.
Provides best practices for using Shadcn Vue components with UI prefix naming and semantic colors.
/plugin marketplace add josephanson/claude-plugin/plugin install ja@josephansonThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/component-patterns.mdreferences/dialog-pattern.mdreferences/form-validation.mdThis skill provides guidance for using Shadcn Vue components effectively in the fitness application.
Component Naming: All Shadcn Vue components are prefixed with UI (e.g., UIButton, UIDialog, UICard, UIInput). This is enforced across the entire codebase for consistency.
Semantic Colors: Use CSS variables for theming instead of arbitrary Tailwind colors:
bg-background, text-foreground - Base colorsbg-primary, text-primary-foreground - Primary actionsbg-secondary, text-secondary-foreground - Secondary elementsbg-muted, text-muted-foreground - Subtle backgroundsbg-accent, text-accent-foreground - Highlightsbg-destructive, text-destructive-foreground - Errors/delete actionsbg-card, text-card-foreground - Card backgroundsborder-border, ring-ring - Borders and focus ringsDocumentation: When looking up shadcn components, use the pattern: https://www.shadcn-vue.com/docs/components/{component}.html where {component} is the component name (e.g., tooltip, button, dialog).
NEVER use refs to manage dialog state. Use the v-slot="{ close }" pattern:
<UIDialog v-slot="{ close }">
<UIDialogTrigger as-child>
<UIButton>Open Dialog</UIButton>
</UIDialogTrigger>
<UIDialogContent>
<UIDialogHeader>
<UIDialogTitle>Dialog Title</UIDialogTitle>
<UIDialogDescription>Description text</UIDialogDescription>
</UIDialogHeader>
<!-- Content -->
<UIDialogFooter>
<UIButton variant="outline" @click="close">Cancel</UIButton>
<UIButton @click="handleSubmit(); close()">Save</UIButton>
</UIDialogFooter>
</UIDialogContent>
</UIDialog>
For detailed dialog patterns including multiple dialogs and form integration, see references/dialog-pattern.md.
All forms MUST use vee-validate with Zod schemas. Never create forms without schema validation.
Basic pattern:
<script setup lang="ts">
import { toTypedSchema } from '@vee-validate/zod'
import { z } from 'zod'
import { useForm } from 'vee-validate'
const formSchema = toTypedSchema(z.object({
name: z.string().min(2).max(50),
email: z.email(),
}))
const { handleSubmit } = useForm({ validationSchema: formSchema })
const onSubmit = handleSubmit((values) => {
// Handle form submission
})
</script>
<template>
<form @submit="onSubmit">
<UIFormField v-slot="{ componentField }" name="name">
<UIFormItem>
<UIFormLabel>Name</UIFormLabel>
<UIFormControl>
<UIInput type="text" v-bind="componentField" />
</UIFormControl>
<UIFormMessage />
</UIFormItem>
</UIFormField>
<UIButton type="submit">Submit</UIButton>
</form>
</template>
For complete form patterns and advanced validation, see references/form-validation.md.
Components follow a folder-based structure:
components/
├── {Feature}/
│ ├── Form/
│ │ ├── Create.vue # Creation form
│ │ ├── Edit.vue # Edit form
│ │ └── Delete.vue # Delete confirmation
│ ├── Card.vue # Display card
│ └── List.vue # List view
Auto-import naming:
components/Goal/Form/Create.vue → <GoalFormCreate />components/Goal/Card.vue → <GoalCard />For complete component conventions, see references/component-patterns.md.
UIButton:
<UIButton variant="default">Submit</UIButton>
<UIButton variant="outline" size="sm">Cancel</UIButton>
<UIButton icon="i-lucide-plus" to="/create">Create</UIButton>
<UIButton variant="destructive" icon="i-lucide-trash">Delete</UIButton>
Variants: default, destructive, outline, secondary, ghost, link
UICard:
<UICard>
<UICardHeader>
<UICardTitle>Title</UICardTitle>
<UICardDescription>Description</UICardDescription>
</UICardHeader>
<UICardContent>Content</UICardContent>
<UICardFooter>
<UIButton>Action</UIButton>
</UICardFooter>
</UICard>
UISelect (multi-component pattern):
<UISelect v-model="value">
<UISelectTrigger>
<UISelectValue placeholder="Select..." />
</UISelectTrigger>
<UISelectContent>
<UISelectGroup>
<UISelectLabel>Group Label</UISelectLabel>
<UISelectItem value="option1">Option 1</UISelectItem>
<UISelectItem value="option2">Option 2</UISelectItem>
</UISelectGroup>
</UISelectContent>
</UISelect>
UIToast (vue-sonner):
import { toast } from 'vue-sonner'
toast.success('Success!', {
description: 'Your changes have been saved.',
})
toast.error('Error!', {
description: 'Something went wrong.',
})
UI prefix for all Shadcn componentsbg-primary, text-foreground)v-slot="{ close }" pattern for dialogsUIAlertDialog for confirmations (never native confirm())aria-label for icon-only buttonsbg-blue-500)isOpen.value)confirm(), alert(), prompt())aria-label attributesFor detailed information, reference these files as needed:
references/component-patterns.md - Complete component organization and naming conventionsreferences/dialog-pattern.md - Detailed dialog patterns including multiple dialogsreferences/form-validation.md - Complete form validation patterns and examplesTo look up Shadcn Vue component documentation:
https://www.shadcn-vue.com/docs/components/{component}.html
Examples:
https://www.shadcn-vue.com/docs/components/button.htmlhttps://www.shadcn-vue.com/docs/components/dialog.htmlhttps://www.shadcn-vue.com/docs/components/form.htmlhttps://www.shadcn-vue.com/docs/components/select.htmlActivates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.