GithubHelp home page GithubHelp logo

nuxt-icons's Introduction

nuxt-icons

Nuxt Icons

A module for Nuxt 3 that allows you to use your own SVG icons quickly and enjoyably.

playground-usage

Installation

  1. `npx nuxi@latest module add icons
  2. add nuxt-icons to modules, nuxt.config.ts:
export default defineNuxtConfig({
    modules: ['nuxt-icons']
})

Usage

  1. Create a icons folder in assets: assets/icons
  2. Drop your icons with the .svg extension into the icons folder
  3. In the project, use <nuxt-icon name="">, where name is the name of your svg icon from the folder

If you need to use the original color from the svg file (for example, if your icon has defs) you need to use the filled attribute:
<nuxt-icon name="mySuperIcon" filled />

Subfolders

If you would like to use some more complicated folder arrangement you will have to use paths from /icons

If you have a svg icon in nested directories such as:

📁icons
  └📁admin
  ⠀⠀└ badge.svg
  └📁user
  ⠀⠀└ badge.svg

then the icons's name will be based on its own path directory and filename. Therefore, the icon's name will be:

<nuxt-icon name="admin/badge"> and <nuxt-icon name="user/badge">

I don't like the basic styles that are assigned to the icons!

The styles that have been created for the icons look as follows:

width: 1em;
height: 1em;
margin-bottom: 0.125em;
vertical-align: middle;

You can easily change these styles using regular CSS for example in your index.vue file:

<style>
.nuxt-icon svg{
  margin-bottom: 0;
}
</style>

I would like to use icons from an icon pack available online

You can download icons in SVG format and put them in the /icons folder, or use another module that supports this natively: nuxt-icon

What this module does

The module retrieves all svg files from the assets/icons folder, overwrites the height and width from them to make them scalable, and using the <nuxt-icon> component allows them to be used. <nuxt-icon> injects the SVG code directly into <span>.

Features

  • Easy SVG icon management ✅
  • HMR (You don't have to reset the project to reload the icons) ✅
  • Ability to manipulate icons just like fonts, e.g. using color, font-size instead of fill,width,height
  • Ability to use the original color scheme for complex icons using the filled attribute ✅
  • Icon only loads if used ✅

Development

  • Run npm run dev:prepare to generate type stubs.
  • Use npm run dev to start playground in development mode.

Thoughts and ToDo's:

  • Automatic svg file optimization
  • Automatic icon scaling that have non-square dimensions to maintain their proportions (maybe with preserveAspectRatio)
  • Usable for previous nuxt versions (just use something like this)
  • If a lot of the same icons are used on the page create a separate svg sprite (significant improvement in performance)

A big thank you to @Diizzayy for his invaluable help in developing the project

nuxt-icons's People

Contributors

danielroe avatar ghettoddos avatar gitfoxcode avatar pi0 avatar shba007 avatar tdekoning avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

nuxt-icons's Issues

[feature request] Ability to define default properties for the `nuxt-icon` component

Describe
I think it would be nice to give this option to users in the configuration for the module. For example, for the :filled="true" property, my icons often break like this:
image
⬇️
image

More complex svg's often require me to manually set the fill="currentColor" attribute. It would be much more convenient if I didn't have to define the filled property every time when I use this component.

SVG Icons Not Displaying Correctly in Multi-Tabs (ID collision)

I don't know if this is a bug report or a feature request because I think it is not directly related to nuxt-icons. However, there is a problem, and I reported it here in the hope that someone comes up with a solution.

Describe the bug
When I use an SVG icon in 2 or more tab items, it doesn't display correctly.

To Reproduce

  1. Define a multi-tab using vuetify.
  2. Place the same SVG into all tabs
  3. Observe that only the first item displays correctly

Expected behavior
I expect all other SVGs in the other tabs to display correctly.

Desktop:

  • OS: Mac
  • Browser: Chrome/Firefox (It works with Safari but it has some other issues)
  • Version: Latest Versions

Reproduction link:
https://stackblitz.com/edit/github-remtxs-pnzwnx

Some Reaserch:
I believe that nuxt-icons should prefix IDs of defs with a unique value for each render.
Currently, it renders something like this for all SVGs in all tabs:

<defs>
    <linearGradient id="i" x1="64.421" x2="79.438" y1="71.286" y2="184.675" gradientUnits="userSpaceOnUse">...</linearGradient
    <linearGradient id="j" x1="52" x2="60.884" y1="46.942" y2="108.476" gradientUnits="userSpaceOnUse">...</linearGradient
    <linearGradient id="k" x1="107.644" x2="116.528" y1="46.942" y2="108.476" gradientUnits="userSpaceOnUse">...</linearGradient
</defs>

Since all of them are using the same ID (i, j, k), I think Chrome/Firefox only consider the defs of the first SVG, and when the first SVG is gone, all other SVGs face with the problem.




nuxt-icons.mp4

Ignoring width and height in <rect />

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  <rect opacity="0.3" width="12" height="2" rx="1" transform="matrix(-1 0 0 1 15.5 11)" fill="currentColor" />
  <path
    d="M13.6313 11.6927L11.8756 10.2297C11.4054 9.83785 11.3732 9.12683 11.806 8.69401C12.1957 8.3043 12.8216 8.28591 13.2336 8.65206L16.1592 11.2526C16.6067 11.6504 16.6067 12.3496 16.1592 12.7474L13.2336 15.3479C12.8216 15.7141 12.1957 15.6957 11.806 15.306C11.3732 14.8732 11.4054 14.1621 11.8756 13.7703L13.6313 12.3073C13.8232 12.1474 13.8232 11.8526 13.6313 11.6927Z"
    fill="currentColor" />
  <path
    d="M8 5V6C8 6.55228 8.44772 7 9 7C9.55228 7 10 6.55228 10 6C10 5.44772 10.4477 5 11 5H18C18.5523 5 19 5.44772 19 6V18C19 18.5523 18.5523 19 18 19H11C10.4477 19 10 18.5523 10 18C10 17.4477 9.55228 17 9 17C8.44772 17 8 17.4477 8 18V19C8 20.1046 8.89543 21 10 21H19C20.1046 21 21 20.1046 21 19V5C21 3.89543 20.1046 3 19 3H10C8.89543 3 8 3.89543 8 5Z"
    fill="currentColor" />
</svg>

Icon is not showing correctly because width and height in is module deleting.

`vue-tsc` error at line 26 of `nuxt-icon.vue`

Describe the bug
vue-tsc throws error for wrong type in nuxt-icon.vue at line 26.

 ERROR(vue-tsc)  Type 'Record<string, any>' is not assignable to type 'string'.
 /home/...../node_modules/.pnpm/[email protected]/node_modules/nuxt-icons/dist/runtime/components/nuxt-icon.vue:26:5
    24 |     })
    25 |     const rawIcon = await iconsImport[`/assets/icons/${props.name}.svg`]()
  > 26 |     icon.value = rawIcon
       |     ^^^^^^^^^^
    27 |   } catch {
    28 |     console.error(
    29 |       `[nuxt-icons] Icon '${props.name}' doesn't exist in 'assets/icons'`

