Files
BRETT/app/components/TagIcon.vue
T
FliesentischKingandDevin 013e4c8add Add admin-managed icons and animation effects for tags
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-25 00:34:15 +02:00

31 lines
1.1 KiB
Vue

<script setup lang="ts">
import { cn } from '@/lib/utils'
// Tag-Icon: Iconify-Name („ph:x") -> Icon-Komponente, Sticker-Shortcode
// („:name:") -> StickerMedia, lokaler Pfad („/uploads/...") -> <img>,
// sonst Emoji-Text
const props = defineProps<{
icon: string
class?: string
}>()
const { byName } = useStickers()
const stickerName = computed(() => /^:([a-z0-9_]+):$/.exec(props.icon)?.[1] ?? null)
const sticker = computed(() => stickerName.value ? byName.value.get(stickerName.value) ?? null : null)
const isFile = computed(() => props.icon.startsWith('/'))
const isIconify = computed(() => !stickerName.value && !isFile.value && props.icon.includes(':'))
</script>
<template>
<StickerMedia v-if="sticker" :sticker="sticker" variant="tag" :class="props.class" />
<img
v-else-if="isFile"
:src="icon"
:class="cn('size-4 shrink-0 rounded-[2px] object-contain', props.class)"
alt=""
aria-hidden="true"
>
<Icon v-else-if="isIconify" :name="icon" :class="cn('size-3.5 shrink-0', props.class)" aria-hidden="true" />
<span v-else :class="cn('shrink-0 leading-none', props.class)" aria-hidden="true">{{ icon }}</span>
</template>