@basiclines/rampa-sdk 1.5.1 → 1.6.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/color-result.d.ts +16 -1
- package/dist/cube-color-space.d.ts +19 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.js +81 -7
- package/dist/linear-color-space.d.ts +12 -5
- package/dist/types.d.ts +25 -4
- package/package.json +1 -1
package/dist/color-result.d.ts
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import type { ColorResult } from './types';
|
|
1
|
+
import type { ColorFormat, ColorResult, ColorAccessor } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Detect the format of a color string.
|
|
4
|
+
*/
|
|
5
|
+
export declare function detectColorFormat(color: string): ColorFormat;
|
|
6
|
+
/**
|
|
7
|
+
* Validate that all colors in an array share the same format.
|
|
8
|
+
* Returns the detected format.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateSameFormat(colors: string[]): ColorFormat;
|
|
11
|
+
/**
|
|
12
|
+
* Create a ColorAccessor from a hex string with a given output format.
|
|
13
|
+
* Returns a String object with conversion methods so it acts as a string
|
|
14
|
+
* in template literals, comparisons, and concatenation.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createColorAccessor(hex: string, outputFormat: ColorFormat): ColorAccessor;
|
|
2
17
|
/**
|
|
3
18
|
* Create a ColorResult from a hex string.
|
|
4
19
|
* Acts as a string (hex) by default, supports .format() for conversions.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { InterpolationMode, CubeColorSpaceResult } from './types';
|
|
1
|
+
import type { ColorFormat, InterpolationMode, CubeColorSpaceResult } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Create a 3D color cube from 8 named corner colors.
|
|
4
4
|
*
|
|
5
5
|
* The constructor keys become shortcut function names and tint() aliases.
|
|
6
6
|
* Key order determines cube position (see CORNER_MASKS above).
|
|
7
|
+
* All input colors must use the same format.
|
|
7
8
|
*
|
|
8
9
|
* @example
|
|
9
10
|
* ```ts
|
|
@@ -12,10 +13,14 @@ import type { InterpolationMode, CubeColorSpaceResult } from './types';
|
|
|
12
13
|
* y: '#f9e2af', m: '#cba6f7', c: '#94e2d5', w: '#cdd6f4',
|
|
13
14
|
* }).size(6);
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* space.
|
|
16
|
+
* // With different interpolation or output format:
|
|
17
|
+
* const space2 = new CubeColorSpace({ ... }).interpolation('lab').format('rgb').size(6);
|
|
18
|
+
*
|
|
19
|
+
* space.r(4) // → "f38ba8" (string in output format)
|
|
20
|
+
* space.r(4).hsl() // → "hsl(...)" (convert to another format)
|
|
21
|
+
* space.tint({ r: 3, b: 2 }) // → string in output format
|
|
22
|
+
* space.cube(3, 0, 2) // → string in output format
|
|
23
|
+
* space.palette // → string[216]
|
|
19
24
|
*
|
|
20
25
|
* // Destructure for convenience:
|
|
21
26
|
* const { r, w, tint, cube } = space;
|
|
@@ -24,9 +29,18 @@ import type { InterpolationMode, CubeColorSpaceResult } from './types';
|
|
|
24
29
|
export declare class CubeColorSpace {
|
|
25
30
|
private _corners;
|
|
26
31
|
private _interpolation;
|
|
32
|
+
private _format;
|
|
27
33
|
constructor(corners: Record<string, string>, options?: {
|
|
28
34
|
interpolation?: InterpolationMode;
|
|
29
35
|
});
|
|
36
|
+
/**
|
|
37
|
+
* Set the interpolation mode.
|
|
38
|
+
*/
|
|
39
|
+
interpolation(mode: InterpolationMode): this;
|
|
40
|
+
/**
|
|
41
|
+
* Set the output color format (default: 'hex').
|
|
42
|
+
*/
|
|
43
|
+
format(fmt: ColorFormat): this;
|
|
30
44
|
/**
|
|
31
45
|
* Set the steps per axis and return the color space accessor object.
|
|
32
46
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { RampaBuilder } from './builder';
|
|
|
2
2
|
import { ReadOnlyBuilder } from './read-only';
|
|
3
3
|
import { LinearColorSpace } from './linear-color-space';
|
|
4
4
|
import { CubeColorSpace } from './cube-color-space';
|
|
5
|
-
import type { ColorFormat, ScaleType, BlendMode, HarmonyType, RampResult, RampaResult, ColorInfo, InterpolationMode, ColorResult, RgbComponents, LinearColorSpaceFn, CubeColorSpaceResult, ColorSpaceOptions } from './types';
|
|
5
|
+
import type { ColorFormat, ScaleType, BlendMode, HarmonyType, RampResult, RampaResult, ColorInfo, InterpolationMode, ColorResult, ColorAccessor, RgbComponents, LinearColorSpaceFn, CubeColorSpaceResult, ColorSpaceOptions } from './types';
|
|
6
6
|
/**
|
|
7
7
|
* Create a new color ramp builder from a base color.
|
|
8
8
|
*
|
|
@@ -35,4 +35,4 @@ export declare namespace rampa {
|
|
|
35
35
|
*/
|
|
36
36
|
export declare function color(hex: string): ColorResult;
|
|
37
37
|
export { RampaBuilder, ReadOnlyBuilder, LinearColorSpace, CubeColorSpace };
|
|
38
|
-
export type { ColorFormat, ScaleType, BlendMode, HarmonyType, RampResult, RampaResult, ColorInfo, InterpolationMode, ColorResult, RgbComponents, LinearColorSpaceFn, CubeColorSpaceResult, ColorSpaceOptions, };
|
|
38
|
+
export type { ColorFormat, ScaleType, BlendMode, HarmonyType, RampResult, RampaResult, ColorInfo, InterpolationMode, ColorResult, ColorAccessor, RgbComponents, LinearColorSpaceFn, CubeColorSpaceResult, ColorSpaceOptions, };
|
package/dist/index.js
CHANGED
|
@@ -7941,6 +7941,60 @@ function generateCubeSpace(corners, stepsPerAxis, mode = "oklch") {
|
|
|
7941
7941
|
}
|
|
7942
7942
|
|
|
7943
7943
|
// src/color-result.ts
|
|
7944
|
+
function detectColorFormat(color) {
|
|
7945
|
+
const trimmed = color.trim();
|
|
7946
|
+
if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(trimmed))
|
|
7947
|
+
return "hex";
|
|
7948
|
+
if (/^rgb\s*\(/.test(trimmed))
|
|
7949
|
+
return "rgb";
|
|
7950
|
+
if (/^hsl\s*\(/.test(trimmed))
|
|
7951
|
+
return "hsl";
|
|
7952
|
+
if (/^oklch\s*\(/.test(trimmed))
|
|
7953
|
+
return "oklch";
|
|
7954
|
+
throw new Error(`Unknown color format: ${color}`);
|
|
7955
|
+
}
|
|
7956
|
+
function validateSameFormat(colors) {
|
|
7957
|
+
const formats = colors.map((c2) => detectColorFormat(c2));
|
|
7958
|
+
const first = formats[0];
|
|
7959
|
+
for (let i = 1;i < formats.length; i++) {
|
|
7960
|
+
if (formats[i] !== first) {
|
|
7961
|
+
throw new Error(`All colors must use the same format. Found '${first}' and '${formats[i]}': ${colors[0]} vs ${colors[i]}`);
|
|
7962
|
+
}
|
|
7963
|
+
}
|
|
7964
|
+
return first;
|
|
7965
|
+
}
|
|
7966
|
+
function createColorAccessor(hex6, outputFormat) {
|
|
7967
|
+
const c2 = chroma_js_default(hex6);
|
|
7968
|
+
const [l] = c2.oklch();
|
|
7969
|
+
const formatColor2 = (fmt) => {
|
|
7970
|
+
switch (fmt) {
|
|
7971
|
+
case "hsl": {
|
|
7972
|
+
const [h, s, l2] = c2.hsl();
|
|
7973
|
+
return `hsl(${Math.round(h || 0)}, ${Math.round(s * 100)}%, ${Math.round(l2 * 100)}%)`;
|
|
7974
|
+
}
|
|
7975
|
+
case "rgb": {
|
|
7976
|
+
const [r2, g, b] = c2.rgb();
|
|
7977
|
+
return `rgb(${r2}, ${g}, ${b})`;
|
|
7978
|
+
}
|
|
7979
|
+
case "oklch": {
|
|
7980
|
+
const [l2, ch, h] = c2.oklch();
|
|
7981
|
+
return `oklch(${(l2 * 100).toFixed(1)}% ${ch.toFixed(3)} ${Math.round(h || 0)})`;
|
|
7982
|
+
}
|
|
7983
|
+
default:
|
|
7984
|
+
return hex6;
|
|
7985
|
+
}
|
|
7986
|
+
};
|
|
7987
|
+
const value = formatColor2(outputFormat);
|
|
7988
|
+
const accessor = new String(value);
|
|
7989
|
+
Object.defineProperties(accessor, {
|
|
7990
|
+
hex: { value: () => hex6, enumerable: false },
|
|
7991
|
+
hsl: { value: () => formatColor2("hsl"), enumerable: false },
|
|
7992
|
+
rgb: { value: () => formatColor2("rgb"), enumerable: false },
|
|
7993
|
+
oklch: { value: () => formatColor2("oklch"), enumerable: false },
|
|
7994
|
+
luminance: { value: l, enumerable: false }
|
|
7995
|
+
});
|
|
7996
|
+
return accessor;
|
|
7997
|
+
}
|
|
7944
7998
|
function createColorResult(hex6) {
|
|
7945
7999
|
const c2 = chroma_js_default(hex6);
|
|
7946
8000
|
const [r2, g, b] = c2.rgb();
|
|
@@ -7978,30 +8032,39 @@ function createColorResult(hex6) {
|
|
|
7978
8032
|
class LinearColorSpace {
|
|
7979
8033
|
_colors;
|
|
7980
8034
|
_interpolation = "oklch";
|
|
8035
|
+
_format = "hex";
|
|
7981
8036
|
constructor(...colors) {
|
|
7982
8037
|
if (colors.length < 2) {
|
|
7983
8038
|
throw new Error("LinearColorSpace requires at least 2 colors");
|
|
7984
8039
|
}
|
|
8040
|
+
validateSameFormat(colors);
|
|
7985
8041
|
this._colors = colors;
|
|
7986
8042
|
}
|
|
7987
8043
|
interpolation(mode) {
|
|
7988
8044
|
this._interpolation = mode;
|
|
7989
8045
|
return this;
|
|
7990
8046
|
}
|
|
8047
|
+
format(fmt) {
|
|
8048
|
+
this._format = fmt;
|
|
8049
|
+
return this;
|
|
8050
|
+
}
|
|
7991
8051
|
size(steps) {
|
|
7992
8052
|
let palette;
|
|
8053
|
+
const outputFormat = this._format;
|
|
7993
8054
|
if (this._interpolation === false) {
|
|
7994
|
-
palette =
|
|
8055
|
+
palette = this._colors.map((c2) => chroma_js_default(c2).hex());
|
|
7995
8056
|
} else {
|
|
7996
|
-
|
|
8057
|
+
const firstHex = chroma_js_default(this._colors[0]).hex();
|
|
8058
|
+
const lastHex = chroma_js_default(this._colors[this._colors.length - 1]).hex();
|
|
8059
|
+
palette = generateLinearSpace(firstHex, lastHex, steps, this._interpolation);
|
|
7997
8060
|
}
|
|
7998
|
-
return buildFn(palette);
|
|
8061
|
+
return buildFn(palette, outputFormat);
|
|
7999
8062
|
}
|
|
8000
8063
|
}
|
|
8001
|
-
function buildFn(palette) {
|
|
8064
|
+
function buildFn(palette, outputFormat) {
|
|
8002
8065
|
const fn4 = (index) => {
|
|
8003
8066
|
const i = Math.max(1, Math.min(palette.length, index)) - 1;
|
|
8004
|
-
return
|
|
8067
|
+
return createColorAccessor(palette[i], outputFormat);
|
|
8005
8068
|
};
|
|
8006
8069
|
fn4.palette = palette;
|
|
8007
8070
|
fn4.size = palette.length;
|
|
@@ -8023,17 +8086,28 @@ var CORNER_MASKS = [
|
|
|
8023
8086
|
class CubeColorSpace {
|
|
8024
8087
|
_corners;
|
|
8025
8088
|
_interpolation;
|
|
8089
|
+
_format = "hex";
|
|
8026
8090
|
constructor(corners, options) {
|
|
8027
8091
|
const keys = Object.keys(corners);
|
|
8028
8092
|
if (keys.length !== 8) {
|
|
8029
8093
|
throw new Error(`CubeColorSpace requires exactly 8 corner colors, got ${keys.length}`);
|
|
8030
8094
|
}
|
|
8095
|
+
validateSameFormat(Object.values(corners));
|
|
8031
8096
|
this._corners = corners;
|
|
8032
8097
|
this._interpolation = options?.interpolation ?? "oklch";
|
|
8033
8098
|
}
|
|
8099
|
+
interpolation(mode) {
|
|
8100
|
+
this._interpolation = mode;
|
|
8101
|
+
return this;
|
|
8102
|
+
}
|
|
8103
|
+
format(fmt) {
|
|
8104
|
+
this._format = fmt;
|
|
8105
|
+
return this;
|
|
8106
|
+
}
|
|
8034
8107
|
size(stepsPerAxis) {
|
|
8035
8108
|
const keys = Object.keys(this._corners);
|
|
8036
|
-
const cornerColors = keys.map((k3) => this._corners[k3]);
|
|
8109
|
+
const cornerColors = keys.map((k3) => chroma_js_default(this._corners[k3]).hex());
|
|
8110
|
+
const outputFormat = this._format;
|
|
8037
8111
|
const aliases = {};
|
|
8038
8112
|
for (let i = 0;i < 8; i++) {
|
|
8039
8113
|
aliases[keys[i]] = CORNER_MASKS[i];
|
|
@@ -8045,7 +8119,7 @@ class CubeColorSpace {
|
|
|
8045
8119
|
cy = Math.max(0, Math.min(max11, Math.round(cy)));
|
|
8046
8120
|
cz = Math.max(0, Math.min(max11, Math.round(cz)));
|
|
8047
8121
|
const index = cx * stepsPerAxis * stepsPerAxis + cy * stepsPerAxis + cz;
|
|
8048
|
-
return
|
|
8122
|
+
return createColorAccessor(palette[index], outputFormat);
|
|
8049
8123
|
};
|
|
8050
8124
|
const tint = (query) => {
|
|
8051
8125
|
let cx = 0, cy = 0, cz = 0;
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import type { InterpolationMode, LinearColorSpaceFn } from './types';
|
|
1
|
+
import type { ColorFormat, InterpolationMode, LinearColorSpaceFn } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Create a linear color space.
|
|
4
|
+
* All input colors must use the same format.
|
|
4
5
|
*
|
|
5
6
|
* @example
|
|
6
7
|
* ```ts
|
|
7
8
|
* // Interpolated (default: oklch)
|
|
8
9
|
* const neutral = new LinearColorSpace('#ffffff', '#000000').size(24);
|
|
9
|
-
* neutral(12) // →
|
|
10
|
-
* neutral(12).
|
|
10
|
+
* neutral(12) // → "#808080" (string in output format)
|
|
11
|
+
* neutral(12).hsl() // → "hsl(...)" (convert to another format)
|
|
11
12
|
*
|
|
12
|
-
* // Different interpolation
|
|
13
|
-
* const ramp = new LinearColorSpace('#ff0000', '#0000ff').interpolation('lab').size(10);
|
|
13
|
+
* // Different interpolation and output format:
|
|
14
|
+
* const ramp = new LinearColorSpace('#ff0000', '#0000ff').interpolation('lab').format('rgb').size(10);
|
|
15
|
+
* ramp(5) // → "rgb(128, 0, 128)"
|
|
14
16
|
*
|
|
15
17
|
* // Lookup table — no interpolation, just a plain color array
|
|
16
18
|
* const base = new LinearColorSpace('#000', '#f00', '#0f0', '#ff0', '#00f', '#f0f', '#0ff', '#fff')
|
|
@@ -23,12 +25,17 @@ import type { InterpolationMode, LinearColorSpaceFn } from './types';
|
|
|
23
25
|
export declare class LinearColorSpace {
|
|
24
26
|
private _colors;
|
|
25
27
|
private _interpolation;
|
|
28
|
+
private _format;
|
|
26
29
|
constructor(...colors: string[]);
|
|
27
30
|
/**
|
|
28
31
|
* Set the interpolation mode.
|
|
29
32
|
* Pass false for a plain lookup table (no interpolation).
|
|
30
33
|
*/
|
|
31
34
|
interpolation(mode: InterpolationMode | false): this;
|
|
35
|
+
/**
|
|
36
|
+
* Set the output color format (default: 'hex').
|
|
37
|
+
*/
|
|
38
|
+
format(fmt: ColorFormat): this;
|
|
32
39
|
/**
|
|
33
40
|
* Set the number of color steps and return the color accessor function.
|
|
34
41
|
*/
|
package/dist/types.d.ts
CHANGED
|
@@ -55,12 +55,33 @@ export interface ColorResult {
|
|
|
55
55
|
/** String coercion returns hex */
|
|
56
56
|
toString(): string;
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* A color accessor returned by color space functions.
|
|
60
|
+
* Acts as a string via toString()/valueOf() in the color space's output format.
|
|
61
|
+
* Has .hex(), .hsl(), .rgb(), .oklch() methods for format conversion.
|
|
62
|
+
*/
|
|
63
|
+
export interface ColorAccessor {
|
|
64
|
+
/** Convert to hex string */
|
|
65
|
+
hex(): string;
|
|
66
|
+
/** Convert to hsl string */
|
|
67
|
+
hsl(): string;
|
|
68
|
+
/** Convert to rgb string */
|
|
69
|
+
rgb(): string;
|
|
70
|
+
/** Convert to oklch string */
|
|
71
|
+
oklch(): string;
|
|
72
|
+
/** Perceptual luminance (0-1) using OKLCH lightness */
|
|
73
|
+
luminance: number;
|
|
74
|
+
/** String coercion returns color in the space's output format */
|
|
75
|
+
toString(): string;
|
|
76
|
+
/** Primitive coercion returns the formatted string */
|
|
77
|
+
valueOf(): string;
|
|
78
|
+
}
|
|
58
79
|
/**
|
|
59
80
|
* The function signature returned by LinearColorSpace.
|
|
60
81
|
* Call it with a 1-based index to get a color.
|
|
61
82
|
*/
|
|
62
83
|
export interface LinearColorSpaceFn {
|
|
63
|
-
(index: number):
|
|
84
|
+
(index: number): ColorAccessor;
|
|
64
85
|
palette: string[];
|
|
65
86
|
size: number;
|
|
66
87
|
}
|
|
@@ -74,13 +95,13 @@ export interface LinearColorSpaceFn {
|
|
|
74
95
|
*/
|
|
75
96
|
export interface CubeColorSpaceResult {
|
|
76
97
|
/** Multi-axis lookup: tint({ r: 3, b: 2 }) */
|
|
77
|
-
tint(query: Record<string, number>):
|
|
98
|
+
tint(query: Record<string, number>): ColorAccessor;
|
|
78
99
|
/** Raw 3D coordinate lookup: cube(x, y, z) */
|
|
79
|
-
cube(x: number, y: number, z: number):
|
|
100
|
+
cube(x: number, y: number, z: number): ColorAccessor;
|
|
80
101
|
/** Full palette array */
|
|
81
102
|
palette: string[];
|
|
82
103
|
/** Steps per axis */
|
|
83
104
|
size: number;
|
|
84
105
|
/** Per-corner shortcut functions, keyed by constructor key names */
|
|
85
|
-
[key: string]: ((index: number) =>
|
|
106
|
+
[key: string]: ((index: number) => ColorAccessor) | string[] | number | ((query: Record<string, number>) => ColorAccessor) | ((x: number, y: number, z: number) => ColorAccessor);
|
|
86
107
|
}
|