@oscarpalmer/atoms 0.190.0 → 0.192.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 (57) hide show
  1. package/dist/beacon.d.mts +6 -44
  2. package/dist/beacon.mjs +20 -67
  3. package/dist/color/constants.d.mts +82 -35
  4. package/dist/color/constants.mjs +106 -61
  5. package/dist/color/index.d.mts +3 -3
  6. package/dist/color/index.mjs +2 -2
  7. package/dist/color/instance.mjs +60 -35
  8. package/dist/color/misc/alpha.d.mts +1 -1
  9. package/dist/color/misc/alpha.mjs +12 -10
  10. package/dist/color/misc/format.d.mts +7 -0
  11. package/dist/color/misc/format.mjs +20 -0
  12. package/dist/color/misc/get.mjs +25 -25
  13. package/dist/color/misc/is.d.mts +0 -36
  14. package/dist/color/misc/is.mjs +22 -57
  15. package/dist/color/misc/state.d.mts +8 -6
  16. package/dist/color/misc/state.mjs +79 -88
  17. package/dist/color/models.d.mts +106 -6
  18. package/dist/color/space/hex.d.mts +3 -2
  19. package/dist/color/space/hex.mjs +22 -10
  20. package/dist/color/space/hsl.d.mts +3 -2
  21. package/dist/color/space/hsl.mjs +26 -14
  22. package/dist/color/space/hwb.d.mts +3 -2
  23. package/dist/color/space/hwb.mjs +20 -8
  24. package/dist/color/space/rgb.d.mts +3 -2
  25. package/dist/color/space/rgb.mjs +27 -15
  26. package/dist/herald.d.mts +2 -3
  27. package/dist/index.d.mts +139 -73
  28. package/dist/index.mjs +653 -477
  29. package/dist/internal/subscription.d.mts +52 -0
  30. package/dist/internal/subscription.mjs +127 -0
  31. package/dist/models.d.mts +5 -1
  32. package/package.json +4 -4
  33. package/src/beacon.ts +32 -117
  34. package/src/color/constants.ts +115 -66
  35. package/src/color/index.ts +26 -8
  36. package/src/color/instance.ts +113 -45
  37. package/src/color/misc/alpha.ts +18 -20
  38. package/src/color/misc/format.ts +29 -0
  39. package/src/color/misc/get.ts +31 -41
  40. package/src/color/misc/is.ts +31 -71
  41. package/src/color/misc/state.ts +165 -141
  42. package/src/color/models.ts +126 -5
  43. package/src/color/space/hex.ts +46 -18
  44. package/src/color/space/hsl.ts +44 -14
  45. package/src/color/space/hwb.ts +38 -8
  46. package/src/color/space/rgb.ts +48 -15
  47. package/src/herald.ts +1 -3
  48. package/src/index.ts +1 -0
  49. package/src/internal/subscription.ts +264 -0
  50. package/src/models.ts +5 -0
  51. package/src/string/fuzzy.ts +1 -1
  52. package/src/value/freeze.ts +2 -2
  53. package/src/value/shake.ts +1 -1
  54. package/src/value/transform.ts +1 -1
  55. package/dist/color/misc/index.d.mts +0 -7
  56. package/dist/color/misc/index.mjs +0 -15
  57. package/src/color/misc/index.ts +0 -29
@@ -1,5 +1,8 @@
1
1
  // #region Types
2
2
 
