Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
31 lines
1.1 KiB
Vue
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>
|