Giter Site home page Giter Site logo

kreuzerk / svg-icon-library-starter Goto Github PK

View Code? Open in Web Editor NEW
37.0 3.0 44.0 229 KB

Build an astonishing framework-agnostic SVG icon library with ease. Out of the box icon optimization, build process, and icon showcase. ๐Ÿš€

License: MIT License

HTML 14.60% CSS 45.81% JavaScript 39.59%
icons svg libaray starter

svg-icon-library-starter's Introduction

svg-icon-library-starter

Table of Contents generated with DocToc

This is a startert project that helps you build your own awesome icon library for any kind of framework or even for vanilla JS or TypeScript. Each SVG icons is processed, optimized and build for static code analysers to enable tree shaking.

Getting started

  1. Fork this repository
  2. Customize the project by running a full text search and replacing all "REPLACE_ME" occurrences.
  3. Place all you SVG icons into the svg-icons folder.
  4. Open up a terminal and type npm run serve.

Delivering the icons

Once you placed the icons inside the svg-icons folder you can deliver them to production. npm run build converts all the icons to JavaScript and generates the correct TypeScript declaration files into a dist folder.

Consuming your icon library

Once published to npm, your icon library is ready to be consumed. There are various ways to consume the icon library.

Vanilla JS

To consum the icon library in ES6 you can import icons from your library, create an SVG element and add the icon data to it.

// Import the icon from the icon library
import {myIconSmilingFace} from 'my-icon-lib';

// Query the element that you want to append the icon to
const conatiner = document.getElementById('.container');

// Create a new svg element and apply the icon data to it
function buildSVGElement(icon) {
    const div = document.createElement('DIV');
    div.innerHTML = icon.data;
    return (
        div.querySelector('svg') ||
        this.document.createElementNS('http://www.w3.org/2000/svg', 'path')
    );
}

