swatchkit 0.0.14 → 0.0.16
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/build.js +104 -93
- package/package.json +1 -1
- package/src/layout.html +4 -5
package/build.js
CHANGED
|
@@ -74,22 +74,22 @@ function matchesGlob(filename, pattern) {
|
|
|
74
74
|
const parts = pattern.split("*");
|
|
75
75
|
// Handle "foo*"
|
|
76
76
|
if (pattern.endsWith("*") && !pattern.startsWith("*")) {
|
|
77
|
-
|
|
77
|
+
return filename.startsWith(parts[0]);
|
|
78
78
|
}
|
|
79
79
|
// Handle "*bar"
|
|
80
80
|
if (pattern.startsWith("*") && !pattern.endsWith("*")) {
|
|
81
|
-
|
|
81
|
+
return filename.endsWith(parts[1]);
|
|
82
82
|
}
|
|
83
83
|
// Handle "*bar*"
|
|
84
84
|
if (pattern.startsWith("*") && pattern.endsWith("*")) {
|
|
85
|
-
|
|
85
|
+
return filename.includes(parts[1]);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
return filename === pattern;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
function toTitleCase(str) {
|
|
92
|
-
return str.replace(/-/g,
|
|
92
|
+
return str.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
// --- 3. Smart Defaults & Path Resolution ---
|
|
@@ -127,7 +127,7 @@ function resolveSettings(cliOptions, fileConfig) {
|
|
|
127
127
|
const tokensDir = fileConfig.tokens?.input
|
|
128
128
|
? path.resolve(cwd, fileConfig.tokens.input)
|
|
129
129
|
: path.join(swatchkitDir, "tokens");
|
|
130
|
-
|
|
130
|
+
|
|
131
131
|
// Exclude patterns
|
|
132
132
|
const exclude = fileConfig.exclude || [];
|
|
133
133
|
|
|
@@ -180,87 +180,87 @@ function runInit(settings, options) {
|
|
|
180
180
|
const copyDefault = (srcFilename, destFilename) => {
|
|
181
181
|
const destPath = path.join(tokensDir, destFilename);
|
|
182
182
|
if (!fs.existsSync(destPath)) {
|
|
183
|
-
const srcPath = path.join(__dirname,
|
|
184
|
-
const content = fs.readFileSync(srcPath,
|
|
183
|
+
const srcPath = path.join(__dirname, "src/blueprints", srcFilename);
|
|
184
|
+
const content = fs.readFileSync(srcPath, "utf-8");
|
|
185
185
|
fs.writeFileSync(destPath, content);
|
|
186
186
|
console.log(`Created token file at ${destPath}`);
|
|
187
187
|
}
|
|
188
188
|
};
|
|
189
189
|
|
|
190
190
|
// 1. Create Colors Token
|
|
191
|
-
copyDefault(
|
|
191
|
+
copyDefault("colors.json", "colors.json");
|
|
192
192
|
|
|
193
193
|
// 2. Create Text Weights Token
|
|
194
|
-
copyDefault(
|
|
194
|
+
copyDefault("text-weights.json", "text-weights.json");
|
|
195
195
|
|
|
196
196
|
// 3. Create Text Leading Token
|
|
197
|
-
copyDefault(
|
|
197
|
+
copyDefault("text-leading.json", "text-leading.json");
|
|
198
198
|
|
|
199
199
|
// 4. Create Viewports Token
|
|
200
|
-
copyDefault(
|
|
200
|
+
copyDefault("viewports.json", "viewports.json");
|
|
201
201
|
|
|
202
202
|
// 5. Create Text Sizes Token (Fluid)
|
|
203
|
-
copyDefault(
|
|
203
|
+
copyDefault("text-sizes.json", "text-sizes.json");
|
|
204
204
|
|
|
205
205
|
// 6. Create Spacing Token
|
|
206
|
-
copyDefault(
|
|
206
|
+
copyDefault("spacing.json", "spacing.json");
|
|
207
207
|
|
|
208
208
|
// 7. Create Fonts Token
|
|
209
|
-
copyDefault(
|
|
209
|
+
copyDefault("fonts.json", "fonts.json");
|
|
210
210
|
|
|
211
211
|
const copyTemplate = (srcFilename, destFilename) => {
|
|
212
212
|
const destPath = path.join(tokensDir, destFilename);
|
|
213
213
|
if (!fs.existsSync(destPath)) {
|
|
214
|
-
const srcPath = path.join(__dirname,
|
|
215
|
-
const content = fs.readFileSync(srcPath,
|
|
214
|
+
const srcPath = path.join(__dirname, "src/templates", srcFilename);
|
|
215
|
+
const content = fs.readFileSync(srcPath, "utf-8");
|
|
216
216
|
fs.writeFileSync(destPath, content.trim());
|
|
217
217
|
console.log(`Created pattern at ${destPath}`);
|
|
218
218
|
}
|
|
219
219
|
};
|
|
220
220
|
|
|
221
221
|
// Create sample patterns
|
|
222
|
-
copyTemplate(
|
|
223
|
-
copyTemplate(
|
|
224
|
-
copyTemplate(
|
|
225
|
-
copyTemplate(
|
|
226
|
-
copyTemplate(
|
|
227
|
-
copyTemplate(
|
|
222
|
+
copyTemplate("colors.html", "colors.html");
|
|
223
|
+
copyTemplate("text-weights.html", "text-weights.html");
|
|
224
|
+
copyTemplate("text-leading.html", "text-leading.html");
|
|
225
|
+
copyTemplate("typography.html", "typography.html");
|
|
226
|
+
copyTemplate("spacing.html", "spacing.html");
|
|
227
|
+
copyTemplate("fonts.html", "fonts.html");
|
|
228
228
|
|
|
229
229
|
// Create shared script for tokens
|
|
230
230
|
const tokensScriptFile = path.join(tokensDir, "script.js");
|
|
231
231
|
if (!fs.existsSync(tokensScriptFile)) {
|
|
232
|
-
const srcPath = path.join(__dirname,
|
|
233
|
-
const content = fs.readFileSync(srcPath,
|
|
232
|
+
const srcPath = path.join(__dirname, "src/templates/script.js");
|
|
233
|
+
const content = fs.readFileSync(srcPath, "utf-8");
|
|
234
234
|
fs.writeFileSync(tokensScriptFile, content.trim());
|
|
235
235
|
console.log(`Created tokens script at ${tokensScriptFile}`);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
// Create starter styles.css
|
|
239
239
|
if (!fs.existsSync(settings.stylesCssFile)) {
|
|
240
|
-
const srcPath = path.join(__dirname,
|
|
241
|
-
const content = fs.readFileSync(srcPath,
|
|
240
|
+
const srcPath = path.join(__dirname, "src/blueprints/styles.css");
|
|
241
|
+
const content = fs.readFileSync(srcPath, "utf-8");
|
|
242
242
|
fs.writeFileSync(settings.stylesCssFile, content);
|
|
243
243
|
console.log(`Created starter stylesheet at ${settings.stylesCssFile}`);
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
// Copy CSS Reset
|
|
247
|
-
const resetSrc = path.join(__dirname,
|
|
248
|
-
const resetDest = path.join(settings.cssDir,
|
|
247
|
+
const resetSrc = path.join(__dirname, "src/blueprints/reset.css");
|
|
248
|
+
const resetDest = path.join(settings.cssDir, "reset.css");
|
|
249
249
|
if (fs.existsSync(resetSrc) && !fs.existsSync(resetDest)) {
|
|
250
250
|
fs.copyFileSync(resetSrc, resetDest);
|
|
251
251
|
console.log(`Created CSS reset at ${resetDest}`);
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
// Copy Compositions
|
|
255
|
-
const compositionsSrc = path.join(__dirname,
|
|
256
|
-
const compositionsDest = path.join(settings.cssDir,
|
|
255
|
+
const compositionsSrc = path.join(__dirname, "src/blueprints/compositions");
|
|
256
|
+
const compositionsDest = path.join(settings.cssDir, "compositions");
|
|
257
257
|
if (fs.existsSync(compositionsSrc)) {
|
|
258
|
-
|
|
258
|
+
copyDir(compositionsSrc, compositionsDest);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
261
|
// Copy SwatchKit UI Styles
|
|
262
|
-
const uiSrc = path.join(__dirname,
|
|
263
|
-
const uiDest = path.join(settings.cssDir,
|
|
262
|
+
const uiSrc = path.join(__dirname, "src/blueprints/swatchkit-ui.css");
|
|
263
|
+
const uiDest = path.join(settings.cssDir, "swatchkit-ui.css");
|
|
264
264
|
if (fs.existsSync(uiSrc) && !fs.existsSync(uiDest)) {
|
|
265
265
|
fs.copyFileSync(uiSrc, uiDest);
|
|
266
266
|
console.log(`Created UI styles at ${uiDest}`);
|
|
@@ -317,7 +317,7 @@ function scanSwatches(dir, scriptsCollector, exclude = []) {
|
|
|
317
317
|
|
|
318
318
|
items.forEach((item) => {
|
|
319
319
|
// Skip excluded items
|
|
320
|
-
if (exclude.some(pattern => matchesGlob(item, pattern))) return;
|
|
320
|
+
if (exclude.some((pattern) => matchesGlob(item, pattern))) return;
|
|
321
321
|
|
|
322
322
|
// Skip _layout.html or hidden files
|
|
323
323
|
if (item.startsWith("_") || item.startsWith(".")) return;
|
|
@@ -420,58 +420,66 @@ function build(settings) {
|
|
|
420
420
|
const exclude = settings.exclude || [];
|
|
421
421
|
|
|
422
422
|
// Scan subdirectories (Sections)
|
|
423
|
-
items.forEach(item => {
|
|
424
|
-
if (exclude.some(p => matchesGlob(item, p))) return;
|
|
423
|
+
items.forEach((item) => {
|
|
424
|
+
if (exclude.some((p) => matchesGlob(item, p))) return;
|
|
425
425
|
if (item.startsWith(".") || item.startsWith("_")) return;
|
|
426
426
|
|
|
427
427
|
const itemPath = path.join(settings.swatchkitDir, item);
|
|
428
428
|
if (fs.lstatSync(itemPath).isDirectory()) {
|
|
429
429
|
const hasIndex = fs.existsSync(path.join(itemPath, "index.html"));
|
|
430
|
-
|
|
430
|
+
|
|
431
431
|
if (!hasIndex) {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
432
|
+
// It is a Section Container (e.g. "Utilities")
|
|
433
|
+
const sectionName =
|
|
434
|
+
item === "tokens" ? "Design Tokens" : toTitleCase(item);
|
|
435
|
+
const swatches = scanSwatches(itemPath, scripts, exclude);
|
|
436
|
+
if (swatches.length > 0) {
|
|
437
|
+
sections[sectionName] = swatches;
|
|
438
|
+
}
|
|
438
439
|
}
|
|
439
440
|
}
|
|
440
441
|
});
|
|
441
442
|
|
|
442
443
|
// Scan root swatches (Files + Component Folders at root)
|
|
443
444
|
const rootSwatches = [];
|
|
444
|
-
items.forEach(item => {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
445
|
+
items.forEach((item) => {
|
|
446
|
+
if (exclude.some((p) => matchesGlob(item, p))) return;
|
|
447
|
+
if (item.startsWith(".") || item.startsWith("_")) return;
|
|
448
|
+
|
|
449
|
+
const itemPath = path.join(settings.swatchkitDir, item);
|
|
450
|
+
const stat = fs.statSync(itemPath);
|
|
451
|
+
|
|
452
|
+
if (stat.isFile() && item.endsWith(".html")) {
|
|
453
|
+
const name = path.basename(item, ".html");
|
|
454
|
+
const content = fs.readFileSync(itemPath, "utf-8");
|
|
455
|
+
rootSwatches.push({ name, id: name, content });
|
|
456
|
+
} else if (stat.isDirectory()) {
|
|
457
|
+
const indexFile = path.join(itemPath, "index.html");
|
|
458
|
+
if (fs.existsSync(indexFile)) {
|
|
459
|
+
// Component folder swatch at root
|
|
460
|
+
const name = item;
|
|
461
|
+
const content = fs.readFileSync(indexFile, "utf-8");
|
|
462
|
+
rootSwatches.push({ name, id: name, content });
|
|
463
|
+
|
|
464
|
+
// Collect JS
|
|
465
|
+
const jsFiles = fs
|
|
466
|
+
.readdirSync(itemPath)
|
|
467
|
+
.filter((f) => f.endsWith(".js"));
|
|
468
|
+
jsFiles.forEach((jsFile) => {
|
|
469
|
+
const scriptContent = fs.readFileSync(
|
|
470
|
+
path.join(itemPath, jsFile),
|
|
471
|
+
"utf-8",
|
|
472
|
+
);
|
|
473
|
+
scripts.push(
|
|
474
|
+
`/* ${name}/${jsFile} */ (function(){${scriptContent}})();`,
|
|
475
|
+
);
|
|
476
|
+
});
|
|
470
477
|
}
|
|
478
|
+
}
|
|
471
479
|
});
|
|
472
|
-
|
|
480
|
+
|
|
473
481
|
if (rootSwatches.length > 0) {
|
|
474
|
-
|
|
482
|
+
sections["Patterns"] = rootSwatches;
|
|
475
483
|
}
|
|
476
484
|
}
|
|
477
485
|
|
|
@@ -483,38 +491,41 @@ function build(settings) {
|
|
|
483
491
|
|
|
484
492
|
// Helper to sort sections: Tokens first, then A-Z, Patterns last
|
|
485
493
|
const sortedKeys = Object.keys(sections).sort((a, b) => {
|
|
486
|
-
if (a ===
|
|
487
|
-
if (b ===
|
|
488
|
-
if (a ===
|
|
489
|
-
if (b ===
|
|
494
|
+
if (a === "Design Tokens") return -1;
|
|
495
|
+
if (b === "Design Tokens") return 1;
|
|
496
|
+
if (a === "Patterns") return 1;
|
|
497
|
+
if (b === "Patterns") return -1;
|
|
490
498
|
return a.localeCompare(b);
|
|
491
499
|
});
|
|
492
500
|
|
|
493
|
-
sortedKeys.forEach(section => {
|
|
501
|
+
sortedKeys.forEach((section) => {
|
|
494
502
|
const swatches = sections[section];
|
|
495
503
|
sidebarLinks += `<h3>${section}</h3>\n`;
|
|
504
|
+
sidebarLinks += `<ul role="list">\n`;
|
|
496
505
|
sidebarLinks += swatches
|
|
497
|
-
.map((p) =>
|
|
506
|
+
.map((p) => ` <li><a href="#${p.id}">${p.name}</a></li>`)
|
|
498
507
|
.join("\n");
|
|
499
|
-
sidebarLinks += `\n`;
|
|
508
|
+
sidebarLinks += `\n</ul>\n`;
|
|
500
509
|
|
|
501
510
|
// Generate Blocks
|
|
502
|
-
swatchBlocks += swatches
|
|
503
|
-
|
|
504
|
-
.
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
+
swatchBlocks += swatches
|
|
512
|
+
.map((p) => {
|
|
513
|
+
const escapedContent = p.content
|
|
514
|
+
.replace(/&/g, "&")
|
|
515
|
+
.replace(/</g, "<")
|
|
516
|
+
.replace(/>/g, ">")
|
|
517
|
+
.replace(/"/g, """)
|
|
518
|
+
.replace(/'/g, "'");
|
|
519
|
+
|
|
520
|
+
return `
|
|
511
521
|
<section id="${p.id}">
|
|
512
522
|
<h2>${p.name} <small style="font-weight: normal; opacity: 0.6; font-size: 0.7em">(${section})</small></h2>
|
|
513
523
|
<div class="preview">${p.content}</div>
|
|
514
524
|
<pre><code>${escapedContent}</code></pre>
|
|
515
525
|
</section>
|
|
516
526
|
`;
|
|
517
|
-
|
|
527
|
+
})
|
|
528
|
+
.join("\n");
|
|
518
529
|
});
|
|
519
530
|
|
|
520
531
|
// 6. Write JS Bundle
|
|
@@ -557,12 +568,12 @@ function watch(settings) {
|
|
|
557
568
|
settings.swatchkitDir,
|
|
558
569
|
settings.tokensDir,
|
|
559
570
|
settings.projectLayout,
|
|
560
|
-
settings.stylesCssFile
|
|
561
|
-
].filter(p => fs.existsSync(p)); // Only watch files that exist
|
|
571
|
+
settings.stylesCssFile,
|
|
572
|
+
].filter((p) => fs.existsSync(p)); // Only watch files that exist
|
|
562
573
|
|
|
563
574
|
console.log("[SwatchKit] Watch mode enabled.");
|
|
564
575
|
console.log("Watching for changes in:");
|
|
565
|
-
watchPaths.forEach(p => console.log(` - ${p}`));
|
|
576
|
+
watchPaths.forEach((p) => console.log(` - ${p}`));
|
|
566
577
|
|
|
567
578
|
let buildTimeout;
|
|
568
579
|
const rebuild = () => {
|
|
@@ -580,10 +591,10 @@ function watch(settings) {
|
|
|
580
591
|
const watcher = chokidar.watch(watchPaths, {
|
|
581
592
|
ignored: /(^|[\/\\])\../, // ignore dotfiles
|
|
582
593
|
persistent: true,
|
|
583
|
-
ignoreInitial: true
|
|
594
|
+
ignoreInitial: true,
|
|
584
595
|
});
|
|
585
596
|
|
|
586
|
-
watcher.on(
|
|
597
|
+
watcher.on("all", (event, path) => {
|
|
587
598
|
rebuild();
|
|
588
599
|
});
|
|
589
600
|
}
|
package/package.json
CHANGED
package/src/layout.html
CHANGED
|
@@ -9,18 +9,17 @@
|
|
|
9
9
|
<!-- HEAD_EXTRAS -->
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
|
-
<div class="sidebar">
|
|
13
|
-
<nav class="
|
|
12
|
+
<div class="sidebar wrapper">
|
|
13
|
+
<nav class="flow">
|
|
14
14
|
<header>
|
|
15
|
-
|
|
15
|
+
<h2>SwatchKit</h2>
|
|
16
16
|
</header>
|
|
17
17
|
<!-- SIDEBAR_LINKS -->
|
|
18
18
|
</nav>
|
|
19
|
-
<main class="
|
|
19
|
+
<main class="flow">
|
|
20
20
|
<!-- SWATCHES -->
|
|
21
21
|
</main>
|
|
22
22
|
</div>
|
|
23
23
|
<script src="js/swatches.js"></script>
|
|
24
24
|
</body>
|
|
25
25
|
</html>
|
|
26
|
-
|