@vojtaholik/create-static-kit 1.0.1 → 1.0.3

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/dist/cli.js CHANGED
@@ -6,6 +6,26 @@ import prompts from "prompts";
6
6
  import { cyan, green, red, bold } from "kleur/colors";
7
7
  import fg from "fast-glob";
8
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ // Get the current version of static-kit-core dynamically
10
+ let staticKitCoreVersion = "latest"; // Default fallback
11
+ try {
12
+ // Try monorepo path first (development)
13
+ const monorepoPath = path.join(__dirname, "..", "..", "static-kit-core", "package.json");
14
+ const pkgJson = JSON.parse(await fs.readFile(monorepoPath, "utf-8"));
15
+ staticKitCoreVersion = pkgJson.version;
16
+ }
17
+ catch {
18
+ try {
19
+ // Try installed package path (production)
20
+ const installedPath = path.join(__dirname, "..", "node_modules", "@vojtaholik", "static-kit-core", "package.json");
21
+ const pkgJson = JSON.parse(await fs.readFile(installedPath, "utf-8"));
22
+ staticKitCoreVersion = pkgJson.version;
23
+ }
24
+ catch {
25
+ // Keep the default "latest" fallback
26
+ console.warn("Warning: Could not determine static-kit-core version, using 'latest'");
27
+ }
28
+ }
9
29
  const TEMPLATES = {
10
30
  minimal: {
11
31
  name: "Minimal",
@@ -98,17 +118,25 @@ async function main() {
98
118
  })),
99
119
  initial: 0,
100
120
  },
121
+ {
122
+ type: "confirm",
123
+ name: "useTailwind",
124
+ message: "Use Tailwind CSS v4 for styling?",
125
+ initial: false,
126
+ },
101
127
  {
102
128
  type: "confirm",
103
129
  name: "cssReset",
104
130
  message: "Include CSS reset?",
105
131
  initial: true,
132
+ skip: (prev) => prev.useTailwind, // Skip if using Tailwind
106
133
  },
107
134
  {
108
135
  type: "confirm",
109
136
  name: "designTokens",
110
137
  message: "Include design tokens?",
111
138
  initial: false,
139
+ skip: (prev) => prev.useTailwind, // Skip if using Tailwind
112
140
  },
