@oscarpalmer/atoms 0.190.0 → 0.191.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.
Files changed (42) hide show
  1. package/dist/color/constants.d.mts +7 -1
  2. package/dist/color/constants.mjs +7 -1
  3. package/dist/color/index.d.mts +3 -3
  4. package/dist/color/index.mjs +2 -2
  5. package/dist/color/instance.mjs +27 -25
  6. package/dist/color/misc/alpha.d.mts +1 -1
  7. package/dist/color/misc/alpha.mjs +10 -7
  8. package/dist/color/misc/format.d.mts +7 -0
  9. package/dist/color/misc/format.mjs +20 -0
  10. package/dist/color/misc/get.mjs +16 -16
  11. package/dist/color/misc/is.d.mts +0 -36
  12. package/dist/color/misc/is.mjs +1 -37
  13. package/dist/color/misc/state.d.mts +3 -2
  14. package/dist/color/misc/state.mjs +69 -83
  15. package/dist/color/models.d.mts +28 -5
  16. package/dist/color/space/hex.d.mts +3 -2
  17. package/dist/color/space/hex.mjs +13 -1
  18. package/dist/color/space/hsl.d.mts +3 -2
  19. package/dist/color/space/hsl.mjs +13 -1
  20. package/dist/color/space/hwb.d.mts +3 -2
  21. package/dist/color/space/hwb.mjs +13 -1
  22. package/dist/color/space/rgb.d.mts +3 -2
  23. package/dist/color/space/rgb.mjs +14 -2
  24. package/dist/index.d.mts +23 -29
  25. package/dist/index.mjs +198 -184
  26. package/package.json +4 -4
  27. package/src/color/constants.ts +12 -0
  28. package/src/color/index.ts +26 -8
  29. package/src/color/instance.ts +60 -45
  30. package/src/color/misc/alpha.ts +12 -6
  31. package/src/color/misc/format.ts +29 -0
  32. package/src/color/misc/get.ts +20 -13
  33. package/src/color/misc/is.ts +7 -37
  34. package/src/color/misc/state.ts +115 -127
  35. package/src/color/models.ts +32 -4
  36. package/src/color/space/hex.ts +34 -1
  37. package/src/color/space/hsl.ts +40 -2
  38. package/src/color/space/hwb.ts +32 -2
  39. package/src/color/space/rgb.ts +33 -3
  40. package/dist/color/misc/index.d.mts +0 -7
  41. package/dist/color/misc/index.mjs +0 -15
  42. package/src/color/misc/index.ts +0 -29
package/dist/index.mjs CHANGED
@@ -4014,38 +4014,6 @@ const NAME_OBSERVABLE = "observable";
4014
4014
  const NAME_SUBSCRIPTION = "subscription";
4015
4015
  const TYPE_ERROR = "error";
4016
4016
  const TYPE_NEXT = "next";
4017
- //#endregion
4018
- //#region src/color/misc/index.ts
4019
- function formatHslColor(state, alpha) {
4020
- const { hue, lightness, saturation } = state.hsl;
4021
- return `hsl(${hue}deg ${saturation}% ${lightness}%${alpha ? ` / ${state.alpha.value}%` : ""})`;
4022
- }
4023
- function formatHwbColor(state, alpha) {
4024
- const { blackness, hue, whiteness } = state.hwb;
4025
- return `hwb(${hue}deg ${whiteness}% ${blackness}%${alpha ? ` / ${state.alpha.value}%` : ""})`;
4026
- }
4027
- function formatRgbColor(state, alpha) {
4028
- const { blue, green, red } = state.rgb;
4029
- return `rgb(${red} ${green} ${blue}${alpha ? ` / ${state.alpha.value}%` : ""})`;
4030
- }
4031
- //#endregion
4032
- //#region src/internal/math/misc.ts
4033
- /**
4034
- * Round a number
4035
- *
4036
- * @param value Number to round
4037
- * @param decimals Number of decimal places to round to _(defaults to `0`)_
4038
- * @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
4039
- */
4040
- function round(value, decimals) {
4041
- return roundNumber(Math.round, value, decimals);
4042
- }
4043
- function roundNumber(callback, value, decimals) {
4044
- if (typeof value !== "number") return NaN;
4045
- if (typeof decimals !== "number" || decimals < 1) return callback(value);
4046
- const mod = 10 ** decimals;
4047
- return callback((value + Number.EPSILON) * mod) / mod;
4048
- }
4049
4017
  const ALPHA_FULL_HEX_LONG = `ff`;
4050
4018
  const DEFAULT_ALPHA = {
4051
4019
  hex: ALPHA_FULL_HEX_LONG,
@@ -4066,6 +4034,7 @@ const DEFAULT_RGB = {
4066
4034
  green: 0,
4067
4035
  red: 0
4068
4036
  };
4037
+ const EXPRESSION_ALPHA_HEX = /^([a-f0-9]{1,2})$/i;
4069
4038
  const EXPRESSION_HEX_LONG = /^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i;
4070
4039
  const EXPRESSION_HEX_SHORT = /^#?([a-f0-9]{3,4})$/i;
4071
4040
  const EXPRESSION_PREFIX = /^#/;
@@ -4089,24 +4058,44 @@ const KEYS_RGB = [
4089
4058
  "blue"
4090
4059
  ];
4091
4060
  const KEYS_RGBA = [...KEYS_RGB, "alpha"];
4061
+ const PROPERTY_COLOR = "$color";
4092
4062
  const SRGB_LUMINANCE_EXPONENT = 2.4;
4093
4063
  const SRGB_LUMINANCE_MODIFIER = 1.055;
4094
4064
  const SRGB_LUMINANCE_MULTIPLIER = 12.92;
4095
4065
  const SRGB_LUMINANCE_OFFSET = .055;
4096
4066
  //#endregion
4067
+ //#region src/internal/math/misc.ts
4068
+ /**
4069
+ * Round a number
4070
+ *
4071
+ * @param value Number to round
4072
+ * @param decimals Number of decimal places to round to _(defaults to `0`)_
4073
+ * @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
4074
+ */
4075
+ function round(value, decimals) {
4076
+ return roundNumber(Math.round, value, decimals);
4077
+ }
4078
+ function roundNumber(callback, value, decimals) {
4079
+ if (typeof value !== "number") return NaN;
4080
+ if (typeof decimals !== "number" || decimals < 1) return callback(value);
4081
+ const mod = 10 ** decimals;
4082
+ return callback((value + Number.EPSILON) * mod) / mod;
4083
+ }
4084
+ //#endregion
4097
4085
  //#region src/color/misc/alpha.ts
4098
- function getAlpha(value) {
4086
+ function getAlpha(value, hex) {
4099
4087
  if (typeof value === "number") return getAlphaFromValue(value);
4100
- if (typeof value === "string" && value !== ALPHA_FULL_HEX_LONG) return {
4088
+ if (typeof value !== "string" || value.toLowerCase() === ALPHA_FULL_HEX_LONG) return { ...DEFAULT_ALPHA };
4089
+ if (hex && EXPRESSION_ALPHA_HEX.test(value)) return {
4101
4090
  hex: value,
4102
4091
  value: Number.parseInt(value, 16) / 255
4103
4092
  };
4104
- return { ...DEFAULT_ALPHA };
4093
+ return getAlphaFromValue(Number.parseFloat(value));
4105
4094
  }
4106
4095
  function getAlphaHexadecimal(value) {
4107
4096
  if (value === 0) return "00";
4108
4097
  if (value === 100) return ALPHA_FULL_HEX_LONG;
4109
- return round(value * 255).toString(16);
4098
+ return round(value / 100 * 255).toString(16);
4110
4099
  }
4111
4100
  function getAlphaFromValue(value) {
4112
4101
  const alpha = getAlphaValue(value);
@@ -4116,8 +4105,8 @@ function getAlphaFromValue(value) {
4116
4105
  };
4117
4106
  }
4118
4107
  function getAlphaValue(original) {
4119
- if (Number.isNaN(original) || original >= 100) return 100;
4120
- return original <= 0 ? 0 : original;
4108
+ if (Number.isNaN(original)) return 100;
4109
+ return clamp(original, 0, 100);
4121
4110
  }
4122
4111
  //#endregion
4123
4112
  //#region src/color/misc/get.ts
@@ -4125,7 +4114,7 @@ function getClampedValue(value, minimum, maximum, rounding) {
4125
4114
  return typeof value === "number" && !Number.isNaN(value) ? clamp(rounding ?? false ? round(value) : value, minimum, maximum) : minimum;
4126
4115
  }
4127
4116
  function getForegroundColor(value, hex) {
4128
- const { blue, green, red } = getColorState(value).rgb;
4117
+ const { blue, green, red } = getColorFromState(getColorState(value), "rgb");
4129
4118
  const values = [
4130
4119
  blue / 255,
4131
4120
  green / 255,
@@ -4163,7 +4152,7 @@ function getHexaColor(value) {
4163
4152
  * @returns Hex color string
4164
4153
  */
4165
4154
  function getHexColor(value) {
4166
- return getColorState(value).hex;
4155
+ return getColorFromState(getColorState(value), "hex");
4167
4156
  }
4168
4157
  function getHexValue(value) {
4169
4158
  return getClampedValue(value, 0, 255, true);
@@ -4181,10 +4170,10 @@ function getDegrees(value) {
4181
4170
  * @returns _HSLA_ color
4182
4171
  */
4183
4172
  function getHslaColor(value) {
4184
- const { alpha, hsl } = getColorState(value);
4173
+ const state = getColorState(value);
4185
4174
  return {
4186
- ...hsl,
4187
- alpha: alpha.value
4175
+ ...getColorFromState(state, "hsl"),
4176
+ alpha: state.alpha.value
4188
4177
  };
4189
4178
  }
4190
4179
  /**
@@ -4197,7 +4186,7 @@ function getHslaColor(value) {
4197
4186
  * @returns _HWB_ color
4198
4187
  */
4199
4188
  function getHwbColor(value) {
4200
- return getColorState(value).hwb;
4189
+ return getColorFromState(getColorState(value), "hwb");
4201
4190
  }
4202
4191
  /**
4203
4192
  * Get the _HWBA_ color from any kind of value
@@ -4209,10 +4198,10 @@ function getHwbColor(value) {
4209
4198
  * @returns _HWBA_ color
4210
4199
  */
4211
4200
  function getHwbaColor(value) {
4212
- const { alpha, hwb } = getColorState(value);
4201
+ const state = getColorState(value);
4213
4202
  return {
4214
- ...hwb,
4215
- alpha: alpha.value
4203
+ ...getColorFromState(state, "hwb"),
4204
+ alpha: state.alpha.value
4216
4205
  };
4217
4206
  }
4218
4207
  /**
@@ -4225,7 +4214,7 @@ function getHwbaColor(value) {
4225
4214
  * @returns _HSL_ color
4226
4215
  */
4227
4216
  function getHslColor(value) {
4228
- return getColorState(value).hsl;
4217
+ return getColorFromState(getColorState(value), "hsl");
4229
4218
  }
4230
4219
  function getPercentage(value) {
4231
4220
  return getClampedValue(value, 0, 100);
@@ -4240,10 +4229,10 @@ function getPercentage(value) {
4240
4229
  * @returns _RGBA_ color
4241
4230
  */
4242
4231
  function getRgbaColor(value) {
4243
- const { alpha, rgb } = getColorState(value);
4232
+ const state = getColorState(value);
4244
4233
  return {
4245
- ...rgb,
4246
- alpha: alpha.value
4234
+ ...getColorFromState(state, "rgb"),
4235
+ alpha: state.alpha.value
4247
4236
  };
4248
4237
  }
4249
4238
  /**
@@ -4256,7 +4245,7 @@ function getRgbaColor(value) {
4256
4245
  * @returns _RGB_ color
4257
4246
  */
4258
4247
  function getRgbColor(value) {
4259
- return getColorState(value).rgb;
4248
+ return getColorFromState(getColorState(value), "rgb");
4260
4249
  }
4261
4250
  //#endregion
4262
4251
  //#region src/color/misc/is.ts
@@ -4276,7 +4265,7 @@ function isBytey(value) {
4276
4265
  * @returns `true` if the value is a _Color_, otherwise `false`
4277
4266
  */
4278
4267
  function isColor(value) {
4279
- return typeof value === "object" && value !== null && "$color" in value && value.$color === true;
4268
+ return typeof value === "object" && value !== null && "$color" in value && value["$color"] === true;
4280
4269
  }
4281
4270
  function isColorValue(obj, properties) {
4282
4271
  if (typeof obj !== "object" || obj === null) return false;
@@ -4335,12 +4324,6 @@ function isHslaColor(value) {
4335
4324
  function isHslColor(value) {
4336
4325
  return isColorValue(value, KEYS_HSLA) || isColorValue(value, KEYS_HSL);
4337
4326
  }
4338
- /**
4339
- * Is the value like an _HSL_ color?
4340
- *
4341
- * @param value Value to check
4342
- * @returns `true` if the value is like an _HSL_ color, otherwise `false`
4343
- */
4344
4327
  function isHslLike(value) {
4345
4328
  return hasKeys(value, KEYS_HSL);
4346
4329
  }
@@ -4354,15 +4337,6 @@ function isHwbaColor(value) {
4354
4337
  return isColorValue(value, KEYS_HWBA);
4355
4338
  }
4356
4339
  /**
4357
- * Is the value like an _HWBA_ color?
4358
- *
4359
- * @param value Value to check
4360
- * @returns `true` if the value is like an _HWBA_ color, otherwise `false`
4361
- */
4362
- function isHwbaLike(value) {
4363
- return hasKeys(value, KEYS_HWBA);
4364
- }
4365
- /**
4366
4340
  * Is the value an _HWB_ color?
4367
4341
  *
4368
4342
  * @param value Value to check
@@ -4371,12 +4345,6 @@ function isHwbaLike(value) {
4371
4345
  function isHwbColor(value) {
4372
4346
  return isColorValue(value, KEYS_HWB) || isColorValue(value, KEYS_HWBA);
4373
4347
  }
4374
- /**
4375
- * Is the value like an _HWB_ color?
4376
- *
4377
- * @param value Value to check
4378
- * @returns `true` if the value is like an _HWB_ color, otherwise `false`
4379
- */
4380
4348
  function isHwbLike(value) {
4381
4349
  return hasKeys(value, KEYS_HWB);
4382
4350
  }
@@ -4398,12 +4366,6 @@ function isRgbaColor(value) {
4398
4366
  function isRgbColor(value) {
4399
4367
  return isColorValue(value, KEYS_RGBA) || isColorValue(value, KEYS_RGB);
4400
4368
  }
4401
- /**
4402
- * Is the value like an _RGB_ color?
4403
- *
4404
- * @param value Value to check
4405
- * @returns `true` if the value is like an _RGB_ color, otherwise `false`
4406
- */
4407
4369
  function isRgbLike(value) {
4408
4370
  return hasKeys(value, KEYS_RGB);
4409
4371
  }
@@ -4433,7 +4395,7 @@ function convertRgbToHex(rgb, alpha) {
4433
4395
  return hexString.length === 1 ? `0${hexString}` : hexString;
4434
4396
  }))}`;
4435
4397
  let a = "";
4436
- if (typeof alpha === "boolean" && alpha) a = getAlpha(rgb.alpha).hex;
4398
+ if (typeof alpha === "boolean" && alpha) a = getAlpha(rgb.alpha, false).hex;
4437
4399
  return `${hex}${a}`;
4438
4400
  }
4439
4401
  function convertRgbToHsla(value) {
@@ -4469,6 +4431,18 @@ function convertRgbToHwba(value) {
4469
4431
  alpha: getAlphaValue(value?.alpha ?? 100)
4470
4432
  };
4471
4433
  }
4434
+ function getColorFromRgb(state, type) {
4435
+ switch (type) {
4436
+ case "hex":
4437
+ state.hex = rgbToHex(state.rgb);
4438
+ break;
4439
+ case "hsl":
4440
+ state.hsl = rgbToHsl(state.rgb);
4441
+ break;
4442
+ case "hwb": state.hwb = rgbToHwb(state.rgb);
4443
+ }
4444
+ return state[type];
4445
+ }
4472
4446
  function getRgbHue(values) {
4473
4447
  const { blue, delta, green, max, red } = values;
4474
4448
  switch (max) {
@@ -4588,6 +4562,18 @@ function convertHexToRgba(value) {
4588
4562
  red: getHexValue(values[0])
4589
4563
  };
4590
4564
  }
4565
+ function getColorFromHex(state, type) {
4566
+ switch (type) {
4567
+ case "hsl":
4568
+ state.hsl ??= hexToHsl(state.hex);
4569
+ break;
4570
+ case "hwb":
4571
+ state.hwb ??= hexToHwb(state.hex);
4572
+ break;
4573
+ case "rgb": state.rgb ??= hexToRgb(state.hex);
4574
+ }
4575
+ return state[type];
4576
+ }
4591
4577
  /**
4592
4578
  * Get the normalized hex color from a value
4593
4579
  *
@@ -4714,6 +4700,18 @@ function convertHslToRgba(input) {
4714
4700
  red: getHexValue(getHexyValue(hue, lightness, saturation, 0))
4715
4701
  };
4716
4702
  }
4703
+ function getColorFromHsl(state, type) {
4704
+ switch (type) {
4705
+ case "hex":
4706
+ state.hex = hslToHex(state.hsl);
4707
+ break;
4708
+ case "hwb":
4709
+ state.hwb = hslToHwb(state.hsl);
4710
+ break;
4711
+ case "rgb": state.rgb = hslToRgb(state.hsl);
4712
+ }
4713
+ return state[type];
4714
+ }
4717
4715
  function getHexyValue(hue, lightness, saturation, value) {
4718
4716
  const part = (value + hue / 30) % 12;
4719
4717
  return (lightness - saturation * Math.min(lightness, 1 - lightness) * Math.max(-1, Math.min(part - 3, 9 - part, 1))) * 255;
@@ -4814,6 +4812,18 @@ function convertHwbToHsl(input) {
4814
4812
  alpha: getAlphaValue(input?.alpha ?? 100)
4815
4813
  };
4816
4814
  }
4815
+ function getColorFromHwb(state, type) {
4816
+ switch (type) {
4817
+ case "hex":
4818
+ state.hex = hwbToHex(state.hwb);
4819
+ break;
4820
+ case "hsl":
4821
+ state.hsl = hwbToHsl(state.hwb);
4822
+ break;
4823
+ case "rgb": state.rgb = hwbToRgb(state.hwb);
4824
+ }
4825
+ return state[type];
4826
+ }
4817
4827
  function getHwbSaturation(blackness, whiteness, lightness) {
4818
4828
  const hue = 1 - blackness - whiteness;
4819
4829
  if (hue <= 0) return 0;
@@ -4889,115 +4899,118 @@ function hwbToRgba(hwb) {
4889
4899
  }
4890
4900
  //#endregion
4891
4901
  //#region src/color/misc/state.ts
4902
+ function getColorFromState(state, type) {
4903
+ const { origin } = state;
4904
+ if (type === origin) return state[origin];
4905
+ return state[type] ?? getters[origin](state, type);
4906
+ }
4892
4907
  function getColorState(value) {
4893
4908
  if (typeof value === "string") return getColorStateForHex(value);
4894
- if (isColor(value)) return {
4895
- hex: value.hex,
4896
- hsl: value.hsl,
4897
- hwb: value.hwb,
4898
- rgb: value.rgb,
4899
- alpha: getAlpha(value.alpha)
4900
- };
4901
- const state = {};
4909
+ if (isColor(value)) {
4910
+ const { origin } = value;
4911
+ return {
4912
+ origin,
4913
+ [origin]: value[origin],
4914
+ alpha: getAlpha(value.alpha, false)
4915
+ };
4916
+ }
4902
4917
  if (typeof value === "object" && value !== null) {
4903
- state.alpha = getAlpha(value.alpha);
4904
- if (KEYS_HSL.every((key) => key in value)) return getColorStateForHsl(state, value);
4905
- if (KEYS_HWB.every((key) => key in value)) return getColorStateForHwb(state, value);
4906
- if (KEYS_RGB.every((key) => key in value)) return getColorStateForRgb(state, value);
4918
+ const state = {
4919
+ alpha: getAlpha(value.alpha, false),
4920
+ origin: void 0
4921
+ };
4922
+ if (KEYS_HSL.every((key) => key in value)) {
4923
+ state.hsl = getHslValue(value);
4924
+ state.origin = "hsl";
4925
+ } else if (KEYS_HWB.every((key) => key in value)) {
4926
+ state.hwb = getHwbValue(value);
4927
+ state.origin = "hwb";
4928
+ } else if (KEYS_RGB.every((key) => key in value)) {
4929
+ state.rgb = getRgbValue(value);
4930
+ state.origin = "rgb";
4931
+ }
4932
+ if (state.origin != null) return state;
4907
4933
  }
4908
- return getDefaultColorState(state);
4934
+ return getDefaultColorState();
4909
4935
  }
4910
4936
  function getColorStateForHex(value) {
4911
4937
  const normalized = getNormalizedHex(value, true);
4912
- const hex = normalized.slice(0, 6);
4913
- const hsl = hexToHsl(hex);
4914
4938
  return {
4915
- hex,
4916
- hsl,
4917
- alpha: getAlpha(normalized.slice(6)),
4918
- hwb: hslToHwb(hsl),
4919
- rgb: hslToRgb(hsl)
4939
+ hex: normalized.slice(0, 6),
4940
+ alpha: getAlpha(normalized.slice(6), true),
4941
+ origin: "hex"
4920
4942
  };
4921
4943
  }
4922
- function getColorStateForHsl(state, value) {
4923
- state.hsl = getHslValue(value);
4924
- state.rgb = hslToRgb(state.hsl);
4925
- state.hex = hslToHex(state.hsl);
4926
- state.hwb = hslToHwb(state.hsl);
4927
- return state;
4928
- }
4929
- function getColorStateForHwb(state, value) {
4930
- state.hwb = getHwbValue(value);
4931
- state.hsl = hwbToHsl(state.hwb);
4932
- state.rgb = hwbToRgb(state.hwb);
4933
- state.hex = hwbToHex(state.hwb);
4934
- return state;
4935
- }
4936
- function getColorStateForRgb(state, value) {
4937
- state.rgb = getRgbValue(value);
4938
- state.hex = rgbToHex(state.rgb);
4939
- state.hsl = rgbToHsl(state.rgb);
4940
- state.hwb = rgbToHwb(state.rgb);
4941
- return state;
4942
- }
4943
- function getDefaultColorState(state) {
4944
- state.alpha = getAlpha(100);
4945
- state.hex = HEX_BLACK;
4946
- state.hsl = { ...DEFAULT_HSL };
4947
- state.hwb = { ...DEFAULT_HWB };
4948
- state.rgb = { ...DEFAULT_RGB };
4949
- return state;
4944
+ function getDefaultColorState() {
4945
+ return {
4946
+ alpha: getAlpha(100, false),
4947
+ hex: HEX_BLACK,
4948
+ hsl: { ...DEFAULT_HSL },
4949
+ hwb: { ...DEFAULT_HWB },
4950
+ rgb: { ...DEFAULT_RGB },
4951
+ origin: "hex"
4952
+ };
4953
+ }
4954
+ function setColorValue(state, type, value, alpha) {
4955
+ state.hex = void 0;
4956
+ state.hsl = void 0;
4957
+ state.hwb = void 0;
4958
+ state.rgb = void 0;
4959
+ state.origin = type;
4960
+ state[type] = value;
4961
+ if (alpha != null) state.alpha = getAlpha(alpha, type === "hex");
4950
4962
  }
4951
4963
  function setHexColor(state, value, alpha) {
4952
4964
  if (!isHexColor(value) || !alpha && value === state.hex) return;
4953
4965
  const normalized = getNormalizedHex(value, true);
4954
- const hex = normalized.slice(0, 6);
4955
- const hsl = hexToHsl(hex);
4956
- state.hex = hex;
4957
- state.hsl = hsl;
4958
- state.rgb = hslToRgb(hsl);
4959
- state.hwb = hslToHwb(hsl);
4960
- if (alpha) state.alpha = getAlpha(normalized.slice(6));
4966
+ setColorValue(state, "hex", normalized.slice(0, 6), alpha ? normalized.slice(6) : void 0);
4961
4967
  }
4962
4968
  function setHSLColor(state, value, alpha) {
4963
4969
  if (!isHslLike(value)) return;
4964
- const hsl = {
4970
+ setColorValue(state, "hsl", {
4965
4971
  hue: getDegrees(value.hue),
4966
4972
  saturation: getPercentage(value.saturation),
4967
4973
  lightness: getPercentage(value.lightness)
4968
- };
4969
- state.hsl = hsl;
4970
- state.hex = hslToHex(hsl);
4971
- state.hwb = hslToHwb(hsl);
4972
- state.rgb = hslToRgb(hsl);
4973
- if (alpha) state.alpha = getAlpha(value.alpha);
4974
+ }, alpha ? value.alpha : void 0);
4974
4975
  }
4975
4976
  function setHWBColor(state, value, alpha) {
4976
4977
  if (!isHwbLike(value)) return;
4977
- const hwb = {
4978
+ setColorValue(state, "hwb", {
4978
4979
  hue: getDegrees(value.hue),
4979
4980
  whiteness: getPercentage(value.whiteness),
4980
4981
  blackness: getPercentage(value.blackness)
4981
- };
4982
- state.hwb = hwb;
4983
- state.hex = hwbToHex(hwb);
4984
- state.hsl = hwbToHsl(hwb);
4985
- state.rgb = hwbToRgb(hwb);
4986
- if (alpha) state.alpha = getAlpha(value.alpha);
4982
+ }, alpha ? value.alpha : void 0);
4987
4983
  }
4988
4984
  function setRGBColor(state, value, alpha) {
4989
4985
  if (!isRgbLike(value)) return;
4990
- const rgb = {
4991
- blue: getHexValue(value.blue),
4986
+ setColorValue(state, "rgb", {
4987
+ red: getHexValue(value.red),
4992
4988
  green: getHexValue(value.green),
4993
- red: getHexValue(value.red)
4994
- };
4995
- const hsl = rgbToHsl(rgb);
4996
- state.hsl = hsl;
4997
- state.rgb = rgb;
4998
- state.hex = hslToHex(hsl);
4999
- state.hwb = hslToHwb(hsl);
5000
- if (alpha) state.alpha = getAlpha(value.alpha);
4989
+ blue: getHexValue(value.blue)
4990
+ }, alpha ? value.alpha : void 0);
4991
+ }
4992
+ const getters = {
4993
+ hex: getColorFromHex,
4994
+ hsl: getColorFromHsl,
4995
+ hwb: getColorFromHwb,
4996
+ rgb: getColorFromRgb
4997
+ };
4998
+ //#endregion
4999
+ //#region src/color/misc/format.ts
5000
+ function formatHslColor(state, alpha) {
5001
+ const { hue, lightness, saturation } = getColorFromState(state, "hsl");
5002
+ return `hsl(${hue}deg ${saturation}% ${lightness}%${getSuffix(state, alpha)})`;
5003
+ }
5004
+ function formatHwbColor(state, alpha) {
5005
+ const { blackness, hue, whiteness } = getColorFromState(state, "hwb");
5006
+ return `hwb(${hue}deg ${whiteness}% ${blackness}%${getSuffix(state, alpha)})`;
5007
+ }
5008
+ function formatRgbColor(state, alpha) {
5009
+ const { blue, green, red } = getColorFromState(state, "rgb");
5010
+ return `rgb(${red} ${green} ${blue}${getSuffix(state, alpha)})`;
5011
+ }
5012
+ function getSuffix(state, alpha) {
5013
+ return alpha === true ? ` / ${state.alpha.value}%` : "";
5001
5014
  }
5002
5015
  //#endregion
5003
5016
  //#region src/color/instance.ts
@@ -5005,22 +5018,20 @@ function color(value) {
5005
5018
  const state = getColorState(value);
5006
5019
  const instance = {
5007
5020
  toHexString: (alpha) => `#${alpha === true ? instance.hexa : instance.hex}`,
5008
- toHslString: (alpha) => formatHslColor(state, alpha === true),
5009
- toHwbString: (alpha) => formatHwbColor(state, alpha === true),
5010
- toRgbString: (alpha) => formatRgbColor(state, alpha === true),
5021
+ toHslString: (alpha) => formatHslColor(state, alpha),
5022
+ toHwbString: (alpha) => formatHwbColor(state, alpha),
5023
+ toRgbString: (alpha) => formatRgbColor(state, alpha),
5011
5024
  toString: () => instance.toHexString()
5012
5025
  };
5013
5026
  Object.defineProperties(instance, {
5014
- $color: {
5027
+ [PROPERTY_COLOR]: {
5015
5028
  enumerable: false,
5016
- get: () => true
5029
+ value: true
5017
5030
  },
5018
5031
  alpha: {
5019
5032
  enumerable: true,
5020
5033
  get: () => state.alpha.value,
5021
- set: (value) => {
5022
- if (typeof value === "number" && !Number.isNaN(value)) state.alpha = getAlpha(value);
5023
- }
5034
+ set: (value) => setAlphaValue(state, value)
5024
5035
  },
5025
5036
  hex: getProperty("hex", state, false),
5026
5037
  hexa: getProperty("hex", state, true),
@@ -5028,31 +5039,34 @@ function color(value) {
5028
5039
  hsla: getProperty("hsl", state, true),
5029
5040
  hwb: getProperty("hwb", state, false),
5030
5041
  hwba: getProperty("hwb", state, true),
5042
+ origin: {
5043
+ enumerable: true,
5044
+ get: () => state.origin
5045
+ },
5031
5046
  rgb: getProperty("rgb", state, false),
5032
5047
  rgba: getProperty("rgb", state, true)
5033
5048
  });
5034
5049
  return Object.freeze(instance);
5035
5050
  }
5036
- function getHex(state, alpha) {
5037
- return alpha ? `${state.hex}${state.alpha.hex}` : state.hex;
5038
- }
5039
5051
  function getProperty(space, state, alpha) {
5040
- const setter = setters[space];
5052
+ const setValue = setters[space];
5041
5053
  return {
5042
5054
  enumerable: true,
5043
- get: () => {
5044
- const value = state[space];
5045
- if (typeof value === "string") return getHex(state, alpha);
5046
- return alpha ? {
5047
- ...value,
5048
- alpha: state.alpha.value
5049
- } : { ...value };
5050
- },
5051
- set: (value) => {
5052
- setter(state, value, alpha);
5053
- }
5055
+ get: () => getValue$1(space, state, alpha),
5056
+ set: (value) => setValue(state, value, alpha)
5054
5057
  };
5055
5058
  }
5059
+ function getValue$1(space, state, alpha) {
5060
+ const value = getColorFromState(state, space);
5061
+ if (typeof value === "string") return alpha ? `${value}${state.alpha.hex}` : value;
5062
+ return alpha ? {
5063
+ ...value,
5064
+ alpha: state.alpha.value
5065
+ } : { ...value };
5066
+ }
5067
+ function setAlphaValue(state, value) {
5068
+ if (typeof value === "number" && !Number.isNaN(value)) state.alpha = getAlpha(value, false);
5069
+ }
5056
5070
  const setters = {
5057
5071
  hex: setHexColor,
5058
5072
  hsl: setHSLColor,
@@ -6114,4 +6128,4 @@ var SizedSet = class extends Set {
6114
6128
  }
6115
6129
  };
6116
6130
  //#endregion
6117
- export { CancelablePromise, Logger, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isColor, isConstructor, isEmpty, isError, isEvents, isFrozen, isFulfilled, isHerald, isHexColor, isHslColor, isHslLike, isHslaColor, isHwbColor, isHwbLike, isHwbaColor, isHwbaLike, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
6131
+ export { CancelablePromise, Logger, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isBeacon, isColor, isConstructor, isEmpty, isError, isEvents, isFrozen, isFulfilled, isHerald, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isTimedLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/atoms",
3
- "version": "0.190.0",
3
+ "version": "0.191.0",
4
4
  "description": "Atomic utilities for making your JavaScript better.",
5
5
  "keywords": [
6
6
  "helper",
@@ -257,10 +257,10 @@
257
257
  "watch": "npx vite build --watch"
258
258
  },
259
259
  "devDependencies": {
260
- "@oxlint/plugins": "^1.78",
260
+ "@oxlint/plugins": "^1.79",
261
261
  "@types/node": "^26.2",
262
- "@vitest/coverage-istanbul": "4.1.10",
263
- "eslint": "^10.8",
262
+ "@vitest/coverage-istanbul": "^4.1",
263
+ "eslint": "^10.9",
264
264
  "jsdom": "^30",
265
265
  "tsdown": "^0.22",
266
266
  "typescript": "^6",
@@ -33,6 +33,8 @@ export const DEFAULT_RGB: RGBColor = {
33
33
  red: 0,
34
34
  };
35
35
 
36
+ export const EXPRESSION_ALPHA_HEX = /^([a-f0-9]{1,2})$/i;
37
+
36
38
  export const EXPRESSION_HEX_LONG = /^#?([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?$/i;
37
39
 
38
40
  export const EXPRESSION_HEX_SHORT = /^#?([a-f0-9]{3,4})$/i;
@@ -65,6 +67,16 @@ export const MAX_HEX = 255;
65
67
 
66
68
  export const MAX_PERCENT = 100;
67
69
 
70
+ export const PROPERTY_COLOR = '$color';
71
+
72
+ export const TYPE_HEX = 'hex';
73
+
74
+ export const TYPE_HSL = 'hsl';
75
+
76
+ export const TYPE_HWB = 'hwb';
77
+
78
+ export const TYPE_RGB = 'rgb';
79
+
68
80
  // https://www.w3.org/TR/WCAG20/#relativeluminancedef
69
81
 
70
82
  export const SRGB_LUMINANCE_BLUE = 0.0722;