// Append the icon to the container
container.appendChild(buildSVGElement(icon);

Typescript

The TypeScript usage is very similar to the JavaScript usage. The only difference is that you have additional type safety.

// Import the icon from the icon library
import {myIconSmilingFace, MyIcon} from 'my-icon-lib';

// Query the element that you want to append the icon to
const conatiner = document.getElementById('.container');

// Create a new svg element and apply the icon data to it
function buildSVGElement(icon: MyIcon): SVGElement {
    const div = document.createElement('DIV');
    div.innerHTML = icon.data;
    return (
        div.querySelector('svg') ||
        this.document.createElementNS('http://www.w3.org/2000/svg', 'path')
    );
}

// Append the icon to the container
container.appendChild(buildSVGElement(icon));

Framework usage

The usage in frameworks can be a bit more sophisticated than the usage in plain JavaScript or TypeScript. In frameworks we often work with additional concepts like components and more sophisticated builds.

Angular

In Angular we want to provide a reusable component for the icons. A reusable component that accepts a name as an Input property and displays the desired icon. Furthermore, we want to guarantee that tree shaking is supported. If the icon library contains 300 icons but only one of them is used, only one should end up in the resulting bundle. Furthermore it should also support code splitting and lazy loading in a way that the icon only ends up in the chunk it is used.

To achieve these things we implement a IconRegistry.

import {Injectable} from '@angular/core';
import {MyIcon} from './my-icon-lib';

@Injectable({
    providedIn: 'root'
})
export class MyIconsRegistry {

    private registry = new Map<string, string>();

    public registerIcons(icons: MyIcon[]): void {
        icons.forEach((icon: MyIcon) => this.registry.set(icon.name, icon.data));
    }

    public getIcon(iconName: string): string | undefined {
        if (!this.registry.has(iconName)) {
            console.warn(
              `We could not find the Icon with the name ${iconName}, did you add it to the Icon registry?`
            );
        }
        return this.registry.get(iconName);
    }
}

The icon registry holds all the icons in a Map. Next we build the my-icon.component.ts that will use the registry to display an icon.

import {
  ChangeDetectionStrategy, Component, ElementRef, HostBinding, Inject, Input, Optional, ViewEncapsulation
} from '@angular/core';
import {MyIconsRegistry} from './my-icons-registry.service';
import {DOCUMENT} from '@angular/common';

@Component({
    selector: 'my-icon',
    template: `
        <ng-content></ng-content>
    `,
    styles: [':host::ng-deep svg{width: 50px; height: 50px}'],
    changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyIconComponent {
    private svgIcon: SVGElement;

    @Input()
    set name(iconName: string) {
        if (this.svgIcon) {
            this.element.nativeElement.removeChild(this.svgIcon);
        }
        const svgData = this.myIconsRegistry.getIcon(iconName);
        this.svgIcon = this.svgElementFromString(svgData);
        this.element.nativeElement.appendChild(this.svgIcon);
    }

    constructor(private element: ElementRef, private myIconsRegistry: MyIconsRegistry,
                @Optional() @Inject(DOCUMENT) private document: any) {
    }

    private svgElementFromString(svgContent: string): SVGElement {
        const div = this.document.createElement('DIV');
        div.innerHTML = svgContent;
        return div.querySelector('svg') || this.document.createElementNS('http://www.w3.org/2000/svg', 'path');
    }
}

At this point we are ready to consum the my-icon component. We first register the desired icon in the lazy loaded module and then consume it in a component.

import { NgModule, Component } from '@angular/core';
import {myIconSmilingFace} from 'my-icon-lib';

import {MyIconsRegistry} from './my-icons-registry';
import {MyIconModule} from './my-icon.module.ts';

@Component({
  selector: 'my-feature',
  template: `<my-icon name="smiling_face"></my-icon>`
})
export class MyFeatureComponent {}

@NgModule({
  declarations: [MyFeatureComponent],
  imports: [MyIconModule]
})
export class MyFeatureModule { 

	constructor(private myIconsRegistry: MyIconsRegistry) {
		myIconsRegistry.registerIcons([myIconSmilingFace]);
	}

}

If you want to find out more about why we need a registry and how it helps tree shaking I recommend you to check out this blogpost.

Custom build

Maybe you have a special setup or you are only interested in TypeScript files and don't want to compile the icons to JavaScript. In such cases you can always adjust the svg-to-ts config in your project. To prevent the JavaScript compilation for example you can simply disable it by setting the compileSources flag to false. For more information check out the svg-to-ts docs.

svg-icon-library-starter's People

Contributors

kreuzerk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

svg-icon-library-starter's Issues

Can not find main.js or main.ts

Hi when trying to start the project after npm install with npm run serve I get an error that there is no entry file main.js for the webpack configuration in the directory showcase.
I see that you have deleted that file, can you tell me why and how to run the showcase ?

Thanks :)

Usage of this Starter in a Vue 3 Project

Hi there,

i want to use this Starter Project in a Vue based Project but there is no instructions how to do that.

Any help would be highly appreciated.

Thanks in Advance.

No authentication during installation

During installation of the project's dependecies I get an error stating:

npm ERR! code E401
npm ERR! Unable to authenticate, your authentication token seems to be invalid.
npm ERR! To correct this please trying logging in again with:
npm ERR!     npm login

In the npm log I found that it was trying to fetch some dependency from a private repository:

3483 verbose statusCode 401
3484 verbose pkgid yaml@https://pkgs.dev.azure.com/diemobiliar/RWC/_packaging/npm-main/npm/registry/yaml/-/yaml-1.10.0.tgz
3485 verbose cwd E:\Arbeit Arbeit\svg-icon-library-starter

Can you maybe make this repository public or host it on npm instead?

The package may have incorrect main/module/exports specified in its package.json.

I get this error when I run npm run build. However, it generated code

[commonjs--resolver] Failed to resolve entry for package "C:\Users\myname\Desktop\icons\icon_lib\svg-icon-library-starter-main\dist\icons". The package may haverror during build: Error: Failed to resolve entry for package "C:\Users\myname\Desktop\icons\icon_lib\svg-icon-library-starter-main\dist\icons". The package may have incorrect main/module/exports specified in its package.json. ect main/module/exports specified in it at packageEntryFailure (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/vite/dist/node/chunks/dep-ca21228b.js:22005:11) js:22005:11) at resolvePackageEntry (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/vite/dist/node/chunks/dep-ca21228b. :5) js:22002:5) js:22002 at tryResolveFile (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/vite/dist/node/chunks/dep-ca21228b.js:21610:38) 610:38) ) at tryFsResolve (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/vite/dist/node/chunks/dep-ca21228b.js:21588:16) 8:16) 21430:28node-entry.js:24243:28) at Object.resolveId (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/vite/dist/node/chunks/dep-ca21228b.js: ync ModuleLoader.resolve21430:28) at as at file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/rollup/dist/es/shared/node-entry.js:24343:40 /shared/5) at async PluginDriver.hookFirstAndGetPlugin (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/rollup/dist/es 72:10) /shared/node-entry.js:24243:28) 87:26) at async resolveId (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/rollup/dist/es/shared/node-entry.js:231ntry.js:87:26) at async ModuleLoader.resolveId (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/rollup/dist/es/shared/node-entry.js:23451:15) 8b.js:79 at async Object.resolveId (file:///C:/Users/myname/Desktop/icons/icon_lib/svg-icon-library-starter-main/node_modules/vite/dist/node/chunks/dep-ca21228b.js:7972:10)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.