@clhaas/palette-kit 0.1.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/.markdownlint.json +4 -0
- package/LICENSE +21 -0
- package/README.md +128 -0
- package/biome.json +43 -0
- package/package.json +33 -0
- package/src/alpha/generateAlphaScale.ts +43 -0
- package/src/contrast/apca.ts +7 -0
- package/src/contrast/onSolid.ts +38 -0
- package/src/contrast/solveText.ts +49 -0
- package/src/createTheme.ts +130 -0
- package/src/data/radixSeeds.ts +37 -0
- package/src/diagnostics/analyzeScale.ts +6 -0
- package/src/diagnostics/analyzeTheme.ts +54 -0
- package/src/diagnostics/warnings.ts +25 -0
- package/src/engine/curves.ts +64 -0
- package/src/engine/oklch.ts +53 -0
- package/src/engine/templates.ts +58 -0
- package/src/exporters/selectColorMode.ts +25 -0
- package/src/exporters/toCssVars.ts +116 -0
- package/src/exporters/toJson.ts +31 -0
- package/src/exporters/toReactNative.ts +39 -0
- package/src/exporters/toTailwind.ts +110 -0
- package/src/exporters/toTs.ts +34 -0
- package/src/generateScale.ts +163 -0
- package/src/index.ts +30 -0
- package/src/tokens/presetRadixLikeUi.ts +75 -0
- package/src/types.ts +63 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ColorHex, Scale, Step } from "../types.js";
|
|
2
|
+
|
|
3
|
+
type TokenMapEntry = {
|
|
4
|
+
token: string;
|
|
5
|
+
slot: string;
|
|
6
|
+
step: Step;
|
|
7
|
+
required?: boolean;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const tokenMap: TokenMapEntry[] = [
|
|
11
|
+
{ token: "bg.app", slot: "neutral", step: 1 },
|
|
12
|
+
{ token: "bg.subtle", slot: "neutral", step: 2 },
|
|
13
|
+
{ token: "surface.card", slot: "neutral", step: 2 },
|
|
14
|
+
{ token: "surface.raised", slot: "neutral", step: 3 },
|
|
15
|
+
{ token: "component.bg", slot: "neutral", step: 3 },
|
|
16
|
+
{ token: "component.bgHover", slot: "neutral", step: 4 },
|
|
17
|
+
{ token: "component.bgActive", slot: "neutral", step: 5 },
|
|
18
|
+
{ token: "border.subtle", slot: "neutral", step: 6 },
|
|
19
|
+
{ token: "border.default", slot: "neutral", step: 7 },
|
|
20
|
+
{ token: "border.strong", slot: "neutral", step: 8 },
|
|
21
|
+
{ token: "text.secondary", slot: "neutral", step: 11 },
|
|
22
|
+
{ token: "text.primary", slot: "neutral", step: 12 },
|
|
23
|
+
{ token: "text.disabled", slot: "neutral", step: 10 },
|
|
24
|
+
|
|
25
|
+
{ token: "focus.ring", slot: "accent", step: 8 },
|
|
26
|
+
{ token: "accent.solid", slot: "accent", step: 9 },
|
|
27
|
+
{ token: "accent.solidHover", slot: "accent", step: 10 },
|
|
28
|
+
{ token: "accent.border", slot: "accent", step: 7 },
|
|
29
|
+
{ token: "accent.subtle", slot: "accent", step: 3 },
|
|
30
|
+
{ token: "accent.subtleHover", slot: "accent", step: 4 },
|
|
31
|
+
|
|
32
|
+
{ token: "status.success.solidBg", slot: "success", step: 9, required: false },
|
|
33
|
+
{ token: "status.success.solidHover", slot: "success", step: 10, required: false },
|
|
34
|
+
{ token: "status.success.subtleBg", slot: "success", step: 3, required: false },
|
|
35
|
+
{ token: "status.success.border", slot: "success", step: 7, required: false },
|
|
36
|
+
{ token: "status.success.text", slot: "success", step: 11, required: false },
|
|
37
|
+
{ token: "status.success.textStrong", slot: "success", step: 12, required: false },
|
|
38
|
+
|
|
39
|
+
{ token: "status.warning.solidBg", slot: "warning", step: 9, required: false },
|
|
40
|
+
{ token: "status.warning.solidHover", slot: "warning", step: 10, required: false },
|
|
41
|
+
{ token: "status.warning.subtleBg", slot: "warning", step: 3, required: false },
|
|
42
|
+
{ token: "status.warning.border", slot: "warning", step: 7, required: false },
|
|
43
|
+
{ token: "status.warning.text", slot: "warning", step: 11, required: false },
|
|
44
|
+
{ token: "status.warning.textStrong", slot: "warning", step: 12, required: false },
|
|
45
|
+
|
|
46
|
+
{ token: "status.danger.solidBg", slot: "danger", step: 9, required: false },
|
|
47
|
+
{ token: "status.danger.solidHover", slot: "danger", step: 10, required: false },
|
|
48
|
+
{ token: "status.danger.subtleBg", slot: "danger", step: 3, required: false },
|
|
49
|
+
{ token: "status.danger.border", slot: "danger", step: 7, required: false },
|
|
50
|
+
{ token: "status.danger.text", slot: "danger", step: 11, required: false },
|
|
51
|
+
{ token: "status.danger.textStrong", slot: "danger", step: 12, required: false },
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
export function buildPresetTokens(scales: Record<string, Scale>): {
|
|
55
|
+
light: Record<string, ColorHex>;
|
|
56
|
+
dark: Record<string, ColorHex>;
|
|
57
|
+
} {
|
|
58
|
+
const light: Record<string, ColorHex> = {};
|
|
59
|
+
const dark: Record<string, ColorHex> = {};
|
|
60
|
+
|
|
61
|
+
for (const { token, slot, step, required } of tokenMap) {
|
|
62
|
+
const scale = scales[slot];
|
|
63
|
+
if (!scale) {
|
|
64
|
+
if (required === false) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Missing scale for slot: ${slot}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
light[token] = scale.light[step];
|
|
71
|
+
dark[token] = scale.dark[step];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return { light, dark };
|
|
75
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export type Step = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
2
|
+
|
|
3
|
+
export type ColorHex = `#${string}`;
|
|
4
|
+
export type ColorP3 = string;
|
|
5
|
+
|
|
6
|
+
export type RadixSeedName = string;
|
|
7
|
+
|
|
8
|
+
export type TemplateId = "neutral" | "warm" | "cool";
|
|
9
|
+
|
|
10
|
+
export type ColorSource =
|
|
11
|
+
| { source: "seed"; value: ColorHex }
|
|
12
|
+
| { source: "radix"; name: RadixSeedName };
|
|
13
|
+
|
|
14
|
+
export type ScaleDiagnostics = {
|
|
15
|
+
outOfGamutCount: number;
|
|
16
|
+
outOfP3GamutCount?: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type Scale = {
|
|
20
|
+
light: Record<Step, ColorHex>;
|
|
21
|
+
dark: Record<Step, ColorHex>;
|
|
22
|
+
p3?: {
|
|
23
|
+
light: Record<Step, ColorP3>;
|
|
24
|
+
dark: Record<Step, ColorP3>;
|
|
25
|
+
};
|
|
26
|
+
meta?: ScaleDiagnostics;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type ScaleColorMode = Omit<Scale, "light" | "dark"> & {
|
|
30
|
+
light: Record<Step, string>;
|
|
31
|
+
dark: Record<Step, string>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type AlphaScale = {
|
|
35
|
+
light: Record<Step, ColorHex>;
|
|
36
|
+
dark: Record<Step, ColorHex>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type ThemeDiagnostics = {
|
|
40
|
+
contrast: Record<string, number>;
|
|
41
|
+
outOfGamutCount: number;
|
|
42
|
+
warnings?: string[];
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type Theme = {
|
|
46
|
+
scales: Record<string, Scale>;
|
|
47
|
+
tokens: {
|
|
48
|
+
light: Record<string, ColorHex>;
|
|
49
|
+
dark: Record<string, ColorHex>;
|
|
50
|
+
};
|
|
51
|
+
alpha?: AlphaScale;
|
|
52
|
+
diagnostics?: ThemeDiagnostics;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export type ThemeColorMode = Omit<Theme, "scales"> & {
|
|
56
|
+
scales: Record<string, ScaleColorMode>;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type OklchColor = {
|
|
60
|
+
l: number;
|
|
61
|
+
c: number;
|
|
62
|
+
h: number;
|
|
63
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"noEmit": true
|
|
11
|
+
},
|
|
12
|
+
"include": ["src/**/*.ts"],
|
|
13
|
+
"exclude": ["examples/**", "tests/**", "node_modules/**"]
|
|
14
|
+
}
|