colorizr 3.0.0 → 3.0.2

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 CHANGED
@@ -8,7 +8,7 @@ Color conversion, generation, manipulation, comparison, and analysis.
8
8
 
9
9
  - 🏖 **Easy to use**: Works with Hex, HSL, OkLab, OkLCH, and RGB.
10
10
  - ♿️ **Accessibility:** WCAG analysis and comparison.
11
- - 🛠 **Small:** Less than 7k (gzipped) and tree-shakable.
11
+ - 🛠 **Small:** 7kB (gzipped) and tree-shakable.
12
12
  - 🟦 **Modern:** Written in Typescript.
13
13
 
14
14
  ## Setup
@@ -544,6 +544,27 @@ import { formatHex } from 'colorizr';
544
544
  formatHex('#07e'); // '#0077ee'
545
545
  formatHex('#f058'); // '#ff005588'
546
546
  ```
547
+
548
+ **getOkLCHMaxChroma(input: string | LCH, precision?: number): number**
549
+ Get the maximum chroma for a given lightness and hue in the OkLCH color space.
550
+
551
+ ```typescript
552
+ import { getOkLCHMaxChroma } from 'colorizr';
553
+
554
+ getOkLCHMaxChroma({ l: 0.63269, c: 0.25404, h: 19.90218 }); // 0.28643
555
+ getOkLCHMaxChroma('#00ff44'); // 0.30921
556
+ ```
557
+
558
+ **getP3Color(input: string | LCH): string**
559
+ Get a OkLCH color in the P3 color space.
560
+
561
+ ```typescript
562
+ import { getP3Color } from 'colorizr';
563
+
564
+ getP3Color({ l: 0.63269, c: 0.25404, h: 19.90218 }); // oklch(0.63269 0.28643 19.90218)
565
+ getP3Color('#00ff44'); // oklch(0.86876 0.30921 144.65534)
566
+ ```
567
+
547
568
  **parseCSS(input: string, format?: ColorType): string | HSL | RGB**
548
569
  Parse a css string to hex, HSL, OKLAB, OKLCH, or RGB.
549
570
  If the format isn't set, it will return the same format as the input.
package/dist/index.d.mts CHANGED
@@ -18,7 +18,6 @@ type Alpha = number;
18
18
  type Amount = number;
19
19
  type Degrees = number;
20
20
  type HEX = `#${string}`;
