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.
- package/README.md +154 -29
- package/dist/index.d.mts +101 -1
- package/dist/index.d.ts +101 -1
- package/dist/index.js +855 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +844 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -13
- package/scripts/init.js +675 -0
package/scripts/init.js
ADDED
|
@@ -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();
|