@clhaas/palette-kit 0.1.8 → 0.4.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/CHANGELOG.md +59 -0
- package/README.md +80 -177
- package/dist/contrast/contrast.d.ts +16 -0
- package/dist/contrast/contrast.js +102 -0
- package/dist/core/intent-registry.d.ts +11 -0
- package/dist/core/intent-registry.js +70 -0
- package/dist/core/oklch.d.ts +16 -0
- package/dist/core/oklch.js +56 -0
- package/dist/create-palette-kit.d.ts +9 -0
- package/dist/create-palette-kit.js +67 -0
- package/dist/engine/context/context.d.ts +13 -0
- package/dist/engine/context/context.js +37 -0
- package/dist/engine/level/curves.d.ts +17 -0
- package/dist/engine/level/curves.js +49 -0
- package/dist/engine/level/level.d.ts +4 -0
- package/dist/engine/level/level.js +13 -0
- package/dist/engine/relation/relation.d.ts +105 -0
- package/dist/engine/relation/relation.js +137 -0
- package/dist/engine/resolve/resolve.d.ts +36 -0
- package/dist/engine/resolve/resolve.js +116 -0
- package/dist/engine/state/state.d.ts +46 -0
- package/dist/engine/state/state.js +68 -0
- package/dist/engine/usage/fill.d.ts +9 -0
- package/dist/engine/usage/fill.js +9 -0
- package/dist/engine/usage/lines.d.ts +9 -0
- package/dist/engine/usage/lines.js +9 -0
- package/dist/engine/usage/overlays.d.ts +9 -0
- package/dist/engine/usage/overlays.js +9 -0
- package/dist/engine/usage/strategy.d.ts +56 -0
- package/dist/engine/usage/strategy.js +30 -0
- package/dist/engine/usage/visualVocabulary.d.ts +9 -0
- package/dist/engine/usage/visualVocabulary.js +9 -0
- package/dist/export/serialize.d.ts +14 -0
- package/dist/export/serialize.js +89 -0
- package/dist/export/types.d.ts +37 -0
- package/dist/export/types.js +31 -0
- package/dist/index.d.ts +3 -22
- package/dist/index.js +2 -18
- package/dist/operators/convert.d.ts +32 -0
- package/dist/operators/convert.js +80 -0
- package/dist/presets/presets.d.ts +95 -0
- package/dist/presets/presets.js +308 -0
- package/dist/types/index.d.ts +111 -0
- package/dist/utils/errors/errors.d.ts +17 -0
- package/dist/utils/errors/errors.js +22 -0
- package/docs/API.md +167 -0
- package/docs/Alpha.md +14 -0
- package/docs/Architecture.md +56 -0
- package/docs/CLI.md +22 -0
- package/docs/Concepts.md +73 -0
- package/docs/Config.md +144 -0
- package/docs/Diagnostics.md +22 -0
- package/docs/Exporters.md +33 -0
- package/docs/FAQ.md +59 -0
- package/docs/Migration.md +61 -0
- package/docs/Overlays.md +33 -0
- package/docs/README.md +60 -0
- package/docs/Text.md +41 -0
- package/docs/Tokens.md +42 -0
- package/docs/Usage-JSON.md +39 -0
- package/docs/Usage-ReactNative.md +63 -0
- package/docs/Usage-Web.md +66 -0
- package/docs/Validation.md +97 -0
- package/docs/Why.md +37 -0
- package/docs/_api-surface.md +53 -0
- package/docs/snippets/serialize-oklch.md +9 -0
- package/docs/spec.md +98 -0
- package/package.json +74 -52
- package/dist/alpha/generateAlphaScale.d.ts +0 -5
- package/dist/alpha/generateAlphaScale.js +0 -34
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -150
- package/dist/contrast/apca.d.ts +0 -2
- package/dist/contrast/apca.js +0 -5
- package/dist/contrast/onSolid.d.ts +0 -6
- package/dist/contrast/onSolid.js +0 -28
- package/dist/contrast/solveText.d.ts +0 -2
- package/dist/contrast/solveText.js +0 -31
- package/dist/createTheme.d.ts +0 -38
- package/dist/createTheme.js +0 -148
- package/dist/data/radixSeeds.d.ts +0 -3
- package/dist/data/radixSeeds.js +0 -34
- package/dist/diagnostics/analyzeScale.d.ts +0 -2
- package/dist/diagnostics/analyzeScale.js +0 -7
- package/dist/diagnostics/analyzeTheme.d.ts +0 -2
- package/dist/diagnostics/analyzeTheme.js +0 -35
- package/dist/diagnostics/warnings.d.ts +0 -2
- package/dist/diagnostics/warnings.js +0 -20
- package/dist/engine/curves.d.ts +0 -9
- package/dist/engine/curves.js +0 -48
- package/dist/engine/oklch.d.ts +0 -8
- package/dist/engine/oklch.js +0 -40
- package/dist/engine/templates.d.ts +0 -14
- package/dist/engine/templates.js +0 -45
- package/dist/exporters/selectColorMode.d.ts +0 -2
- package/dist/exporters/selectColorMode.js +0 -19
- package/dist/exporters/toCssVars.d.ts +0 -13
- package/dist/exporters/toCssVars.js +0 -108
- package/dist/exporters/toJson.d.ts +0 -3
- package/dist/exporters/toJson.js +0 -25
- package/dist/exporters/toReactNative.d.ts +0 -54
- package/dist/exporters/toReactNative.js +0 -33
- package/dist/exporters/toTailwind.d.ts +0 -17
- package/dist/exporters/toTailwind.js +0 -111
- package/dist/exporters/toTs.d.ts +0 -3
- package/dist/exporters/toTs.js +0 -43
- package/dist/generateScale.d.ts +0 -48
- package/dist/generateScale.js +0 -274
- package/dist/overlays/generateOverlayScale.d.ts +0 -2
- package/dist/overlays/generateOverlayScale.js +0 -34
- package/dist/text/generateTextScale.d.ts +0 -8
- package/dist/text/generateTextScale.js +0 -18
- package/dist/text/resolveOnBgText.d.ts +0 -9
- package/dist/text/resolveOnBgText.js +0 -28
- package/dist/tokens/presetRadixLikeUi.d.ts +0 -5
- package/dist/tokens/presetRadixLikeUi.js +0 -55
- package/dist/types.d.ts +0 -69
- /package/dist/{types.js → types/index.js} +0 -0
package/package.json
CHANGED
|
@@ -1,54 +1,76 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
2
|
+
"author": "Claus Haas",
|
|
3
|
+
"dependencies": {
|
|
4
|
+
"apca-w3": "^0.1.9"
|
|
5
|
+
},
|
|
6
|
+
"description": "Easy way to create the color palette of your app",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@biomejs/biome": "^2.4.13",
|
|
9
|
+
"@types/apca-w3": "^0.1.3",
|
|
10
|
+
"@types/node": "^25.6.0",
|
|
11
|
+
"markdownlint-cli": "^0.48.0",
|
|
12
|
+
"tsx": "^4.21.0",
|
|
13
|
+
"typescript": "^6.0.3",
|
|
14
|
+
"vitest": "^4.1.5"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"default": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"CHANGELOG.md",
|
|
27
|
+
"docs/README.md",
|
|
28
|
+
"docs/API.md",
|
|
29
|
+
"docs/Config.md",
|
|
30
|
+
"docs/Concepts.md",
|
|
31
|
+
"docs/Architecture.md",
|
|
32
|
+
"docs/Validation.md",
|
|
33
|
+
"docs/FAQ.md",
|
|
34
|
+
"docs/Usage-Web.md",
|
|
35
|
+
"docs/Usage-ReactNative.md",
|
|
36
|
+
"docs/Usage-JSON.md",
|
|
37
|
+
"docs/CLI.md",
|
|
38
|
+
"docs/Exporters.md",
|
|
39
|
+
"docs/Tokens.md",
|
|
40
|
+
"docs/Diagnostics.md",
|
|
41
|
+
"docs/Alpha.md",
|
|
42
|
+
"docs/Overlays.md",
|
|
43
|
+
"docs/Text.md",
|
|
44
|
+
"docs/Why.md",
|
|
45
|
+
"docs/Migration.md",
|
|
46
|
+
"docs/spec.md",
|
|
47
|
+
"docs/_api-surface.md",
|
|
48
|
+
"docs/snippets/serialize-oklch.md"
|
|
49
|
+
],
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"main": "dist/index.js",
|
|
52
|
+
"name": "@clhaas/palette-kit",
|
|
53
|
+
"packageManager": "pnpm@10.33.2",
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public"
|
|
56
|
+
},
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "https://github.com/claushaas/palette-kit"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsc -p tsconfig.build.json",
|
|
63
|
+
"clean": "rm -rf dist",
|
|
64
|
+
"lint": "pnpm run lint:biome && pnpm run lint:md && pnpm run typecheck",
|
|
65
|
+
"lint:biome": "biome check --unsafe --write",
|
|
66
|
+
"lint:md": "markdownlint \"**/*.md\" --ignore node_modules --fix",
|
|
67
|
+
"prepublishOnly": "npm run build",
|
|
68
|
+
"test": "vitest run",
|
|
69
|
+
"test:watch": "vitest",
|
|
70
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
71
|
+
"update": "pnpm dlx npm-check-updates -i"
|
|
72
|
+
},
|
|
73
|
+
"type": "module",
|
|
74
|
+
"types": "dist/index.d.ts",
|
|
75
|
+
"version": "0.4.0"
|
|
54
76
|
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import Color from "colorjs.io";
|
|
2
|
-
const steps = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
|
3
|
-
const alphaCurve = {
|
|
4
|
-
1: 0.05,
|
|
5
|
-
2: 0.1,
|
|
6
|
-
3: 0.15,
|
|
7
|
-
4: 0.2,
|
|
8
|
-
5: 0.3,
|
|
9
|
-
6: 0.4,
|
|
10
|
-
7: 0.5,
|
|
11
|
-
8: 0.6,
|
|
12
|
-
9: 0.7,
|
|
13
|
-
10: 0.8,
|
|
14
|
-
11: 0.9,
|
|
15
|
-
12: 0.95,
|
|
16
|
-
};
|
|
17
|
-
function mixWithAlpha(foreground, alpha) {
|
|
18
|
-
const color = new Color(foreground).to("srgb");
|
|
19
|
-
const [r, g, b] = color.coords;
|
|
20
|
-
const hex = new Color({ space: "srgb", coords: [r, g, b], alpha }).toString({
|
|
21
|
-
format: "hex",
|
|
22
|
-
});
|
|
23
|
-
return hex;
|
|
24
|
-
}
|
|
25
|
-
export function generateAlphaScale(base, _background) {
|
|
26
|
-
const light = {};
|
|
27
|
-
const dark = {};
|
|
28
|
-
for (const step of steps) {
|
|
29
|
-
const alpha = alphaCurve[step];
|
|
30
|
-
light[step] = mixWithAlpha(base, alpha);
|
|
31
|
-
dark[step] = mixWithAlpha(base, alpha);
|
|
32
|
-
}
|
|
33
|
-
return { light, dark };
|
|
34
|
-
}
|
package/dist/cli.d.ts
DELETED
package/dist/cli.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { createRequire } from "node:module";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { pathToFileURL } from "node:url";
|
|
6
|
-
import { createTheme } from "./createTheme.js";
|
|
7
|
-
import { toTs, toTsWithMode } from "./exporters/toTs.js";
|
|
8
|
-
const DEFAULT_CONFIG_FILES = [
|
|
9
|
-
"palette.config.mjs",
|
|
10
|
-
"palette.config.js",
|
|
11
|
-
"palette.config.cjs",
|
|
12
|
-
"palette.config.json",
|
|
13
|
-
];
|
|
14
|
-
const args = process.argv.slice(2);
|
|
15
|
-
const command = args[0];
|
|
16
|
-
if (!command || command === "--help" || command === "-h") {
|
|
17
|
-
printHelp();
|
|
18
|
-
process.exit(0);
|
|
19
|
-
}
|
|
20
|
-
if (command !== "generate") {
|
|
21
|
-
console.error(`Unknown command: ${command}`);
|
|
22
|
-
printHelp();
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
const options = parseArgs(args.slice(1));
|
|
26
|
-
const configPath = resolveConfigPath(options.configPath);
|
|
27
|
-
const outPath = path.resolve(process.cwd(), options.outPath ?? "src/theme.ts");
|
|
28
|
-
const mode = options.mode;
|
|
29
|
-
const config = await loadConfig(configPath);
|
|
30
|
-
if (!config || typeof config !== "object") {
|
|
31
|
-
console.error("Config must export a plain object with createTheme options.");
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
if (!("neutral" in config) || !("accent" in config)) {
|
|
35
|
-
console.error("Config must include at least `neutral` and `accent` sources.");
|
|
36
|
-
process.exit(1);
|
|
37
|
-
}
|
|
38
|
-
const theme = createTheme(config);
|
|
39
|
-
const ts = mode ? toTsWithMode(theme, mode) : toTs(theme);
|
|
40
|
-
mkdirSync(path.dirname(outPath), { recursive: true });
|
|
41
|
-
writeFileSync(outPath, ts);
|
|
42
|
-
console.log(`Generated ${path.relative(process.cwd(), outPath)}`);
|
|
43
|
-
function parseArgs(input) {
|
|
44
|
-
const options = {};
|
|
45
|
-
for (let i = 0; i < input.length; i += 1) {
|
|
46
|
-
const arg = input[i];
|
|
47
|
-
if (arg === "--config" || arg === "-c") {
|
|
48
|
-
options.configPath = input[i + 1];
|
|
49
|
-
i += 1;
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
if (arg?.startsWith("--config=")) {
|
|
53
|
-
options.configPath = arg.split("=")[1];
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if (arg === "--out" || arg === "-o") {
|
|
57
|
-
options.outPath = input[i + 1];
|
|
58
|
-
i += 1;
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (arg?.startsWith("--out=")) {
|
|
62
|
-
options.outPath = arg.split("=")[1];
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
if (arg === "--mode" || arg === "-m") {
|
|
66
|
-
const value = input[i + 1];
|
|
67
|
-
if (!value) {
|
|
68
|
-
console.error('Missing value for --mode. Use "srgb" or "p3".');
|
|
69
|
-
process.exit(1);
|
|
70
|
-
}
|
|
71
|
-
if (value !== "srgb" && value !== "p3") {
|
|
72
|
-
console.error(`Invalid mode: ${value}. Use "srgb" or "p3".`);
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
options.mode = value;
|
|
76
|
-
i += 1;
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
if (arg?.startsWith("--mode=")) {
|
|
80
|
-
const value = arg.split("=")[1];
|
|
81
|
-
if (!value) {
|
|
82
|
-
console.error('Missing value for --mode. Use "srgb" or "p3".');
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
if (value !== "srgb" && value !== "p3") {
|
|
86
|
-
console.error(`Invalid mode: ${value}. Use "srgb" or "p3".`);
|
|
87
|
-
process.exit(1);
|
|
88
|
-
}
|
|
89
|
-
options.mode = value;
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
if (arg === "--help" || arg === "-h") {
|
|
93
|
-
printHelp();
|
|
94
|
-
process.exit(0);
|
|
95
|
-
}
|
|
96
|
-
console.error(`Unknown argument: ${arg}`);
|
|
97
|
-
printHelp();
|
|
98
|
-
process.exit(1);
|
|
99
|
-
}
|
|
100
|
-
return options;
|
|
101
|
-
}
|
|
102
|
-
function resolveConfigPath(configPath) {
|
|
103
|
-
if (configPath) {
|
|
104
|
-
const resolved = path.resolve(process.cwd(), configPath);
|
|
105
|
-
if (!existsSync(resolved)) {
|
|
106
|
-
console.error(`Config not found: ${configPath}`);
|
|
107
|
-
process.exit(1);
|
|
108
|
-
}
|
|
109
|
-
return resolved;
|
|
110
|
-
}
|
|
111
|
-
for (const filename of DEFAULT_CONFIG_FILES) {
|
|
112
|
-
const candidate = path.resolve(process.cwd(), filename);
|
|
113
|
-
if (existsSync(candidate)) {
|
|
114
|
-
return candidate;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
console.error("No config file found. Expected one of:");
|
|
118
|
-
for (const filename of DEFAULT_CONFIG_FILES) {
|
|
119
|
-
console.error(` - ${filename}`);
|
|
120
|
-
}
|
|
121
|
-
process.exit(1);
|
|
122
|
-
throw new Error("No config file found.");
|
|
123
|
-
}
|
|
124
|
-
async function loadConfig(filePath) {
|
|
125
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
126
|
-
if (ext === ".json") {
|
|
127
|
-
const raw = readFileSync(filePath, "utf8");
|
|
128
|
-
return JSON.parse(raw);
|
|
129
|
-
}
|
|
130
|
-
if (ext === ".cjs") {
|
|
131
|
-
const require = createRequire(import.meta.url);
|
|
132
|
-
return require(filePath);
|
|
133
|
-
}
|
|
134
|
-
const module = await import(pathToFileURL(filePath).href);
|
|
135
|
-
return (module.default ?? module.config ?? module.theme ?? module);
|
|
136
|
-
}
|
|
137
|
-
function printHelp() {
|
|
138
|
-
console.log([
|
|
139
|
-
"palette-kit generate [options]",
|
|
140
|
-
"",
|
|
141
|
-
"Options:",
|
|
142
|
-
" -c, --config <file> Config file (default: palette.config.*)",
|
|
143
|
-
" -o, --out <file> Output file (default: src/theme.ts)",
|
|
144
|
-
" -m, --mode <srgb|p3> Export mode (default: theme as-is)",
|
|
145
|
-
" -h, --help Show help",
|
|
146
|
-
"",
|
|
147
|
-
"Example:",
|
|
148
|
-
" palette-kit generate --config palette.config.mjs --out src/theme.ts",
|
|
149
|
-
].join("\n"));
|
|
150
|
-
}
|
package/dist/contrast/apca.d.ts
DELETED
package/dist/contrast/apca.js
DELETED
package/dist/contrast/onSolid.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { apcaContrast } from "./apca.js";
|
|
2
|
-
const white = "#ffffff";
|
|
3
|
-
const black = "#000000";
|
|
4
|
-
const alphaLevels = {
|
|
5
|
-
primary: 0.92,
|
|
6
|
-
secondary: 0.72,
|
|
7
|
-
disabled: 0.48,
|
|
8
|
-
};
|
|
9
|
-
function withAlpha(hex, alpha) {
|
|
10
|
-
const normalized = hex.replace("#", "");
|
|
11
|
-
const alphaHex = Math.round(alpha * 255)
|
|
12
|
-
.toString(16)
|
|
13
|
-
.padStart(2, "0");
|
|
14
|
-
return `#${normalized}${alphaHex}`;
|
|
15
|
-
}
|
|
16
|
-
function chooseTextColor(background) {
|
|
17
|
-
const whiteScore = Math.abs(apcaContrast(white, background));
|
|
18
|
-
const blackScore = Math.abs(apcaContrast(black, background));
|
|
19
|
-
return whiteScore >= blackScore ? white : black;
|
|
20
|
-
}
|
|
21
|
-
export function onSolidTextTokens(background) {
|
|
22
|
-
const base = chooseTextColor(background);
|
|
23
|
-
return {
|
|
24
|
-
primary: withAlpha(base, alphaLevels.primary),
|
|
25
|
-
secondary: withAlpha(base, alphaLevels.secondary),
|
|
26
|
-
disabled: withAlpha(base, alphaLevels.disabled),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import Color from "colorjs.io";
|
|
2
|
-
import { compressToSrgb, oklchToHex } from "../engine/oklch.js";
|
|
3
|
-
import { apcaContrast } from "./apca.js";
|
|
4
|
-
function clamp(value, min, max) {
|
|
5
|
-
return Math.min(max, Math.max(min, value));
|
|
6
|
-
}
|
|
7
|
-
function adjustLightness(oklch, background, target, maxIterations = 24) {
|
|
8
|
-
const bg = new Color(background).to("oklch");
|
|
9
|
-
const bgL = bg.coords[0] ?? 0;
|
|
10
|
-
const direction = bgL > 0.5 ? -1 : 1;
|
|
11
|
-
let current = { ...oklch };
|
|
12
|
-
for (let i = 0; i < maxIterations; i += 1) {
|
|
13
|
-
const contrast = Math.abs(apcaContrast(oklchToHex(current), background));
|
|
14
|
-
if (contrast >= target) {
|
|
15
|
-
return current;
|
|
16
|
-
}
|
|
17
|
-
current = {
|
|
18
|
-
...current,
|
|
19
|
-
l: clamp(current.l + direction * 0.02, 0, 1),
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
return current;
|
|
23
|
-
}
|
|
24
|
-
export function adjustTextColor(foreground, background, target) {
|
|
25
|
-
const fg = new Color(foreground).to("oklch");
|
|
26
|
-
const [l, c, h] = fg.coords;
|
|
27
|
-
let candidate = { l: l ?? 0, c: c ?? 0, h: h ?? 0 };
|
|
28
|
-
candidate = adjustLightness(candidate, background, target);
|
|
29
|
-
candidate = compressToSrgb(candidate);
|
|
30
|
-
return oklchToHex(candidate);
|
|
31
|
-
}
|
package/dist/createTheme.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { GenerateScaleOptions } from "./generateScale.js";
|
|
2
|
-
import type { ColorHex, ColorSource, Theme } from "./types.js";
|
|
3
|
-
export type TokenOverrides = {
|
|
4
|
-
light?: Record<string, ColorHex>;
|
|
5
|
-
dark?: Record<string, ColorHex>;
|
|
6
|
-
};
|
|
7
|
-
export type CreateThemeOptions = {
|
|
8
|
-
neutral: ColorSource;
|
|
9
|
-
accent: ColorSource;
|
|
10
|
-
semantic?: {
|
|
11
|
-
success?: ColorSource;
|
|
12
|
-
warning?: ColorSource;
|
|
13
|
-
danger?: ColorSource;
|
|
14
|
-
};
|
|
15
|
-
extras?: Record<string, ColorSource>;
|
|
16
|
-
tokens?: {
|
|
17
|
-
preset?: "radix-like-ui";
|
|
18
|
-
overrides?: TokenOverrides;
|
|
19
|
-
};
|
|
20
|
-
alpha?: {
|
|
21
|
-
enabled?: boolean;
|
|
22
|
-
background?: {
|
|
23
|
-
light?: ColorHex;
|
|
24
|
-
dark?: ColorHex;
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
text?: {
|
|
28
|
-
darkBase?: ColorHex;
|
|
29
|
-
lightBase?: ColorHex;
|
|
30
|
-
};
|
|
31
|
-
contrast?: {
|
|
32
|
-
textPrimary?: number;
|
|
33
|
-
textSecondary?: number;
|
|
34
|
-
};
|
|
35
|
-
scale?: Omit<GenerateScaleOptions, "source" | "mode" | "p3">;
|
|
36
|
-
p3?: boolean;
|
|
37
|
-
};
|
|
38
|
-
export declare function createTheme(options: CreateThemeOptions): Theme;
|
package/dist/createTheme.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { generateAlphaScale } from "./alpha/generateAlphaScale.js";
|
|
2
|
-
import { onSolidTextTokens } from "./contrast/onSolid.js";
|
|
3
|
-
import { analyzeTheme } from "./diagnostics/analyzeTheme.js";
|
|
4
|
-
import { generateScale } from "./generateScale.js";
|
|
5
|
-
import { generateOverlayScale } from "./overlays/generateOverlayScale.js";
|
|
6
|
-
import { generateTextScale } from "./text/generateTextScale.js";
|
|
7
|
-
import { buildPresetTokens } from "./tokens/presetRadixLikeUi.js";
|
|
8
|
-
export function createTheme(options) {
|
|
9
|
-
const includeP3 = options.p3 ?? false;
|
|
10
|
-
const scaleOptions = options.scale ?? {};
|
|
11
|
-
const scales = {
|
|
12
|
-
neutral: generateScale({ source: options.neutral, ...scaleOptions, p3: includeP3 }),
|
|
13
|
-
accent: generateScale({ source: options.accent, ...scaleOptions, p3: includeP3 }),
|
|
14
|
-
};
|
|
15
|
-
if (options.semantic?.success) {
|
|
16
|
-
scales.success = generateScale({
|
|
17
|
-
source: options.semantic.success,
|
|
18
|
-
...scaleOptions,
|
|
19
|
-
p3: includeP3,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
if (options.semantic?.warning) {
|
|
23
|
-
scales.warning = generateScale({
|
|
24
|
-
source: options.semantic.warning,
|
|
25
|
-
...scaleOptions,
|
|
26
|
-
p3: includeP3,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
if (options.semantic?.danger) {
|
|
30
|
-
scales.danger = generateScale({
|
|
31
|
-
source: options.semantic.danger,
|
|
32
|
-
...scaleOptions,
|
|
33
|
-
p3: includeP3,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
if (options.extras) {
|
|
37
|
-
for (const [key, source] of Object.entries(options.extras)) {
|
|
38
|
-
scales[key] = generateScale({ source, ...scaleOptions, p3: includeP3 });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
const preset = options.tokens?.preset ?? "radix-like-ui";
|
|
42
|
-
const tokens = preset === "radix-like-ui" ? buildPresetTokens(scales) : { light: {}, dark: {} };
|
|
43
|
-
const accentScale = scales.accent;
|
|
44
|
-
const lightOnSolid = onSolidTextTokens(accentScale.light[9]);
|
|
45
|
-
const darkOnSolid = onSolidTextTokens(accentScale.dark[9]);
|
|
46
|
-
tokens.light["onSolid.primary"] = lightOnSolid.primary;
|
|
47
|
-
tokens.light["onSolid.secondary"] = lightOnSolid.secondary;
|
|
48
|
-
tokens.light["onSolid.disabled"] = lightOnSolid.disabled;
|
|
49
|
-
tokens.dark["onSolid.primary"] = darkOnSolid.primary;
|
|
50
|
-
tokens.dark["onSolid.secondary"] = darkOnSolid.secondary;
|
|
51
|
-
tokens.dark["onSolid.disabled"] = darkOnSolid.disabled;
|
|
52
|
-
const textScale = generateTextScale({
|
|
53
|
-
darkBase: options.text?.darkBase,
|
|
54
|
-
lightBase: options.text?.lightBase,
|
|
55
|
-
});
|
|
56
|
-
const darkTextSteps = {
|
|
57
|
-
primary: 12,
|
|
58
|
-
secondary: 10,
|
|
59
|
-
tertiary: 9,
|
|
60
|
-
disabled: 8,
|
|
61
|
-
};
|
|
62
|
-
const lightTextSteps = {
|
|
63
|
-
primary: 1,
|
|
64
|
-
secondary: 3,
|
|
65
|
-
tertiary: 4,
|
|
66
|
-
disabled: 5,
|
|
67
|
-
};
|
|
68
|
-
const midDarkTextSteps = {
|
|
69
|
-
primary: 12,
|
|
70
|
-
secondary: 11,
|
|
71
|
-
};
|
|
72
|
-
const midLightTextSteps = {
|
|
73
|
-
primary: 1,
|
|
74
|
-
secondary: 3,
|
|
75
|
-
};
|
|
76
|
-
const onBgLightMode = {
|
|
77
|
-
light: { scale: "dark", steps: darkTextSteps },
|
|
78
|
-
mid: { scale: "dark", steps: midDarkTextSteps },
|
|
79
|
-
dark: { scale: "light", steps: lightTextSteps },
|
|
80
|
-
};
|
|
81
|
-
const onBgDarkMode = {
|
|
82
|
-
light: { scale: "light", steps: lightTextSteps },
|
|
83
|
-
mid: { scale: "light", steps: midLightTextSteps },
|
|
84
|
-
dark: { scale: "dark", steps: darkTextSteps },
|
|
85
|
-
};
|
|
86
|
-
const applyOnBgTokens = (target, mapping) => {
|
|
87
|
-
for (const [zone, config] of Object.entries(mapping)) {
|
|
88
|
-
const scale = config.scale === "dark" ? textScale.dark : textScale.light;
|
|
89
|
-
for (const [role, step] of Object.entries(config.steps)) {
|
|
90
|
-
target[`text.onBg.${zone}.${role}`] = scale[step];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
for (const [step, value] of Object.entries(textScale.dark)) {
|
|
95
|
-
tokens.light[`text.dark.${step}`] = value;
|
|
96
|
-
tokens.dark[`text.dark.${step}`] = value;
|
|
97
|
-
}
|
|
98
|
-
for (const [step, value] of Object.entries(textScale.light)) {
|
|
99
|
-
tokens.light[`text.light.${step}`] = value;
|
|
100
|
-
tokens.dark[`text.light.${step}`] = value;
|
|
101
|
-
}
|
|
102
|
-
for (const [key, step] of Object.entries(darkTextSteps)) {
|
|
103
|
-
const token = `text.dark.${key}`;
|
|
104
|
-
tokens.light[token] = textScale.dark[step];
|
|
105
|
-
tokens.dark[token] = textScale.dark[step];
|
|
106
|
-
}
|
|
107
|
-
for (const [key, step] of Object.entries(lightTextSteps)) {
|
|
108
|
-
const token = `text.light.${key}`;
|
|
109
|
-
tokens.light[token] = textScale.light[step];
|
|
110
|
-
tokens.dark[token] = textScale.light[step];
|
|
111
|
-
}
|
|
112
|
-
applyOnBgTokens(tokens.light, onBgLightMode);
|
|
113
|
-
applyOnBgTokens(tokens.dark, onBgDarkMode);
|
|
114
|
-
tokens.light["text.primary"] = tokens.light["text.onBg.light.primary"];
|
|
115
|
-
tokens.light["text.secondary"] = tokens.light["text.onBg.light.secondary"];
|
|
116
|
-
tokens.light["text.tertiary"] = tokens.light["text.onBg.light.tertiary"];
|
|
117
|
-
tokens.light["text.disabled"] = tokens.light["text.onBg.light.disabled"];
|
|
118
|
-
tokens.dark["text.primary"] = tokens.dark["text.onBg.light.primary"];
|
|
119
|
-
tokens.dark["text.secondary"] = tokens.dark["text.onBg.light.secondary"];
|
|
120
|
-
tokens.dark["text.tertiary"] = tokens.dark["text.onBg.light.tertiary"];
|
|
121
|
-
tokens.dark["text.disabled"] = tokens.dark["text.onBg.light.disabled"];
|
|
122
|
-
if (options.tokens?.overrides?.light) {
|
|
123
|
-
Object.assign(tokens.light, options.tokens.overrides.light);
|
|
124
|
-
}
|
|
125
|
-
if (options.tokens?.overrides?.dark) {
|
|
126
|
-
Object.assign(tokens.dark, options.tokens.overrides.dark);
|
|
127
|
-
}
|
|
128
|
-
let alpha;
|
|
129
|
-
if (options.alpha?.enabled !== false) {
|
|
130
|
-
const background = {
|
|
131
|
-
light: options.alpha?.background?.light ?? "#ffffff",
|
|
132
|
-
dark: options.alpha?.background?.dark ?? "#111111",
|
|
133
|
-
};
|
|
134
|
-
alpha = Object.fromEntries(Object.entries(scales).map(([slot, scale]) => [
|
|
135
|
-
slot,
|
|
136
|
-
generateAlphaScale(scale.light[9], background),
|
|
137
|
-
]));
|
|
138
|
-
}
|
|
139
|
-
const overlay = generateOverlayScale();
|
|
140
|
-
const diagnostics = analyzeTheme({ scales, tokens, alpha, overlay });
|
|
141
|
-
return {
|
|
142
|
-
scales,
|
|
143
|
-
tokens,
|
|
144
|
-
alpha,
|
|
145
|
-
overlay,
|
|
146
|
-
diagnostics,
|
|
147
|
-
};
|
|
148
|
-
}
|
package/dist/data/radixSeeds.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
export const radixSeeds = {
|
|
2
|
-
amber: "#ffc53d",
|
|
3
|
-
blue: "#0090ff",
|
|
4
|
-
bronze: "#a18072",
|
|
5
|
-
brown: "#ad7f58",
|
|
6
|
-
crimson: "#e93d82",
|
|
7
|
-
cyan: "#00a2c7",
|
|
8
|
-
gold: "#978365",
|
|
9
|
-
grass: "#46a758",
|
|
10
|
-
gray: "#8d8d8d",
|
|
11
|
-
green: "#30a46c",
|
|
12
|
-
indigo: "#3e63dd",
|
|
13
|
-
iris: "#5b5bd6",
|
|
14
|
-
jade: "#29a383",
|
|
15
|
-
lime: "#bdee63",
|
|
16
|
-
mauve: "#8e8c99",
|
|
17
|
-
mint: "#86ead4",
|
|
18
|
-
olive: "#898e87",
|
|
19
|
-
orange: "#f76b15",
|
|
20
|
-
pink: "#d6409f",
|
|
21
|
-
plum: "#ab4aba",
|
|
22
|
-
purple: "#8e4ec6",
|
|
23
|
-
red: "#e5484d",
|
|
24
|
-
ruby: "#e54666",
|
|
25
|
-
sage: "#868e8b",
|
|
26
|
-
sand: "#8d8d86",
|
|
27
|
-
sky: "#7ce2fe",
|
|
28
|
-
slate: "#8b8d98",
|
|
29
|
-
teal: "#12a594",
|
|
30
|
-
tomato: "#e54d2e",
|
|
31
|
-
violet: "#6e56cf",
|
|
32
|
-
yellow: "#ffe629",
|
|
33
|
-
};
|
|
34
|
-
export const radixSeedNames = Object.keys(radixSeeds).sort();
|