Skip to content

Commit

Permalink
Merge pull request #33 from czeckd/ng5
Browse files Browse the repository at this point in the history
Use HttpClient
  • Loading branch information
czeckd authored Dec 3, 2017
2 parents dcb97d8 + e6c9056 commit d2d6acb
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 179 deletions.
54 changes: 31 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
[![npm version](https://badge.fury.io/js/angular-svg-icon.svg)](https://badge.fury.io/js/angular-svg-icon)

Angular SVG Icon
Angular SVG Icon
=========

The **angular-svg-icon** is an Angular 2+ service and component that provides a
means to inline SVG images to allow for them to be easily styled by CSS and
code.
The **angular-svg-icon** is an Angular 4.3+ service and component that provides a
means to inline SVG files to allow for them to be easily styled by CSS and code.

The service provides an icon registery that loads and caches a svg indexed by
its url. The component is responsible for displaying the svg. After getting the
svg from the registry it clones the `SVGElement` and the svg to the component's
The service provides an icon registery that loads and caches a SVG indexed by
its url. The component is responsible for displaying the SVG. After getting the
svg from the registry it clones the `SVGElement` and the SVG to the component's
inner HTML.

A [working demo](http://czeckd.github.io/angular-svg-icon/demo/) shows solution
in action.
A [working demo](http://czeckd.github.io/angular-svg-icon/demo/) shows solution in action.

## How to use?
```
$ npm i angular-svg-icon --save
```
(**Note:** For use Angular 2.4 through Angular 4.2, please install [email protected]
and see the module's accompanying README.md for instructions.)

## Integration

The **angular-svg-icon** should work as-is with webpack/angular-cli. Just add
the ``AngularSvgIconModule``.
The **angular-svg-icon** should work as-is with webpack/angular-cli. Just import the
``AngularSvgIconModule`` and the ```HttpClientModule```.

```typescript
import { HttpClientModule } from '@angular/common/http';
import { AngularSvgIconModule } from 'angular-svg-icon';

@NgModule({
imports: [ AngularSvgIconModule ],
imports: [ HttpClientModule, AngularSvgIconModule ],
...
})
export class AppModule {}
Expand All @@ -52,14 +53,14 @@ constructor(private iconReg:SvgIconRegistryService) { }

The registry has two public functions: `loadSvg(string)` and `unloadSvg(string)`.

To preload a svg file into the registry:
To preload a svg file into the registry:

```typescript
{
...
this.iconReg.loadSvg('foo.svg');
}
```
```

To unload a svg from the registry.

Expand All @@ -70,22 +71,29 @@ To unload a svg from the registry.
}
```

## SVG Preparation
The SVG should be modified to remove the height and width attributes from the file
per Sara Soueidan's advice in "[Making SVGs Responsive With
CSS](http://tympanus.net/codrops/2014/08/19/making-svgs-responsive-with-css/)" if
size is to be modified through CSS. Removing the height and width has two immedate
impacts: (1) CSS can be used to size the SVG, and (2) CSS will be *required* to
size the SVG.

## Background

The svg-icon is an Angular 2 component that allows for the continuation of the
AngularJS method for easily inlining SVGs explained by [Ben
Markowitz](https://www.mobomo.com/2014/09/angular-js-svg/) and others. Including
The svg-icon is an Angular 2 component that allows for the continuation of the
AngularJS method for easily inlining SVGs explained by [Ben
Markowitz](https://www.mobomo.com/2014/09/angular-js-svg/) and others. Including
the SVG source inline allows for the graphic to be easily styled by CSS.

The technique made use of ng-include to inline the svg source into the document.
Angular 2, however, drops the support of ng-include, so this is my work-around
The technique made use of ng-include to inline the svg source into the document.
Angular 2, however, drops the support of ng-include, so this is my work-around
method.

*Note:* The [icon
component](https://www.npmjs.com/package/@angular2-material/icon) from
[angular/material2](https://github.com/angular/material2) used to have a direct
means to load svg similar to this, but this functionality was removed because of
*Note:* The [icon
component](https://www.npmjs.com/package/@angular2-material/icon) from
[angular/material2](https://github.com/angular/material2) used to have a direct
means to load svg similar to this, but this functionality was removed because of
security concerns.

## License
Expand Down
3 changes: 2 additions & 1 deletion app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';

import { AngularSvgIconModule } from 'angular-svg-icon';
import { DemoAppComponent } from './demo-app.component';

@NgModule({
imports: [ BrowserModule, FormsModule, AngularSvgIconModule ],
imports: [ BrowserModule, FormsModule, HttpClientModule, AngularSvgIconModule ],
declarations: [ DemoAppComponent ],
bootstrap: [ DemoAppComponent ]

Expand Down
2 changes: 1 addition & 1 deletion demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<!-- Polyfill(s) for older browsers -->
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>

<script src="https://unpkg.com/[email protected].4?main=browser"></script>
<script src="https://unpkg.com/[email protected].18?main=browser"></script>
<script src="https://unpkg.com/[email protected]/dist/system.src.js"></script>

<script src="demo/systemjs.config.js"></script>
Expand Down
110 changes: 53 additions & 57 deletions demo/systemjs.config.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,57 @@
(function(global) {

var ngVer = '@4.0.0';

var paths = {
'npm:' : 'https://unpkg.com/'
}

// map tells the System loader where to look for things
var map = {
'app': 'app',
'rxjs': 'npm:[email protected]',
'@angular': 'npm:@angular',
'typescript' : 'npm:[email protected]/lib/typescript.js',
'angular-svg-icon': 'lib'
};

// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.ts', defaultExtension: 'ts' },
'rxjs': { defaultExtension: 'js' },
'angular-svg-icon': { main: 'index.ts', defaultExtension: 'ts' }
};

var ngPackageNames = [
'common',
'compiler',
'core',
'forms',
'http',
'platform-browser',
'platform-browser-dynamic'
];

ngPackageNames.forEach(function(pkgName) {
map['@angular/'+pkgName] = 'npm:@angular/' + pkgName + ngVer;
});

// Add package entries for angular packages
ngPackageNames.forEach(function(pkgName) {
packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
});

var config = {
transpiler: 'typescript',
typescriptOptions: {
emitDecoratorMetadata: true
},
paths: paths,
map: map,
packages: packages
}

// filterSystemConfig - index.html's chance to modify config before it is registered.
if (global.filterSystemConfig) {
global.filterSystemConfig(config);
}

System.config(config);
var ngVer = '@5.0.0';

var paths = {
'npm:' : 'https://unpkg.com/'
}

// map tells the System loader where to look for things
var map = {
'app': 'app',
'angular-svg-icon': 'lib',
'rxjs': 'npm:[email protected]',
'tslib': 'npm:[email protected]',
'typescript' : 'npm:[email protected]/lib/typescript.js',

'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js'
};

// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.ts', defaultExtension: 'ts' },
'angular-svg-icon': { main: 'index.ts', defaultExtension: 'ts' },

'rxjs': { defaultExtension: 'js' },
'tslib': { main: 'tslib.js', defaultExtension: 'js' }
};

var config = {
transpiler: 'typescript',
typescriptOptions: {
sourceMap: true,
emitDecoratorMetadata: true,
experimentalDecorators: true
},
meta: {
typescript: { exports: 'ts' }
},
paths: paths,
map: map,
packages: packages
}

// filterSystemConfig - index.html's chance to modify config before it is registered.
if (global.filterSystemConfig) {
global.filterSystemConfig(config);
}

System.config(config);

})(this);
5 changes: 2 additions & 3 deletions lib/angular-svg-icon.module.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';


import { SvgIconComponent, SVG_ICON_REGISTRY_PROVIDER } from './svg-icon.component';
import { SVG_ICON_REGISTRY_PROVIDER } from './svg-icon-registry.service';
import { SvgIconComponent } from './svg-icon.component';

@NgModule({
imports: [
CommonModule,
HttpModule
],
declarations: [ SvgIconComponent ],
providers: [ SVG_ICON_REGISTRY_PROVIDER ],
Expand Down
22 changes: 16 additions & 6 deletions lib/svg-icon-registry.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Injectable, Optional, SkipSelf } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';

Expand All @@ -16,7 +16,7 @@ export class SvgIconRegistryService {
private iconsByUrl = new Map<string, SVGElement>();
private iconsLoadingByUrl = new Map<string, Observable<SVGElement>>();

constructor(private http:Http) {
constructor(private http:HttpClient) {
}

loadSvg(url:string): Observable<SVGElement> {
Expand All @@ -26,10 +26,10 @@ export class SvgIconRegistryService {
} else if (this.iconsLoadingByUrl.has(url)) {
return this.iconsLoadingByUrl.get(url);
} else {
const o = <Observable<SVGElement>> this.http.get( url )
.map( (res:Response) => {
const o = <Observable<SVGElement>> this.http.get(url, { responseType: 'text' })
.map(svg => {
const div = document.createElement('DIV');
div.innerHTML = res.text();
div.innerHTML = svg;
return <SVGElement>div.querySelector('svg');
})
.do(svg => {
Expand All @@ -52,3 +52,13 @@ export class SvgIconRegistryService {
}

}

export function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry:SvgIconRegistryService, http:HttpClient) {
return parentRegistry || new SvgIconRegistryService(http);
}

export const SVG_ICON_REGISTRY_PROVIDER = {
provide: SvgIconRegistryService,
deps: [ [new Optional(), new SkipSelf(), SvgIconRegistryService], HttpClient ],
useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY
};
15 changes: 2 additions & 13 deletions lib/svg-icon.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, Optional,
Renderer, SimpleChange, SkipSelf } from '@angular/core';
import { Http } from '@angular/http';
import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit,
Renderer, SimpleChange } from '@angular/core';

import { Subscription } from 'rxjs/Subscription';

Expand Down Expand Up @@ -56,13 +55,3 @@ export class SvgIconComponent implements OnInit, OnDestroy, OnChanges {
this.renderer.projectNodes(elem, [icon]);
}
}

export function SVG_ICON_REGISTRY_PROVIDER_FACTORY(parentRegistry:SvgIconRegistryService, http:Http) {
return parentRegistry || new SvgIconRegistryService(http);
}

export const SVG_ICON_REGISTRY_PROVIDER = {
provide: SvgIconRegistryService,
deps: [ [new Optional(), new SkipSelf(), SvgIconRegistryService], Http ],
useFactory: SVG_ICON_REGISTRY_PROVIDER_FACTORY
};
43 changes: 21 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "angular-svg-icon",
"description": "Angular 2+ component for inlining SVGs allowing them to be easily styled with CSS.",
"version": "4.2.6",
"description": "Angular 5 component for inlining SVGs allowing them to be easily styled with CSS.",
"version": "5.0.0",
"repository": {
"type": "git",
"url": "https://github.com/czeckd/angular-svg-icon.git"
Expand All @@ -26,31 +26,30 @@
"lint": "tslint -c tslint.json ./app/**/*.ts ./lib/**/*.ts -t verbose || true"
},
"peerDependencies": {
"@angular/core": "^2.4.0 || ^4.0.0 || ^5.0.0",
"@angular/http": "^2.4.0 || ^4.0.0 || ^5.0.0",
"rxjs": "^5.2.0"
"@angular/core": "^4.3.0 || ^5.0.0",
"@angular/common": "^4.3.0 || ^5.0.0",
"rxjs": "^5.5.2"
},
"devDependencies": {
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/compiler-cli": "^4.0.0",
"@angular/core": "^4.0.0",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@types/core-js": "^0.9.39",
"@types/node": "^6.0.60",
"@angular/common": "^5.0.0",
"@angular/compiler": "^5.0.0",
"@angular/compiler-cli": "^5.0.0",
"@angular/core": "^5.0.0",
"@angular/forms": "^5.0.0",
"@angular/platform-browser": "^5.0.0",
"@angular/platform-browser-dynamic": "^5.0.0",
"@types/core-js": "^0.9.43",
"@types/node": "^8.0.50",
"concurrently": "^2.2.0",
"core-js": "^2.4.1",
"core-js": "^2.5.1",
"lite-server": "^2.2.2",
"rimraf": "^2.6.1",
"rollup": "^0.41.6",
"rxjs": "^5.2.0",
"rollup": "^0.51.1",
"rxjs": "^5.5.2",
"systemjs": "0.19.47",
"ts-node": "^3.0.2",
"tslint": "~4.5.0",
"typescript": "~2.2.0",
"zone.js": "^0.8.12"
"ts-node": "^3.3.0",
"tslint": "~5.8.0",
"typescript": "~2.4.2",
"zone.js": "^0.8.18"
}
}
Loading

0 comments on commit d2d6acb

Please sign in to comment.