Skip to content
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

Convert to component? #77

Open
NullVoxPopuli opened this issue Oct 23, 2019 · 2 comments
Open

Convert to component? #77

NullVoxPopuli opened this issue Oct 23, 2019 · 2 comments

Comments

@NullVoxPopuli
Copy link

I'm also kinda wondering why this is helper?

It'd be great if we could wrap this in something like:

{{#if this.someCondition}}
  <InlineSvg @path={{this.path}} ...attributes />
{{/if}}

there the invocation could then become:

<MyIcon class='blue' />
@raido
Copy link
Collaborator

raido commented Feb 13, 2020

This can be as for Glimmer component, not sure if worth to do with classic component?

Related issue with class attributes #36 .

@abel-n
Copy link

abel-n commented Dec 2, 2021

Context

I wanted to create a component for custom (uploaded) Font Awesome icons so that I can keep the default way of installing FA packages via package manager and using the component provided by FA for all icons and handle only custom icons this way.

Disclaimer

This is a very minimal implementation which I'll further extend so I have one component to render all FA icons from the kit.
Please note that all SVGs are manually optimized to the same format FA uses, the regular expressions can easily fail if optimization is not done that way.
Also, this is in an addon, hence the addon namespace. (obviously it has the respective app export)

addon/components/icon.ts

import Component from '@glimmer/component';
import { htmlSafe } from '@ember/string';
import { assert } from '@ember/debug';
import { dottify } from 'ember-inline-svg/utils/general';

import type { SafeString } from '@ember/template/-private/handlebars';

const XMLNS_RE = /xmlns="([^"]*)"/;
const VIEWBOX_RE = /viewBox="([^"]*)"/;
const SVG_CONTENT_RE = /^<svg[^>]*>(.*)<\/svg>$/;

function extract(tag: string, attrRe: RegExp): string {
  return (tag.match(attrRe) as RegExpMatchArray)[1];
}

interface Args {
  path: string;
}

export default class IconComponent extends Component<Args> {
  xmlns!: string;
  viewBox!: string;
  svgContent!: SafeString;

  constructor(owner: unknown, args: Args) {
    super(owner, args);

    // @ts-expect-error not bothering to type resolveRegistration
    const svgs = owner.resolveRegistration('svgs:main') || [];
    const svg = svgs[dottify(this.args.path)];

    assert('No SVG found for ' + this.args.path, svg);

    this.xmlns = extract(svg, XMLNS_RE);
    this.viewBox = extract(svg, VIEWBOX_RE);
    this.svgContent = htmlSafe(extract(svg, SVG_CONTENT_RE));
  }
}

addon/components/icon.hbs

<svg xmlns={{this.xmlns}} viewBox={{this.viewBox}} ...attributes>
  {{this.svgContent}}
</svg>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants