58 lines
1.5 KiB
Vue
58 lines
1.5 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from "vue";
|
|
import { resolveVuesaxIcon } from "@imen/shared";
|
|
import icons from "~/icons/vuesax-linear.json";
|
|
|
|
const props = defineProps<{
|
|
/** Short name (`add`), alias (`ShieldCheck`, `Phone`), or full key (`vuesax-linear:add`) */
|
|
name: string;
|
|
size?: number | string;
|
|
}>();
|
|
|
|
const pack = icons as Record<string, string>;
|
|
|
|
const svgHtml = computed(() => {
|
|
const resolved = resolveVuesaxIcon(props.name || "");
|
|
const key = resolved.includes(":") ? resolved : `vuesax-linear:${resolved}`;
|
|
const raw = pack[key] || pack[`vuesax-linear:${resolved.toLowerCase()}`] || pack["vuesax-linear:shield-tick"];
|
|
if (!raw) return "";
|
|
return raw
|
|
.replace(/\swidth="24"/, "")
|
|
.replace(/\sheight="24"/, "")
|
|
.replace(/stroke="#[A-Fa-f0-9]{3,8}"/g, 'stroke="currentColor"')
|
|
.replace(/fill="(?!none)#[A-Fa-f0-9]{3,8}"/g, 'fill="currentColor"');
|
|
});
|
|
|
|
const box = computed(() => {
|
|
if (!props.size) return undefined;
|
|
return typeof props.size === "number" ? `${props.size}px` : props.size;
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<span
|
|
class="anticon vx-icon"
|
|
:style="box ? { width: box, height: box } : undefined"
|
|
:aria-hidden="true"
|
|
v-html="svgHtml"
|
|
/>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.vx-icon {
|
|
display: inline-flex;
|
|
flex-shrink: 0;
|
|
align-items: center;
|
|
justify-content: center;
|
|
line-height: 0;
|
|
color: inherit;
|
|
vertical-align: -0.15em;
|
|
}
|
|
|
|
.vx-icon :deep(svg) {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: block;
|
|
}
|
|
</style>
|