Directives are like secret ninja techniques - they extend the capabilities of elements.
1@Directive({
2 selector: '[appHighlight]',
3 standalone: true
4})
5export class HighlightDirective {
6 private el = inject(ElementRef);
7 private renderer = inject(Renderer2);
8
9 // Input with alias (directive name)
10 @Input() appHighlight = '#ffff00';
11 @Input() highlightOnFocus = false;
12
13 @HostListener('mouseenter')
14 onMouseEnter(): void {
15 this.setBackground(this.appHighlight);
16 }
17
18 @HostListener('mouseleave')
19 onMouseLeave(): void {
20 this.setBackground('');
21 }
22
23 @HostListener('focus')
24 onFocus(): void {
25 if (this.highlightOnFocus) {
26 this.setBackground(this.appHighlight);
27 }
28 }
29
30 private setBackground(color: string): void {
31 this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', color);
32 }
33}
34
35// Usage
36<p appHighlight>Yellow highlight</p>
37<p [appHighlight]="'#c41e3a'">Red highlight</p>
38<input [appHighlight]="'#90EE90'" [highlightOnFocus]="true">1@Directive({
2 selector: '[appRepeat]',
3 standalone: true
4})
5export class RepeatDirective {
6 private templateRef = inject(TemplateRef<any>);
7 private viewContainer = inject(ViewContainerRef);
8
9 @Input() set appRepeat(count: number) {
10 this.viewContainer.clear();
11
12 for (let i = 0; i < count; i++) {
13 this.viewContainer.createEmbeddedView(this.templateRef, {
14 $implicit: i, // Available as let-i
15 index: i,
16 first: i === 0,
17 last: i === count - 1
18 });
19 }
20 }
21}
22
23// Usage
24<div *appRepeat="5; let i; let isFirst = first">
25 Element {{ i }} {{ isFirst ? '(first)' : '' }}
26</div>1@Directive({
2 selector: '[appHasPermission]',
3 standalone: true
4})
5export class HasPermissionDirective {
6 private templateRef = inject(TemplateRef<any>);
7 private viewContainer = inject(ViewContainerRef);
8 private authService = inject(AuthService);
9
10 private hasView = false;
11
12 @Input() set appHasPermission(permission: string | string[]) {
13 const permissions = Array.isArray(permission) ? permission : [permission];
14 const hasPermission = this.authService.hasAnyPermission(permissions);
15
16 if (hasPermission && !this.hasView) {
17 this.viewContainer.createEmbeddedView(this.templateRef);
18 this.hasView = true;
19 } else if (!hasPermission && this.hasView) {
20 this.viewContainer.clear();
21 this.hasView = false;
22 }
23 }
24}
25
26// Usage
27<button *appHasPermission="'admin'">Admin Panel</button>
28<div *appHasPermission="['editor', 'admin']">Edit Content</div>