ionicons icon indicating copy to clipboard operation
ionicons copied to clipboard

ionic 4 custom icons

Open chukwu opened this issue 5 years ago โ€ข 36 comments

Migrating from ionic 3 to ionic 4 doesn't look and feel as easy as the ionic team say.

  1. How do i add extra custom icons compatible to tabs, buttons and everything
<ion-icon name="my-custom-icon"></ion-icon>
<ion-tab label="Music" icon="my-custom-icon"></ion-tab>

Without a documentation or tutorial, migrating would be a waste of my time. Alot has changed and thus far, this seems to be the most painful

chukwu avatar Aug 02 '18 07:08 chukwu

@chukwu Look at this issue: https://github.com/ionic-team/ionic/issues/14857 Working demo here: https://aesvg.adaept.com/ Repo here: https://github.com/peterennis/ae-svg-components

Custom icons would also be svg. Look in the iconicons repo here: https://github.com/ionic-team/ionicons

Here is an example of a custom icon: https://aetabs.adaept.com/tabs/(contact:contact) Repo here: https://github.com/peterennis/aetabs/blob/master/src/app/pages/contact/contact.page.html

Documentation is behind the curve but being worked on by the ionic team ๐Ÿ˜„

peterennis avatar Aug 03 '18 06:08 peterennis

@peterennis How do I add custom svg icons to the tabbar ? in ionic 3 I did this:

$home-active: url(../assets/svg/homeactive.svg);
$home-inactive: url(../assets/svg/homeinactive.svg);

ion-icon {
      &[class*="aw-"] {
      mask-size: contain;
      mask-position: 50% 50%;
      mask-repeat: no-repeat;
      background: transparent;
      --ion-color-base: transparent !important;
     
    }

      &[class*="aw-home"] {
        mask-image: $home-inactive;
        .tab-button[aria-selected=true] & {
          mask-image: $home-active;
        }
     }

Now this does not work.

Awoshe avatar Aug 03 '18 12:08 Awoshe

@brandyscarney @manucorporat @adamdbradley Looks like custom icons is becoming a constant request. I also have an example for Ionic 3 here: https://aeicons.adaept.com/ Repo: https://github.com/peterennis/aeicons If you provide some guidance on this I will update the repo with the recommended official solution.

peterennis avatar Aug 04 '18 19:08 peterennis

You can slightly modify the build config to add new icons to the ionicons library, and use them anywhere.

  1. Create a new folder in your project to store your custom icons, i.e. src/assets/custom-ion-icons.
  2. Modify angular.json. Find this section:
            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              }
            ],

See how it's packaging all the svg files from the ionic library into "./svg"? Those are the default icons. Whenever you use one of the default icons, your app finds it in that output directory. We can add our own icons to that directory. Add one more object to the "assets" array, so it looks like this:

            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "src/assets/custom-ion-icons",
                "output": "./svg"
              }
            ],
  1. Create your own icons and save them to your custom-ion-icons folder. For each new icon, create two files (one for iOS, one for android/material-design). The following would create a new icon named "newicon":
src/assets/custom-ion-icons/ios-newicon.svg
src/assets/custom-ion-icons/md-newicon.svg

The svg image should consist of shapes with black fills. Strokes won't always show up, depending on the context.

  1. Use your icon anywhere, using the name "newicon"!
<ion-icon name="newicon"></ion-icon>
<ion-tabs>
  <ion-tab label="your-tab-label" icon="newicon" href="/tabs/(home:home)">
    <ion-router-outlet name="your-outlet-name"></ion-router-outlet>
  </ion-tab>
</ion-tabs>

ransoing avatar Aug 31 '18 23:08 ransoing

@ransoing .... I'll try this. If it works, then I'm all set for migration. It actually looks easier this way than IONIC 3. The next big thing would be to modify my CSS nestings due to shadow DOM restrictions.

Thanks mate.

chukwu avatar Sep 01 '18 19:09 chukwu

Giving it a little bit more thought, it would be better to put your custom-ion-icons folder as a sibling to src, because otherwise your icons will be included twice in the final package.

ransoing avatar Sep 01 '18 19:09 ransoing

I've discovered that this may not work properly if your custom svg file defines any colors. The ionic framework overrides svg fill colors with CSS, and defining colors in the svg file may prevent ionic from setting colors properly.

ransoing avatar Sep 03 '18 17:09 ransoing

