create-ng-tailwind 2.1.1 → 3.0.0

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/CHANGELOG.md CHANGED
@@ -5,6 +5,61 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.0.0] - 2025-11-30
9
+
10
+ ### 💥 Breaking Changes
11
+
12
+ - **Angular CLI Alignment**: Now fully relies on Angular CLI for project configuration
13
+ - Removed custom `ensureZoneJs()` method - Angular CLI handles zone.js natively
14
+ - Explicitly passes `--zoneless=false` or `--zoneless=true` to Angular CLI in non-interactive mode
15
+ - Projects now match exactly what `ng new` produces interactively
16
+
17
+ ### 🐛 Bug Fixes
18
+
19
+ - **zone.js Configuration**: Fixed issue where zone.js was not being properly configured when selecting "No" for zoneless application
20
+ - Fixes runtime error `NG0908: In this configuration Angular requires Zone.js`
21
+
22
+ ## [2.2.0] - 2025-11-01
23
+
24
+ ### ✨ New Features - Comprehensive Tailwind v4 Theming System
25
+
26
+ - **Complete Theme System using Tailwind v4 @theme directive**:
27
+ - Added comprehensive color theming with 7 semantic color scales (primary, secondary, accent, success, danger, warning, info)
28
+ - Each color includes full 50-950 scale for maximum flexibility
29
+ - All colors defined using modern `@theme` directive in `styles.css`
30
+ - Automatic utility class generation (bg-*, text-*, border-*, ring-*, etc.)
31
+
32
+ - **Theme Customization**:
33
+ - Easy customization by editing CSS custom properties in `styles.css`
34
+ - Clear documentation and usage examples in theme configuration
35
+ - All components automatically update when theme colors change
36
+ - No JavaScript configuration needed - pure CSS approach
37
+
38
+ - **Updated All Components to Use Theme Colors**:
39
+ - ButtonComponent: Uses primary, secondary, and danger theme colors
40
+ - ToastComponent: Uses success, danger, warning, and info colors
41
+ - LoadingSpinnerComponent: Supports all theme color variants
42
+ - Contact page: Gradient backgrounds using primary, secondary, and accent
43
+ - Header component: Navigation and active states use primary theme
44
+ - Home & About pages: Hero sections and feature cards use theme colors
45
+ - Auth pages: Login, Register, Forgot Password use primary theme
46
+ - Footer: Links use primary theme colors
47
+
48
+ - **Developer Experience**:
49
+ - Comprehensive inline documentation in `styles.css`
50
+ - Usage examples for all theme colors
51
+ - Clear instructions for customization
52
+ - Consistent color usage across all generated components
53
+
54
+ ### 🎨 Design Improvements
55
+
56
+ - Replaced all hardcoded blue, cyan, red, green colors with semantic theme colors
57
+ - Updated gradients to use primary-secondary-accent combinations
58
+ - Error states now use danger theme color instead of hardcoded red
59
+ - Success states use success theme color instead of hardcoded green
60
+ - Info messages use info theme color
61
+ - Warning states use warning theme color
62
+
8
63
  ## [2.1.1] - 2025-10-30
9
64
 
10
65
  ### 🐛 Fixed
package/README.md CHANGED
@@ -168,6 +168,40 @@ This tool uses **Tailwind CSS v4** with the official PostCSS approach:
168
168
 
169
169
  **Note:** Tailwind v4 does not support SCSS, Sass, or Less. Modern CSS provides all the features you need!
170
170
 
171
+ ### 🎨 Comprehensive Theming System
172
+
173
+ The starter template includes a **powerful Tailwind v4 theming system** using the `@theme` directive:
174
+
175
+ **Theme Colors:**
176
+ - `primary` - Main brand color (with full 50-950 scale)
177
+ - `secondary` - Secondary brand color (with full 50-950 scale)
178
+ - `accent` - Accent/highlight color (with full 50-950 scale)
179
+ - `success` - Success states (green)
180
+ - `danger` - Error/danger states (red)
181
+ - `warning` - Warning states (yellow/orange)
182
+ - `info` - Informational states (blue)
183
+
184
+ **Customization:**
185
+ Simply edit `src/styles.css` and change the color values in the `@theme` block. All components automatically update!
186
+
187
+ ```css
188
+ @theme {
189
+ --color-primary-500: #3b82f6; /* Change this to your brand color */
190
+ --color-secondary-500: #06b6d4;
191
+ --color-accent-500: #a855f7;
192
+ /* ... complete color scales included */
193
+ }
194
+ ```
195
+
196
+ **Usage in templates:**
197
+ ```html
198
+ <div class="bg-primary-600 text-white">Primary button</div>
199
+ <div class="bg-secondary-500">Secondary element</div>
200
+ <p class="text-danger-600">Error message</p>
201
+ ```
202
+
203
+ All UI components, pages, and layouts use these theme colors, making it easy to rebrand your entire application by changing a few color values!
204
+
171
205
  ## 📄 License
172
206
 
173
207
  MIT License - see the LICENSE file included in the package.
@@ -1,9 +1,8 @@
1
- const fs = require("fs-extra");
2
- const path = require("path");
3
- const execa = require("execa");
4
- const TailwindManager = require("./TailwindManager");
5
- const TemplateManager = require("./TemplateManager");
6
- const { createAIConfigs } = require("../utils/ai-config");
1
+ const fs = require('fs-extra');
2
+ const execa = require('execa');
3
+ const TailwindManager = require('./TailwindManager');
4
+ const TemplateManager = require('./TemplateManager');
5
+ const { createAIConfigs } = require('../utils/ai-config');
7
6
 
