@nightshadeui/palette-generator 2.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/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +31 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +20 -0
- package/dist/constants.js.map +1 -0
- package/dist/generate.d.ts +7 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +47 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +23 -0
- package/src/constants.ts +24 -0
- package/src/generate.ts +65 -0
- package/src/index.ts +3 -0
- package/src/types.ts +14 -0
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { generatePaletteCss } from './generate.js';
|
|
5
|
+
const program = new Command();
|
|
6
|
+
program
|
|
7
|
+
.name('palette-generator')
|
|
8
|
+
.description('Emit OKLCH palette as CSS custom properties')
|
|
9
|
+
.option('-f, --file <path>', 'read JSON palette spec from file (stdin if "-" )')
|
|
10
|
+
.option('-o, --output <path>', 'write to file instead of stdout')
|
|
11
|
+
.option('--raw', 'emit property lines only (no :root wrapper)')
|
|
12
|
+
.action((opts) => {
|
|
13
|
+
let palette = {};
|
|
14
|
+
if (opts.file) {
|
|
15
|
+
const raw = opts.file === '-'
|
|
16
|
+
? readFileSync(0, 'utf8')
|
|
17
|
+
: readFileSync(opts.file, 'utf8');
|
|
18
|
+
palette = JSON.parse(raw);
|
|
19
|
+
}
|
|
20
|
+
const css = generatePaletteCss(palette, {
|
|
21
|
+
selector: opts.raw ? false : ':root',
|
|
22
|
+
});
|
|
23
|
+
if (opts.output) {
|
|
24
|
+
writeFileSync(opts.output, css, 'utf8');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
process.stdout.write(`${css}\n`);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
program.parse();
|
|
31
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGnD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,mBAAmB,CAAC;KACzB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,mBAAmB,EAAE,kDAAkD,CAAC;KAC/E,MAAM,CAAC,qBAAqB,EAAE,iCAAiC,CAAC;KAChE,MAAM,CAAC,OAAO,EAAE,6CAA6C,CAAC;KAC9D,MAAM,CAAC,CAAC,IAAuD,EAAE,EAAE;IAChE,IAAI,OAAO,GAAgB,EAAE,CAAC;IAC9B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,MAAM,GAAG,GACL,IAAI,CAAC,IAAI,KAAK,GAAG;YACb,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC;YACzB,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgB,CAAC;IAC7C,CAAC;IACD,MAAM,GAAG,GAAG,kBAAkB,CAAC,OAAO,EAAE;QACpC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO;KACvC,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;AACL,CAAC,CAAC,CAAC;AAEP,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PaletteScaleSpec } from './types.js';
|
|
2
|
+
export declare const SCALE_STEPS: readonly [0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950];
|
|
3
|
+
export declare const DEFAULT_LIGHTNESS_SCALE: number[];
|
|
4
|
+
export declare const DEFAULT_CHROMA_SCALE: number[];
|
|
5
|
+
export declare const DEFAULT_SCALE_SPECS: PaletteScaleSpec[];
|
|
6
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,eAAO,MAAM,WAAW,oEAEd,CAAC;AAEX,eAAO,MAAM,uBAAuB,UAEnC,CAAC;AAEF,eAAO,MAAM,oBAAoB,UAEhC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,gBAAgB,EASjD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const SCALE_STEPS = [
|
|
2
|
+
0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950,
|
|
3
|
+
];
|
|
4
|
+
export const DEFAULT_LIGHTNESS_SCALE = [
|
|
5
|
+
1, 0.98, 0.94, 0.88, 0.80, 0.72, 0.64, 0.56, 0.48, 0.42, 0.36, 0.32,
|
|
6
|
+
];
|
|
7
|
+
export const DEFAULT_CHROMA_SCALE = [
|
|
8
|
+
0.01, 0.02, 0.03, 0.06, 0.09, 0.12, 0.12, 0.09, 0.06, 0.03, 0.02, 0.01,
|
|
9
|
+
];
|
|
10
|
+
export const DEFAULT_SCALE_SPECS = [
|
|
11
|
+
{ name: 'base-light', hue: 320, int: 0.2, lum: 1 },
|
|
12
|
+
{ name: 'base-dark', hue: 340, int: 0.2, lum: 1, reverse: true },
|
|
13
|
+
{ name: 'primary', hue: 340, int: 1.2, lum: 1 },
|
|
14
|
+
{ name: 'secondary', hue: 172, int: 0.72, lum: 1 },
|
|
15
|
+
{ name: 'tertiary', hue: 20, int: 0.25, lum: 1 },
|
|
16
|
+
{ name: 'success', hue: 140, int: 1.2, lum: 1 },
|
|
17
|
+
{ name: 'warning', hue: 72, int: 1.33, lum: 1.12 },
|
|
18
|
+
{ name: 'danger', hue: 24, int: 1.5, lum: 0.9 },
|
|
19
|
+
];
|
|
20
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;CACjD,CAAC;AAEX,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACnC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;CACtE,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAChC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;CACzE,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAuB;IACnD,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE;IAClD,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE;IAChE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE;IAC/C,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE;IAClD,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE;IAChD,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE;IAC/C,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE;IAClD,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;CAClD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PaletteScaleSpec, PaletteSpec } from './types.js';
|
|
2
|
+
export declare function generatePaletteOklch(palette?: PaletteSpec): Record<string, string>;
|
|
3
|
+
export declare function generateScaleOklch(scale: PaletteScaleSpec, lightnessScale: number[], chromaScale: number[]): Record<string, string>;
|
|
4
|
+
export declare function generateTextColor(scale: PaletteScaleSpec, lightnessScale: number[], chromaScale: number[]): "#000" | "#fff";
|
|
5
|
+
export declare function generatePaletteCss(palette?: PaletteSpec): string;
|
|
6
|
+
export declare function contrastColor(l: number, c: number): "#000" | "#fff";
|
|
7
|
+
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,WAAgB,0BAS7D;AAED,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,gBAAgB,EACvB,cAAc,EAAE,MAAM,EAAE,EACxB,WAAW,EAAE,MAAM,EAAE,0BAcxB;AAED,wBAAgB,iBAAiB,CAC7B,KAAK,EAAE,gBAAgB,EACvB,cAAc,EAAE,MAAM,EAAE,EACxB,WAAW,EAAE,MAAM,EAAE,mBAKxB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,WAAgB,UAY3D;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,mBAEjD"}
|
package/dist/generate.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { DEFAULT_CHROMA_SCALE, DEFAULT_LIGHTNESS_SCALE, DEFAULT_SCALE_SPECS, SCALE_STEPS, } from './constants.js';
|
|
2
|
+
export function generatePaletteOklch(palette = {}) {
|
|
3
|
+
const lightnessScale = palette.lightnessScale ?? DEFAULT_LIGHTNESS_SCALE;
|
|
4
|
+
const chromaScale = palette.chromaScale ?? DEFAULT_CHROMA_SCALE;
|
|
5
|
+
const out = {};
|
|
6
|
+
for (const scale of palette.scales ?? DEFAULT_SCALE_SPECS) {
|
|
7
|
+
const lightness = scale.reverse ? lightnessScale.toReversed() : lightnessScale;
|
|
8
|
+
Object.assign(out, generateScaleOklch(scale, lightness, chromaScale));
|
|
9
|
+
}
|
|
10
|
+
return out;
|
|
11
|
+
}
|
|
12
|
+
export function generateScaleOklch(scale, lightnessScale, chromaScale) {
|
|
13
|
+
const { name } = scale;
|
|
14
|
+
const variables = {};
|
|
15
|
+
const textColor = generateTextColor(scale, lightnessScale, chromaScale);
|
|
16
|
+
variables[`--color-${name}-text`] = textColor;
|
|
17
|
+
for (const [index, step] of SCALE_STEPS.entries()) {
|
|
18
|
+
const varName = `--color-${name}-${step}`;
|
|
19
|
+
const l = scale.lum * lightnessScale[index];
|
|
20
|
+
const c = scale.int * chromaScale[index];
|
|
21
|
+
const oklch = `oklch(${l} ${c} ${scale.hue})`;
|
|
22
|
+
variables[varName] = oklch;
|
|
23
|
+
}
|
|
24
|
+
return variables;
|
|
25
|
+
}
|
|
26
|
+
export function generateTextColor(scale, lightnessScale, chromaScale) {
|
|
27
|
+
const l = scale.lum * lightnessScale[6];
|
|
28
|
+
const c = scale.int * chromaScale[6];
|
|
29
|
+
return contrastColor(l, c);
|
|
30
|
+
}
|
|
31
|
+
export function generatePaletteCss(palette = {}) {
|
|
32
|
+
const selector = palette.cssSelector === undefined ? ':root' : palette.cssSelector;
|
|
33
|
+
const variables = generatePaletteOklch(palette);
|
|
34
|
+
const body = Object.entries(variables)
|
|
35
|
+
.map(([key, value]) => ` ${key}: ${value};`)
|
|
36
|
+
.join('\n');
|
|
37
|
+
if (selector === false) {
|
|
38
|
+
return Object.entries(variables)
|
|
39
|
+
.map(([key, value]) => `${key}: ${value};`)
|
|
40
|
+
.join('\n');
|
|
41
|
+
}
|
|
42
|
+
return `${selector} {\n${body}\n}`;
|
|
43
|
+
}
|
|
44
|
+
export function contrastColor(l, c) {
|
|
45
|
+
return l > 0.62 + 0.8 * c ? '#000' : '#fff';
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface PaletteScaleSpec {
|
|
2
|
+
name: string;
|
|
3
|
+
hue: number;
|
|
4
|
+
int: number;
|
|
5
|
+
lum: number;
|
|
6
|
+
reverse?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface PaletteSpec {
|
|
9
|
+
lightnessScale?: number[];
|
|
10
|
+
chromaScale?: number[];
|
|
11
|
+
cssSelector?: string | false;
|
|
12
|
+
scales?: PaletteScaleSpec[];
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC7B,MAAM,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC/B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nightshadeui/palette-generator",
|
|
3
|
+
"version": "2.9.0",
|
|
4
|
+
"description": "OKLCH palette CSS variable generator for Nightshade",
|
|
5
|
+
"author": "Boris Okunskiy",
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./src": "./src/index.ts"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc"
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { PaletteScaleSpec } from './types.js';
|
|
2
|
+
|
|
3
|
+
export const SCALE_STEPS = [
|
|
4
|
+
0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950,
|
|
5
|
+
] as const;
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_LIGHTNESS_SCALE = [
|
|
8
|
+
1, 0.98, 0.94, 0.88, 0.80, 0.72, 0.64, 0.56, 0.48, 0.42, 0.36, 0.32,
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
export const DEFAULT_CHROMA_SCALE = [
|
|
12
|
+
0.01, 0.02, 0.03, 0.06, 0.09, 0.12, 0.12, 0.09, 0.06, 0.03, 0.02, 0.01,
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
export const DEFAULT_SCALE_SPECS: PaletteScaleSpec[] = [
|
|
16
|
+
{ name: 'base-light', hue: 320, int: 0.2, lum: 1 },
|
|
17
|
+
{ name: 'base-dark', hue: 340, int: 0.2, lum: 1, reverse: true },
|
|
18
|
+
{ name: 'primary', hue: 340, int: 1.2, lum: 1 },
|
|
19
|
+
{ name: 'secondary', hue: 172, int: 0.72, lum: 1 },
|
|
20
|
+
{ name: 'tertiary', hue: 20, int: 0.25, lum: 1 },
|
|
21
|
+
{ name: 'success', hue: 140, int: 1.2, lum: 1 },
|
|
22
|
+
{ name: 'warning', hue: 72, int: 1.33, lum: 1.12 },
|
|
23
|
+
{ name: 'danger', hue: 24, int: 1.5, lum: 0.9 },
|
|
24
|
+
];
|
package/src/generate.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_CHROMA_SCALE,
|
|
3
|
+
DEFAULT_LIGHTNESS_SCALE,
|
|
4
|
+
DEFAULT_SCALE_SPECS,
|
|
5
|
+
SCALE_STEPS,
|
|
6
|
+
} from './constants.js';
|
|
7
|
+
import { PaletteScaleSpec, PaletteSpec } from './types.js';
|
|
8
|
+
|
|
9
|
+
export function generatePaletteOklch(palette: PaletteSpec = {}) {
|
|
10
|
+
const lightnessScale = palette.lightnessScale ?? DEFAULT_LIGHTNESS_SCALE;
|
|
11
|
+
const chromaScale = palette.chromaScale ?? DEFAULT_CHROMA_SCALE;
|
|
12
|
+
const out: Record<string, string> = {};
|
|
13
|
+
for (const scale of palette.scales ?? DEFAULT_SCALE_SPECS) {
|
|
14
|
+
const lightness = scale.reverse ? lightnessScale.toReversed() : lightnessScale;
|
|
15
|
+
Object.assign(out, generateScaleOklch(scale, lightness, chromaScale));
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function generateScaleOklch(
|
|
21
|
+
scale: PaletteScaleSpec,
|
|
22
|
+
lightnessScale: number[],
|
|
23
|
+
chromaScale: number[],
|
|
24
|
+
) {
|
|
25
|
+
const { name } = scale;
|
|
26
|
+
const variables: Record<string, string> = {};
|
|
27
|
+
const textColor = generateTextColor(scale, lightnessScale, chromaScale);
|
|
28
|
+
variables[`--color-${name}-text`] = textColor;
|
|
29
|
+
for (const [index, step] of SCALE_STEPS.entries()) {
|
|
30
|
+
const varName = `--color-${name}-${step}`;
|
|
31
|
+
const l = scale.lum * lightnessScale[index]!;
|
|
32
|
+
const c = scale.int * chromaScale[index]!;
|
|
33
|
+
const oklch = `oklch(${l} ${c} ${scale.hue})`;
|
|
34
|
+
variables[varName] = oklch;
|
|
35
|
+
}
|
|
36
|
+
return variables;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function generateTextColor(
|
|
40
|
+
scale: PaletteScaleSpec,
|
|
41
|
+
lightnessScale: number[],
|
|
42
|
+
chromaScale: number[],
|
|
43
|
+
) {
|
|
44
|
+
const l = scale.lum * lightnessScale[6]!;
|
|
45
|
+
const c = scale.int * chromaScale[6]!;
|
|
46
|
+
return contrastColor(l, c);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function generatePaletteCss(palette: PaletteSpec = {}) {
|
|
50
|
+
const selector = palette.cssSelector === undefined ? ':root' : palette.cssSelector;
|
|
51
|
+
const variables = generatePaletteOklch(palette);
|
|
52
|
+
const body = Object.entries(variables)
|
|
53
|
+
.map(([key, value]) => ` ${key}: ${value};`)
|
|
54
|
+
.join('\n');
|
|
55
|
+
if (selector === false) {
|
|
56
|
+
return Object.entries(variables)
|
|
57
|
+
.map(([key, value]) => `${key}: ${value};`)
|
|
58
|
+
.join('\n');
|
|
59
|
+
}
|
|
60
|
+
return `${selector} {\n${body}\n}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function contrastColor(l: number, c: number) {
|
|
64
|
+
return l > 0.62 + 0.8 * c ? '#000' : '#fff';
|
|
65
|
+
}
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface PaletteScaleSpec {
|
|
2
|
+
name: string;
|
|
3
|
+
hue: number;
|
|
4
|
+
int: number;
|
|
5
|
+
lum: number;
|
|
6
|
+
reverse?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface PaletteSpec {
|
|
10
|
+
lightnessScale?: number[];
|
|
11
|
+
chromaScale?: number[];
|
|
12
|
+
cssSelector?: string | false;
|
|
13
|
+
scales?: PaletteScaleSpec[];
|
|
14
|
+
}
|