3
+ import type {Subscription} from '../internal/subscription';
4
+ import type {COLOR_ALPHA, COLOR_TYPE} from './constants';
5
+
3
6
  export type Alpha = {
4
7
  hex: string;
5
8
  value: number;
@@ -117,6 +120,13 @@ export type Color = {
117
120
  */
118
121
  set hwba(value: HWBAColor);
119
122
 
123
+ /**
124
+ * Last color format that was set on the color
125
+ *
126
+ * @returns Color type
127
+ */
128
+ get origin(): ColorType;
129
+
120
130
  /**
121
131
  * Get the color as an _RGB_ color
122
132
  *
@@ -145,6 +155,85 @@ export type Color = {
145
155
  */
146
156
  set rgba(value: RGBAColor);
147
157
 
158
+ /**
159
+ * Subscribe to alpha channel _(opacity)_ changes of the color
160
+ *
161
+ * @param key Color property to subscribe to
162
+ * @param callback Callback function for changes
163
+ */
164
+ subscribe(key: 'alpha', callback: (value: number) => void): Subscription;
165
+
166
+ /**
167
+ * Subscribe to hex color changes of the color
168
+ *
169
+ * @param key Color type to subscribe to
170
+ * @param callback Callback function for changes
171
+ */
172
+ subscribe(key: typeof COLOR_TYPE.hex, callback: (value: string) => void): Subscription;
173
+
174
+ /**
175
+ * Subscribe to hex color changes of the color with alpha channel _(opacity)_
176
+ *
177
+ * @param key Color type to subscribe to
178
+ * @param callback Callback function for changes
179
+ */
180
+ subscribe(key: typeof COLOR_TYPE.hexa, callback: (value: string) => void): Subscription;
181
+
182
+ /**
183
+ * Subscribe to _HSL_ color changes of the color
184
+ *
185
+ * @param key Color type to subscribe to
186
+ * @param callback Callback function for changes
187
+ */
188
+ subscribe(key: typeof COLOR_TYPE.hsl, callback: (value: HSLColor) => void): Subscription;
189
+
190
+ /**
191
+ * Subscribe to _HSL(A)_ color changes of the color
192
+ *
193
+ * @param key Color type to subscribe to
194
+ * @param callback Callback function for changes
195
+ */
196
+ subscribe(key: typeof COLOR_TYPE.hsla, callback: (value: HSLAColor) => void): Subscription;
197
+
198
+ /**
199
+ * Subscribe to _HWB_ color changes of the color
200
+ *
201
+ * @param key Color type to subscribe to
202
+ * @param callback Callback function for changes
203
+ */
204
+ subscribe(key: typeof COLOR_TYPE.hwb, callback: (value: HWBColor) => void): Subscription;
205
+
206
+ /**
207
+ * Subscribe to _HWB(A)_ color changes of the color
208
+ *
209
+ * @param key Color type to subscribe to
210
+ * @param callback Callback function for changes
211
+ */
212
+ subscribe(key: typeof COLOR_TYPE.hwba, callback: (value: HWBAColor) => void): Subscription;
213
+
214
+ /**
215
+ * Subscribe to _RGB_ color changes of the color
216
+ *
217
+ * @param key Color type to subscribe to
218
+ * @param callback Callback function for changes
219
+ */
220
+ subscribe(key: typeof COLOR_TYPE.rgb, callback: (value: RGBColor) => void): Subscription;
221
+
222
+ /**
223
+ * Subscribe to _RGBA_ color changes of the color
224
+ *
225
+ * @param key Color type to subscribe to
226
+ * @param callback Callback function for changes
227
+ */
228
+ subscribe(key: typeof COLOR_TYPE.rgba, callback: (value: RGBAColor) => void): Subscription;
229
+
230
+ /**
231
+ * Subscribe to any color changes of the color
232
+ *
233
+ * @param callback Callback function for changes
234
+ */
235
+ subscribe(callback: (value: Color) => void): Subscription;
236
+
148
237
  /**
149
238
  * Get the color as a hex string
150
239
  *
@@ -183,6 +272,13 @@ export type Color = {
183
272
  * @returns Hex color string
184
273
  */
185
274
  toString(): string;
275
+
276
+ /**
277
+ * Unsubscribe from all color changes of the color
278
+ *
279
+ * _(To unsubscribe from a specific color change, use the `unsubscribe()` method on the `Subscription` returned by the individual `subscribe()` method)_
280
+ */
281
+ unsubscribe(): void;
186
282
  };
187
283
 
188
284
  type ColorWithAlpha = {
@@ -255,14 +351,39 @@ export type RGBColor = {
255
351
  red: number;
256
352
  };
257
353
 
258
- export type ColorProperty = 'alpha' | keyof HSLColor | keyof HWBColor | keyof RGBColor;
354
+ export type ColorProperty =
355
+ | typeof COLOR_ALPHA.name
356
+ | keyof HSLColor
357
+ | keyof HWBColor
358
+ | keyof RGBColor;
259
359
 
260
360
  export type ColorState = {
261
361
  alpha: Alpha;
262
- hex: string;
263
- hsl: HSLColor;
264
- hwb: HWBColor;
265
- rgb: RGBColor;
362
+ hex?: string;
363
+ hsl?: HSLColor;
364
+ hwb?: HWBColor;
365
+ origin: ColorType;
366
+ rgb?: RGBColor;
266
367
  };
267
368
 
369
+ /**
370
+ * Base color types
371
+ */
372
+ export type ColorType = 'hex' | 'hsl' | 'hwb' | 'rgb';
373
+
374
+ /**
375
+ * Extended color types
376
+ */
377
+ export type ColorTypeExtended = ColorType | 'hsla' | 'hwba' | 'rgba';
378
+
379
+ /**
380
+ * Base color values
381
+ */
382
+ export type ColorValue = string | HSLColor | HWBColor | RGBColor;
383
+
384
+ /**
385
+ * Extended color values
386
+ */
387
+ export type ColorValueExtended = ColorValue | HSLAColor | HWBAColor | RGBAColor;
388
+
268
389
  // #endregion
@@ -1,24 +1,31 @@
1
1
  import {join} from '../../internal/string';
2
2
  import {
3
- ALPHA_FULL_HEX_LONG,
4
- ALPHA_FULL_HEX_SHORT,
5
- EXPRESSION_HEX_LONG,
6
- EXPRESSION_PREFIX,
7
- HEX_BLACK,
8
- LENGTH_LONG,
9
- LENGTH_SHORT,
10
- MAX_HEX,
3
+ COLOR_ALPHA,
4
+ COLOR_DEFAULTS,
5
+ COLOR_EXPRESSION,
6
+ COLOR_LENGTHS,
7
+ COLOR_MAX,
8
+ COLOR_TYPE,
11
9
  } from '../constants';
12
10
  import {getHexValue, getPercentage} from '../misc/get';
13
11
  import {isHexColor} from '../misc/is';
14
- import type {HSLAColor, HSLColor, HWBAColor, HWBColor, RGBAColor, RGBColor} from '../models';
12
+ import type {
13
+ ColorState,
14
+ ColorType,
15
+ HSLAColor,
16
+ HSLColor,
17
+ HWBAColor,
18
+ HWBColor,
19
+ RGBAColor,
20
+ RGBColor,
21
+ } from '../models';
15
22
  import {convertRgbToHsla, convertRgbToHwba} from './rgb';
16
23
 
17
24
  // #region Functions
18
25
 
19
26
  function convertHexToRgba(value: string): RGBAColor {
20
27
  const normalized = getNormalizedHex(value, true);
21
- const pairs = EXPRESSION_HEX_LONG.exec(normalized) as RegExpExecArray;
28
+ const pairs = COLOR_EXPRESSION.hexLong.exec(normalized) as RegExpExecArray;
22
29
  const values: number[] = [];
23
30
 
24
31
  const {length} = pairs;
@@ -28,13 +35,34 @@ function convertHexToRgba(value: string): RGBAColor {
28
35
  }
29
36
 
30
37
  return {
31
- alpha: getPercentage((values[3] / MAX_HEX) * 100),
38
+ alpha: getPercentage((values[3] / COLOR_MAX.hex) * 100),
32
39
  blue: getHexValue(values[2]),
33
40
  green: getHexValue(values[1]),
34
41
  red: getHexValue(values[0]),
35
42
  };
36
43
  }
37
44
 
45
+ export function getColorFromHex<Type extends ColorType>(
46
+ state: ColorState,
47
+ type: Type,
48
+ ): NonNullable<ColorState[Type]> {
49
+ switch (type) {
50
+ case COLOR_TYPE.hsl:
51
+ state.hsl ??= hexToHsl(state.hex!);
52
+ break;
53
+
54
+ case COLOR_TYPE.hwb:
55
+ state.hwb ??= hexToHwb(state.hex!);
56
+ break;
57
+
58
+ case COLOR_TYPE.rgb:
59
+ state.rgb ??= hexToRgb(state.hex!);
60
+ break;
61
+ }
62
+
63
+ return state[type]!;
64
+ }
65
+
38
66
  /**
39
67
  * Get the normalized hex color from a value
40
68
  *
@@ -48,21 +76,21 @@ export function getNormalizedHex(value: unknown, alpha?: boolean): string {
48
76
  const includeAlpha = alpha ?? false;
49
77
 
50
78
  if (!isHexColor(value)) {
51
- return `${HEX_BLACK}${includeAlpha ? ALPHA_FULL_HEX_LONG : ''}`;
79
+ return `${COLOR_DEFAULTS.hexBlack}${includeAlpha ? COLOR_ALPHA.fullHexLong : ''}`;
52
80
  }
53
81
 
54
- const normalized = value.replace(EXPRESSION_PREFIX, '');
82
+ const normalized = value.replace(COLOR_EXPRESSION.prefix, '');
55
83
 
56
- if (normalized.length < LENGTH_LONG) {
57
- const hex = normalized.slice(0, LENGTH_SHORT);
58
- const a = includeAlpha ? (normalized[LENGTH_SHORT] ?? ALPHA_FULL_HEX_SHORT) : '';
84
+ if (normalized.length < COLOR_LENGTHS.hexLong) {
85
+ const hex = normalized.slice(0, COLOR_LENGTHS.hexShort);
86
+ const a = includeAlpha ? (normalized[COLOR_LENGTHS.hexShort] ?? COLOR_ALPHA.fullHexShort) : '';
59
87
 
60
88
  return join(`${hex}${a}`.split('').map(character => character.repeat(2)));
61
89
  }
62
90
 
63
- const hex = normalized.slice(0, LENGTH_LONG);
91
+ const hex = normalized.slice(0, COLOR_LENGTHS.hexLong);
64
92
 
65
- const a = includeAlpha ? normalized.slice(LENGTH_LONG) || ALPHA_FULL_HEX_LONG : '';
93
+ const a = includeAlpha ? normalized.slice(COLOR_LENGTHS.hexLong) || COLOR_ALPHA.fullHexLong : '';
66
94
 
67
95
  return `${hex}${a}`;
68
96
  }
@@ -1,19 +1,28 @@
1
- import {DEFAULT_HSL, MAX_DEGREE, MAX_HEX, MAX_PERCENT} from '../constants';
1
+ import {COLOR_DEFAULTS, COLOR_MAX, COLOR_TYPE} from '../constants';
2
2
  import {getAlphaValue} from '../misc/alpha';
3
3
  import {getDegrees, getHexValue, getPercentage} from '../misc/get';
4
4
  import {isHslLike} from '../misc/is';
5
- import type {HSLAColor, HSLColor, HWBAColor, HWBColor, RGBAColor, RGBColor} from '../models';
5
+ import type {
6
+ ColorState,
7
+ ColorType,
8
+ HSLAColor,
9
+ HSLColor,
10
+ HWBAColor,
11
+ HWBColor,
12
+ RGBAColor,
13
+ RGBColor,
14
+ } from '../models';
6
15
  import {convertRgbToHex} from './rgb';
7
16
 
8
17
  // #region Functions
9
18
 
10
19
  function convertHslToHwba(input: unknown): HWBAColor {
11
- const hsl = isHslLike(input) ? getHslValue(input) : {...DEFAULT_HSL};
20
+ const hsl = isHslLike(input) ? getHslValue(input) : {...COLOR_DEFAULTS.hsl};
12
21
 
13
22
  let {hue, lightness, saturation} = hsl;
14
23
 
15
- lightness /= MAX_PERCENT;
16
- saturation /= MAX_PERCENT;
24
+ lightness /= COLOR_MAX.percent;
25
+ saturation /= COLOR_MAX.percent;
17
26
 
18
27
  const value = lightness + saturation * Math.min(lightness, 1 - lightness);
19
28
 
@@ -28,32 +37,53 @@ function convertHslToHwba(input: unknown): HWBAColor {
28
37
 
29
38
  return {
30
39
  hue,
31
- whiteness: whiteness * MAX_PERCENT,
32
- blackness: blackness * MAX_PERCENT,
33
- alpha: getAlphaValue((input as HSLAColor)?.alpha ?? MAX_PERCENT),
40
+ whiteness: whiteness * COLOR_MAX.percent,
41
+ blackness: blackness * COLOR_MAX.percent,
42
+ alpha: getAlphaValue((input as HSLAColor)?.alpha ?? COLOR_MAX.percent),
34
43
  };
35
44
  }
36
45
 
37
46
  function convertHslToRgba(input: unknown): RGBAColor {
38
- const hsl = isHslLike(input) ? getHslValue(input) : {...DEFAULT_HSL};
47
+ const hsl = isHslLike(input) ? getHslValue(input) : {...COLOR_DEFAULTS.hsl};
39
48
 
40
- const hue = hsl.hue % MAX_DEGREE;
41
- const saturation = hsl.saturation / MAX_PERCENT;
42
- const lightness = hsl.lightness / MAX_PERCENT;
49
+ const hue = hsl.hue % COLOR_MAX.degree;
50
+ const saturation = hsl.saturation / COLOR_MAX.percent;
51
+ const lightness = hsl.lightness / COLOR_MAX.percent;
43
52
 
44
53
  return {
45
- alpha: getAlphaValue((input as HSLAColor)?.alpha ?? MAX_PERCENT),
54
+ alpha: getAlphaValue((input as HSLAColor)?.alpha ?? COLOR_MAX.percent),
46
55
  blue: getHexValue(getHexyValue(hue, lightness, saturation, 4)),
47
56
  green: getHexValue(getHexyValue(hue, lightness, saturation, 8)),
48
57
  red: getHexValue(getHexyValue(hue, lightness, saturation, 0)),
49
58
  };
50
59
  }
51
60
 
61
+ export function getColorFromHsl<Type extends ColorType>(
62
+ state: ColorState,
63
+ type: Type,
64
+ ): NonNullable<ColorState[Type]> {
65
+ switch (type) {
66
+ case COLOR_TYPE.hex:
67
+ state.hex = hslToHex(state.hsl!);
68
+ break;
69
+
70
+ case COLOR_TYPE.hwb:
71
+ state.hwb = hslToHwb(state.hsl!);
72
+ break;
73
+
74
+ case COLOR_TYPE.rgb:
75
+ state.rgb = hslToRgb(state.hsl!);
76
+ break;
77
+ }
78
+
79
+ return state[type]!;
80
+ }
81
+
52
82
  function getHexyValue(hue: number, lightness: number, saturation: number, value: number): number {
53
83
  const part = (value + hue / 30) % 12;
54
84
  const mod = saturation * Math.min(lightness, 1 - lightness);
55
85
 
56
- return (lightness - mod * Math.max(-1, Math.min(part - 3, 9 - part, 1))) * MAX_HEX;
86
+ return (lightness - mod * Math.max(-1, Math.min(part - 3, 9 - part, 1))) * COLOR_MAX.hex;
57
87
  }
58
88
 
59
89
  export function getHslValue(value: Record<keyof HSLColor, unknown>): HSLColor {
@@ -1,18 +1,27 @@
1
- import {DEFAULT_HWB, MAX_PERCENT} from '../constants';
1
+ import {COLOR_DEFAULTS, COLOR_MAX, COLOR_TYPE} from '../constants';
2
2
  import {getAlphaValue} from '../misc/alpha';
3
3
  import {getDegrees, getPercentage} from '../misc/get';
4
4
  import {isHwbLike} from '../misc/is';
5
- import type {HSLAColor, HSLColor, HWBAColor, HWBColor, RGBAColor, RGBColor} from '../models';
5
+ import type {
6
+ ColorState,
7
+ ColorType,
8
+ HSLAColor,
9
+ HSLColor,
10
+ HWBAColor,
11
+ HWBColor,
12
+ RGBAColor,
13
+ RGBColor,
14
+ } from '../models';
6
15
  import {hslToRgb, hslToRgba} from './hsl';
7
16
  import {rgbToHex} from './rgb';
8
17
 
9
18
  // #region Functions
10
19
 
11
20
  export function convertHwbToHsl(input: HWBAColor | HWBColor): HSLAColor {
12
- let {blackness, hue, whiteness} = isHwbLike(input) ? getHwbValue(input) : DEFAULT_HWB;
21
+ let {blackness, hue, whiteness} = isHwbLike(input) ? getHwbValue(input) : COLOR_DEFAULTS.hwb;
13
22
 
14
- blackness /= MAX_PERCENT;
15
- whiteness /= MAX_PERCENT;
23
+ blackness /= COLOR_MAX.percent;
24
+ whiteness /= COLOR_MAX.percent;
16
25
 
17
26
  if (blackness + whiteness > 1) {
18
27
  const total = blackness + whiteness;
@@ -27,12 +36,33 @@ export function convertHwbToHsl(input: HWBAColor | HWBColor): HSLAColor {
27
36
 
28
37
  return {
29
38
  hue,
30
- saturation: saturation * MAX_PERCENT,
31
- lightness: lightness * MAX_PERCENT,
32
- alpha: getAlphaValue((input as HWBAColor)?.alpha ?? MAX_PERCENT),
39
+ saturation: saturation * COLOR_MAX.percent,
40
+ lightness: lightness * COLOR_MAX.percent,
41
+ alpha: getAlphaValue((input as HWBAColor)?.alpha ?? COLOR_MAX.percent),
33
42
  };
34
43
  }
35
44
 
45
+ export function getColorFromHwb<Type extends ColorType>(
46
+ state: ColorState,
47
+ type: Type,
48
+ ): NonNullable<ColorState[Type]> {
49
+ switch (type) {
50
+ case COLOR_TYPE.hex:
51
+ state.hex = hwbToHex(state.hwb!);
52
+ break;
53
+
54
+ case COLOR_TYPE.hsl:
55
+ state.hsl = hwbToHsl(state.hwb!);
56
+ break;
57
+
58
+ case COLOR_TYPE.rgb:
59
+ state.rgb = hwbToRgb(state.hwb!);
60
+ break;
61
+ }
62
+
63
+ return state[type]!;
64
+ }
65
+
36
66
  function getHwbSaturation(blackness: number, whiteness: number, lightness: number): number {
37
67
  const value = 1 - blackness;
38
68
 
@@ -1,9 +1,18 @@
1
1
  import {join} from '../../internal/string';
2
- import {DEFAULT_RGB, MAX_HEX, MAX_PERCENT} from '../constants';
2
+ import {COLOR_DEFAULTS, COLOR_MAX, COLOR_TYPE} from '../constants';
3
3
  import {getAlpha, getAlphaValue} from '../misc/alpha';
4
4
  import {getHexValue} from '../misc/get';
5
5
  import {isRgbLike} from '../misc/is';
6
- import type {HSLAColor, HSLColor, HWBAColor, HWBColor, RGBAColor, RGBColor} from '../models';
6
+ import type {
7
+ ColorState,
8
+ ColorType,
9
+ HSLAColor,
10
+ HSLColor,
11
+ HWBAColor,
12
+ HWBColor,
13
+ RGBAColor,
14
+ RGBColor,
15
+ } from '../models';
7
16
 
8
17
  // #region Types
9
18
 
@@ -32,14 +41,14 @@ export function convertRgbToHex(rgb: RGBAColor | RGBColor, alpha: boolean): stri
32
41
  let a = '';
33
42
 
34
43
  if (typeof alpha === 'boolean' && alpha) {
35
- a = getAlpha((rgb as RGBAColor).alpha).hex;
44
+ a = getAlpha((rgb as RGBAColor).alpha, false).hex;
36
45
  }
37
46
 
38
47
  return `${hex}${a}`;
39
48
  }
40
49
 
41
50
  export function convertRgbToHsla(value: unknown): HSLAColor {
42
- const rgb = isRgbLike(value) ? getRgbValue(value) : {...DEFAULT_RGB};
51
+ const rgb = isRgbLike(value) ? getRgbValue(value) : {...COLOR_DEFAULTS.rgb};
43
52
  const values = getRgbValues(rgb);
44
53
 
45
54
  const {delta, max, min} = values;
@@ -59,14 +68,14 @@ export function convertRgbToHsla(value: unknown): HSLAColor {
59
68
 
60
69
  return {
61
70
  hue,
62
- saturation: saturation * MAX_PERCENT,
63
- lightness: lightness * MAX_PERCENT,
64
- alpha: getAlphaValue((value as RGBAColor)?.alpha ?? MAX_PERCENT),
71
+ saturation: saturation * COLOR_MAX.percent,
72
+ lightness: lightness * COLOR_MAX.percent,
73
+ alpha: getAlphaValue((value as RGBAColor)?.alpha ?? COLOR_MAX.percent),
65
74
  };
66
75
  }
67
76
 
68
77
  export function convertRgbToHwba(value: unknown): HWBAColor {
69
- const rgb = isRgbLike(value) ? getRgbValue(value) : {...DEFAULT_RGB};
78
+ const rgb = isRgbLike(value) ? getRgbValue(value) : {...COLOR_DEFAULTS.rgb};
70
79
  const values = getRgbValues(rgb);
71
80
 
72
81
  const {delta, max, min} = values;
@@ -81,12 +90,33 @@ export function convertRgbToHwba(value: unknown): HWBAColor {
81
90
 
82
91
  return {
83
92
  hue,
84
- whiteness: min * MAX_PERCENT,
85
- blackness: (1 - max) * MAX_PERCENT,
86
- alpha: getAlphaValue((value as RGBAColor)?.alpha ?? MAX_PERCENT),
93
+ whiteness: min * COLOR_MAX.percent,
94
+ blackness: (1 - max) * COLOR_MAX.percent,
95
+ alpha: getAlphaValue((value as RGBAColor)?.alpha ?? COLOR_MAX.percent),
87
96
  };
88
97
  }
89
98
 
99
+ export function getColorFromRgb<Type extends ColorType>(
100
+ state: ColorState,
101
+ type: Type,
102
+ ): NonNullable<ColorState[Type]> {
103
+ switch (type) {
104
+ case COLOR_TYPE.hex:
105
+ state.hex = rgbToHex(state.rgb!);
106
+ break;
107
+
108
+ case COLOR_TYPE.hsl:
109
+ state.hsl = rgbToHsl(state.rgb!);
110
+ break;
111
+
112
+ case COLOR_TYPE.hwb:
113
+ state.hwb = rgbToHwb(state.rgb!);
114
+ break;
115
+ }
116
+
117
+ return state[type]!;
118
+ }
119
+
90
120
  function getRgbHue(values: RgbValues): number {
91
121
  const {blue, delta, green, max, red} = values;
92
122
 
@@ -111,9 +141,9 @@ export function getRgbValue(value: Record<keyof RGBColor, unknown>): RGBColor {
111
141
  }
112
142
 
113
143
  function getRgbValues(rgb: RGBColor): RgbValues {
114
- const blue = rgb.blue / MAX_HEX;
115
- const green = rgb.green / MAX_HEX;
116
- const red = rgb.red / MAX_HEX;
144
+ const blue = rgb.blue / COLOR_MAX.hex;
145
+ const green = rgb.green / COLOR_MAX.hex;
146
+ const red = rgb.red / COLOR_MAX.hex;
117
147
 
118
148
  const max = Math.max(blue, green, red);
119
149
  const min = Math.min(blue, green, red);
@@ -133,7 +163,10 @@ function getRgbValues(rgb: RGBColor): RgbValues {
133
163
  * @returns Hex color string
134
164
  */
135
165
  export function rgbToHex(rgb: RGBAColor | RGBColor, alpha?: boolean): string {
136
- return convertRgbToHex(isRgbLike(rgb) ? getRgbValue(rgb) : {...DEFAULT_RGB}, alpha ?? false);
166
+ return convertRgbToHex(
167
+ isRgbLike(rgb) ? getRgbValue(rgb) : {...COLOR_DEFAULTS.rgb},
168
+ alpha ?? false,
169
+ );
137
170
  }
138
171
 
139
172
  /**
package/src/herald.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import {noop} from './internal/function/misc';
2
- import type {GenericCallback} from './models';
2
+ import type {GenericCallback, Unsubscriber} from './models';
3
3
 
4
4
  // #region Types
5
5
 
@@ -57,8 +57,6 @@ export type Herald<Map extends Record<string, GenericCallback>> = {
57
57
  unsubscribe<Event extends keyof Map>(event: Event, callback?: Map[Event]): void;
58
58
  };
59
59
 
60
- export type Unsubscriber = () => void;
61
-
62
60
  // #endregion
63
61
 
64
62
  // #region Functions
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ export * from './herald';
21
21
 
22
22
  export * from './internal/function/misc';
23
23
  export * from './internal/string';
24
+ export {isSubscription, type Subscription} from './internal/subscription';
24
25
  export * from './internal/value/compare';
25
26
  export * from './internal/value/equal';
26
27
  export * from './internal/value/get';