color-value-tools 1.1.9 → 1.1.11
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/README.md +49 -677
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,31 +6,6 @@ A comprehensive utility library for parsing, converting, manipulating, and analy
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## Contents
|
|
10
|
-
|
|
11
|
-
- [Features](#features)
|
|
12
|
-
- [Installation](#installation)
|
|
13
|
-
- [Quick start](#quick-start)
|
|
14
|
-
- [Detection](#detection)
|
|
15
|
-
- [Parsing & Normalization](#parsing--normalization)
|
|
16
|
-
- [Conversions](#conversions)
|
|
17
|
-
- [Manipulation](#manipulation)
|
|
18
|
-
- [Interpolation & Scales](#interpolation--scales)
|
|
19
|
-
- [Color Harmonies](#color-harmonies)
|
|
20
|
-
- [Palette Generation](#palette-generation)
|
|
21
|
-
- [Accessibility (WCAG)](#accessibility-wcag)
|
|
22
|
-
- [Color Blindness Simulation](#color-blindness-simulation)
|
|
23
|
-
- [Formatting](#formatting)
|
|
24
|
-
- [Cache Management](#cache-management)
|
|
25
|
-
- [Generator Functions](#generator-functions)
|
|
26
|
-
- [CLI](#cli)
|
|
27
|
-
- [Cookbook](#cookbook)
|
|
28
|
-
- [TypeScript types](#typescript-types)
|
|
29
|
-
- [Architecture](#architecture)
|
|
30
|
-
- [Bundle size & dependencies](#bundle-size--dependencies)
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
9
|
## Features
|
|
35
10
|
|
|
36
11
|
- **Universal parser** — `normalizeColor()` accepts hex (3/4/6/8-digit), `rgb()` / `rgba()`, `hsl()` / `hsla()`, `hwb()`, `oklch()` / `oklcha()`, `color(display-p3 ...)`, CSS named colors (all 148), and plain `{r,g,b}` / `{h,s,l}` objects
|
|
@@ -38,13 +13,13 @@ A comprehensive utility library for parsing, converting, manipulating, and analy
|
|
|
38
13
|
- **Manipulation** — `lighten`, `darken`, `saturate`, `desaturate`, `invertColor`, `grayscale`, `setAlpha`, `rotateHue`, `adjustHexBrightness`
|
|
39
14
|
- **Mixing & Interpolation** — `mixColors` and `interpolateColors` in 6 color spaces with 4 hue interpolation modes; `createColorScale` across multiple anchor colors with custom positions; `midpointColor` for a perceptual midpoint
|
|
40
15
|
- **Color Harmonies** — `complement`, `triadic`, `analogous`, `splitComplementary`, `tetradic`
|
|
41
|
-
- **Palette Generation** — `colorShades`, `monochromatic`, `tints`, `shades`, `tones` — all Oklab-accurate where applicable
|
|
16
|
+
- **Palette Generation** — `colorShades`, `monochromatic`, `tints`, `shades`, `tones`, `randomColor` — all Oklab-accurate where applicable
|
|
42
17
|
- **WCAG Accessibility** — `relativeLuminance`, `contrastRatio`, `wcagLevel`, `bestTextColor`, `bestContrastColor`, `bestContrastPalette`, `isReadableOnBackground` (solid, semi-transparent, and gradient backgrounds)
|
|
43
18
|
- **Color Blindness Simulation** — protanopia, deuteranopia, tritanopia using Vienot 1999 matrices on linear RGB
|
|
44
19
|
- **Perceptual color distance** — `colorDeltaE` implementing the full CIEDE2000 formula
|
|
45
20
|
- **CSS Formatting** — `toHslString`, `toHwbString`, `toOklchString`, `toColorP3String`
|
|
46
|
-
- **
|
|
47
|
-
- **
|
|
21
|
+
- **Memoization cache** — `normalizeColorCached` caches parsed results in memory; `getCacheStats`, `clearColorCache`, `enableCache` / `disableCache`
|
|
22
|
+
- **Lazy generator functions** — `generateGradientColors`, `generateTints`, `generateShades` for iterating without pre-allocating arrays
|
|
48
23
|
- **CLI (`cvt`)** — inspect any color from the terminal: full info, all conversions, WCAG contrast, shades, harmonies, nearest named color
|
|
49
24
|
- **Zero dependencies** — no runtime deps; ships as tree-shakeable ESM + CommonJS
|
|
50
25
|
|
|
@@ -52,46 +27,50 @@ A comprehensive utility library for parsing, converting, manipulating, and analy
|
|
|
52
27
|
|
|
53
28
|
## Installation
|
|
54
29
|
|
|
30
|
+
Requires Node.js `18+`. No runtime or peer dependencies — the package is fully framework-agnostic and works in any JS/TS environment (browser, Node, edge runtimes).
|
|
31
|
+
|
|
55
32
|
```bash
|
|
56
33
|
npm install color-value-tools
|
|
57
34
|
```
|
|
58
35
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Quick start
|
|
36
|
+
### Quick start
|
|
64
37
|
|
|
65
38
|
```ts
|
|
66
39
|
import {
|
|
67
|
-
normalizeColor,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
40
|
+
normalizeColor,
|
|
41
|
+
mixColors,
|
|
42
|
+
lighten,
|
|
43
|
+
darken,
|
|
44
|
+
saturate,
|
|
45
|
+
complement,
|
|
46
|
+
triadic,
|
|
47
|
+
wcagLevel,
|
|
48
|
+
bestTextColor,
|
|
49
|
+
colorDeltaE,
|
|
50
|
+
randomColor,
|
|
72
51
|
} from 'color-value-tools'
|
|
73
52
|
|
|
74
53
|
// Parse any color format
|
|
75
54
|
normalizeColor('#3498db')
|
|
76
|
-
// { type: 'hex', hex: '#3498db', r: 52, g: 152, b: 219, h: 204, s: 70, l: 53, v: 86
|
|
55
|
+
// { type: 'hex', hex: '#3498db', r: 52, g: 152, b: 219, a: 1, h: 204, s: 70, l: 53, v: 86 }
|
|
77
56
|
|
|
78
57
|
// Manipulate
|
|
79
|
-
lighten('#3498db', 15)
|
|
80
|
-
darken('#3498db', 15)
|
|
81
|
-
saturate('#3498db', 20)
|
|
58
|
+
lighten('#3498db', 15) // '#74b9e7'
|
|
59
|
+
darken('#3498db', 15) // '#1d6ea5'
|
|
60
|
+
saturate('#3498db', 20) // '#1b9df3'
|
|
82
61
|
|
|
83
62
|
// Harmonies
|
|
84
|
-
complement('#3498db')
|
|
85
|
-
triadic('#3498db')
|
|
63
|
+
complement('#3498db') // '#db7633'
|
|
64
|
+
triadic('#3498db') // ['#3498db', '#db3398', '#98db33']
|
|
86
65
|
|
|
87
66
|
// WCAG accessibility
|
|
88
|
-
wcagLevel('#ffffff', '#3498db')
|
|
89
|
-
bestTextColor('#3498db')
|
|
67
|
+
wcagLevel('#ffffff', '#3498db') // 'AA-large'
|
|
68
|
+
bestTextColor('#3498db') // '#000000'
|
|
90
69
|
|
|
91
70
|
// Perceptual color distance (CIEDE2000)
|
|
92
|
-
colorDeltaE('#ff0000', '#fe0000')
|
|
71
|
+
colorDeltaE('#ff0000', '#fe0000') // 0.2079
|
|
93
72
|
|
|
94
|
-
// Random color
|
|
73
|
+
// Random color within a hue/saturation range
|
|
95
74
|
randomColor({ hRange: [200, 260], sRange: [60, 80] })
|
|
96
75
|
```
|
|
97
76
|
|
|
@@ -101,644 +80,47 @@ CommonJS:
|
|
|
101
80
|
const { normalizeColor, mixColors } = require('color-value-tools')
|
|
102
81
|
```
|
|
103
82
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
## Detection
|
|
107
|
-
|
|
108
|
-
| Function | Description |
|
|
109
|
-
|---|---|
|
|
110
|
-
| `getColorType(value)` | Returns `'hex'` \| `'css-var'` \| `'rgb'` \| `'hsl'` \| `'named'` \| `'oklch'` \| `'color'` \| `'unknown'` |
|
|
111
|
-
| `isHexColor(value)` | Detects 3-, 4-, or 6-digit hex strings (with or without `#`) |
|
|
112
|
-
| `isRgbColor(value)` | Detects `rgb()` / `rgba()` strings |
|
|
113
|
-
| `isHslColor(value)` | Detects `hsl()` / `hsla()` strings |
|
|
114
|
-
| `isOklchColor(value)` | Detects `oklch()` / `oklcha()` strings |
|
|
115
|
-
| `isColorFunction(value)` | Detects `color(display-p3 ...)`, `color(srgb ...)`, `color(srgb-linear ...)` strings |
|
|
116
|
-
| `isCssVariable(value)` | Checks for `var(--name)` pattern |
|
|
117
|
-
| `extractCssVariableName(value)` | Extracts `--name` from `var(--name, fallback)` |
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## Parsing & Normalization
|
|
122
|
-
|
|
123
|
-
| Function | Description |
|
|
124
|
-
|---|---|
|
|
125
|
-
| `normalizeColor(input)` | Universal parser. Accepts hex (3/4/6/8-digit), `rgb()`, `hsl()`, `hwb()`, `oklch()`, `color()`, named color, `{r,g,b}` object, `{h,s,l}` object. Returns `{ type, hex, r, g, b, a, h, s, l, v }` |
|
|
126
|
-
| `normalizeColorCached(input)` | Same as `normalizeColor` but uses an internal LRU-style cache. String input only |
|
|
127
|
-
| `normalizeHex(hex)` | Normalizes 3- or 6-digit hex to lowercase 6-digit with `#` |
|
|
128
|
-
| `rgbaStringToRgba(str)` | Parses `rgb()` / `rgba()` string to `{r, g, b, a}`; supports percentage channels |
|
|
129
|
-
| `hex8ToRgba(hex)` | Parses 8-digit hex (`#rrggbbaa`) or 4-digit hex (`#rgba`) to `{r, g, b, a}` |
|
|
130
|
-
| `shortHexToRgba(hex)` | Parses 4-digit hex (`#rgba`) to `{r, g, b, a}` — e.g. `#f0f0` → `{r:255,g:0,b:255,a:0}` |
|
|
131
|
-
| `parseHwbString(str)` | Parses `hwb()` string to `{H, W, B, alpha}` |
|
|
132
|
-
| `parseOklchString(str)` | Parses `oklch(L C H / alpha)` to `{L, C, H, alpha}`; accepts percentage L |
|
|
133
|
-
| `parseColorFn(str)` | Parses `color(display-p3 r g b / alpha)` to `{space, r, g, b, alpha}` |
|
|
134
|
-
| `parseCssVar(value)` | Parses `var(--name, fallback)` to `{variableName, fallback?}` |
|
|
135
|
-
|
|
136
|
-
### `normalizeColor` return value
|
|
137
|
-
|
|
138
|
-
```ts
|
|
139
|
-
{
|
|
140
|
-
type: 'hex' | 'rgb' | 'hsl' | 'oklch' | 'color' | 'named' | 'css-var' | 'unknown'
|
|
141
|
-
hex?: string // '#rrggbb'
|
|
142
|
-
r?: number // 0–255
|
|
143
|
-
g?: number // 0–255
|
|
144
|
-
b?: number // 0–255
|
|
145
|
-
a?: number // 0–1
|
|
146
|
-
h?: number // hue 0–360
|
|
147
|
-
s?: number // HSL saturation 0–100
|
|
148
|
-
l?: number // HSL lightness 0–100
|
|
149
|
-
v?: number // HSV value 0–100
|
|
150
|
-
raw?: string // set for css-var type
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
```ts
|
|
155
|
-
// Object input
|
|
156
|
-
normalizeColor({ r: 52, g: 152, b: 219 }) // → full result with hex, h, s, l, v
|
|
157
|
-
normalizeColor({ h: 204, s: 70, l: 53 }) // → full result with hex, r, g, b, v
|
|
158
|
-
|
|
159
|
-
// CSS variable — returns raw, no color channels
|
|
160
|
-
normalizeColor('var(--brand-color)') // → { type: 'css-var', raw: 'var(--brand-color)' }
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Conversions
|
|
166
|
-
|
|
167
|
-
| Function | Description |
|
|
168
|
-
|---|---|
|
|
169
|
-
| `hexToRgb(hex)` | `→ [r, g, b]` |
|
|
170
|
-
| `hexToRgba(hex, opacity)` | `→ rgba(...)` string |
|
|
171
|
-
| `hexToHsl(hex)` | `→ [h, s, l]` |
|
|
172
|
-
| `hexToHsv(hex)` | `→ [h, s, v]` |
|
|
173
|
-
| `hslToHex(h, s, l)` | `→ #rrggbb` |
|
|
174
|
-
| `hslToRgb(h, s, l)` | `→ {r, g, b}` |
|
|
175
|
-
| `hsvToHex(h, s, v)` | `→ #rrggbb` |
|
|
176
|
-
| `hsvToRgb(h, s, v)` | `→ {r, g, b}` |
|
|
177
|
-
| `rgbToHex({r,g,b})` | `→ #rrggbb` |
|
|
178
|
-
| `rgbaToHex({r,g,b,a})` | `→ #rrggbbaa` |
|
|
179
|
-
| `rgbaToHex8({r,g,b,a})` | Alias for `rgbaToHex` |
|
|
180
|
-
| `rgbToRgbaString({r,g,b}, a)` | `→ rgba(...)` string |
|
|
181
|
-
| `rgbToHsl({r,g,b})` | `→ [h, s, l]` |
|
|
182
|
-
| `rgbToHsv({r,g,b})` | `→ [h, s, v]` |
|
|
183
|
-
| `rgbToHwb({r,g,b})` | `→ [H, W, B]` |
|
|
184
|
-
| `hwbToRgb(H, W, B)` | `→ {r, g, b}` |
|
|
185
|
-
| `rgbToCmyk({r,g,b})` | `→ {c, m, y, k}` (0–1 range) |
|
|
186
|
-
| `cmykToRgb({c,m,y,k})` | `→ {r, g, b}` |
|
|
187
|
-
| `rgbToLab({r,g,b})` | `→ {L, a, b}` (CIE Lab D65) |
|
|
188
|
-
| `labToRgb({L,a,b})` | `→ {r, g, b}` |
|
|
189
|
-
| `rgbToLch({r,g,b})` | `→ {L, C, H}` (CIE LCH) |
|
|
190
|
-
| `lchToRgb({L,C,H})` | `→ {r, g, b}` |
|
|
191
|
-
| `rgbToOklab({r,g,b})` | `→ {L, a, b}` (Oklab) |
|
|
192
|
-
| `oklabToRgb({L,a,b})` | `→ {r, g, b}` |
|
|
193
|
-
| `rgbToOklch({r,g,b})` | `→ {L, C, H}` (Oklch) |
|
|
194
|
-
| `oklchToRgb({L,C,H})` | `→ {r, g, b}` |
|
|
195
|
-
| `rgbToDisplayP3({r,g,b})` | `→ {r, g, b}` in Display P3 space (0–1 per channel) |
|
|
196
|
-
| `displayP3ToRgb({r,g,b})` | `→ {r, g, b}` sRGB (0–255) |
|
|
197
|
-
| `toDisplayP3Hex(color)` | Converts any color → Display P3 → hex |
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
## Manipulation
|
|
202
|
-
|
|
203
|
-
| Function | Description |
|
|
204
|
-
|---|---|
|
|
205
|
-
| `lighten(color, amount)` | Increase HSL lightness by `amount` (0–100) |
|
|
206
|
-
| `darken(color, amount)` | Decrease HSL lightness by `amount` (0–100) |
|
|
207
|
-
| `saturate(color, amount)` | Increase HSL saturation by `amount` (0–100) |
|
|
208
|
-
| `desaturate(color, amount)` | Decrease HSL saturation by `amount` (0–100) |
|
|
209
|
-
| `setAlpha(color, alpha)` | Returns `rgba(...)` with the given alpha (0–1) |
|
|
210
|
-
| `getAlpha(color)` | Returns the alpha channel value (0–1) |
|
|
211
|
-
| `invertColor(color)` | Inverts all three RGB channels |
|
|
212
|
-
| `grayscale(color)` | Converts to grayscale using ITU-R BT.709 perceptual weights |
|
|
213
|
-
| `rotateHue(hex, degrees)` | Rotates hue by degrees; supports negative values |
|
|
214
|
-
| `adjustHexBrightness(hex, offsetPercent)` | Lightens (positive) or darkens (negative) by percentage |
|
|
215
|
-
| `mixColors(c1, c2, t, opts?)` | Interpolates between two colors. `t` = 0–1. `mode`: `'rgb'` \| `'hsl'` \| `'lab'` \| `'lch'` \| `'oklab'` \| `'oklch'`. `hueInterpolation`: `'shorter'` \| `'longer'` \| `'increasing'` \| `'decreasing'` |
|
|
216
|
-
|
|
217
|
-
### `mixColors` example
|
|
218
|
-
|
|
219
|
-
```ts
|
|
220
|
-
import { mixColors } from 'color-value-tools'
|
|
221
|
-
|
|
222
|
-
// RGB mix at midpoint
|
|
223
|
-
mixColors('#e74c3c', '#3498db', 0.5)
|
|
224
|
-
// → '#8dc6bc'
|
|
225
|
-
|
|
226
|
-
// Perceptually even mix in Oklab
|
|
227
|
-
mixColors('#e74c3c', '#3498db', 0.5, { mode: 'oklab', format: 'hex' })
|
|
228
|
-
|
|
229
|
-
// HSL with "longer" hue path
|
|
230
|
-
mixColors('#e74c3c', '#3498db', 0.5, { mode: 'hsl', hueInterpolation: 'longer' })
|
|
231
|
-
|
|
232
|
-
// Get rgba string output
|
|
233
|
-
mixColors('#ff0000', '#0000ff', 0.25, { mode: 'lab', format: 'rgba' })
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
---
|
|
237
|
-
|
|
238
|
-
## Interpolation & Scales
|
|
239
|
-
|
|
240
|
-
| Function | Description |
|
|
241
|
-
|---|---|
|
|
242
|
-
| `interpolateColors(c1, c2, steps, opts?)` | Returns array of `steps` colors from `c1` to `c2`. Same `space` / `format` / `hueInterpolation` options as `mixColors` |
|
|
243
|
-
| `createColorScale(anchors, steps, opts?)` | Generates a `steps`-color scale across multiple anchor colors with optional positions (0–1) |
|
|
244
|
-
| `midpointColor(c1, c2, opts?)` | Perceptual midpoint between two colors (default space: `'oklab'`) |
|
|
245
|
-
|
|
246
|
-
### `createColorScale` — multi-stop gradient
|
|
247
|
-
|
|
248
|
-
```ts
|
|
249
|
-
import { createColorScale } from 'color-value-tools'
|
|
250
|
-
|
|
251
|
-
// Evenly spaced anchors
|
|
252
|
-
createColorScale(['#ff0000', '#ffff00', '#00ff00'], 9)
|
|
253
|
-
|
|
254
|
-
// With explicit positions
|
|
255
|
-
createColorScale(
|
|
256
|
-
[
|
|
257
|
-
{ color: '#1a1a2e', position: 0 },
|
|
258
|
-
{ color: '#e94560', position: 0.4 },
|
|
259
|
-
{ color: '#f5a623', position: 1 },
|
|
260
|
-
],
|
|
261
|
-
12,
|
|
262
|
-
{ space: 'oklch' }
|
|
263
|
-
)
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
---
|
|
267
|
-
|
|
268
|
-
## Color Harmonies
|
|
269
|
-
|
|
270
|
-
| Function | Description |
|
|
271
|
-
|---|---|
|
|
272
|
-
| `complement(color)` | Complementary color (180° rotation) |
|
|
273
|
-
| `triadic(color)` | 3 colors evenly spaced 120° apart |
|
|
274
|
-
| `analogous(color, angle?)` | 3 neighboring colors (default ±30°) |
|
|
275
|
-
| `splitComplementary(color)` | Base + two colors at 150° and 210° |
|
|
276
|
-
| `tetradic(color)` | 4 colors evenly spaced 90° apart |
|
|
277
|
-
|
|
278
|
-
```ts
|
|
279
|
-
import { triadic, analogous, tetradic } from 'color-value-tools'
|
|
280
|
-
|
|
281
|
-
triadic('#6c3483') // ['#6c3483', '#34836c', '#83346c']
|
|
282
|
-
analogous('#6c3483', 45) // ['#833469', '#6c3483', '#3469…']
|
|
283
|
-
tetradic('#6c3483') // 4 colors
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
---
|
|
287
|
-
|
|
288
|
-
## Palette Generation
|
|
83
|
+
### More examples
|
|
289
84
|
|
|
290
|
-
|
|
291
|
-
|---|---|
|
|
292
|
-
| `colorShades(color, steps?)` | Light-to-dark HSL scale (default 9 steps) |
|
|
293
|
-
| `monochromatic(color, steps?)` | Varying saturation at fixed lightness (default 5 steps) |
|
|
294
|
-
| `tints(color, steps?)` | Mix toward white in Oklab (default 5 steps) |
|
|
295
|
-
| `shades(color, steps?)` | Mix toward black in Oklab (default 5 steps) |
|
|
296
|
-
| `tones(color, steps?, gray?)` | Mix toward gray in Oklab (default 5 steps, gray `#808080`) |
|
|
85
|
+
#### What your palette looks like to a colorblind user
|
|
297
86
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
## Accessibility (WCAG)
|
|
301
|
-
|
|
302
|
-
| Function | Description |
|
|
303
|
-
|---|---|
|
|
304
|
-
| `relativeLuminance(color)` | WCAG relative luminance (0–1) |
|
|
305
|
-
| `contrastRatio(c1, c2)` | WCAG contrast ratio (1–21) |
|
|
306
|
-
| `wcagLevel(fg, bg)` | Returns `'AAA'` \| `'AA'` \| `'AA-large'` \| `'fail'` |
|
|
307
|
-
| `bestTextColor(bg)` | Returns `'#000000'` or `'#ffffff'` for best contrast on `bg` |
|
|
308
|
-
| `bestContrastColor(bg, candidates)` | Picks the most readable color from an array of candidates |
|
|
309
|
-
| `bestContrastPalette(bg, palettes, opts?)` | Picks the palette with best overall contrast. Returns `{ paletteIndex, palette, minContrastRatio, avgContrastRatio }` |
|
|
310
|
-
| `isReadableOnBackground(text, bg, opts?)` | Checks readability on solid, semi-transparent, or gradient backgrounds. Returns `{ readable, minContrastRatio, wcagLevel }` |
|
|
311
|
-
| `isDark(color, threshold?)` | `true` if luminance is below threshold (default 0.5) |
|
|
312
|
-
| `isLight(color, threshold?)` | Inverse of `isDark` |
|
|
313
|
-
|
|
314
|
-
### `isReadableOnBackground` — complex backgrounds
|
|
315
|
-
|
|
316
|
-
`background` can be a plain color string, a semi-transparent spec, or a gradient with multiple stops:
|
|
317
|
-
|
|
318
|
-
```ts
|
|
319
|
-
import { isReadableOnBackground } from 'color-value-tools'
|
|
320
|
-
|
|
321
|
-
// Solid background
|
|
322
|
-
isReadableOnBackground('#ffffff', '#3498db')
|
|
323
|
-
// → { readable: true, minContrastRatio: 3.05, wcagLevel: 'AA-large' }
|
|
324
|
-
|
|
325
|
-
// Semi-transparent overlay composited over white
|
|
326
|
-
isReadableOnBackground('#ffffff', {
|
|
327
|
-
type: 'semi-transparent',
|
|
328
|
-
color: 'rgba(52, 152, 219, 0.5)',
|
|
329
|
-
underlay: '#f0f0f0',
|
|
330
|
-
})
|
|
331
|
-
|
|
332
|
-
// Gradient — worst stop is used for the result
|
|
333
|
-
isReadableOnBackground('#ffffff', {
|
|
334
|
-
type: 'gradient',
|
|
335
|
-
stops: ['#1a1a2e', '#e94560', '#f5a623'],
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
// AAA + large text
|
|
339
|
-
isReadableOnBackground('#000000', '#f0f0f0', { level: 'AAA', largeText: true })
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
### `bestContrastPalette` — pick accessible palette
|
|
343
|
-
|
|
344
|
-
```ts
|
|
345
|
-
import { bestContrastPalette } from 'color-value-tools'
|
|
346
|
-
|
|
347
|
-
const result = bestContrastPalette('#1a1a2e', [
|
|
348
|
-
['#ffffff', '#f0f0f0', '#cccccc'],
|
|
349
|
-
['#ffff00', '#ffd700', '#ff8c00'],
|
|
350
|
-
])
|
|
351
|
-
// → { paletteIndex: 0, palette: [...], minContrastRatio: 12.1, avgContrastRatio: 14.3 }
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
---
|
|
355
|
-
|
|
356
|
-
## Color Blindness Simulation
|
|
357
|
-
|
|
358
|
-
Simulates perception using Vienot 1999 matrices applied to linearized RGB.
|
|
359
|
-
|
|
360
|
-
| Function | Description |
|
|
361
|
-
|---|---|
|
|
362
|
-
| `simulateProtanopia(color)` | No L-cones (red-blind) |
|
|
363
|
-
| `simulateDeuteranopia(color)` | No M-cones (green-blind) |
|
|
364
|
-
| `simulateTritanopia(color)` | No S-cones (blue-blind) |
|
|
365
|
-
| `simulateColorBlindness(color, type)` | Generic — `type`: `'protanopia'` \| `'deuteranopia'` \| `'tritanopia'` |
|
|
87
|
+
`simulateColorBlindness` applies the Vienot 1999 matrices to linearized RGB — you can check contrast before shipping, not guess from a checklist.
|
|
366
88
|
|
|
367
89
|
```ts
|
|
368
90
|
import { simulateColorBlindness } from 'color-value-tools'
|
|
369
91
|
|
|
370
|
-
simulateColorBlindness('#e74c3c', 'deuteranopia')
|
|
371
|
-
simulateColorBlindness('#3498db', 'protanopia')
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
---
|
|
375
|
-
|
|
376
|
-
## Formatting
|
|
377
|
-
|
|
378
|
-
| Function | Description |
|
|
379
|
-
|---|---|
|
|
380
|
-
| `toHslString(h, s, l, alpha?)` | Formats as `hsl(...)` or `hsla(...)` |
|
|
381
|
-
| `toHwbString(H, W, B, alpha?)` | Formats as `hwb(...)` with optional alpha |
|
|
382
|
-
| `toOklchString(color, alpha?)` | Converts any color to `oklch(L C H)` CSS string |
|
|
383
|
-
| `toColorP3String(color, alpha?)` | Converts any color to `color(display-p3 r g b)` CSS string |
|
|
92
|
+
simulateColorBlindness('#e74c3c', 'deuteranopia') // '#9a7b00'
|
|
93
|
+
simulateColorBlindness('#3498db', 'protanopia') // '#5282db'
|
|
384
94
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
toOklchString('#3498db') // 'oklch(0.6 0.1175 234.77)'
|
|
389
|
-
toColorP3String('#3498db') // 'color(display-p3 0.2493 0.5875 0.8479)'
|
|
390
|
-
toHwbString(204, 20, 14) // 'hwb(204 20% 14%)'
|
|
391
|
-
toHwbString(204, 20, 14, 0.8) // 'hwb(204 20% 14% / 0.8)'
|
|
95
|
+
// Vienot 1999 matrices applied to linearized RGB — good enough to check a
|
|
96
|
+
// palette before it ships, not just guess from a colorblind-safe checklist.
|
|
392
97
|
```
|
|
393
98
|
|
|
394
|
-
|
|
99
|
+
#### A harmony and a shade scale from one color
|
|
395
100
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
Useful in rendering loops, color pickers, or any context with repeated `normalizeColor` calls on the same values.
|
|
399
|
-
|
|
400
|
-
| Function | Description |
|
|
401
|
-
|---|---|
|
|
402
|
-
| `normalizeColorCached(input)` | Cached version of `normalizeColor` for repeated string calls |
|
|
403
|
-
| `clearColorCache()` | Clears the normalization cache and resets hit counter |
|
|
404
|
-
| `getCacheStats()` | Returns `{ size: number, hits: number }` |
|
|
405
|
-
| `enableCache()` | Re-enables the cache (on by default) |
|
|
406
|
-
| `disableCache()` | Disables caching (useful in tests) |
|
|
101
|
+
`triadic` builds three colors 120° apart, `colorShades` a light-to-dark scale of nine steps. One base color in, a coordinated palette out — no manual hue math, no hand-picked hex values.
|
|
407
102
|
|
|
408
103
|
```ts
|
|
409
|
-
import {
|
|
104
|
+
import { triadic, colorShades } from 'color-value-tools'
|
|
410
105
|
|
|
411
|
-
//
|
|
412
|
-
normalizeColorCached('#3498db')
|
|
106
|
+
triadic('#6c3483') // ['#6c3483', '#34836c', '#83346c'] — evenly spaced 120°
|
|
413
107
|
|
|
414
|
-
//
|
|
415
|
-
normalizeColorCached('#3498db')
|
|
108
|
+
const shades = colorShades('#6c3483', 9) // light-to-dark HSL scale, 9 steps
|
|
416
109
|
|
|
417
|
-
|
|
418
|
-
|
|
110
|
+
// One base color in, a coordinated palette out — no manual hue-rotation
|
|
111
|
+
// math, no hand-picked hex values.
|
|
419
112
|
```
|
|
420
113
|
|
|
421
114
|
---
|
|
422
115
|
|
|
423
|
-
##
|
|
424
|
-
|
|
425
|
-
Useful for large palettes and frame-by-frame animations without allocating full arrays upfront.
|
|
426
|
-
|
|
427
|
-
| Function | Description |
|
|
428
|
-
|---|---|
|
|
429
|
-
| `generateGradientColors*(start, end, steps, opts?)` | Yields `steps` colors from `start` to `end`. Same `mode` / `format` options as `mixColors` |
|
|
430
|
-
| `generateTints*(color, steps, opts?)` | Yields tints toward white in Oklab |
|
|
431
|
-
| `generateShades*(color, steps, opts?)` | Yields shades toward black in Oklab |
|
|
432
|
-
|
|
433
|
-
```ts
|
|
434
|
-
import { generateGradientColors, generateTints } from 'color-value-tools'
|
|
116
|
+
## Documentation & links
|
|
435
117
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const first5 = [...generateTints('#e74c3c', 100)].slice(0, 5)
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
---
|
|
446
|
-
|
|
447
|
-
## CLI
|
|
448
|
-
|
|
449
|
-
The `cvt` CLI is included in the package. Install globally or use via `npx`:
|
|
450
|
-
|
|
451
|
-
```bash
|
|
452
|
-
npm install -g color-value-tools
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
```bash
|
|
456
|
-
# Full info (default command)
|
|
457
|
-
cvt "#3498db"
|
|
458
|
-
|
|
459
|
-
# All format conversions — hex, rgb, hsl, hsv, hwb, lab, lch, oklab, oklch, cmyk
|
|
460
|
-
cvt "#3498db" convert
|
|
461
|
-
|
|
462
|
-
# Contrast ratio and WCAG level
|
|
463
|
-
cvt "#3498db" contrast "#ffffff"
|
|
464
|
-
|
|
465
|
-
# Generate 7 shades
|
|
466
|
-
cvt "#3498db" shades 7
|
|
467
|
-
|
|
468
|
-
# All harmonies — complement, triadic, analogous, split-comp, tetradic
|
|
469
|
-
cvt "#3498db" harmonies
|
|
470
|
-
|
|
471
|
-
# Nearest CSS named color
|
|
472
|
-
cvt "cornflowerblue" nearest
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
Accepts any valid color format: hex, `rgb()`, `hsl()`, `oklch()`, named colors.
|
|
476
|
-
|
|
477
|
-
```
|
|
478
|
-
cvt "#3498db"
|
|
479
|
-
────────────────────────────────────────
|
|
480
|
-
Type: hex
|
|
481
|
-
Hex: #3498db
|
|
482
|
-
RGB: rgb(52, 152, 219)
|
|
483
|
-
HSL: hsl(204, 70%, 53%)
|
|
484
|
-
HSV: hsv(204, 76%, 86%)
|
|
485
|
-
Nearest named: cornflowerblue
|
|
486
|
-
Best text on it: #ffffff
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
---
|
|
490
|
-
|
|
491
|
-
## Cookbook
|
|
492
|
-
|
|
493
|
-
### Generate an accessible button palette
|
|
494
|
-
|
|
495
|
-
```ts
|
|
496
|
-
import { colorShades, bestTextColor, wcagLevel } from 'color-value-tools'
|
|
497
|
-
|
|
498
|
-
function buttonPalette(base: string) {
|
|
499
|
-
return colorShades(base, 9).map(shade => ({
|
|
500
|
-
bg: shade,
|
|
501
|
-
text: bestTextColor(shade),
|
|
502
|
-
wcag: wcagLevel(bestTextColor(shade), shade),
|
|
503
|
-
}))
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
buttonPalette('#3498db')
|
|
507
|
-
// [{ bg: '#ffffff', text: '#000000', wcag: 'AAA' }, ...]
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
### Theme-aware color adaptation
|
|
511
|
-
|
|
512
|
-
```ts
|
|
513
|
-
import { isDark, lighten, darken } from 'color-value-tools'
|
|
514
|
-
|
|
515
|
-
function adaptToTheme(color: string, isDarkTheme: boolean): string {
|
|
516
|
-
return isDarkTheme ? lighten(color, 20) : darken(color, 10)
|
|
517
|
-
}
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
### Mix two brand colors at a perceptual midpoint
|
|
521
|
-
|
|
522
|
-
```ts
|
|
523
|
-
import { midpointColor } from 'color-value-tools'
|
|
524
|
-
|
|
525
|
-
const mid = midpointColor('#e74c3c', '#3498db') // Oklab midpoint
|
|
526
|
-
const midLch = midpointColor('#e74c3c', '#3498db', { space: 'oklch' })
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
### Build a triadic scheme and check contrast
|
|
530
|
-
|
|
531
|
-
```ts
|
|
532
|
-
import { triadic, contrastRatio } from 'color-value-tools'
|
|
533
|
-
|
|
534
|
-
const [base, second, third] = triadic('#6c3483')
|
|
535
|
-
console.log(contrastRatio(base, '#ffffff')) // e.g. 8.4
|
|
536
|
-
console.log(contrastRatio(second, '#ffffff'))
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
### Convert any color string to all formats at once
|
|
540
|
-
|
|
541
|
-
```ts
|
|
542
|
-
import { normalizeColor, rgbToOklch, rgbToCmyk, toColorP3String } from 'color-value-tools'
|
|
543
|
-
|
|
544
|
-
const n = normalizeColor('hsl(204, 70%, 53%)')
|
|
545
|
-
const oklch = rgbToOklch({ r: n.r!, g: n.g!, b: n.b! })
|
|
546
|
-
const cmyk = rgbToCmyk({ r: n.r!, g: n.g!, b: n.b! })
|
|
547
|
-
const p3 = toColorP3String(n.hex!)
|
|
548
|
-
console.log(n.hex, oklch, cmyk, p3)
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
### Find the nearest CSS named color
|
|
552
|
-
|
|
553
|
-
```ts
|
|
554
|
-
import { toNearestNamedColor } from 'color-value-tools'
|
|
555
|
-
|
|
556
|
-
toNearestNamedColor('#1a8ccc') // 'steelblue'
|
|
557
|
-
toNearestNamedColor('#e74c3c') // 'tomato'
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
### Random palette within a hue range
|
|
561
|
-
|
|
562
|
-
```ts
|
|
563
|
-
import { randomColor, colorShades } from 'color-value-tools'
|
|
564
|
-
|
|
565
|
-
const accent = randomColor({ hRange: [200, 260], sRange: [60, 80], lRange: [40, 60] })
|
|
566
|
-
const palette = colorShades(accent, 5)
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
### Simulate color blindness for a palette
|
|
570
|
-
|
|
571
|
-
```ts
|
|
572
|
-
import { triadic, simulateColorBlindness } from 'color-value-tools'
|
|
573
|
-
|
|
574
|
-
const palette = triadic('#e74c3c')
|
|
575
|
-
const deuteranopia = palette.map(c => simulateColorBlindness(c, 'deuteranopia'))
|
|
576
|
-
// Compare palette vs deuteranopia to verify distinguishability
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
### Lazy gradient — process 10 000 colors one at a time
|
|
580
|
-
|
|
581
|
-
```ts
|
|
582
|
-
import { generateGradientColors } from 'color-value-tools'
|
|
583
|
-
|
|
584
|
-
for (const color of generateGradientColors('#1a1a2e', '#f5a623', 10_000, { mode: 'oklch' })) {
|
|
585
|
-
ctx.fillStyle = color
|
|
586
|
-
ctx.fillRect(x++, 0, 1, height)
|
|
587
|
-
}
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
---
|
|
591
|
-
|
|
592
|
-
## TypeScript types
|
|
593
|
-
|
|
594
|
-
All public types are exported from the package root:
|
|
595
|
-
|
|
596
|
-
```ts
|
|
597
|
-
import type {
|
|
598
|
-
ColorType, // 'hex' | 'css-var' | 'rgb' | 'hsl' | 'named' | 'oklch' | 'color' | 'unknown'
|
|
599
|
-
WcagLevel, // 'AAA' | 'AA' | 'AA-large' | 'fail'
|
|
600
|
-
ColorBlindnessType, // 'protanopia' | 'deuteranopia' | 'tritanopia'
|
|
601
|
-
BackgroundSpec, // string | { type: 'semi-transparent'; ... } | { type: 'gradient'; ... }
|
|
602
|
-
PaletteScore, // { palette, minContrastRatio, avgContrastRatio }
|
|
603
|
-
} from 'color-value-tools'
|
|
604
|
-
```
|
|
605
|
-
|
|
606
|
-
### `BackgroundSpec` — discriminated union
|
|
607
|
-
|
|
608
|
-
```ts
|
|
609
|
-
import type { BackgroundSpec } from 'color-value-tools'
|
|
610
|
-
|
|
611
|
-
const solid: BackgroundSpec = '#3498db'
|
|
612
|
-
|
|
613
|
-
const semiTransparent: BackgroundSpec = {
|
|
614
|
-
type: 'semi-transparent',
|
|
615
|
-
color: 'rgba(0,0,0,0.4)',
|
|
616
|
-
underlay: '#ffffff', // optional, defaults to white
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
const gradient: BackgroundSpec = {
|
|
620
|
-
type: 'gradient',
|
|
621
|
-
stops: ['#1a1a2e', '#e94560', '#f5a623'],
|
|
622
|
-
}
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
### `PaletteScore` — from `bestContrastPalette`
|
|
626
|
-
|
|
627
|
-
```ts
|
|
628
|
-
import type { PaletteScore } from 'color-value-tools'
|
|
629
|
-
|
|
630
|
-
const result: PaletteScore & { paletteIndex: number } = bestContrastPalette(bg, palettes)
|
|
631
|
-
result.paletteIndex // number
|
|
632
|
-
result.palette // string[]
|
|
633
|
-
result.minContrastRatio // number
|
|
634
|
-
result.avgContrastRatio // number
|
|
635
|
-
```
|
|
636
|
-
|
|
637
|
-
### Inference from `normalizeColor`
|
|
638
|
-
|
|
639
|
-
```ts
|
|
640
|
-
import { normalizeColor } from 'color-value-tools'
|
|
641
|
-
|
|
642
|
-
const n = normalizeColor('#3498db')
|
|
643
|
-
// TypeScript knows: n.hex, n.r, n.g, n.b, n.h, n.s, n.l, n.v, n.a, n.type
|
|
644
|
-
|
|
645
|
-
if (n.type !== 'unknown' && n.type !== 'css-var') {
|
|
646
|
-
const r: number = n.r! // available for all resolved color types
|
|
647
|
-
}
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
---
|
|
651
|
-
|
|
652
|
-
## Architecture
|
|
653
|
-
|
|
654
|
-
```
|
|
655
|
-
color-value-tools
|
|
656
|
-
│
|
|
657
|
-
├── Detection
|
|
658
|
-
│ getColorType, isHexColor, isRgbColor, isHslColor,
|
|
659
|
-
│ isOklchColor, isColorFunction, isCssVariable
|
|
660
|
-
│
|
|
661
|
-
├── Parsing
|
|
662
|
-
│ normalizeColor → universal entry point; handles all formats + objects
|
|
663
|
-
│ rgbaStringToRgba → rgb()/rgba() parser
|
|
664
|
-
│ hex8ToRgba → 8-digit and 4-digit hex with alpha
|
|
665
|
-
│ parseOklchString → oklch(L C H / alpha) with % L support
|
|
666
|
-
│ parseColorFn → color(display-p3 ...) / color(srgb ...)
|
|
667
|
-
│ parseHwbString → hwb() string
|
|
668
|
-
│ parseCssVar → var(--name, fallback)
|
|
669
|
-
│
|
|
670
|
-
├── Color Math — every space via RGB as the hub
|
|
671
|
-
│ sRGB ↔ Linear (srgbChanToLinear / linearChanToSrgb)
|
|
672
|
-
│ XYZ D65 intermediate for Lab/LCH
|
|
673
|
-
│ Oklab/Oklch — Björn Ottosson matrices
|
|
674
|
-
│ Display P3 — ICC sRGB→P3 and P3→sRGB matrices
|
|
675
|
-
│
|
|
676
|
-
├── Manipulation
|
|
677
|
-
│ lighten / darken / saturate / desaturate — via HSL
|
|
678
|
-
│ invertColor — RGB invert
|
|
679
|
-
│ grayscale — BT.709 perceptual weights
|
|
680
|
-
│ rotateHue — via HSL hue shift
|
|
681
|
-
│ adjustHexBrightness — linear channel blend toward 0/255
|
|
682
|
-
│ setAlpha / getAlpha — rgba string manipulation
|
|
683
|
-
│
|
|
684
|
-
├── mixColors (core of interpolation system)
|
|
685
|
-
│ 6 color space modes: rgb | hsl | lab | lch | oklab | oklch
|
|
686
|
-
│ 4 hue interpolation modes: shorter | longer | increasing | decreasing
|
|
687
|
-
│ 4 output formats: hex | rgb | rgba | hsl
|
|
688
|
-
│ Used internally by: interpolateColors, createColorScale,
|
|
689
|
-
│ midpointColor, tints, shades, tones,
|
|
690
|
-
│ generateGradientColors*, generateTints*, generateShades*
|
|
691
|
-
│
|
|
692
|
-
├── Color Harmonies
|
|
693
|
-
│ All implemented as hue rotations on normalized hex
|
|
694
|
-
│
|
|
695
|
-
├── Palette Generation
|
|
696
|
-
│ colorShades — HSL lightness sweep
|
|
697
|
-
│ monochromatic — HSL saturation sweep
|
|
698
|
-
│ tints / shades / tones — Oklab interpolation via mixColors
|
|
699
|
-
│
|
|
700
|
-
├── Accessibility
|
|
701
|
-
│ relativeLuminance — WCAG linearization formula
|
|
702
|
-
│ contrastRatio — (L1+0.05)/(L2+0.05)
|
|
703
|
-
│ wcagLevel — ratio thresholds 3 / 4.5 / 7
|
|
704
|
-
│ isReadableOnBackground — handles 3 background types;
|
|
705
|
-
│ semi-transparent: alpha-composites onto underlay before ratio check
|
|
706
|
-
│ gradient: evaluates each stop, uses minimum ratio
|
|
707
|
-
│ bestContrastPalette — score = avg×0.4 + min×0.6
|
|
708
|
-
│
|
|
709
|
-
├── Color Blindness
|
|
710
|
-
│ Vienot 1999 matrices on linear RGB
|
|
711
|
-
│ 3 types: protanopia / deuteranopia / tritanopia
|
|
712
|
-
│
|
|
713
|
-
├── Cache (Section 5.1)
|
|
714
|
-
│ Simple Map<string, NormalizeResult>
|
|
715
|
-
│ normalizeColorCached — Map lookup before calling normalizeColor
|
|
716
|
-
│ getCacheStats / clearColorCache / enableCache / disableCache
|
|
717
|
-
│
|
|
718
|
-
├── Generator functions (Section 5.2)
|
|
719
|
-
│ ES2015 generator syntax (*) — yield one color at a time
|
|
720
|
-
│ generateGradientColors* → mixColors inside the generator
|
|
721
|
-
│ generateTints* / generateShades* → Oklab mix toward white/black
|
|
722
|
-
│
|
|
723
|
-
└── CLI (dist/cli/bin/cli.js → cvt)
|
|
724
|
-
Commands: info | convert | contrast | shades | harmonies | nearest
|
|
725
|
-
Accepts any color format normalizeColor understands
|
|
726
|
-
```
|
|
727
|
-
|
|
728
|
-
---
|
|
729
|
-
|
|
730
|
-
## Bundle size & dependencies
|
|
731
|
-
|
|
732
|
-
| | |
|
|
733
|
-
|---|---|
|
|
734
|
-
| **Runtime dependencies** | None |
|
|
735
|
-
| **Peer dependencies** | None |
|
|
736
|
-
| **Dev dependencies** | TypeScript, Vitest |
|
|
737
|
-
| **ESM entry** | `dist/esm/index.js` (tree-shakeable) |
|
|
738
|
-
| **CJS entry** | `dist/cjs/index.js` |
|
|
739
|
-
| **CLI entry** | `dist/cli/bin/cli.js` → `cvt` |
|
|
740
|
-
|
|
741
|
-
The package ships both ESM (`type: module`) and CommonJS modules. Every function is a named export — unused functions are eliminated by bundlers that support tree-shaking.
|
|
118
|
+
- 📖 **Full documentation:** [npm.vuecraft.ru/en/packages/color-value-tools](https://npm.vuecraft.ru/en/packages/color-value-tools/guide/overview.html)
|
|
119
|
+
- 🌐 **VueCraft:** [vuecraft.ru/en](https://vuecraft.ru/en)
|
|
120
|
+
- 👤 **Author:** [macrulez.ru/en](https://macrulez.ru/en)
|
|
121
|
+
- 💻 **GitHub:** [macrulezru/color-value-tools](https://github.com/macrulezru/color-value-tools)
|
|
122
|
+
- 📦 **NPM:** [color-value-tools](https://www.npmjs.com/package/color-value-tools)
|
|
123
|
+
- 🐛 **Issues:** [github.com/macrulezru/color-value-tools/issues](https://github.com/macrulezru/color-value-tools/issues)
|
|
742
124
|
|
|
743
125
|
---
|
|
744
126
|
|
|
@@ -748,19 +130,9 @@ MIT
|
|
|
748
130
|
|
|
749
131
|
---
|
|
750
132
|
|
|
751
|
-
## Author
|
|
752
|
-
|
|
753
|
-
Danil Lisin Vladimirovich aka Macrulez
|
|
754
|
-
|
|
755
|
-
GitHub: [macrulezru](https://github.com/macrulezru) · Website: [npm.vuecraft.ru/en/](https://npm.vuecraft.ru/en/packages/color-value-tools/)
|
|
756
|
-
|
|
757
|
-
Bugs and questions — [issues](https://github.com/macrulezru/color-value-tools/issues)
|
|
758
|
-
|
|
759
|
-
---
|
|
760
|
-
|
|
761
133
|
## 💖 Support the project
|
|
762
134
|
|
|
763
|
-
Open source takes time and effort. If
|
|
135
|
+
Open source takes time and effort. If this library saves you time or brings value, consider supporting further development.
|
|
764
136
|
|
|
765
137
|
<a href="https://donate.cryptocloud.plus/M6O34NIN" target="_blank">
|
|
766
138
|
<img src="https://img.shields.io/badge/Donate-CryptoCloud-8A2BE2?style=for-the-badge&logo=cryptocurrency&logoColor=white" alt="Donate via CryptoCloud">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "color-value-tools",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.11",
|
|
4
4
|
"description": "Parse, convert and manipulate colors across hex, RGB, HSL, Lab, LCH, OKLCH and CMYK, with WCAG contrast checks and CSS variables. Zero dependencies.",
|
|
5
5
|
"author": "macrulez <macrulezru@gmail.com> (https://macrulez.ru/en)",
|
|
6
6
|
"license": "MIT",
|