@fractaldesign/fractalstyler 0.0.0-stage → 0.9.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/LICENSE +19 -0
- package/README.md +123 -2
- package/cli/main.mjs +141 -0
- package/cli/scaffold.mjs +406 -0
- package/data/recipes.json +61 -0
- package/dist/asset.d.ts +3 -0
- package/dist/css/fractalstyler.css +2453 -0
- package/dist/css/fractalstyler.min.css +2 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/styles/_00_config.sass +29 -0
- package/dist/styles/_00_fonts.sass +58 -0
- package/dist/styles/_00_tokens.sass +211 -0
- package/dist/styles/_01_base.sass +58 -0
- package/dist/styles/_02_dimensions.sass +70 -0
- package/dist/styles/_03_typography.sass +170 -0
- package/dist/styles/_04_containers.sass +173 -0
- package/dist/styles/_05_layouts.sass +104 -0
- package/dist/styles/_06_shells.sass +135 -0
- package/dist/styles/_07_interactions.sass +212 -0
- package/dist/styles/_08_visuals.sass +136 -0
- package/dist/styles/_09_own.sass +174 -0
- package/dist/styles/colorpacks.sass +119 -0
- package/dist/styles/index.sass +14 -0
- package/dist/styles/themeplates.sass +159 -0
- package/docs/REGISTRY.api.md +477 -0
- package/docs/REGISTRY.md +14 -0
- package/docs/references/configurations-api.md +220 -0
- package/docs/references/configurations.md +258 -0
- package/lint/browser.mjs +79 -0
- package/lint/cli.mjs +212 -0
- package/lint/lib/agent-reporter.mjs +51 -0
- package/lint/lib/fuzzy.mjs +45 -0
- package/lint/lib/registry.mjs +107 -0
- package/lint/lib/sass-linter.mjs +71 -0
- package/lint/lib/svelte-linter.mjs +116 -0
- package/lint/lib/token-linter.mjs +97 -0
- package/package.json +112 -5
- package/registry.json +3999 -0
- package/scripts/class-vocab.js +197 -0
- package/scripts/update-registry.js +934 -0
- package/skills/fractal-styler/references/fractals.md +630 -0
- package/skills/fractal-styler/references/tokens.md +226 -0
- package/skills/fractalstyler/SKILL.md +59 -0
- package/skills/fractalstyler/references/fractals.md +630 -0
- package/skills/fractalstyler/references/tokens.md +226 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Token-purity linter for fractalstyler.
|
|
3
|
+
//
|
|
4
|
+
// Enforces:
|
|
5
|
+
// fs/token-purity:
|
|
6
|
+
// - No raw hex colors (#fff, #123456) — all colors must resolve via tokens.
|
|
7
|
+
// - >2px pixel budget — arbitrary pixels break density and design scale.
|
|
8
|
+
// - No unmapped custom properties — var(--name) must resolve to a valid token.
|
|
9
|
+
// =============================================================================
|
|
10
|
+
|
|
11
|
+
import { findClosestMatches } from './fuzzy.mjs';
|
|
12
|
+
|
|
13
|
+
const PX_BUDGET = 2; // 1-2px stays legal for hairlines and borders.
|
|
14
|
+
|
|
15
|
+
export class TokenLinter {
|
|
16
|
+
/**
|
|
17
|
+
* @param {string} rootDir
|
|
18
|
+
* @param {{ tokens: Set<string> }} opts
|
|
19
|
+
*/
|
|
20
|
+
constructor(rootDir, opts) {
|
|
21
|
+
this.rootDir = rootDir;
|
|
22
|
+
this.validTokens = new Set(opts.tokens);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Scans a stylesheet string.
|
|
27
|
+
* @param {string} relPath
|
|
28
|
+
* @param {string} content
|
|
29
|
+
* @param {Set<string>} [localProperties] Locally defined custom properties in project.
|
|
30
|
+
*/
|
|
31
|
+
lintFile(relPath, content, localProperties = new Set()) {
|
|
32
|
+
const diagnostics = [];
|
|
33
|
+
const lines = content.split('\n');
|
|
34
|
+
|
|
35
|
+
lines.forEach((line, idx) => {
|
|
36
|
+
const lineNum = idx + 1;
|
|
37
|
+
const cleanLine = line.replace(/\/\/.*$/, '').replace(/\/\*[\s\S]*?\*\//, '').trim();
|
|
38
|
+
if (!cleanLine) return;
|
|
39
|
+
|
|
40
|
+
// Rule 1: No raw hex colors
|
|
41
|
+
for (const m of cleanLine.matchAll(/#[0-9a-fA-F]{3,8}\b/g)) {
|
|
42
|
+
diagnostics.push({
|
|
43
|
+
rule: 'fs/token-purity',
|
|
44
|
+
severity: 'error',
|
|
45
|
+
file: relPath,
|
|
46
|
+
line: lineNum,
|
|
47
|
+
column: m.index + 1,
|
|
48
|
+
found: m[0],
|
|
49
|
+
rationale:
|
|
50
|
+
'Raw hex colors bypass semantic theming. Every color must resolve through a system token (var(--bg), var(--text-primary), var(--brand), etc.) so light/dark mode and presets reach it.',
|
|
51
|
+
suggestion: `Replace "${m[0]}" with the semantic color token it expresses, or define it in _00_tokens.sass.`
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Rule 2: The px budget (>2px must come from dimension ladder or tokens)
|
|
56
|
+
for (const m of cleanLine.matchAll(/(?<![0-9a-zA-Z_.-])(-?\d+)px\b/g)) {
|
|
57
|
+
const px = parseInt(m[1], 10);
|
|
58
|
+
if (Math.abs(px) <= PX_BUDGET) continue;
|
|
59
|
+
diagnostics.push({
|
|
60
|
+
rule: 'fs/token-purity',
|
|
61
|
+
severity: 'error',
|
|
62
|
+
file: relPath,
|
|
63
|
+
line: lineNum,
|
|
64
|
+
column: m.index + 1,
|
|
65
|
+
found: m[0],
|
|
66
|
+
rationale:
|
|
67
|
+
'Arbitrary pixel dimensions bypass the dimension ladder and token scale. Only 1-2px (borders, outlines, hairlines) may be literal.',
|
|
68
|
+
suggestion: `Replace "${m[0]}" with the nearest system class (e.g. .gap-16, .pad-sm, .w-64) or a spacing/dimension token.`
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Rule 3: Unmapped variables
|
|
73
|
+
for (const vm of cleanLine.matchAll(/var\((--[a-zA-Z0-9_-]+)/g)) {
|
|
74
|
+
const varName = vm[1];
|
|
75
|
+
if (this.validTokens.has(varName) || localProperties.has(varName)) continue;
|
|
76
|
+
const closest = findClosestMatches(varName, this.validTokens, 3, 5);
|
|
77
|
+
const suggestion =
|
|
78
|
+
closest.length > 0
|
|
79
|
+
? `Did you mean one of these?\n - ${closest.map((t) => `var(${t})`).join('\n - ')}`
|
|
80
|
+
: `Token "${varName}" is not in the system contract. Use an existing token or define it in _00_tokens.sass / _09_own.sass.`;
|
|
81
|
+
|
|
82
|
+
diagnostics.push({
|
|
83
|
+
rule: 'fs/token-purity',
|
|
84
|
+
severity: 'error',
|
|
85
|
+
file: relPath,
|
|
86
|
+
line: lineNum,
|
|
87
|
+
column: vm.index + 1,
|
|
88
|
+
found: vm[0],
|
|
89
|
+
rationale: `The custom property "${varName}" is not defined in the system token contract.`,
|
|
90
|
+
suggestion
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return diagnostics;
|
|
96
|
+
}
|
|
97
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,113 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@fractaldesign/fractalstyler",
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "A composition styling system, shipped as plain CSS and as editable SASS. The class registry is the public API: compose in markup, write no stylesheet.",
|
|
6
|
+
"bin": {
|
|
7
|
+
"fractalstyler": "cli/main.mjs",
|
|
8
|
+
"fractalstyler-lint": "lint/cli.mjs"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"registry": "node scripts/update-registry.js && node scripts/class-vocab.js",
|
|
12
|
+
"vocab": "node scripts/class-vocab.js",
|
|
13
|
+
"lint": "node lint/cli.mjs",
|
|
14
|
+
"browser": "node lint/browser.mjs",
|
|
15
|
+
"dev": "vite dev",
|
|
16
|
+
"preview": "vite preview",
|
|
17
|
+
"build": "npm run registry && npm run prepack",
|
|
18
|
+
"prepare": "svelte-kit sync || echo ''",
|
|
19
|
+
"prepack": "npm run registry && svelte-kit sync && svelte-package && npm run css && ([ -f lint/cli.mjs ] && chmod +x lint/cli.mjs || true) && publint",
|
|
20
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && node scripts/validate-deck.js && node lint/cli.mjs",
|
|
21
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
22
|
+
"validate:deck": "node scripts/validate-deck.js",
|
|
23
|
+
"css": "node scripts/build-css.js",
|
|
24
|
+
"version": "npm run registry && git add -A",
|
|
25
|
+
"pair": "node scripts/generate-pairs.mjs && node scripts/update-registry.js"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"!dist/**/*.test.*",
|
|
30
|
+
"!dist/**/*.spec.*",
|
|
31
|
+
"registry.json",
|
|
32
|
+
"skills",
|
|
33
|
+
"lint",
|
|
34
|
+
"data",
|
|
35
|
+
"cli",
|
|
36
|
+
"docs/REGISTRY.md",
|
|
37
|
+
"docs/REGISTRY.api.md",
|
|
38
|
+
"docs/references",
|
|
39
|
+
"scripts/update-registry.js",
|
|
40
|
+
"scripts/class-vocab.js"
|
|
41
|
+
],
|
|
42
|
+
"sideEffects": [
|
|
43
|
+
"**/*.css"
|
|
44
|
+
],
|
|
45
|
+
"svelte": "./dist/index.js",
|
|
46
|
+
"types": "./dist/index.d.ts",
|
|
47
|
+
"type": "module",
|
|
48
|
+
"exports": {
|
|
49
|
+
".": {
|
|
50
|
+
"types": "./dist/index.d.ts",
|
|
51
|
+
"svelte": "./dist/index.js",
|
|
52
|
+
"default": "./dist/index.js"
|
|
53
|
+
},
|
|
54
|
+
"./styles": {
|
|
55
|
+
"types": "./dist/asset.d.ts",
|
|
56
|
+
"default": "./dist/styles/index.sass"
|
|
57
|
+
},
|
|
58
|
+
"./styles/*": "./dist/styles/*",
|
|
59
|
+
"./tokens": {
|
|
60
|
+
"types": "./dist/asset.d.ts",
|
|
61
|
+
"default": "./dist/styles/_00_tokens.sass"
|
|
62
|
+
},
|
|
63
|
+
"./css": {
|
|
64
|
+
"types": "./dist/asset.d.ts",
|
|
65
|
+
"default": "./dist/css/fractalstyler.css"
|
|
66
|
+
},
|
|
67
|
+
"./css/min": {
|
|
68
|
+
"types": "./dist/asset.d.ts",
|
|
69
|
+
"default": "./dist/css/fractalstyler.min.css"
|
|
70
|
+
},
|
|
71
|
+
"./recipes": "./data/recipes.json",
|
|
72
|
+
"./package.json": "./package.json"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"svelte": "^5.0.0",
|
|
76
|
+
"sass": "^1.102.0"
|
|
77
|
+
},
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@sveltejs/adapter-auto": "^7.0.1",
|
|
80
|
+
"@sveltejs/kit": "^2.63.0",
|
|
81
|
+
"@sveltejs/package": "^2.5.8",
|
|
82
|
+
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
83
|
+
"@types/node": "^26.2.0",
|
|
84
|
+
"publint": "^0.3.21",
|
|
85
|
+
"sass": "^1.102.0",
|
|
86
|
+
"svelte": "^5.56.1",
|
|
87
|
+
"svelte-check": "^4.6.0",
|
|
88
|
+
"typescript": "^6.0.3",
|
|
89
|
+
"vite": "^8.0.16"
|
|
90
|
+
},
|
|
91
|
+
"keywords": [
|
|
92
|
+
"css",
|
|
93
|
+
"sass",
|
|
94
|
+
"design-system",
|
|
95
|
+
"styling",
|
|
96
|
+
"svelte",
|
|
97
|
+
"sveltekit",
|
|
98
|
+
"utility-classes",
|
|
99
|
+
"design-tokens",
|
|
100
|
+
"fractal"
|
|
101
|
+
],
|
|
102
|
+
"dependencies": {
|
|
103
|
+
"@modelcontextprotocol/sdk": "^1.30.0"
|
|
104
|
+
},
|
|
105
|
+
"engines": {
|
|
106
|
+
"node": ">=18"
|
|
107
|
+
},
|
|
108
|
+
"peerDependenciesMeta": {
|
|
109
|
+
"sass": {
|
|
110
|
+
"optional": true
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|