diff --git a/README.md b/README.md index 84488f6..5182bfb 100644 --- a/README.md +++ b/README.md @@ -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 angular-svg-icon@4.2.6 +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 {} @@ -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. @@ -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 diff --git a/app/app.module.ts b/app/app.module.ts index c5668bc..9b39ef5 100644 --- a/app/app.module.ts +++ b/app/app.module.ts @@ -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 ] diff --git a/demo/index.html b/demo/index.html index 57aa9a6..068e273 100644 --- a/demo/index.html +++ b/demo/index.html @@ -13,7 +13,7 @@ - + diff --git a/demo/systemjs.config.js b/demo/systemjs.config.js index 3be821e..9f8b64b 100644 --- a/demo/systemjs.config.js +++ b/demo/systemjs.config.js @@ -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:rxjs@5.2.0', - '@angular': 'npm:@angular', - 'typescript' : 'npm:typescript@2.2.0/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:rxjs@5.5.2', + 'tslib': 'npm:tslib@1.7.1', + 'typescript' : 'npm:typescript@2.4.2/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); diff --git a/lib/angular-svg-icon.module.ts b/lib/angular-svg-icon.module.ts index 8ee5256..113da3a 100644 --- a/lib/angular-svg-icon.module.ts +++ b/lib/angular-svg-icon.module.ts @@ -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 ], diff --git a/lib/svg-icon-registry.service.ts b/lib/svg-icon-registry.service.ts index 1657f7d..76296e4 100644 --- a/lib/svg-icon-registry.service.ts +++ b/lib/svg-icon-registry.service.ts @@ -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'; @@ -16,7 +16,7 @@ export class SvgIconRegistryService { private iconsByUrl = new Map(); private iconsLoadingByUrl = new Map>(); - constructor(private http:Http) { + constructor(private http:HttpClient) { } loadSvg(url:string): Observable { @@ -26,10 +26,10 @@ export class SvgIconRegistryService { } else if (this.iconsLoadingByUrl.has(url)) { return this.iconsLoadingByUrl.get(url); } else { - const o = > this.http.get( url ) - .map( (res:Response) => { + const o = > this.http.get(url, { responseType: 'text' }) + .map(svg => { const div = document.createElement('DIV'); - div.innerHTML = res.text(); + div.innerHTML = svg; return div.querySelector('svg'); }) .do(svg => { @@ -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 +}; diff --git a/lib/svg-icon.component.ts b/lib/svg-icon.component.ts index 5b936f6..a587225 100644 --- a/lib/svg-icon.component.ts +++ b/lib/svg-icon.component.ts @@ -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'; @@ -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 -}; diff --git a/package.json b/package.json index d54d4e9..c50945b 100644 --- a/package.json +++ b/package.json @@ -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" @@ -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" } } diff --git a/rollup.config.js b/rollup.config.js index 2fd7b6a..740f273 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,10 +1,9 @@ export default { - format: 'umd', - moduleName: 'angular-svg-icon', + name: 'angular-svg-icon', external: [ '@angular/common', + '@angular/common/http', '@angular/core', - '@angular/http', 'rxjs/add/observable/of', 'rxjs/add/operator/do', 'rxjs/add/operator/finally', @@ -14,8 +13,8 @@ export default { ], globals: { '@angular/common': 'ng.common', + '@angular/common/http': 'ng.common.http', '@angular/core': 'ng.core', - '@angular/http': 'ng.http', 'rxjs/add/observable/of' : 'Rx.Observable', 'rxjs/add/operator/do' : 'Rx.Observable.prototype', 'rxjs/add/operator/finally' : 'Rx.Observable.prototype', @@ -31,6 +30,9 @@ export default { if ( skip_codes.indexOf(warning.code) != -1 ) return; console.error(warning); + }, + output: { + format: 'umd' } }; diff --git a/systemjs.config.js b/systemjs.config.js index b1a4ce6..d93be9d 100644 --- a/systemjs.config.js +++ b/systemjs.config.js @@ -1,51 +1,39 @@ (function(global) { - // map tells the System loader where to look for things - var map = { - 'app': 'runt/app', - 'rxjs': 'node_modules/rxjs', - '@angular': 'node_modules/@angular', - 'angular-svg-icon': 'runt/lib' - }; - - // packages tells the System loader how to load when no filename and/or no extension - var packages = { - 'app': { main: 'main.js', defaultExtension: 'js' }, - 'rxjs': { defaultExtension: 'js' }, - 'angular-svg-icon': { main: 'index.js', defaultExtension: 'js' } - }; - - var ngPackageNames = [ - 'common', - 'compiler', - 'core', - 'forms', - 'http', - 'platform-browser', - 'platform-browser-dynamic' - ]; - - // Individual files (~300 requests): - function packIndex(pkgName) { - packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' }; - } - - // Bundled (~40 requests): - function packUmd(pkgName) { - packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' }; - } - - // Most environments should use UMD; some (Karma) need the individual index files - var setPackageConfig = System.packageWithIndex ? packIndex : packUmd; - - // Add package entries for angular packages - ngPackageNames.forEach(setPackageConfig); - - var config = { - map: map, - packages: packages - }; - - System.config(config); + // map tells the System loader where to look for things + var map = { + 'app': 'runt/app', + 'angular-svg-icon': 'runt/lib', + + 'rxjs': 'npm:rxjs', + 'tslib': 'npm:tslib', + + '@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.js', defaultExtension: 'js' }, + 'angular-svg-icon': { main: 'index.js', defaultExtension: 'js' }, + + 'rxjs': { defaultExtension: 'js' }, + 'tslib': { main: 'tslib.js', defaultExtension: 'js' }, + }; + + var config = { + paths: { + 'npm:': 'node_modules/' + }, + map: map, + packages: packages + }; + + System.config(config); })(this); diff --git a/tools/mkdist b/tools/mkdist index 7b2c5e0..0fa4d88 100755 --- a/tools/mkdist +++ b/tools/mkdist @@ -3,5 +3,4 @@ echo 'Transpiling...' && tsc -p tsconfig-esm.json && \ echo 'Rolling...' && rollup -c rollup.config.js dist/index.js > dist/angular-svg-icon.bundle.js && \ echo 'Angularizing...' && ngc -p tsconfig-esm.json && \ echo 'Packaging...' && ts-node tools/packager.ts && \ -echo 'Licensing...' && cp README.md LICENSE dist - +echo 'Licensing...' && cp README.md LICENSE dist \ No newline at end of file