angular-fontawesome.mjs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. import * as i0 from '@angular/core';
  2. import { Injectable, input, effect, Directive, computed, ChangeDetectionStrategy, Component, model, inject, DOCUMENT, NgModule } from '@angular/core';
  3. import { DomSanitizer } from '@angular/platform-browser';
  4. import { config, dom, icon, parse, counter, text } from '@fortawesome/fontawesome-svg-core';
  5. class FaConfig {
  6. /**
  7. * Default prefix to use, when one is not provided with the icon name.
  8. *
  9. * @default 'fas'
  10. */
  11. defaultPrefix = 'fas';
  12. /**
  13. * Provides a fallback icon to use whilst main icon is being loaded asynchronously.
  14. * When value is null, then fa-icon component will throw an error if icon input is missing.
  15. * When value is not null, then the provided icon will be used as a fallback icon if icon input is missing.
  16. *
  17. * @default null
  18. */
  19. fallbackIcon = null;
  20. /**
  21. * Set icons to the same fixed width.
  22. *
  23. * @see {@link: https://fontawesome.com/how-to-use/on-the-web/styling/fixed-width-icons}
  24. * @default false
  25. */
  26. fixedWidth;
  27. /**
  28. * Automatically add Font Awesome styles to the document when icon is rendered.
  29. *
  30. * For the majority of the cases the automatically added CSS is sufficient,
  31. * please refer to the linked guide for more information on when to disable
  32. * this feature.
  33. *
  34. * @see {@link: https://github.com/FortAwesome/angular-fontawesome/blob/main/docs/guide/adding-css.md}
  35. * @default true
  36. */
  37. set autoAddCss(value) {
  38. config.autoAddCss = value;
  39. this._autoAddCss = value;
  40. }
  41. get autoAddCss() {
  42. return this._autoAddCss;
  43. }
  44. _autoAddCss = true;
  45. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
  46. static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaConfig, providedIn: 'root' });
  47. }
  48. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaConfig, decorators: [{
  49. type: Injectable,
  50. args: [{ providedIn: 'root' }]
  51. }] });
  52. class FaIconLibrary {
  53. definitions = {};
  54. addIcons(...icons) {
  55. for (const icon of icons) {
  56. if (!(icon.prefix in this.definitions)) {
  57. this.definitions[icon.prefix] = {};
  58. }
  59. this.definitions[icon.prefix][icon.iconName] = icon;
  60. for (const alias of icon.icon[2]) {
  61. if (typeof alias === 'string') {
  62. this.definitions[icon.prefix][alias] = icon;
  63. }
  64. }
  65. }
  66. }
  67. addIconPacks(...packs) {
  68. for (const pack of packs) {
  69. const icons = Object.keys(pack).map((key) => pack[key]);
  70. this.addIcons(...icons);
  71. }
  72. }
  73. getIconDefinition(prefix, name) {
  74. if (prefix in this.definitions && name in this.definitions[prefix]) {
  75. return this.definitions[prefix][name];
  76. }
  77. return null;
  78. }
  79. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaIconLibrary, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
  80. static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaIconLibrary, providedIn: 'root' });
  81. }
  82. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaIconLibrary, decorators: [{
  83. type: Injectable,
  84. args: [{ providedIn: 'root' }]
  85. }] });
  86. const faWarnIfIconDefinitionMissing = (iconSpec) => {
  87. throw new Error(`Could not find icon with iconName=${iconSpec.iconName} and prefix=${iconSpec.prefix} in the icon library.`);
  88. };
  89. const faWarnIfIconSpecMissing = () => {
  90. throw new Error('Property `icon` is required for `fa-icon`/`fa-duotone-icon` components.');
  91. };
  92. const isKnownRotateValue = (rotate) => rotate != null &&
  93. (rotate === 90 || rotate === 180 || rotate === 270 || rotate === '90' || rotate === '180' || rotate === '270');
  94. /**
  95. * Fontawesome class list.
  96. * Returns classes array by props.
  97. */
  98. const faClassList = (props) => {
  99. const knownRotateValue = isKnownRotateValue(props.rotate);
  100. const classes = {
  101. [`fa-${props.animation}`]: props.animation != null && !props.animation.startsWith('spin'),
  102. 'fa-spin': props.animation === 'spin' || props.animation === 'spin-reverse',
  103. 'fa-spin-pulse': props.animation === 'spin-pulse' || props.animation === 'spin-pulse-reverse',
  104. 'fa-spin-reverse': props.animation === 'spin-reverse' || props.animation === 'spin-pulse-reverse',
  105. // According to https://fontawesome.com/docs/web/style/animate#spin fa-pulse
  106. // class is deprecated, remove the below line when Font Awesome 5 support
  107. // is dropped.
  108. 'fa-pulse': props.animation === 'spin-pulse' || props.animation === 'spin-pulse-reverse',
  109. 'fa-fw': props.fixedWidth,
  110. 'fa-border': props.border,
  111. 'fa-inverse': props.inverse,
  112. 'fa-layers-counter': props.counter,
  113. 'fa-flip-horizontal': props.flip === 'horizontal' || props.flip === 'both',
  114. 'fa-flip-vertical': props.flip === 'vertical' || props.flip === 'both',
  115. [`fa-${props.size}`]: props.size !== null,
  116. [`fa-rotate-${props.rotate}`]: knownRotateValue,
  117. 'fa-rotate-by': props.rotate != null && !knownRotateValue,
  118. [`fa-pull-${props.pull}`]: props.pull !== null,
  119. [`fa-stack-${props.stackItemSize}`]: props.stackItemSize != null,
  120. };
  121. return Object.keys(classes)
  122. .map((key) => (classes[key] ? key : null))
  123. .filter((key) => key != null);
  124. };
  125. const cssInserted = new WeakSet();
  126. const autoCssId = 'fa-auto-css';
  127. /**
  128. * Ensure that Font Awesome CSS is inserted into the page.
  129. *
  130. * SVG Core has the same logic to insert the same styles into the page, however
  131. * it's not aware of Angular SSR and therefore styles won't be added in that
  132. * context leading to https://github.com/FortAwesome/angular-fontawesome/issues/48.
  133. * That's why the same logic is duplicated here.
  134. *
  135. * @param document - Document.
  136. * @param config - Font Awesome configuration.
  137. */
  138. function ensureCss(document, config) {
  139. if (!config.autoAddCss) {
  140. return;
  141. }
  142. if (cssInserted.has(document)) {
  143. return;
  144. }
  145. // Prevent adding the same styles again after hydration.
  146. if (document.getElementById(autoCssId) != null) {
  147. config.autoAddCss = false;
  148. cssInserted.add(document);
  149. return;
  150. }
  151. const style = document.createElement('style');
  152. style.setAttribute('type', 'text/css');
  153. style.setAttribute('id', autoCssId);
  154. style.innerHTML = dom.css();
  155. const headChildren = document.head.childNodes;
  156. let beforeChild = null;
  157. for (let i = headChildren.length - 1; i > -1; i--) {
  158. const child = headChildren[i];
  159. const tagName = child.nodeName.toUpperCase();
  160. if (['STYLE', 'LINK'].indexOf(tagName) > -1) {
  161. beforeChild = child;
  162. }
  163. }
  164. document.head.insertBefore(style, beforeChild);
  165. // Prevent SVG Core from adding the same styles.
  166. //
  167. // As the logic is present in two places and SVG Core is not aware about
  168. // this library, it may lead to styles being added twice. This can only
  169. // occur when icon is rendered by SVG Core before the Angular component
  170. // and should not have any significant negative impact. This is a rare
  171. // use case, and it's tricky to prevent, so we accept this behavior. Consumer
  172. // can choose to disable `FaConfig.autoAddCss` and add styles manually to
  173. // prevent this from happening.
  174. config.autoAddCss = false;
  175. cssInserted.add(document);
  176. }
  177. /**
  178. * Returns if is IconLookup or not.
  179. */
  180. const isIconLookup = (i) => i.prefix !== undefined && i.iconName !== undefined;
  181. /**
  182. * Normalizing icon spec.
  183. */
  184. const faNormalizeIconSpec = (iconSpec, defaultPrefix) => {
  185. if (isIconLookup(iconSpec)) {
  186. return iconSpec;
  187. }
  188. if (Array.isArray(iconSpec) && iconSpec.length === 2) {
  189. return { prefix: iconSpec[0], iconName: iconSpec[1] };
  190. }
  191. return { prefix: defaultPrefix, iconName: iconSpec };
  192. };
  193. class FaStackItemSizeDirective {
  194. /**
  195. * Specify whether icon inside {@link FaStackComponent} should be rendered in
  196. * regular size (1x) or as a larger icon (2x).
  197. */
  198. stackItemSize = input('1x');
  199. /**
  200. * @internal
  201. */
  202. size = input();
  203. _effect = effect(() => {
  204. const size = this.size();
  205. if (size) {
  206. throw new Error('fa-icon is not allowed to customize size when used inside fa-stack. ' +
  207. 'Set size on the enclosing fa-stack instead: <fa-stack size="4x">...</fa-stack>.');
  208. }
  209. });
  210. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaStackItemSizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
  211. 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 });
  212. }
  213. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaStackItemSizeDirective, decorators: [{
  214. type: Directive,
  215. args: [{
  216. // eslint-disable-next-line @angular-eslint/directive-selector
  217. selector: 'fa-icon[stackItemSize],fa-duotone-icon[stackItemSize]',
  218. }]
  219. }] });
  220. class FaStackComponent {
  221. /**
  222. * Size of the stacked icon.
  223. * Note that stacked icon is by default 2 times bigger, than non-stacked icon.
  224. * You'll need to set size using custom CSS to align stacked icon with a
  225. * simple one. E.g. `fa-stack { font-size: 0.5em; }`.
  226. */
  227. size = input();
  228. classes = computed(() => {
  229. const sizeValue = this.size();
  230. const sizeClass = sizeValue ? { [`fa-${sizeValue}`]: true } : {};
  231. return {
  232. ...sizeClass,
  233. 'fa-stack': true,
  234. };
  235. });
  236. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaStackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
  237. 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: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
  238. }
  239. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaStackComponent, decorators: [{
  240. type: Component,
  241. args: [{
  242. selector: 'fa-stack',
  243. template: `<ng-content></ng-content>`,
  244. host: {
  245. '[class]': 'classes()',
  246. },
  247. changeDetection: ChangeDetectionStrategy.OnPush,
  248. }]
  249. }] });
  250. class FaIconComponent {
  251. icon = model.required();
  252. /**
  253. * Specify a title for the icon.
  254. *
  255. * This text will be displayed in a tooltip on hover and presented to the
  256. * screen readers.
  257. */
  258. title = model();
  259. /**
  260. * Icon animation.
  261. *
  262. * Most of the animations are only available when using Font Awesome 6. With
  263. * Font Awesome 5, only 'spin' and 'spin-pulse' are supported.
  264. */
  265. animation = model();
  266. mask = model();
  267. flip = model();
  268. size = model();
  269. pull = model();
  270. border = model();
  271. inverse = model();
  272. symbol = model();
  273. rotate = model();
  274. fixedWidth = model();
  275. transform = model();
  276. /**
  277. * Specify the `role` attribute for the rendered <svg> element.
  278. *
  279. * @default 'img'
  280. */
  281. a11yRole = model();
  282. renderedIconHTML = computed(() => {
  283. const iconValue = this.icon();
  284. if (iconValue == null && this.config.fallbackIcon == null) {
  285. faWarnIfIconSpecMissing();
  286. return '';
  287. }
  288. const iconDefinition = this.findIconDefinition(iconValue ?? this.config.fallbackIcon);
  289. if (!iconDefinition) {
  290. return '';
  291. }
  292. const params = this.buildParams();
  293. ensureCss(this.document, this.config);
  294. const renderedIcon = icon(iconDefinition, params);
  295. return this.sanitizer.bypassSecurityTrustHtml(renderedIcon.html.join('\n'));
  296. });
  297. document = inject(DOCUMENT);
  298. sanitizer = inject(DomSanitizer);
  299. config = inject(FaConfig);
  300. iconLibrary = inject(FaIconLibrary);
  301. stackItem = inject(FaStackItemSizeDirective, { optional: true });
  302. stack = inject(FaStackComponent, { optional: true });
  303. constructor() {
  304. if (this.stack != null && this.stackItem == null) {
  305. console.error('FontAwesome: fa-icon and fa-duotone-icon elements must specify stackItemSize attribute when wrapped into ' +
  306. 'fa-stack. Example: <fa-icon stackItemSize="2x"></fa-icon>.');
  307. }
  308. }
  309. findIconDefinition(i) {
  310. const lookup = faNormalizeIconSpec(i, this.config.defaultPrefix);
  311. if ('icon' in lookup) {
  312. return lookup;
  313. }
  314. const definition = this.iconLibrary.getIconDefinition(lookup.prefix, lookup.iconName);
  315. if (definition != null) {
  316. return definition;
  317. }
  318. faWarnIfIconDefinitionMissing(lookup);
  319. return null;
  320. }
  321. buildParams() {
  322. const fixedWidth = this.fixedWidth();
  323. const classOpts = {
  324. flip: this.flip(),
  325. animation: this.animation(),
  326. border: this.border(),
  327. inverse: this.inverse(),
  328. size: this.size(),
  329. pull: this.pull(),
  330. rotate: this.rotate(),
  331. fixedWidth: typeof fixedWidth === 'boolean' ? fixedWidth : this.config.fixedWidth,
  332. stackItemSize: this.stackItem != null ? this.stackItem.stackItemSize() : undefined,
  333. };
  334. const transform = this.transform();
  335. const parsedTransform = typeof transform === 'string' ? parse.transform(transform) : transform;
  336. const mask = this.mask();
  337. const maskIconDefinition = mask != null ? this.findIconDefinition(mask) : null;
  338. const attributes = {};
  339. const a11yRole = this.a11yRole();
  340. if (a11yRole != null) {
  341. attributes['role'] = a11yRole;
  342. }
  343. const styles = {};
  344. if (classOpts.rotate != null && !isKnownRotateValue(classOpts.rotate)) {
  345. styles['--fa-rotate-angle'] = `${classOpts.rotate}`;
  346. }
  347. return {
  348. title: this.title(),
  349. transform: parsedTransform,
  350. classes: faClassList(classOpts),
  351. mask: maskIconDefinition ?? undefined,
  352. symbol: this.symbol(),
  353. attributes,
  354. styles,
  355. };
  356. }
  357. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
  358. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: FaIconComponent, isStandalone: true, selector: "fa-icon", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null }, mask: { classPropertyName: "mask", publicName: "mask", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "flip", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, pull: { classPropertyName: "pull", publicName: "pull", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, inverse: { classPropertyName: "inverse", publicName: "inverse", isSignal: true, isRequired: false, transformFunction: null }, symbol: { classPropertyName: "symbol", publicName: "symbol", isSignal: true, isRequired: false, transformFunction: null }, rotate: { classPropertyName: "rotate", publicName: "rotate", isSignal: true, isRequired: false, transformFunction: null }, fixedWidth: { classPropertyName: "fixedWidth", publicName: "fixedWidth", isSignal: true, isRequired: false, transformFunction: null }, transform: { classPropertyName: "transform", publicName: "transform", isSignal: true, isRequired: false, transformFunction: null }, a11yRole: { classPropertyName: "a11yRole", publicName: "a11yRole", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { icon: "iconChange", title: "titleChange", animation: "animationChange", mask: "maskChange", flip: "flipChange", size: "sizeChange", pull: "pullChange", border: "borderChange", inverse: "inverseChange", symbol: "symbolChange", rotate: "rotateChange", fixedWidth: "fixedWidthChange", transform: "transformChange", a11yRole: "a11yRoleChange" }, host: { properties: { "attr.title": "title()", "innerHTML": "renderedIconHTML()" }, classAttribute: "ng-fa-icon" }, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
  359. }
  360. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaIconComponent, decorators: [{
  361. type: Component,
  362. args: [{
  363. selector: 'fa-icon',
  364. template: ``,
  365. host: {
  366. class: 'ng-fa-icon',
  367. '[attr.title]': 'title()',
  368. '[innerHTML]': 'renderedIconHTML()',
  369. },
  370. changeDetection: ChangeDetectionStrategy.OnPush,
  371. }]
  372. }], ctorParameters: () => [] });
  373. class FaDuotoneIconComponent extends FaIconComponent {
  374. /**
  375. * Swap the default opacity of each duotone icon’s layers. This will make an
  376. * icon’s primary layer have the default opacity of 40% rather than its
  377. * secondary layer.
  378. *
  379. * @default false
  380. */
  381. swapOpacity = input();
  382. /**
  383. * Customize the opacity of the primary icon layer.
  384. * Valid values are in range [0, 1.0].
  385. *
  386. * @default 1.0
  387. */
  388. primaryOpacity = input();
  389. /**
  390. * Customize the opacity of the secondary icon layer.
  391. * Valid values are in range [0, 1.0].
  392. *
  393. * @default 0.4
  394. */
  395. secondaryOpacity = input();
  396. /**
  397. * Customize the color of the primary icon layer.
  398. * Accepts any valid CSS color value.
  399. *
  400. * @default CSS inherited color
  401. */
  402. primaryColor = input();
  403. /**
  404. * Customize the color of the secondary icon layer.
  405. * Accepts any valid CSS color value.
  406. *
  407. * @default CSS inherited color
  408. */
  409. secondaryColor = input();
  410. findIconDefinition(i) {
  411. const definition = super.findIconDefinition(i);
  412. if (definition != null && !Array.isArray(definition.icon[4])) {
  413. throw new Error('The specified icon does not appear to be a Duotone icon. ' +
  414. 'Check that you specified the correct style: ' +
  415. `<fa-duotone-icon [icon]="['fad', '${definition.iconName}']"></fa-duotone-icon> ` +
  416. `or use: <fa-icon icon="${definition.iconName}"></fa-icon> instead.`);
  417. }
  418. return definition;
  419. }
  420. buildParams() {
  421. const params = super.buildParams();
  422. const swapOpacity = this.swapOpacity();
  423. if (swapOpacity === true || swapOpacity === 'true') {
  424. if (Array.isArray(params.classes)) {
  425. params.classes.push('fa-swap-opacity');
  426. }
  427. else if (typeof params.classes === 'string') {
  428. params.classes = [params.classes, 'fa-swap-opacity'];
  429. }
  430. else {
  431. params.classes = ['fa-swap-opacity'];
  432. }
  433. }
  434. if (params.styles == null) {
  435. params.styles = {};
  436. }
  437. const primaryOpacity = this.primaryOpacity();
  438. if (primaryOpacity != null) {
  439. params.styles['--fa-primary-opacity'] = primaryOpacity.toString();
  440. }
  441. const secondaryOpacity = this.secondaryOpacity();
  442. if (secondaryOpacity != null) {
  443. params.styles['--fa-secondary-opacity'] = secondaryOpacity.toString();
  444. }
  445. const primaryColor = this.primaryColor();
  446. if (primaryColor != null) {
  447. params.styles['--fa-primary-color'] = primaryColor;
  448. }
  449. const secondaryColor = this.secondaryColor();
  450. if (secondaryColor != null) {
  451. params.styles['--fa-secondary-color'] = secondaryColor;
  452. }
  453. return params;
  454. }
  455. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaDuotoneIconComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
  456. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: FaDuotoneIconComponent, isStandalone: true, selector: "fa-duotone-icon", inputs: { swapOpacity: { classPropertyName: "swapOpacity", publicName: "swapOpacity", isSignal: true, isRequired: false, transformFunction: null }, primaryOpacity: { classPropertyName: "primaryOpacity", publicName: "primaryOpacity", isSignal: true, isRequired: false, transformFunction: null }, secondaryOpacity: { classPropertyName: "secondaryOpacity", publicName: "secondaryOpacity", isSignal: true, isRequired: false, transformFunction: null }, primaryColor: { classPropertyName: "primaryColor", publicName: "primaryColor", isSignal: true, isRequired: false, transformFunction: null }, secondaryColor: { classPropertyName: "secondaryColor", publicName: "secondaryColor", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
  457. }
  458. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaDuotoneIconComponent, decorators: [{
  459. type: Component,
  460. args: [{
  461. selector: 'fa-duotone-icon',
  462. template: ``,
  463. changeDetection: ChangeDetectionStrategy.OnPush,
  464. }]
  465. }] });
  466. /**
  467. * Warns if parent component not existing.
  468. */
  469. const faWarnIfParentNotExist = (parent, parentName, childName) => {
  470. if (!parent) {
  471. throw new Error(`${childName} should be used as child of ${parentName} only.`);
  472. }
  473. };
  474. /**
  475. * Fontawesome layers.
  476. */
  477. class FaLayersComponent {
  478. size = input();
  479. fixedWidth = input();
  480. faFw = computed(() => {
  481. const fixedWidth = this.fixedWidth();
  482. return typeof fixedWidth === 'boolean' ? fixedWidth : this.config.fixedWidth;
  483. });
  484. classes = computed(() => {
  485. const sizeValue = this.size();
  486. const sizeClass = sizeValue ? { [`fa-${sizeValue}`]: true } : {};
  487. return {
  488. ...sizeClass,
  489. 'fa-fw': this.faFw(),
  490. 'fa-layers': true,
  491. };
  492. });
  493. document = inject(DOCUMENT);
  494. config = inject(FaConfig);
  495. ngOnInit() {
  496. ensureCss(this.document, this.config);
  497. }
  498. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaLayersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
  499. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: FaLayersComponent, isStandalone: true, selector: "fa-layers", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fixedWidth: { classPropertyName: "fixedWidth", publicName: "fixedWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
  500. }
  501. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaLayersComponent, decorators: [{
  502. type: Component,
  503. args: [{
  504. selector: 'fa-layers',
  505. template: `<ng-content></ng-content>`,
  506. host: {
  507. '[class]': 'classes()',
  508. },
  509. changeDetection: ChangeDetectionStrategy.OnPush,
  510. }]
  511. }] });
  512. class FaLayersCounterComponent {
  513. content = input.required();
  514. title = input();
  515. position = input();
  516. renderedHTML = computed(() => {
  517. const params = this.buildParams();
  518. return this.updateContent(params);
  519. });
  520. document = inject(DOCUMENT);
  521. config = inject(FaConfig);
  522. parent = inject(FaLayersComponent, { optional: true });
  523. sanitizer = inject(DomSanitizer);
  524. constructor() {
  525. faWarnIfParentNotExist(this.parent, 'FaLayersComponent', this.constructor.name);
  526. }
  527. buildParams() {
  528. const position = this.position();
  529. return {
  530. title: this.title(),
  531. classes: position != null ? [`fa-layers-${position}`] : undefined,
  532. };
  533. }
  534. updateContent(params) {
  535. ensureCss(this.document, this.config);
  536. return this.sanitizer.bypassSecurityTrustHtml(counter(this.content() || '', params).html.join(''));
  537. }
  538. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaLayersCounterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
  539. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: FaLayersCounterComponent, isStandalone: true, selector: "fa-layers-counter", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "innerHTML": "renderedHTML()" }, classAttribute: "ng-fa-layers-counter" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
  540. }
  541. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaLayersCounterComponent, decorators: [{
  542. type: Component,
  543. args: [{
  544. selector: 'fa-layers-counter',
  545. template: '',
  546. host: {
  547. class: 'ng-fa-layers-counter',
  548. '[innerHTML]': 'renderedHTML()',
  549. },
  550. changeDetection: ChangeDetectionStrategy.OnPush,
  551. }]
  552. }], ctorParameters: () => [] });
  553. class FaLayersTextComponent {
  554. content = input.required();
  555. title = input();
  556. flip = input();
  557. size = input();
  558. pull = input();
  559. border = input();
  560. inverse = input();
  561. rotate = input();
  562. fixedWidth = input();
  563. transform = input();
  564. renderedHTML = computed(() => {
  565. const params = this.buildParams();
  566. return this.updateContent(params);
  567. });
  568. document = inject(DOCUMENT);
  569. config = inject(FaConfig);
  570. parent = inject(FaLayersComponent, { optional: true });
  571. sanitizer = inject(DomSanitizer);
  572. constructor() {
  573. faWarnIfParentNotExist(this.parent, 'FaLayersComponent', this.constructor.name);
  574. }
  575. /**
  576. * Updating params by component props.
  577. */
  578. buildParams() {
  579. const classOpts = {
  580. flip: this.flip(),
  581. border: this.border(),
  582. inverse: this.inverse(),
  583. size: this.size(),
  584. pull: this.pull(),
  585. rotate: this.rotate(),
  586. fixedWidth: this.fixedWidth(),
  587. };
  588. const transform = this.transform();
  589. const parsedTransform = typeof transform === 'string' ? parse.transform(transform) : transform;
  590. const styles = {};
  591. if (classOpts.rotate != null && !isKnownRotateValue(classOpts.rotate)) {
  592. styles['--fa-rotate-angle'] = `${classOpts.rotate}`;
  593. }
  594. return {
  595. transform: parsedTransform,
  596. classes: faClassList(classOpts),
  597. title: this.title(),
  598. styles,
  599. };
  600. }
  601. updateContent(params) {
  602. ensureCss(this.document, this.config);
  603. return this.sanitizer.bypassSecurityTrustHtml(text(this.content() || '', params).html.join('\n'));
  604. }
  605. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaLayersTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
  606. static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.0", type: FaLayersTextComponent, isStandalone: true, selector: "fa-layers-text", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "flip", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, pull: { classPropertyName: "pull", publicName: "pull", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, inverse: { classPropertyName: "inverse", publicName: "inverse", isSignal: true, isRequired: false, transformFunction: null }, rotate: { classPropertyName: "rotate", publicName: "rotate", isSignal: true, isRequired: false, transformFunction: null }, fixedWidth: { classPropertyName: "fixedWidth", publicName: "fixedWidth", isSignal: true, isRequired: false, transformFunction: null }, transform: { classPropertyName: "transform", publicName: "transform", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "innerHTML": "renderedHTML()" }, classAttribute: "ng-fa-layers-text" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
  607. }
  608. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FaLayersTextComponent, decorators: [{
  609. type: Component,
  610. args: [{
  611. selector: 'fa-layers-text',
  612. template: '',
  613. host: {
  614. class: 'ng-fa-layers-text',
  615. '[innerHTML]': 'renderedHTML()',
  616. },
  617. changeDetection: ChangeDetectionStrategy.OnPush,
  618. }]
  619. }], ctorParameters: () => [] });
  620. class FontAwesomeModule {
  621. static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FontAwesomeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
  622. static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.0.0", ngImport: i0, type: FontAwesomeModule, imports: [FaIconComponent,
  623. FaDuotoneIconComponent,
  624. FaLayersComponent,
  625. FaLayersTextComponent,
  626. FaLayersCounterComponent,
  627. FaStackComponent,
  628. FaStackItemSizeDirective], exports: [FaIconComponent,
  629. FaDuotoneIconComponent,
  630. FaLayersComponent,
  631. FaLayersTextComponent,
  632. FaLayersCounterComponent,
  633. FaStackComponent,
  634. FaStackItemSizeDirective] });
  635. static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FontAwesomeModule });
  636. }
  637. i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.0", ngImport: i0, type: FontAwesomeModule, decorators: [{
  638. type: NgModule,
  639. args: [{
  640. imports: [
  641. FaIconComponent,
  642. FaDuotoneIconComponent,
  643. FaLayersComponent,
  644. FaLayersTextComponent,
  645. FaLayersCounterComponent,
  646. FaStackComponent,
  647. FaStackItemSizeDirective,
  648. ],
  649. exports: [
  650. FaIconComponent,
  651. FaDuotoneIconComponent,
  652. FaLayersComponent,
  653. FaLayersTextComponent,
  654. FaLayersCounterComponent,
  655. FaStackComponent,
  656. FaStackItemSizeDirective,
  657. ],
  658. }]
  659. }] });
  660. /**
  661. * Generated bundle index. Do not edit.
  662. */
  663. export { FaConfig, FaDuotoneIconComponent, FaIconComponent, FaIconLibrary, FaLayersComponent, FaLayersCounterComponent, FaLayersTextComponent, FaStackComponent, FaStackItemSizeDirective, FontAwesomeModule };
  664. //# sourceMappingURL=angular-fontawesome.mjs.map