import * as i0 from '@angular/core';
import { Injectable, input, effect, Directive, computed, ChangeDetectionStrategy, Component, model, inject, DOCUMENT, NgModule } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { config, dom, icon, parse, counter, text } from '@fortawesome/fontawesome-svg-core';
class FaConfig {
/**
* Default prefix to use, when one is not provided with the icon name.
*
* @default 'fas'
*/
defaultPrefix = 'fas';
/**
* Provides a fallback icon to use whilst main icon is being loaded asynchronously.
* When value is null, then fa-icon component will throw an error if icon input is missing.
* When value is not null, then the provided icon will be used as a fallback icon if icon input is missing.
*
* @default null
*/
fallbackIcon = null;
/**
* Set icons to the same fixed width.
*
* @see {@link: https://fontawesome.com/how-to-use/on-the-web/styling/fixed-width-icons}
* @default false
*/
fixedWidth;
/**
* Automatically add Font Awesome styles to the document when icon is rendered.
*
* For the majority of the cases the automatically added CSS is sufficient,
* please refer to the linked guide for more information on when to disable
* this feature.
*
* @see {@link: https://github.com/FortAwesome/angular-fontawesome/blob/main/docs/guide/adding-css.md}
* @default true
*/
set autoAddCss(value) {
config.autoAddCss = value;
this._autoAddCss = value;
}
get autoAddCss() {
return this._autoAddCss;
}
_autoAddCss = true;
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaConfig, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaConfig, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}] });
class FaIconLibrary {
definitions = {};
addIcons(...icons) {
for (const icon of icons) {
if (!(icon.prefix in this.definitions)) {
this.definitions[icon.prefix] = {};
}
this.definitions[icon.prefix][icon.iconName] = icon;
for (const alias of icon.icon[2]) {
if (typeof alias === 'string') {
this.definitions[icon.prefix][alias] = icon;
}
}
}
}
addIconPacks(...packs) {
for (const pack of packs) {
const icons = Object.keys(pack).map((key) => pack[key]);
this.addIcons(...icons);
}
}
getIconDefinition(prefix, name) {
if (prefix in this.definitions && name in this.definitions[prefix]) {
return this.definitions[prefix][name];
}
return null;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaIconLibrary, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaIconLibrary, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaIconLibrary, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}] });
const faWarnIfIconDefinitionMissing = (iconSpec) => {
throw new Error(`Could not find icon with iconName=${iconSpec.iconName} and prefix=${iconSpec.prefix} in the icon library.`);
};
const faWarnIfIconSpecMissing = () => {
throw new Error('Property `icon` is required for `fa-icon`/`fa-duotone-icon` components.');
};
const isKnownRotateValue = (rotate) => rotate != null &&
(rotate === 90 || rotate === 180 || rotate === 270 || rotate === '90' || rotate === '180' || rotate === '270');
/**
* Fontawesome class list.
* Returns classes array by props.
*/
const faClassList = (props) => {
const knownRotateValue = isKnownRotateValue(props.rotate);
const classes = {
[`fa-${props.animation}`]: props.animation != null && !props.animation.startsWith('spin'),
'fa-spin': props.animation === 'spin' || props.animation === 'spin-reverse',
'fa-spin-pulse': props.animation === 'spin-pulse' || props.animation === 'spin-pulse-reverse',
'fa-spin-reverse': props.animation === 'spin-reverse' || props.animation === 'spin-pulse-reverse',
// According to https://fontawesome.com/docs/web/style/animate#spin fa-pulse
// class is deprecated, remove the below line when Font Awesome 5 support
// is dropped.
'fa-pulse': props.animation === 'spin-pulse' || props.animation === 'spin-pulse-reverse',
'fa-fw': props.fixedWidth,
'fa-border': props.border,
'fa-inverse': props.inverse,
'fa-layers-counter': props.counter,
'fa-flip-horizontal': props.flip === 'horizontal' || props.flip === 'both',
'fa-flip-vertical': props.flip === 'vertical' || props.flip === 'both',
[`fa-${props.size}`]: props.size !== null,
[`fa-rotate-${props.rotate}`]: knownRotateValue,
'fa-rotate-by': props.rotate != null && !knownRotateValue,
[`fa-pull-${props.pull}`]: props.pull !== null,
[`fa-stack-${props.stackItemSize}`]: props.stackItemSize != null,
};
return Object.keys(classes)
.map((key) => (classes[key] ? key : null))
.filter((key) => key != null);
};
const cssInserted = new WeakSet();
const autoCssId = 'fa-auto-css';
/**
* Ensure that Font Awesome CSS is inserted into the page.
*
* SVG Core has the same logic to insert the same styles into the page, however
* it's not aware of Angular SSR and therefore styles won't be added in that
* context leading to https://github.com/FortAwesome/angular-fontawesome/issues/48.
* That's why the same logic is duplicated here.
*
* @param document - Document.
* @param config - Font Awesome configuration.
*/
function ensureCss(document, config) {
if (!config.autoAddCss) {
return;
}
if (cssInserted.has(document)) {
return;
}
// Prevent adding the same styles again after hydration.
if (document.getElementById(autoCssId) != null) {
config.autoAddCss = false;
cssInserted.add(document);
return;
}
const style = document.createElement('style');
style.setAttribute('type', 'text/css');
style.setAttribute('id', autoCssId);
style.innerHTML = dom.css();
const headChildren = document.head.childNodes;
let beforeChild = null;
for (let i = headChildren.length - 1; i > -1; i--) {
const child = headChildren[i];
const tagName = child.nodeName.toUpperCase();
if (['STYLE', 'LINK'].indexOf(tagName) > -1) {
beforeChild = child;
}
}
document.head.insertBefore(style, beforeChild);
// Prevent SVG Core from adding the same styles.
//
// As the logic is present in two places and SVG Core is not aware about
// this library, it may lead to styles being added twice. This can only
// occur when icon is rendered by SVG Core before the Angular component
// and should not have any significant negative impact. This is a rare
// use case, and it's tricky to prevent, so we accept this behavior. Consumer
// can choose to disable `FaConfig.autoAddCss` and add styles manually to
// prevent this from happening.
config.autoAddCss = false;
cssInserted.add(document);
}
/**
* Returns if is IconLookup or not.
*/
const isIconLookup = (i) => i.prefix !== undefined && i.iconName !== undefined;
/**
* Normalizing icon spec.
*/
const faNormalizeIconSpec = (iconSpec, defaultPrefix) => {
if (isIconLookup(iconSpec)) {
return iconSpec;
}
if (Array.isArray(iconSpec) && iconSpec.length === 2) {
return { prefix: iconSpec[0], iconName: iconSpec[1] };
}
return { prefix: defaultPrefix, iconName: iconSpec };
};
class FaStackItemSizeDirective {
/**
* Specify whether icon inside {@link FaStackComponent} should be rendered in
* regular size (1x) or as a larger icon (2x).
*/
stackItemSize = input('1x');
/**
* @internal
*/
size = input();
_effect = effect(() => {
const size = this.size();
if (size) {
throw new Error('fa-icon is not allowed to customize size when used inside fa-stack. ' +
'Set size on the enclosing fa-stack instead: ....');
}
});
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaStackItemSizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.0", type: FaStackItemSizeDirective, isStandalone: true, selector: "fa-icon[stackItemSize],fa-duotone-icon[stackItemSize]", inputs: { stackItemSize: { classPropertyName: "stackItemSize", publicName: "stackItemSize", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaStackItemSizeDirective, decorators: [{
type: Directive,
args: [{
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'fa-icon[stackItemSize],fa-duotone-icon[stackItemSize]',
}]
}] });
class FaStackComponent {
/**
* Size of the stacked icon.
* Note that stacked icon is by default 2 times bigger, than non-stacked icon.
* You'll need to set size using custom CSS to align stacked icon with a
* simple one. E.g. `fa-stack { font-size: 0.5em; }`.
*/
size = input();
classes = computed(() => {
const sizeValue = this.size();
const sizeClass = sizeValue ? { [`fa-${sizeValue}`]: true } : {};
return {
...sizeClass,
'fa-stack': true,
};
});
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaStackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: FaStackComponent, isStandalone: true, selector: "fa-stack", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaStackComponent, decorators: [{
type: Component,
args: [{
selector: 'fa-stack',
template: ``,
host: {
'[class]': 'classes()',
},
changeDetection: ChangeDetectionStrategy.OnPush,
}]
}] });
class FaIconComponent {
icon = model.required();
/**
* Specify a title for the icon.
*
* This text will be displayed in a tooltip on hover and presented to the
* screen readers.
*/
title = model();
/**
* Icon animation.
*
* Most of the animations are only available when using Font Awesome 6. With
* Font Awesome 5, only 'spin' and 'spin-pulse' are supported.
*/
animation = model();
mask = model();
flip = model();
size = model();
pull = model();
border = model();
inverse = model();
symbol = model();
rotate = model();
fixedWidth = model();
transform = model();
/**
* Specify the `role` attribute for the rendered