Skip to content

obewds/icon-svg-to-vue

Repository files navigation

icon-svg-to-vue

Tiny node-based utility scripts to convert icon svg markup to vue/typescript components

GitHub package.json version   npm


Check out the CHANGELOG


Documentation

A quick overview of the package functionality.

Installation

npm install @obewds/icon-svg-to-vue

Use

Use npx to run the script from your project's root directory via a command line with something like this:

npx icon-svg-to-vue path/to/icon-file.svg path/to/IconFile.vue

Arguments

The command requires two arguments.

Argument Description
1st The path from the root directory (no leading dots or slashes) to the source path-based SVG file.
2nd The path from the root directory (no leading dots or slashes) to the output destination for the Vue component version of the icon SVG to end up.

Examples

Let's say you have some icon SVG markup from free icon providers like FontAwesome or Heroicons. For this example, we'll use FontAwesome's free house.svg and Heroicons' backspace.svg icons.

Now let's assume you've brought them into your Vue project (along with any licensing files 😉), giving you the following hierarchy:

.
├─ node_modules
├─ iconSvgs
│  ├─ fontAwesome
│  │  └─ free
│  │     └─ house.svg
│  ├─ heroicons
│  │  └─ outline
│  │     └─ backspace.svg
├─ src
│  ├─ components
│  │  ├─ HelloWorld.vue
│  │  └─ SomeComponent.vue
│  ├─ App.vue
│  ├─ main.ts
│  ├─ index.ts
│  └─ ...
├─ package-lock.json
├─ package.json
├─ vite.config.ts
├─ vitest.config.ts
└─ ...

SVG Paths and Files

If we wanted to convert the house.svg and backspace.svg icons to Vue files using this package, we'd want to construct our two paths to the SVG files (without any leading dots or slashes).

So for the house.svg icon, we'd get:

iconSvgs/fontAwesome/free/house.svg

And for the backspace.svg icon, we'd get:

iconSvgs/heroicons/outline/backspace.svg

Vue Paths and Files

Next up we'll want to figure out the other argument, mainly where the new Vue version of the file should go!

So for the house.svg icon, we'd want something like:

src/components/fontAwesome/free/FaFreeHouse.vue

And for the backspace.svg icon, we'd get:

src/components/heroicons/outline/HiOutlineBackspace.vue

Finished Commands

Now we can put things together to run this package's script.

So for the house.svg icon:

npx icon-svg-to-vue iconSvgs/fontAwesome/free/house.svg src/components/fontAwesome/free/FaFreeHouse.vue

And for the backspace.svg icon:

npx icon-svg-to-vue iconSvgs/heroicons/outline/backspace.svg src/components/heroicons/outline/HiOutlineBackspace.vue

Final Output

Running those finished commands would change your files to now look like this:

.
├─ node_modules
├─ iconSvgs
│  ├─ fontAwesome
│  │  └─ free
│  │     └─ FaFreeHouse.vue
│  ├─ heroicons
│  │  └─ outline
│  │     └─ HiOutlineBackspace.vue
├─ src
│  ├─ components
│  │  ├─ fontAwesome
│  │  │  └─ free
│  │  │     └─ house.svg
│  │  ├─ heroicons
│  │  │  └─ outline
│  │  │     └─ backspace.svg
│  │  ├─ HelloWorld.vue
│  │  └─ SomeComponent.vue
│  ├─ App.vue
│  ├─ main.ts
│  ├─ index.ts
│  └─ ...
├─ package-lock.json
├─ package.json
├─ vite.config.ts
├─ vitest.config.ts
└─ ...

This means you could call your new components in a Vue and Tailwind CSS project for example, like this:

<!-- ./src/components/SomeComponent.vue -->

<script setup lang="ts">
    import FaFreeHouse from './fontAwesome/free/FaFreeHouse.vue'
    import HiOutlineBackspace from './heroicons/outline/HiOutlineBackspace.vue'
</script>

<template>
    <div class="flex justify-center items-center gap-10">
        <FaFreeHouse
            class="w-20"
            fill-classes="fill-blue-700 dark:fill-blue-300"
        />
        <HiOutlineBackspace
            class="w-20"
            fill-classes="fill-blue-700 dark:fill-blue-300"
        />
    </div>
</template>

Mutations

This package does mutate the source SVG code a tiny bit. Right now this mutation mainly focuses on the removing some downstream use blocking defaults from typical SVG icons from the two sets of icons in the examples above - IE FontAwesome and Heroicons.

  • In the case of the former, this package's command line script will change the characters !--! to just !--.
  • In the case of the latter, it will remove the strings class="w-6 h-6" and class="w-5 h-5".
  • In both cases, the icon SVG's child node path elements will each have a Vue prop-driven :class="fillClasses" string added to them.

All together this means you can control the sizing for your new SVG Vue components using the class attribute on the component instance itself, and can control the color of the icon itself using the Vue prop fill-classes="..." on the same component instance (yay one-liners).

Moving Forward

This package came to be after one too many issues from icon providers, even with their awesome JavaScript integrations. So this package essentially allows for Vue-ifying a couple of the major icon providers' icons in a very fast, easy and specific way so coders can get back to coding and stop losing time to icons libraries.

That said, it'd be interesting to over time find out how this basic idea can be adapted to most of the free SVG icon providers out there!

So feel free to make a PR and maybe down the road and if needed we can simply add another argument to specify a type of icon to strip down and convert to Vue.js goodness!


About

Tiny node-based utility scripts to convert icon svg markup to vue/typescript components

Resources

License

Stars

Watchers

Forks

Packages

No packages published