21
- type CSS = `('#' | 'hsl' | 'oklab' | 'oklch' | 'rgb')${string}`;
22
21
  interface HSL {
23
22
  h: number;
24
23
  s: number;
@@ -265,6 +264,15 @@ declare function opacify(input: string, alpha: Alpha, format?: ColorType): strin
265
264
 
266
265
  declare function opacity(input: string): number;
267
266
 
267
+ /**
268
+ * Get the maximum chroma for a given lightness and hue in the OkLCH color space
269
+ */
270
+ declare function getOkLCHMaxChroma(input: string | LCH, precision?: number): number;
271
+ /**
272
+ * Get a OkLCH color in the P3 color space.
273
+ */
274
+ declare function getP3Color(input: string | LCH): string;
275
+
268
276
  type ParseCSSReturn<T extends ColorType> = T extends 'hex' ? HEX : T extends 'hsl' ? HSL : T extends 'oklab' ? LAB : T extends 'oklch' ? LCH : T extends 'rgb' ? RGB : never;
269
277
  /**
270
278
  * Parse CSS color
@@ -447,4 +455,4 @@ declare function isLCH(input: unknown): input is LCH;
447
455
  */
448
456
  declare function isRGB(input: unknown): input is RGB;
449
457
 
450
- export { type Alpha, type Amount, type Analysis, type CSS, type ColorKeysTuple, type ColorModel, type ColorModelKey, type ColorModelKeys, type ColorTuple, type ColorType, type Colors, type ConverterParameters, type Degrees, type HEX, type HSL, type LAB, type LCH, type PlainObject, type RGB, addAlphaToHex, brightnessDifference, chroma, colorDifference, compare, contrast, convert, convertAlphaToHex, darken, Colorizr as default, desaturate, extractAlphaFromHex, extractColorParts, formatCSS, formatHex, hex2hsl, hex2oklab, hex2oklch, hex2rgb, hexadecimalToNumber, hsl2hex, hsl2oklab, hsl2oklch, hsl2rgb, isHSL, isHex, isLAB, isLCH, isRGB, isValidColor, lighten, luminance, name, oklab2hex, oklab2hsl, oklab2oklch, oklab2rgb, oklch2hex, oklch2hsl, oklch2oklab, oklch2rgb, opacify, opacity, palette, parseCSS, random, removeAlphaFromHex, rgb2hex, rgb2hsl, rgb2oklab, rgb2oklch, rotate, saturate, scheme, swatch, textColor, transparentize };
458
+ export { type Alpha, type Amount, type Analysis, type ColorKeysTuple, type ColorModel, type ColorModelKey, type ColorModelKeys, type ColorTuple, type ColorType, type Colors, type ConverterParameters, type Degrees, type HEX, type HSL, type LAB, type LCH, type PlainObject, type RGB, addAlphaToHex, brightnessDifference, chroma, colorDifference, compare, contrast, convert, convertAlphaToHex, darken, Colorizr as default, desaturate, extractAlphaFromHex, extractColorParts, formatCSS, formatHex, getOkLCHMaxChroma, getP3Color, hex2hsl, hex2oklab, hex2oklch, hex2rgb, hexadecimalToNumber, hsl2hex, hsl2oklab, hsl2oklch, hsl2rgb, isHSL, isHex, isLAB, isLCH, isRGB, isValidColor, lighten, luminance, name, oklab2hex, oklab2hsl, oklab2oklch, oklab2rgb, oklch2hex, oklch2hsl, oklch2oklab, oklch2rgb, opacify, opacity, palette, parseCSS, random, removeAlphaFromHex, rgb2hex, rgb2hsl, rgb2oklab, rgb2oklch, rotate, saturate, scheme, swatch, textColor, transparentize };
package/dist/index.d.ts CHANGED
@@ -18,7 +18,6 @@ type Alpha = number;
18
18
  type Amount = number;
19
19
  type Degrees = number;
20
20
  type HEX = `#${string}`;
21
- type CSS = `('#' | 'hsl' | 'oklab' | 'oklch' | 'rgb')${string}`;
22
21
  interface HSL {
23
22
  h: number;
24
23
  s: number;
@@ -265,6 +264,15 @@ declare function opacify(input: string, alpha: Alpha, format?: ColorType): strin
265
264
 
266
265
  declare function opacity(input: string): number;
267
266
 
267
+ /**
268
+ * Get the maximum chroma for a given lightness and hue in the OkLCH color space
269
+ */
270
+ declare function getOkLCHMaxChroma(input: string | LCH, precision?: number): number;
271
+ /**
272
+ * Get a OkLCH color in the P3 color space.
273
+ */
274
+ declare function getP3Color(input: string | LCH): string;
275
+
268
276
  type ParseCSSReturn<T extends ColorType> = T extends 'hex' ? HEX : T extends 'hsl' ? HSL : T extends 'oklab' ? LAB : T extends 'oklch' ? LCH : T extends 'rgb' ? RGB : never;
269
277
  /**
270
278
  * Parse CSS color
@@ -447,4 +455,4 @@ declare function isLCH(input: unknown): input is LCH;
447
455
  */
448
456
  declare function isRGB(input: unknown): input is RGB;
449
457
 
450
- export { type Alpha, type Amount, type Analysis, type CSS, type ColorKeysTuple, type ColorModel, type ColorModelKey, type ColorModelKeys, type ColorTuple, type ColorType, type Colors, type ConverterParameters, type Degrees, type HEX, type HSL, type LAB, type LCH, type PlainObject, type RGB, addAlphaToHex, brightnessDifference, chroma, colorDifference, compare, contrast, convert, convertAlphaToHex, darken, Colorizr as default, desaturate, extractAlphaFromHex, extractColorParts, formatCSS, formatHex, hex2hsl, hex2oklab, hex2oklch, hex2rgb, hexadecimalToNumber, hsl2hex, hsl2oklab, hsl2oklch, hsl2rgb, isHSL, isHex, isLAB, isLCH, isRGB, isValidColor, lighten, luminance, name, oklab2hex, oklab2hsl, oklab2oklch, oklab2rgb, oklch2hex, oklch2hsl, oklch2oklab, oklch2rgb, opacify, opacity, palette, parseCSS, random, removeAlphaFromHex, rgb2hex, rgb2hsl, rgb2oklab, rgb2oklch, rotate, saturate, scheme, swatch, textColor, transparentize };
458
+ export { type Alpha, type Amount, type Analysis, type ColorKeysTuple, type ColorModel, type ColorModelKey, type ColorModelKeys, type ColorTuple, type ColorType, type Colors, type ConverterParameters, type Degrees, type HEX, type HSL, type LAB, type LCH, type PlainObject, type RGB, addAlphaToHex, brightnessDifference, chroma, colorDifference, compare, contrast, convert, convertAlphaToHex, darken, Colorizr as default, desaturate, extractAlphaFromHex, extractColorParts, formatCSS, formatHex, getOkLCHMaxChroma, getP3Color, hex2hsl, hex2oklab, hex2oklch, hex2rgb, hexadecimalToNumber, hsl2hex, hsl2oklab, hsl2oklch, hsl2rgb, isHSL, isHex, isLAB, isLCH, isRGB, isValidColor, lighten, luminance, name, oklab2hex, oklab2hsl, oklab2oklch, oklab2rgb, oklch2hex, oklch2hsl, oklch2oklab, oklch2rgb, opacify, opacity, palette, parseCSS, random, removeAlphaFromHex, rgb2hex, rgb2hsl, rgb2oklab, rgb2oklch, rotate, saturate, scheme, swatch, textColor, transparentize };
package/dist/index.js CHANGED
@@ -37,6 +37,8 @@ __export(src_exports, {
37
37
  extractColorParts: () => extractColorParts,
38
38
  formatCSS: () => formatCSS,
39
39
  formatHex: () => formatHex,
40
+ getOkLCHMaxChroma: () => getOkLCHMaxChroma,
41
+ getP3Color: () => getP3Color,
40
42
  hex2hsl: () => hex2hsl,
41
43
  hex2oklab: () => hex2oklab,
42
44
  hex2oklch: () => hex2oklch,
@@ -128,19 +130,26 @@ var LSM_TO_RGB = {
128
130
  g: [-1.2684379732850315, 2.609757349287688, -0.341319376002657],
129
131
  b: [-0.0041960761386756, -0.7034186179359362, 1.7076146940746117]
130
132
  };
133
+ var SRGB_TO_P3 = [
134
+ [0.8224270476, 0.1775729524, 0],
135
+ [0.0331008087, 0.9668991913, 0],
136
+ [0.0170720188, 0.0723477973, 0.9105801839]
137
+ ];
131
138
  var PRECISION = 5;
132
139
  var RAD2DEG = 180 / Math.PI;
133
140
  var MESSAGES = {
134
141
  alpha: "amount must be a number between 0 and 1",
135
- left: "left is required and must be a string",
136
- right: "right is required and must be a string",
142
+ hueRange: "hue must be a number between 0 and 360",
137
143
  input: "input is required",
138
144
  inputHex: "input is required and must be a hex",
139
145
  inputNumber: "input is required and must be a number",
140
146
  inputString: "input is required and must be a string",
141
147
  invalid: "invalid input",
142
148
  invalidCSS: "invalid CSS string",
149
+ left: "left is required and must be a string",
150
+ lightnessRange: "lightness must be a number between 0 and 1",
143
151
  options: "invalid options",
152
+ right: "right is required and must be a string",
144
153
  threshold: "threshold must be a number between 0 and 255"
145
154
  };
146
155
 
@@ -1458,6 +1467,56 @@ function palette(input, options = {}) {
1458
1467
  return output.map((color) => convert(color, format ?? colorFormat));
1459
1468
  }
1460
1469
 
1470
+ // src/p3.ts
1471
+ function multiplyMatrix(matrix, vector) {
1472
+ return [
1473
+ matrix[0][0] * vector[0] + matrix[0][1] * vector[1] + matrix[0][2] * vector[2],
1474
+ matrix[1][0] * vector[0] + matrix[1][1] * vector[1] + matrix[1][2] * vector[2],
1475
+ matrix[2][0] * vector[0] + matrix[2][1] * vector[1] + matrix[2][2] * vector[2]
1476
+ ];
1477
+ }
1478
+ function isInP3Gamut(color) {
1479
+ const epsilon = 1e-6;
1480
+ return color.every((component) => component >= 0 - epsilon && component <= 1 + epsilon);
1481
+ }
1482
+ function oklabToLinearSRGB(L, a, b) {
1483
+ const l = (L + LAB_TO_LMS.l[0] * a + LAB_TO_LMS.l[1] * b) ** 3;
1484
+ const m = (L + LAB_TO_LMS.m[0] * a + LAB_TO_LMS.m[1] * b) ** 3;
1485
+ const s = (L + LAB_TO_LMS.s[0] * a + LAB_TO_LMS.s[1] * b) ** 3;
1486
+ return [
1487
+ LSM_TO_RGB.r[0] * l + LSM_TO_RGB.r[1] * m + LSM_TO_RGB.r[2] * s,
1488
+ LSM_TO_RGB.g[0] * l + LSM_TO_RGB.g[1] * m + LSM_TO_RGB.g[2] * s,
1489
+ LSM_TO_RGB.b[0] * l + LSM_TO_RGB.b[1] * m + LSM_TO_RGB.b[2] * s
1490
+ ];
1491
+ }
1492
+ function oklabToLinearP3(L, a, b) {
1493
+ const srgb = oklabToLinearSRGB(L, a, b);
1494
+ return multiplyMatrix(SRGB_TO_P3, srgb);
1495
+ }
1496
+ function getOkLCHMaxChroma(input, precision = PRECISION) {
1497
+ const { l, h } = isString(input) ? parseCSS(input, "oklch") : input;
1498
+ invariant(isNumber(l) && l >= 0 && l <= 1, MESSAGES.lightnessRange);
1499
+ invariant(isNumber(h) && h >= 0 && h <= 360, MESSAGES.hueRange);
1500
+ const epsilon = 1e-6;
1501
+ let low = 0;
1502
+ let high = 0.5;
1503
+ while (high - low > epsilon) {
1504
+ const mid = (low + high) / 2;
1505
+ const { l: L, a, b } = oklch2oklab({ l, c: mid, h }, 16);
1506
+ const p3Color = oklabToLinearP3(L, a, b);
1507
+ if (isInP3Gamut(p3Color)) {
1508
+ low = mid;
1509
+ } else {
1510
+ high = mid;
1511
+ }
1512
+ }
1513
+ return round(low, precision);
1514
+ }
1515
+ function getP3Color(input) {
1516
+ const lch = isString(input) ? parseCSS(input, "oklch") : input;
1517
+ return `oklch(${lch.l} ${getOkLCHMaxChroma(lch)} ${lch.h})`;
1518
+ }
1519
+
1461
1520
  // src/random.ts
1462
1521
  function random(type = "hex") {
1463
1522
  const hsl = {
@@ -1519,7 +1578,7 @@ function shadeColorDynamic(input, lightnessTuningFactor, chromaTuningFactor = 0)
1519
1578
  }
1520
1579
  function shadeColor(input, lightness, chromaTuningFactor = 0) {
1521
1580
  const { c, h } = input;
1522
- return oklch2hex({ l: lightness / 100, c: c + chromaTuningFactor, h });
1581
+ return oklch2hex({ l: lightness / 100, c: clamp(c + chromaTuningFactor, 0, 0.4), h });
1523
1582
  }
1524
1583
  function swatch(input, options = {}) {
1525
1584
  invariant(isString(input), MESSAGES.inputString);
@@ -1581,6 +1640,8 @@ var src_default = Colorizr;
1581
1640
  extractColorParts,
1582
1641
  formatCSS,
1583
1642
  formatHex,
1643
+ getOkLCHMaxChroma,
1644
+ getP3Color,
1584
1645
  hex2hsl,
1585
1646
  hex2oklab,
1586
1647
  hex2oklch,