Modern Angular (v17+) Integration

Modern Angular leverages Standalone Components, Signals, and direct DOM injection via createComponent and ViewContainerRef. This guide covers clean, zero-boilerplate integration with Strelit UI Kit.

1. Installation

Add Strelit UI Kit to your Angular project dependencies:

npm install strelit-ui-kit

2. Standalone Docking Host Component

Create an Angular component that initializes Strelit and mounts standalone Angular components dynamically into Strelit containers:

import {
  Component,
  ElementRef,
  viewChild,
  OnInit,
  OnDestroy,
  ApplicationRef,
  createComponent,
  EnvironmentInjector,
  Type
} from '@angular/core';
import { StrelitLayout, LayoutConfig } from 'strelit-ui-kit';
import { TelemetryPanelComponent } from './telemetry-panel.component';
import { LogStreamPanelComponent } from './log-stream-panel.component';

@Component({
  selector: 'app-docking-workspace',
  standalone: true,
  template: `<div #dockingContainer class="docking-viewport"></div>`,
  styles: [`
    .docking-viewport {
      width: 100vw;
      height: 100vh;
      overflow: hidden;
    }
  `]
})
export class DockingWorkspaceComponent implements OnInit, OnDestroy {
  private containerEl = viewChild.required<ElementRef<HTMLDivElement>>('dockingContainer');
  private layout?: StrelitLayout;

  private registry: Record<string, Type<any>> = {
    'telemetry': TelemetryPanelComponent,
    'logs': LogStreamPanelComponent
  };

  constructor(
    private appRef: ApplicationRef,
    private injector: EnvironmentInjector
  ) {}

  ngOnInit() {
    const config: LayoutConfig = {
      content: [{
        type: 'row',
        content: [
          {
            type: 'component',
            componentName: 'angularHost',
            title: 'Telemetry Inspector',
            componentState: { componentKey: 'telemetry' }
          },
          {
            type: 'component',
            componentName: 'angularHost',
            title: 'Event Log Stream',
            componentState: { componentKey: 'logs' }
          }
        ]
      }]
    };

    this.layout = new StrelitLayout(config, this.containerEl().nativeElement);

    // Register dynamic Angular Component factory
    this.layout.registerComponent('angularHost', (container, state) => {
      const targetEl = container.getElement()[0] || container.getElement();
      const ComponentClass = this.registry[state.componentKey];

      if (!ComponentClass) return;

      // Instantiate standalone component dynamically
      const compRef = createComponent(ComponentClass, {
        environmentInjector: this.injector,
        hostElement: targetEl
      });

      this.appRef.attachView(compRef.hostView);

      // Clean up Angular component lifecycle when pane is closed
      container.on('destroy', () => {
        this.appRef.detachView(compRef.hostView);
        compRef.destroy();
      });
    });

    this.layout.init();
  }

  ngOnDestroy() {
    this.layout?.destroy();
  }
}

3. Reactive State with Angular Signals

Inside your standalone panels, you can use Angular Signals freely. State changes will re-render within their docked panel instantly without triggering unnecessary global change-detection cycles:

import { Component, signal, computed } from '@angular/core';

@Component({
  selector: 'app-telemetry-panel',
  standalone: true,
  template: `
    <div class="telemetry-box">
      <h4>Throughput: {{ throughput() }} req/s</h4>
      <p>Status: {{ statusLabel() }}</p>
      <button (click)="increment()">Simulate Traffic Spike</button>
    </div>
  `
})
export class TelemetryPanelComponent {
  throughput = signal(1240);
  statusLabel = computed(() => this.throughput() > 2000 ? 'High Load 🔥' : 'Nominal 🟢');

  increment() {
    this.throughput.update(v => v + 250);
  }
}

Looking for legacy AngularJS 1.x tutorials?

For historical projects maintaining AngularJS 1.x codebases with $scope, see our Simple AngularJS and Complex AngularJS guides in the Archival section.