To Reproduce
Enable typescript with typecheck: true

Expected behavior
Not sure about this.

Screenshots
N/A

Desktop (please complete the following information):

Cannot start nuxt: nuxtCtx.tryUse is not a function

When I added nuxt-icons to the modules array in the nuxt.config.js I get the following error while and after server restart

ERROR  Cannot start nuxt:  nuxtCtx.tryUse is not a function                              16:58:59

  at useNuxt (node_modules/nuxt-icons/node_modules/@nuxt/kit/dist/index.mjs:47:28)
  at addTemplate (node_modules/nuxt-icons/node_modules/@nuxt/kit/dist/index.mjs:58:16)
  at setup (node_modules/nuxt-icons/dist/module.mjs:18:5)
  at Object.normalizedModule (node_modules/nuxt-icons/node_modules/@nuxt/kit/dist/index.mjs:624:29)
  at async installModule (node_modules/@nuxt/kit/dist/index.mjs:432:3)
  at async initNuxt (node_modules/nuxt/dist/index.mjs:1362:7)
  at async load (node_modules/nuxi/dist/chunks/dev.mjs:6750:9)
  at async Object.invoke (node_modules/nuxi/dist/chunks/dev.mjs:6795:5)
  at async _main (node_modules/nuxi/dist/cli.mjs:46:20)

