Creating a Vue Component from Figma
You will create a Vue.js component from a Figma design following a structured methodology and respecting project conventions.
Project Context
- Frontend Stack: Vue.js 3 + Vuetify
- Styling: SASS with BEM methodology
- Structure: Modular architecture with shared components
Git Branch Setup
FIRST STEP - Branch Creation: Ask the user: "What name would you like for the new Git branch for this component?"
- Use format:
feature/component-[component-name]orfeat/[component-name]as suggestions - Create and switch to the new branch before starting development
Workflow Overview
PREREQUISITES (already done by user):
- Figma component is already selected
- Component name will be taken from Figma component name
- Component will be created in
components/shared/[category]/[FigmaComponentName].vue
ONLY ASK if needed:
- Which category folder? (cards, ui, form, navigation, layout, media, other…)
- Are there specific integration requirements?
NO NEED TO ASK:
- ❌ Component name (use Figma component name)
- ❌ Node ID (component already selected in Figma)
- ❌ Props (determined from Figma design analysis)
- ❌ Responsive behavior (follow Figma breakpoints if any)
- ❌ Icons (use Figma icon names directly)
Session Configuration
IMPORTANT: When prompted by Claude Code for edit permissions, always respond with "Yes" to streamline the development process.
Workflow to Follow
0. Git Branch Setup
STEP 0: Branch Creation
- Ask for branch name (suggest: feature/component-[name] or feat/[name])
- Create and checkout new branch: git checkout -b [branch-name]
- Verify branch switch successful
1. Automatic Figma Design Analysis
STEP 1: Direct Design Extraction (NO questions needed)
- Use mcp__figma__get_code to generate code from selected design
- Use mcp__figma__get_image to visualize the component
- Extract component name from Figma (this becomes the Vue component name)
- Automatically analyze design for:
* Exact dimensions and spacing
* Color palette (convert to closest existing SASS variables)
* Typography and font sizes
* Interactive states ONLY if shown in Figma
* Responsive behavior ONLY if shown in Figma
- Check existing SASS structure for reusable variables/classes
2. Vue Component Creation - EXACT FIGMA REPRODUCTION ONLY
STEP 2: Conversion and Adaptation - STRICT FIGMA ADHERENCE
- Create .vue file in: components/shared/[category]/ComponentName.vue
- Component structure:
* <template>: Convert HTML/React structure to Vue.js
* <script setup>: Use Composition API with MINIMAL props
* <style lang="sass" scoped>: Component-specific styles only when needed
- CRITICAL RULES FOR FIGMA REPRODUCTION:
* ❌ DO NOT add slots unless explicitly visible in Figma design
* ❌ DO NOT add hover effects unless shown in Figma interaction states
* ❌ DO NOT add variant props unless multiple variants exist in Figma
* ❌ DO NOT add elevation/shadow props unless specified in design
* ❌ DO NOT add maxWidth/sizing props unless design shows specific constraints
* ❌ DO NOT create generic/flexible components - reproduce EXACTLY what's in Figma
* ❌ DO NOT add computed classes for variants unless Figma shows variants
* ❌ DO NOT add animation/transition effects unless specified in Figma
- ONLY ADD:
* Props that correspond to dynamic content visible in the Figma design
* Styles that match exactly what's shown in Figma
* Structure that mirrors the Figma component hierarchy
- Required conversions:
* React/JSX → Vue template syntax
* Custom CSS → Vuetify responsive utility classes (PRIORITY)
* React Props → Vue Props with TypeScript validation (ONLY for content shown in Figma)
* React Events → Vue Events (@click, @input, etc.) - ONLY if interactions shown in Figma
* Icons: If icons, Use Figma icon names directly in v-icon (e.g., icon="mdi-home")
- CRITICAL: NEVER use custom responsive mixins (@include mobile, @include tablet). Always use Vuetify native responsive system:
* Grid System: v-container, v-row, v-col with breakpoint props (xs, sm, md, lg, xl)
* Display: d-{breakpoint}-{value} (e.g., d-lg-none, d-sm-flex)
* Spacing: {property}{direction}-{breakpoint}-{size} (e.g., ma-lg-8, pa-sm-4)
* Flex: flex-{breakpoint}-{value} (e.g., flex-lg-row, flex-sm-column)
* Dynamic classes with $vuetify.display: :class="{ 'ga-4': $vuetify.display.mdAndUp }"
* Reactive props: :size="$vuetify.display.smAndDown ? 'small' : 'default'"
* Breakpoints: xs (0-600px), sm (600-960px), md (960-1264px), lg (1264-1904px), xl (1904px+)
3. Vuetify-First Styling Approach
STEP 3: Vuetify Utilities Before Custom Styles
- PRIORITY: Use Vuetify built-in classes and components:
* v-btn variants (color, size, variant props)
* v-card, v-sheet for containers
* v-form components for form elements
* Built-in spacing and display utilities
- Only create custom SASS when Vuetify utilities are insufficient:
* Identify elements that CANNOT be achieved with Vuetify classes
* Create minimal custom styles: assets/sass/components/_[type].sass
* Recommended SASS structure:
.component-name
&__element
// Element styles (only when Vuetify classes insufficient)
&--modifier
// Component variant (prefer Vuetify props when possible)
&:hover, &:focus
// Interactive states (use Vuetify state classes first)
- Examples of Vuetify-first approach:
* Instead of custom .btn-primary → use v-btn color="primary"
* Instead of custom spacing → use ma-4, pa-2, etc.
* Instead of custom grid → use v-container, v-row, v-col
4. Integration and Validation
STEP 4: Ecosystem Integration
- Import component in parent page/component
- Check compatibility with:
* Vue Router (if navigation)
* Vuetify theme, breakpoints, and responsive behavior
* Pinia Store (if state management)
- Test different states and props
- Validate responsive design using Vuetify's breakpoint system:
* Test on different screen sizes (xs, sm, md, lg, xl)
* Verify Vuetify responsive classes work correctly
* Use browser DevTools or $vuetify.display for breakpoint testing
Vuetify Resources & SASS Fallback
PRIORITY: Vuetify Built-in Classes
- Colors: Use Vuetify color system (primary, secondary, accent, error, info, success, warning)
- Apply via props:
color="primary"or classes:text-primary,bg-secondary
- Apply via props:
- Spacing: Use Vuetify spacing utilities instead of custom CSS
- Margins:
ma-{0-16},mx-4,my-2, responsive:ma-lg-8 - Padding:
pa-{0-16},px-4,py-2, responsive:pa-sm-4
- Margins:
- Typography: Use Vuetify text classes
text-h1totext-h6,text-body-1,text-body-2,text-caption
- Layout: Use Vuetify grid and flex utilities
- Grid:
v-container,v-row,v-colwith breakpoint props - Flex:
d-flex,flex-column,justify-center,align-center - Responsive display:
d-sm-none,d-lg-block
- Grid:
SASS Fallback (Only when Vuetify insufficient)
Existing Variables (assets/sass/base/_variables.sass)
- Colors:
$primary,$secondary,$accent(should match Vuetify theme) - Typography:
$body-font-family: 'Poppins' - Layout:
$border-radius-root: 8px,$font-size-root: 16px
Available Mixins (assets/sass/base/_mixins.sass)
- ❌ NEVER USE:
@include mobile,@include tablet,@include desktop- Use Vuetify responsive system instead - Transitions:
@include transition($property, $duration, $easing)(prefer Vuetify component transitions) - Shadows:
@include box-shadow($level)(prefer Vuetify elevation classes) - Buttons:
@include button-style($bg-color, $text-color)(prefer v-btn)
Existing Component Classes (assets/sass/components/)
- Menu components:
.menu-item-base,.btn-nudge-tools,.main-menu-container - Check other component files:
_buttons.sass,_cards.sass,_menus.sass
IMPORTANT:
- FIRST try to achieve the design with Vuetify classes
- Only create custom SASS when Vuetify utilities cannot achieve the desired result
- Always reuse existing classes and variables instead of creating duplicates
Icons Implementation
- Figma icon names match the icon library directly
- Use them as-is in
<v-icon icon="figma-icon-name" /> - No need to ask for icon mapping - implement directly from Figma
Conventions to Follow
File Naming
- Components:
PascalCase.vue(e.g.,ButtonNudgeTools.vue) - SASS Styles:
_kebab-case.sass(e.g.,_button-variants.sass) - Suggested categories: ui, form, navigation, layout, media
Vue Component Structure
<template>
<!-- Use Vuetify components and utility classes -->
<v-card class="component-name" elevation="1">
<v-container>
<v-row>
<v-col cols="12" sm="6" md="4">
<!-- Responsive grid using Vuetify -->
</v-col>
</v-row>
</v-container>
</v-card>
</template>
<script setup lang="ts">
interface Props {
// Props with TypeScript types
}
const props = withDefaults(defineProps<Props>(), {
// Default values
})
const emit = defineEmits<{
// Emitted events
}>()
</script>
<!-- ONLY styles that exactly match Figma design - prefer Vuetify classes in template -->
<style lang="sass" scoped>
@use '@/assets/sass/base/variables' as *
@use '@/assets/sass/base/mixins' as *
.component-name
// ONLY add styles that exactly reproduce the Figma design
// DO NOT add hover effects, transitions, or animations unless shown in Figma
// Most styling should be done via Vuetify classes in template
// ❌ FORBIDDEN unless explicitly in Figma:
// hover effects, transitions, animations, shadows, borders
// variant styles, responsive breakpoints not shown in design
// ❌ NEVER USE custom responsive mixins - use Vuetify responsive system instead:
// @include mobile - FORBIDDEN, use $vuetify.display.smAndDown in template
// @include tablet - FORBIDDEN, use $vuetify.display.md in template
// @include desktop - FORBIDDEN, use $vuetify.display.lgAndUp in template
// ✅ Only add custom CSS for:
// Exact colors, fonts, spacing, layout that match Figma pixel-perfect
// Use standard media queries as last resort, but prefer Vuetify classes
</style>
BEM Methodology
- Block:
.button - Element:
.button__icon,.button__text - Modifier:
.button--primary,.button--disabled
Final Checklist - EXACT FIGMA REPRODUCTION
- Figma design correctly analyzed and reproduced EXACTLY
- Vue component created with proper structure
- PRIORITY: Vuetify responsive classes used instead of custom CSS where possible
- Minimal custom SASS created only when Vuetify insufficient
- BEM classes applied correctly (only for custom styles)
- Component integrated and functional
- TypeScript code validated
- Responsive design tested across Vuetify breakpoints (xs, sm, md, lg, xl)
- Interactive states functional using Vuetify components/utilities
- MCP Vuetify server consulted for component best practices when available
- CRITICAL: NO additional features beyond what's shown in Figma
- CRITICAL: NO generic slots unless explicitly designed in Figma
- CRITICAL: NO hover effects unless shown in Figma interaction states
- CRITICAL: NO variant props unless multiple variants exist in Figma
5. Commit Changes
STEP 5: Create Git Commit
- After successful component creation and validation
- Stage all created/modified files: git add .
- Create commit with descriptive message following project conventions
- Use format: "feat(component): add [ComponentName] from Figma design"
- Include component details in commit body if needed
Dynamic Arguments
$ARGUMENTS
IMPORTANT: Start by analyzing the selected Figma design directly (component name and selection are already done). EXACT design reproduction is the ONLY priority - do not add features, flexibility, or enhancements not explicitly shown in Figma.