Implement Lucide Vue icon system and UI improvements
- Replace emoji icons with professional SVG icons from Lucide Vue - Add collapsible MusicControls with compact top-right collapse button - Improve icon system with dynamic sizing and proper prop handling - Disable SSR to prevent hydration issues with audio APIs - Update IconButton to support both emoji strings and SVG components - Optimize bottom positioning for expanded vs collapsed states - Document new icon system in DESIGN_SYSTEM.md
This commit is contained in:
539
DESIGN_SYSTEM.md
Normal file
539
DESIGN_SYSTEM.md
Normal file
@@ -0,0 +1,539 @@
|
||||
# RepoDructor - Design System & Architecture Guide
|
||||
|
||||
## 🎨 Design Philosophy
|
||||
|
||||
RepoDructor follows a **Glassmorphism** design philosophy with **Aurora-inspired** lighting effects. The application emphasizes transparency, depth, and visual hierarchy through carefully crafted blur effects, subtle borders, and dynamic lighting.
|
||||
|
||||
### Core Design Principles
|
||||
|
||||
1. **Transparency & Depth**: All UI elements use glassmorphism with varying levels of transparency
|
||||
2. **Dynamic Lighting**: Aurora orbs and particles provide ambient lighting that responds to music playback
|
||||
3. **Smooth Animations**: Every interaction includes fluid transitions and micro-animations
|
||||
4. **Responsive Design**: Mobile-first approach with adaptive layouts
|
||||
5. **Accessibility**: Support for reduced motion and high contrast preferences
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Architecture Overview
|
||||
|
||||
### Component Structure
|
||||
|
||||
```
|
||||
components/
|
||||
├── Base Components
|
||||
│ ├── BaseButton.client.vue # Foundation button component
|
||||
│ └── IconButton.client.vue # Extends BaseButton for icon buttons
|
||||
├── UI Components
|
||||
│ ├── ThemeToggle.client.vue # Dark/light theme switcher
|
||||
│ ├── PlaybackControls.client.vue # Shuffle/repeat controls
|
||||
│ ├── TrackListItem.client.vue # Individual track display
|
||||
│ ├── TrackList.client.vue # Track collection container
|
||||
│ └── MusicControls.client.vue # Main playback controls (fixed bottom)
|
||||
├── Layout Components
|
||||
│ ├── MainContainer.client.vue # App layout wrapper
|
||||
│ └── AuroraBackground.client.vue # Dynamic background effects
|
||||
└── pages/
|
||||
└── index.vue # Main application page
|
||||
```
|
||||
|
||||
### Component Hierarchy
|
||||
|
||||
```
|
||||
index.vue
|
||||
├── AuroraBackground.client.vue
|
||||
├── MainContainer.client.vue
|
||||
│ ├── Header (built-in)
|
||||
│ │ ├── PlaybackControls.client.vue
|
||||
│ │ │ ├── IconButton.client.vue (shuffle)
|
||||
│ │ │ └── IconButton.client.vue (repeat)
|
||||
│ │ └── ThemeToggle.client.vue
|
||||
│ └── TrackList.client.vue
|
||||
│ └── TrackListItem.client.vue (multiple)
|
||||
└── MusicControls.client.vue
|
||||
└── IconButton.client.vue (multiple)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Component Design Patterns
|
||||
|
||||
### Base Components
|
||||
|
||||
#### BaseButton.client.vue
|
||||
**Purpose**: Foundation for all interactive buttons
|
||||
**Variants**: `default`, `icon`, `primary`
|
||||
**Key Features**:
|
||||
- Glassmorphism background with blur effects
|
||||
- Hover animations with shimmer effect
|
||||
- Active state management
|
||||
- Accessibility support
|
||||
|
||||
```vue
|
||||
<BaseButton variant="icon" :active="true" @click="handleClick">
|
||||
<Music :size="20" />
|
||||
</BaseButton>
|
||||
```
|
||||
|
||||
#### IconButton.client.vue
|
||||
**Purpose**: Specialized button for icons with badges
|
||||
**Sizes**: `small`, `normal`, `large`
|
||||
**Icon Support**: String (emojis), Object/Function (Lucide Vue components)
|
||||
**Key Features**:
|
||||
- Extends BaseButton with icon-specific styling
|
||||
- Support for both emoji strings and SVG components
|
||||
- Badge support for notifications
|
||||
- Icon-specific hover animations
|
||||
- Responsive sizing with dynamic icon scaling
|
||||
|
||||
### UI Components
|
||||
|
||||
#### ThemeToggle.client.vue
|
||||
**Purpose**: Dark/light theme switcher
|
||||
**Key Features**:
|
||||
- Smooth rotation animation on toggle
|
||||
- Radial glow effect on hover
|
||||
- Persists preference in localStorage
|
||||
- Updates document theme attribute
|
||||
|
||||
#### PlaybackControls.client.vue
|
||||
**Purpose**: Shuffle and repeat mode controls
|
||||
**Key Features**:
|
||||
- Icon-specific hover animations (wiggle for shuffle, spin for repeat)
|
||||
- Active state with glow effects
|
||||
- LocalStorage persistence
|
||||
- Emits change events to parent
|
||||
|
||||
#### TrackListItem.client.vue
|
||||
**Purpose**: Individual track display with interaction
|
||||
**Key Features**:
|
||||
- Ripple effect on click
|
||||
- Hover lift animation
|
||||
- Active state with gradient background
|
||||
- Loading state with spinner
|
||||
- Waveform visualization for active playing tracks
|
||||
|
||||
#### TrackList.client.vue
|
||||
**Purpose**: Container for track collection
|
||||
**Key Features**:
|
||||
- Staggered animations for child items
|
||||
- Scrollable container with custom scrollbar
|
||||
- Empty state and loading state handling
|
||||
- Glassmorphism container styling
|
||||
|
||||
#### MusicControls.client.vue
|
||||
**Purpose**: Main music playback controls (fixed at bottom)
|
||||
**Key Features**:
|
||||
- Collapsible interface with compact and expanded states
|
||||
- Track information display with animated status indicators
|
||||
- Navigation controls with Lucide SVG icons (SkipBack, Play/Pause, SkipForward)
|
||||
- Progress bar with interactive seek functionality
|
||||
- Volume control with visual feedback and mute toggle
|
||||
- Compact collapse button positioned in top-right corner
|
||||
- Dynamic bottom positioning (closer when expanded, standard when collapsed)
|
||||
- Responsive layout that adapts to screen size
|
||||
|
||||
### Layout Components
|
||||
|
||||
#### MainContainer.client.vue
|
||||
**Purpose**: Application layout wrapper
|
||||
**Key Features**:
|
||||
- Header with app branding and controls
|
||||
- Responsive content area
|
||||
- Consistent spacing and margins
|
||||
- Glassmorphism header styling
|
||||
|
||||
#### AuroraBackground.client.vue
|
||||
**Purpose**: Dynamic background effects
|
||||
**Key Features**:
|
||||
- Multiple floating orbs with different colors
|
||||
- Interactive orbs that respond to music playback
|
||||
- Particle system with floating elements
|
||||
- Gradient overlays
|
||||
- Performance optimized animations
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Design Tokens
|
||||
|
||||
### Color System
|
||||
|
||||
```css
|
||||
/* Light Mode */
|
||||
--bg-primary: #f8fafc;
|
||||
--bg-secondary: rgba(255, 255, 255, 0.8);
|
||||
--bg-glass: rgba(255, 255, 255, 0.25);
|
||||
--text-primary: #1e293b;
|
||||
--text-secondary: #64748b;
|
||||
--accent-primary: #3b82f6;
|
||||
--accent-secondary: #8b5cf6;
|
||||
--border-glass: rgba(255, 255, 255, 0.18);
|
||||
|
||||
/* Dark Mode */
|
||||
--bg-primary: #0f172a;
|
||||
--bg-secondary: rgba(15, 23, 42, 0.8);
|
||||
--bg-glass: rgba(15, 23, 42, 0.3);
|
||||
--text-primary: #f1f5f9;
|
||||
--text-secondary: #94a3b8;
|
||||
--accent-primary: #60a5fa;
|
||||
--accent-secondary: #a78bfa;
|
||||
--border-glass: rgba(255, 255, 255, 0.125);
|
||||
|
||||
/* Aurora Colors */
|
||||
--aurora-1: #ff6b6b;
|
||||
--aurora-2: #4ecdc4;
|
||||
--aurora-3: #45b7d1;
|
||||
--aurora-4: #f9ca24;
|
||||
--aurora-5: #6c5ce7;
|
||||
```
|
||||
|
||||
### Typography
|
||||
|
||||
```css
|
||||
font-family: 'Inter', sans-serif;
|
||||
|
||||
/* Sizes */
|
||||
--text-xs: 0.75rem;
|
||||
--text-sm: 0.875rem;
|
||||
--text-base: 1rem;
|
||||
--text-lg: 1.125rem;
|
||||
--text-xl: 1.25rem;
|
||||
--text-2xl: 1.5rem;
|
||||
|
||||
/* Weights */
|
||||
--font-light: 300;
|
||||
--font-normal: 400;
|
||||
--font-medium: 500;
|
||||
--font-semibold: 600;
|
||||
--font-bold: 700;
|
||||
```
|
||||
|
||||
### Spacing
|
||||
|
||||
```css
|
||||
--space-1: 0.25rem; /* 4px */
|
||||
--space-2: 0.5rem; /* 8px */
|
||||
--space-3: 0.75rem; /* 12px */
|
||||
--space-4: 1rem; /* 16px */
|
||||
--space-5: 1.25rem; /* 20px */
|
||||
--space-6: 1.5rem; /* 24px */
|
||||
--space-8: 2rem; /* 32px */
|
||||
--space-10: 2.5rem; /* 40px */
|
||||
```
|
||||
|
||||
### Border Radius
|
||||
|
||||
```css
|
||||
--radius-sm: 8px;
|
||||
--radius-md: 12px;
|
||||
--radius-lg: 16px;
|
||||
--radius-xl: 20px;
|
||||
--radius-full: 50%;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✨ Animation System
|
||||
|
||||
### Core Animation Classes
|
||||
|
||||
Located in `assets/css/animations.css`:
|
||||
|
||||
```css
|
||||
/* Utility Classes */
|
||||
.animate-fade-in /* Fade in effect */
|
||||
.animate-slide-in-up /* Slide up with fade */
|
||||
.animate-bounce-in /* Bounce entrance */
|
||||
.animate-scale-in /* Scale entrance */
|
||||
.animate-glow /* Continuous glow effect */
|
||||
.animate-pulse-glow /* Pulsing glow */
|
||||
|
||||
/* Hover Effects */
|
||||
.hover-lift /* Lift on hover */
|
||||
.hover-scale /* Scale on hover */
|
||||
.hover-glow /* Glow on hover */
|
||||
|
||||
/* Interactive Effects */
|
||||
.ripple /* Click ripple effect */
|
||||
.stagger-children /* Staggered child animations */
|
||||
```
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
```css
|
||||
/* Reduced Motion Support */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
* {
|
||||
animation-duration: 0.01ms !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hardware Acceleration */
|
||||
.aurora-orb,
|
||||
.interactive-orb,
|
||||
.particle {
|
||||
will-change: transform;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Icon System
|
||||
|
||||
### Icon Library: Lucide Vue
|
||||
|
||||
RepoDructor uses **Lucide Vue** as the primary icon system for consistent, scalable iconography that matches the glassmorphism aesthetic.
|
||||
|
||||
### Icon Implementation
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { Play, Pause, SkipForward, SkipBack, Shuffle, Repeat, Repeat1,
|
||||
Volume2, Volume1, VolumeX, Sun, Moon, ChevronUp, ChevronDown, Music } from 'lucide-vue-next'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Direct component usage -->
|
||||
<Play :size="24" />
|
||||
|
||||
<!-- Dynamic icon selection -->
|
||||
<component :is="isPlaying ? Pause : Play" :size="20" />
|
||||
|
||||
<!-- With IconButton wrapper -->
|
||||
<IconButton :icon="Shuffle" :active="isShuffled" title="Shuffle" />
|
||||
</template>
|
||||
```
|
||||
|
||||
### Icon Categories
|
||||
|
||||
**Playback Controls:**
|
||||
- `Play`, `Pause` - Primary playback states
|
||||
- `SkipForward`, `SkipBack` - Navigation controls
|
||||
- `Shuffle` - Random playback mode
|
||||
- `Repeat`, `Repeat1` - Repeat modes
|
||||
|
||||
**Audio Controls:**
|
||||
- `Volume2`, `Volume1`, `VolumeX` - Volume states
|
||||
- `Music` - General music representation
|
||||
|
||||
**Interface Controls:**
|
||||
- `Sun`, `Moon` - Theme toggle states
|
||||
- `ChevronUp`, `ChevronDown` - Collapse/expand actions
|
||||
|
||||
### Icon Sizing
|
||||
|
||||
Icons automatically scale based on context:
|
||||
- **Small buttons**: 18px
|
||||
- **Normal buttons**: 20px
|
||||
- **Large buttons**: 28px
|
||||
- **Custom sizing**: Use `:size` prop
|
||||
|
||||
### Benefits
|
||||
|
||||
- **Consistent**: Unified design language across all icons
|
||||
- **Scalable**: Vector-based for perfect rendering at any size
|
||||
- **Local**: No external dependencies or network requests
|
||||
- **Accessible**: Proper semantic meaning and ARIA support
|
||||
- **Themeable**: Inherit colors from CSS custom properties
|
||||
|
||||
---
|
||||
|
||||
## 📱 Responsive Design
|
||||
|
||||
### Breakpoints
|
||||
|
||||
```css
|
||||
/* Mobile First Approach */
|
||||
@media (max-width: 768px) /* Tablet and below */
|
||||
@media (max-width: 480px) /* Mobile */
|
||||
|
||||
/* Special Mobile Considerations */
|
||||
@media (max-width: 768px) {
|
||||
.music-controls {
|
||||
/* Fixed positioning with safe areas */
|
||||
bottom: calc(20px + env(safe-area-inset-bottom));
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Layout Patterns
|
||||
|
||||
1. **Desktop**: Horizontal layouts with fixed controls at bottom
|
||||
2. **Tablet**: Slightly compressed with smaller gaps
|
||||
3. **Mobile**: Vertical stacking with reorganized control layouts
|
||||
|
||||
---
|
||||
|
||||
## 🎵 Audio Integration Patterns
|
||||
|
||||
### State Management
|
||||
|
||||
```javascript
|
||||
// Core audio states
|
||||
const isPlaying = ref(false)
|
||||
const currentTrack = ref(null)
|
||||
const currentTime = ref(0)
|
||||
const duration = ref(0)
|
||||
const volume = ref(0.7)
|
||||
|
||||
// Playback modes
|
||||
const isShuffled = useLocalStorage('shuffle', false)
|
||||
const repeatMode = useLocalStorage('repeat', 'none')
|
||||
```
|
||||
|
||||
### Event Handling
|
||||
|
||||
```javascript
|
||||
// Component communication pattern
|
||||
const emit = defineEmits(['track-selected', 'shuffle-changed'])
|
||||
|
||||
// Handle track selection
|
||||
const handleTrackClick = (track, index) => {
|
||||
emit('track-selected', { track, index })
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Development Guidelines
|
||||
|
||||
### Component Creation
|
||||
|
||||
1. **Always use `.client.vue` suffix** for client-side components
|
||||
2. **Follow the composition API pattern** with `<script setup>`
|
||||
3. **Include responsive design** in every component
|
||||
4. **Add hover states and animations** for interactive elements
|
||||
5. **Support both light and dark themes**
|
||||
|
||||
### CSS Guidelines
|
||||
|
||||
```css
|
||||
/* Use CSS custom properties for theming */
|
||||
.component {
|
||||
background: var(--bg-glass);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Include smooth transitions */
|
||||
.interactive-element {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* Glassmorphism pattern */
|
||||
.glass-element {
|
||||
background: var(--bg-glass);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid var(--border-glass);
|
||||
border-radius: var(--radius-xl);
|
||||
}
|
||||
```
|
||||
|
||||
### Accessibility
|
||||
|
||||
```vue
|
||||
<!-- Include proper ARIA labels -->
|
||||
<button :aria-label="isPlaying ? 'Pause' : 'Play'" @click="togglePlay">
|
||||
<component :is="isPlaying ? Pause : Play" :size="20" />
|
||||
</button>
|
||||
|
||||
<!-- Support keyboard navigation -->
|
||||
<div class="focus-ring:focus-visible" tabindex="0">
|
||||
<!-- Content -->
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Performance Optimization
|
||||
|
||||
### Image and Asset Handling
|
||||
|
||||
- Use WebP format for images when possible
|
||||
- Implement lazy loading for large lists
|
||||
- Use Lucide Vue for consistent SVG iconography
|
||||
- Icons are locally bundled (no external CDN dependencies)
|
||||
|
||||
### Animation Performance
|
||||
|
||||
```css
|
||||
/* Use transform and opacity for animations */
|
||||
.optimized-animation {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
transition: transform 0.3s ease, opacity 0.3s ease;
|
||||
}
|
||||
|
||||
/* Avoid animating expensive properties */
|
||||
/* ❌ Don't animate: width, height, top, left */
|
||||
/* ✅ Do animate: transform, opacity, filter */
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
|
||||
```javascript
|
||||
// Clean up audio resources
|
||||
const cleanupAudio = () => {
|
||||
if (audioPlayer.value?.currentBlobUrl) {
|
||||
URL.revokeObjectURL(audioPlayer.value.currentBlobUrl)
|
||||
audioPlayer.value.currentBlobUrl = null
|
||||
}
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
cleanupAudio()
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Future Development Considerations
|
||||
|
||||
### Planned Features
|
||||
- Playlist management
|
||||
- Audio visualizer enhancements
|
||||
- Keyboard shortcuts
|
||||
- Drag and drop file upload
|
||||
- Audio effects (equalizer, etc.)
|
||||
|
||||
### Technical Debt
|
||||
- Consider moving to Pinia for state management if app grows
|
||||
- Implement virtual scrolling for large track lists
|
||||
- Add unit tests for components
|
||||
- Consider PWA caching strategies
|
||||
|
||||
### Design Evolution
|
||||
- Seasonal theme variations
|
||||
- User-customizable aurora colors
|
||||
- Advanced animation preferences
|
||||
- Accessibility improvements
|
||||
|
||||
---
|
||||
|
||||
## 📚 Resources
|
||||
|
||||
### Dependencies
|
||||
- **Nuxt 3**: Application framework
|
||||
- **Vue 3**: Component framework
|
||||
- **@vueuse/core**: Composition utilities
|
||||
- **@vite-pwa/nuxt**: PWA functionality
|
||||
- **lucide-vue-next**: SVG icon library for consistent iconography
|
||||
|
||||
### Design References
|
||||
- **Glassmorphism**: https://glassmorphism.com/
|
||||
- **Aurora Borealis**: Color inspiration for background effects
|
||||
- **Apple Music**: UI/UX reference for music controls
|
||||
- **Spotify**: Reference for track list interactions
|
||||
|
||||
### Code Standards
|
||||
- **ESLint**: Code linting
|
||||
- **Prettier**: Code formatting
|
||||
- **Vue Style Guide**: Component structure
|
||||
- **Conventional Commits**: Git commit format
|
||||
|
||||
---
|
||||
|
||||
*This design system is a living document. Update it as the application evolves and new patterns emerge.*
|
||||
Reference in New Issue
Block a user