Issue with coloring in some cases

I have download a direct SVG file from phosphor icon and the SVG file itself seams straight forward. In my case it was airplane-tilt icon.

However I cant color it correctly. It will only add a new background color behind the Icon.
Not sure if I'm missing something in here.

ERROR [unimport] failed to find "NuxtIcons" imported from "#imports"

Tried to use a custom SVG icon with

<nuxt-icon name="bell"></nuxt-icon>

Nuxt returns with error

[vite] Internal server error: [unimport] failed to find "NuxtIcons" imported from "#imports"
  Plugin: nuxt:imports-transform
  File: /node_modules/nuxt-icons/dist/runtime/components/nuxt-icon.vue

Any way to disable the standard css?

Would is be smart to have a setting where you can turn off the standard css ? I know you can overwrite css. But with the fill currentColor it gives me problems with more complex svg's like a logo or one with multiple colors.

.nuxt-icon {
  width: 1em;
  height: 1em;
  margin-bottom: 0.125em;
  vertical-align: middle;
}
.nuxt-icon--fill,
.nuxt-icon--fill * {
  fill: currentColor;
}

Thanks for building this package!

Non existing icon causes whole page to fail

Describe the bug
Non existing icon causes whole page to fail. SSR fails with errorLog.ts:4 iconsImport[props.name] is not a function

To Reproduce
install version 3.0.0 of nuxt-icons

<nuxt-icon name="something-which-does-not-exist" />

Expected behavior
The behavior of version 2.x was fine where instead of an icon some text "undefined" was shown
It seems the issue has already been fixed with this commit but it seems it has not been published to npm.

Screenshots
n/a

Desktop (please complete the following information):

  • OS: any
  • Browser: any (error happens server-side as well, tested in node version 16.17.0)
  • Version: [email protected]

Smartphone (please complete the following information):

Additional context

Inconsistent SVG size in the output

Describe the bug
SVG sizes are different though they have same font size, especially if they have different viewbox size.

To Reproduce

<svg height="596" width="2500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 190.80200000000002">
  <path d="M187.888 178.122H143.52l-13.573-32.738H56.003l-12.366 32.738H0L66.667 12.776h47.761zM91.155 52.286L66.912 116.53h50.913zM349.056 12.776h35.88v165.346h-41.219V74.842l-44.608 51.877h-6.301l-44.605-51.877V178.12h-41.219V12.776h35.88l53.092 61.336zM489.375 12.776c60.364 0 91.391 37.573 91.391 82.909 0 47.517-30.058 82.437-96 82.437h-68.369V12.776zm-31.762 135.041h26.906c41.457 0 53.823-28.129 53.823-52.377 0-28.368-15.276-52.363-54.308-52.363h-26.422v104.74zM662.769 51.981L610.797 0H800v189.21l-51.972-51.975V51.981zM662.708 62.397L609.2 115.903v74.899h74.889l53.505-53.506h-74.886z" />
