> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/angular/angular/llms.txt
> Use this file to discover all available pages before exploring further.

# Components

> Understanding Angular components, the @Component decorator, and component lifecycle

Components are the fundamental UI building blocks of Angular applications. Each component consists of a TypeScript class decorated with `@Component`, an HTML template, and optional CSS styles.

## The @Component Decorator

The `@Component` decorator marks a class as an Angular component and provides configuration metadata:

```typescript theme={null}
import { Component } from '@angular/core';

@Component({
  selector: 'app-hero-detail',
  standalone: true,
  template: `
    <div class="hero-detail">
      <h2>{{ hero.name }}</h2>
      <p>ID: {{ hero.id }}</p>
    </div>
  `,
  styles: [`
    .hero-detail {
      padding: 1rem;
      border: 1px solid #ccc;
    }
  `]
})
export class HeroDetailComponent {
  hero = { id: 1, name: 'Windstorm' };
}
```

## Component Metadata

<Note>
  All components are standalone by default in modern Angular. Set `standalone: false` only if you need to use NgModules.
</Note>

### Essential Properties

```typescript theme={null}
@Component({
  // CSS selector that identifies this component in templates
  selector: 'app-user-profile',
  
  // Component is standalone (default: true)
  standalone: true,
  
  // Dependencies needed by this component's template
  imports: [CommonModule, FormsModule],
  
  // Inline template (use this OR templateUrl)
  template: `<div>{{ name }}</div>`,
  
  // External template file (use this OR template)
  templateUrl: './user-profile.component.html',
  
  // Inline styles
  styles: [`
    .profile { padding: 1rem; }
  `],
  
  // External stylesheet
  styleUrl: './user-profile.component.css',
  
  // Multiple external stylesheets
  styleUrls: [
    './user-profile.component.css',
    './user-profile.theme.css'
  ]
})
export class UserProfileComponent {
  name = 'John Doe';
}
```

## Component Lifecycle

Angular components have a well-defined lifecycle managed by Angular. Implement lifecycle hook interfaces to tap into key moments:

<Steps>
  <Step title="Constructor">
    Called when the component class is instantiated
  </Step>

  <Step title="ngOnInit">
    Called once after the first ngOnChanges
  </Step>

  <Step title="ngOnChanges">
    Called when input properties change
  </Step>

  <Step title="ngDoCheck">
    Called during every change detection run
  </Step>

  <Step title="ngAfterContentInit">
    Called after content projection is initialized
  </Step>

  <Step title="ngAfterContentChecked">
    Called after projected content is checked
  </Step>

  <Step title="ngAfterViewInit">
    Called after component's view is initialized
  </Step>

  <Step title="ngAfterViewChecked">
    Called after component's view is checked
  </Step>

  <Step title="ngOnDestroy">
    Called before the component is destroyed
  </Step>
</Steps>

### Lifecycle Example

```typescript theme={null}
import { Component, OnInit, OnDestroy, Input, OnChanges, SimpleChanges } from '@angular/core';

@Component({
  selector: 'lifecycle-demo',
  standalone: true,
  template: `
    <h3>{{ title }}</h3>
    <p>Count: {{ count }}</p>
  `
})
export class LifecycleDemoComponent implements OnInit, OnChanges, OnDestroy {
  @Input() title: string = '';
  count = 0;
  private intervalId: any;

  constructor() {
    console.log('Constructor called');
  }

  ngOnChanges(changes: SimpleChanges) {
    console.log('OnChanges called', changes);
    if (changes['title']) {
      console.log('Title changed:', changes['title'].currentValue);
    }
  }

  ngOnInit() {
    console.log('OnInit called');
    this.intervalId = setInterval(() => {
      this.count++;
    }, 1000);
  }

  ngOnDestroy() {
    console.log('OnDestroy called');
    if (this.intervalId) {
      clearInterval(this.intervalId);
    }
  }
}
```

<Warning>
  Always clean up resources like subscriptions, timers, and event listeners in `ngOnDestroy` to prevent memory leaks.
