scss-variable-extractor 1.6.3 → 1.6.5

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/THEME-GUIDE.md ADDED
@@ -0,0 +1,289 @@
1
+ # Theme Generation and Global Styles Example
2
+
3
+ This guide demonstrates the new features for theme generation and global styles preservation.
4
+
5
+ ## 1. Generate Theme Structure
6
+
7
+ First, generate a complete theme structure for your Angular Material app:
8
+
9
+ ```bash
10
+ # Analyze existing styles and generate themes
11
+ npx scss-extract generate-themes ./src --analyze --output ./src/styles
12
+ ```
13
+
14
+ This creates:
15
+
16
+ ```
17
+ src/styles/
18
+ ├── _theme-base.scss # Shared variables (spacing, typography)
19
+ ├── _theme-light.scss # Light mode colors
20
+ ├── _theme-dark.scss # Dark mode colors
21
+ ├── themes.scss # Material theme loader
22
+ ├── _css-variables.scss # CSS custom properties
23
+ └── _component-theme-mixin.scss # Theme mixin template
24
+ ```
25
+
26
+ ## 2. Modernize Components (Preserve Global Styles)
27
+
28
+ Next, refactor your components to remove ::ng-deep and !important while preserving the styles globally:
29
+
30
+ ```bash
31
+ # Preview changes
32
+ npx scss-extract modernize ./src --dry-run
33
+
34
+ # Apply modernization with global preservation
35
+ npx scss-extract modernize ./src --global-styles ./src/styles/global-overrides.scss
36
+ ```
37
+
38
+ **Before (component-a.component.scss):**
39
+
40
+ ```scss
41
+ .container {
42
+ padding: 16px;
43
+
44
+ ::ng-deep .mat-dialog-container {
45
+ border-radius: 8px !important; // Override Material's default
46
+ }
47
+
48
+ .header {
49
+ color: #1976d2 !important; // Prevent parent override
50
+ }
51
+ }
52
+ ```
53
+
54
+ **After modernization:**
55
+
56
+ **component-a.component.scss:**
57
+
58
+ ```scss
59
+ .container {
60
+ padding: 16px;
61
+
62
+ // ng-deep and !important removed - see global-overrides.scss
63
+ }
64
+ ```
65
+
66
+ **src/styles/global-overrides.scss:**
67
+
68
+ ```scss
69
+ /* Moved from component-a.component.scss - requires !important for specificity */
70
+ .container .mat-dialog-container {
71
+ border-radius: 8px !important;
72
+ }
73
+
74
+ /* Moved from component-a.component.scss - requires !important for specificity */
75
+ .container .header {
76
+ color: #1976d2 !important;
77
+ }
78
+ ```
79
+
80
+ ✅ **Benefits:**
81
+
82
+ - Styles are preserved with proper specificity
83
+ - No parent component overrides
84
+ - Follows Angular Material v15+ best practices
85
+ - Centralized global styles for easier maintenance
86
+
87
+ ## 3. Set Up Theme Switching
88
+
89
+ Import the generated themes in your `styles.scss`:
90
+
91
+ ```scss
92
+ @use './styles/themes';
93
+ @use './styles/global-overrides';
94
+ ```
95
+
96
+ Add theme toggle to your app component:
97
+
98
+ **app.component.ts:**
99
+
100
+ ```typescript
101
+ import { Component } from '@angular/core';
102
+
103
+ @Component({
104
+ selector: 'app-root',
105
+ templateUrl: './app.component.html',
106
+ styleUrls: ['./app.component.scss'],
107
+ })
108
+ export class AppComponent {
109
+ isDarkMode = false;
110
+
111
+ constructor() {
112
+ // Check user preference or localStorage
113
+ const savedTheme = localStorage.getItem('theme');
114
+ this.isDarkMode = savedTheme === 'dark';
115
+ }
116
+
117
+ toggleTheme() {
118
+ this.isDarkMode = !this.isDarkMode;
119
+ localStorage.setItem('theme', this.isDarkMode ? 'dark' : 'light');
120
+ }
121
+ }
122
+ ```
123
+
124
+ **app.component.html:**
125
+
126
+ ```html
127
+ <div [class.dark-theme]="isDarkMode">
128
+ <mat-toolbar color="primary">
129
+ <span>My App</span>
130
+ <span class="spacer"></span>
131
+ <button mat-icon-button (click)="toggleTheme()">
132
+ <mat-icon>{{ isDarkMode ? 'light_mode' : 'dark_mode' }}</mat-icon>
133
+ </button>
134
+ </mat-toolbar>
135
+
136
+ <router-outlet></router-outlet>
137
+ </div>
138
+ ```
139
+
140
+ ## 4. Use Theme Variables in Components
141
+
142
+ Instead of hardcoded values, use the generated theme variables:
143
+
144
+ **Before:**
145
+
146
+ ```scss
147
+ .my-card {
148
+ padding: 16px;
149
+ margin: 24px;
150
+ border-radius: 8px;
151
+ background: #ffffff;
152
+ color: rgba(0, 0, 0, 0.87);
153
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
154
+ }
155
+ ```
156
+
157
+ **After:**
158
+
159
+ ```scss
160
+ @use '../../styles/theme-base' as base;
161
+
162
+ .my-card {
163
+ padding: base.$spacing-md;
164
+ margin: base.$spacing-lg;
165
+ border-radius: base.$border-radius-md;
166
+ background: var(--surface-color);
167
+ color: var(--text-primary);
168
+ box-shadow: base.$shadow-sm;
169
+ }
170
+ ```
171
+
172
+ ✅ **Benefits:**
173
+
174
+ - Automatic dark/light mode switching
175
+ - Consistent spacing and design tokens
176
+ - No hardcoded values
177
+ - Easy theme updates
178
+
179
+ ## 5. Create Component Theme Mixins (Advanced)
180
+
181
+ For components that need different colors in light/dark themes:
182
+
183
+ **my-component.theme.scss:**
184
+
185
+ ```scss
186
+ @use '@angular/material' as mat;
187
+
188
+ @mixin component-theme($theme) {
189
+ $color-config: mat.get-color-config($theme);
190
+
191
+ @if $color-config != null {
192
+ $primary: map.get($color-config, 'primary');
193
+ $background: map.get($color-config, 'background');
194
+
195
+ .my-special-component {
196
+ background-color: mat.get-color-from-palette($background, 'card');
197
+ border-left: 4px solid mat.get-color-from-palette($primary);
198
+
199
+ &__header {
200
+ background-color: mat.get-color-from-palette($primary);
201
+ color: mat.get-color-from-palette($primary, 'default-contrast');
202
+ }
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ Then include in `themes.scss`:
209
+
210
+ ```scss
211
+ @use './my-component.theme' as my-component;
212
+
213
+ // Light theme
214
+ @include my-component.component-theme($light-theme);
215
+
216
+ // Dark theme
217
+ .dark-theme {
218
+ @include my-component.component-theme($dark-theme);
219
+ }
220
+ ```
221
+
222
+ ## 6. Auto-Format Code
223
+
224
+ Keep your code consistently formatted:
225
+
226
+ ```bash
227
+ # Format all files
228
+ npm run format
229
+
230
+ # Check formatting (CI/CD)
231
+ npm run format:check
232
+ ```
233
+
234
+ The formatter runs automatically before releases.
235
+
236
+ ## Complete Workflow Example
237
+
238
+ ```bash
239
+ # 1. Generate theme structure
240
+ npx scss-extract generate-themes ./src --analyze
241
+
242
+ # 2. Extract hardcoded values to variables
243
+ npx scss-extract refactor ./src --output ./src/styles/_variables.scss
244
+
245
+ # 3. Modernize components (preserve global styles)
246
+ npx scss-extract modernize ./src --global-styles ./src/styles/global-overrides.scss
247
+
248
+ # 4. Detect and migrate Bootstrap (if applicable)
249
+ npx scss-extract detect-bootstrap ./src
250
+ npx scss-extract migrate-bootstrap ./src
251
+
252
+ # 5. Format code
253
+ npm run format
254
+
255
+ # 6. Run tests and commit
256
+ npm test
257
+ git add .
258
+ git commit -m "feat: Implement theme system and modernize styles"
259
+ ```
260
+
261
+ ## Best Practices Summary
262
+
263
+ ✅ **DO:**
264
+
265
+ - Use theme variables for all colors
266
+ - Use base variables for spacing, typography, shadows
267
+ - Move global styles to dedicated files
268
+ - Use CSS custom properties for runtime theme switching
269
+ - Create component theme mixins for complex theming
270
+ - Format code regularly
271
+
272
+ ❌ **DON'T:**
273
+
274
+ - Use ::ng-deep (use theme mixins instead)
275
+ - Hardcode colors (use theme variables)
276
+ - Hardcode spacing (use base spacing scale)
277
+ - Use ViewEncapsulation.None unnecessarily
278
+ - Mix !important in component files (move to global)
279
+
280
+ ## Result
281
+
282
+ 🎨 **Professional Theme System:**
283
+
284
+ - Dark and light modes
285
+ - Consistent design tokens
286
+ - Maintainable global styles
287
+ - No ViewEncapsulation issues
288
+ - Material Design aligned
289
+ - Easy to extend and customize