@ransoing Here: https://github.com/peterennis/ae-svg-components/blob/master/src/index.html#L38 I use a component for custom colors - restricting it to named W3C colors by choice. What do you think about the potential/value for swapping ionicons library with such a custom configuration? Somewhat along the lines of a plugin. I am not sure of the integration needed to get this working in ionic.

peterennis avatar Sep 07 '18 21:09 peterennis

@ransoing Your approach is the most elegant, but for me it works on first load. As soon as I reload the app I get the GET http://localhost:8100/svg/ios-message.svg 404 (Not Found) error. I've set up a custom-ion-icons folder as sibling to src folder with an ios-message.svg and a md-message.svg.

angular.json:

"assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "custom-ion-icons",
                "output": "./svg"
              }
            ]

I guess you could always do something like <ion-icon src="/custom-ion-icons/ios-message.svg" slot="start"></ion-icon>, but is not that elegant of an approach.

Anyone any thoughts on why it only works on initial load ? Thanks!

narcodico avatar Sep 28 '18 22:09 narcodico

@RollyPeres does it work properly if you put your custom-ion-icons inside your src folder? I wonder if there's something weird going on when it detects changes in src and recompiles.

ransoing avatar Oct 08 '18 22:10 ransoing

@anyangdp will check it out. Nice!

narcodico avatar Dec 07 '18 16:12 narcodico

@anyangdp @RollyPeres updated english in the gist here: https://gist.github.com/peterennis/35e4ff213a6f98a1c83ecf15600a51c5

peterennis avatar Dec 07 '18 21:12 peterennis

@ransoing Thanks your solution worked! However importing google material icons, it imports with a square box around it. Is this normal? I'm importing 24DP svgs.

screen shot 2018-12-08 at 11 56 39 am screen shot 2018-12-08 at 11 58 23 am

bkarv avatar Dec 08 '18 00:12 bkarv

@bkarv did you find a solution to this problem. I have the same issue. A black box around the svg.

johnbrattaker avatar Dec 21 '18 12:12 johnbrattaker

No i haven't at this moment. I noticed though the SVG file for Ionic icons are blown compared to a small icon in the top left hand corner for google icons. So it has to be something the format setting.

Iconic Icon screen shot 2018-12-24 at 1 34 20 am

Google Icon screen shot 2018-12-24 at 1 34 57 am

bkarv avatar Dec 23 '18 14:12 bkarv

@bkarv did you find a solution to this problem. I have the same issue. A black box around the svg.

@johnbrattaker Further to above, although I haven't found solution for google icons but the icons from swift svg icons import without the square box into ionic. https://www.swifticons.com I am pretty sure you can fix the google icons problem with an svg editor.

bkarv avatar Dec 29 '18 00:12 bkarv

So has anyone been able to do this with a .png image ? In V3 i was able to do it with a hack like below in app.scss

.ion-md-menu{
    background: no-repeat;
    background-position: center;
    background-image: url('assets/icon/lightbulb.png');
    height: 100%;
    background-size: contain;
    color: rgb(60,60,60)!important;
}

azyth avatar Feb 05 '19 16:02 azyth

@bkarv did you find a solution to this problem. I have the same issue. A black box around the svg.

@johnbrattaker Further to above, although I haven't found solution for google icons but the icons from swift svg icons import without the square box into ionic. https://www.swifticons.com I am pretty sure you can fix the google icons problem with an svg editor.

If it's still relevant. I've found a solution. The border box is actually part of the svg of the material icon when you download it. You can open it in any text editor and delete the rectangle path that looks something like this: <path fill="none" d="M0 0h24v24H0V0z"/>

genadis avatar Mar 02 '19 21:03 genadis

So has anyone been able to do this with a .png image ? In V3 i was able to do it with a hack like below in app.scss

.ion-md-menu{
    background: no-repeat;
    background-position: center;
    background-image: url('assets/icon/lightbulb.png');
    height: 100%;
    background-size: contain;
    color: rgb(60,60,60)!important;
}

image

image

zzmmbb avatar Mar 08 '19 01:03 zzmmbb

any suggestion with vue.js? ๐Ÿ™

sg0rd avatar May 23 '19 15:05 sg0rd

How to put the www file directly into your Objective-C project ๏ผŸ

xuwenshan avatar Jun 27 '19 05:06 xuwenshan

Anyone have a good solution to using Font Awesome icons? They don't bundle svg files AFAICT, it's a js file that exports the svg path...

