dramaling-app/apps/web/src/components/ui/Icon.vue

197 lines
3.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 通用圖示組件 -->
<!-- 支援常用圖示基於CSS和Unicode字符 -->
<template>
<span
class="icon"
:class="[`icon-${name}`, size && `icon-${size}`]"
:style="{ color: color }"
>
{{ iconChar }}
</span>
</template>
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
name: string
size?: 'sm' | 'md' | 'lg' | 'xl'
color?: string
}
const props = withDefaults(defineProps<Props>(), {
size: 'md'
})
// 圖示字符映射
const iconMap: Record<string, string> = {
// 基礎操作
'check': '✓',
'x': '✕',
'check-circle': '✅',
'x-circle': '❌',
'plus': '+',
'minus': '-',
'arrow-right': '→',
'arrow-left': '←',
'arrow-up': '↑',
'arrow-down': '↓',
'chevron-right': '',
'chevron-left': '',
'chevron-up': '',
'chevron-down': '',
// 媒體控制
'play': '▶',
'pause': '⏸',
'stop': '⏹',
'volume': '🔊',
'volume-mute': '🔇',
'skip-forward': '⏭',
'skip-back': '⏮',
'loading': '⟳',
// 學習相關
'book': '📖',
'bookmark': '🔖',
'star': '⭐',
'heart': '❤️',
'trophy': '🏆',
'target': '🎯',
'lightbulb': '💡',
'brain': '🧠',
'graduation-cap': '🎓',
// 時間相關
'clock': '🕐',
'timer': '⏰',
'calendar': '📅',
'history': '🕒',
// 狀態指示
'info': '',
'warning': '⚠',
'error': '⚠',
'success': '✅',
'question': '❓',
'exclamation': '❗',
// 工具
'settings': '⚙',
'edit': '✎',
'delete': '🗑',
'copy': '📄',
'download': '⬇',
'upload': '⬆',
'search': '🔍',
'filter': '🔽',
'sort': '⇅',
// 導航
'home': '🏠',
'menu': '☰',
'more': '⋯',
'close': '✕',
'back': '←',
'forward': '→',
// 社交
'share': '📤',
'like': '👍',
'comment': '💬',
'user': '👤',
'users': '👥',
// 文件
'file': '📄',
'folder': '📁',
'image': '🖼',
'video': '🎬',
'music': '🎵',
// 練習特定
'choice': '☑',
'matching': '🔗',
'reorganize': '🔄',
'microphone': '🎤',
'speaker': '🔊',
'headphones': '🎧'
}
const iconChar = computed(() => {
return iconMap[props.name] || '?'
})
</script>
<style lang="scss" scoped>
.icon {
display: inline-block;
font-style: normal;
line-height: 1;
text-align: center;
vertical-align: middle;
// 尺寸
&.icon-sm {
font-size: 0.875rem; // 14px
}
&.icon-md {
font-size: 1rem; // 16px
}
&.icon-lg {
font-size: 1.25rem; // 20px
}
&.icon-xl {
font-size: 1.5rem; // 24px
}
// 動畫效果
&.icon-loading {
animation: spin 1s linear infinite;
}
// 特定圖示樣式
&.icon-heart {
color: #e74c3c;
}
&.icon-star {
color: #f1c40f;
}
&.icon-trophy {
color: #f39c12;
}
&.icon-success,
&.icon-check-circle {
color: #27ae60;
}
&.icon-error,
&.icon-x-circle {
color: #e74c3c;
}
&.icon-warning {
color: #f39c12;
}
&.icon-info {
color: #3498db;
}
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>