swatchkit 1.1.1 → 2.0.0
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 +82 -90
- package/package.json +1 -1
- package/src/blueprints/main.css +8 -8
- package/src/blueprints/swatches/hello.css +11 -0
- package/src/blueprints/swatches/index.css +7 -0
- package/src/generators/index.js +39 -3
- package/src/layout.html +0 -1
- package/src/preview-layout.html +0 -1
- package/src/templates/hello/README.md +83 -0
- package/src/templates/hello/index.html +1 -0
- package/src/templates/script.js +4 -7
package/build.js
CHANGED
|
@@ -175,10 +175,8 @@ function resolveSettings(cliOptions, fileConfig) {
|
|
|
175
175
|
// Derived paths
|
|
176
176
|
distCssDir: path.join(outDir, "css"),
|
|
177
177
|
distTokensCssFile: path.join(outDir, "css", "tokens.css"),
|
|
178
|
-
distJsDir: path.join(outDir, "js"),
|
|
179
178
|
distPreviewDir: path.join(outDir, "preview"),
|
|
180
179
|
outputFile: path.join(outDir, "index.html"),
|
|
181
|
-
outputJsFile: path.join(outDir, "js/swatches.js"),
|
|
182
180
|
tokensCssFile: path.join(cssDir, "global", "tokens.css"),
|
|
183
181
|
mainCssFile: path.join(cssDir, "main.css"),
|
|
184
182
|
};
|
|
@@ -231,6 +229,22 @@ function buildInitManifest(settings) {
|
|
|
231
229
|
});
|
|
232
230
|
}
|
|
233
231
|
|
|
232
|
+
// Hello swatch (default example in swatchkit/swatches/hello/)
|
|
233
|
+
for (const file of ["index.html", "README.md"]) {
|
|
234
|
+
manifest.push({
|
|
235
|
+
src: path.join(templatesDir, "hello", file),
|
|
236
|
+
dest: path.join(settings.swatchkitDir, "swatches", "hello", file),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Swatches CSS folder (css/swatches/)
|
|
241
|
+
for (const file of ["index.css", "hello.css"]) {
|
|
242
|
+
manifest.push({
|
|
243
|
+
src: path.join(blueprintsDir, "swatches", file),
|
|
244
|
+
dest: path.join(settings.cssDir, "swatches", file),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
234
248
|
// Utility and composition display templates — walk each subfolder
|
|
235
249
|
for (const section of ["utilities", "compositions"]) {
|
|
236
250
|
const sectionSrc = path.join(templatesDir, section);
|
|
@@ -301,8 +315,11 @@ function getInitDirs(settings) {
|
|
|
301
315
|
path.join(settings.swatchkitDir, "tokens"),
|
|
302
316
|
path.join(settings.swatchkitDir, "utilities"),
|
|
303
317
|
path.join(settings.swatchkitDir, "compositions"),
|
|
318
|
+
path.join(settings.swatchkitDir, "swatches"),
|
|
319
|
+
path.join(settings.swatchkitDir, "swatches", "hello"),
|
|
304
320
|
settings.cssDir,
|
|
305
321
|
path.join(settings.cssDir, "global"),
|
|
322
|
+
path.join(settings.cssDir, "swatches"),
|
|
306
323
|
];
|
|
307
324
|
}
|
|
308
325
|
|
|
@@ -550,7 +567,26 @@ function copyDir(src, dest, force = false) {
|
|
|
550
567
|
}
|
|
551
568
|
}
|
|
552
569
|
|
|
553
|
-
|
|
570
|
+
// Special filenames that SwatchKit reads and treats differently — not copied verbatim.
|
|
571
|
+
const SWATCH_SPECIAL_FILES = new Set(["index.html", "description.html"]);
|
|
572
|
+
|
|
573
|
+
// Recursively copy a swatch's assets (all files and subdirs except index.html,
|
|
574
|
+
// description.html, and anything prefixed with _ or .) to destDir.
|
|
575
|
+
function copySwatchAssets(srcDir, destDir) {
|
|
576
|
+
if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
|
577
|
+
for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
578
|
+
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
579
|
+
const src = path.join(srcDir, entry.name);
|
|
580
|
+
const dest = path.join(destDir, entry.name);
|
|
581
|
+
if (entry.isDirectory()) {
|
|
582
|
+
copySwatchAssets(src, dest);
|
|
583
|
+
} else if (!SWATCH_SPECIAL_FILES.has(entry.name)) {
|
|
584
|
+
fs.copyFileSync(src, dest);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
function scanSwatches(dir, destDir, exclude = []) {
|
|
554
590
|
const swatches = [];
|
|
555
591
|
if (!fs.existsSync(dir)) return swatches;
|
|
556
592
|
|
|
@@ -583,23 +619,14 @@ function scanSwatches(dir, scriptsCollector, exclude = []) {
|
|
|
583
619
|
description = fs.readFileSync(descriptionFile, "utf-8");
|
|
584
620
|
}
|
|
585
621
|
|
|
586
|
-
//
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
"utf-8",
|
|
595
|
-
);
|
|
596
|
-
scriptsCollector.push(`
|
|
597
|
-
/* --- Swatch: ${name} / File: ${jsFile} --- */
|
|
598
|
-
(function() {
|
|
599
|
-
${scriptContent}
|
|
600
|
-
})();
|
|
601
|
-
`);
|
|
602
|
-
});
|
|
622
|
+
// Copy all non-special files and subdirectories from the component
|
|
623
|
+
// folder into its preview output directory so index.html can reference
|
|
624
|
+
// them with relative paths (e.g. ./styles.css, ./script.js, ./img/).
|
|
625
|
+
// Files and directories prefixed with _ or . are skipped.
|
|
626
|
+
if (destDir) {
|
|
627
|
+
const swatchDestDir = path.join(destDir, item);
|
|
628
|
+
copySwatchAssets(itemPath, swatchDestDir);
|
|
629
|
+
}
|
|
603
630
|
}
|
|
604
631
|
}
|
|
605
632
|
// Handle Single File
|
|
@@ -608,18 +635,6 @@ ${scriptContent}
|
|
|
608
635
|
id = name;
|
|
609
636
|
content = fs.readFileSync(itemPath, "utf-8");
|
|
610
637
|
}
|
|
611
|
-
// Handle Loose JS Files (e.g. script.js in tokens/)
|
|
612
|
-
else if (item.endsWith(".js")) {
|
|
613
|
-
const scriptContent = fs.readFileSync(itemPath, "utf-8");
|
|
614
|
-
scriptsCollector.push(`
|
|
615
|
-
/* --- File: ${item} --- */
|
|
616
|
-
(function() {
|
|
617
|
-
${scriptContent}
|
|
618
|
-
})();
|
|
619
|
-
`);
|
|
620
|
-
// Don't add to swatches list, just scripts
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
638
|
|
|
624
639
|
if (name && content) {
|
|
625
640
|
swatches.push({ name, id, content, description: description || null });
|
|
@@ -668,7 +683,7 @@ function build(settings) {
|
|
|
668
683
|
}
|
|
669
684
|
|
|
670
685
|
// 3. Ensure dist directories exist
|
|
671
|
-
const distDirs = [settings.outDir
|
|
686
|
+
const distDirs = [settings.outDir];
|
|
672
687
|
if (settings.cssCopy) distDirs.push(settings.distCssDir);
|
|
673
688
|
distDirs.forEach((dir) => {
|
|
674
689
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
@@ -701,9 +716,8 @@ function build(settings) {
|
|
|
701
716
|
console.log(`Skipping CSS copy (cssCopy: false). CSS referenced at: ${settings.cssPath}`);
|
|
702
717
|
}
|
|
703
718
|
|
|
704
|
-
// 4. Read swatches
|
|
719
|
+
// 4. Read swatches
|
|
705
720
|
console.log("Scanning HTML patterns (swatchkit/**/*.html)...");
|
|
706
|
-
const scripts = [];
|
|
707
721
|
const sections = {}; // Map<SectionName, Array<Swatch>>
|
|
708
722
|
|
|
709
723
|
if (fs.existsSync(settings.swatchkitDir)) {
|
|
@@ -723,7 +737,9 @@ function build(settings) {
|
|
|
723
737
|
// It is a Section Container (e.g. "Utilities")
|
|
724
738
|
const sectionName =
|
|
725
739
|
item === "tokens" ? "Design Tokens" : toTitleCase(item);
|
|
726
|
-
|
|
740
|
+
// Pass the preview dest dir so extra files get copied alongside each swatch
|
|
741
|
+
const sectionDestDir = path.join(settings.distPreviewDir, item);
|
|
742
|
+
const swatches = scanSwatches(itemPath, sectionDestDir, exclude);
|
|
727
743
|
// Tag each swatch with its section slug for preview paths
|
|
728
744
|
swatches.forEach((s) => (s.sectionSlug = item));
|
|
729
745
|
if (swatches.length > 0) {
|
|
@@ -749,24 +765,19 @@ function build(settings) {
|
|
|
749
765
|
} else if (stat.isDirectory()) {
|
|
750
766
|
const indexFile = path.join(itemPath, "index.html");
|
|
751
767
|
if (fs.existsSync(indexFile)) {
|
|
752
|
-
// Component folder swatch at root
|
|
768
|
+
// Component folder swatch at root — copy extra files to preview dest
|
|
753
769
|
const name = item;
|
|
754
770
|
const content = fs.readFileSync(indexFile, "utf-8");
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
);
|
|
766
|
-
scripts.push(
|
|
767
|
-
`/* ${name}/${jsFile} */ (function(){${scriptContent}})();`,
|
|
768
|
-
);
|
|
769
|
-
});
|
|
771
|
+
const descriptionFile = path.join(itemPath, "description.html");
|
|
772
|
+
const description = fs.existsSync(descriptionFile)
|
|
773
|
+
? fs.readFileSync(descriptionFile, "utf-8")
|
|
774
|
+
: null;
|
|
775
|
+
|
|
776
|
+
// Copy extra files into preview/id/
|
|
777
|
+
const swatchDestDir = path.join(settings.distPreviewDir, name);
|
|
778
|
+
copySwatchAssets(itemPath, swatchDestDir);
|
|
779
|
+
|
|
780
|
+
rootSwatches.push({ name, id: name, content, description, sectionSlug: null });
|
|
770
781
|
}
|
|
771
782
|
}
|
|
772
783
|
});
|
|
@@ -810,11 +821,13 @@ function build(settings) {
|
|
|
810
821
|
.replace(/"/g, """)
|
|
811
822
|
.replace(/'/g, "'");
|
|
812
823
|
|
|
813
|
-
// Build preview path: preview/{section}/{
|
|
824
|
+
// Build preview path: preview/{section}/{id}/ or preview/{id}/
|
|
825
|
+
// Each swatch is a directory with its own index.html so sibling assets
|
|
826
|
+
// (css, js, images, etc.) can be referenced with relative paths.
|
|
814
827
|
const previewPath = p.sectionSlug
|
|
815
|
-
? `preview/${p.sectionSlug}/${p.id}
|
|
816
|
-
: `preview/${p.id}
|
|
817
|
-
const previewLink = previewPath
|
|
828
|
+
? `preview/${p.sectionSlug}/${p.id}/`
|
|
829
|
+
: `preview/${p.id}/`;
|
|
830
|
+
const previewLink = previewPath;
|
|
818
831
|
|
|
819
832
|
return `
|
|
820
833
|
<section id="${p.id}" class="region flow">
|
|
@@ -832,23 +845,9 @@ function build(settings) {
|
|
|
832
845
|
.join("\n");
|
|
833
846
|
});
|
|
834
847
|
|
|
835
|
-
// 6.
|
|
836
|
-
//
|
|
837
|
-
//
|
|
838
|
-
const tokenDisplayScript = fs.readFileSync(
|
|
839
|
-
path.join(__dirname, "src/templates/script.js"),
|
|
840
|
-
"utf-8",
|
|
841
|
-
);
|
|
842
|
-
const internalScript = `/* --- SwatchKit: token display --- */\n(function() {\n${tokenDisplayScript}\n})();`;
|
|
843
|
-
const allScripts = [internalScript, ...scripts];
|
|
844
|
-
fs.writeFileSync(settings.outputJsFile, allScripts.join("\n"));
|
|
845
|
-
if (scripts.length > 0) {
|
|
846
|
-
console.log(
|
|
847
|
-
`Bundled ${scripts.length} swatch scripts to ${settings.outputJsFile}`,
|
|
848
|
-
);
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
// 7. Generate preview pages (standalone full-screen view of each swatch)
|
|
848
|
+
// 6. Generate preview pages (standalone full-screen view of each swatch)
|
|
849
|
+
// Each swatch gets its own directory: preview/{section}/{id}/index.html
|
|
850
|
+
// This allows index.html to reference sibling assets with relative paths.
|
|
852
851
|
let previewLayoutContent;
|
|
853
852
|
if (fs.existsSync(settings.projectPreviewLayout)) {
|
|
854
853
|
previewLayoutContent = fs.readFileSync(
|
|
@@ -867,32 +866,25 @@ function build(settings) {
|
|
|
867
866
|
sortedKeys.forEach((section) => {
|
|
868
867
|
const swatches = sections[section];
|
|
869
868
|
swatches.forEach((p) => {
|
|
870
|
-
//
|
|
871
|
-
//
|
|
872
|
-
//
|
|
873
|
-
let
|
|
869
|
+
// Each swatch is output as a directory with index.html inside.
|
|
870
|
+
// preview/{section}/{id}/index.html — depth: 3 levels from outDir
|
|
871
|
+
// preview/{id}/index.html — depth: 2 levels from outDir
|
|
872
|
+
let swatchDir, cssPath;
|
|
874
873
|
if (p.sectionSlug) {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
fs.mkdirSync(sectionDir, { recursive: true });
|
|
878
|
-
previewFile = path.join(sectionDir, `${p.id}.html`);
|
|
879
|
-
cssPath = "../../" + settings.cssPath; // preview/section/file.html -> ../../ + cssPath
|
|
874
|
+
swatchDir = path.join(settings.distPreviewDir, p.sectionSlug, p.id);
|
|
875
|
+
cssPath = "../../../" + settings.cssPath; // preview/section/id/index.html -> ../../../ + cssPath
|
|
880
876
|
} else {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
previewFile = path.join(settings.distPreviewDir, `${p.id}.html`);
|
|
884
|
-
cssPath = "../" + settings.cssPath; // preview/file.html -> ../ + cssPath
|
|
877
|
+
swatchDir = path.join(settings.distPreviewDir, p.id);
|
|
878
|
+
cssPath = "../../" + settings.cssPath; // preview/id/index.html -> ../../ + cssPath
|
|
885
879
|
}
|
|
886
880
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
const jsPath = p.sectionSlug ? "../../" : "../";
|
|
881
|
+
if (!fs.existsSync(swatchDir)) fs.mkdirSync(swatchDir, { recursive: true });
|
|
882
|
+
const previewFile = path.join(swatchDir, "index.html");
|
|
890
883
|
|
|
891
884
|
const previewHtml = previewLayoutContent
|
|
892
885
|
.replace("<!-- PREVIEW_TITLE -->", p.name)
|
|
893
886
|
.replace("<!-- PREVIEW_CONTENT -->", p.content)
|
|
894
887
|
.replaceAll("<!-- CSS_PATH -->", cssPath)
|
|
895
|
-
.replaceAll("<!-- JS_PATH -->", jsPath)
|
|
896
888
|
.replace("<!-- HEAD_EXTRAS -->", "");
|
|
897
889
|
|
|
898
890
|
fs.writeFileSync(previewFile, previewHtml);
|
package/package.json
CHANGED
package/src/blueprints/main.css
CHANGED
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
* SwatchKit Main Stylesheet
|
|
3
3
|
*
|
|
4
4
|
* This is your app's CSS entry point. It imports design tokens, reset,
|
|
5
|
-
* global styles,
|
|
6
|
-
*
|
|
5
|
+
* global styles, compositions, utilities, and component swatches.
|
|
6
|
+
* Edit freely — this file is yours.
|
|
7
|
+
*
|
|
8
|
+
* Note: swatchkit scaffold --force will overwrite blueprint files (with .bak backups).
|
|
7
9
|
* The only truly auto-generated files are css/global/tokens.css and
|
|
8
10
|
* css/utilities/tokens.css — do not edit those manually.
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
|
-
/*
|
|
12
|
-
* Import Global Styles (Reset, Tokens, Variables, Elements)
|
|
13
|
-
*
|
|
14
|
-
* NOTE: Some global styles (variables & elements) are DISABLED by default.
|
|
15
|
-
* You must open `css/global/index.css` to verify variable names and enable them.
|
|
16
|
-
*/
|
|
13
|
+
/* Import global styles (reset, tokens, variables, elements) */
|
|
17
14
|
@import "global/index.css";
|
|
18
15
|
|
|
19
16
|
/* Import layout compositions */
|
|
@@ -22,6 +19,9 @@
|
|
|
22
19
|
/* Import utilities */
|
|
23
20
|
@import "utilities/index.css";
|
|
24
21
|
|
|
22
|
+
/* Import swatches (component styles) */
|
|
23
|
+
@import "swatches/index.css";
|
|
24
|
+
|
|
25
25
|
/* === Your App Styles === */
|
|
26
26
|
|
|
27
27
|
/* Add your component styles below */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* === Hello Swatch ===
|
|
2
|
+
*
|
|
3
|
+
* Styles for the hello swatch (swatchkit/swatches/hello/).
|
|
4
|
+
* Replace or delete this file once you have real components to document.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
.hello-swatch {
|
|
8
|
+
font-family: var(--font-base, sans-serif);
|
|
9
|
+
font-size: var(--size-step-0, 1rem);
|
|
10
|
+
color: var(--color-primary, currentColor);
|
|
11
|
+
}
|
package/src/generators/index.js
CHANGED
|
@@ -8,6 +8,39 @@
|
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const path = require('path');
|
|
10
10
|
|
|
11
|
+
// Inline script that resolves CSS custom property values and annotates
|
|
12
|
+
// .token-value elements with their computed value (e.g. "(#3b82f6)").
|
|
13
|
+
// Included directly in any generated HTML fragment that uses .token-value
|
|
14
|
+
// so the fragment is self-contained and doesn't depend on a shared bundle.
|
|
15
|
+
const TOKEN_DISPLAY_SCRIPT = `<script>
|
|
16
|
+
(function() {
|
|
17
|
+
var elements = document.querySelectorAll('.token-value');
|
|
18
|
+
if (!elements.length) return;
|
|
19
|
+
elements.forEach(function(el) {
|
|
20
|
+
var prop = el.getAttribute('data-var');
|
|
21
|
+
var computed = getComputedStyle(el).getPropertyValue(prop).trim();
|
|
22
|
+
if (computed) {
|
|
23
|
+
el.innerHTML += ' <span style="opacity:0.5;font-family:monospace;font-size:0.8em">(' + computed + ')</span>';
|
|
24
|
+
} else {
|
|
25
|
+
var temp = document.createElement('div');
|
|
26
|
+
temp.style.fontSize = '16px';
|
|
27
|
+
temp.style.lineHeight = 'var(' + prop + ')';
|
|
28
|
+
document.body.appendChild(temp);
|
|
29
|
+
var computedPx = getComputedStyle(temp).lineHeight;
|
|
30
|
+
document.body.removeChild(temp);
|
|
31
|
+
var displayValue = computedPx;
|
|
32
|
+
if (computedPx.endsWith('px')) {
|
|
33
|
+
var ratio = Math.round((parseFloat(computedPx) / 16) * 100) / 100;
|
|
34
|
+
displayValue = String(ratio);
|
|
35
|
+
}
|
|
36
|
+
if (displayValue) {
|
|
37
|
+
el.innerHTML += ' <span style="opacity:0.5;font-family:monospace;font-size:0.8em">(' + displayValue + ')</span>';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
})();
|
|
42
|
+
</script>`;
|
|
43
|
+
|
|
11
44
|
/**
|
|
12
45
|
* Read and parse a JSON token file
|
|
13
46
|
*/
|
|
@@ -113,7 +146,8 @@ function generateTypography(tokensDir) {
|
|
|
113
146
|
</style>
|
|
114
147
|
<div class="type-ladder">
|
|
115
148
|
${steps}
|
|
116
|
-
</div
|
|
149
|
+
</div>
|
|
150
|
+
${TOKEN_DISPLAY_SCRIPT}`;
|
|
117
151
|
}
|
|
118
152
|
|
|
119
153
|
/**
|
|
@@ -233,7 +267,8 @@ function generateFonts(tokensDir) {
|
|
|
233
267
|
|
|
234
268
|
return `<div class="font-stack">
|
|
235
269
|
${stacks}
|
|
236
|
-
</div
|
|
270
|
+
</div>
|
|
271
|
+
${TOKEN_DISPLAY_SCRIPT}`;
|
|
237
272
|
}
|
|
238
273
|
|
|
239
274
|
/**
|
|
@@ -294,7 +329,8 @@ ${leadings}
|
|
|
294
329
|
color: #666;
|
|
295
330
|
margin-left: 0.5rem;
|
|
296
331
|
}
|
|
297
|
-
</style
|
|
332
|
+
</style>
|
|
333
|
+
${TOKEN_DISPLAY_SCRIPT}`;
|
|
298
334
|
}
|
|
299
335
|
|
|
300
336
|
/**
|
package/src/layout.html
CHANGED
package/src/preview-layout.html
CHANGED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Hello Swatch
|
|
2
|
+
|
|
3
|
+
This is your first swatch. It lives at `swatchkit/swatches/hello/`.
|
|
4
|
+
|
|
5
|
+
## How swatch folders work
|
|
6
|
+
|
|
7
|
+
SwatchKit treats every folder inside `swatchkit/` that contains an `index.html`
|
|
8
|
+
as a swatch. The `index.html` is rendered inside a preview iframe in the pattern
|
|
9
|
+
library. It is an HTML fragment — no `<html>`, `<head>`, or `<body>` needed, since
|
|
10
|
+
SwatchKit wraps it in a full page automatically.
|
|
11
|
+
|
|
12
|
+
## Sibling files are copied alongside
|
|
13
|
+
|
|
14
|
+
Every file in this folder **other than** `index.html` and `description.html` is
|
|
15
|
+
copied into the build output next to the preview page. That means your `index.html`
|
|
16
|
+
can reference sibling files using relative paths:
|
|
17
|
+
|
|
18
|
+
```html
|
|
19
|
+
<link rel="stylesheet" href="./styles.css">
|
|
20
|
+
<script src="./script.js"></script>
|
|
21
|
+
<img src="./demo-image.png" alt="">
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This makes each swatch self-contained. Drop in whatever assets the demo needs.
|
|
25
|
+
|
|
26
|
+
## description.html
|
|
27
|
+
|
|
28
|
+
If you add a `description.html` file to this folder, its contents will be
|
|
29
|
+
displayed above the iframe in the pattern library UI — useful for documenting
|
|
30
|
+
usage notes, props, or design decisions.
|
|
31
|
+
|
|
32
|
+
## Global CSS
|
|
33
|
+
|
|
34
|
+
Component styles that belong in your real app's stylesheet (not just the demo)
|
|
35
|
+
live in `css/swatches/`. The `hello.css` file there is imported into `main.css`
|
|
36
|
+
via `css/swatches/index.css`. Add new component CSS files to that folder and
|
|
37
|
+
import them from `css/swatches/index.css`.
|
|
38
|
+
|
|
39
|
+
## Opting out with underscores
|
|
40
|
+
|
|
41
|
+
Prefix any file or folder with `_` to exclude it from the build entirely —
|
|
42
|
+
it won't be rendered as a swatch and won't be copied to the output.
|
|
43
|
+
|
|
44
|
+
This works at every level:
|
|
45
|
+
|
|
46
|
+
- `swatchkit/swatches/_wip/` — entire swatch folder ignored
|
|
47
|
+
- `swatchkit/_drafts/` — entire section folder ignored
|
|
48
|
+
- `swatchkit/swatches/hello/_notes.md` — single file inside a swatch, not copied
|
|
49
|
+
- `swatchkit/swatches/hello/_fixtures/` — subdirectory inside a swatch, not copied
|
|
50
|
+
|
|
51
|
+
This is useful for work-in-progress components, private notes, test fixtures,
|
|
52
|
+
or any file that should live alongside a swatch but never appear in the output.
|
|
53
|
+
|
|
54
|
+
## A note on CSS isolation
|
|
55
|
+
|
|
56
|
+
SwatchKit does not scope or isolate CSS between swatches. Every preview page
|
|
57
|
+
loads the same global stylesheet (`main.css` and everything it imports), so
|
|
58
|
+
styles defined in `css/swatches/hello.css` are active on *every* swatch's
|
|
59
|
+
preview page — not just this one.
|
|
60
|
+
|
|
61
|
+
This means `button { background: red }` in one swatch's CSS will affect the
|
|
62
|
+
`<button>` elements in every other swatch. If two swatches both style `button`
|
|
63
|
+
differently, the cascade determines which wins.
|
|
64
|
+
|
|
65
|
+
The fix is to scope your styles with a component-specific class:
|
|
66
|
+
|
|
67
|
+
```css
|
|
68
|
+
/* Instead of this: */
|
|
69
|
+
button { background: red; }
|
|
70
|
+
|
|
71
|
+
/* Do this: */
|
|
72
|
+
.hello-swatch button { background: red; }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The same applies to sibling CSS files (`./styles.css` next to `index.html`) —
|
|
76
|
+
they load per-page on top of the global stylesheet, so unscoped rules will
|
|
77
|
+
still bleed into any swatch that shares the same elements.
|
|
78
|
+
|
|
79
|
+
## This README
|
|
80
|
+
|
|
81
|
+
This file (`README.md`) is ignored by SwatchKit's UI — it is just for you and
|
|
82
|
+
your team. It gets copied into the build output alongside `index.html`, but it
|
|
83
|
+
is not rendered anywhere in the pattern library.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p class="hello-swatch">Hello from SwatchKit! Edit <code>swatchkit/swatches/hello/index.html</code> to get started.</p>
|
package/src/templates/script.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
// Token Value Display Script
|
|
1
|
+
// Token Value Display Script (reference copy — not used directly by the build)
|
|
2
2
|
//
|
|
3
3
|
// Shows the computed (resolved) value of CSS custom properties next to each
|
|
4
4
|
// .token-value element in the token documentation pages. For example, a color
|
|
5
5
|
// token swatch might display "(#3b82f6)" beside the variable name.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// (along with any component-folder scripts), wraps each in an IIFE, and
|
|
11
|
-
// concatenates them into dist/swatchkit/js/swatches.js
|
|
12
|
-
// 3. The layout templates include a <script> tag pointing to js/swatches.js
|
|
7
|
+
// The minified version of this logic is inlined directly into the HTML fragments
|
|
8
|
+
// generated by src/generators/index.js (TOKEN_DISPLAY_SCRIPT constant), so each
|
|
9
|
+
// token swatch page is fully self-contained with no external script dependency.
|
|
13
10
|
|
|
14
11
|
const elements = document.querySelectorAll('.token-value');
|
|
15
12
|
if (elements.length > 0) {
|