swatchkit 0.0.7 → 0.0.9
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 +59 -4
- package/build.js +71 -5
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -71,7 +71,59 @@ SwatchKit scaffolds a design system for you. Edit the JSON files in `swatches/to
|
|
|
71
71
|
|
|
72
72
|
Documentation patterns for these are automatically created alongside the JSON files.
|
|
73
73
|
|
|
74
|
-
### 3.
|
|
74
|
+
### 3. Intelligent Fluid Logic (New!)
|
|
75
|
+
|
|
76
|
+
SwatchKit can auto-calculate fluid typography and spacing scales.
|
|
77
|
+
|
|
78
|
+
**Static vs Fluid:**
|
|
79
|
+
* **Static:** Provide a `value` (e.g. `"16px"`).
|
|
80
|
+
* **Fluid:** Provide `min` and `max` (e.g. `16` and `18`).
|
|
81
|
+
* **Auto-Fluid:** Provide just ONE side (`min` or `max`), and SwatchKit calculates the other using a default ratio (1.125).
|
|
82
|
+
|
|
83
|
+
**Example (`swatches/tokens/text-sizes.json`):**
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"title": "Text Sizes",
|
|
87
|
+
"fluidRatio": 1.25,
|
|
88
|
+
"items": [
|
|
89
|
+
{ "name": "base", "value": "1rem" }, // Static: 1rem always
|
|
90
|
+
{ "name": "md", "min": 16, "max": 20 }, // Fluid: 16px -> 20px
|
|
91
|
+
{ "name": "lg", "max": 24 }, // Auto: 19.2px -> 24px (24 / 1.25)
|
|
92
|
+
{ "name": "xl", "min": 32 }, // Auto: 32px -> 40px (32 * 1.25)
|
|
93
|
+
{ "name": "jumbo", "max": 64, "fluidRatio": 1.5 } // Auto: 42.6px -> 64px (64 / 1.5)
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Generated CSS:**
|
|
99
|
+
```css
|
|
100
|
+
:root {
|
|
101
|
+
--s-base: 1rem;
|
|
102
|
+
--s-md: clamp(1rem, ... , 1.25rem);
|
|
103
|
+
--s-lg: clamp(1.2rem, ... , 1.5rem);
|
|
104
|
+
--s-xl: clamp(2rem, ... , 2.5rem);
|
|
105
|
+
--s-jumbo: clamp(2.66rem, ... , 4rem);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 4. Hybrid Text Leading
|
|
110
|
+
|
|
111
|
+
You can mix modular scales with manual overrides.
|
|
112
|
+
|
|
113
|
+
**Example (`swatches/tokens/text-leading.json`):**
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"base": 1,
|
|
117
|
+
"ratio": 1.2,
|
|
118
|
+
"items": [
|
|
119
|
+
{ "name": "tight", "step": -1 }, // Modular: 1 * (1.2 ^ -1)
|
|
120
|
+
{ "name": "flat", "value": 1 }, // Manual: 1
|
|
121
|
+
{ "name": "loose", "step": 1 } // Modular: 1 * (1.2 ^ 1)
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 5. CSS Workflow
|
|
75
127
|
|
|
76
128
|
SwatchKit generates `css/tokens.css` with your design tokens as CSS custom properties. The starter `css/styles.css` imports this file:
|
|
77
129
|
|
|
@@ -88,7 +140,7 @@ body {
|
|
|
88
140
|
|
|
89
141
|
The pattern library uses **your stylesheet**, so components render exactly as they will in your app.
|
|
90
142
|
|
|
91
|
-
###
|
|
143
|
+
### 6. Custom Layouts
|
|
92
144
|
When you run `swatchkit init`, we create `swatches/_layout.html`.
|
|
93
145
|
**You own this file.**
|
|
94
146
|
* Link to your own stylesheets.
|
|
@@ -97,7 +149,7 @@ When you run `swatchkit init`, we create `swatches/_layout.html`.
|
|
|
97
149
|
|
|
98
150
|
SwatchKit injects content into the `<!-- PATTERNS -->`, `<!-- SIDEBAR_LINKS -->`, and `<!-- HEAD_EXTRAS -->` placeholders.
|
|
99
151
|
|
|
100
|
-
###
|
|
152
|
+
### 7. JavaScript Bundling
|
|
101
153
|
If your component needs client-side JS:
|
|
102
154
|
1. Create a folder: `swatches/carousel/`.
|
|
103
155
|
2. Add `index.html` (Markup).
|
|
@@ -118,7 +170,7 @@ swatchkit [command] [options]
|
|
|
118
170
|
### Flags
|
|
119
171
|
| Flag | Short | Description |
|
|
120
172
|
| :--- | :--- | :--- |
|
|
121
|
-
| `--watch` | `-w` | Watch
|
|
173
|
+
| `--watch` | `-w` | Watch files and rebuild on change. |
|
|
122
174
|
| `--config` | `-c` | Path to config file. |
|
|
123
175
|
| `--input` | `-i` | Pattern directory (Default: `swatches/`). |
|
|
124
176
|
| `--outDir` | `-o` | Output directory (Default: `public/swatchkit`). |
|
|
@@ -138,6 +190,9 @@ module.exports = {
|
|
|
138
190
|
// Override CSS directory
|
|
139
191
|
css: './assets/css',
|
|
140
192
|
|
|
193
|
+
// Exclude files (supports glob patterns)
|
|
194
|
+
exclude: ['*.test.js', 'temp*'],
|
|
195
|
+
|
|
141
196
|
// Override token settings
|
|
142
197
|
tokens: {
|
|
143
198
|
input: './design-tokens', // Where token JSON files live
|
package/build.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const fs = require("fs");
|
|
3
3
|
const path = require("path");
|
|
4
|
+
const chokidar = require("chokidar");
|
|
4
5
|
const { processTokens } = require("./src/tokens");
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -66,6 +67,27 @@ function loadConfig(configPath) {
|
|
|
66
67
|
return {};
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
// --- 2.5 Glob Matching Helper ---
|
|
71
|
+
function matchesPattern(filename, pattern) {
|
|
72
|
+
// Simple wildcard support
|
|
73
|
+
if (pattern.includes("*")) {
|
|
74
|
+
const parts = pattern.split("*");
|
|
75
|
+
// Handle "foo*"
|
|
76
|
+
if (pattern.endsWith("*") && !pattern.startsWith("*")) {
|
|
77
|
+
return filename.startsWith(parts[0]);
|
|
78
|
+
}
|
|
79
|
+
// Handle "*bar"
|
|
80
|
+
if (pattern.startsWith("*") && !pattern.endsWith("*")) {
|
|
81
|
+
return filename.endsWith(parts[1]);
|
|
82
|
+
}
|
|
83
|
+
// Handle "*bar*"
|
|
84
|
+
if (pattern.startsWith("*") && pattern.endsWith("*")) {
|
|
85
|
+
return filename.includes(parts[1]);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return filename === pattern;
|
|
89
|
+
}
|
|
90
|
+
|
|
69
91
|
// --- 3. Smart Defaults & Path Resolution ---
|
|
70
92
|
function resolveSettings(cliOptions, fileConfig) {
|
|
71
93
|
const cwd = process.cwd();
|
|
@@ -108,12 +130,16 @@ function resolveSettings(cliOptions, fileConfig) {
|
|
|
108
130
|
const tokensDir = fileConfig.tokens?.input
|
|
109
131
|
? path.resolve(cwd, fileConfig.tokens.input)
|
|
110
132
|
: path.join(patternsDir, "tokens");
|
|
133
|
+
|
|
134
|
+
// Exclude patterns
|
|
135
|
+
const exclude = fileConfig.exclude || [];
|
|
111
136
|
|
|
112
137
|
return {
|
|
113
138
|
patternsDir,
|
|
114
139
|
outDir,
|
|
115
140
|
cssDir,
|
|
116
141
|
tokensDir,
|
|
142
|
+
exclude,
|
|
117
143
|
fileConfig, // Expose config to init
|
|
118
144
|
// Internal layout template (relative to this script)
|
|
119
145
|
internalLayout: path.join(__dirname, "src/layout.html"),
|
|
@@ -264,8 +290,10 @@ function scanDirectory(dir, scriptsCollector, exclude = []) {
|
|
|
264
290
|
const items = fs.readdirSync(dir);
|
|
265
291
|
|
|
266
292
|
items.forEach((item) => {
|
|
267
|
-
// Skip excluded items
|
|
268
|
-
if (exclude.
|
|
293
|
+
// Skip excluded items
|
|
294
|
+
if (exclude.some(pattern => matchesPattern(item, pattern))) return;
|
|
295
|
+
|
|
296
|
+
// Skip _layout.html or hidden files
|
|
269
297
|
if (item.startsWith("_") || item.startsWith(".")) return;
|
|
270
298
|
|
|
271
299
|
const itemPath = path.join(dir, item);
|
|
@@ -372,8 +400,9 @@ function build(settings) {
|
|
|
372
400
|
const tokensDir = path.join(settings.patternsDir, "tokens");
|
|
373
401
|
const tokenPages = scanDirectory(tokensDir, scripts);
|
|
374
402
|
|
|
375
|
-
// Pass 2: Patterns (in [patternsDir], excluding 'tokens')
|
|
376
|
-
const
|
|
403
|
+
// Pass 2: Patterns (in [patternsDir], excluding 'tokens' and user excludes)
|
|
404
|
+
const userExcludes = settings.exclude || [];
|
|
405
|
+
const patternPages = scanDirectory(settings.patternsDir, scripts, ["tokens", ...userExcludes]);
|
|
377
406
|
|
|
378
407
|
// Combine for content generation (Tokens first, then Patterns)
|
|
379
408
|
const allPatterns = [...tokenPages, ...patternPages];
|
|
@@ -451,6 +480,43 @@ function build(settings) {
|
|
|
451
480
|
console.log(`Build complete! Generated ${settings.outputFile}`);
|
|
452
481
|
}
|
|
453
482
|
|
|
483
|
+
// --- 6. Watch Logic ---
|
|
484
|
+
function watch(settings) {
|
|
485
|
+
const watchPaths = [
|
|
486
|
+
settings.patternsDir,
|
|
487
|
+
settings.tokensDir,
|
|
488
|
+
settings.projectLayout,
|
|
489
|
+
settings.stylesCssFile
|
|
490
|
+
].filter(p => fs.existsSync(p)); // Only watch files that exist
|
|
491
|
+
|
|
492
|
+
console.log("[SwatchKit] Watch mode enabled.");
|
|
493
|
+
console.log("Watching for changes in:");
|
|
494
|
+
watchPaths.forEach(p => console.log(` - ${p}`));
|
|
495
|
+
|
|
496
|
+
let buildTimeout;
|
|
497
|
+
const rebuild = () => {
|
|
498
|
+
if (buildTimeout) clearTimeout(buildTimeout);
|
|
499
|
+
buildTimeout = setTimeout(() => {
|
|
500
|
+
try {
|
|
501
|
+
console.log("[SwatchKit] Change detected. Rebuilding...");
|
|
502
|
+
build(settings);
|
|
503
|
+
} catch (e) {
|
|
504
|
+
console.error("[SwatchKit] Build failed:", e.message);
|
|
505
|
+
}
|
|
506
|
+
}, 100); // 100ms debounce
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
const watcher = chokidar.watch(watchPaths, {
|
|
510
|
+
ignored: /(^|[\/\\])\../, // ignore dotfiles
|
|
511
|
+
persistent: true,
|
|
512
|
+
ignoreInitial: true
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
watcher.on('all', (event, path) => {
|
|
516
|
+
rebuild();
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
|
|
454
520
|
// --- Main Execution ---
|
|
455
521
|
try {
|
|
456
522
|
const cliOptions = parseArgs(process.argv);
|
|
@@ -462,7 +528,7 @@ try {
|
|
|
462
528
|
} else {
|
|
463
529
|
build(settings);
|
|
464
530
|
if (cliOptions.watch) {
|
|
465
|
-
|
|
531
|
+
watch(settings);
|
|
466
532
|
}
|
|
467
533
|
}
|
|
468
534
|
} catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swatchkit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "A lightweight tool for creating HTML pattern libraries.",
|
|
5
5
|
"main": "build.js",
|
|
6
6
|
"bin": {
|
|
@@ -23,5 +23,8 @@
|
|
|
23
23
|
"bugs": {
|
|
24
24
|
"url": "https://github.com/cwebley/swatchkit/issues"
|
|
25
25
|
},
|
|
26
|
-
"homepage": "https://github.com/cwebley/swatchkit#readme"
|
|
26
|
+
"homepage": "https://github.com/cwebley/swatchkit#readme",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"chokidar": "^5.0.0"
|
|
29
|
+
}
|
|
27
30
|
}
|