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.