monacousa-portal/components/ui/Icon.vue

49 lines
1.4 KiB
Vue

<template>
<component
:is="iconComponent"
v-if="iconComponent"
v-bind="$attrs"
/>
<span v-else class="icon-placeholder">
{{ name }}
</span>
</template>
<script setup lang="ts">
import { computed, defineAsyncComponent } from 'vue'
interface Props {
name: string
}
const props = defineProps<Props>()
// Map common icon names to Heroicons components
// This is a simplified version - in production you'd import the actual icons
const iconMap: Record<string, any> = {
'chevron-down': defineAsyncComponent(() => import('./icons/ChevronDownIcon.vue')),
'chevron-up': defineAsyncComponent(() => import('./icons/ChevronUpIcon.vue')),
'x': defineAsyncComponent(() => import('./icons/XIcon.vue')),
'check': defineAsyncComponent(() => import('./icons/CheckIcon.vue')),
'alert-circle': defineAsyncComponent(() => import('./icons/AlertCircleIcon.vue')),
'trending-up': defineAsyncComponent(() => import('./icons/TrendingUpIcon.vue')),
'trending-down': defineAsyncComponent(() => import('./icons/TrendingDownIcon.vue')),
'minus': defineAsyncComponent(() => import('./icons/MinusIcon.vue')),
}
const iconComponent = computed(() => iconMap[props.name])
</script>
<style scoped>
.icon-placeholder {
display: inline-flex;
align-items: center;
justify-content: center;
width: 1em;
height: 1em;
font-size: 0.75em;
color: currentColor;
background: rgba(220, 38, 38, 0.1);
border-radius: 4px;
}
</style>