Edit: Of course once I break down to ask for help I figure it out ๐Ÿ™„

I used @ransoing's approach and to make Font Awesome work I downloaded the desktop version of the icons which includes the svg icons. I then duplicated the svg I wanted and prefixed it with ios- and md- then I was able to use it in my tabs ๐Ÿ™Œ. I wish there was an easy way to expose all of them but this works for now

joshstrange avatar Jun 28 '19 04:06 joshstrange

You can slightly modify the build config to add new icons to the ionicons library, and use them anywhere.

  1. Create a new folder in your project to store your custom icons, i.e. src/assets/custom-ion-icons.
  2. Modify angular.json. Find this section:
            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              }
            ],

See how it's packaging all the svg files from the ionic library into "./svg"? Those are the default icons. Whenever you use one of the default icons, your app finds it in that output directory. We can add our own icons to that directory. Add one more object to the "assets" array, so it looks like this:

            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/@ionic/angular/dist/ionic/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "src/assets/custom-ion-icons",
                "output": "./svg"
              }
            ],
  1. Create your own icons and save them to your custom-ion-icons folder. ~~For each new icon, create two files (one for iOS, one for android/material-design). The following would create a new icon named "newicon":~~

~~src/assets/custom-ion-icons/ios-newicon.svg~~ ~~src/assets/custom-ion-icons/md-newicon.svg~~

The svg image should consist of shapes with black fills. Strokes won't always show up, depending on the context.

  1. Use your icon anywhere, using the name "newicon"!
<ion-icon name="newicon"></ion-icon>
<ion-tabs>
  <ion-tab label="your-tab-label" icon="newicon" href="/tabs/(home:home)">
    <ion-router-outlet name="your-outlet-name"></ion-router-outlet>
  </ion-tab>
</ion-tabs>

For Ionic v5 the above solution still works, but the ios- and md- prefix is no longer required.

Thanks heaps @ransoing !

SimonBrazell avatar Feb 13 '20 03:02 SimonBrazell

@SimonBrazell I got this to work in v5 as well but the custom icons only show when I serve my app using โ€˜ionic serve -lโ€™ If I use โ€˜ionic serveโ€™ I will get 404 errors for all my custom icons.

Is there something else I need to do?

EDIT: I was able to get this working by starting a new app and copying the angular.json file, deleting the node_modules folder and running npm install again, but I cannot style any of the custom icons. For example, I cannot set the color to red.

mikev10 avatar Feb 22 '20 15:02 mikev10

@mikev10 it all worked fine for me, I however varied the instructions for my project slightly by putting my custom icons in icons/ in the root of the project rather than in the src directory as then they will get imported twice I believe. My project was a newly generated one too.

My angular.json projects.app.architect.build.options.assets array looks like this:

"assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/ionicons/dist/ionicons/svg",
                "output": "./svg"
              },
              {
                "glob": "**/*.svg",
                "input": "icons", // <= custom icons stored in the project root 'icons' folder
                "output": "./svg"
              }
            ],

If you are having problems colouring the icons then perhaps the problem lies with SVGs themselves, note this part of @ransoing's instructions:

The svg image should consist of shapes with black fills. Strokes won't always show up, depending on the context.

SimonBrazell avatar Feb 24 '20 23:02 SimonBrazell

@SimonBrazell Ionicons 5 have now 3 types per icon. Coloring works e.g. https://aeicon5.firebaseapp.com/ with named colors. When I get a chance to test your implementation I will provide an update here.

peterennis avatar Feb 24 '20 23:02 peterennis

@peterennis yes this implementation all worked fine for me, colours and everything worked as expected e.g. <ion-icon name="some-custom-icon" color="primary"></ion-icon>

Ionicons 5 have now 3 types per icon.

You don't need to worry about creating -outline or -sharp variants, unless you want them for your custom icons.

SimonBrazell avatar Feb 25 '20 00:02 SimonBrazell

@SimonBrazell It is working. See this commit: https://github.com/adaept/ae-icon5-component/commit/38133e3e6220acb1949efde05719972f7b601210 It is a stencil component wrapping the ionicons component so I used the src attribute. Probably should svgomg the files. Site is updated also.

peterennis avatar Feb 25 '20 04:02 peterennis

@SimonBrazell Thanks man. I was using those ios- and md- prefixes. Removing them solved it. Thanks again.

umairrafiq1133 avatar Feb 29 '20 08:02 umairrafiq1133