</svg>
<svg height="986" viewBox="4.7 3.1 388.2 150.6" width="2500" xmlns="http://www.w3.org/2000/svg">
  <path d="m4.7 5.2h28.1v28.1h-28.1zm27.4 146.4v-101.3h-26.7v101.2h26.7zm176.8 1v-24.8c-3.9 0-7.2-.2-9.6-.6-2.8-.4-4.9-1.4-6.3-2.8s-2.3-3.4-2.8-6.1c-.4-2.5-.6-5.8-.6-9.8v-35.3h19.3v-22.9h-19.3v-39.4h-26.7v97.9c0 8.3.7 15.3 2.1 20.9 1.4 5.5 3.8 10 7.1 13.4s7.7 5.8 13 7.3c5.4 1.5 12.2 2.2 20.3 2.2zm152.8-1v-148.5h-26.7v148.5zm-224.5-91.3c-7.4-8-17.8-12-31-12-6.4 0-12.3 1.3-17.5 3.9-5.3 2.6-9.7 6.2-13.3 10.8l-1.4 1.9v-14.6h-26.3v101.2h26.5v-53.9 1.9c.3-9.5 2.6-16.5 7-21 4.7-4.8 10.4-7.2 16.9-7.2 7.7 0 13.6 2.4 17.5 7 3.8 4.6 5.8 11.1 5.8 19.4v53.8h26.9v-57.4c.1-14.4-3.7-25.8-11.1-33.8zm184 40.5c0-7.3-1.3-14.1-3.8-20.5-2.6-6.3-6.2-11.9-10.7-16.7-4.6-4.8-10.1-8.5-16.5-11.2s-13.5-4-21.2-4c-7.3 0-14.2 1.4-20.6 4.1-6.4 2.8-12 6.5-16.7 11.2s-8.5 10.3-11.2 16.7c-2.8 6.4-4.1 13.3-4.1 20.6s1.3 14.2 3.9 20.6 6.3 12 10.9 16.7 10.3 8.5 16.9 11.2c6.6 2.8 13.9 4.2 21.7 4.2 22.6 0 36.6-10.3 45-19.9l-19.2-14.6c-4 4.8-13.6 11.3-25.6 11.3-7.5 0-13.7-1.7-18.4-5.2-4.7-3.4-7.9-8.2-9.6-14.1l-.3-.9h79.5zm-79.3-9.3c0-7.4 8.5-20.3 26.8-20.4 18.3 0 26.9 12.9 26.9 20.3zm150.2 47.3c-.5-1.2-1.2-2.2-2.1-3.1s-1.9-1.6-3.1-2.1-2.5-.8-3.8-.8c-1.4 0-2.6.3-3.8.8s-2.2 1.2-3.1 2.1-1.6 1.9-2.1 3.1-.8 2.5-.8 3.8c0 1.4.3 2.6.8 3.8s1.2 2.2 2.1 3.1 1.9 1.6 3.1 2.1 2.5.8 3.8.8c1.4 0 2.6-.3 3.8-.8s2.2-1.2 3.1-2.1 1.6-1.9 2.1-3.1.8-2.5.8-3.8-.3-2.6-.8-3.8zm-1.6 7c-.4 1-1 1.9-1.7 2.6s-1.6 1.3-2.6 1.7-2 .6-3.2.6c-1.1 0-2.2-.2-3.2-.6s-1.9-1-2.6-1.7-1.3-1.6-1.7-2.6-.6-2-.6-3.2c0-1.1.2-2.2.6-3.2s1-1.9 1.7-2.6 1.6-1.3 2.6-1.7 2-.6 3.2-.6c1.1 0 2.2.2 3.2.6s1.9 1 2.6 1.7 1.3 1.6 1.7 2.6.6 2 .6 3.2-.2 2.2-.6 3.2zm-5.6-2.3c.8-.1 1.4-.4 1.9-.9s.8-1.2.8-2.2c0-1.1-.3-1.9-1-2.5-.6-.6-1.7-.9-3-.9h-4.4v11.3h2.1v-4.6h1.5l2.8 4.6h2.2zm-1.1-1.7h-2.5v-3.2h2.5c.3 0 .6.1.9.2s.5.3.6.5c.2.2.2.5.2.9s-.1.7-.2.9c-.2.2-.4.4-.6.5-.3.1-.6.2-.9.2z" />