</Warning>

## Component Inputs and Outputs

### Input Properties

Receive data from parent components:

```typescript theme={null}
import { Component, Input } from '@angular/core';

@Component({
  selector: 'user-card',
  standalone: true,
  template: `
    <div class="card">
      <h3>{{ userName }}</h3>
      <p>{{ userEmail }}</p>
    </div>
  `
})
export class UserCardComponent {
  // Simple input
  @Input() userName: string = '';
  
  // Input with alias
  @Input({ alias: 'email' }) userEmail: string = '';
  
  // Required input
  @Input({ required: true }) userId!: number;
  
  // Input with transform function
  @Input({ transform: (value: string) => value.toUpperCase() })
  department: string = '';
}
```

Usage in parent template:

```html theme={null}
<user-card 
  [userName]="user.name" 
  [email]="user.email"
  [userId]="user.id"
  [department]="user.dept">
</user-card>
```

### Output Properties

Emit events to parent components:

```typescript theme={null}
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'counter-button',
  standalone: true,
  template: `
    <button (click)="handleClick()">{{ label }}</button>
  `
})
export class CounterButtonComponent {
  @Output() counterChange = new EventEmitter<number>();
  private count = 0;
  label = 'Click me';

  handleClick() {
    this.count++;
    this.counterChange.emit(this.count);
  }
}
```

Parent component usage:

```html theme={null}
<counter-button (counterChange)="onCounterChange($event)"></counter-button>
```

## View Encapsulation

Control how component styles are scoped:

```typescript theme={null}
import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'styled-component',
  standalone: true,
  template: `<div class="container">Content</div>`,
  styles: [`
    .container { color: blue; }
  `],
  // Options: Emulated (default), None, ShadowDom
  encapsulation: ViewEncapsulation.Emulated
})
export class StyledComponent { }
```

<CardGroup cols={3}>
  <Card title="Emulated" icon="shield">
    Scopes styles to component (default)
  </Card>

  <Card title="None" icon="globe">
    Styles apply globally
  </Card>

  <Card title="ShadowDom" icon="lock">
    Uses native Shadow DOM
  </Card>
</CardGroup>

## Change Detection Strategy

Optimize performance with `OnPush` change detection:

```typescript theme={null}
import { Component, ChangeDetectionStrategy, Input } from '@angular/core';

interface User {
  id: number;
  name: string;
}

@Component({
  selector: 'user-list',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div *ngFor="let user of users">
      {{ user.name }}
    </div>
  `
})
export class UserListComponent {
  @Input() users: User[] = [];
}
```

<Note>
  `OnPush` only checks the component when:

  * Input references change
  * Events are triggered from the component or its children
  * Observables emit new values with the async pipe
  * Manually triggered with `ChangeDetectorRef.markForCheck()`
</Note>

## Host Element Binding

Bind to the component's host element:

```typescript theme={null}
import { Component } from '@angular/core';

@Component({
  selector: 'highlighted-box',
  standalone: true,
  template: `<ng-content></ng-content>`,
  host: {
    'class': 'box highlighted',
    '[class.active]': 'isActive',
    '[attr.role]': '"region"',
    '(click)': 'handleClick()'
  }
})
export class HighlightedBoxComponent {
  isActive = true;

  handleClick() {
    this.isActive = !this.isActive;
  }
}
```

## Best Practices

1. **Keep components focused** - Single responsibility principle
2. **Use OnPush** when possible for better performance
3. **Implement lifecycle hooks** only when needed
4. **Clean up in ngOnDestroy** - Prevent memory leaks
5. **Use standalone components** for better tree-shaking
6. **Leverage signals** for reactive state management

## Next Steps

<CardGroup cols={2}>
  <Card title="Templates" href="/concepts/templates">
    Learn template syntax and bindings
  </Card>

  <Card title="Directives" href="/concepts/directives">
    Extend component behavior with directives
  </Card>
</CardGroup>