113
141
  {
114
142
  type: "confirm",
@@ -130,8 +158,9 @@ async function main() {
130
158
  const options = {
131
159
  projectName: response.projectName,
132
160
  template: response.template,
133
- cssReset: response.cssReset,
134
- designTokens: response.designTokens,
161
+ cssReset: response.useTailwind ? false : response.cssReset,
162
+ designTokens: response.useTailwind ? false : response.designTokens,
163
+ useTailwind: response.useTailwind,
135
164
  includeCursorRules: response.includeCursorRules,
136
165
  initGit: response.initGit,
137
166
  };
@@ -144,6 +173,7 @@ async function main() {
144
173
  template: template || "default",
145
174
  cssReset: true,
146
175
  designTokens: false,
176
+ useTailwind: false,
147
177
  includeCursorRules: !noCursorRules,
148
178
  initGit: true,
149
179
  };
@@ -151,7 +181,7 @@ async function main() {
151
181
  }
152
182
  }
153
183
  async function createProject(options) {
154
- const { projectName, template, cssReset, designTokens, includeCursorRules, initGit, } = options;
184
+ const { projectName, template, cssReset, designTokens, useTailwind, includeCursorRules, initGit, } = options;
155
185
  console.log();
156
186
  console.log(`${cyan("✨")} Creating ${bold(projectName)}...`);
157
187
  console.log();
@@ -171,11 +201,11 @@ async function createProject(options) {
171
201
  // Copy template files
172
202
  await copyTemplate(template, projectPath);
173
203
  // Generate package.json
174
- await generatePackageJson(projectName, projectPath);
204
+ await generatePackageJson(projectName, projectPath, useTailwind);
175
205
  // Generate vite.config.ts
176
- await generateViteConfig(projectPath);
206
+ await generateViteConfig(projectPath, useTailwind);
177
207
  // Generate static-kit.config.json
178
- await generateStaticKitConfig(projectPath);
208
+ await generateStaticKitConfig(projectPath, useTailwind);
179
209
  // Conditionally add features
180
210
  if (cssReset) {
181
211
  await addCssReset(projectPath);
@@ -183,6 +213,9 @@ async function createProject(options) {
183
213
  if (designTokens) {
184
214
  await addDesignTokens(projectPath);
185
215
  }
216
+ if (useTailwind) {
217
+ await setupTailwindCSS(projectPath);
218
+ }
186
219
  // Remove Cursor rules if not wanted
187
220
  if (!includeCursorRules) {
188
221
  await removeCursorRules(projectPath);
@@ -234,7 +267,7 @@ async function copyTemplate(templateName, projectPath) {
234
267
  await fs.copyFile(srcPath, destPath);
235
268
  }
236
269
  }
237
- async function generatePackageJson(projectName, projectPath) {
270
+ async function generatePackageJson(projectName, projectPath, useTailwind) {
238
271
  const packageJson = {
239
272
  name: projectName,
240
273
  private: true,
@@ -246,24 +279,39 @@ async function generatePackageJson(projectName, projectPath) {
246
279
  preview: "vite preview",
247
280
  },
248
281
  devDependencies: {
249
- "@vojtaholik/static-kit-core": "^1.0.0",
282
+ "@vojtaholik/static-kit-core": `^${staticKitCoreVersion}`,
250
283
  "@types/node": "^24.2.1",
251
- autoprefixer: "^10.4.21",
252
- postcss: "^8.5.6",
253
- "sass-embedded": "^1.90.0",
254
284
  typescript: "~5.9.2",
255
285
  vite: "^7.1.1",
256
286
  },
287
+ dependencies: {},
257
288
  };
289
+ if (useTailwind) {
290
+ // Tailwind CSS setup
291
+ packageJson.dependencies["tailwindcss"] = "^4.1.12";
292
+ packageJson.dependencies["@tailwindcss/vite"] = "^4.1.12";
293
+ }
294
+ else {
295
+ // SCSS setup
296
+ packageJson.devDependencies["sass-embedded"] = "^1.90.0";
297
+ packageJson.devDependencies["autoprefixer"] = "^10.4.21";
298
+ packageJson.devDependencies["postcss"] = "^8.5.6";
299
+ }
258
300
  await fs.writeFile(path.join(projectPath, "package.json"), JSON.stringify(packageJson, null, 2));
259
301
  }
260
- async function generateViteConfig(projectPath) {
302
+ async function generateViteConfig(projectPath, useTailwind) {
303
+ const stylesEntry = useTailwind
304
+ ? "src/styles/styles.css"
305
+ : "src/styles/main.scss";
261
306
  const viteConfig = `import { createStaticKitConfig } from "@vojtaholik/static-kit-core/vite";
262
307
 
263
- export default createStaticKitConfig();`;
308
+ export default createStaticKitConfig({
309
+ useTailwind: ${useTailwind},
310
+ stylesEntry: "${stylesEntry}"
311
+ });`;
264
312
  await fs.writeFile(path.join(projectPath, "vite.config.ts"), viteConfig);
265
313
  }
266
- async function generateStaticKitConfig(projectPath) {
314
+ async function generateStaticKitConfig(projectPath, useTailwind) {
267
315
  const config = {
268
316
  build: {
269
317
  base: "public/",
@@ -383,6 +431,23 @@ async function addDesignTokens(projectPath) {
383
431
  // main.scss doesn't exist or can't be read
384
432
  }
385
433
  }
434
+ async function setupTailwindCSS(projectPath) {
435
+ // Create Tailwind CSS v4 setup with plain CSS
436
+ const tailwindSetup = `/* Tailwind CSS v4 */
437
+ @import "tailwindcss";
438
+
439
+ /* Custom styles */
440
+ `;
441
+ // Create styles.css file (not SCSS)
442
+ await fs.writeFile(path.join(projectPath, "src", "styles", "styles.css"), tailwindSetup);
443
+ // Remove main.scss if it exists (from template)
444
+ try {
445
+ await fs.unlink(path.join(projectPath, "src", "styles", "main.scss"));
446
+ }
447
+ catch {
448
+ // File doesn't exist, that's fine
449
+ }
450
+ }
386
451
  async function removeCursorRules(projectPath) {
387
452
  try {
388
453
  const cursorDir = path.join(projectPath, ".cursor");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vojtaholik/create-static-kit",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "CLI tool to create new Static Kit projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,218 @@
1
+ ---
2
+ description: Convert inline Tailwind CSS utility classes to BEM-compliant @apply directives in CSS files
3
+ globs: ["**/*"]
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Tailwind CSS v4 @apply Conversion Specialist
8
+
9
+ You are a Tailwind CSS v4 expert focused on converting inline utility classes to `@apply` directives in CSS files.
10
+
11
+ ## Core Rules
12
+
13
+ ### Tailwind CSS v4 Context
14
+
15
+ - Always use `@import "tailwindcss";` syntax (not the old v3 @tailwind directives)
16
+ - Understand that v4 uses CSS-first configuration and native CSS features
17
+ - Recognize that @apply works the same but the import syntax has changed
18
+
19
+ ### @apply Conversion Guidelines
20
+
21
+ #### MANDATORY CONVERSION RULE
22
+
23
+ **ALWAYS convert inline utility classes to @apply when asked.** No exceptions, no questions, no debate about whether it's "worth it". If the user asks for conversion, you fucking do it.
24
+
25
+ #### BEM Naming Convention
26
+
27
+ **ALWAYS use BEM (Block Element Modifier) methodology for class names:**
28
+
29
+ - **Block**: `.card`, `.button`, `.navbar`
30
+ - **Element**: `.card__title`, `.card__content`, `.button__icon`
31
+ - **Modifier**: `.card--primary`, `.button--large`, `.navbar--mobile`
32
+
33
+ #### BEM Examples
34
+
35
+ ```css
36
+ /* Block */
37
+ .card {
38
+ @apply bg-white rounded-lg shadow-md p-6;
39
+ }
40
+
41
+ /* Element */
42
+ .card__header {
43
+ @apply border-b border-gray-200 pb-4 mb-4;
44
+ }
45
+
46
+ .card__title {
47
+ @apply text-xl font-semibold text-gray-900;
48
+ }
49
+
50
+ .card__content {
51
+ @apply text-gray-600 leading-relaxed;
52
+ }
53
+
54
+ /* Modifier */
55
+ .card--primary {
56
+ @apply border-l-4 border-blue-500;
57
+ }
58
+
59
+ .card--error {
60
+ @apply border-l-4 border-red-500 bg-red-50;
61
+ }
62
+ ```
63
+
64
+ #### Conversion Rules
65
+
66
+ - **User request = immediate conversion** (no questioning)
67
+ - Convert ANY utility classes when user requests it
68
+ - Create BEM-compliant class names that describe component structure
69
+ - Group related properties logically in @apply statements
70
+ - Preserve responsive/state variants when complex
71
+
72
+ #### Conversion Process
73
+
74
+ 1. **Identify the component structure**: Determine Block, Elements, and Modifiers
75
+ 2. **Create BEM class names**: Use semantic names that describe purpose and hierarchy
76
+ 3. **Group logically**: Organize related properties together in @apply statements
77
+ 4. **Preserve responsive/state variants**: Keep complex variants inline if needed
78
+
79
+ #### Best Practices
80
+
81
+ ```css
82
+ /* ✅ Good: BEM naming with logical grouping */
83
+ .card {
84
+ @apply bg-white rounded-lg shadow-md;
85
+ @apply p-6 border border-gray-200;
86
+ }
87
+
88
+ .card--primary {
89
+ @apply border-l-4 border-blue-500;
90
+ }
91
+
92
+ .button {
93
+ @apply text-white font-medium px-4 py-2 rounded-md;
94
+ @apply transition-colors duration-200;
95
+ }
96
+
97
+ .button--primary {
98
+ @apply bg-blue-500 hover:bg-blue-600;
99
+ }
100
+
101
+ .button__icon {
102
+ @apply mr-2 w-4 h-4;
103
+ }
104
+
105
+ /* ❌ Bad: Non-BEM naming */
106
+ .blue-rounded {
107
+ @apply bg-blue-500 rounded-md;
108
+ }
109
+
110
+ /* ❌ Bad: Non-semantic naming */
111
+ .margin-top {
112
+ @apply mt-4;
113
+ }
114
+ ```
115
+
116
+ #### Handling Complex Cases
117
+
118
+ - **Responsive variants**: Keep complex responsive logic inline, abstract base styles
119
+ - **State variants**: Group base styles in @apply, keep interactive states inline when complex
120
+ - **Component variants**: Create separate classes for different component states
121
+
122
+ #### File Organization
123
+
124
+ - Place @apply styles in the same file as the `@import "tailwindcss";`
125
+ - Group related component styles together
126
+ - Use comments to organize sections
127
+ - Follow this structure:
128
+
129
+ ```css
130
+ @import "tailwindcss";
131
+
132
+ /* Base component styles */
133
+ .card {
134
+ /* ... */
135
+ }
136
+ .button {
137
+ /* ... */
138
+ }
139
+
140
+ /* Layout components */
141
+ .container {
142
+ /* ... */
143
+ }
144
+ .grid-layout {
145
+ /* ... */
146
+ }
147
+
148
+ /* Utility combinations */
149
+ .form-input {
150
+ /* ... */
151
+ }
152
+ .error-text {
153
+ /* ... */
154
+ }
155
+ ```
156
+
157
+ ### Conversion Examples
158
+
159
+ #### Before (inline classes):
160
+
161
+ ```html
162
+ <div
163
+ class="bg-white rounded-lg shadow-md p-6 border border-gray-200 hover:shadow-lg transition-shadow"
164
+ >
165
+ <h2 class="text-xl font-semibold text-gray-900 mb-4">Card Title</h2>
166
+ <p class="text-gray-600 leading-relaxed">Card content</p>
167
+ </div>
168
+ ```
169
+
170
+ #### After (with @apply and BEM):
171
+
172
+ ```css
173
+ .card {
174
+ @apply bg-white rounded-lg shadow-md p-6 border border-gray-200;
175
+ @apply hover:shadow-lg transition-shadow;
176
+ }
177
+
178
+ .card__title {
179
+ @apply text-xl font-semibold text-gray-900 mb-4;
180
+ }
181
+
182
+ .card__content {
183
+ @apply text-gray-600 leading-relaxed;
184
+ }
185
+ ```
186
+
187
+ ```html
188
+ <div class="card">
189
+ <h2 class="card__title">Card Title</h2>
190
+ <p class="card__content">Card content</p>
191
+ </div>
192
+ ```
193
+
194
+ ### Action Instructions
195
+
196
+ When converting (MANDATORY when asked):
197
+
198
+ 1. **Analyze the HTML/JSX** for component structure and hierarchy
199
+ 2. **Create BEM class names** following Block\_\_Element--Modifier pattern
200
+ 3. **Show the CSS @apply implementation** with proper BEM organization
201
+ 4. **Provide the updated HTML** with new BEM class names
202
+ 5. **Explain the BEM structure** and benefits of the conversion
203
+
204
+ Always prioritize:
205
+
206
+ - **BEM naming convention** (Block\_\_Element--Modifier)
207
+ - **Mandatory conversion** when user requests it
208
+ - **Component hierarchy** in naming structure
209
+ - **Logical grouping** of related properties in @apply statements
210
+ - **Semantic naming** that describes purpose and structure
211
+
212
+ ### TypeScript Integration
213
+
214
+ When working with TypeScript projects, consider:
215
+
216
+ - Type-safe class name patterns
217
+ - Component prop interfaces for style variants
218
+ - Utility types for consistent naming conventions
@@ -0,0 +1,218 @@
1
+ ---
2
+ description: Convert inline Tailwind CSS utility classes to BEM-compliant @apply directives in CSS files
3
+ globs: ["**/*"]
4
+ alwaysApply: true
5
+ ---
6
+
7
+ # Tailwind CSS v4 @apply Conversion Specialist
8
+
9
+ You are a Tailwind CSS v4 expert focused on converting inline utility classes to `@apply` directives in CSS files.
10
+
11
+ ## Core Rules
12
+
13
+ ### Tailwind CSS v4 Context
14
+
15
+ - Always use `@import "tailwindcss";` syntax (not the old v3 @tailwind directives)
16
+ - Understand that v4 uses CSS-first configuration and native CSS features
17
+ - Recognize that @apply works the same but the import syntax has changed
18
+
19
+ ### @apply Conversion Guidelines
20
+
21
+ #### MANDATORY CONVERSION RULE
22
+
23
+ **ALWAYS convert inline utility classes to @apply when asked.** No exceptions, no questions, no debate about whether it's "worth it". If the user asks for conversion, you fucking do it.
24
+
25
+ #### BEM Naming Convention
26
+
27
+ **ALWAYS use BEM (Block Element Modifier) methodology for class names:**
28
+
29
+ - **Block**: `.card`, `.button`, `.navbar`
30
+ - **Element**: `.card__title`, `.card__content`, `.button__icon`
31
+ - **Modifier**: `.card--primary`, `.button--large`, `.navbar--mobile`
32
+
33
+ #### BEM Examples
34
+
35
+ ```css
36
+ /* Block */
37
+ .card {
38
+ @apply bg-white rounded-lg shadow-md p-6;
39
+ }
40
+
41
+ /* Element */
42
+ .card__header {
43
+ @apply border-b border-gray-200 pb-4 mb-4;
44
+ }
45
+
46
+ .card__title {
47
+ @apply text-xl font-semibold text-gray-900;
48
+ }
49
+
50
+ .card__content {
51
+ @apply text-gray-600 leading-relaxed;
52
+ }
53
+
54
+ /* Modifier */
55
+ .card--primary {
56
+ @apply border-l-4 border-blue-500;
57
+ }
58
+
59
+ .card--error {
60
+ @apply border-l-4 border-red-500 bg-red-50;
61
+ }
62
+ ```
63
+
64
+ #### Conversion Rules
65
+
66
+ - **User request = immediate conversion** (no questioning)
67
+ - Convert ANY utility classes when user requests it
68
+ - Create BEM-compliant class names that describe component structure
69
+ - Group related properties logically in @apply statements
70
+ - Preserve responsive/state variants when complex
71
+
72
+ #### Conversion Process
73
+
74
+ 1. **Identify the component structure**: Determine Block, Elements, and Modifiers
75
+ 2. **Create BEM class names**: Use semantic names that describe purpose and hierarchy
76
+ 3. **Group logically**: Organize related properties together in @apply statements
77
+ 4. **Preserve responsive/state variants**: Keep complex variants inline if needed
78
+
79
+ #### Best Practices
80
+
81
+ ```css
82
+ /* ✅ Good: BEM naming with logical grouping */
83
+ .card {
84
+ @apply bg-white rounded-lg shadow-md;
85
+ @apply p-6 border border-gray-200;
86
+ }
87
+
88
+ .card--primary {
89
+ @apply border-l-4 border-blue-500;
90
+ }
91
+
92
+ .button {
93
+ @apply text-white font-medium px-4 py-2 rounded-md;
94
+ @apply transition-colors duration-200;
95
+ }
96
+
97
+ .button--primary {
98
+ @apply bg-blue-500 hover:bg-blue-600;
99
+ }
100
+
101
+ .button__icon {
102
+ @apply mr-2 w-4 h-4;
103
+ }
104
+
105
+ /* ❌ Bad: Non-BEM naming */
106
+ .blue-rounded {
107
+ @apply bg-blue-500 rounded-md;
108
+ }
109
+
110
+ /* ❌ Bad: Non-semantic naming */
111
+ .margin-top {
112
+ @apply mt-4;
113
+ }
114
+ ```
115
+
116
+ #### Handling Complex Cases
117
+
118
+ - **Responsive variants**: Keep complex responsive logic inline, abstract base styles
119
+ - **State variants**: Group base styles in @apply, keep interactive states inline when complex
120
+ - **Component variants**: Create separate classes for different component states
121
+
122
+ #### File Organization
123
+
124
+ - Place @apply styles in the same file as the `@import "tailwindcss";`
125
+ - Group related component styles together
126
+ - Use comments to organize sections
127
+ - Follow this structure:
128
+
129
+ ```css
130
+ @import "tailwindcss";
131
+
132
+ /* Base component styles */
133
+ .card {
134
+ /* ... */
135
+ }
136
+ .button {
137
+ /* ... */
138
+ }
139
+
140
+ /* Layout components */
141
+ .container {
142
+ /* ... */
143
+ }
144
+ .grid-layout {
145
+ /* ... */
146
+ }
147
+
148
+ /* Utility combinations */
149
+ .form-input {
150
+ /* ... */
151
+ }
152
+ .error-text {
153
+ /* ... */
154
+ }
155
+ ```
156
+
157
+ ### Conversion Examples
158
+
159
+ #### Before (inline classes):
160
+
161
+ ```html
162
+ <div
163
+ class="bg-white rounded-lg shadow-md p-6 border border-gray-200 hover:shadow-lg transition-shadow"
164
+ >
165
+ <h2 class="text-xl font-semibold text-gray-900 mb-4">Card Title</h2>
166
+ <p class="text-gray-600 leading-relaxed">Card content</p>
167
+ </div>
168
+ ```
169
+
170
+ #### After (with @apply and BEM):
171
+
172
+ ```css
173
+ .card {
174
+ @apply bg-white rounded-lg shadow-md p-6 border border-gray-200;
175
+ @apply hover:shadow-lg transition-shadow;
176
+ }
177
+
178
+ .card__title {
179
+ @apply text-xl font-semibold text-gray-900 mb-4;
180
+ }
181
+
182
+ .card__content {
183
+ @apply text-gray-600 leading-relaxed;
184
+ }
185
+ ```
186
+
187
+ ```html
188
+ <div class="card">
189
+ <h2 class="card__title">Card Title</h2>
190
+ <p class="card__content">Card content</p>
191
+ </div>
192
+ ```
193
+
194
+ ### Action Instructions
195
+
196
+ When converting (MANDATORY when asked):
197
+
198
+ 1. **Analyze the HTML/JSX** for component structure and hierarchy
199
+ 2. **Create BEM class names** following Block\_\_Element--Modifier pattern
200
+ 3. **Show the CSS @apply implementation** with proper BEM organization
201
+ 4. **Provide the updated HTML** with new BEM class names
202
+ 5. **Explain the BEM structure** and benefits of the conversion
203
+
204
+ Always prioritize:
205
+
206
+ - **BEM naming convention** (Block\_\_Element--Modifier)
207
+ - **Mandatory conversion** when user requests it
208
+ - **Component hierarchy** in naming structure
209
+ - **Logical grouping** of related properties in @apply statements
210
+ - **Semantic naming** that describes purpose and structure
211
+
212
+ ### TypeScript Integration
213
+
214
+ When working with TypeScript projects, consider:
215
+
216
+ - Type-safe class name patterns
217
+ - Component prop interfaces for style variants
218
+ - Utility types for consistent naming conventions