@zag-js/color-utils 0.23.0 → 0.24.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/index.d.mts CHANGED
@@ -1,10 +1,12 @@
1
1
  type ColorFormat = "hex" | "hexa" | "rgb" | "rgba" | "hsl" | "hsla" | "hsb" | "hsba";
2
2
  type ColorChannel = "hue" | "saturation" | "brightness" | "lightness" | "red" | "green" | "blue" | "alpha";
3
- type ColorAxes = {
3
+ interface Color2DAxes {
4
4
  xChannel: ColorChannel;
5
5
  yChannel: ColorChannel;
6
+ }
7
+ interface ColorAxes extends Color2DAxes {
6
8
  zChannel: ColorChannel;
7
- };
9
+ }
8
10
  interface ColorChannelRange {
9
11
  /** The minimum value of the color channel. */
10
12
  minValue: number;
@@ -18,6 +20,8 @@ interface ColorChannelRange {
18
20
  interface ColorType {
19
21
  /** Converts the color to the given color format, and returns a new Color object. */
20
22
  toFormat(format: ColorFormat): ColorType;
23
+ /** Converts the color to a JSON object. */
24
+ toJSON(): Record<string, number>;
21
25
  /** Converts the color to a string in the given format. */
22
26
  toString(format: ColorFormat | "css"): string;
23
27
  /** Converts the color to hex, and returns an integer representation. */
@@ -39,18 +43,15 @@ interface ColorType {
39
43
  /**
40
44
  * Returns the color space, 'rgb', 'hsb' or 'hsl', for the current color.
41
45
  */
42
- getColorFormat(): ColorFormat;
46
+ getFormat(): ColorFormat;
43
47
  /**
44
48
  * Returns the color space axes, xChannel, yChannel, zChannel.
45
49
  */
46
- getColorSpaceAxes(xyChannels: {
47
- xChannel?: ColorChannel;
48
- yChannel?: ColorChannel;
49
- }): ColorAxes;
50
+ getColorAxes(xyChannels: Color2DAxes): ColorAxes;
50
51
  /**
51
52
  * Returns an array of the color channels within the current color space space.
52
53
  */
53
- getColorChannels(): [ColorChannel, ColorChannel, ColorChannel];
54
+ getChannels(): [ColorChannel, ColorChannel, ColorChannel];
54
55
  /**
55
56
  * Returns a new Color object with the same values as the current color.
56
57
  */
@@ -59,23 +60,40 @@ interface ColorType {
59
60
  * Whether the color is equal to another color.
60
61
  */
61
62
  isEqual(color: ColorType): boolean;
63
+ /**
64
+ * Increments the color channel by the given step size, and returns a new Color object.
65
+ */
66
+ incrementChannel(channel: ColorChannel, stepSize: number): ColorType;
67
+ /**
68
+ * Decrements the color channel by the given step size, and returns a new Color object.
69
+ */
70
+ decrementChannel(channel: ColorChannel, stepSize: number): ColorType;
71
+ /**
72
+ * Returns the color channel value as a percentage of the channel range.
73
+ */
74
+ getChannelValuePercent(channel: ColorChannel, value?: number): number;
75
+ /**
76
+ * Returns the color channel value for a given percentage of the channel range.
77
+ */
78
+ getChannelPercentValue(channel: ColorChannel, percent: number): number;
62
79
  }
63
80
 
64
81
  declare abstract class Color implements ColorType {
65
82
  abstract toFormat(format: ColorFormat): ColorType;
83
+ abstract toJSON(): Record<string, number>;
66
84
  abstract toString(format: ColorFormat | "css"): string;
67
85
  abstract clone(): ColorType;
68
86
  abstract getChannelRange(channel: ColorChannel): ColorChannelRange;
69
- abstract getColorFormat(): ColorFormat;
70
- abstract getColorChannels(): [ColorChannel, ColorChannel, ColorChannel];
71
- hasColorChannel(channel: ColorChannel): boolean;
87
+ abstract getFormat(): ColorFormat;
88
+ abstract getChannels(): [ColorChannel, ColorChannel, ColorChannel];
72
89
  toHexInt(): number;
73
90
  getChannelValue(channel: ColorChannel): number;
91
+ getChannelValuePercent(channel: ColorChannel, valueToCheck?: number): number;
92
+ getChannelPercentValue(channel: ColorChannel, percentToCheck: number): number;
74
93
  withChannelValue(channel: ColorChannel, value: number): ColorType;
75
- getColorSpaceAxes(xyChannels: {
76
- xChannel?: ColorChannel;
77
- yChannel?: ColorChannel;
78
- }): ColorAxes;
94
+ getColorAxes(xyChannels: Color2DAxes): ColorAxes;
95
+ incrementChannel(channel: ColorChannel, stepSize: number): ColorType;
96
+ decrementChannel(channel: ColorChannel, stepSize: number): ColorType;
79
97
  isEqual(color: ColorType): boolean;
80
98
  }
81
99
 
package/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  type ColorFormat = "hex" | "hexa" | "rgb" | "rgba" | "hsl" | "hsla" | "hsb" | "hsba";
2
2
  type ColorChannel = "hue" | "saturation" | "brightness" | "lightness" | "red" | "green" | "blue" | "alpha";
3
- type ColorAxes = {
3
+ interface Color2DAxes {
4
4
  xChannel: ColorChannel;
5
5
  yChannel: ColorChannel;
6
+ }
7
+ interface ColorAxes extends Color2DAxes {
6
8
  zChannel: ColorChannel;
7
- };
9
+ }
8
10
  interface ColorChannelRange {
9
11
  /** The minimum value of the color channel. */
10
12
  minValue: number;
@@ -18,6 +20,8 @@ interface ColorChannelRange {
18
20
  interface ColorType {
19
21
  /** Converts the color to the given color format, and returns a new Color object. */
20
22
  toFormat(format: ColorFormat): ColorType;
23
+ /** Converts the color to a JSON object. */
24
+ toJSON(): Record<string, number>;
21
25
  /** Converts the color to a string in the given format. */
22
26
  toString(format: ColorFormat | "css"): string;
23
27
  /** Converts the color to hex, and returns an integer representation. */
@@ -39,18 +43,15 @@ interface ColorType {
39
43
  /**
40
44
  * Returns the color space, 'rgb', 'hsb' or 'hsl', for the current color.
41
45
  */
42
- getColorFormat(): ColorFormat;
46
+ getFormat(): ColorFormat;
43
47
  /**
44
48
  * Returns the color space axes, xChannel, yChannel, zChannel.
45
49
  */
46
- getColorSpaceAxes(xyChannels: {
47
- xChannel?: ColorChannel;
48
- yChannel?: ColorChannel;
49
- }): ColorAxes;
50
+ getColorAxes(xyChannels: Color2DAxes): ColorAxes;
50
51
  /**
51
52
  * Returns an array of the color channels within the current color space space.
52
53
  */
53
- getColorChannels(): [ColorChannel, ColorChannel, ColorChannel];
54
+ getChannels(): [ColorChannel, ColorChannel, ColorChannel];
54
55
  /**
55
56
  * Returns a new Color object with the same values as the current color.
56
57
  */
@@ -59,23 +60,40 @@ interface ColorType {
59
60
  * Whether the color is equal to another color.
60
61
  */
61
62
  isEqual(color: ColorType): boolean;
63
+ /**
64
+ * Increments the color channel by the given step size, and returns a new Color object.
65
+ */
66
+ incrementChannel(channel: ColorChannel, stepSize: number): ColorType;
67
+ /**
68
+ * Decrements the color channel by the given step size, and returns a new Color object.
69
+ */
70
+ decrementChannel(channel: ColorChannel, stepSize: number): ColorType;
71
+ /**
72
+ * Returns the color channel value as a percentage of the channel range.
73
+ */
74
+ getChannelValuePercent(channel: ColorChannel, value?: number): number;
75
+ /**
76
+ * Returns the color channel value for a given percentage of the channel range.
77
+ */
78
+ getChannelPercentValue(channel: ColorChannel, percent: number): number;
62
79
  }
63
80
 
64
81
  declare abstract class Color implements ColorType {
65
82
  abstract toFormat(format: ColorFormat): ColorType;
83
+ abstract toJSON(): Record<string, number>;
66
84
  abstract toString(format: ColorFormat | "css"): string;
67
85
  abstract clone(): ColorType;
68
86
  abstract getChannelRange(channel: ColorChannel): ColorChannelRange;
69
- abstract getColorFormat(): ColorFormat;
70
- abstract getColorChannels(): [ColorChannel, ColorChannel, ColorChannel];
71
- hasColorChannel(channel: ColorChannel): boolean;
87
+ abstract getFormat(): ColorFormat;
88
+ abstract getChannels(): [ColorChannel, ColorChannel, ColorChannel];
72
89
  toHexInt(): number;
73
90
  getChannelValue(channel: ColorChannel): number;
91
+ getChannelValuePercent(channel: ColorChannel, valueToCheck?: number): number;
92
+ getChannelPercentValue(channel: ColorChannel, percentToCheck: number): number;
74
93
  withChannelValue(channel: ColorChannel, value: number): ColorType;
75
- getColorSpaceAxes(xyChannels: {
76
- xChannel?: ColorChannel;
77
- yChannel?: ColorChannel;
78
- }): ColorAxes;
94
+ getColorAxes(xyChannels: Color2DAxes): ColorAxes;
95
+ incrementChannel(channel: ColorChannel, stepSize: number): ColorType;
96
+ decrementChannel(channel: ColorChannel, stepSize: number): ColorType;
79
97
  isEqual(color: ColorType): boolean;
80
98
  }
81
99
 
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
16
16
  }
17
17
  return to;
18
18
  };
19
- var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
19
+ var __toCommonJS = (mod3) => __copyProps(__defProp({}, "__esModule", { value: true }), mod3);
20
20
  var __publicField = (obj, key, value) => {
21
21
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
22
  return value;
@@ -156,14 +156,14 @@ var generateHSB_B = (orientation, dir, alphaValue) => {
156
156
  // src/area-gradient.ts
157
157
  function getColorAreaGradient(color, options) {
158
158
  const { xChannel, yChannel, dir: dirProp } = options;
159
- const { zChannel } = color.getColorSpaceAxes({ xChannel, yChannel });
159
+ const { zChannel } = color.getColorAxes({ xChannel, yChannel });
160
160
  const zValue = color.getChannelValue(zChannel);
161
161
  const { minValue: zMin, maxValue: zMax } = color.getChannelRange(zChannel);
162
162
  const orientation = ["top", dirProp === "rtl" ? "left" : "right"];
163
163
  let dir = false;
164
164
  let background = { areaStyles: {}, areaGradientStyles: {} };
165
165
  let alphaValue = (zValue - zMin) / (zMax - zMin);
166
- let isHSL = color.getColorFormat() === "hsl";
166
+ let isHSL = color.getFormat() === "hsl";
167
167
  switch (zChannel) {
168
168
  case "red": {
169
169
  dir = xChannel === "green";
@@ -213,19 +213,34 @@ function getColorAreaGradient(color, options) {
213
213
  }
214
214
 
215
215
  // src/color.ts
216
+ var import_numeric_range = require("@zag-js/numeric-range");
217
+ var isEqualObject = (a, b) => {
218
+ if (Object.keys(a).length !== Object.keys(b).length)
219
+ return false;
220
+ for (let key in a)
221
+ if (a[key] !== b[key])
222
+ return false;
223
+ return true;
224
+ };
216
225
  var Color = class {
217
- hasColorChannel(channel) {
218
- return this.getColorChannels().includes(channel);
219
- }
220
226
  toHexInt() {
221
227
  return this.toFormat("rgb").toHexInt();
222
228
  }
223
229
  getChannelValue(channel) {
224
- if (channel in this) {
230
+ if (channel in this)
225
231
  return this[channel];
226
- }
227
232
  throw new Error("Unsupported color channel: " + channel);
228
233
  }
234
+ getChannelValuePercent(channel, valueToCheck) {
235
+ const value = valueToCheck ?? this.getChannelValue(channel);
236
+ const { minValue, maxValue } = this.getChannelRange(channel);
237
+ return (0, import_numeric_range.getValuePercent)(value, minValue, maxValue);
238
+ }
239
+ getChannelPercentValue(channel, percentToCheck) {
240
+ const { minValue, maxValue, step } = this.getChannelRange(channel);
241
+ const percentValue = (0, import_numeric_range.getPercentValue)(percentToCheck, minValue, maxValue, step);
242
+ return (0, import_numeric_range.snapValueToStep)(percentValue, minValue, maxValue, step);
243
+ }
229
244
  withChannelValue(channel, value) {
230
245
  if (channel in this) {
231
246
  let clone = this.clone();
@@ -234,30 +249,40 @@ var Color = class {
234
249
  }
235
250
  throw new Error("Unsupported color channel: " + channel);
236
251
  }
237
- getColorSpaceAxes(xyChannels) {
252
+ getColorAxes(xyChannels) {
238
253
  let { xChannel, yChannel } = xyChannels;
239
- let xCh = xChannel || this.getColorChannels().find((c) => c !== yChannel);
240
- let yCh = yChannel || this.getColorChannels().find((c) => c !== xCh);
241
- let zCh = this.getColorChannels().find((c) => c !== xCh && c !== yCh);
254
+ let xCh = xChannel || this.getChannels().find((c) => c !== yChannel);
255
+ let yCh = yChannel || this.getChannels().find((c) => c !== xCh);
256
+ let zCh = this.getChannels().find((c) => c !== xCh && c !== yCh);
242
257
  return { xChannel: xCh, yChannel: yCh, zChannel: zCh };
243
258
  }
259
+ incrementChannel(channel, stepSize) {
260
+ const { minValue, maxValue, step } = this.getChannelRange(channel);
261
+ const value = (0, import_numeric_range.snapValueToStep)(
262
+ (0, import_numeric_range.clampValue)(this.getChannelValue(channel) + stepSize, minValue, maxValue),
263
+ minValue,
264
+ maxValue,
265
+ step
266
+ );
267
+ return this.withChannelValue(channel, value);
268
+ }
269
+ decrementChannel(channel, stepSize) {
270
+ return this.incrementChannel(channel, -stepSize);
271
+ }
244
272
  isEqual(color) {
245
- return this.toHexInt() === color.toHexInt() && this.getChannelValue("alpha") === color.getChannelValue("alpha");
273
+ const isSame = isEqualObject(this.toJSON(), color.toJSON());
274
+ return isSame && this.getChannelValue("alpha") === color.getChannelValue("alpha");
246
275
  }
247
276
  };
248
277
 
249
- // src/utils.ts
250
- function mod(n, m) {
251
- return (n % m + m) % m;
252
- }
253
- function toFixedNumber(num, digits) {
254
- return Math.round(Math.pow(10, digits) * num) / Math.pow(10, digits);
255
- }
256
- function clampValue(value, min, max) {
257
- return Math.min(Math.max(value, min), max);
258
- }
278
+ // src/hsb-color.ts
279
+ var import_numeric_range4 = require("@zag-js/numeric-range");
280
+
281
+ // src/hsl-color.ts
282
+ var import_numeric_range3 = require("@zag-js/numeric-range");
259
283
 
260
284
  // src/rgb-color.ts
285
+ var import_numeric_range2 = require("@zag-js/numeric-range");
261
286
  var _RGBColor = class _RGBColor extends Color {
262
287
  constructor(red, green, blue, alpha) {
263
288
  super();
@@ -277,7 +302,7 @@ var _RGBColor = class _RGBColor extends Color {
277
302
  }
278
303
  const match = value.match(/^rgba?\((.*)\)$/);
279
304
  if (match?.[1]) {
280
- colors = match[1].split(",").map((value2) => Number(value2.trim())).map((num, i) => clampValue(num, 0, i < 3 ? 255 : 1));
305
+ colors = match[1].split(",").map((value2) => Number(value2.trim())).map((num, i) => (0, import_numeric_range2.clampValue)(num, 0, i < 3 ? 255 : 1));
281
306
  }
282
307
  return colors.length < 3 ? void 0 : new _RGBColor(colors[0], colors[1], colors[2], colors[3] ?? 1);
283
308
  }
@@ -345,10 +370,10 @@ var _RGBColor = class _RGBColor extends Color {
345
370
  hue /= 6;
346
371
  }
347
372
  return new HSBColor(
348
- toFixedNumber(hue * 360, 2),
349
- toFixedNumber(saturation * 100, 2),
350
- toFixedNumber(brightness * 100, 2),
351
- this.alpha
373
+ (0, import_numeric_range2.toFixedNumber)(hue * 360, 2),
374
+ (0, import_numeric_range2.toFixedNumber)(saturation * 100, 2),
375
+ (0, import_numeric_range2.toFixedNumber)(brightness * 100, 2),
376
+ (0, import_numeric_range2.toFixedNumber)(this.alpha, 2)
352
377
  );
353
378
  }
354
379
  /**
@@ -384,10 +409,10 @@ var _RGBColor = class _RGBColor extends Color {
384
409
  hue /= 6;
385
410
  }
386
411
  return new HSLColor(
387
- toFixedNumber(hue * 360, 2),
388
- toFixedNumber(saturation * 100, 2),
389
- toFixedNumber(lightness * 100, 2),
390
- this.alpha
412
+ (0, import_numeric_range2.toFixedNumber)(hue * 360, 2),
413
+ (0, import_numeric_range2.toFixedNumber)(saturation * 100, 2),
414
+ (0, import_numeric_range2.toFixedNumber)(lightness * 100, 2),
415
+ (0, import_numeric_range2.toFixedNumber)(this.alpha, 2)
391
416
  );
392
417
  }
393
418
  clone() {
@@ -405,10 +430,13 @@ var _RGBColor = class _RGBColor extends Color {
405
430
  throw new Error("Unknown color channel: " + channel);
406
431
  }
407
432
  }
408
- getColorFormat() {
433
+ toJSON() {
434
+ return { r: this.red, g: this.green, b: this.blue };
435
+ }
436
+ getFormat() {
409
437
  return "rgb";
410
438
  }
411
- getColorChannels() {
439
+ getChannels() {
412
440
  return _RGBColor.colorChannels;
413
441
  }
414
442
  };
@@ -429,7 +457,7 @@ var _HSLColor = class _HSLColor extends Color {
429
457
  let m;
430
458
  if (m = value.match(HSL_REGEX)) {
431
459
  const [h, s, l, a] = (m[1] ?? m[2]).split(",").map((n) => Number(n.trim().replace("%", "")));
432
- return new _HSLColor(mod(h, 360), clampValue(s, 0, 100), clampValue(l, 0, 100), clampValue(a ?? 1, 0, 1));
460
+ return new _HSLColor((0, import_numeric_range3.mod)(h, 360), (0, import_numeric_range3.clampValue)(s, 0, 100), (0, import_numeric_range3.clampValue)(l, 0, 100), (0, import_numeric_range3.clampValue)(a ?? 1, 0, 1));
433
461
  }
434
462
  }
435
463
  toString(format) {
@@ -439,10 +467,10 @@ var _HSLColor = class _HSLColor extends Color {
439
467
  case "hexa":
440
468
  return this.toRGB().toString("hexa");
441
469
  case "hsl":
442
- return `hsl(${this.hue}, ${toFixedNumber(this.saturation, 2)}%, ${toFixedNumber(this.lightness, 2)}%)`;
470
+ return `hsl(${this.hue}, ${(0, import_numeric_range3.toFixedNumber)(this.saturation, 2)}%, ${(0, import_numeric_range3.toFixedNumber)(this.lightness, 2)}%)`;
443
471
  case "css":
444
472
  case "hsla":
445
- return `hsla(${this.hue}, ${toFixedNumber(this.saturation, 2)}%, ${toFixedNumber(this.lightness, 2)}%, ${this.alpha})`;
473
+ return `hsla(${this.hue}, ${(0, import_numeric_range3.toFixedNumber)(this.saturation, 2)}%, ${(0, import_numeric_range3.toFixedNumber)(this.lightness, 2)}%, ${this.alpha})`;
446
474
  default:
447
475
  return this.toFormat(format).toString(format);
448
476
  }
@@ -473,10 +501,10 @@ var _HSLColor = class _HSLColor extends Color {
473
501
  let brightness = lightness + saturation * Math.min(lightness, 1 - lightness);
474
502
  saturation = brightness === 0 ? 0 : 2 * (1 - lightness / brightness);
475
503
  return new HSBColor(
476
- toFixedNumber(this.hue, 2),
477
- toFixedNumber(saturation * 100, 2),
478
- toFixedNumber(brightness * 100, 2),
479
- this.alpha
504
+ (0, import_numeric_range3.toFixedNumber)(this.hue, 2),
505
+ (0, import_numeric_range3.toFixedNumber)(saturation * 100, 2),
506
+ (0, import_numeric_range3.toFixedNumber)(brightness * 100, 2),
507
+ (0, import_numeric_range3.toFixedNumber)(this.alpha, 2)
480
508
  );
481
509
  }
482
510
  /**
@@ -490,7 +518,12 @@ var _HSLColor = class _HSLColor extends Color {
490
518
  let lightness = this.lightness / 100;
491
519
  let a = saturation * Math.min(lightness, 1 - lightness);
492
520
  let fn = (n, k = (n + hue / 30) % 12) => lightness - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
493
- return new RGBColor(Math.round(fn(0) * 255), Math.round(fn(8) * 255), Math.round(fn(4) * 255), this.alpha);
521
+ return new RGBColor(
522
+ Math.round(fn(0) * 255),
523
+ Math.round(fn(8) * 255),
524
+ Math.round(fn(4) * 255),
525
+ (0, import_numeric_range3.toFixedNumber)(this.alpha, 2)
526
+ );
494
527
  }
495
528
  clone() {
496
529
  return new _HSLColor(this.hue, this.saturation, this.lightness, this.alpha);
@@ -508,10 +541,13 @@ var _HSLColor = class _HSLColor extends Color {
508
541
  throw new Error("Unknown color channel: " + channel);
509
542
  }
510
543
  }
511
- getColorFormat() {
544
+ toJSON() {
545
+ return { h: this.hue, s: this.saturation, l: this.lightness };
546
+ }
547
+ getFormat() {
512
548
  return "hsl";
513
549
  }
514
- getColorChannels() {
550
+ getChannels() {
515
551
  return _HSLColor.colorChannels;
516
552
  }
517
553
  };
@@ -532,7 +568,7 @@ var _HSBColor = class _HSBColor extends Color {
532
568
  let m;
533
569
  if (m = value.match(HSB_REGEX)) {
534
570
  const [h, s, b, a] = (m[1] ?? m[2]).split(",").map((n) => Number(n.trim().replace("%", "")));
535
- return new _HSBColor(mod(h, 360), clampValue(s, 0, 100), clampValue(b, 0, 100), clampValue(a ?? 1, 0, 1));
571
+ return new _HSBColor((0, import_numeric_range4.mod)(h, 360), (0, import_numeric_range4.clampValue)(s, 0, 100), (0, import_numeric_range4.clampValue)(b, 0, 100), (0, import_numeric_range4.clampValue)(a ?? 1, 0, 1));
536
572
  }
537
573
  }
538
574
  toString(format) {
@@ -544,9 +580,9 @@ var _HSBColor = class _HSBColor extends Color {
544
580
  case "hexa":
545
581
  return this.toRGB().toString("hexa");
546
582
  case "hsb":
547
- return `hsb(${this.hue}, ${toFixedNumber(this.saturation, 2)}%, ${toFixedNumber(this.brightness, 2)}%)`;
583
+ return `hsb(${this.hue}, ${(0, import_numeric_range4.toFixedNumber)(this.saturation, 2)}%, ${(0, import_numeric_range4.toFixedNumber)(this.brightness, 2)}%)`;
548
584
  case "hsba":
549
- return `hsba(${this.hue}, ${toFixedNumber(this.saturation, 2)}%, ${toFixedNumber(this.brightness, 2)}%, ${this.alpha})`;
585
+ return `hsba(${this.hue}, ${(0, import_numeric_range4.toFixedNumber)(this.saturation, 2)}%, ${(0, import_numeric_range4.toFixedNumber)(this.brightness, 2)}%, ${this.alpha})`;
550
586
  default:
551
587
  return this.toFormat(format).toString(format);
552
588
  }
@@ -577,10 +613,10 @@ var _HSBColor = class _HSBColor extends Color {
577
613
  let lightness = brightness * (1 - saturation / 2);
578
614
  saturation = lightness === 0 || lightness === 1 ? 0 : (brightness - lightness) / Math.min(lightness, 1 - lightness);
579
615
  return new HSLColor(
580
- toFixedNumber(this.hue, 2),
581
- toFixedNumber(saturation * 100, 2),
582
- toFixedNumber(lightness * 100, 2),
583
- this.alpha
616
+ (0, import_numeric_range4.toFixedNumber)(this.hue, 2),
617
+ (0, import_numeric_range4.toFixedNumber)(saturation * 100, 2),
618
+ (0, import_numeric_range4.toFixedNumber)(lightness * 100, 2),
619
+ (0, import_numeric_range4.toFixedNumber)(this.alpha, 2)
584
620
  );
585
621
  }
586
622
  /**
@@ -593,7 +629,12 @@ var _HSBColor = class _HSBColor extends Color {
593
629
  let saturation = this.saturation / 100;
594
630
  let brightness = this.brightness / 100;
595
631
  let fn = (n, k = (n + hue / 60) % 6) => brightness - saturation * brightness * Math.max(Math.min(k, 4 - k, 1), 0);
596
- return new RGBColor(Math.round(fn(5) * 255), Math.round(fn(3) * 255), Math.round(fn(1) * 255), this.alpha);
632
+ return new RGBColor(
633
+ Math.round(fn(5) * 255),
634
+ Math.round(fn(3) * 255),
635
+ Math.round(fn(1) * 255),
636
+ (0, import_numeric_range4.toFixedNumber)(this.alpha, 2)
637
+ );
597
638
  }
598
639
  clone() {
599
640
  return new _HSBColor(this.hue, this.saturation, this.brightness, this.alpha);
@@ -611,10 +652,13 @@ var _HSBColor = class _HSBColor extends Color {
611
652
  throw new Error("Unknown color channel: " + channel);
612
653
  }
613
654
  }
614
- getColorFormat() {
655
+ toJSON() {
656
+ return { h: this.hue, s: this.saturation, b: this.brightness };
657
+ }
658
+ getFormat() {
615
659
  return "hsb";
616
660
  }
617
- getColorChannels() {
661
+ getChannels() {
618
662
  return _HSBColor.colorChannels;
619
663
  }
620
664
  };