Skip to content

Commit e405e22

Browse files
feat(angular-3d): implement canvas and render loop core infrastructure
- Add Scene3dComponent with WebGLRenderer, Scene, PerspectiveCamera - Add SceneService for DI-based scene access by child components - Add RenderLoopService with callback registration and FPS tracking - Add AnimationService with GSAP integration for float, rotate, flight animations - Add WebGL mocking for Jest test environment - Update eslint config to exclude test files from strict linting - Add Angular best practices documentation
1 parent e41fb55 commit e405e22

File tree

17 files changed

+2394
-17
lines changed

17 files changed

+2394
-17
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
---
2+
trigger: always_on
3+
---
4+
5+
# Angular & TypeScript Best Practices Guide
6+
7+
> Retrieved from Angular CLI MCP Server for Angular v20+
8+
9+
You are an expert in TypeScript, Angular, and scalable web application development. You write functional, maintainable, performant, and accessible code following Angular and TypeScript best practices.
10+
11+
---
12+
13+
## TypeScript Best Practices
14+
15+
### Type Safety
16+
17+
- Use strict type checking (`strict: true` in tsconfig)
18+
- Prefer type inference when the type is obvious
19+
- Avoid the `any` type; use `unknown` when type is uncertain
20+
- Use explicit return types for public methods
21+
- Prefer `readonly` for properties that shouldn't change
22+
23+
### Naming Conventions
24+
25+
- Use PascalCase for classes, interfaces, types, enums
26+
- Use camelCase for variables, functions, methods
27+
- Use UPPER_SNAKE_CASE for constants
28+
- Prefix interfaces with `I` only when necessary to avoid ambiguity
29+
- Use descriptive names that convey purpose
30+
31+
### Code Organization
32+
33+
- One class/interface per file
34+
- Group related files in feature folders
35+
- Use barrel exports (`index.ts`) for clean imports
36+
- Keep functions small and focused (single responsibility)
37+
38+
### Modern TypeScript Features
39+
40+
```typescript
41+
// Use nullish coalescing
42+
const value = data ?? defaultValue;
43+
44+
// Use optional chaining
45+
const name = user?.profile?.name;
46+
47+
// Use satisfies for type-safe object literals
48+
const config = {
49+
port: 3000,
50+
host: 'localhost',
51+
} satisfies ServerConfig;
52+
53+
// Use const assertions for literal types
54+
const actions = ['add', 'remove', 'update'] as const;
55+
```
56+
57+
### Explicit Member Accessibility
58+
59+
Always use explicit accessibility modifiers:
60+
61+
```typescript
62+
export class MyService {
63+
private readonly _state = signal<State>(initialState);
64+
public readonly state = this._state.asReadonly();
65+
66+
public constructor() {}
67+
68+
public doSomething(): void {}
69+
70+
private helperMethod(): void {}
71+
}
72+
```
73+
74+
---
75+
76+
## Angular Best Practices
77+
78+
### Component Architecture
79+
80+
- Always use standalone components (default in Angular v20+)
81+
- Must NOT set `standalone: true` inside Angular decorators - it's the default
82+
- Set `changeDetection: ChangeDetectionStrategy.OnPush` always
83+
- Keep components small and focused on a single responsibility
84+
- Prefer inline templates for small components
85+
86+
### Signals & Reactivity
87+
88+
- Use `input()` and `output()` functions instead of decorators
89+
- Use `viewChild()` and `contentChild()` signal functions
90+
- Use `computed()` for derived state
91+
- Use signals for local component state
92+
- Keep state transformations pure and predictable
93+
- Do NOT use `mutate` on signals, use `update` or `set` instead
94+
95+
```typescript
96+
// Modern Angular 20+ patterns
97+
export class MyComponent {
98+
// Signal-based inputs
99+
public readonly name = input.required<string>();
100+
public readonly count = input<number>(0);
101+
102+
// Signal-based outputs
103+
public readonly clicked = output<void>();
104+
105+
// Signal-based view queries
106+
private readonly buttonRef = viewChild<ElementRef>('button');
107+
108+
// Computed derived state
109+
public readonly displayName = computed(() => `Hello, ${this.name()}`);
110+
}
111+
```
112+
113+
### Host Bindings
114+
115+
- Do NOT use `@HostBinding` and `@HostListener` decorators
116+
- Put host bindings inside the `host` object of the decorator:
117+
118+
```typescript
119+
@Component({
120+
selector: 'app-button',
121+
host: {
122+
'[class.active]': 'isActive()',
123+
'(click)': 'onClick($event)',
124+
},
125+
})
126+
export class ButtonComponent {}
127+
```
128+
129+
### Templates
130+
131+
- Keep templates simple and avoid complex logic
132+
- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch`
133+
- Use the async pipe to handle observables
134+
- Do NOT use `ngClass`, use `class` bindings instead
135+
- Do NOT use `ngStyle`, use `style` bindings instead
136+
- Do not write arrow functions in templates (not supported)
137+
138+
```html
139+
<!-- Modern Angular control flow -->
140+
@if (isLoading()) {
141+
<app-spinner />
142+
} @else { @for (item of items(); track item.id) {
143+
<app-item [data]="item" />
144+
} }
145+
```
146+
147+
### Services
148+
149+
- Design services around a single responsibility
150+
- Use `providedIn: 'root'` for singleton services
151+
- Use `inject()` function instead of constructor injection
152+
- Component-scoped services should use `providers: []` array
153+
154+
```typescript
155+
@Injectable({ providedIn: 'root' })
156+
export class DataService {
157+
private readonly http = inject(HttpClient);
158+
159+
public getData(): Observable<Data[]> {
160+
return this.http.get<Data[]>('/api/data');
161+
}
162+
}
163+
```
164+
165+
### Forms
166+
167+
- Prefer Reactive forms over Template-driven forms
168+
- Use typed form controls (`FormControl<string>`)
169+
- Validate on blur or submit, not on every keystroke
170+
171+
### Images
172+
173+
- Use `NgOptimizedImage` for all static images
174+
- Note: `NgOptimizedImage` does not work for inline base64 images
175+
176+
---
177+
178+
## Accessibility Requirements
179+
180+
- It MUST pass all AXE checks
181+
- It MUST follow all WCAG AA minimums:
182+
- Focus management
183+
- Color contrast (4.5:1 for normal text, 3:1 for large text)
184+
- ARIA attributes
185+
- Keyboard navigation
186+
- Use semantic HTML elements
187+
- Provide alt text for images
188+
- Ensure interactive elements are focusable
189+
190+
---
191+
192+
## Performance
193+
194+
- Implement lazy loading for feature routes
195+
- Use `OnPush` change detection
196+
- Track items in `@for` loops with `track`
197+
- Avoid function calls in templates (use computed signals)
198+
- Use `NgOptimizedImage` for optimized image loading
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
# Angular & TypeScript Best Practices Guide
2+
3+
> Retrieved from Angular CLI MCP Server for Angular v20+
4+
5+
You are an expert in TypeScript, Angular, and scalable web application development. You write functional, maintainable, performant, and accessible code following Angular and TypeScript best practices.
6+
7+
---
8+
9+
## TypeScript Best Practices
10+
11+
### Type Safety
12+
13+
- Use strict type checking (`strict: true` in tsconfig)
14+
- Prefer type inference when the type is obvious
15+
- Avoid the `any` type; use `unknown` when type is uncertain
16+
- Use explicit return types for public methods
17+
- Prefer `readonly` for properties that shouldn't change
18+
19+
### Naming Conventions
20+
21+
- Use PascalCase for classes, interfaces, types, enums
22+
- Use camelCase for variables, functions, methods
23+
- Use UPPER_SNAKE_CASE for constants
24+
- Prefix interfaces with `I` only when necessary to avoid ambiguity
25+
- Use descriptive names that convey purpose
26+
27+
### Code Organization
28+
29+
- One class/interface per file
30+
- Group related files in feature folders
31+
- Use barrel exports (`index.ts`) for clean imports
32+
- Keep functions small and focused (single responsibility)
33+
34+
### Modern TypeScript Features
35+
36+
```typescript
37+
// Use nullish coalescing
38+
const value = data ?? defaultValue;
39+
40+
// Use optional chaining
41+
const name = user?.profile?.name;
42+
43+
// Use satisfies for type-safe object literals
44+
const config = {
45+
port: 3000,
46+
host: 'localhost',
47+
} satisfies ServerConfig;
48+
49+
// Use const assertions for literal types
50+
const actions = ['add', 'remove', 'update'] as const;
51+
```
52+
53+
### Explicit Member Accessibility
54+
55+
Always use explicit accessibility modifiers:
56+
57+
```typescript
58+
export class MyService {
59+
private readonly _state = signal<State>(initialState);
60+
public readonly state = this._state.asReadonly();
61+
62+
public constructor() {}
63+
64+
public doSomething(): void {}
65+
66+
private helperMethod(): void {}
67+
}
68+
```
69+
70+
---
71+
72+
## Angular Best Practices
73+
74+
### Component Architecture
75+
76+
- Always use standalone components (default in Angular v20+)
77+
- Must NOT set `standalone: true` inside Angular decorators - it's the default
78+
- Set `changeDetection: ChangeDetectionStrategy.OnPush` always
79+
- Keep components small and focused on a single responsibility
80+
- Prefer inline templates for small components
81+
82+
### Signals & Reactivity
83+
84+
- Use `input()` and `output()` functions instead of decorators
85+
- Use `viewChild()` and `contentChild()` signal functions
86+
- Use `computed()` for derived state
87+
- Use signals for local component state
88+
- Keep state transformations pure and predictable
89+
- Do NOT use `mutate` on signals, use `update` or `set` instead
90+
91+
```typescript
92+
// Modern Angular 20+ patterns
93+
export class MyComponent {
94+
// Signal-based inputs
95+
public readonly name = input.required<string>();
96+
public readonly count = input<number>(0);
97+
98+
// Signal-based outputs
99+
public readonly clicked = output<void>();
100+
101+
// Signal-based view queries
102+
private readonly buttonRef = viewChild<ElementRef>('button');
103+
104+
// Computed derived state
105+
public readonly displayName = computed(() => `Hello, ${this.name()}`);
106+
}
107+
```
108+
109+
### Host Bindings
110+
111+
- Do NOT use `@HostBinding` and `@HostListener` decorators
112+
- Put host bindings inside the `host` object of the decorator:
113+
114+
```typescript
115+
@Component({
116+
selector: 'app-button',
117+
host: {
118+
'[class.active]': 'isActive()',
119+
'(click)': 'onClick($event)',
120+
},
121+
})
122+
export class ButtonComponent {}
123+
```
124+
125+
### Templates
126+
127+
- Keep templates simple and avoid complex logic
128+
- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch`
129+
- Use the async pipe to handle observables
130+
- Do NOT use `ngClass`, use `class` bindings instead
131+
- Do NOT use `ngStyle`, use `style` bindings instead
132+
- Do not write arrow functions in templates (not supported)
133+
134+
```html
135+
<!-- Modern Angular control flow -->
136+
@if (isLoading()) {
137+
<app-spinner />
138+
} @else { @for (item of items(); track item.id) {
139+
<app-item [data]="item" />
140+
} }
141+
```
142+
143+
### Services
144+
145+
- Design services around a single responsibility
146+
- Use `providedIn: 'root'` for singleton services
147+
- Use `inject()` function instead of constructor injection
148+
- Component-scoped services should use `providers: []` array
149+
150+
```typescript
151+
@Injectable({ providedIn: 'root' })
152+
export class DataService {
153+
private readonly http = inject(HttpClient);
154+
155+
public getData(): Observable<Data[]> {
156+
return this.http.get<Data[]>('/api/data');
157+
}
158+
}
159+
```
160+
161+
### Forms
162+
163+
- Prefer Reactive forms over Template-driven forms
164+
- Use typed form controls (`FormControl<string>`)
165+
- Validate on blur or submit, not on every keystroke
166+
167+
### Images
168+
169+
- Use `NgOptimizedImage` for all static images
170+
- Note: `NgOptimizedImage` does not work for inline base64 images
171+
172+
---
173+
174+
## Accessibility Requirements
175+
176+
- It MUST pass all AXE checks
177+
- It MUST follow all WCAG AA minimums:
178+
- Focus management
179+
- Color contrast (4.5:1 for normal text, 3:1 for large text)
180+
- ARIA attributes
181+
- Keyboard navigation
182+
- Use semantic HTML elements
183+
- Provide alt text for images
184+
- Ensure interactive elements are focusable
185+
186+
---
187+
188+
## Performance
189+
190+
- Implement lazy loading for feature routes
191+
- Use `OnPush` change detection
192+
- Track items in `@for` loops with `track`
193+
- Avoid function calls in templates (use computed signals)
194+
- Use `NgOptimizedImage` for optimized image loading

0 commit comments

Comments
 (0)