Skip to content

Commit a63db92

Browse files
committed
Add support for all Font Awesome 6 animations
See https://fontawesome.com/docs/web/style/animate Fixes #393
1 parent c8ef757 commit a63db92

File tree

9 files changed

+131
-24
lines changed

9 files changed

+131
-24
lines changed

docs/usage/features.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ The following features are available as part of Font Awesome. Note that the synt
4141
[FontAwesome Spec](https://fontawesome.com/how-to-use/on-the-web/styling/animating-icons)
4242

4343
```html
44-
<fa-icon [icon]="['fas', 'spinner']" [spin]="true"></fa-icon>
45-
<fa-icon [icon]="['fas', 'spinner']" [pulse]="true"></fa-icon>
44+
<fa-icon [icon]="['fas', 'cog']" animation="spin"></fa-icon>
45+
<fa-icon [icon]="['fas', 'heart']" animation="beat"></fa-icon>
46+
<fa-icon [icon]="['fas', 'bell']" animation="shake"></fa-icon>
4647
```
4748

4849
### Border

projects/demo/e2e/src/app.e2e-spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe('Angular FontAwesome demo', () => {
77
});
88

99
it('should render all icons', async () => {
10-
expect(await appPage.icons.count()).toBe(28);
10+
expect(await appPage.icons.count()).toBe(43);
1111
});
1212

1313
afterEach(async () => {

projects/demo/src/app/app.component.html

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,60 @@ <h3>With Mask and Transform</h3>
3737
<h3>Change Size</h3>
3838
<fa-icon [icon]="faAdjust" size="2x"></fa-icon>
3939

40-
<h3>Animation</h3>
41-
<p>Click to toggle animation.</p>
42-
<fa-icon [icon]="faSync" [spin]="isSyncAnimated" (click)="isSyncAnimated = !isSyncAnimated"></fa-icon>
40+
<h3>Animations</h3>
41+
42+
<button type="button" (click)="isAnimated = !isAnimated">Toggle animations</button>
43+
44+
<p>
45+
<fa-icon [icon]="faHeart" [animation]="isAnimated ? 'beat' : undefined"></fa-icon>&nbsp;
46+
<fa-icon
47+
[icon]="faHeart"
48+
[animation]="isAnimated ? 'beat' : undefined"
49+
style="--fa-animation-duration: 0.5s"
50+
></fa-icon
51+
>&nbsp;
52+
<fa-icon [icon]="faHeart" [animation]="isAnimated ? 'beat' : undefined" style="--fa-beat-scale: 2"></fa-icon>
53+
</p>
54+
55+
<p>
56+
<fa-icon [icon]="faHeart" [animation]="isAnimated ? 'fade' : undefined"></fa-icon>&nbsp;
57+
<fa-icon [icon]="faHeart" [animation]="isAnimated ? 'fade' : undefined" style="--fa-fade-opacity: 0.1"></fa-icon
58+
>&nbsp;
59+
</p>
60+
61+
<p>
62+
<fa-icon [icon]="faHeart" [animation]="isAnimated ? 'beat-fade' : undefined"></fa-icon>&nbsp;
63+
<fa-icon
64+
[icon]="faHeart"
65+
[animation]="isAnimated ? 'beat-fade' : undefined"
66+
style="--fa-beat-fade-opacity: 0.1"
67+
></fa-icon
68+
>&nbsp;
69+
<fa-icon [icon]="faHeart" [animation]="isAnimated ? 'beat-fade' : undefined" style="--fa-beat-fade-scale: 2"></fa-icon
70+
>&nbsp;
71+
</p>
72+
73+
<p><fa-icon [icon]="faHeart" [animation]="isAnimated ? 'bounce' : undefined"></fa-icon>&nbsp;</p>
74+
75+
<p>
76+
<fa-icon [icon]="faHeart" [animation]="isAnimated ? 'flip' : undefined"></fa-icon>&nbsp;
77+
<fa-icon
78+
[icon]="faHeart"
79+
[animation]="isAnimated ? 'flip' : undefined"
80+
style="--fa-flip-x: 1; --fa-flip-y: 0"
81+
></fa-icon
82+
>&nbsp;
83+
</p>
84+
85+
<p><fa-icon [icon]="faHeart" [animation]="isAnimated ? 'shake' : undefined"></fa-icon>&nbsp;</p>
86+
87+
<p>
88+
<fa-icon [icon]="faCog" [animation]="isAnimated ? 'spin' : undefined"></fa-icon>&nbsp;
89+
<fa-icon [icon]="faCog" [animation]="isAnimated ? 'spin-reverse' : undefined"></fa-icon>&nbsp;
90+
<fa-icon [icon]="faSpinner" [animation]="isAnimated ? 'spin-pulse' : undefined"></fa-icon>&nbsp;
91+
<fa-icon [icon]="faSpinner" [animation]="isAnimated ? 'spin-pulse-reverse' : undefined"></fa-icon>&nbsp;
92+
</p>
93+
4394
<p>Slide to turn up the magic.</p>
4495
<fa-icon [icon]="faMagic" transform="rotate-{{ magicLevel }}"></fa-icon>
4596
<input type="range" [value]="magicLevel" (input)="magicLevel = $any($event.target).value" />

projects/demo/src/app/app.component.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ import {
1111
faEllipsisH,
1212
faFighterJet,
1313
faFlag as solidFlag,
14+
faHeart,
1415
faMagic,
16+
faSpinner,
1517
faSquare,
16-
faSync,
18+
faCog,
1719
faTimes,
1820
faUser,
1921
} from '@fortawesome/free-solid-svg-icons';
@@ -25,7 +27,7 @@ import {
2527
})
2628
export class AppComponent {
2729
faBell = faBell;
28-
faSync = faSync;
30+
faCog = faCog;
2931
faFlag = faFlag;
3032
solidFlag = solidFlag;
3133
faTimes = faTimes;
@@ -38,14 +40,16 @@ export class AppComponent {
3840
faEllipsisH = faEllipsisH;
3941
faFighterJet = faFighterJet;
4042
faBatteryQuarter = faBatteryQuarter;
43+
faHeart = faHeart;
44+
faSpinner = faSpinner;
4145
faDummy: IconDefinition = {
4246
prefix: 'fad',
4347
iconName: 'dummy' as IconName,
4448
icon: [512, 512, [], 'f030', ['M50 50 H412 V250 H50 Z', 'M50 262 H412 V462 H50 Z']],
4549
};
4650

4751
notificationsCounter = 1000;
48-
isSyncAnimated = true;
52+
isAnimated = true;
4953
magicLevel = 0;
5054

5155
selectedPosition: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';

src/lib/icon/icon.component.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { FaConfig } from '../config';
1818
import { FaIconLibrary } from '../icon-library';
1919
import { faWarnIfIconDefinitionMissing } from '../shared/errors/warn-if-icon-html-missing';
2020
import { faWarnIfIconSpecMissing } from '../shared/errors/warn-if-icon-spec-missing';
21-
import { FaProps } from '../shared/models/props.model';
21+
import { AnimationProp, FaProps } from '../shared/models/props.model';
2222
import { faClassList } from '../shared/utils/classlist.util';
2323
import { faNormalizeIconSpec } from '../shared/utils/normalize-icon-spec.util';
2424
import { FaStackItemSizeDirective } from '../stack/stack-item-size.directive';
@@ -42,8 +42,29 @@ export class FaIconComponent implements OnChanges {
4242
* screen readers.
4343
*/
4444
@Input() title?: string;
45-
@Input() spin?: boolean;
46-
@Input() pulse?: boolean;
45+
46+
/**
47+
* Icon animation.
48+
*
49+
* Most of the animations are only available when using Font Awesome 6. With
50+
* Font Awesome 5, only 'spin' and 'spin-pulse' are supported.
51+
*/
52+
@Input() animation?: AnimationProp;
53+
54+
/**
55+
* @deprecated Use animation="spin" instead. To be removed in 0.14.0.
56+
*/
57+
@Input() set spin(value: boolean) {
58+
this.animation = value ? 'spin' : undefined;
59+
}
60+
61+
/**
62+
* @deprecated Use animation="spin-pulse" instead. To be removed in 0.14.0.
63+
*/
64+
@Input() set pulse(value: boolean) {
65+
this.animation = value ? 'spin-pulse' : undefined;
66+
}
67+
4768
@Input() mask?: IconProp;
4869

4970
/**
@@ -144,8 +165,7 @@ export class FaIconComponent implements OnChanges {
144165
protected buildParams() {
145166
const classOpts: FaProps = {
146167
flip: this.flip,
147-
spin: this.spin,
148-
pulse: this.pulse,
168+
animation: this.animation,
149169
border: this.border,
150170
inverse: this.inverse,
151171
size: this.size || null,

src/lib/layers/layers-text.component.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
Transform,
1313
} from '@fortawesome/fontawesome-svg-core';
1414
import { faWarnIfParentNotExist } from '../shared/errors/warn-if-parent-not-exist';
15-
import { FaProps } from '../shared/models/props.model';
15+
import { AnimationProp, FaProps } from '../shared/models/props.model';
1616
import { faClassList } from '../shared/utils/classlist.util';
1717
import { FaLayersComponent } from './layers.component';
1818

@@ -46,8 +46,21 @@ export class FaLayersTextComponent implements OnChanges {
4646
* This input is deprecated since 0.12.0 and will be removed in 0.13.0.
4747
*/
4848
@Input() classes?: string[] = [];
49-
@Input() spin?: boolean;
50-
@Input() pulse?: boolean;
49+
50+
/**
51+
* @deprecated This input was incorrectly exposed and never worked correctly. To be removed in 0.14.0.
52+
*/
53+
@Input() set spin(value: boolean) {
54+
this.animation = value ? 'spin' : undefined;
55+
}
56+
57+
/**
58+
* @deprecated This input was incorrectly exposed and never worked correctly. To be removed in 0.14.0.
59+
*/
60+
@Input() set pulse(value: boolean) {
61+
this.animation = value ? 'spin-pulse' : undefined;
62+
}
63+
5164
@Input() flip?: FlipProp;
5265
@Input() size?: SizeProp;
5366
@Input() pull?: PullProp;
@@ -59,6 +72,8 @@ export class FaLayersTextComponent implements OnChanges {
5972

6073
@HostBinding('innerHTML') renderedHTML: SafeHtml;
6174

75+
private animation: AnimationProp;
76+
6277
constructor(@Optional() private parent: FaLayersComponent, private sanitizer: DomSanitizer) {
6378
faWarnIfParentNotExist(this.parent, 'FaLayersComponent', this.constructor.name);
6479
}
@@ -76,8 +91,7 @@ export class FaLayersTextComponent implements OnChanges {
7691
protected buildParams(): TextParams {
7792
const classOpts: FaProps = {
7893
flip: this.flip,
79-
spin: this.spin,
80-
pulse: this.pulse,
94+
animation: this.animation,
8195
border: this.border,
8296
inverse: this.inverse,
8397
size: this.size || null,

src/lib/public_api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export { FontAwesomeModule } from './fontawesome.module';
2-
export { FaProps } from './shared/models/props.model';
2+
export { AnimationProp, FaProps } from './shared/models/props.model';
33
export { FaIconComponent } from './icon/icon.component';
44
export { FaDuotoneIconComponent } from './icon/duotone-icon.component';
55
export { FaConfig } from './config';

src/lib/shared/models/props.model.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ import {
1515
export interface FaProps {
1616
mask?: IconProp;
1717
className?: string;
18-
spin?: boolean;
19-
pulse?: boolean;
18+
animation?: AnimationProp;
2019
border?: boolean;
2120
fixedWidth?: boolean;
2221
counter?: boolean;
@@ -30,3 +29,15 @@ export interface FaProps {
3029
style?: Styles;
3130
stackItemSize?: '1x' | '2x';
3231
}
32+
33+
export type AnimationProp =
34+
| 'beat'
35+
| 'fade'
36+
| 'beat-fade'
37+
| 'bounce'
38+
| 'flip'
39+
| 'shake'
40+
| 'spin'
41+
| 'spin-reverse'
42+
| 'spin-pulse'
43+
| 'spin-pulse-reverse';

src/lib/shared/utils/classlist.util.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ import { FaProps } from '../models/props.model';
66
*/
77
export const faClassList = (props: FaProps): string[] => {
88
const classes = {
9-
'fa-spin': props.spin,
10-
'fa-pulse': props.pulse,
9+
[`fa-${props.animation}`]: props.animation != null && !props.animation.startsWith('spin'),
10+
'fa-spin': props.animation === 'spin' || props.animation === 'spin-reverse',
11+
'fa-spin-pulse': props.animation === 'spin-pulse' || props.animation === 'spin-pulse-reverse',
12+
'fa-spin-reverse': props.animation === 'spin-reverse' || props.animation === 'spin-pulse-reverse',
13+
// According to https://fontawesome.com/docs/web/style/animate#spin fa-pulse
14+
// class is deprecated, remove the below line when Font Awesome 5 support
15+
// is dropped.
16+
'fa-pulse': props.animation === 'spin-pulse' || props.animation === 'spin-pulse-reverse',
1117
'fa-fw': props.fixedWidth,
1218
'fa-border': props.border,
1319
'fa-inverse': props.inverse,

0 commit comments

Comments
 (0)