Components: icon: Keep symbol viewBox value when register an iconSet

Created on 4 Jul 2017  路  11Comments  路  Source: angular/components

Bug, feature request, or proposal:

Bug

What is the expected behavior?

When registering an SVG iconSet, every symbol may provide a custom viewBox attribute. This attribute should be keep in the newly SVG element created.

What is the current behavior?

The viewBox attribute is swallowed.

What are the steps to reproduce?

What is the use-case or motivation for changing an existing behavior?

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

At least since beta 7

Is there anything else we should know?

This is related to #5188 #2981
For SVG icon set with symbol, see https://css-tricks.com/svg-symbol-good-choice-icons/

P4 materiaicon

Most helpful comment

I still do not understand why this 3-lines patch is not applied?

All 11 comments

I think this is captured by work on #5188. md-icon is specifically intended to cover the Material Design icon treatment; a cdk-svg directive would be able to be a lot more general.

hi, i don't see the fix of @ilaborie in the current MatIconRegistry ? The fix is current and I always need a override of MatIconRegistry with this fix.

I still do not understand why this 3-lines patch is not applied?

hi @jelbourn, any news please ?

I struggled with trying to use a sprite svg file exported from FlatIcon.com (svg file using inline elements) with the addSvgIconSetInNamespace function. I finally realized the viewBox attribute is NOT inserted into the output svg code with the mat-icon component. I'm glad I found this github issue to confirm.

I'm wondering if anyone has a solution? Without the viewBox values, the SVG cannot be rendered and scaled properly. Is it just not possible? I'll register the icons individually with addSvgIcon if I have to; just thought it would be so much more efficient to have one combined svg file. Advice?

Potentially revisiting this now

Do you support both <defs> and <symbol> in an svg icon set? Symbols seem to work with the exception of the viewbox missing, which causes the icons to not be centered. I'm hesitant to manually fix my entire sprite file since it was easily dynamically generated, unless you don't support <symbol>.

Here is the fix I applied in my code by overriding _toSvgElement method exactly like @ilaborie did:

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      deps: [MatIconRegistry],
      useFactory: preserveSvgViewBox,
      multi: true
    }
  ]
})
export class IconModule {
}

function preserveSvgViewBox(matIconRegistry: MatIconRegistry) {
  return () => {
    const oldToSvgElement = matIconRegistry['_toSvgElement'];

    matIconRegistry['_toSvgElement'] = (element: Element) => {
      const svg = oldToSvgElement.call(matIconRegistry, element);

      const viewBox = element.getAttribute('viewBox');
      if (viewBox !== null) {
        svg.setAttribute('viewBox', viewBox);
      }
      return svg;
    };
  };
}

Wonderful @Humberd . It is working like a charm. What a bad documentation though. And hard to find some issues. A pity foor such a good framework.

@bsteffl , from material documentation on icon sets:

This is done by creating a single root tag that contains multiple nested tags in its section. Each of these nested tags is identified with an id attribute. This id is used as the name of the icon.

The problem is that icons services like icomoon.io creats icon sets with <symbol>. You can replace it to <svg>, but why?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shlomiassaf picture shlomiassaf  路  3Comments

dzrust picture dzrust  路  3Comments

crutchcorn picture crutchcorn  路  3Comments

MurhafSousli picture MurhafSousli  路  3Comments

julianobrasil picture julianobrasil  路  3Comments