color-value-tools 1.1.8 → 1.1.10
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 +36 -695
- package/dist/cjs/index.js +8 -0
- package/dist/cli/src/index.js +8 -0
- package/dist/esm/index.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,36 +1,11 @@
|
|
|
1
1
|
# **Color Value Tools**
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
A comprehensive utility library for parsing, converting, manipulating, and analyzing color values across all major color models — hex, RGB, HSL, HSV, HWB, Lab, LCH, Oklab, Oklch, CMYK, Display P3 — plus CSS variables and named colors. Zero dependencies.
|
|
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
|
|
|
@@ -103,642 +82,14 @@ const { normalizeColor, mixColors } = require('color-value-tools')
|
|
|
103
82
|
|
|
104
83
|
---
|
|
105
84
|
|
|
106
|
-
##
|
|
85
|
+
## Documentation & links
|
|
107
86
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
|
289
|
-
|
|
290
|
-
| Function | Description |
|
|
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`) |
|
|
297
|
-
|
|
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'` |
|
|
366
|
-
|
|
367
|
-
```ts
|
|
368
|
-
import { simulateColorBlindness } from 'color-value-tools'
|
|
369
|
-
|
|
370
|
-
simulateColorBlindness('#e74c3c', 'deuteranopia') // '#9a7b00'
|
|
371
|
-
simulateColorBlindness('#3498db', 'protanopia') // '#5282db'
|
|
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 |
|
|
384
|
-
|
|
385
|
-
```ts
|
|
386
|
-
import { toOklchString, toColorP3String, toHwbString } from 'color-value-tools'
|
|
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)'
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
---
|
|
395
|
-
|
|
396
|
-
## Cache Management
|
|
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) |
|
|
407
|
-
|
|
408
|
-
```ts
|
|
409
|
-
import { normalizeColorCached, getCacheStats, clearColorCache } from 'color-value-tools'
|
|
410
|
-
|
|
411
|
-
// First call — parsed and cached
|
|
412
|
-
normalizeColorCached('#3498db')
|
|
413
|
-
|
|
414
|
-
// Second call — instant cache hit
|
|
415
|
-
normalizeColorCached('#3498db')
|
|
416
|
-
|
|
417
|
-
getCacheStats() // { size: 1, hits: 1 }
|
|
418
|
-
clearColorCache() // { size: 0, hits: 0 } reset
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
## Generator Functions
|
|
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'
|
|
435
|
-
|
|
436
|
-
// Process one color at a time — no intermediate array
|
|
437
|
-
for (const color of generateGradientColors('#ff0000', '#0000ff', 1000, { mode: 'oklch' })) {
|
|
438
|
-
renderPixel(color)
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
// Collect lazily
|
|
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.
|
|
87
|
+
- 📖 **Full documentation:** [npm.vuecraft.ru/en/packages/color-value-tools](https://npm.vuecraft.ru/en/packages/color-value-tools/guide/overview.html)
|
|
88
|
+
- 🌐 **VueCraft:** [vuecraft.ru/en](https://vuecraft.ru/en)
|
|
89
|
+
- 👤 **Author:** [macrulez.ru/en](https://macrulez.ru/en)
|
|
90
|
+
- 💻 **GitHub:** [macrulezru/color-value-tools](https://github.com/macrulezru/color-value-tools)
|
|
91
|
+
- 📦 **NPM:** [color-value-tools](https://www.npmjs.com/package/color-value-tools)
|
|
92
|
+
- 🐛 **Issues:** [github.com/macrulezru/color-value-tools/issues](https://github.com/macrulezru/color-value-tools/issues)
|
|
742
93
|
|
|
743
94
|
---
|
|
744
95
|
|
|
@@ -748,19 +99,9 @@ MIT
|
|
|
748
99
|
|
|
749
100
|
---
|
|
750
101
|
|
|
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
102
|
## 💖 Support the project
|
|
762
103
|
|
|
763
|
-
Open source takes time and effort. If
|
|
104
|
+
Open source takes time and effort. If this library saves you time or brings value, consider supporting further development.
|
|
764
105
|
|
|
765
106
|
<a href="https://donate.cryptocloud.plus/M6O34NIN" target="_blank">
|
|
766
107
|
<img src="https://img.shields.io/badge/Donate-CryptoCloud-8A2BE2?style=for-the-badge&logo=cryptocurrency&logoColor=white" alt="Donate via CryptoCloud">
|
package/dist/cjs/index.js
CHANGED
|
@@ -708,6 +708,14 @@ function normalizeColor(input) {
|
|
|
708
708
|
}
|
|
709
709
|
if (str === 'transparent')
|
|
710
710
|
return { type: 'named', hex: '#000000', r: 0, g: 0, b: 0, a: 0 };
|
|
711
|
+
const lowerStr = str.toLowerCase();
|
|
712
|
+
if (lowerStr in NAMED_COLORS) {
|
|
713
|
+
const hex = NAMED_COLORS[lowerStr];
|
|
714
|
+
const [r, g, b] = hexToRgb(hex);
|
|
715
|
+
const [h, s, l] = hexToHsl(hex);
|
|
716
|
+
const [, , vv] = rgbToHsv({ r, g, b });
|
|
717
|
+
return { type: 'named', hex, r, g, b, a: 1, h, s, l, v: vv };
|
|
718
|
+
}
|
|
711
719
|
// oklch / oklcha
|
|
712
720
|
if (isOklchColor(str)) {
|
|
713
721
|
const parsed = parseOklchString(str);
|
package/dist/cli/src/index.js
CHANGED
|
@@ -708,6 +708,14 @@ function normalizeColor(input) {
|
|
|
708
708
|
}
|
|
709
709
|
if (str === 'transparent')
|
|
710
710
|
return { type: 'named', hex: '#000000', r: 0, g: 0, b: 0, a: 0 };
|
|
711
|
+
const lowerStr = str.toLowerCase();
|
|
712
|
+
if (lowerStr in NAMED_COLORS) {
|
|
713
|
+
const hex = NAMED_COLORS[lowerStr];
|
|
714
|
+
const [r, g, b] = hexToRgb(hex);
|
|
715
|
+
const [h, s, l] = hexToHsl(hex);
|
|
716
|
+
const [, , vv] = rgbToHsv({ r, g, b });
|
|
717
|
+
return { type: 'named', hex, r, g, b, a: 1, h, s, l, v: vv };
|
|
718
|
+
}
|
|
711
719
|
// oklch / oklcha
|
|
712
720
|
if (isOklchColor(str)) {
|
|
713
721
|
const parsed = parseOklchString(str);
|
package/dist/esm/index.js
CHANGED
|
@@ -608,6 +608,14 @@ export function normalizeColor(input) {
|
|
|
608
608
|
}
|
|
609
609
|
if (str === 'transparent')
|
|
610
610
|
return { type: 'named', hex: '#000000', r: 0, g: 0, b: 0, a: 0 };
|
|
611
|
+
const lowerStr = str.toLowerCase();
|
|
612
|
+
if (lowerStr in NAMED_COLORS) {
|
|
613
|
+
const hex = NAMED_COLORS[lowerStr];
|
|
614
|
+
const [r, g, b] = hexToRgb(hex);
|
|
615
|
+
const [h, s, l] = hexToHsl(hex);
|
|
616
|
+
const [, , vv] = rgbToHsv({ r, g, b });
|
|
617
|
+
return { type: 'named', hex, r, g, b, a: 1, h, s, l, v: vv };
|
|
618
|
+
}
|
|
611
619
|
// oklch / oklcha
|
|
612
620
|
if (isOklchColor(str)) {
|
|
613
621
|
const parsed = parseOklchString(str);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "color-value-tools",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.10",
|
|
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",
|