vmware-archive / clarity

Clarity is a scalable, accessible, customizable, open source design system built with web components. Works with any JavaScript framework, built for enterprises, and designed to be inclusive.
http://clarity.design
MIT License
6.43k stars 760 forks source link

Not able to add custom icons using ClarityIcons.add #689

Closed tarundhillon closed 7 years ago

tarundhillon commented 7 years ago

ClarityIcons.add({"myLogo": '<svg version="1.1" viewBox="0 0 36 36" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> < title > zoom - out < /title>< path d="M16,4A12,12,0,1,0,28,16,12,12,0,0,0,16,4Zm0,21.91A10,10,0,1,1,26,16,10,10,0,0,1,16,25.91Z" class="clr-i-outline clr-i-outline-path-1" /><path d="M31.71,29.69l-5.17-5.17A13.68,13.68,0,0,1,25.15,26l5.15,5.15a1,1,0,0,0,1.41-1.41Z" class="clr-i-outline clr-i-outline-path-2" /><path d="M20,15H12a1,1,0,0,0,0,2h8a1,1,0,0,0,0-2Z" class="clr-i-outline clr-i-outline-path-3" /></svg>'});

Ideally it will be good to link an external file here.

Select one ... (check one with "x")

[x ] bug
[ ] feature request
[ ] enhancement

Expected behavior

this should display the Logo svg

Actual behavior

Error in the browser console 'myLogo' is not found in the Clarity Icons set.

Reproduction of behavior

https://plnkr.co/edit/2NzkpsExVOOHBg6QYYXy?p=preview

Environment details

Shijir commented 7 years ago

@tarundhillon I looked at the Plunkr and it looks like you placed your application logic, which is adding a new icon into ClarityIcons in this case, in the AppModule, which is solely responsible for bootstrapping your application. So you would want to place it in the root component class. Also, It needs to be in a constructor or method to run.

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { ClarityIcons } from 'clarity-icons';

@Component({
  selector: 'my-app',
  styleUrls: ['app/app.component.css'],
  templateUrl: 'app/app.component.html'
})
export class AppComponent {
  constructor(){
    ClarityIcons.add({"myLogo": '<svg version="1.1" viewBox="0 0 36 36" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> < title > zoom - out < /title>< path d="M16,4A12,12,0,1,0,28,16,12,12,0,0,0,16,4Zm0,21.91A10,10,0,1,1,26,16,10,10,0,0,1,16,25.91Z" class="clr-i-outline clr-i-outline-path-1" /><path d="M31.71,29.69l-5.17-5.17A13.68,13.68,0,0,1,25.15,26l5.15,5.15a1,1,0,0,0,1.41-1.41Z" class="clr-i-outline clr-i-outline-path-2" /><path d="M20,15H12a1,1,0,0,0,0,2h8a1,1,0,0,0,0-2Z" class="clr-i-outline clr-i-outline-path-3" /></svg>'});
  }
}
b-ritter commented 7 years ago

Unfortunately, I was not able to get this solution to work with Angular 4. Here is a fork of the Clarity seed repo with the svg used in the documentation. I am able to console.log the data from the svg immediately after adding it with the api, but in trying to access it in the template using the clr-icon directive it throws the error 'my-first-custom-icon' is not found in the Clarity Icons set. Any help would be much appreciated!

mathisscott commented 7 years ago

I made a plunkr out of the code in the fork and it works.

b-ritter commented 7 years ago

Thank you @mathisscott for your quick response! The issue I am experiencing is when I run the app with the angular cli using ng serve. I can perhaps try to modify it to run locally with AOT.

mathisscott commented 7 years ago

@Shijir may be able to help you figure out the issue. We have clarity-icons running with both ng serve and AOT, iirc.

b-ritter commented 7 years ago

Okay, thank you. clarity-icons works wonderfully, it's just adding custom icons that is the problem.

Shijir commented 7 years ago

The problem you are facing could happen when you are running two instances of ClarityIcons. If you are importing and loading ClarityIcons in your typescript, make sure you are not loading it through script tag too.

tarundhillon commented 7 years ago

It works for me with on Angular4, I have approached it as follows

  1. Define a service
import { Injectable } from '@angular/core';
@Injectable()
export class IconService {
    constructor){}

    icons : any = {
        "appLogo": '<svg viewBox="0 0 100 100"><use xlink:href="/src/icons/logo.svg#appLogo"></use></svg>',
        "appLogoWithText": '<svg viewBox="0 0 100 100"><use xlink:href="/src/icons/logo.1.svg#appLogo"></use></svg>'
    };

    public load(){        
          window['ClarityIcons'].add(this.icons);
    }

}
  1. Call the load at an appropriate point, for it was when a component is being loaded
 constructor(private iconService: IconService) {
        iconService.load();
  1. in the html <clr-icon shape="appLogo" size='48'></clr-icon>
b-ritter commented 7 years ago

@Shijir, thank you, I removed the line from the angular-cli.json scripts section that includes clarity-icons.js. It works! Very cool.

github-actions[bot] commented 4 years ago

Hi there 👋, this is an automated message. To help Clarity keep track of discussions, we automatically lock closed issues after 14 days. Please look for another open issue or open a new issue with updated details and reference this one as necessary.