mcpField
A
angular-directives

angular-directives

github.com/oguzhan18Development7176 installsUpdated 31w ago
Repository

About angular-directives

An Angular 21 reference skill for developers creating and maintaining directives. It explains directive patterns, recent API changes, and practices for focused, reusable behavior.

Key features

  1. 01Attribute and structural directive patterns
  2. 02Directive composition with hostDirectives
  3. 03Signal inputs and standalone directives
  4. 04TemplateRef and ViewContainerRef usage
  5. 05Focused directives and descriptive selectors

Use cases

  1. 01Create reusable element behavior
  2. 02Build conditional embedded views
  3. 03Compose directives on a component
  4. 04Add reactive inputs to directives

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/oguzhan18/angular-ecosystem-skills --skill angular-directives

After installing, type/angular-directivesin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/discussions/
_INDEX.md
references/docs/
_INDEX.md
references/issues/
_INDEX.md
references/releases/
_INDEX.md

Details

From the project README

Angular Directives

Version: Angular 21 (2025) Tags: Directives, Components, DOM, Custom Directives

References: Directives Guide • Attribute Directives • Structural Directives

API Changes

This section documents recent version-specific API changes.

  • NEW: Directive composition API — Use hostDirectives to compose directives source

  • NEW: Signal inputs in directives — Use input() for reactive directive properties

  • NEW: Standalone directives — All directives can be standalone

  • NEW: Control flow syntax — @if, @for, @switch replace *ngIf, *ngFor

Best Practices

  • Create attribute directives for reusable behavior
import { Directive, ElementRef, Renderer2, Input } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  @Input() set appHighlight(color: string) {
    this.renderer.setStyle(this.el.nativeElement, 'background-color', color || 'yellow');
  }

  constructor(private el: ElementRef, private renderer: Renderer2) {}
}
  • Use @Input and @Output for directive communication
@Directive({
  selector: '[appClickTracker]'
})
export class ClickTrackerDirective {
  @Input() trackName = 'default';
  @Output() clicked = new EventEmitter<string>();

  @HostListener('click')
  onClick() {
    this.clicked.emit(this.trackName);
  }
}
  • Use TemplateRef for structural directives
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appUnless]'
})
export class UnlessDirective {
  @Input() set appUnless(condition: boolean) {
    if (!condition) {
      this.vcRef.createEmbeddedView(this.templateRef);
    } else {
      this.vcRef.clear();
    }
  }

  constructor(
    private templateRef: TemplateRef<any>,
    private vcRef: ViewContainerRef
  ) {}
}
  • Use ViewContainerRef for complex structural logic
@Directive({ selector: '[appDynamic]' })
export class DynamicDirective {
  constructor(
    private vcr: ViewContainerRef,
    private templateRef: TemplateRef<any>
  ) {
    this.vcr.createEmbeddedView(this.templateRef);
  }
}
  • Use hostDirectives for composition
@Component({
  selector: 'app-card',
  standalone: true,
  imports: [HighlightDirective],
  hostDirectives: [
    {
      directive: HighlightDirective,
      inputs: ['appHighlight: highlight']
    }
  ],
  template: `<ng-content></ng-content>`
})
export class CardComponent {}
  • Use standalone: true for modern directives
@Directive({
  selector: '[appStandalone]',
  standalone: true
})
export class StandaloneDirective {}
  • Use signals in directives
@Directive({
  selector: '[appSignal]'
})
export class SignalDirective {
  value = input<string>('');
  
  ngOnInit() {
    console.log(this.value());
  }
}
  • Use @HostBinding for property binding
@Directive({
  selector: '[appDisable]'
})
export class DisableDirective {
  @Input() set disabled(value: boolean) {
    this.hostBinding.nativeElement.disabled = value;
  }
  
  constructor(private hostBinding: ElementRef) {}
}
  • Keep directives focused — One responsibility
// ✅ Good - focused directive
@Directive({ selector: '[appTooltip]' })

// ❌ Bad - too many responsibilities
@Directive({ selector: '[appTooltip][appTooltipMaxWidth][appTooltipTheme]' })
  • Use descriptive selectors
// ✅ Good
@Directive({ selector: '[appUserCard]' })

// ❌ Bad
@Directive({ selector: '[appUc]' })

Comments

Markdown supported