</svg>
 <div class="mt-6 grid grid-cols-2 gap-0.5 md:grid-cols-3 lg:mt-8">
        <div class="col-span-1 flex items-center justify-center py-8 px-8">
          <NuxtIcon name="brand/amd" class="text-[8rem] text-gray-300" />
        </div>
        <div class="col-span-1 flex items-center justify-center py-8 px-8">
          <NuxtIcon name="brand/intel" class="text-[8rem] text-gray-300" />
        </div>
  </div>

These two svg have different height, however the width is same, in the output result.
Also, using height: 2rem and font-size: 2rem has a very significant difference. To get the same result as height: 2rem font-size: 8rem needs to be used.

Expected behavior
All the icons should have same height, if it has same font size. The font size is supposed to alter the height first and then width. (Correct me if I'm wrong here).
Also, I suppose height and font-size should behave same, in this context.

Screenshots
image

Desktop (please complete the following information):

  • Operating System: Linux
  • Node Version: v16.18.1
  • Nuxt Version: 3.1.1
  • Nitro Version: 2.1.0
  • Package Manager: [email protected]
  • Builder: vite
  • User Config: extends, app, modules
  • Runtime Modules: @nuxtjs/[email protected], nuxt-icons
  • Build Modules: -

Additional context

.nuxt-icon svg {
    /* width: 1em; */
    height: 1em;
    /* margin-bottom: 0.125em; */
    vertical-align: middle;
}

Disabling width somewhat gives the expected result. Also, margin-bottom seems redundant here.

I suppose, width and height are set to 1em to make the ratio square.

A option to override the default css would do the job probably.

Icons are getting filled by default

I am using linear svg pack, but the module is automatically filling in the svg icon even though the svg explicitly sets fill to none. Interestingly, however, when I add the filled prop icons are displayed normally, without automatic filling. Isn't the filled prop supposed to work the other way around?

This is my svg icon code:
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M20.39 10.13L14.34 13.16C13.59 13.54 13.11 14.31 13.11 15.15V20.8701C13.11 21.7001 13.98 22.2301 14.72 21.8601L20.77 18.83C21.52 18.45 22 17.68 22 16.84V11.12C22 10.29 21.13 9.76005 20.39 10.13Z" stroke="#292D32" stroke- width="1.5" stroke-linecap="round" stroke-linejoin="round"/> </svg>

"Icon only loads if used" is probably not true

Describe the bug
I'm afraid that the statement "Icon only loads if used" in the documentation is unfortunately not true. During the yarn generate command, all the icons from the ~/assets/icons folder appeared in the .output/public/_nuxt. For example, the test-icon icon, which I don't use anywhere in the project:
image

I think it has to do with Vite's lousy import handling (import.meta.glob). I have no idea how or if it is possible to fix this, but I also encountered this problem when I wanted to dynamically fetch images from ~/assets/images with:

import.meta.glob('/assets/images/**/**.svg', { as: 'url', eager: false });

To Reproduce

  1. Add unnecessary icons to ~/assets/icons folder
  2. Run yarn/npm generate command and see .output/public/_nuxt

Expected behavior
It would be great to fix it. I've been looking for a way to dynamically download images from Vite for several months now and it's slowly driving me crazy. I'm thinking more and more seriously about migrating to webpack.

Icons aren't rendered on the SSR

Describe the bug
Icons in wrapper aren't rendered on the SSR

To Reproduce
typical use NuxtIcon component. (client-only is not used anywhere above)

  <button
            aria-describedby="cart"
        >
            <NuxtIcon name="cart" filled class="text-2xl lg:text-3xl relative" aria-hidden="true" />
            <span
                v-if="isFull"
                class="w-[7px] h-[7px] bg-green block rounded-full absolute top-0 -right-0.5 lg:top-1"
                aria-hidden="true"
            />
        </button>

Expected behavior
Icons should render at ssr

Screenshots
Screen from SSR preview ( extension for chrome)
image

After render all
image

Desktop (please complete the following information):

  • OS: Linux Ubuntu
  • Browser Brave/Chrome

Additional context
Add any other context about the problem here.

Module improvement suggestions

Hi! Some small things i've noticed in module can be improved:

  • Please use a fixed version of @nuxt/kit in dependencies and not edge! (
    "@nuxt/kit": "npm:@nuxt/kit-edge@latest"
    ). It can be like "3.0.0-rc.2"
  • There is a leftover addPlugin option remaining from template (
    addPlugin: boolean
    )
  • We have addAutoImports utility from kit as well :)
  • (just heads up) Signigurare of resolveFiles from kit might be changed before 3.0.0 release.

