-
-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom Icons #12
Comments
Thanks, glad you enjoy the workflow! For the custom icon sets, it's indeed possible for |
Well, using Vitesse as an example, and assuming I have a custom icon called <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 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 Edit: Maybe they could be called |
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. |
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.... 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" ;) |
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 ;-).
After thinking about it, I would propose to add one configuration key 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 In this case, LazyCollection could make a lookup in the Maybe the 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! |
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! |
💡 The Popular category from Icons8 is free, for example. |
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> |
Thanks everyone, it's now landed as v0.11! |
Works perfectly, thank you so much! |
Just as a reference, in order to integrate FontAwesome Pro icons via vite use some configuration like this. Add npm dependencies, esp.
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: |
Actually, the above mentioned approach has one big disadvantage: the fontawesome icons don't come with the SVG attribute 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 To make it work, I created a custom loader function that uses the same code as 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,
},
}),
],
}); |
@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. |
@antfu I created an issue and would appreciate your input on the "unplugin-icons" way of doing things. |
This is great, I've tried using the vscode-iconify with Vitesse and the DX is super good, I don't think I'll want to go back to the older days!
Which raises the following question: Is it possible to configure custom svgs to be loaded using the same system? I know since the icons are my own, I can just pack them in the project or create my own component to load them (which is what I've been doing so far). But it'd be great to be able of using the same affordances as the other icons, like seeing the icon preview in vscode and such.
The text was updated successfully, but these errors were encountered: