@zag-js/color-utils 0.23.0 → 0.25.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,10 +20,14 @@ 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. */
24
28
  toHexInt(): number;
29
+ /** The output format of the color. */
30
+ outputFormat: ColorFormat | undefined;
25
31
  /**
26
32
  * Returns the numeric value for a given channel.
27
33
  * Throws an error if the channel is unsupported in the current color format.
@@ -39,18 +45,15 @@ interface ColorType {
39
45
  /**
40
46
  * Returns the color space, 'rgb', 'hsb' or 'hsl', for the current color.
41
47
  */
42
- getColorFormat(): ColorFormat;
48
+ getFormat(): ColorFormat;
43
49
  /**
44
50
  * Returns the color space axes, xChannel, yChannel, zChannel.
45
51
  */
46
- getColorSpaceAxes(xyChannels: {
47
- xChannel?: ColorChannel;
48
- yChannel?: ColorChannel;
49
- }): ColorAxes;
52
+ getColorAxes(xyChannels: Color2DAxes): ColorAxes;
50
53
  /**
51
54
  * Returns an array of the color channels within the current color space space.
52
55
  */
53
- getColorChannels(): [ColorChannel, ColorChannel, ColorChannel];
56
+ getChannels(): [ColorChannel, ColorChannel, ColorChannel];
54
57
  /**
55
58
  * Returns a new Color object with the same values as the current color.
56
59
  */
@@ -59,23 +62,41 @@ interface ColorType {
59
62
  * Whether the color is equal to another color.
60
63
  */
61
64
  isEqual(color: ColorType): boolean;
65
+ /**
66
+ * Increments the color channel by the given step size, and returns a new Color object.
67
+ */
68
+ incrementChannel(channel: ColorChannel, stepSize: number): ColorType;
69
+ /**
70
+ * Decrements the color channel by the given step size, and returns a new Color object.
71
+ */
72
+ decrementChannel(channel: ColorChannel, stepSize: number): ColorType;
73
+ /**
74
+ * Returns the color channel value as a percentage of the channel range.
75
+ */
76
+ getChannelValuePercent(channel: ColorChannel, value?: number): number;
77
+ /**
78
+ * Returns the color channel value for a given percentage of the channel range.
79
+ */
80
+ getChannelPercentValue(channel: ColorChannel, percent: number): number;
62
81
  }
63
82
 
64
83
  declare abstract class Color implements ColorType {
65
84
  abstract toFormat(format: ColorFormat): ColorType;
85
+ abstract toJSON(): Record<string, number>;
66
86
  abstract toString(format: ColorFormat | "css"): string;
67
87
  abstract clone(): ColorType;
68
88
  abstract getChannelRange(channel: ColorChannel): ColorChannelRange;
69
- abstract getColorFormat(): ColorFormat;
70
- abstract getColorChannels(): [ColorChannel, ColorChannel, ColorChannel];
71
- hasColorChannel(channel: ColorChannel): boolean;
89
+ abstract getFormat(): ColorFormat;
90
+ abstract getChannels(): [ColorChannel, ColorChannel, ColorChannel];
91
+ outputFormat: ColorFormat | undefined;
72
92
  toHexInt(): number;
73
93
  getChannelValue(channel: ColorChannel): number;
94
+ getChannelValuePercent(channel: ColorChannel, valueToCheck?: number): number;
95
+ getChannelPercentValue(channel: ColorChannel, percentToCheck: number): number;
74
96
  withChannelValue(channel: ColorChannel, value: number): ColorType;
75
- getColorSpaceAxes(xyChannels: {
76
- xChannel?: ColorChannel;
77
- yChannel?: ColorChannel;
78
- }): ColorAxes;
97
+ getColorAxes(xyChannels: Color2DAxes): ColorAxes;
98
+ incrementChannel(channel: ColorChannel, stepSize: number): ColorType;
99
+ decrementChannel(channel: ColorChannel, stepSize: number): ColorType;
79
100
  isEqual(color: ColorType): boolean;
80
101
  }
81
102
 
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,10 +20,14 @@ 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. */
24
28
  toHexInt(): number;
29
+ /** The output format of the color. */
30
+ outputFormat: ColorFormat | undefined;
25
31
  /**
26
32
  * Returns the numeric value for a given channel.
27
33
  * Throws an error if the channel is unsupported in the current color format.
@@ -39,18 +45,15 @@ interface ColorType {
39
45
  /**
40
46
  * Returns the color space, 'rgb', 'hsb' or 'hsl', for the current color.
41
47
  */
42
- getColorFormat(): ColorFormat;
48
+ getFormat(): ColorFormat;
43
49
  /**
44
50
  * Returns the color space axes, xChannel, yChannel, zChannel.
45
51
  */
46
- getColorSpaceAxes(xyChannels: {
47
- xChannel?: ColorChannel;
48
- yChannel?: ColorChannel;
49
- }): ColorAxes;
52
+ getColorAxes(xyChannels: Color2DAxes): ColorAxes;
50
53
  /**
51
54
  * Returns an array of the color channels within the current color space space.
52
55
  */
53
- getColorChannels(): [ColorChannel, ColorChannel, ColorChannel];
56
+ getChannels(): [ColorChannel, ColorChannel, ColorChannel];
54
57
  /**
55
58
  * Returns a new Color object with the same values as the current color.
56
59
  */
@@ -59,23 +62,41 @@ interface ColorType {
59
62
  * Whether the color is equal to another color.
60
63
  */
61
64
  isEqual(color: ColorType): boolean;
65
+ /**
66
+ * Increments the color channel by the given step size, and returns a new Color object.
67
+ */
68
+ incrementChannel(channel: ColorChannel, stepSize: number): ColorType;
69
+ /**
70
+ * Decrements the color channel by the given step size, and returns a new Color object.
71
+ */
72
+ decrementChannel(channel: ColorChannel, stepSize: number): ColorType;
73
+ /**
74
+ * Returns the color channel value as a percentage of the channel range.
75
+ */
76
+ getChannelValuePercent(channel: ColorChannel, value?: number): number;
77
+ /**
78
+ * Returns the color channel value for a given percentage of the channel range.
79
+ */
80
+ getChannelPercentValue(channel: ColorChannel, percent: number): number;
62
81
  }
63
82
 
64
83
  declare abstract class Color implements ColorType {
65
84
  abstract toFormat(format: ColorFormat): ColorType;
85
+ abstract toJSON(): Record<string, number>;
66
86
  abstract toString(format: ColorFormat | "css"): string;
67
87
  abstract clone(): ColorType;
68
88
  abstract getChannelRange(channel: ColorChannel): ColorChannelRange;
69
- abstract getColorFormat(): ColorFormat;
70
- abstract getColorChannels(): [ColorChannel, ColorChannel, ColorChannel];
71
- hasColorChannel(channel: ColorChannel): boolean;
89
+ abstract getFormat(): ColorFormat;
90
+ abstract getChannels(): [ColorChannel, ColorChannel, ColorChannel];
91
+ outputFormat: ColorFormat | undefined;
72
92
  toHexInt(): number;
73
93
  getChannelValue(channel: ColorChannel): number;
94
+ getChannelValuePercent(channel: ColorChannel, valueToCheck?: number): number;
95
+ getChannelPercentValue(channel: ColorChannel, percentToCheck: number): number;
74
96
  withChannelValue(channel: ColorChannel, value: number): ColorType;
75
- getColorSpaceAxes(xyChannels: {
76
- xChannel?: ColorChannel;
77
- yChannel?: ColorChannel;
78
- }): ColorAxes;
97
+ getColorAxes(xyChannels: Color2DAxes): ColorAxes;
98
+ incrementChannel(channel: ColorChannel, stepSize: number): ColorType;
99
+ decrementChannel(channel: ColorChannel, stepSize: number): ColorType;
79
100
  isEqual(color: ColorType): boolean;
80
101
  }
81
102
 
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,37 @@ 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);
226
+ constructor() {
227
+ __publicField(this, "outputFormat");
219
228
  }
220
229
  toHexInt() {
221
230
  return this.toFormat("rgb").toHexInt();
222
231
  }
223
232
  getChannelValue(channel) {
224
- if (channel in this) {
233
+ if (channel in this)
225
234
  return this[channel];
226
- }
227
235
  throw new Error("Unsupported color channel: " + channel);
228
236
  }
237
+ getChannelValuePercent(channel, valueToCheck) {
238
+ const value = valueToCheck ?? this.getChannelValue(channel);
239
+ const { minValue, maxValue } = this.getChannelRange(channel);
240
+ return (0, import_numeric_range.getValuePercent)(value, minValue, maxValue);
241
+ }
242
+ getChannelPercentValue(channel, percentToCheck) {
243
+ const { minValue, maxValue, step } = this.getChannelRange(channel);
244
+ const percentValue = (0, import_numeric_range.getPercentValue)(percentToCheck, minValue, maxValue, step);
245
+ return (0, import_numeric_range.snapValueToStep)(percentValue, minValue, maxValue, step);
246
+ }
229
247
  withChannelValue(channel, value) {
230
248
  if (channel in this) {
231
249
  let clone = this.clone();
@@ -234,30 +252,40 @@ var Color = class {
234
252
  }
235
253
  throw new Error("Unsupported color channel: " + channel);
236
254
  }
237
- getColorSpaceAxes(xyChannels) {
255
+ getColorAxes(xyChannels) {
238
256
  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);
257
+ let xCh = xChannel || this.getChannels().find((c) => c !== yChannel);
258
+ let yCh = yChannel || this.getChannels().find((c) => c !== xCh);
259
+ let zCh = this.getChannels().find((c) => c !== xCh && c !== yCh);
242
260
  return { xChannel: xCh, yChannel: yCh, zChannel: zCh };
243
261
  }
262
+ incrementChannel(channel, stepSize) {
263
+ const { minValue, maxValue, step } = this.getChannelRange(channel);
264
+ const value = (0, import_numeric_range.snapValueToStep)(
265
+ (0, import_numeric_range.clampValue)(this.getChannelValue(channel) + stepSize, minValue, maxValue),
266
+ minValue,
267
+ maxValue,
268
+ step
269
+ );
270
+ return this.withChannelValue(channel, value);
271
+ }
272
+ decrementChannel(channel, stepSize) {
273
+ return this.incrementChannel(channel, -stepSize);
274
+ }
244
275
  isEqual(color) {
245
- return this.toHexInt() === color.toHexInt() && this.getChannelValue("alpha") === color.getChannelValue("alpha");
276
+ const isSame = isEqualObject(this.toJSON(), color.toJSON());
277
+ return isSame && this.getChannelValue("alpha") === color.getChannelValue("alpha");
246
278
  }
247
279
  };
248
280
 
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
- }
281
+ // src/hsb-color.ts
282
+ var import_numeric_range4 = require("@zag-js/numeric-range");
283
+
284
+ // src/hsl-color.ts
285
+ var import_numeric_range3 = require("@zag-js/numeric-range");
259
286
 
260
287
  // src/rgb-color.ts
288
+ var import_numeric_range2 = require("@zag-js/numeric-range");
261
289
  var _RGBColor = class _RGBColor extends Color {
262
290
  constructor(red, green, blue, alpha) {
263
291
  super();
@@ -277,7 +305,7 @@ var _RGBColor = class _RGBColor extends Color {
277
305
  }
278
306
  const match = value.match(/^rgba?\((.*)\)$/);
279
307
  if (match?.[1]) {
280
- colors = match[1].split(",").map((value2) => Number(value2.trim())).map((num, i) => clampValue(num, 0, i < 3 ? 255 : 1));
308
+ colors = match[1].split(",").map((value2) => Number(value2.trim())).map((num, i) => (0, import_numeric_range2.clampValue)(num, 0, i < 3 ? 255 : 1));
281
309
  }
282
310
  return colors.length < 3 ? void 0 : new _RGBColor(colors[0], colors[1], colors[2], colors[3] ?? 1);
283
311
  }
@@ -345,10 +373,10 @@ var _RGBColor = class _RGBColor extends Color {
345
373
  hue /= 6;
346
374
  }
347
375
  return new HSBColor(
348
- toFixedNumber(hue * 360, 2),
349
- toFixedNumber(saturation * 100, 2),
350
- toFixedNumber(brightness * 100, 2),
351
- this.alpha
376
+ (0, import_numeric_range2.toFixedNumber)(hue * 360, 2),
377
+ (0, import_numeric_range2.toFixedNumber)(saturation * 100, 2),
378
+ (0, import_numeric_range2.toFixedNumber)(brightness * 100, 2),
379
+ (0, import_numeric_range2.toFixedNumber)(this.alpha, 2)
352
380
  );
353
381
  }
354
382
  /**
@@ -384,10 +412,10 @@ var _RGBColor = class _RGBColor extends Color {
384
412
  hue /= 6;
385
413
  }
386
414
  return new HSLColor(
387
- toFixedNumber(hue * 360, 2),
388
- toFixedNumber(saturation * 100, 2),
389
- toFixedNumber(lightness * 100, 2),
390
- this.alpha
415
+ (0, import_numeric_range2.toFixedNumber)(hue * 360, 2),
416
+ (0, import_numeric_range2.toFixedNumber)(saturation * 100, 2),
417
+ (0, import_numeric_range2.toFixedNumber)(lightness * 100, 2),
418
+ (0, import_numeric_range2.toFixedNumber)(this.alpha, 2)
391
419
  );
392
420
  }
393
421
  clone() {
@@ -405,10 +433,13 @@ var _RGBColor = class _RGBColor extends Color {
405
433
  throw new Error("Unknown color channel: " + channel);
406
434
  }
407
435
  }
408
- getColorFormat() {
436
+ toJSON() {
437
+ return { r: this.red, g: this.green, b: this.blue };
438
+ }
439
+ getFormat() {
409
440
  return "rgb";
410
441
  }
411
- getColorChannels() {
442
+ getChannels() {
412
443
  return _RGBColor.colorChannels;
413
444
  }
414
445
  };
@@ -429,7 +460,7 @@ var _HSLColor = class _HSLColor extends Color {
429
460
  let m;
430
461
  if (m = value.match(HSL_REGEX)) {
431
462
  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));
463
+ 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
464
  }
434
465
  }
435
466
  toString(format) {
@@ -439,10 +470,10 @@ var _HSLColor = class _HSLColor extends Color {
439
470
  case "hexa":
440
471
  return this.toRGB().toString("hexa");
441
472
  case "hsl":
442
- return `hsl(${this.hue}, ${toFixedNumber(this.saturation, 2)}%, ${toFixedNumber(this.lightness, 2)}%)`;
473
+ return `hsl(${this.hue}, ${(0, import_numeric_range3.toFixedNumber)(this.saturation, 2)}%, ${(0, import_numeric_range3.toFixedNumber)(this.lightness, 2)}%)`;
443
474
  case "css":
444
475
  case "hsla":
445
- return `hsla(${this.hue}, ${toFixedNumber(this.saturation, 2)}%, ${toFixedNumber(this.lightness, 2)}%, ${this.alpha})`;
476
+ return `hsla(${this.hue}, ${(0, import_numeric_range3.toFixedNumber)(this.saturation, 2)}%, ${(0, import_numeric_range3.toFixedNumber)(this.lightness, 2)}%, ${this.alpha})`;
446
477
  default:
447
478
  return this.toFormat(format).toString(format);
448
479
  }
@@ -473,10 +504,10 @@ var _HSLColor = class _HSLColor extends Color {
473
504
  let brightness = lightness + saturation * Math.min(lightness, 1 - lightness);
474
505
  saturation = brightness === 0 ? 0 : 2 * (1 - lightness / brightness);
475
506
  return new HSBColor(
476
- toFixedNumber(this.hue, 2),
477
- toFixedNumber(saturation * 100, 2),
478
- toFixedNumber(brightness * 100, 2),
479
- this.alpha
507
+ (0, import_numeric_range3.toFixedNumber)(this.hue, 2),
508
+ (0, import_numeric_range3.toFixedNumber)(saturation * 100, 2),
509
+ (0, import_numeric_range3.toFixedNumber)(brightness * 100, 2),
510
+ (0, import_numeric_range3.toFixedNumber)(this.alpha, 2)
480
511
  );
481
512
  }
482
513
  /**
@@ -490,7 +521,12 @@ var _HSLColor = class _HSLColor extends Color {
490
521
  let lightness = this.lightness / 100;
491
522
  let a = saturation * Math.min(lightness, 1 - lightness);
492
523
  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);
524
+ return new RGBColor(
525
+ Math.round(fn(0) * 255),
526
+ Math.round(fn(8) * 255),
527
+ Math.round(fn(4) * 255),
528
+ (0, import_numeric_range3.toFixedNumber)(this.alpha, 2)
529
+ );
494
530
  }
495
531
  clone() {
496
532
  return new _HSLColor(this.hue, this.saturation, this.lightness, this.alpha);
@@ -508,10 +544,13 @@ var _HSLColor = class _HSLColor extends Color {
508
544
  throw new Error("Unknown color channel: " + channel);
509
545
  }
510
546
  }
511
- getColorFormat() {
547
+ toJSON() {
548
+ return { h: this.hue, s: this.saturation, l: this.lightness };
549
+ }
550
+ getFormat() {
512
551
  return "hsl";
513
552
  }
514
- getColorChannels() {
553
+ getChannels() {
515
554
  return _HSLColor.colorChannels;
516
555
  }
517
556
  };
@@ -532,7 +571,7 @@ var _HSBColor = class _HSBColor extends Color {
532
571
  let m;
533
572
  if (m = value.match(HSB_REGEX)) {
534
573
  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));
574
+ 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
575
  }
537
576
  }
538
577
  toString(format) {
@@ -544,9 +583,9 @@ var _HSBColor = class _HSBColor extends Color {
544
583
  case "hexa":
545
584
  return this.toRGB().toString("hexa");
546
585
  case "hsb":
547
- return `hsb(${this.hue}, ${toFixedNumber(this.saturation, 2)}%, ${toFixedNumber(this.brightness, 2)}%)`;
586
+ return `hsb(${this.hue}, ${(0, import_numeric_range4.toFixedNumber)(this.saturation, 2)}%, ${(0, import_numeric_range4.toFixedNumber)(this.brightness, 2)}%)`;
548
587
  case "hsba":
549
- return `hsba(${this.hue}, ${toFixedNumber(this.saturation, 2)}%, ${toFixedNumber(this.brightness, 2)}%, ${this.alpha})`;
588
+ return `hsba(${this.hue}, ${(0, import_numeric_range4.toFixedNumber)(this.saturation, 2)}%, ${(0, import_numeric_range4.toFixedNumber)(this.brightness, 2)}%, ${this.alpha})`;
550
589
  default:
551
590
  return this.toFormat(format).toString(format);
552
591
  }
@@ -577,10 +616,10 @@ var _HSBColor = class _HSBColor extends Color {
577
616
  let lightness = brightness * (1 - saturation / 2);
578
617
  saturation = lightness === 0 || lightness === 1 ? 0 : (brightness - lightness) / Math.min(lightness, 1 - lightness);
579
618
  return new HSLColor(
580
- toFixedNumber(this.hue, 2),
581
- toFixedNumber(saturation * 100, 2),
582
- toFixedNumber(lightness * 100, 2),
583
- this.alpha
619
+ (0, import_numeric_range4.toFixedNumber)(this.hue, 2),
620
+ (0, import_numeric_range4.toFixedNumber)(saturation * 100, 2),
621
+ (0, import_numeric_range4.toFixedNumber)(lightness * 100, 2),
622
+ (0, import_numeric_range4.toFixedNumber)(this.alpha, 2)
584
623
  );
585
624
  }
586
625
  /**
@@ -593,7 +632,12 @@ var _HSBColor = class _HSBColor extends Color {
593
632
  let saturation = this.saturation / 100;
594
633
  let brightness = this.brightness / 100;
595
634
  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);
635
+ return new RGBColor(
636
+ Math.round(fn(5) * 255),
637
+ Math.round(fn(3) * 255),
638
+ Math.round(fn(1) * 255),
639
+ (0, import_numeric_range4.toFixedNumber)(this.alpha, 2)
640
+ );
597
641
  }
598
642
  clone() {
599
643
  return new _HSBColor(this.hue, this.saturation, this.brightness, this.alpha);
@@ -611,10 +655,13 @@ var _HSBColor = class _HSBColor extends Color {
611
655
  throw new Error("Unknown color channel: " + channel);
612
656
  }
613
657
  }
614
- getColorFormat() {
658
+ toJSON() {
659
+ return { h: this.hue, s: this.saturation, b: this.brightness };
660
+ }
661
+ getFormat() {
615
662
  return "hsb";
616
663
  }
617
- getColorChannels() {
664
+ getChannels() {
618
665
  return _HSBColor.colorChannels;
619
666
  }
620
667
  };