<script setup lang="ts">
import { computed } from 'vue'
import { iconSvgs, normalizeIconName } from '@/icons'

const props = defineProps<{
  icon?: string | null
  size?: number | string
  title?: string
}>()

const isUrl = computed(() => {
  const value = props.icon ?? ''
  return /^(https?:\/\/|\/|data:)/.test(value)
})

const svg = computed(() => {
  const name = normalizeIconName(props.icon)
  if (!name) return undefined
  return iconSvgs[name]
})

const sizePx = computed(() => {
  const size = props.size ?? 18
  return typeof size === 'number' ? `${size}px` : size
})
</script>

<template>
  <span
    v-if="svg"
    class="app-icon"
    :style="{ '--size': sizePx }"
    :aria-hidden="title ? undefined : 'true'"
    :aria-label="title"
    role="img"
    v-html="svg"
  />
  <img
    v-else-if="isUrl && icon"
    class="app-icon-img"
    :src="icon"
    :alt="title ?? ''"
    :style="{ width: sizePx, height: sizePx }"
    loading="lazy"
    decoding="async"
  />
</template>

<style scoped>
.app-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.app-icon :deep(svg) {
  display: block;
  width: var(--size);
  height: var(--size);
}

.app-icon-img {
  display: inline-block;
  vertical-align: middle;
}
</style>
