Newer
Older
vmk-ui-kit / src / vue / components / Icon.js
@Eugene Sukhodolskiy Eugene Sukhodolskiy 19 hours ago 1 KB so many changes
/**
 * VmkIcon — async inline SVG icon renderer.
 *
 * Loads icons via the shared icon helper and renders them as inline SVG.
 * The icon name is a VMK key such as "essentials/plus" or "arrows/arrow/right".
 */

import { defineComponent, h, onMounted, ref, watch } from "vue";
import { iconSvg } from "../../js/components/icon-helper.js";

export default defineComponent({
	name: "VmkIcon",
	inheritAttrs: false,
	props: {
		name: { type: String, default: "" },
		spin: { type: Boolean, default: false },
		phName: { type: String, default: "" }
	},
	setup(props, { attrs }) {
		const svg = ref("");

		const load = async () => {
			if (!props.name) {
				svg.value = "";
				return;
			}
			svg.value = await iconSvg(props.name);
		};

		onMounted(load);
		watch(() => props.name, load);

		return () => {
			if (!props.name) return null;

			// If the VMK SVG is missing and we know the Phosphor name,
			// fall back to the Phosphor icon font glyph.
			if (!svg.value && props.phName) {
				return h("i", {
					...attrs,
					class: ["ph", `ph-${props.phName}`, attrs.class],
					"aria-hidden": "true"
				});
			}

			return h("span", {
				...attrs,
				class: ["vmk-icon", { "is-spinning": props.spin }, attrs.class],
				innerHTML: svg.value,
				"aria-hidden": "true"
			});
		};
	}
});