create-claude-workspace 1.1.69 → 1.1.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -47,8 +47,14 @@ nx g @nx/js:library --directory=libs/[domain]/[layer] --no-interactive
|
|
|
47
47
|
|
|
48
48
|
**Creating components:**
|
|
49
49
|
```bash
|
|
50
|
+
# Each component MUST have its own subdirectory — [name] in --path is REQUIRED
|
|
50
51
|
nx g @nx/angular:component --path=libs/[domain]/[layer]/src/lib/[name] --no-interactive
|
|
52
|
+
|
|
53
|
+
# Example: badge component in shared/ui library
|
|
54
|
+
nx g @nx/angular:component --path=libs/shared/ui/src/lib/badge --no-interactive
|
|
55
|
+
# Result: libs/shared/ui/src/lib/badge/badge.ts, badge.html, badge.scss
|
|
51
56
|
```
|
|
57
|
+
**NEVER** omit the component name from `--path`. Without it, all component files land flat in `lib/` — no subdirectory separation.
|
|
52
58
|
|
|
53
59
|
**Bundler rule:** Omit `--bundler` for internal monorepo libs (no bundler needed). Only add `--bundler=esbuild|tsc|swc` for **publishable/buildable** libraries (npm packages, standalone deploys).
|
|
54
60
|
|
|
@@ -148,6 +154,53 @@ export class ProjectDetail {
|
|
|
148
154
|
- WebSocket/SSE streams — use dedicated services
|
|
149
155
|
- Non-HTTP async — use `resource()` instead
|
|
150
156
|
|
|
157
|
+
## Forms — Signal Forms API
|
|
158
|
+
|
|
159
|
+
Use the **signal-based forms API** (`@angular/forms/signals`) for all form handling when available in the project's Angular version (stable or experimental). NEVER use legacy `FormControl`/`FormGroup`/`FormBuilder`/`ReactiveFormsModule`.
|
|
160
|
+
|
|
161
|
+
**Signal forms pattern:**
|
|
162
|
+
```typescript
|
|
163
|
+
import { Component, signal } from '@angular/core';
|
|
164
|
+
import { form, FormField, required, email, minLength } from '@angular/forms/signals';
|
|
165
|
+
|
|
166
|
+
@Component({
|
|
167
|
+
imports: [FormField],
|
|
168
|
+
template: `
|
|
169
|
+
<input type="email" [formField]="loginForm.email" />
|
|
170
|
+
<input type="password" [formField]="loginForm.password" />
|
|
171
|
+
<button [disabled]="loginForm.invalid()">Submit</button>
|
|
172
|
+
`,
|
|
173
|
+
})
|
|
174
|
+
export class LoginForm {
|
|
175
|
+
readonly loginModel = signal({ email: '', password: '' });
|
|
176
|
+
readonly loginForm = form(this.loginModel, (schema) => {
|
|
177
|
+
required(schema.email);
|
|
178
|
+
email(schema.email);
|
|
179
|
+
required(schema.password);
|
|
180
|
+
minLength(schema.password, 8);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Field state is signal-based:
|
|
184
|
+
// this.loginForm.email().value() — current value (signal)
|
|
185
|
+
// this.loginForm.email().dirty() — boolean signal
|
|
186
|
+
// this.loginForm.email().invalid() — boolean signal
|
|
187
|
+
// this.loginForm.email().value.set('new@email.com') — update programmatically
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Key rules:**
|
|
192
|
+
- `form()` function with a signal model — form structure derived from model shape
|
|
193
|
+
- Validators from `@angular/forms/signals`: `required()`, `email()`, `minLength()`, `maxLength()`, `min()`, `max()`, `pattern()`
|
|
194
|
+
- Template binding via `[formField]` directive (import `FormField`)
|
|
195
|
+
- All field state (value, dirty, invalid, disabled) is signal-based — bind directly in templates
|
|
196
|
+
- No `.valueChanges` subscriptions — state is already reactive
|
|
197
|
+
|
|
198
|
+
**NEVER:**
|
|
199
|
+
- `new FormControl()` / `new FormGroup()` / `new FormArray()` / `FormBuilder` — use `form()` with signal model
|
|
200
|
+
- `ReactiveFormsModule` / `FormsModule` — use `FormField` directive from `@angular/forms/signals`
|
|
201
|
+
- `.valueChanges.subscribe()` — field state is already reactive via signals
|
|
202
|
+
- Wrapping validators in arrow functions (`control => Validators.required(control)`)
|
|
203
|
+
|
|
151
204
|
## Templates — MINIMAL Logic
|
|
152
205
|
|
|
153
206
|
- ZERO method calls in templates — wrap in `computed()`, bind the signal
|
|
@@ -343,6 +396,8 @@ describe('CardBadge', () => {
|
|
|
343
396
|
|
|
344
397
|
When reviewing Angular code, check:
|
|
345
398
|
- Signal usage: signal/computed/input/output/model correctly used
|
|
399
|
+
- Forms: signal forms API used (no legacy FormControl/FormGroup/FormBuilder)
|
|
400
|
+
- Component file organization: each component in its own subdirectory (not flat in lib/)
|
|
346
401
|
- ZERO method calls in templates — all derived state in computed()
|
|
347
402
|
- Feature vs dumb separation — no inject() in ui/ components
|
|
348
403
|
- Content projection (composite pattern) over deep @Input trees
|