ionic-team / ionicons

Premium hand-crafted icons built by Ionic, for Ionic apps and web apps everywhere 🌎
http://ionicons.com
MIT License
17.55k stars 2.06k forks source link

Using Ionicons with a bundler #1133

Open raymondboswel opened 2 years ago

raymondboswel commented 2 years ago

URL https://ionic.io/ionicons/usage

I'm currently using ionicons along with Ionic v6 in a Svelte project bundled with Vite. I would like to have everything bundled for offline use, so using a remote reference such as in index.html as suggested by the documentation page is not a suitable strategy for me.

So the missing documentation is how to use Ionicons in a bundled context without using @ionic/angular / react / vue.

raymondboswel commented 2 years ago

I have found a dirty workaround, but I'm sure a better solution must exist. package.json postinstall script:

mkdir assets/ionicons; 
cp -R node_modules/ionicons/* assets/ionicons/; 
mkdir assets/ionicons/dist/esm/svg; 
cp node_modules/ionicons/dist/svg/* assets/ionicons/dist/esm/svg;

index.html:

<head>
...
<base href="/" >
<script type="module" src="ionicons/dist/esm/ionicons.js"></script>
...
</head>
raymondboswel commented 2 years ago

As mentioned here, https://github.com/ionic-team/ionic-framework/issues/24455, the solution is to import the actual icon itself and use the reference, instead of passing in a string reference. This isn't documented at https://ionic.io/ionicons/usage, so I'll leave this open for now.

Erudition commented 1 year ago

Wait, I'm using Elm to dynamically render html components that output like: <ion-icon name="stopwatch-outline"> ...and I don't want to use the CDN script. How can I get Vite to stop remapping the icons to /svg/stopwatch-outline.svg which causes a 404?

joezappie commented 8 months ago

I finally figured this one out myself that doesn't include copying during bundling:

All Icons

Probably not great performance wise

import { addIcons } from 'ionicons';
import { defineCustomElement } from 'ionicons/components/ion-icon.js';
import * as icons from 'ionicons/icons';

addIcons(icons);
defineCustomElement();

Select icons

import { addIcons } from 'ionicons';
import { defineCustomElement } from 'ionicons/components/ion-icon.js';
import { closeOutline, refreshOutline  } from 'ionicons/icons';

addIcons({closeOutline, refreshOutline  });
defineCustomElement();

Custom Icons

import { addIcons } from 'ionicons';
import { defineCustomElement } from 'ionicons/components/ion-icon.js';

const maximizeOutline = `data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><title>maximize</title><rect x="0.5" y="0.5" width="9" height="9"/></svg>`;

addIcons({maximizeOutline });
defineCustomElement();

Guessing it just converts camel case to kebab case but you can use custom elements with <ion-icon name='maximize-outline>`

It is annoying having to predefine all the icons you want to use instead of just letting the browser load svgs as it needs it, but I often want custom icons and this is much cleaner than using src="/path/to/file.svg".

Hope this helps, i wish ESM import would be documented because I work on government projects where we have NO internet and cant just load ion icons from a CDN.