shru-design-system 0.1.0 → 0.1.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.
@@ -0,0 +1,675 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Design system init script
5
+ * Sets up Tailwind CSS and required configuration
6
+ * This file is part of the design system library
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const { execSync } = require('child_process');
12
+
13
+ // Get package name dynamically from package.json
14
+ function getPackageName() {
15
+ try {
16
+ const packageJsonPath = path.join(__dirname, '..', 'package.json');
17
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
18
+ return packageJson.name || 'shru-design-system';
19
+ } catch (error) {
20
+ // Fallback if package.json can't be read
21
+ return 'shru-design-system';
22
+ }
23
+ }
24
+
25
+ const PACKAGE_NAME = getPackageName();
26
+ const LIBRARY_NAME = `${PACKAGE_NAME} library`;
27
+
28
+ // Configuration constants
29
+ const TAILWIND_VERSION = '^3.4.0';
30
+
31
+ const colors = {
32
+ reset: '\x1b[0m',
33
+ green: '\x1b[32m',
34
+ yellow: '\x1b[33m',
35
+ blue: '\x1b[34m',
36
+ red: '\x1b[31m',
37
+ };
38
+
39
+ function log(message, color = 'reset') {
40
+ console.log(`${colors[color]}${message}${colors.reset}`);
41
+ }
42
+
43
+ function checkPackageInstalled(packageName) {
44
+ try {
45
+ require.resolve(packageName);
46
+ return true;
47
+ } catch {
48
+ return false;
49
+ }
50
+ }
51
+
52
+ function installPackage(packageName, isDev = true) {
53
+ log(`Installing ${packageName}...`, 'blue');
54
+ try {
55
+ execSync(`npm install ${isDev ? '-D' : ''} ${packageName}`, { stdio: 'inherit' });
56
+ return true;
57
+ } catch (error) {
58
+ log(`Failed to install ${packageName}`, 'red');
59
+ return false;
60
+ }
61
+ }
62
+
63
+ function createTailwindConfig() {
64
+ const configPath = path.join(process.cwd(), 'tailwind.config.js');
65
+
66
+ if (fs.existsSync(configPath)) {
67
+ log('tailwind.config.js already exists. Updating it...', 'yellow');
68
+ const existing = fs.readFileSync(configPath, 'utf8');
69
+
70
+ // Check if our config is already there
71
+ if (existing.includes(PACKAGE_NAME)) {
72
+ log(`Configuration already includes ${PACKAGE_NAME} setup.`, 'green');
73
+ return;
74
+ }
75
+
76
+ // Try to merge (basic approach - user might need to do this manually)
77
+ log('Please manually merge the Tailwind config. See docs for details.', 'yellow');
78
+ return;
79
+ }
80
+
81
+ const config = `/** @type {import('tailwindcss').Config} */
82
+ // This file was created by ${LIBRARY_NAME}
83
+ export default {
84
+ content: [
85
+ "./index.html",
86
+ "./src/**/*.{js,ts,jsx,tsx}",
87
+ "./node_modules/${PACKAGE_NAME}/dist/**/*.{js,mjs}",
88
+ ],
89
+ theme: {
90
+ extend: {
91
+ colors: {
92
+ background: "hsl(var(--background))",
93
+ foreground: "hsl(var(--foreground))",
94
+ primary: {
95
+ DEFAULT: "hsl(var(--primary))",
96
+ foreground: "hsl(var(--primary-foreground))",
97
+ },
98
+ secondary: {
99
+ DEFAULT: "hsl(var(--secondary))",
100
+ foreground: "hsl(var(--secondary-foreground))",
101
+ },
102
+ destructive: {
103
+ DEFAULT: "hsl(var(--destructive))",
104
+ foreground: "hsl(var(--destructive-foreground))",
105
+ },
106
+ muted: {
107
+ DEFAULT: "hsl(var(--muted))",
108
+ foreground: "hsl(var(--muted-foreground))",
109
+ },
110
+ accent: {
111
+ DEFAULT: "hsl(var(--accent))",
112
+ foreground: "hsl(var(--accent-foreground))",
113
+ },
114
+ popover: {
115
+ DEFAULT: "hsl(var(--popover))",
116
+ foreground: "hsl(var(--popover-foreground))",
117
+ },
118
+ border: "hsl(var(--border))",
119
+ input: "hsl(var(--input))",
120
+ ring: "hsl(var(--ring))",
121
+ },
122
+ borderRadius: {
123
+ lg: "var(--radius)",
124
+ md: "calc(var(--radius) - 2px)",
125
+ sm: "calc(var(--radius) - 4px)",
126
+ },
127
+ },
128
+ },
129
+ plugins: [],
130
+ }
131
+ `;
132
+
133
+ fs.writeFileSync(configPath, config);
134
+ log('Created tailwind.config.js', 'green');
135
+ }
136
+
137
+ function createPostCSSConfig() {
138
+ const configPath = path.join(process.cwd(), 'postcss.config.js');
139
+
140
+ if (fs.existsSync(configPath)) {
141
+ log('postcss.config.js already exists. Skipping...', 'yellow');
142
+ return;
143
+ }
144
+
145
+ const config = `// This file was created by ${LIBRARY_NAME}
146
+ export default {
147
+ plugins: {
148
+ tailwindcss: {},
149
+ autoprefixer: {},
150
+ },
151
+ }
152
+ `;
153
+
154
+ fs.writeFileSync(configPath, config);
155
+ log('Created postcss.config.js', 'green');
156
+ }
157
+
158
+ function createCSSFile() {
159
+ const cssPath = path.join(process.cwd(), 'src', 'index.css');
160
+ const cssDir = path.dirname(cssPath);
161
+
162
+ // Create src directory if it doesn't exist
163
+ if (!fs.existsSync(cssDir)) {
164
+ fs.mkdirSync(cssDir, { recursive: true });
165
+ }
166
+
167
+ if (fs.existsSync(cssPath)) {
168
+ log('src/index.css already exists. Checking if variables are defined...', 'yellow');
169
+ const existing = fs.readFileSync(cssPath, 'utf8');
170
+
171
+ if (existing.includes('--primary')) {
172
+ log('CSS variables already defined.', 'green');
173
+ return;
174
+ }
175
+
176
+ // Append to existing file
177
+ const cssVars = `
178
+
179
+ /* Design system CSS variables - Created by ${LIBRARY_NAME} */
180
+ @layer base {
181
+ :root {
182
+ --background: 0 0% 100%;
183
+ --foreground: 222.2 84% 4.9%;
184
+ --primary: 222.2 47.4% 11.2%;
185
+ --primary-foreground: 210 40% 98%;
186
+ --secondary: 210 40% 96.1%;
187
+ --secondary-foreground: 222.2 47.4% 11.2%;
188
+ --destructive: 0 84.2% 60.2%;
189
+ --destructive-foreground: 210 40% 98%;
190
+ --muted: 210 40% 96.1%;
191
+ --muted-foreground: 215.4 16.3% 46.9%;
192
+ --accent: 210 40% 96.1%;
193
+ --accent-foreground: 222.2 47.4% 11.2%;
194
+ --popover: 0 0% 100%;
195
+ --popover-foreground: 222.2 84% 4.9%;
196
+ --border: 214.3 31.8% 91.4%;
197
+ --input: 214.3 31.8% 91.4%;
198
+ --ring: 222.2 84% 4.9%;
199
+ --radius: 0.5rem;
200
+ }
201
+
202
+ * {
203
+ border-color: hsl(var(--border));
204
+ }
205
+
206
+ body {
207
+ background-color: hsl(var(--background));
208
+ color: hsl(var(--foreground));
209
+ }
210
+ }
211
+ `;
212
+ fs.appendFileSync(cssPath, cssVars);
213
+ log('Added CSS variables to existing index.css', 'green');
214
+ return;
215
+ }
216
+
217
+ const css = `@tailwind base;
218
+ @tailwind components;
219
+ @tailwind utilities;
220
+
221
+ /* This file was created by ${LIBRARY_NAME} */
222
+ @layer base {
223
+ :root {
224
+ --background: 0 0% 100%;
225
+ --foreground: 222.2 84% 4.9%;
226
+ --primary: 222.2 47.4% 11.2%;
227
+ --primary-foreground: 210 40% 98%;
228
+ --secondary: 210 40% 96.1%;
229
+ --secondary-foreground: 222.2 47.4% 11.2%;
230
+ --destructive: 0 84.2% 60.2%;
231
+ --destructive-foreground: 210 40% 98%;
232
+ --muted: 210 40% 96.1%;
233
+ --muted-foreground: 215.4 16.3% 46.9%;
234
+ --accent: 210 40% 96.1%;
235
+ --accent-foreground: 222.2 47.4% 11.2%;
236
+ --popover: 0 0% 100%;
237
+ --popover-foreground: 222.2 84% 4.9%;
238
+ --border: 214.3 31.8% 91.4%;
239
+ --input: 214.3 31.8% 91.4%;
240
+ --ring: 222.2 84% 4.9%;
241
+ --radius: 0.5rem;
242
+ }
243
+
244
+ * {
245
+ border-color: hsl(var(--border));
246
+ }
247
+
248
+ body {
249
+ background-color: hsl(var(--background));
250
+ color: hsl(var(--foreground));
251
+ }
252
+ }
253
+ `;
254
+
255
+ fs.writeFileSync(cssPath, css);
256
+ log('Created src/index.css', 'green');
257
+ }
258
+
259
+ function createTokenFiles() {
260
+ const publicDir = path.join(process.cwd(), 'public');
261
+ const tokensDir = path.join(publicDir, 'tokens');
262
+ const themesDir = path.join(tokensDir, 'themes');
263
+
264
+ // Create directories
265
+ if (!fs.existsSync(publicDir)) {
266
+ fs.mkdirSync(publicDir, { recursive: true });
267
+ }
268
+ if (!fs.existsSync(tokensDir)) {
269
+ fs.mkdirSync(tokensDir, { recursive: true });
270
+ }
271
+ if (!fs.existsSync(themesDir)) {
272
+ fs.mkdirSync(themesDir, { recursive: true });
273
+ }
274
+
275
+ // Create base.json
276
+ const basePath = path.join(tokensDir, 'base.json');
277
+ if (!fs.existsSync(basePath)) {
278
+ const baseJson = {
279
+ "_createdBy": LIBRARY_NAME,
280
+ "color": {
281
+ "primary": "{palette.blue.500}",
282
+ "primary-hover": "{palette.blue.600}",
283
+ "primary-foreground": "{palette.white}",
284
+ "secondary": "{palette.gray.100}",
285
+ "secondary-foreground": "{palette.gray.900}",
286
+ "background": "{palette.white}",
287
+ "foreground": "{palette.gray.900}",
288
+ "card": "{palette.white}",
289
+ "card-foreground": "{palette.gray.900}",
290
+ "popover": "{palette.white}",
291
+ "popover-foreground": "{palette.gray.900}",
292
+ "muted": "{palette.gray.100}",
293
+ "muted-foreground": "{palette.gray.500}",
294
+ "accent": "{palette.gray.100}",
295
+ "accent-foreground": "{palette.gray.900}",
296
+ "destructive": "{palette.red.500}",
297
+ "destructive-foreground": "{palette.white}",
298
+ "border": "{palette.gray.200}",
299
+ "input": "{palette.gray.200}",
300
+ "ring": "{palette.gray.400}",
301
+ "skeleton": "{palette.gray.200}"
302
+ },
303
+ "spacing": {
304
+ "component": {
305
+ "xs": "0.25rem",
306
+ "sm": "0.5rem",
307
+ "md": "1rem",
308
+ "lg": "1.5rem",
309
+ "xl": "2rem"
310
+ },
311
+ "base": "0.25rem"
312
+ },
313
+ "typography": {
314
+ "font": {
315
+ "body": "var(--font-sans)",
316
+ "sans": "var(--font-sans)",
317
+ "mono": "var(--font-mono)"
318
+ }
319
+ },
320
+ "shape": {
321
+ "radius": {
322
+ "button": "0.375rem",
323
+ "card": "0.5rem",
324
+ "input": "0.375rem"
325
+ }
326
+ }
327
+ };
328
+ fs.writeFileSync(basePath, JSON.stringify(baseJson, null, 2));
329
+ log('Created public/tokens/base.json', 'green');
330
+ } else {
331
+ log('public/tokens/base.json already exists. Skipping...', 'yellow');
332
+ }
333
+
334
+ // Create palettes.json
335
+ const palettesPath = path.join(tokensDir, 'palettes.json');
336
+ if (!fs.existsSync(palettesPath)) {
337
+ const palettesJson = {
338
+ "_createdBy": LIBRARY_NAME,
339
+ "palette": {
340
+ "white": "#ffffff",
341
+ "black": "#000000",
342
+ "transparent": "transparent",
343
+ "gray": {
344
+ "50": "#f9fafb",
345
+ "100": "#f3f4f6",
346
+ "200": "#e5e7eb",
347
+ "300": "#d1d5db",
348
+ "400": "#9ca3af",
349
+ "500": "#6b7280",
350
+ "600": "#4b5563",
351
+ "700": "#374151",
352
+ "800": "#1f2937",
353
+ "900": "#111827",
354
+ "950": "#030712"
355
+ },
356
+ "blue": {
357
+ "50": "#eff6ff",
358
+ "100": "#dbeafe",
359
+ "200": "#bfdbfe",
360
+ "300": "#93c5fd",
361
+ "400": "#60a5fa",
362
+ "500": "#3b82f6",
363
+ "600": "#2563eb",
364
+ "700": "#1d4ed8",
365
+ "800": "#1e40af",
366
+ "900": "#1e3a8a",
367
+ "950": "#172554"
368
+ },
369
+ "red": {
370
+ "50": "#fef2f2",
371
+ "100": "#fee2e2",
372
+ "200": "#fecaca",
373
+ "300": "#fca5a5",
374
+ "400": "#f87171",
375
+ "500": "#ef4444",
376
+ "600": "#dc2626",
377
+ "700": "#b91c1c",
378
+ "800": "#991b1b",
379
+ "900": "#7f1d1d",
380
+ "950": "#450a0a"
381
+ }
382
+ }
383
+ };
384
+ fs.writeFileSync(palettesPath, JSON.stringify(palettesJson, null, 2));
385
+ log('Created public/tokens/palettes.json', 'green');
386
+ } else {
387
+ log('public/tokens/palettes.json already exists. Skipping...', 'yellow');
388
+ }
389
+
390
+ // Create theme directories and files
391
+ const themeCategories = ['color', 'typography', 'shape', 'density', 'animation', 'custom'];
392
+
393
+ themeCategories.forEach(category => {
394
+ const categoryDir = path.join(themesDir, category);
395
+ if (!fs.existsSync(categoryDir)) {
396
+ fs.mkdirSync(categoryDir, { recursive: true });
397
+ }
398
+ });
399
+
400
+ // Create color/white.json
401
+ const whiteThemePath = path.join(themesDir, 'color', 'white.json');
402
+ if (!fs.existsSync(whiteThemePath)) {
403
+ const whiteTheme = {
404
+ "_createdBy": LIBRARY_NAME,
405
+ "color": {
406
+ "primary": "{palette.blue.500}",
407
+ "primary-foreground": "{palette.white}",
408
+ "background": "{palette.white}",
409
+ "foreground": "{palette.gray.900}",
410
+ "card": "{palette.white}",
411
+ "card-foreground": "{palette.gray.900}",
412
+ "popover": "{palette.white}",
413
+ "popover-foreground": "{palette.gray.900}",
414
+ "secondary": "{palette.gray.100}",
415
+ "secondary-foreground": "{palette.gray.900}",
416
+ "muted": "{palette.gray.100}",
417
+ "muted-foreground": "{palette.gray.500}",
418
+ "accent": "{palette.gray.100}",
419
+ "accent-foreground": "{palette.gray.900}",
420
+ "destructive": "{palette.red.500}",
421
+ "destructive-foreground": "{palette.white}",
422
+ "border": "{palette.gray.200}",
423
+ "input": "{palette.gray.200}",
424
+ "ring": "{palette.gray.400}",
425
+ "skeleton": "{palette.gray.200}"
426
+ }
427
+ };
428
+ fs.writeFileSync(whiteThemePath, JSON.stringify(whiteTheme, null, 2));
429
+ log('Created public/tokens/themes/color/white.json', 'green');
430
+ }
431
+
432
+ // Create color/dark.json
433
+ const darkThemePath = path.join(themesDir, 'color', 'dark.json');
434
+ if (!fs.existsSync(darkThemePath)) {
435
+ const darkTheme = {
436
+ "_createdBy": LIBRARY_NAME,
437
+ "color": {
438
+ "primary": "{palette.blue.400}",
439
+ "primary-foreground": "{palette.gray.900}",
440
+ "background": "{palette.gray.900}",
441
+ "foreground": "{palette.gray.50}",
442
+ "card": "{palette.gray.800}",
443
+ "card-foreground": "{palette.gray.50}",
444
+ "popover": "{palette.gray.800}",
445
+ "popover-foreground": "{palette.gray.50}",
446
+ "secondary": "{palette.gray.800}",
447
+ "secondary-foreground": "{palette.gray.50}",
448
+ "muted": "{palette.gray.800}",
449
+ "muted-foreground": "{palette.gray.400}",
450
+ "accent": "{palette.gray.800}",
451
+ "accent-foreground": "{palette.gray.50}",
452
+ "destructive": "{palette.red.500}",
453
+ "destructive-foreground": "{palette.white}",
454
+ "border": "{palette.gray.700}",
455
+ "input": "{palette.gray.700}",
456
+ "ring": "{palette.gray.600}",
457
+ "skeleton": "{palette.gray.700}"
458
+ }
459
+ };
460
+ fs.writeFileSync(darkThemePath, JSON.stringify(darkTheme, null, 2));
461
+ log('Created public/tokens/themes/color/dark.json', 'green');
462
+ }
463
+
464
+ // Create typography/sans.json
465
+ const sansThemePath = path.join(themesDir, 'typography', 'sans.json');
466
+ if (!fs.existsSync(sansThemePath)) {
467
+ const sansTheme = {
468
+ "_createdBy": LIBRARY_NAME,
469
+ "typography": {
470
+ "font": {
471
+ "body": "system-ui, -apple-system, sans-serif",
472
+ "sans": "system-ui, -apple-system, sans-serif"
473
+ }
474
+ }
475
+ };
476
+ fs.writeFileSync(sansThemePath, JSON.stringify(sansTheme, null, 2));
477
+ log('Created public/tokens/themes/typography/sans.json', 'green');
478
+ }
479
+
480
+ // Create typography/serif.json
481
+ const serifThemePath = path.join(themesDir, 'typography', 'serif.json');
482
+ if (!fs.existsSync(serifThemePath)) {
483
+ const serifTheme = {
484
+ "_createdBy": LIBRARY_NAME,
485
+ "typography": {
486
+ "font": {
487
+ "body": "Georgia, serif",
488
+ "sans": "Georgia, serif"
489
+ }
490
+ }
491
+ };
492
+ fs.writeFileSync(serifThemePath, JSON.stringify(serifTheme, null, 2));
493
+ log('Created public/tokens/themes/typography/serif.json', 'green');
494
+ }
495
+
496
+ // Create shape/smooth.json
497
+ const smoothThemePath = path.join(themesDir, 'shape', 'smooth.json');
498
+ if (!fs.existsSync(smoothThemePath)) {
499
+ const smoothTheme = {
500
+ "_createdBy": LIBRARY_NAME,
501
+ "shape": {
502
+ "radius": {
503
+ "button": "0.5rem",
504
+ "card": "0.75rem",
505
+ "input": "0.5rem"
506
+ }
507
+ }
508
+ };
509
+ fs.writeFileSync(smoothThemePath, JSON.stringify(smoothTheme, null, 2));
510
+ log('Created public/tokens/themes/shape/smooth.json', 'green');
511
+ }
512
+
513
+ // Create shape/sharp.json
514
+ const sharpThemePath = path.join(themesDir, 'shape', 'sharp.json');
515
+ if (!fs.existsSync(sharpThemePath)) {
516
+ const sharpTheme = {
517
+ "_createdBy": LIBRARY_NAME,
518
+ "shape": {
519
+ "radius": {
520
+ "button": "0",
521
+ "card": "0",
522
+ "input": "0"
523
+ }
524
+ }
525
+ };
526
+ fs.writeFileSync(sharpThemePath, JSON.stringify(sharpTheme, null, 2));
527
+ log('Created public/tokens/themes/shape/sharp.json', 'green');
528
+ }
529
+
530
+ // Create density/comfortable.json
531
+ const comfortableThemePath = path.join(themesDir, 'density', 'comfortable.json');
532
+ if (!fs.existsSync(comfortableThemePath)) {
533
+ const comfortableTheme = {
534
+ "_createdBy": LIBRARY_NAME,
535
+ "spacing": {
536
+ "component": {
537
+ "xs": "0.5rem",
538
+ "sm": "0.75rem",
539
+ "md": "1.25rem",
540
+ "lg": "2rem",
541
+ "xl": "2.5rem"
542
+ }
543
+ }
544
+ };
545
+ fs.writeFileSync(comfortableThemePath, JSON.stringify(comfortableTheme, null, 2));
546
+ log('Created public/tokens/themes/density/comfortable.json', 'green');
547
+ }
548
+
549
+ // Create density/compact.json
550
+ const compactThemePath = path.join(themesDir, 'density', 'compact.json');
551
+ if (!fs.existsSync(compactThemePath)) {
552
+ const compactTheme = {
553
+ "_createdBy": LIBRARY_NAME,
554
+ "spacing": {
555
+ "component": {
556
+ "xs": "0.25rem",
557
+ "sm": "0.5rem",
558
+ "md": "0.75rem",
559
+ "lg": "1rem",
560
+ "xl": "1.5rem"
561
+ }
562
+ }
563
+ };
564
+ fs.writeFileSync(compactThemePath, JSON.stringify(compactTheme, null, 2));
565
+ log('Created public/tokens/themes/density/compact.json', 'green');
566
+ }
567
+
568
+ // Create animation/gentle.json
569
+ const gentleThemePath = path.join(themesDir, 'animation', 'gentle.json');
570
+ if (!fs.existsSync(gentleThemePath)) {
571
+ const gentleTheme = {
572
+ "_createdBy": LIBRARY_NAME,
573
+ "animation": {
574
+ "duration": {
575
+ "fast": "150ms",
576
+ "normal": "300ms",
577
+ "slow": "500ms"
578
+ }
579
+ }
580
+ };
581
+ fs.writeFileSync(gentleThemePath, JSON.stringify(gentleTheme, null, 2));
582
+ log('Created public/tokens/themes/animation/gentle.json', 'green');
583
+ }
584
+
585
+ // Create animation/brisk.json
586
+ const briskThemePath = path.join(themesDir, 'animation', 'brisk.json');
587
+ if (!fs.existsSync(briskThemePath)) {
588
+ const briskTheme = {
589
+ "_createdBy": LIBRARY_NAME,
590
+ "animation": {
591
+ "duration": {
592
+ "fast": "100ms",
593
+ "normal": "200ms",
594
+ "slow": "300ms"
595
+ }
596
+ }
597
+ };
598
+ fs.writeFileSync(briskThemePath, JSON.stringify(briskTheme, null, 2));
599
+ log('Created public/tokens/themes/animation/brisk.json', 'green');
600
+ }
601
+ }
602
+
603
+ function checkMainFile() {
604
+ const possiblePaths = [
605
+ path.join(process.cwd(), 'src', 'main.tsx'),
606
+ path.join(process.cwd(), 'src', 'main.ts'),
607
+ path.join(process.cwd(), 'src', 'index.tsx'),
608
+ path.join(process.cwd(), 'src', 'index.ts'),
609
+ path.join(process.cwd(), 'src', 'App.tsx'),
610
+ ];
611
+
612
+ for (const filePath of possiblePaths) {
613
+ if (fs.existsSync(filePath)) {
614
+ const content = fs.readFileSync(filePath, 'utf8');
615
+ if (!content.includes("index.css") && !content.includes("'./index.css'")) {
616
+ log(`\n⚠️ Don't forget to import the CSS file in your entry point:`, 'yellow');
617
+ log(` import './index.css'`, 'blue');
618
+ log(` Add this to: ${filePath}\n`, 'yellow');
619
+ } else {
620
+ log('CSS import found in entry file.', 'green');
621
+ }
622
+ return;
623
+ }
624
+ }
625
+
626
+ log('\n⚠️ Could not find entry file. Please manually import:', 'yellow');
627
+ log(" import './index.css'", 'blue');
628
+ }
629
+
630
+ // Main execution
631
+ function main() {
632
+ log(`\n🚀 Setting up ${PACKAGE_NAME}...\n`, 'blue');
633
+
634
+ // Check and install Tailwind
635
+ if (!checkPackageInstalled('tailwindcss')) {
636
+ log('Tailwind CSS not found. Installing...', 'yellow');
637
+ if (!installPackage(`tailwindcss@${TAILWIND_VERSION}`)) {
638
+ log('Failed to install Tailwind CSS. Please install manually.', 'red');
639
+ process.exit(1);
640
+ }
641
+ } else {
642
+ log('Tailwind CSS already installed.', 'green');
643
+ }
644
+
645
+ // Check and install PostCSS
646
+ if (!checkPackageInstalled('postcss')) {
647
+ installPackage('postcss');
648
+ }
649
+
650
+ // Check and install Autoprefixer
651
+ if (!checkPackageInstalled('autoprefixer')) {
652
+ installPackage('autoprefixer');
653
+ }
654
+
655
+ // Create configuration files
656
+ createTailwindConfig();
657
+ createPostCSSConfig();
658
+ createCSSFile();
659
+ createTokenFiles();
660
+ checkMainFile();
661
+
662
+ log('\n✅ Setup complete!', 'green');
663
+ log('\nNext steps:', 'blue');
664
+ log('1. Make sure to import the CSS file in your entry point:', 'yellow');
665
+ log(" import './index.css'", 'blue');
666
+ log('2. Start using components:', 'yellow');
667
+ log(` import { Button, ThemeToggle } from '${PACKAGE_NAME}'`, 'blue');
668
+ log('\n💡 Custom Token Files:', 'blue');
669
+ log(' You can add custom theme files to public/tokens/themes/{category}/', 'yellow');
670
+ log(' Example: public/tokens/themes/color/ocean.json', 'blue');
671
+ log(' The ThemeToggle will automatically discover and use them.', 'blue');
672
+ log('\n');
673
+ }
674
+
675
+ main();