49 lines
1.4 KiB
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> |