angular-line-awesome
Version:
Angular Line Awesome is an Angular component to manage Line Awesome icons.
363 lines (353 loc) • 21.5 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Input, Directive, HostBinding, Optional, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
import * as i1 from '@angular/platform-browser';
// FUNCTION HANDLERS
const IconNamePrefix = 'la';
const IconDefaultPrefix = 'las';
const isIconLookup = (i) => {
return i.prefix !== undefined && i.iconName !== undefined;
};
const faNormalizeIcon = (icon) => {
if (isIconLookup(icon)) {
return icon;
}
if (Array.isArray(icon) && icon.length === 2) {
return { prefix: icon[0], iconName: icon[1] };
}
if (typeof icon === 'string') {
const iconArray = icon.split(' ');
if (iconArray.length === 1) {
iconArray.unshift(IconDefaultPrefix);
}
return { prefix: iconArray[0], iconName: iconArray[1] };
}
};
const laClassList = (props) => {
const classes = {
'la-spin': props.spin,
'la-pulse': props.pulse,
'la-fw': props.fixedWidth,
'la-border': props.border,
'la-inverse': props.inverse,
'la-layers-counter': props.counter,
'la-flip-horizontal': props.flip === 'horizontal' || props.flip === 'both',
'la-flip-vertical': props.flip === 'vertical' || props.flip === 'both',
[`la-${props.size}`]: props.size !== null,
[`la-rotate-${props.rotate}`]: props.rotate !== null,
[`la-pull-${props.pull}`]: props.pull !== null,
[`la-stack-${props.stackItemSize}`]: props.stackItemSize != null
};
return Object.keys(classes)
.map(key => (classes[key] ? key : null))
.filter(key => key);
};
const applyCssTransforms = (transformObj) => {
const transformsHandlers = {
size: (value) => `scale(${1 + value / 10})`,
rotate: (value) => `rotate(${value}deg)`,
flipY: (value) => (value ? `scaleY(-1)` : null),
flipX: (value) => (value ? `scaleX(-1)` : null),
y: (value) => `translateY(${value}px)`,
x: (value) => `translateX(${value}px)`
};
return Object.keys(transformObj)
.map(key => transformsHandlers[key](transformObj[key]))
.filter(key => key)
.join(' ');
};
const parseTransformString = (transformString) => {
const transform = {
size: 0,
x: 0,
y: 0,
rotate: 0,
flipX: false,
flipY: false
};
if (!transformString) {
return transform;
}
return transformString
.toLowerCase()
.split(' ')
.reduce((acc, n) => {
const parts = n.toLowerCase().split('-');
const first = parts[0];
let rest = parts.slice(1).join('-');
if (first && rest === 'h') {
acc.flipX = true;
return acc;
}
if (first && rest === 'v') {
acc.flipY = true;
return acc;
}
rest = parseFloat(rest);
if (isNaN(rest)) {
return acc;
}
switch (first) {
case 'grow':
acc.size = acc.size + rest;
break;
case 'shrink':
acc.size = acc.size - rest;
break;
case 'left':
acc.x = acc.x - rest;
break;
case 'right':
acc.x = acc.x + rest;
break;
case 'up':
acc.y = acc.y - rest;
break;
case 'down':
acc.y = acc.y + rest;
break;
case 'rotate':
acc.rotate = acc.rotate + rest;
break;
}
return acc;
}, transform);
};
class LaIconLibrary {
constructor() {
this.registry = new Map();
}
addIcons(icons) {
icons.forEach((icon) => {
this.registry.set(icon.name, icon.data);
});
}
getIcon(icon) {
const iconName = `${icon.prefix}-${icon.iconName}`;
if (!this.registry.has(iconName)) {
throw new Error(`Could not find icon with prefix=${icon.prefix} and iconName=${icon.iconName} in the icon library.`);
}
return this.registry.get(iconName);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaIconLibrary, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaIconLibrary, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaIconLibrary, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}] });
class LaStackItemSizeDirective {
constructor() {
/**
* Specify whether icon inside {@link LaStackComponent} should be rendered in
* regular size (1x) or as a larger icon (2x).
*/
this.stackItemSize = '1x';
}
ngOnChanges(changes) {
if ('size' in changes) {
throw new Error('la-icon is not allowed to customize size when used inside la-stack. ' +
'Set size on the enclosing la-stack instead: <la-stack size="4x">...</la-stack>.');
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaStackItemSizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.4", type: LaStackItemSizeDirective, isStandalone: false, selector: "la-icon[stackItemSize]", inputs: { stackItemSize: "stackItemSize", size: "size" }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaStackItemSizeDirective, decorators: [{
type: Directive,
args: [{
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'la-icon[stackItemSize]',
standalone: false
}]
}], propDecorators: { stackItemSize: [{
type: Input
}], size: [{
type: Input
}] } });
class LaIconComponent {
/**
* Specify a title for the icon.
* This text will be displayed in a tooltip on hover and presented to the
* screen readers.
*/
get titleAttr() {
return this.title;
}
constructor(sanitizer, renderer, iconRegistry, stackItem) {
this.sanitizer = sanitizer;
this.renderer = renderer;
this.iconRegistry = iconRegistry;
this.stackItem = stackItem;
this.classes = [];
}
/**
* Programmatically trigger rendering of the icon.
*
* This method is useful, when creating dynamically or
* changing its inputs programmatically as in these cases icon won't be
* re-rendered automatically.
*/
render() {
this.ngOnChanges({});
}
ngOnChanges(changes) {
if (!this.icon) {
throw new Error('Property `icon` is required for `la-icon` component.');
}
if (changes) {
const iconDefinition = faNormalizeIcon(this.icon);
const params = this.buildParams();
this.renderIcon(iconDefinition, params);
}
}
buildParams() {
const classOpts = {
flip: this.flip,
spin: this.spin,
pulse: this.pulse,
border: this.border,
inverse: this.inverse,
size: this.size || null,
pull: this.pull || null,
rotate: this.rotate || null,
fixedWidth: this.fixedWidth,
stackItemSize: this.stackItem ? this.stackItem.stackItemSize : null
};
const parsedTransform = typeof this.transform === 'string'
? parseTransformString(this.transform)
: this.transform || {};
return {
title: this.title,
transform: parsedTransform,
classes: [...laClassList(classOpts), ...this.classes],
styles: this.styles != null ? this.styles : {}
};
}
renderIcon(definition, params) {
const svgData = this.iconRegistry.getIcon(definition);
const renderedIcon = this.svgElementFromString(svgData);
const attributes = {
'aria-hidden': 'true',
role: 'img',
focusable: 'false',
// Note: prefix and prefix-icon-name classes are helpfully to make the tests
class: [definition.prefix, `${IconNamePrefix}-${definition.iconName}`, ...params.classes].join(' ')
};
// Apply attributes, note the classes also goes here
for (const [key, value] of Object.entries(attributes)) {
this.renderer.setAttribute(renderedIcon, key, value);
}
// Apply css transforms
this.renderer.setStyle(renderedIcon, 'transform', applyCssTransforms(params.transform));
// Inject svg icon
this.renderedIconHTML = this.sanitizer.bypassSecurityTrustHtml(renderedIcon.outerHTML);
}
svgElementFromString(svgContent) {
const div = this.renderer.createElement('div');
div.innerHTML = svgContent;
return div.querySelector('svg');
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaIconComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.Renderer2 }, { token: LaIconLibrary }, { token: LaStackItemSizeDirective, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: LaIconComponent, isStandalone: false, selector: "la-icon", inputs: { icon: "icon", size: "size", fixedWidth: "fixedWidth", rotate: "rotate", flip: "flip", pull: "pull", spin: "spin", pulse: "pulse", border: "border", inverse: "inverse", styles: "styles", classes: "classes", transform: "transform", mask: "mask", title: "title" }, host: { properties: { "innerHTML": "this.renderedIconHTML", "attr.title": "this.titleAttr" } }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, styles: [".la-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.la-xs{font-size:.75em}.la-2x{font-size:1em}.la-2x{font-size:2em}.la-3x{font-size:3em}.la-4x{font-size:4em}.la-5x{font-size:5em}.la-6x{font-size:6em}.la-7x{font-size:7em}.la-8x{font-size:8em}.la-9x{font-size:9em}.la-10x{font-size:10em}.la-fw{text-align:center;width:1.25em}.la-fw{width:1.25em;text-align:center}.la-ul{padding-left:0;margin-left:1.4285714286em;list-style-type:none}.la-ul>li{position:relative}.la-li{position:absolute;left:-2em;text-align:center;width:1.4285714286em;line-height:inherit}.la-li.la-lg{left:-1.1428571429em}.la-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.la.la-pull-left{margin-right:.3em}.la.la-pull-right{margin-left:.3em}.la.pull-left{margin-right:.3em}.la.pull-right{margin-left:.3em}.la-pull-left{float:left}.la-pull-right{float:right}.la.la-pull-left,.las.la-pull-left,.lar.la-pull-left,.lal.la-pull-left,.lab.la-pull-left{margin-right:.3em}.la.la-pull-right,.las.la-pull-right,.lar.la-pull-right,.lal.la-pull-right,.lab.la-pull-right{margin-left:.3em}.la-spin{-webkit-animation:la-spin 2s infinite linear;animation:la-spin 2s infinite linear}.la-pulse{-webkit-animation:la-spin 1s infinite steps(8);animation:la-spin 1s infinite steps(8)}@-webkit-keyframes la-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes la-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.la-rotate-90{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.la-rotate-180{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.la-rotate-270{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.la-flip-horizontal{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";-webkit-transform:scale(-1,1);transform:scaleX(-1)}.la-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";-webkit-transform:scale(1,-1);transform:scaleY(-1)}.la-flip-both,.la-flip-horizontal.la-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";-webkit-transform:scale(-1,-1);transform:scale(-1)}:root .la-rotate-90,:root .la-rotate-180,:root .la-rotate-270,:root .la-flip-horizontal,:root .la-flip-vertical,:root .la-flip-both{-webkit-filter:none;filter:none}.la-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.la-stack-1x,.la-stack-2x{left:0;position:absolute;text-align:center;width:100%}.la-stack-1x{line-height:inherit}.la-stack-2x{font-size:2em}.la-inverse{color:#fff}svg{display:inline-block;height:1em;overflow:visible;vertical-align:-.125em;fill:currentColor}svg:not(:root){overflow:hidden}.la-stack-1x{margin-top:.5em}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaIconComponent, decorators: [{
type: Component,
args: [{ selector: 'la-icon', template: '', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: false, styles: [".la-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.la-xs{font-size:.75em}.la-2x{font-size:1em}.la-2x{font-size:2em}.la-3x{font-size:3em}.la-4x{font-size:4em}.la-5x{font-size:5em}.la-6x{font-size:6em}.la-7x{font-size:7em}.la-8x{font-size:8em}.la-9x{font-size:9em}.la-10x{font-size:10em}.la-fw{text-align:center;width:1.25em}.la-fw{width:1.25em;text-align:center}.la-ul{padding-left:0;margin-left:1.4285714286em;list-style-type:none}.la-ul>li{position:relative}.la-li{position:absolute;left:-2em;text-align:center;width:1.4285714286em;line-height:inherit}.la-li.la-lg{left:-1.1428571429em}.la-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.la.la-pull-left{margin-right:.3em}.la.la-pull-right{margin-left:.3em}.la.pull-left{margin-right:.3em}.la.pull-right{margin-left:.3em}.la-pull-left{float:left}.la-pull-right{float:right}.la.la-pull-left,.las.la-pull-left,.lar.la-pull-left,.lal.la-pull-left,.lab.la-pull-left{margin-right:.3em}.la.la-pull-right,.las.la-pull-right,.lar.la-pull-right,.lal.la-pull-right,.lab.la-pull-right{margin-left:.3em}.la-spin{-webkit-animation:la-spin 2s infinite linear;animation:la-spin 2s infinite linear}.la-pulse{-webkit-animation:la-spin 1s infinite steps(8);animation:la-spin 1s infinite steps(8)}@-webkit-keyframes la-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes la-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.la-rotate-90{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";-webkit-transform:rotate(90deg);transform:rotate(90deg)}.la-rotate-180{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";-webkit-transform:rotate(180deg);transform:rotate(180deg)}.la-rotate-270{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";-webkit-transform:rotate(270deg);transform:rotate(270deg)}.la-flip-horizontal{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";-webkit-transform:scale(-1,1);transform:scaleX(-1)}.la-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";-webkit-transform:scale(1,-1);transform:scaleY(-1)}.la-flip-both,.la-flip-horizontal.la-flip-vertical{-ms-filter:\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";-webkit-transform:scale(-1,-1);transform:scale(-1)}:root .la-rotate-90,:root .la-rotate-180,:root .la-rotate-270,:root .la-flip-horizontal,:root .la-flip-vertical,:root .la-flip-both{-webkit-filter:none;filter:none}.la-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.la-stack-1x,.la-stack-2x{left:0;position:absolute;text-align:center;width:100%}.la-stack-1x{line-height:inherit}.la-stack-2x{font-size:2em}.la-inverse{color:#fff}svg{display:inline-block;height:1em;overflow:visible;vertical-align:-.125em;fill:currentColor}svg:not(:root){overflow:hidden}.la-stack-1x{margin-top:.5em}\n"] }]
}], ctorParameters: () => [{ type: i1.DomSanitizer }, { type: i0.Renderer2 }, { type: LaIconLibrary }, { type: LaStackItemSizeDirective, decorators: [{
type: Optional
}] }], propDecorators: { icon: [{
type: Input
}], size: [{
type: Input
}], fixedWidth: [{
type: Input
}], rotate: [{
type: Input
}], flip: [{
type: Input
}], pull: [{
type: Input
}], spin: [{
type: Input
}], pulse: [{
type: Input
}], border: [{
type: Input
}], inverse: [{
type: Input
}], styles: [{
type: Input
}], classes: [{
type: Input
}], transform: [{
type: Input
}], mask: [{
type: Input
}], title: [{
type: Input
}], renderedIconHTML: [{
type: HostBinding,
args: ['innerHTML']
}], titleAttr: [{
type: HostBinding,
args: ['attr.title']
}] } });
class LaStackComponent {
constructor(renderer, elementRef) {
this.renderer = renderer;
this.elementRef = elementRef;
}
ngOnInit() {
this.renderer.addClass(this.elementRef.nativeElement, 'la-stack');
}
ngOnChanges(changes) {
if ('size' in changes) {
if (changes.size.currentValue != null) {
this.renderer.addClass(this.elementRef.nativeElement, `${IconNamePrefix}-${changes.size.currentValue}`);
}
if (changes.size.previousValue != null) {
this.renderer.removeClass(this.elementRef.nativeElement, `${IconNamePrefix}-${changes.size.previousValue}`);
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaStackComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.4", type: LaStackComponent, isStandalone: false, selector: "la-stack", inputs: { size: "size" }, usesOnChanges: true, ngImport: i0, template: `
<ng-content select="la-icon[stackItemSize]"></ng-content>
`, isInline: true }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: LaStackComponent, decorators: [{
type: Component,
args: [{
selector: 'la-stack',
// TODO: See if it is better to select la-icon and throw if it does not have stackItemSize directive
template: `
<ng-content select="la-icon[stackItemSize]"></ng-content>
`,
standalone: false
}]
}], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }], propDecorators: { size: [{
type: Input
}] } });
class AngularLineawesomeModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: AngularLineawesomeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.4", ngImport: i0, type: AngularLineawesomeModule, declarations: [LaIconComponent, LaStackComponent, LaStackItemSizeDirective], exports: [LaIconComponent, LaStackComponent, LaStackItemSizeDirective] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: AngularLineawesomeModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImport: i0, type: AngularLineawesomeModule, decorators: [{
type: NgModule,
args: [{
declarations: [LaIconComponent, LaStackComponent, LaStackItemSizeDirective],
imports: [],
exports: [LaIconComponent, LaStackComponent, LaStackItemSizeDirective]
}]
}] });
/*
* Public API Surface of angular-line-awesome
*/
/**
* Generated bundle index. Do not edit.
*/
export { AngularLineawesomeModule, LaIconComponent, LaIconLibrary, LaStackComponent, LaStackItemSizeDirective };
//# sourceMappingURL=angular-line-awesome.mjs.map