Icon not showing in chrome based browsers

Describe the bug
Icon not appearing in chrome browsers

To Reproduce
This is the icon I'm using. It shows fine in Safari and Firefox but it won't appear in Chrome nor Opera.

<svg width="533" height="531" viewBox="0 0 533 531" fill="none" xmlns="http://www.w3.org/2000/svg"> <g filter="url(#filter0_b_127_1002)"> <path d="M532.709 265.745C532.709 412.227 413.458 530.974 266.355 530.974C119.251 530.974 0 412.227 0 265.745C0 119.263 119.251 0.5159 266.355 0.5159C413.458 0.5159 532.709 119.263 532.709 265.745ZM119.957 265.745C119.957 346.257 185.501 411.524 266.355 411.524C347.208 411.524 412.753 346.257 412.753 265.745C412.753 185.233 347.208 119.966 266.355 119.966C185.501 119.966 119.957 185.233 119.957 265.745Z" fill="#586B4B" fill-opacity="0.1"/> </g> <g filter="url(#filter1_b_127_1002)"> <path d="M389.403 265.745C389.403 333.081 334.48 387.668 266.73 387.668C198.979 387.668 144.057 333.081 144.057 265.745C144.057 198.409 198.979 143.822 266.73 143.822C334.48 143.822 389.403 198.409 389.403 265.745ZM217.66 265.745C217.66 292.679 239.629 314.514 266.73 314.514C293.83 314.514 315.799 292.679 315.799 265.745C315.799 238.811 293.83 216.976 266.73 216.976C239.629 216.976 217.66 238.811 217.66 265.745Z" fill="#586B4B" fill-opacity="0.1"/> </g> <defs> <filter id="filter0_b_127_1002" x="-6.75265" y="-6.23675" width="546.214" height="543.963" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> <feFlood flood-opacity="0" result="BackgroundImageFix"/> <feGaussianBlur in="BackgroundImageFix" stdDeviation="3.37633"/> <feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_127_1002"/> <feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_127_1002" result="shape"/> </filter> <filter id="filter1_b_127_1002" x="137.304" y="137.069" width="258.852" height="257.351" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> <feFlood flood-opacity="0" result="BackgroundImageFix"/> <feGaussianBlur in="BackgroundImageFix" stdDeviation="3.37633"/> <feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_127_1002"/> <feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_127_1002" result="shape"/> </filter> </defs> </svg>

Expected behavior
For the icon to show in any browser.

Screenshots
image

image

Desktop (please complete the following information):

  • OS: MacOS Ventura 13.0
  • Browser: chrome 109.0.5414.87, opera 94.0.4606.65

nuxt-icons doesn't work in rc versions of nuxt3

tried installing it on nuxtjs 3.0.0-rc.9, this occurs:

WARN Module nuxt-icons is disabled due to incompatibility issues: 10:44:03

  • [nuxt] Nuxt version ^3.0.0 is required but currently using 3.0.0-rc.9

Prop type failed for prop "name"

Hi there, thanks for great work!
Just want to ask if there is possibility to specify type props for name, since using conditional icon rendering with
<nuxt-icon :name="[ SomeCondition ?IconName-1:IconName-2, ]"
getting errors in console.
Of course there are workarounds for that, but I am just curioous, if prop types could be somehow specified for name.
Thank you!

Wrong `<nuxt-icon />` type

Describe the bug
Like below.

To Reproduce
Install and use.

Expected behavior
Green highlight and correct component type.

Screenshots
image

Additional context


