@julianoczkowski/create-trimble-app 2.0.0 → 2.0.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@julianoczkowski/create-trimble-app",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Interactive CLI to scaffold Modus 2.0 web component applications for React and Angular - templates bundled, works offline",
5
5
  "type": "module",
6
6
  "main": "src/cli.js",
@@ -0,0 +1,377 @@
1
+ # AGENTS.MD - Modus Angular Application
2
+
3
+ This file provides guidance to AI agents (GitHub Copilot, Claude, Cursor, etc.) when working with this codebase.
4
+
5
+ ## Agent Profile
6
+
7
+ **Name**: `modus-angular-agent`
8
+ **Role**: Angular 20 + Modus Web Components Specialist
9
+ **Description**: Expert in building Angular applications with Trimble Modus Design System, Tailwind CSS v4, and strict design system compliance.
10
+
11
+ ## Tech Stack
12
+
13
+ | Technology | Version | Package |
14
+ |------------|---------|---------|
15
+ | Angular | 20.3.0 | `@angular/core` |
16
+ | Modus Web Components | 1.0.6 | `@trimble-oss/moduswebcomponents` |
17
+ | Modus Angular Wrappers | 1.0.6-ng19 | `@trimble-oss/moduswebcomponents-angular` |
18
+ | Modus Icons | 1.18.0 | `@trimble-oss/modus-icons` |
19
+ | Tailwind CSS | 4.1.16 | `tailwindcss` |
20
+ | TypeScript | 5.9.2 | `typescript` |
21
+
22
+ ---
23
+
24
+ ## Commands (Run Frequently)
25
+
26
+ ### Lint Commands (Run Before Committing)
27
+
28
+ ```bash
29
+ npm run lint:all # Run ALL design system compliance checks
30
+ npm run type-check # TypeScript type validation
31
+ npm run lint:colors # Modus 9-color system compliance
32
+ npm run lint:styles # Inline styles validation
33
+ npm run lint:borders # Border pattern violations
34
+ npm run lint:opacity # Opacity utilities validation
35
+ npm run lint:icons # Modus Icons library validation
36
+ npm run lint:icon-names # Icon name validation (700+ icons)
37
+ ```
38
+
39
+ ### Development Commands
40
+
41
+ ```bash
42
+ npm start # Dev server on localhost:4200
43
+ npm run build # Production build
44
+ npm test # Run unit tests with Karma
45
+ ```
46
+
47
+ ### Pre-commit Hook
48
+
49
+ All lint commands run automatically on `git commit`. Fix all violations before committing.
50
+
51
+ ---
52
+
53
+ ## File Structure
54
+
55
+ | Directory | Purpose | Agent Action |
56
+ |-----------|---------|--------------|
57
+ | `src/app/pages/` | User application pages | WRITE - Build your app here |
58
+ | `src/app/components/` | Modus wrapper components | READ ONLY - Use as-is |
59
+ | `src/app/demos/` | Component demos | READ - Reference examples |
60
+ | `src/app/dev/` | Dev panel infrastructure | READ ONLY |
61
+ | `.cursor/rules/` | Detailed development rules | READ - Follow patterns |
62
+ | `scripts/` | Lint scripts | READ ONLY |
63
+ | `src/styles.css` | Design system definitions | READ - Color reference |
64
+
65
+ ---
66
+
67
+ ## Design System: 9 Colors Only
68
+
69
+ ### Base Colors (5)
70
+
71
+ | Color | Class | Usage |
72
+ |-------|-------|-------|
73
+ | Background | `bg-background` | Page background |
74
+ | Card | `bg-card` | Card surfaces |
75
+ | Muted | `bg-muted` | Muted backgrounds |
76
+ | Secondary | `bg-secondary` | Secondary surfaces |
77
+ | Foreground | `text-foreground` | Primary text |
78
+
79
+ ### Status Colors (4)
80
+
81
+ | Color | Class | Usage |
82
+ |-------|-------|-------|
83
+ | Primary | `bg-primary`, `text-primary` | Primary actions, info |
84
+ | Success | `bg-success`, `text-success` | Success states |
85
+ | Warning | `bg-warning`, `text-warning` | Warning states |
86
+ | Error | `bg-error`, `text-error` | Error states |
87
+
88
+ ### Code Examples
89
+
90
+ ```html
91
+ <!-- CORRECT: Design system colors -->
92
+ <div class="bg-background text-foreground p-4">
93
+ <div class="bg-card text-foreground border-default rounded-lg">
94
+ <div class="text-primary">Primary action</div>
95
+ <div class="text-muted-foreground">Muted text</div>
96
+ </div>
97
+ </div>
98
+
99
+ <!-- WRONG: Generic Tailwind colors - LINT WILL FAIL -->
100
+ <div class="bg-blue-500 text-white">
101
+ <div class="bg-gray-100 text-gray-600">
102
+ <div style="background-color: #ffffff">
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Critical Patterns & Bug Fixes
108
+
109
+ ### 1. Checkbox Value Inversion Bug
110
+
111
+ **Problem**: `modus-wc-checkbox` returns inverted values in `inputChange` event.
112
+
113
+ ```typescript
114
+ // CRITICAL: Always invert the value
115
+ handleChange(event: CustomEvent<InputEvent>): void {
116
+ const value = (event.target as HTMLModusWcCheckboxElement).value;
117
+ const actualChecked = !value; // INVERT: false means checked, true means unchecked
118
+ this.isChecked.set(actualChecked);
119
+ }
120
+ ```
121
+
122
+ ### 2. Modal Access Pattern
123
+
124
+ **Use `getElementById` with native HTMLDialogElement API:**
125
+
126
+ ```typescript
127
+ // CORRECT: Use getElementById with modalId
128
+ openModal(): void {
129
+ const dialog = document.getElementById('my-modal') as HTMLDialogElement | null;
130
+ if (dialog && typeof dialog.showModal === 'function') {
131
+ dialog.showModal();
132
+ }
133
+ }
134
+
135
+ closeModal(): void {
136
+ const dialog = document.getElementById('my-modal') as HTMLDialogElement | null;
137
+ if (dialog && typeof dialog.close === 'function') {
138
+ dialog.close();
139
+ }
140
+ }
141
+
142
+ // WRONG: Don't use querySelector or web component methods
143
+ const modal = document.querySelector('modus-wc-modal'); // WRONG
144
+ modal.open(); // WRONG - method doesn't exist
145
+ ```
146
+
147
+ ### 3. Signal Initialization
148
+
149
+ **Never use IIFE pattern with `signal()`:**
150
+
151
+ ```typescript
152
+ // WRONG: Causes TypeScript parsing errors
153
+ readonly minDate = signal<string>(() => {
154
+ return new Date().toISOString().split('T')[0];
155
+ }());
156
+
157
+ // CORRECT: Use helper method
158
+ private getTodayDate(): string {
159
+ return new Date().toISOString().split('T')[0];
160
+ }
161
+ readonly minDate = signal<string>(this.getTodayDate());
162
+
163
+ // CORRECT: Simple inline computation
164
+ readonly today = signal<string>(new Date().toISOString().split('T')[0]);
165
+ ```
166
+
167
+ ### 4. Opacity Utilities
168
+
169
+ **Tailwind `/80` syntax doesn't work with CSS variables:**
170
+
171
+ ```html
172
+ <!-- WRONG: Tailwind opacity syntax fails with design system colors -->
173
+ <div class="text-foreground/80">
174
+ <div class="bg-primary/20">
175
+
176
+ <!-- CORRECT: Custom opacity utilities -->
177
+ <div class="text-foreground-80">
178
+ <div class="bg-primary-20">
179
+
180
+ <!-- Available levels: 20, 40, 60, 80 -->
181
+ <div class="text-foreground-80 text-foreground-60 text-foreground-40 text-foreground-20">
182
+ ```
183
+
184
+ ### 5. Wrapper Component Usage
185
+
186
+ **Always use Angular wrappers, never web components directly:**
187
+
188
+ ```html
189
+ <!-- CORRECT: Use wrapper selectors -->
190
+ <modus-button color="primary" (buttonClick)="handleClick($event)">
191
+ Click Me
192
+ </modus-button>
193
+ <modus-alert alertTitle="Success" variant="success" />
194
+ <modus-icon name="add" size="md" />
195
+
196
+ <!-- WRONG: Never use modus-wc-* in application templates -->
197
+ <modus-wc-button color="primary">Click</modus-wc-button>
198
+ <modus-wc-alert alert-title="Success"></modus-wc-alert>
199
+ ```
200
+
201
+ ### 6. Divider Component
202
+
203
+ **Vertical dividers require `items-stretch` and explicit height:**
204
+
205
+ ```html
206
+ <!-- CORRECT: Vertical divider -->
207
+ <div class="flex items-stretch gap-4 min-h-[60px]">
208
+ <div>Left</div>
209
+ <modus-divider [orientation]="'vertical'" />
210
+ <div>Right</div>
211
+ </div>
212
+
213
+ <!-- WRONG: Won't render without items-stretch and height -->
214
+ <div class="flex items-center gap-4">
215
+ <modus-divider [orientation]="'vertical'" />
216
+ </div>
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Angular 20 Patterns
222
+
223
+ ### Required Patterns
224
+
225
+ ```typescript
226
+ @Component({
227
+ selector: 'app-example',
228
+ changeDetection: ChangeDetectionStrategy.OnPush, // REQUIRED
229
+ template: `
230
+ @if (isVisible()) {
231
+ <modus-button [color]="color()" (buttonClick)="handleClick($event)">
232
+ {{ buttonText() }}
233
+ </modus-button>
234
+ }
235
+ @for (item of items(); track item.id) {
236
+ <div>{{ item.name }}</div>
237
+ }
238
+ `,
239
+ })
240
+ export class ExampleComponent {
241
+ // Signal-based inputs (not @Input decorator)
242
+ readonly color = input<ButtonColor>('primary');
243
+ readonly disabled = input<boolean>(false);
244
+
245
+ // Signal-based outputs (not @Output decorator)
246
+ readonly buttonClick = output<MouseEvent>();
247
+
248
+ // Writable signals for state
249
+ readonly isVisible = signal(true);
250
+ readonly items = signal<Item[]>([]);
251
+
252
+ // Computed for derived state
253
+ readonly isDisabled = computed(() => this.disabled() || this.loading());
254
+
255
+ // inject() for DI (not constructor injection)
256
+ private readonly myService = inject(MyService);
257
+ }
258
+ ```
259
+
260
+ ### Forbidden Patterns
261
+
262
+ ```typescript
263
+ // WRONG: @Input/@Output decorators
264
+ @Input() color: string;
265
+ @Output() buttonClick = new EventEmitter();
266
+
267
+ // WRONG: Constructor injection
268
+ constructor(private myService: MyService) {}
269
+
270
+ // WRONG: *ngIf/*ngFor directives
271
+ <div *ngIf="condition">
272
+ <div *ngFor="let item of items">
273
+
274
+ // WRONG: standalone: true (implicit in Angular 20)
275
+ @Component({ standalone: true, ... })
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Boundaries
281
+
282
+ ### Always Do
283
+
284
+ - Run `npm run lint:all` before committing
285
+ - Use wrapper components (`<modus-button>` not `<modus-wc-button>`)
286
+ - Use design system colors only (9 colors)
287
+ - Use Modus Icons only (`<i class="modus-icons">icon_name</i>`)
288
+ - Invert checkbox values from `inputChange` events
289
+ - Use `getElementById` for modal access
290
+ - Use custom opacity utilities (`-80` not `/80`)
291
+ - Use `ChangeDetectionStrategy.OnPush`
292
+ - Use `input()`, `output()`, `signal()`, `computed()`
293
+ - Use `@if`, `@for`, `@switch` control flow
294
+ - Use `inject()` for dependency injection
295
+ - Test in all 6 themes (classic/modern, light/dark, connect)
296
+
297
+ ### Ask First
298
+
299
+ - Creating new wrapper components in `src/app/components/`
300
+ - Modifying existing wrapper components
301
+ - Changes to `src/styles.css` (design system definitions)
302
+ - Changes to lint scripts in `scripts/`
303
+ - Adding new dependencies
304
+
305
+ ### Never Do
306
+
307
+ - Use generic Tailwind colors (`bg-blue-500`, `text-gray-600`)
308
+ - Use hardcoded hex colors (`#ffffff`, `#000000`)
309
+ - Use inline styles (except truly dynamic values)
310
+ - Use other icon libraries (Font Awesome, Material Icons, Heroicons)
311
+ - Use semantic HTML (`h1`, `p`, `section`, `header`) - use `div` only
312
+ - Use Tailwind opacity syntax (`/80`) with design system colors
313
+ - Use web components directly (`modus-wc-*`) in app templates
314
+ - Use `@Input()`, `@Output()` decorators
315
+ - Use `*ngIf`, `*ngFor` directives
316
+ - Use constructor injection
317
+ - Skip lint checks before committing
318
+ - Commit with lint violations
319
+
320
+ ---
321
+
322
+ ## Icons
323
+
324
+ ### Usage
325
+
326
+ ```html
327
+ <!-- Angular component -->
328
+ <modus-icon name="add" size="md" />
329
+
330
+ <!-- Direct class usage -->
331
+ <i class="modus-icons">add</i>
332
+ <i class="modus-icons text-lg text-primary">save_disk</i>
333
+ ```
334
+
335
+ ### Naming
336
+
337
+ - Icon names use **underscores**: `save_disk`, `arrow_left`, `check_circle`
338
+ - Run `npm run lint:icon-names` to validate icon names
339
+ - 700+ icons available - check `/dev/icons` route for browser
340
+
341
+ ---
342
+
343
+ ## Themes
344
+
345
+ 6 themes supported:
346
+ - `modus-classic-light` / `modus-classic-dark`
347
+ - `modus-modern-light` / `modus-modern-dark`
348
+ - `modus-connect-light` / `modus-connect-dark`
349
+
350
+ Toggle Dev Panel with `Ctrl+Shift+D` in development mode to test themes.
351
+
352
+ ---
353
+
354
+ ## Reference
355
+
356
+ For comprehensive patterns, examples, and edge cases:
357
+ - **Master Rule**: `.cursor/rules/modus-angular-master.mdc`
358
+ - **Essentials**: `.cursor/rules/modus-angular-essentials.mdc`
359
+ - **Component Rules**: `.cursor/rules/modus-angular-[component].mdc`
360
+ - **Design System**: `.cursor/rules/modus-angular-design-system.mdc`
361
+ - **Scripts README**: `scripts/README.md`
362
+
363
+ ---
364
+
365
+ ## Quick Checklist
366
+
367
+ Before completing any task:
368
+
369
+ - [ ] `npm run lint:all` passes with 0 violations
370
+ - [ ] Using wrapper components only (`<modus-button>` not `<modus-wc-button>`)
371
+ - [ ] Using design system colors only (no `bg-blue-500`)
372
+ - [ ] Using Modus Icons only (no Font Awesome)
373
+ - [ ] Using `div` elements only (no semantic HTML)
374
+ - [ ] Using custom opacity utilities (`-80` not `/80`)
375
+ - [ ] Using signal-based APIs (`input()`, `output()`, `signal()`)
376
+ - [ ] Using modern control flow (`@if`, `@for`)
377
+ - [ ] Tested in at least light and dark themes