UNPKG

@alyle/ui

Version:

Minimal Design, a set of components for Angular

332 lines (326 loc) 12.9 kB
import * as i0 from '@angular/core'; import { SecurityContext, Optional, Inject, Injectable, Input, Directive, NgModule } from '@angular/core'; import * as i2$1 from '@alyle/ui'; import { keyframesUniqueId, mixinStyleUpdater, mixinBg, mixinColor, mixinRaised, mixinOutlined, mixinElevation, mixinShadowColor, StyleRenderer, LyCommonModule } from '@alyle/ui'; import { share, map, take } from 'rxjs/operators'; import { DOCUMENT } from '@angular/common'; import * as i1 from '@angular/common/http'; import * as i2 from '@angular/platform-browser'; import * as i3 from '@angular/cdk/platform'; const STYLE_PRIORITY$1 = -2; /** The following styles will never be updated */ const styles = { svg: { width: 'inherit', height: 'inherit', fill: 'currentColor', } }; class LyIconService { get defaultClass() { return this._defaultClass; } get defaultClassPrefix() { return this._defaultClassPrefix; } constructor(http, _sanitizer, _document, theme) { this.http = http; this._sanitizer = _sanitizer; this._document = _document; this.theme = theme; this._defaultClass = 'material-icons'; this.svgMap = new Map(); this._fontClasses = new Map(); /** * Styles * @docs-private */ this.classes = this.theme.addStyleSheet(styles, STYLE_PRIORITY$1); this.defaultSvgIcon = '<svg viewBox="0 0 20 20"><circle cx="10" cy="10" r="10"></circle></svg>'; } setSvg(key, url) { if (!this.svgMap.has(key)) { const urlSanitized = this._sanitizer.sanitize(SecurityContext.RESOURCE_URL, url); const svgIcon = { obs: this.http.get(`${urlSanitized}.svg`, { responseType: 'text' }) .pipe(share(), map(svgText => { if (svgIcon.svg) { return svgIcon.svg; } const svg = this._textToSvg(svgText); this._cacheSvgIcon(svg, key); return svg; })) }; this.svgMap.set(key, svgIcon); } } addSvgIconLiteral(key, literal) { if (!this.svgMap.has(key)) { const sanitizedLiteral = this._sanitizer.sanitize(SecurityContext.HTML, literal); if (!sanitizedLiteral) { throw new Error(`LyIconService: Failed sanitize '${key}'`); } const svg = this._textToSvg(sanitizedLiteral); this.svgMap.set(key, { svg }); } } /** String to SVG */ _textToSvg(str) { const div = this._document.createElement('DIV'); div.innerHTML = str; const svg = div.querySelector('svg'); return svg; } _cacheSvgIcon(svg, key) { const svgIconInfo = this.svgMap.get(key); if (!svgIconInfo.svg) { this.svgMap.get(key).svg = svg; } } getSvg(key) { if (!this.svgMap.has(key)) { throw new Error(`LyIconService: Icon ${key} not found`); } return this.svgMap.get(key); } /** * Set default className for `ly-icon` * @param className class name * @param prefix Class prefix, * For example if you use FontAwesome your prefix would be `fa-`, * then in the template it is no longer necessary to use the prefix * Example: `<ly-icon fontIcon="alarm">` */ setDefaultClass(className, prefix) { this._defaultClass = className; this._defaultClassPrefix = prefix; } /** * Register new font class alias * demo: * For FontAwesome * registerFontClass({ * key: 'fa', * class: 'fa' * prefix: 'fa-' * }) */ registerFontClass(opt) { this._fontClasses.set(opt.key, opt); } getFontClass(key) { return this._fontClasses.get(key); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyIconService, deps: [{ token: i1.HttpClient }, { token: i2.DomSanitizer }, { token: DOCUMENT, optional: true }, { token: i2$1.LyTheme2 }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyIconService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyIconService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.DomSanitizer }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT] }] }, { type: i2$1.LyTheme2 }] }); const STYLE_PRIORITY = -2; const STYLES = (theme) => { const loading = keyframesUniqueId.next(); const { primary, secondary, tertiary } = theme.background; const lum = primary.default.luminance(); let one = (lum < .5 ? tertiary : secondary); let two = (lum < .5 ? secondary : tertiary); one = one.darken(.25 * (lum < .5 ? -1 : 1.1)); two = two.darken(.25 * (lum < .5 ? -1 : 1.1)); return { $priority: STYLE_PRIORITY, $global: (_className) => `@keyframes ${loading}{0%{background-position:200% 50%;}100%{background-position:-200% 50%;}}`, root: () => (_className) => `${_className}{font-size:${theme.icon.fontSize};width:1em;position:relative;height:1em;display:inline-flex;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;}`, loading: (_className) => `${_className}{background:${`linear-gradient(270deg, ${one}, ${two}, ${two}, ${one})`};background-size:400% 400%;animation:${loading} 8s ease-in-out infinite;}`, defaultIcon: (_className) => `${_className}{border-radius:50px;}` }; }; /** @docs-private */ class LyIconBase { constructor(_theme) { this._theme = _theme; } } /** @docs-private */ const LyIconMixinBase = mixinStyleUpdater(mixinBg(mixinColor(mixinRaised(mixinOutlined(mixinElevation(mixinShadowColor(LyIconBase))))))); class LyIcon extends LyIconMixinBase { get icon() { return this._icon; } set icon(val) { this._icon = val; this._addDefaultIcon(); if (this._platform.isBrowser) { this._prepareSvgIcon(this.iconService.getSvg(val)); } } get fontSet() { return this._fontSet; } set fontSet(key) { this._fontSet = key; } get fontIcon() { return this._fontIcon; } set fontIcon(key) { this._fontIcon = key; } /** @docs-private */ get hostElement() { return this._el.nativeElement; } constructor(iconService, _el, _renderer, theme, sRenderer, _platform) { super(theme); this.iconService = iconService; this._el = _el; this._renderer = _renderer; this.sRenderer = sRenderer; this._platform = _platform; this.classes = this.sRenderer.renderSheet(STYLES, true); this.setAutoContrast(); } ngOnChanges() { if (this.fontSet || this.fontIcon) { this._updateFontClass(); } this.updateStyle(this._el); } _isDefault() { return !(this.icon || this.fontSet); } _prepareSvgIcon(svgIcon) { if (svgIcon.svg) { this._appendChild(svgIcon.svg.cloneNode(true)); } else { svgIcon.obs .pipe(take(1)) .subscribe((svgElement) => { this._appendChild(svgElement.cloneNode(true)); }); } } _appendChild(svg) { this._cleanIcon(); this._iconElement = svg; this._renderer.addClass(svg, this.iconService.classes.svg); this._renderer.appendChild(this._el.nativeElement, svg); } _addDefaultIcon() { this.sRenderer.addClass(this.classes.defaultIcon); this.sRenderer.addClass(this.classes.loading); } // private _appendDefaultSvgIcon() { // const svgIcon = this.iconService._textToSvg(this.iconService.defaultSvgIcon) as SVGAElement; // svgIcon.classList.add(this.classes.loading); // this._appendChild(svgIcon); // } _updateClass() { if (this._isDefault() && this.iconService.defaultClass) { this._renderer.addClass(this._el.nativeElement, this.iconService.defaultClass); } } ngOnInit() { this._updateClass(); } ngOnDestroy() { this._cleanIcon(); } /** * run only browser * remove current icon */ _cleanIcon() { const icon = this._iconElement; this.sRenderer.removeClass(this.classes.defaultIcon); this.sRenderer.removeClass(this.classes.loading); if (icon) { this._renderer.removeChild(this._el.nativeElement, icon); this._iconElement = undefined; } } _updateFontClass() { const currentClass = this._currentClass; const fontSetKey = this.fontSet; const icon = this.fontIcon; const el = this._el.nativeElement; const iconClass = this.iconService.getFontClass(fontSetKey); if (currentClass) { this._renderer.removeClass(el, currentClass); } if (this._previousFontSet) { if (this._previousFontSet.class) { this._renderer.removeClass(el, this._previousFontSet.class); } } if (iconClass) { this._previousFontSet = iconClass; } else { throw new Error(`Icon with key${fontSetKey} not found`); } this._currentClass = `${iconClass.prefix}${icon}`; this._renderer.addClass(el, this._currentClass); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyIcon, deps: [{ token: LyIconService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i2$1.LyTheme2 }, { token: i2$1.StyleRenderer }, { token: i3.Platform }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.10", type: LyIcon, isStandalone: false, selector: "ly-icon", inputs: { bg: "bg", color: "color", raised: "raised", outlined: "outlined", elevation: "elevation", shadowColor: "shadowColor", icon: "icon", fontSet: "fontSet", fontIcon: "fontIcon" }, providers: [ StyleRenderer ], exportAs: ["lyIcon"], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyIcon, decorators: [{ type: Directive, args: [{ selector: 'ly-icon', inputs: [ 'bg', 'color', 'raised', 'outlined', 'elevation', 'shadowColor', ], exportAs: 'lyIcon', providers: [ StyleRenderer ], standalone: false }] }], ctorParameters: () => [{ type: LyIconService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i2$1.LyTheme2 }, { type: i2$1.StyleRenderer }, { type: i3.Platform }], propDecorators: { icon: [{ type: Input }], fontSet: [{ type: Input }], fontIcon: [{ type: Input }] } }); class LyIconModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyIconModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.10", ngImport: i0, type: LyIconModule, declarations: [LyIcon], exports: [LyIcon, LyCommonModule] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyIconModule, imports: [LyCommonModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyIconModule, decorators: [{ type: NgModule, args: [{ declarations: [LyIcon], exports: [LyIcon, LyCommonModule] }] }] }); /** * Generated bundle index. Do not edit. */ export { LyIcon, LyIconBase, LyIconMixinBase, LyIconModule, LyIconService, STYLES }; //# sourceMappingURL=alyle-ui-icon.mjs.map