
Angular Component
Apply modern Angular component patterns—model inputs, queries, DI, and dynamic components—while shipping UI in an Angular or Analog app.
Overview
Angular Component is an agent skill for the Build phase that encodes modern Angular component patterns for models, queries, communication, and dynamic mounting.
Install
npx skills add https://github.com/analogjs/angular-skills --skill angular-componentWhat is this skill?
- Model inputs for two-way binding with model() and [(value)] usage
- viewChild and viewChildren query patterns for template references and child components
- Content queries and component communication patterns between parents and children
- Dependency injection patterns inside standalone-style components
- Dynamic component loading guidance beyond static templates
- 6 documented pattern sections in the component guide
- Table of contents covers model inputs through dynamic components
Adoption & trust: 8.6k installs on skills.sh; 592 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are building Angular UI but keep mixing legacy @Input/@Output patterns with signals, model(), and query APIs incorrectly.
Who is it for?
Solo developers on Angular or Analog projects who want snippet-accurate component code during feature work.
Skip if: React or Vue codebases, greenfield learners who need full course-style Angular onboarding, or backend-only API services with no UI.
When should I use this skill?
You are implementing or refactoring Angular components and need correct model(), query, DI, or dynamic component patterns.
What do I get? / Deliverables
Your agent generates components that follow current Angular component APIs with consistent two-way binding and query usage.
- Component TypeScript and template snippets using model inputs and queries
- Refactored parent-child communication and dynamic component hosts
Recommended Skills
Journey fit
How it compares
Use as a focused Angular component pattern reference, not as a full design system or Storybook generator skill.
Common Questions / FAQ
Who is angular-component for?
Indie builders and small teams shipping Angular frontends who want agents to follow signal-era component APIs instead of outdated decorator-only examples.
When should I use angular-component?
While building frontend features—sliders with two-way binding, galleries with viewChildren, content projection, or dynamic component hosts in your Angular app.
Is angular-component safe to install?
It is documentation-only pattern guidance; confirm compatibility with your Angular version and review the Security Audits panel on this Prism page before trusting any third-party skill source.
SKILL.md
READMESKILL.md - Angular Component
# Angular Component Patterns ## Table of Contents - [Model Inputs (Two-Way Binding)](#model-inputs-two-way-binding) - [View Queries](#view-queries) - [Content Queries](#content-queries) - [Dependency Injection in Components](#dependency-injection-in-components) - [Component Communication Patterns](#component-communication-patterns) - [Dynamic Components](#dynamic-components) ## Model Inputs (Two-Way Binding) For two-way binding with `[(value)]` syntax: ```typescript import { Component, model } from '@angular/core'; @Component({ selector: 'app-slider', host: { '(input)': 'onInput($event)', }, template: ` <input type="range" [value]="value()" [min]="min()" [max]="max()" /> <span>{{ value() }}</span> `, }) export class Slider { // Model creates both input and output value = model(0); min = input(0); max = input(100); onInput(event: Event) { const target = event.target as HTMLInputElement; this.value.set(Number(target.value)); } } // Usage: <app-slider [(value)]="sliderValue" /> ``` Required model: ```typescript value = model.required<number>(); ``` ## View Queries Query elements and components in the template: ```typescript import { Component, viewChild, viewChildren, ElementRef } from '@angular/core'; @Component({ selector: 'app-gallery', template: ` <div #container class="gallery"> @for (image of images(); track image.id) { <app-image-card [image]="image" /> } </div> `, }) export class Gallery { images = input.required<Image[]>(); // Query single element container = viewChild.required<ElementRef<HTMLDivElement>>('container'); // Query single component (optional) firstCard = viewChild(ImageCard); // Query all matching components allCards = viewChildren(ImageCard); } ``` ## Content Queries Query projected content: ```typescript import { Component, contentChild, contentChildren, effect, signal } from '@angular/core'; @Component({ selector: 'app-tabs', template: ` <div class="tab-headers"> @for (tab of tabs(); track tab.label()) { <button [class.active]="tab === activeTab()" (click)="selectTab(tab)" > {{ tab.label() }} </button> } </div> <div class="tab-content"> <ng-content /> </div> `, }) export class Tabs { // Query all projected Tab children tabs = contentChildren(Tab); // Query single projected element header = contentChild('tabHeader'); activeTab = signal<Tab | undefined>(undefined); constructor() { // Set first tab as active when tabs are available effect(() => { const firstTab = this.tabs()[0]; if (firstTab && !this.activeTab()) { this.activeTab.set(firstTab); } }); } selectTab(tab: Tab) { this.activeTab.set(tab); } } @Component({ selector: 'app-tab', template: `<ng-content />`, host: { '[class.active]': 'isActive()', '[style.display]': 'isActive() ? "block" : "none"', }, }) export class Tab { label = input.required<string>(); isActive = input(false); } ``` ## Dependency Injection in Components Use `inject()` function instead of constructor injection: ```typescript import { Component, inject } from '@angular/core'; import { Router } from '@angular/router'; @Component({ selector: 'app-dashboard', template: `...`, }) export class Dashboard { private router = inject(Router); private userService = inject(User); private config = inject(APP_CONFIG); // Optional injection private analytics = inject(Analytics, { optional: true }); // Self-only injection private localService = inject(Local, { self: true }); navigateToProfile() { this.router.navigate(['/profile']); } } ``` ## Component Communication Patterns ### Parent to Child (Inputs) ```typescript // Parent @Component({ template: `<app-child [data]="parentData()" [config]="config" />`, }) export class Parent { parentD