8
7
  class ProjectManager {
9
8
  constructor(config, logger) {
@@ -18,15 +17,15 @@ class ProjectManager {
18
17
  if (await fs.pathExists(this.config.fullPath)) {
19
18
  const { overwrite } = await this.logger.prompt([
20
19
  {
21
- type: "confirm",
22
- name: "overwrite",
20
+ type: 'confirm',
21
+ name: 'overwrite',
23
22
  message: `Directory ${this.config.projectName} already exists. Do you want to overwrite it?`,
24
23
  default: false,
25
24
  },
26
25
  ]);
27
26
 
28
27
  if (!overwrite) {
29
- this.logger.warn("Operation cancelled");
28
+ this.logger.warn('Operation cancelled');
30
29
  process.exit(0);
31
30
  }
32
31
 
@@ -43,37 +42,30 @@ class ProjectManager {
43
42
  await this.templateManager.apply();
44
43
 
45
44
  // Create AI configuration files (CLAUDE.md + tool-specific)
46
- await createAIConfigs(
47
- this.config.fullPath,
48
- this.config.projectName,
49
- this.config.aiConfig,
50
- );
45
+ await createAIConfigs(this.config.fullPath, this.config.projectName, this.config.aiConfig);
51
46
  }
52
47
 
53
48
  async createAngularProject() {
54
- const spinner = this.logger.spinner("Creating Angular project...");
49
+ const spinner = this.logger.spinner('Creating Angular project...');
55
50
 
56
51
  try {
57
52
  // Build ng new command with user's choices
58
53
  const routing = this.config.routing !== false;
59
54
  const ssr = this.config.ssr || false;
60
55
  const zoneless = this.config.zoneless || false;
61
- const aiConfig = this.config.aiConfig || ["none"];
56
+ const aiConfig = this.config.aiConfig || ['none'];
62
57
 
63
58
  let cmd = `npx @angular/cli@latest new ${this.config.projectName}`;
64
59
  cmd += ` --routing=${routing}`;
65
60
  cmd += ` --style=css`; // Always use CSS (Tailwind v4 official approach)
66
61
  cmd += ` --ssr=${ssr}`;
67
-
68
- if (zoneless) {
69
- cmd += ` --zoneless`;
70
- }
62
+ cmd += ` --zoneless=${zoneless}`;
71
63
 
72
64
  // Add AI config - Angular CLI supports multiple --ai-config flags
73
- if (aiConfig.length > 0 && !aiConfig.includes("none")) {
65
+ if (aiConfig.length > 0 && !aiConfig.includes('none')) {
74
66
  // Add each AI tool as a separate --ai-config flag
75
67
  aiConfig.forEach((tool) => {
76
- if (tool !== "none") {
68
+ if (tool !== 'none') {
77
69
  cmd += ` --ai-config=${tool}`;
78
70
  }
79
71
  });
@@ -83,12 +75,12 @@ class ProjectManager {
83
75
 
84
76
  await execa.command(cmd, {
85
77
  cwd: process.cwd(),
86
- stdio: "pipe",
78
+ stdio: 'pipe',
87
79
  });
88
80
 
89
- spinner.succeed("Angular project created");
81
+ spinner.succeed('Angular project created');
90
82
  } catch (error) {
91
- spinner.fail("Failed to create Angular project");
83
+ spinner.fail('Failed to create Angular project');
92
84
  throw error;
93
85
  }
94
86
  }
@@ -284,12 +284,11 @@ export class ToastService {
284
284
 
285
285
  async function createToastComponent(config) {
286
286
  const toastComponent = `import { Component, inject } from '@angular/core';
287
- import { CommonModule } from '@angular/common';
288
287
  import { ToastService, Toast } from '@core/services/toast.service';
289
288
 
290
289
  @Component({
291
290
  selector: 'app-toast',
292
- imports: [CommonModule],
291
+ imports: [],
293
292
  template: \`
294
293
  <!-- Toast Container -->
295
294
  <div class="fixed top-4 right-4 z-50 space-y-2 max-w-sm w-full">
@@ -302,22 +301,22 @@ import { ToastService, Toast } from '@core/services/toast.service';
302
301
  <div class="shrink-0">
303
302
  @switch (toast.type) {
304
303
  @case ('success') {
305
- <svg class="h-6 w-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
304
+ <svg class="h-6 w-6 text-success-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
306
305
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
307
306
  </svg>
308
307
  }
309
308
  @case ('error') {
310
- <svg class="h-6 w-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
309
+ <svg class="h-6 w-6 text-danger-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
311
310
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
312
311
  </svg>
313
312
  }
314
313
  @case ('warning') {
315
- <svg class="h-6 w-6 text-yellow-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
314
+ <svg class="h-6 w-6 text-warning-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
316
315
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
317
316
  </svg>
318
317
  }
319
318
  @case ('info') {
320
- <svg class="h-6 w-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
319
+ <svg class="h-6 w-6 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
321
320
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
322
321
  </svg>
323
322
  }
@@ -364,10 +363,10 @@ export class ToastComponent {
364
363
  getToastClasses(toast: Toast): string {
365
364
  const baseClasses = 'border-l-4';
366
365
  const typeClasses = {
367
- success: 'bg-green-50 border-green-500',
368
- error: 'bg-red-50 border-red-500',
369
- warning: 'bg-yellow-50 border-yellow-500',
370
- info: 'bg-blue-50 border-blue-500'
366
+ success: 'bg-success-50 border-success-500',
367
+ error: 'bg-danger-50 border-danger-500',
368
+ warning: 'bg-warning-50 border-warning-500',
369
+ info: 'bg-info-50 border-info-500'
371
370
  };
372
371
 
373
372
  return \`\${baseClasses} \${typeClasses[toast.type]}\`;