component
Generate an Angular component with signals, OnPush, and host-based styling following Momentum CMS conventions. Use when creating new UI components in any library.
Best use case
component is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Generate an Angular component with signals, OnPush, and host-based styling following Momentum CMS conventions. Use when creating new UI components in any library.
Teams using component should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/component/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How component Compares
| Feature / Agent | component | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Generate an Angular component with signals, OnPush, and host-based styling following Momentum CMS conventions. Use when creating new UI components in any library.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Generate Angular Component
Create an Angular component following Momentum CMS conventions.
## Arguments
- First argument: Library path (e.g., "admin", "ui", "admin/components")
- Second argument: Component name in kebab-case (e.g., "data-table", "field-renderer")
## File Naming Convention
Momentum CMS uses **short file names without the `.component` infix**. This is a deliberate project convention — do NOT follow the Angular CLI default of `.component.ts`.
| File | Name it | NOT |
| --------- | ---------------- | ------------------------------ |
| Component | `<name>.ts` | ~~`<name>.component.ts`~~ |
| Template | `<name>.html` | ~~`<name>.component.html`~~ |
| Tests | `<name>.spec.ts` | ~~`<name>.component.spec.ts`~~ |
For example, a component called `data-table` produces:
- `data-table.ts`
- `data-table.html` (only if template is complex)
- `data-table.spec.ts`
## Steps
1. Create component files in `libs/<library>/src/lib/<component>/`:
- `<component>.ts` — the component class (NOT `<component>.component.ts`)
- `<component>.html` — template, only if complex (NOT `<component>.component.html`)
- `<component>.spec.ts` — tests (NOT `<component>.component.spec.ts`)
2. Use this template for the component:
```typescript
import { ChangeDetectionStrategy, Component, computed, input, output, signal, inject } from '@angular/core';
@Component({
selector: 'mcms-<component-name>',
host: { class: 'block' },
template: `
<!-- Template here -->
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class <PascalName>Component {
// Signal inputs (use proper types, never `any`)
readonly data = input.required<DataType>();
// Optional inputs with defaults
readonly disabled = input(false);
// Signal outputs
readonly valueChange = output<ValueType>();
// Internal state
private readonly _loading = signal(false);
// Computed values
readonly loading = this._loading.asReadonly();
readonly hasData = computed(() => !!this.data());
// Injected services
private readonly http = inject(HttpClient);
}
```
3. Export from library's `index.ts`:
```typescript
export { <PascalName>Component } from './lib/<component>/<component>';
```
Note: the import path ends with `/<component>` (the short filename), NOT `/<component>.component`.
## Key Conventions
- **NO `standalone: true`** — default in Angular 21, redundant (ESLint enforced)
- **NO `any` types** — use proper interfaces (ESLint enforced)
- **NO `CommonModule` import** — unnecessary in Angular 21
- **NO `.component.ts` suffix** — use plain `.ts` (project convention, see File Naming above)
- Always set `changeDetection: ChangeDetectionStrategy.OnPush` — never use Default
- Use `input()` and `input.required()` for inputs — never use `@Input()` decorator
- Use `output()` for outputs — never use `@Output()` decorator
- Use `signal()` for internal state, `computed()` for derived values
- Use `inject()` for dependency injection — never use constructor injection
- Use `@for`/`@if`/`@switch` control flow — never use `*ngFor`/`*ngIf`/`[ngSwitch]`
- Prefix selectors with `mcms-`
## UI Component Patterns
### No Wrapping Divs
Angular components create a host element. Style the host directly — do NOT add wrapper divs:
```typescript
@Component({
selector: 'mcms-button',
host: { class: 'inline-flex items-center gap-2' },
template: `<ng-content />`,
})
```
NOT:
```typescript
// BAD: unnecessary wrapper div
template: `<div class="inline-flex items-center gap-2"><ng-content /></div>`,
```
### Class Configuration
Accept a `class` input for Tailwind customization via `hostClasses()` computed:
```typescript
@Component({
selector: 'button[mcms-button]',
host: { '[class]': 'hostClasses()' },
template: `<ng-content />`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class McmsButtonComponent {
readonly variant = input<'primary' | 'secondary'>('primary');
readonly class = input('');
readonly hostClasses = computed(
() => `${baseClasses} ${variantClasses[this.variant()]} ${this.class()}`,
);
}
```
### Theme Service
Use `McmsThemeService` for dark mode support:
```typescript
import { McmsThemeService } from '@momentumcms/admin';
@Component({...})
export class MyComponent {
private readonly theme = inject(McmsThemeService);
toggleDarkMode(): void {
this.theme.toggleTheme();
}
readonly isDark = this.theme.isDark; // computed signal
readonly currentTheme = this.theme.theme; // 'light' | 'dark' | 'system'
}
```
### App Tailwind Setup
Apps using the admin library must:
1. **tailwind.config.js** — Use the admin preset and include library sources:
```javascript
const adminPreset = require('../../libs/admin/tailwind.preset');
module.exports = {
presets: [adminPreset],
content: [
join(__dirname, 'src/**/!(*.stories|*.spec).{ts,html}'),
join(__dirname, '../../libs/admin/src/**/*.{ts,html}'),
...createGlobPatternsForDependencies(__dirname),
],
};
```
2. **styles.css** — Include CSS variables inline (Angular's esbuild can't resolve library CSS imports):
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--mcms-background: 0 0% 100%;
--mcms-foreground: 222 47% 11%;
/* ... copy from libs/admin/src/styles/theme.css */
}
.dark {
/* dark mode variables */
}
}
```Related Skills
headless-ui
Use @momentumcms/headless inside generated Momentum apps. Use when building custom public UI, composing accessible primitives, configuring global styles for hdl-* elements, or adding app-level tests around headless interactions.
ui-audit
Comprehensive UI component audit for Momentum CMS. Use when asked to audit, review, check, or validate a UI component. Checks Storybook stories, interaction tests, variants, kitchen sink integration, admin dashboard usage, accessibility, and responsive design (mobile-first). AUTOMATICALLY FIXES issues found and verifies with visual inspection. Triggers include "audit button", "review the card component", "check accessibility of tabs", or "/ui-audit <component-name>".
test-all
Run the FULL Momentum CMS test suite — every single suite, no skips. Triggers on "test all", "test everything", "run all tests", "run the test all script", "test-all script", "run the full suite", "run every test", "test the whole thing", "make sure everything passes", "run test:all", or ANY variation asking to run all/every/full tests. Also triggers on typos like "test al", "tets all", "tes all". NEVER skip suites unless the user EXPLICITLY names suites to skip.
stroll-test
End-to-end CLI stroll test of npm-published Momentum CMS packages. Scaffolds a fresh project with create-momentum-app, adds all plugins, runs migrations, starts server, and verifies everything works. Triggers include "stroll test", "cli stroll", "test published packages", or "/stroll-test".
skill-improve
Self-improving skill loop. Analyzes eval failures, rewrites the skill, re-evaluates, and repeats until convergence. Run after /skill-eval produces baseline results.
skill-eval
Run structured evaluations comparing skill vs no-skill performance. Measures assertion pass rates, timing, and output quality to systematically improve skills.
prepare-release
Prepare a patch/minor/major version release for all Momentum CMS packages. Bumps versions, generates changelogs, verifies builds/tests, adds new packages to Nx release config, and commits. Triggers include "prepare release", "bump version", "release patch", or "/prepare-release".
momentum-api
Work with Momentum API for data operations in Angular components
migrations
Run migrations, generate schemas, and manage code generation for Momentum CMS. Use when working with database migrations, Drizzle schema generation, type generation, or Angular schematics.
mcp-setup
Set up the Momentum CMS MCP server plugin and generate Claude Code MCP config for AI tool integration. Use when connecting Claude Code (or any MCP client) to a Momentum CMS instance.
SYSTEM ROLE & BEHAVIORAL PROTOCOLS
**ROLE:** Senior Frontend Architect & Avant-Garde UI Designer.
headless-primitive
Author, extend, or repair primitives in libs/headless. Use when adding a new headless primitive, changing its accessibility contract, updating slots/state attrs, wiring overlay behavior, or expanding the example styling lab and tests.