You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.0 KiB
90 lines
2.0 KiB
<template>
|
|
<svg
|
|
v-if="iconData"
|
|
:class="svgClass"
|
|
:fill="fill"
|
|
:stroke="stroke"
|
|
:viewBox="viewBox"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
>
|
|
<path v-for="(path, index) in iconData.paths" :key="index" v-bind="path" />
|
|
</svg>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Component, Prop, Vue } from "vue-facing-decorator";
|
|
import icons from "../assets/icons.json";
|
|
import { logger } from "../utils/logger";
|
|
|
|
/**
|
|
* Icon path interface
|
|
*/
|
|
interface IconPath {
|
|
d: string;
|
|
fillRule?: string;
|
|
clipRule?: string;
|
|
strokeLinecap?: string;
|
|
strokeLinejoin?: string;
|
|
strokeWidth?: string | number;
|
|
fill?: string;
|
|
stroke?: string;
|
|
}
|
|
|
|
/**
|
|
* Icon data interface
|
|
*/
|
|
interface IconData {
|
|
paths: IconPath[];
|
|
}
|
|
|
|
/**
|
|
* Icons JSON structure
|
|
*/
|
|
interface IconsJson {
|
|
[key: string]: IconPath | IconData;
|
|
}
|
|
|
|
/**
|
|
* Icon Renderer Component
|
|
*
|
|
* This component loads SVG icon definitions from a JSON file and renders them
|
|
* as SVG elements. It provides a clean way to use icons without cluttering
|
|
* templates with long SVG path definitions.
|
|
*
|
|
* @author Matthew Raymer
|
|
* @version 1.0.0
|
|
* @since 2024
|
|
*/
|
|
@Component({
|
|
name: "IconRenderer",
|
|
})
|
|
export default class IconRenderer extends Vue {
|
|
@Prop({ required: true }) readonly iconName!: string;
|
|
@Prop({ default: "h-5 w-5" }) readonly svgClass!: string;
|
|
@Prop({ default: "none" }) readonly fill!: string;
|
|
@Prop({ default: "currentColor" }) readonly stroke!: string;
|
|
@Prop({ default: "0 0 24 24" }) readonly viewBox!: string;
|
|
|
|
/**
|
|
* Get the icon data for the specified icon name
|
|
*
|
|
* @returns {IconData | null} The icon data object or null if not found
|
|
*/
|
|
get iconData(): IconData | null {
|
|
const icon = (icons as IconsJson)[this.iconName];
|
|
if (!icon) {
|
|
logger.warn(`Icon "${this.iconName}" not found in icons.json`);
|
|
return null;
|
|
}
|
|
|
|
// Convert single path to array format for consistency
|
|
if ("d" in icon) {
|
|
return {
|
|
paths: [icon as IconPath],
|
|
};
|
|
}
|
|
|
|
return icon as IconData;
|
|
}
|
|
}
|
|
</script>
|
|
|