Git Product home page Git Product logo

Comments (14)

antfu avatar antfu commented on May 20, 2024 7

Thanks everyone, it's now landed as v0.11!
https://github.com/antfu/unplugin-icons#custom-icons

from unplugin-icons.

chojnicki avatar chojnicki commented on May 20, 2024 5

I resolved problem, but not by using this package.

Vite-plugin-icons uses vite-plugin-components from same author (thanks @antfu for awesome work) for auto-discovery components, so Installed this instead. Then I combined this with vite-plugin-vue-svg for importing .svg as components. Simple as that, now we have universal package for any icons pack :)

After doing everything ready to work, I found that actually @antfu did exactly that in example from 3 days ago....
https://github.com/antfu/vite-plugin-components/blob/master/examples/vue3/vite.config.ts

But sure similar functionality should be available in vite-plugin-icons because it would be more straightforward. Anyone should be using any icons they want. After all this package is named "-icons" and not "-iconify" ;)

from unplugin-icons.

antfu avatar antfu commented on May 20, 2024 4

Thanks, glad you enjoy the workflow!

For the custom icon sets, it's indeed possible for vite-plugin-icons to support it. But we'd need to design a good API and conventions for loading the custom icons. What would you expect for how the API looks like to you can configure it?

from unplugin-icons.

NoelDeMartin avatar NoelDeMartin commented on May 20, 2024 4

Well, using Vitesse as an example, and assuming I have a custom icon called my-custom-icon.svg, I'd like to use it like this:

<vitesse-my-custom-icon />

Where "vitesse" is the namespace of my app, maybe by default it could be "app" if it isn't specified, so you'd write:

<app-my-custom-icon />

And I think it's pretty common to have icons under src/assets/icons, so that could also be a good default. Although I'm not sure if it's possible to know where the root of the project is.

With these, I think the configuration could be something like this:

// Specifying everything...
ViteIconsResolver({
    customIcons: {
        folder: '/~/assets/icons', // defaults to 'src/assets/icons'
        componentPrefix: 'vitesse', // defaults to 'app'
    },
});

// Or using all the defaults
ViteIconsResolver({
    customIcons: true;
});

And I would expect this to make any .svg from that folder available as an icon, using the file name as the icon name :).

Edit: Maybe they could be called localIcons or something else, if that's more clear. Naming is hard 😅.

from unplugin-icons.

jceb avatar jceb commented on May 20, 2024 2

Just as a reference, in order to integrate FontAwesome Pro icons via vite use some configuration like this.

Add npm dependencies, esp. @fortawesome/fontawesome-pro.

vite.config.js:

import { defineConfig } from "vite";
import Icons from "unplugin-icons/vite";
import IconsResolver from "unplugin-icons/resolver";
import AutoImport from "unplugin-auto-import/vite";
import { FileSystemIconLoader } from "unplugin-icons/loaders";
import { promises as fs } from "fs";

export default defineConfig({
  plugins: [
    ...,
    AutoImport({
      resolvers: [
        IconsResolver({
          prefix: "Icon",
          extension: "jsx",
          customCollections: [
            "fap-brands",
            "fap-duotone",
            "fap-light",
            "fap-regular",
            "fap-solid",
          ],
        }),
      ],
    }),

    Icons({
      compiler: "solid",
      customCollections: {
        "fap-brands": FileSystemIconLoader(
          "PATH_TO/node_modules/@fortawesome/fontawesome-pro/svgs/brands",
        ),
        "fap-duotone": FileSystemIconLoader(
          "PATH_TO/node_modules/@fortawesome/fontawesome-pro/svgs/duotone",
        ),
        "fap-regular": FileSystemIconLoader(
          "PATH_TO/node_modules/@fortawesome/fontawesome-pro/svgs/regular",
        ),
        "fap-solid": FileSystemIconLoader(
          "PATH_TO/node_modules/@fortawesome/fontawesome-pro/svgs/solid",
        ),
        "fap-light": FileSystemIconLoader(
          "PATH_TO/node_modules/@fortawesome/fontawesome-pro/svgs/light",
        ),
      },
    }),
  ],
});

Then import icons by placing this in your react/solid code: <IconFapSolidEnveleope />.

from unplugin-icons.

JohnCampionJr avatar JohnCampionJr commented on May 20, 2024 1

Could I also suggest an ability to import an Iconify JSON bundle? As an example, Font Awesome Pro JSONs are available but not part of the public Iconify bundles.

from unplugin-icons.

oliverpool avatar oliverpool commented on May 20, 2024 1

