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.
Files changed (3) hide show
  1. package/build.js +104 -93
  2. package/package.json +1 -1
  3. 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
- return filename.startsWith(parts[0]);
77
+ return filename.startsWith(parts[0]);
78
78
  }
79
79
  // Handle "*bar"
80
80
  if (pattern.startsWith("*") && !pattern.endsWith("*")) {
81
- return filename.endsWith(parts[1]);
81
+ return filename.endsWith(parts[1]);
82
82
  }
83
83
  // Handle "*bar*"
84
84
  if (pattern.startsWith("*") && pattern.endsWith("*")) {
85
- return filename.includes(parts[1]);
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, ' ').replace(/\b\w/g, l => l.toUpperCase());
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, 'src/blueprints', srcFilename);
184
- const content = fs.readFileSync(srcPath, 'utf-8');
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('colors.json', 'colors.json');
191
+ copyDefault("colors.json", "colors.json");
192
192
 
193
193
  // 2. Create Text Weights Token
194
- copyDefault('text-weights.json', 'text-weights.json');
194
+ copyDefault("text-weights.json", "text-weights.json");
195
195
 
196
196
  // 3. Create Text Leading Token
197
- copyDefault('text-leading.json', 'text-leading.json');
197
+ copyDefault("text-leading.json", "text-leading.json");
198
198
 
199
199
  // 4. Create Viewports Token
200
- copyDefault('viewports.json', 'viewports.json');
200
+ copyDefault("viewports.json", "viewports.json");
201
201
 
202
202
  // 5. Create Text Sizes Token (Fluid)
203
- copyDefault('text-sizes.json', 'text-sizes.json');
203
+ copyDefault("text-sizes.json", "text-sizes.json");
204
204
 
205
205
  // 6. Create Spacing Token
206
- copyDefault('spacing.json', 'spacing.json');
206
+ copyDefault("spacing.json", "spacing.json");
207
207
 
208
208
  // 7. Create Fonts Token
209
- copyDefault('fonts.json', 'fonts.json');
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, 'src/templates', srcFilename);
215
- const content = fs.readFileSync(srcPath, 'utf-8');
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('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');
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, 'src/templates/script.js');
233
- const content = fs.readFileSync(srcPath, 'utf-8');
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, 'src/blueprints/styles.css');
241
- const content = fs.readFileSync(srcPath, 'utf-8');
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, 'src/blueprints/reset.css');
248
- const resetDest = path.join(settings.cssDir, 'reset.css');
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, 'src/blueprints/compositions');
256
- const compositionsDest = path.join(settings.cssDir, 'compositions');
255
+ const compositionsSrc = path.join(__dirname, "src/blueprints/compositions");
256
+ const compositionsDest = path.join(settings.cssDir, "compositions");
257
257
  if (fs.existsSync(compositionsSrc)) {
258
- copyDir(compositionsSrc, compositionsDest);
258
+ copyDir(compositionsSrc, compositionsDest);
259
259
  }
260
260
 
261
261
  // Copy SwatchKit UI Styles
262
- const uiSrc = path.join(__dirname, 'src/blueprints/swatchkit-ui.css');
263
- const uiDest = path.join(settings.cssDir, 'swatchkit-ui.css');
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
- // It is a Section Container (e.g. "Utilities")
433
- const sectionName = item === 'tokens' ? 'Design Tokens' : toTitleCase(item);
434
- const swatches = scanSwatches(itemPath, scripts, exclude);
435
- if (swatches.length > 0) {
436
- sections[sectionName] = swatches;
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
- if (exclude.some(p => matchesGlob(item, p))) return;
446
- if (item.startsWith(".") || item.startsWith("_")) return;
447
-
448
- const itemPath = path.join(settings.swatchkitDir, item);
449
- const stat = fs.statSync(itemPath);
450
-
451
- if (stat.isFile() && item.endsWith('.html')) {
452
- const name = path.basename(item, ".html");
453
- const content = fs.readFileSync(itemPath, "utf-8");
454
- rootSwatches.push({ name, id: name, content });
455
- } else if (stat.isDirectory()) {
456
- const indexFile = path.join(itemPath, "index.html");
457
- if (fs.existsSync(indexFile)) {
458
- // Component folder swatch at root
459
- const name = item;
460
- const content = fs.readFileSync(indexFile, "utf-8");
461
- rootSwatches.push({ name, id: name, content });
462
-
463
- // Collect JS
464
- const jsFiles = fs.readdirSync(itemPath).filter(f => f.endsWith(".js"));
465
- jsFiles.forEach(jsFile => {
466
- const scriptContent = fs.readFileSync(path.join(itemPath, jsFile), "utf-8");
467
- scripts.push(`/* ${name}/${jsFile} */ (function(){${scriptContent}})();`);
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
- sections["Patterns"] = rootSwatches;
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 === 'Design Tokens') return -1;
487
- if (b === 'Design Tokens') return 1;
488
- if (a === 'Patterns') return 1;
489
- if (b === 'Patterns') return -1;
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) => `<a href="#${p.id}">${p.name}</a>`)
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.map((p) => {
503
- const escapedContent = p.content
504
- .replace(/&/g, "&amp;")
505
- .replace(/</g, "&lt;")
506
- .replace(/>/g, "&gt;")
507
- .replace(/"/g, "&quot;")
508
- .replace(/'/g, "&#039;");
509
-
510
- return `
511
+ swatchBlocks += swatches
512
+ .map((p) => {
513
+ const escapedContent = p.content
514
+ .replace(/&/g, "&amp;")
515
+ .replace(/</g, "&lt;")
516
+ .replace(/>/g, "&gt;")
517
+ .replace(/"/g, "&quot;")
518
+ .replace(/'/g, "&#039;");
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
- }).join("\n");
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('all', (event, path) => {
597
+ watcher.on("all", (event, path) => {
587
598
  rebuild();
588
599
  });
589
600
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swatchkit",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "A lightweight tool for creating HTML pattern libraries.",
5
5
  "main": "build.js",
6
6
  "bin": {
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="swatchkit-nav flow">
12
+ <div class="sidebar wrapper">
13
+ <nav class="flow">
14
14
  <header>
15
- <h2>SwatchKit</h2>
15
+ <h2>SwatchKit</h2>
16
16
  </header>
17
17
  <!-- SIDEBAR_LINKS -->
18
18
  </nav>
19
- <main class="swatchkit-main flow">
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
-