vue-tsc error at line 27 of nuxt-icon.vue, while activated noUncheckedIndexedAccess in tsconfig

Describe the bug
I found a bug about type error.
vue-tsc error at line 27 of nuxt-icon.vue, while activated noUncheckedIndexedAccess in tsconfig.

To Reproduce

It occurs vue-tsc error on building nuxt-icons.

  • nuxt.config.ts
export default defineNuxtConfig({
  ssr: false,
  typescript: {
    typeCheck: true,
  },
  app: {
    head: {
      charset: 'utf-8',
      title: '',
    },
  },
  modules: ['nuxt-icons'],
  vue: {
    compilerOptions: {
      whitespace: 'preserve',
    },
  },
  telemetry: false,
  devtools: {
    enabled: true
  },
})
  • tsconfig.json
{
  "extends": "./.nuxt/tsconfig.json",
  "compilerOptions": {
    "noUncheckedIndexedAccess": true
  }
}
  • package.json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "author": "",
  "scripts": {
    "build": "nuxt build",
    "dev": "rm -rf /tmp/nitro && HOST=0.0.0.0 PORT=8080 nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare",
  },
  "dependencies": {
    "nuxt": "^3.8.2",
    "nuxt-icons": "^3.2.1",
    "sass": "^1.69.5",
    "vue": "^3.3.10",
  },
  "devDependencies": {
    "@nuxt/devtools": "latest",
    "typescript": "^5.4.3",
    "vue-tsc": "^1.8.27"
  },
  "optionalDependencies": {
    "@rollup/rollup-linux-arm64-gnu": "^4.9.1",
    "@rollup/rollup-linux-x64-gnu": "^4.9.1"
  }
}

Expected behavior

// nuxt-icons/dist/runtime 27 line
const rawIcon = await iconsImport[`/assets/icons/${props.name}.svg`]()

Maybe, It needs to fix.

const iconsImportFunc = iconsImport[`/assets/icons/${props.name}.svg`]
if (iconsImportFunc === undefined) {
  return
}
const rawIcon = await iconsImportFunc()

Screenshots
スクリーンショット 2024-04-08 16 46 38

Desktop (please complete the following information):

  • OS: Apple M2 13.5
  • Browser: Chrome
  • Version: 122.0.6261.112(Official Build) (arm64)

icons not rendered correctly with nuxt-icon

When I use this Icon with nuxt-icon it doesn't render correctly

image

Svg:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="10" height="10" viewBox="0 0 10 10">
    <defs>
        <path id="a" d="M2.69 1.019H.057v.424H2.69c.101.469.497.827.997.827.497 0 .896-.358.996-.827h3.126v-.424H4.683a1.025 1.025 0 0 0-.996-.827c-.499 0-.895.358-.997.827z"/>
        <path id="c" d="M5.85 1.749H.018v.424H5.85c.099.468.498.828.995.828a1.04 1.04 0 0 0 0-2.08c-.497 0-.896.359-.995.828z"/>
        <path id="e" d="M5.831 1.262H0v.423h5.831c.099.47.498.828.995.828a1.04 1.04 0 0 0 1.04-1.039c0-.574-.467-1.04-1.04-1.04-.497 0-.896.359-.995.828z"/>
    </defs>
    <g fill="none" fill-rule="evenodd">
        <g transform="translate(1 3.566)">
            <mask id="b" fill="#fff">
                <use xlink:href="#a"/>
            </mask>
            <path fill="#14D719" d="M-4.943 7.27h17.752V-4.808H-4.943z" mask="url(#b)"/>
        </g>
        <g transform="translate(1 5.566)">
            <mask id="d" fill="#fff">
                <use xlink:href="#c"/>
            </mask>
            <path fill="#14D719" d="M-4.981 8h17.866V-4.079H-4.981z" mask="url(#d)"/>
        </g>
        <g transform="translate(1 .566)">
            <mask id="f" fill="#fff">
                <use xlink:href="#e"/>
            </mask>
            <path fill="#14D719" d="M-5 7.513h17.866V-4.566H-5z" mask="url(#f)"/>
        </g>
    </g>
