1
- import { Component , computed , input } from '@angular/core' ;
1
+ import { CdkCopyToClipboard } from '@angular/cdk/clipboard' ;
2
+ import { Component , computed , input , signal } from '@angular/core' ;
2
3
import { TranslocoDirective } from '@jsverse/transloco' ;
3
4
import { FastSvgComponent } from '@push-based/ngx-fast-svg' ;
4
5
5
- import { IconComponent , IconType } from '@angular-love/blog/shared/ui-icon' ;
6
+ import { IconType } from '@angular-love/blog/shared/ui-icon' ;
6
7
7
8
type ShareItem = {
8
9
href : string ;
@@ -13,16 +14,16 @@ type ShareItem = {
13
14
@Component ( {
14
15
standalone : true ,
15
16
selector : 'al-article-share-icons' ,
16
- imports : [ IconComponent , TranslocoDirective , FastSvgComponent ] ,
17
+ imports : [ TranslocoDirective , FastSvgComponent , CdkCopyToClipboard ] ,
18
+ styleUrls : [ './article-share-icons.component.scss' ] ,
17
19
template : `
18
- <div class="flex items-center gap-4">
19
- <span *transloco="let t" class="text-lg font-bold">
20
+ <div *transloco="let t" class="flex items-center gap-4">
21
+ <span class="text-lg font-bold">
20
22
{{ t('articleShareIcons.title') }}
21
23
</span>
22
24
23
25
@for (item of items(); track $index) {
24
26
<a
25
- *transloco="let t"
26
27
role="button"
27
28
[attr.aria-label]="t(item.ariaLabel)"
28
29
[href]="item.href"
@@ -31,19 +32,46 @@ type ShareItem = {
31
32
<fast-svg class="text-al-foreground" [name]="item.icon" size="28" />
32
33
</a>
33
34
}
35
+ <a
36
+ role="button"
37
+ [attr.aria-label]="t('articleShareIcons.urlAriaLabel')"
38
+ [class.url-icon-animated]="animating()"
39
+ [cdkCopyToClipboard]="articleUrl()"
40
+ (click)="animating.set(true)"
41
+ (animationend)="animating.set(false)"
42
+ target="_blank"
43
+ >
44
+ <fast-svg
45
+ name="link"
46
+ class="text-al-foreground"
47
+ [class.!hidden]="animating()"
48
+ size="28"
49
+ />
50
+ <fast-svg
51
+ name="circle-check"
52
+ class="text-al-foreground"
53
+ [class.!hidden]="!animating()"
54
+ size="28"
55
+ />
56
+ </a>
34
57
</div>
35
58
` ,
36
59
} )
37
60
export class ArticleShareIconsComponent {
38
- slug = input . required < string > ( ) ;
39
- title = input . required < string > ( ) ;
40
- language = input . required < string > ( ) ;
61
+ readonly slug = input . required < string > ( ) ;
62
+ readonly title = input . required < string > ( ) ;
63
+ readonly language = input . required < string > ( ) ;
64
+
65
+ readonly animating = signal ( false ) ;
66
+
67
+ readonly articleUrl = computed ( ( ) =>
68
+ this . language ( ) === 'pl_PL'
69
+ ? `https://angular.love/${ this . slug ( ) } `
70
+ : `https://angular.love/en/${ this . slug ( ) } ` ,
71
+ ) ;
41
72
42
73
readonly items = computed < ShareItem [ ] > ( ( ) => {
43
- const url =
44
- this . language ( ) === 'pl_PL'
45
- ? `https://angular.love/${ this . slug ( ) } `
46
- : `https://angular.love/en/${ this . slug ( ) } ` ;
74
+ const url = this . articleUrl ( ) ;
47
75
const text = encodeURIComponent ( this . title ( ) ) ;
48
76
49
77
return [
0 commit comments