--- description: Create a new Vue component following ThrillWiki patterns --- # New Component Workflow Create a new Vue component following ThrillWiki's design system and conventions. ## Information Gathering 1. **Component Name**: PascalCase (e.g., `ParkCard`, `RatingDisplay`) 2. **Category**: - `ui/` - Base components (Button, Card, Input) - `entity/` - Domain-specific (ParkCard, RideCard) - `forms/` - Form components - `specialty/` - Complex/unique components 3. **Props**: What data does it receive? 4. **Emits**: What events does it emit? 5. **State**: Does it have internal state? 6. **Variants**: Does it need multiple variants/sizes? ## Component Template ### Base Component Structure Location: `frontend/components/[category]/ComponentName.vue` ```vue ``` ### Entity Card Component For ParkCard, RideCard, etc.: ```vue ``` ### Skeleton Loading Component Every entity card should have a matching skeleton: ```vue ``` ## Variant Pattern (using CVA) For components with many variants, use class-variance-authority: ```vue ``` ## Composable Integration If component needs shared logic, create a composable: ```typescript // composables/useUnitDisplay.ts export function useUnitDisplay() { const { preferredUnits } = useUserPreferences() function formatSpeed(kmh: number): string { if (preferredUnits.value === 'imperial') { return `${Math.round(kmh * 0.621371)} mph` } return `${kmh} km/h` } function formatHeight(meters: number): string { if (preferredUnits.value === 'imperial') { return `${Math.round(meters * 3.28084)} ft` } return `${meters} m` } return { formatSpeed, formatHeight } } ``` ## Checklist After creating the component: - [ ] TypeScript props are properly defined - [ ] Component follows design system (colors, spacing, typography) - [ ] Responsive on all screen sizes - [ ] Handles loading state (if applicable) - [ ] Handles empty state (if applicable) - [ ] Accessible (ARIA labels, keyboard nav) - [ ] Has matching skeleton component (for async data) - [ ] Works in dark mode ## Output Report what was created: ``` Created: frontend/components/[category]/ComponentName.vue Props: [list of props] Emits: [list of events] Related: [any composables or sub-components] ```