</svg>

Expected behavior
here is the same icon just with inline-svg
image

Desktop:

  • OS: windows
  • Browser: tested all but safari - all have the issue
  • Versions: latest

Nuxt-Icon applies classes to all imported svgs using svgo

Describe the bug
I'm using nuxt-icon for my icons, but i tried to use svgo to import a custom svg (not icon, illustration). The issue is that nuxt-icon is adding .nuxt-icon and .nuxt-icon--fill to the svg breaking his original fill.

Here is my nuxt.config

modules: ['woonuxt-settings', 'nuxt-graphql-client', '@nuxtjs/tailwindcss', 'nuxt-icon', '@nuxt/image', '@nuxtjs/i18n', '@pinia/nuxt', '@nuxtjs/device', 'nuxt-svgo'],
svgoOptions: {
svgo: true,
defaultImport: 'component',
svgoConfig: {
multipass: true,
removeViewBox: false,
},
},

Responsive Icon hit area too big

Hi, great work!

I just found an issue and I was wondering if this could help in any way. In the CSS you declare this:

.nuxt-config svg {
    width: 1em;
    height: 1em; // <-- This is causing a huge hit area for rectangle svg's
    margin-bottom: 0.125em; // <-- This should be choose by the developer
    vertical-align: middle;
}

Right now I am overriding these 2 rules with !important which works fine but I think this can be improved. As you can see in the next image the hit area is perfectly align with the svg itself.

Screenshot 2022-12-07 at 16 16 00

On the other hand, the next image shows the bigger hit area, this could possibly cause issues when dealing with other elements on the page.

Screenshot 2022-12-07 at 16 16 15

For the height issue I suggest just using height: auto as default.
For the margin bottom I suggest using css-vars instead, something like margin-botton: var(--ni-margin-bottom, '0'), this way we as developers could override the value without the need of !important rules. Also noticed that I suggested 0 instead of 0.125em because having margings on SVG could cause UI design issues when dealing with icon buttons and suchs.

How can it be loaded on demand?

This scheme will write all svg to nuxticons.mjs file, my project has several thousand svg icons, nuxticons.mjs file will be over 5mb.

How can it be loaded on demand?

Configuration option: icons path

I need to load my icons from a package without saving them to assets/icons. We get our icons from a shared component library which has a package containing all our system icons. These icons should be able to change without our teams intervention. I see that you have the path hardcoded in getIcon(), but would it be possible to add a configuration option for where to look for svg files?

// some config file
{
  path: '@my-components/icons/svg'
}

TypeError: iconsImport[props.name] is not a function

I got the newest version ^3.0.0. with Nuxt 3.0.0 running and see the following error:

[nitro] [dev] [unhandledRejection] TypeError: iconsImport[props.name] is not a function

My imported icons looks like this:

<nuxt-icon class="s-icon" name="NavEarth" />

I also tried to bind the name value:

<nuxt-icon class="s-icon" :name="'NavEarth'" />

but it doesnt work either.

Not using `fill` attribute creates fill in `stroke` only SVGs - no way to target stroke!

My Icon pack mostly makes use of stroke in the SVGs

When NOT using the fill attribute, all strokes in the SVG are filled with shapes. This breaks the icons visually.
Adding the fill attribute fixes rendering.
This is linguistically confusing as you are adding a fill color by not using fill attribute - but using fill attribute uses the original fill? 🤔

Also There is currently no way to target the stroke of the SVG to set color.

p.s. @gitFoxCode Epic work here! Exactly what I was looking for!

Name prop format

Is it possible to change the name format? In the project I use kebab-case for svg icons and it looks quite strange. So far, I have used the format preferred by @nuxtjs/svg-sprite (e.g: "fa/ban-solid"). It would be nice to be able to use something similar here.
image
image

I also have if the module is working properly. Currently, I can only use icons nested in a folder. Those located directly in it (without prefix) don't work. Is this the expected behavior?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.