Skip to content

Instantly share code, notes, and snippets.

@dominique-mueller
Created January 29, 2024 14:17
Show Gist options
  • Save dominique-mueller/244e5122b92361e7a585ddff6bc1b7a4 to your computer and use it in GitHub Desktop.
Save dominique-mueller/244e5122b92361e7a585ddff6bc1b7a4 to your computer and use it in GitHub Desktop.
Nuxt Icon Component
<script lang="ts" setup>
/**
* Icon Component
*
* Inspired by <https://github.com/gitFoxCode/nuxt-icons/blob/d7e4e5b0f59c923fe97c7b9eebd5b94be0650180/src/runtime/components/nuxt-icon.vue>
*/
// Props
const props = defineProps({
name: {
required: true,
type: String,
},
});
/**
* Load (svg) icon as (Vue) component
*/
async function loadIconAsComponent(name: string) {
try {
// Load module info for all svg icons
// Note: This uses Vite-specific functionality, see <https://vitejs.dev/guide/features#glob-import>
const allIconsAsModules = import.meta.glob<Component>('/assets/icons/*.svg', {
as: 'component', // Import as Vue component - via "vite-svg-loader"
eager: false, // Lazy-loaded
});
const iconComponent = await allIconsAsModules[`/assets/icons/${name}.svg`]();
return iconComponent;
} catch {
console.error(`Icon with the name '${name}' does not exist in the 'assets/icons' folder.`);
}
}
const iconComponent = ref<Component>();
iconComponent.value = await loadIconAsComponent(props.name);
watch(
() => props.name,
async (newName) => {
iconComponent.value = await loadIconAsComponent(newName);
},
);
</script>
<template>
<component :is="iconComponent" role="img" aria-hidden="true" focusable="false" />
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment