Angular
Angular
This guide will help you set up and integrate Cosmos web components into your Angular application using the @cosmos/web-angular package.
Supported Versions
We aim to align with the Angular team's actively supported versions. For @cosmos/web-angular:
- Angular: v18, v19, v20
- TypeScript: 5.8+
⚠️ Angular Support for versions 15 and below has been dropped with Cosmos version 8.3.0.
⚠️ Angular Support for version 16 has been dropped with Cosmos version 9.3.0.
⚠️ Angular Support for version 17 has been dropped with Cosmos version 9.12.0.
Prerequisites: Install Cosmos
Before integrating Cosmos components into your Angular application, you must complete the general Cosmos installation process. This includes:
- Configuring access to Red Bull's private npm registry via an .npmrc or .yarnrc.yml file.
- Installing the core @cosmos/web-angular package.
- Setting up the required custom fonts.
➡️ Please follow the complete instructions on our dedicated Installation Guide.
Once you have successfully installed @cosmos/web-angular and configured the fonts by following the installation guide, you can proceed with the steps below.
Angular Integration with @cosmos/web-angular
The @cosmos/web-angular package is the recommended way to use Cosmos web components in Angular applications. It provides Angular-specific wrappers that enhance integration and provide a better developer experience. (For historical context on package evolution, see the deprecation roadmap).
⚠️ Note on Deprecated Package
With release v9.7.0, the Angular wrapper is provided as the standalone package @cosmos/web-angular. For projects upgrading from a previous version that might have used direct imports from the core @cosmos/web package for Angular integration, dependencies and imports should be updated to use @cosmos/web-angular.
"dependencies": {
// "@cosmos/web": "9.6.0",
"@cosmos/web-angular": "9.7.0"
}The benefits of using these Stencil's component wrappers include:
- Angular component wrappers will be detached from change detection, preventing unnecessary repaints of your web component.
- Web component events will1 be converted to RxJS observables to align with Angular's @Output()and will not emit across component boundaries.
- The input web components can be used as control value accessors with Angular's reactive forms or [ngModel].
Usage with Standalone Components (Recommended for Angular 17+)
Angular 17+ defaults to a standalone component architecture. Import Cosmos components from @cosmos/web-angular and necessary Angular modules directly into your standalone components.
import { Component } from '@angular/core';
import { CosmosButton, CosmosInput } from '@cosmos/web-angular'; // Import from @cosmos/web-angular
@Component({
selector: 'app-root',
standalone: true,
templateUrl: './app.component.html',
imports: [
CosmosButton, // Importing individual Cosmos component
CosmosInput // Importing another Cosmos component
],
})
export class AppComponent {
name = 'Max';
}<cosmos-button>Button</cosmos-button>
<cosmos-input [label]="'Your Name'" [(value)]="name"></cosmos-input>NgModel / Reactive Forms with Standalone Components
Our input components from @cosmos/web-angular can be used with the ngModel directive or within reactive forms.
☝️ Watch out
- For [(ngModel)], ensure FormsModule is imported into your standalone component.
- For reactive forms, ensure ReactiveFormsModule is imported into your standalone component.
To use standalone Cosmos form fields (from @cosmos/web-angular) in dynamic forms or with ngModel, their corresponding value-accessor directives must also be imported from @cosmos/web-angular.
Value-Accessor Directives (exported from @cosmos/web-angular):
Component | Value-Accessor Directive |
|---|---|
CosmosInput | CosmosInputValueAccessor |
CosmosTextarea | CosmosTextareaValueAccessor |
CosmosCheckbox | CosmosCheckboxValueAccessor |
CosmosRadio | CosmosRadioValueAccessor |
CosmosSelect | CosmosSelectValueAccessor |
NgModel Example (Standalone)
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CosmosInput, CosmosInputValueAccessor } from '@cosmos/web-angular'; // Import from @cosmos/web-angular
@Component({
selector: 'app-root',
standalone: true,
imports: [
FormsModule,
CosmosInput,
CosmosInputValueAccessor // Value accessor for CosmosInput
],
templateUrl: './app.component.html',
})
export class AppComponent {
name = 'Max';
}<h1>Hello {{ name }}!</h1>
<cosmos-input label="Your name" [(ngModel)]="name"></cosmos-input>Reactive Forms Example (Standalone)
import { Component } from '@angular/core';
import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import {
CosmosButton,
CosmosInput,
CosmosInputValueAccessor
} from '@cosmos/web-angular'; // Import from @cosmos/web-angular
@Component({
selector: 'app-root',
standalone: true,
imports: [
CommonModule,
ReactiveFormsModule,
CosmosInput,
CosmosInputValueAccessor, // Value accessor for CosmosInput
CosmosButton
],
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
myForm;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
name: ['', Validators.required],
});
}
onSubmit() {
if (this.myForm.valid) {
alert(JSON.stringify(this.myForm.value));
}
}
}<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<p>Form Value: {{ myForm.value | json }}</p>
<p>Form Status: {{ myForm.status }}</p>
<cosmos-input
label="Name"
formControlName="name"
[invalid]="myForm.get('name')?.invalid && myForm.get('name')?.touched"
>
</cosmos-input>
<cosmos-button
type="submit"
[disabled]="!myForm.valid"
>
Submit
</cosmos-button>
</form>Usage with NgModules (Legacy / Non-Standalone Projects)
For projects still based on NgModules, @cosmos/web-angular offers ways to integrate Cosmos components. You can either import the entire CosmosModule or import individual components directly into your NgModule.
Option 1: Importing CosmosModule
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms'; // Example for Reactive Forms
import { AppComponent } from './app.component';
import { CosmosModule } from '@cosmos/web-angular'; // Import the main CosmosModule
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ReactiveFormsModule,
CosmosModule // Add CosmosModule here
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}Option 2: Importing Individual Components (into an NgModule)
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import {
CosmosButton,
CosmosInput,
CosmosInputValueAccessor
} from '@cosmos/web-angular'; // Import from @cosmos/web-angular
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ReactiveFormsModule,
CosmosInput, // Import individual Cosmos component
CosmosInputValueAccessor, // Value accessor for CosmosInput
CosmosButton // Import individual Cosmos component
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}The component (app.component.ts) and template (app.component.html) for NgModule-based apps would be similar to the standalone examples, but the component itself would not have the standalone: true flag or an imports array in its decorator.