I really like this package, since it supports both vue 2 and 3 (maybe the compiler part could be integrated into https://github.com/vueuse/vue-demi ;-).

we'd need to design a good API and conventions for loading the custom icons. What would you expect for how the API looks like to you can configure it?

After thinking about it, I would propose to add one configuration key customCollections (or some other name) of type Record<string, IconCollection>:

export interface IconCollection {
  getIconData(icon: string): object | null; // like Iconify, { "body": "<path ...>", "width": 20, "height": 20} should be enough
}
export default {
  plugins: [
    Vue(),
    Icons({
      customCollections: {
          'app': new LazyCollection('./folder'),
      }
    })
  ],
}

This customCollection would be checked before (or inside) the getCollection(name) call.

In this case, LazyCollection could make a lookup in the ./folder on every call to getIconData. However I would expressly let implementations of IconCollection outside of this package, since there might be a lot of usecases (caching / svgo compression / FontAwesomePro / fallback...).
Maybe one implementation could live in this repo to serve as a base for the users to implement their own IconCollection.


Maybe the getIconData should be async (since loading the file would be done in a non-blocking way), but I don't have enough package experience to know if this is a good idea or not.


I think this very minimal API would be quite a powerful addition to this package, since it would make it pluggable to a lot of icon sources.

If enough people think that this would be a good idea, I would be glad to craft a PR.

@antfu thank you for you awesome work for the vue community!

from unplugin-icons.

Akryum avatar Akryum commented on May 20, 2024 1

Here are some icons I made, you are free to use them however you want:

~/src/assets/icons/SteeringWheel.svg

<svg
    fill="none"
    stroke-linecap="round"
    stroke-linejoin="round"
    stroke-width="2"
    viewBox="0 0 24 24"
    stroke="currentColor"
  ><path d="M12 14V20M10 12L4 10M14 12L20 10M21 12a9 9 0 11-18 0 9 9 0 0118 0zM14 12a2 2 0 11-4 0 2 2 0 014 0z" /></svg>

~/src/assets/icons/Car.svg

<svg
    fill="none"
    stroke-linecap="round"
    stroke-linejoin="round"
    stroke-width="2"
    viewBox="0 0 24 24"
    stroke="currentColor"
  ><path d="M17 10a4 4 0 0 0-4-4h-2a4 4 0 0 0-4 4m5-4v4M3 16h2m4 0h6m4 0h2v-3a3 3 0 0 0-3-3h-12a3 3 0 0 0-3 3v3M9 16a2 2 0 1 1-4 0a2 2 0 0 1 4 0zM19 16a2 2 0 1 1-4 0a2 2 0 0 1 4 0z" /></svg>

from unplugin-icons.

antfu avatar antfu commented on May 20, 2024

Could anyone offer me a small sample of custom icons (with the folder/file structure you would like) for me to experiment with the API design? It would be great if their license allow me to include them as examples in this repo in the future. Thanks!

from unplugin-icons.

m5o avatar m5o commented on May 20, 2024

💡 The Popular category from Icons8 is free, for example.
They only want to include a link and the License seems open source friendly for all the other categories.
Icons8 key feature: they offer icons in many different styles, icon naming and meaning are consistent. Useful for theming applications, you just need to change the icon style/file structure. Maybe this is a resource you’ll find interesting. ✌️

from unplugin-icons.

oliverpool avatar oliverpool commented on May 20, 2024

Works perfectly, thank you so much!

from unplugin-icons.

jceb avatar jceb commented on May 20, 2024

Actually, the above mentioned approach has one big disadvantage: the fontawesome icons don't come with the SVG attribute fill="currentColor" so the color can't be changed.

In order to make it work one has to build the icons first with a build script that's described here: iconify/iconify#4 (comment)

However, the compiled json files can be loaded directly into unplugin-icons because the loader (https://github.com/antfu/unplugin-icons/blob/e0cb01043b6eb462f4ea42b9b054382874495285/src/core/modern.ts#L51) is hard-coded receive only icons that are part of @iconify/json (https://github.com/antfu/unplugin-icons/blob/e0cb01043b6eb462f4ea42b9b054382874495285/src/core/loader.ts#L74). The customCollections attribute doesn't accept the JSON data structure that @iconify uses, instead it directly expects SVGs.

To make it work, I created a custom loader function that uses the same code as searchForIcon. Here's the whole code in vite.config.js:

import { defineConfig } from "vite";
import solid from "solid-start";
import Icons from "unplugin-icons/vite";
import IconsResolver from "unplugin-icons/resolver";
import AutoImport from "unplugin-auto-import/vite";
import _fab from "./json/fab.json";
import _fad from "./json/fad.json";
import _fal from "./json/fal.json";
import _far from "./json/far.json";
import _fas from "./json/fas.json";
import { iconToSVG } from "@iconify/utils/lib/svg/build";
import { getIconData } from "@iconify/utils/lib/icon-set/get-icon";
import { defaults as DefaultIconCustomizations } from "@iconify/utils/lib/customisations";

const getIcon = (iconSet) => (iconName) => {
  const iconData = getIconData(iconSet, iconName, true);
  if (iconData) {
    const scale = 1;
    const { attributes, body } = iconToSVG(iconData, {
      ...DefaultIconCustomizations,
      height: `${scale}em`,
      width: `${scale}em`,
    });
    return `<svg ${Object.entries(attributes)
      .map((i) => `${i[0]}="${i[1]}"`)
      .join(" ")}>${body}</svg>`;
  }
};

const fab = getIcon(_fab);
const fad = getIcon(_fad);
const fal = getIcon(_fal);
const far = getIcon(_far);
const fas = getIcon(_fas);


export default defineConfig({
  plugins: [
    solid(),
    AutoImport({
      resolvers: [
        IconsResolver({
          prefix: "Icon",
          extension: "jsx",
          customCollections: [
            "fap-brands",
            "fap-duotone",
            "fap-light",
            "fap-regular",
            "fap-solid",
          ],
        }),
      ],
    }),

    Icons({
      compiler: "solid",
      customCollections: {
        "fap-brands": fab,
        "fap-duotone": fad,
        "fap-light": fal,
        "fap-regular": far,
        "fap-solid": fas,
      },
    }),
  ],
});

from unplugin-icons.

antfu avatar antfu commented on May 20, 2024

@jceb thanks for the update! If you see a way to make it general, I am happy to have a PR to include this loader into the plugin directly.

from unplugin-icons.

jceb avatar jceb commented on May 20, 2024

@antfu I created an issue and would appreciate your input on the "unplugin-icons" way of doing things.

from unplugin-icons.

Related Issues (20)

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.