@usertour/helpers 0.0.54 → 0.0.56

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.
@@ -451,17 +451,6 @@ function hexToRgb(hex) {
451
451
  b: Number.parseInt(result[3], 16)
452
452
  } : null;
453
453
  }
454
- var isDark = (hex) => {
455
- const rgb = hexToRgb(hex);
456
- if (!rgb) {
457
- return null;
458
- }
459
- const { r, g, b } = rgb;
460
- if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
461
- return true;
462
- }
463
- return false;
464
- };
465
454
  var evalCode = (code) => {
466
455
  try {
467
456
  return eval(code);
@@ -2,10 +2,10 @@ import {
2
2
  evaluateRulesConditions,
3
3
  filterConditionsByType,
4
4
  isConditionsActived
5
- } from "../chunk-SIG4WTEF.js";
5
+ } from "../chunk-X6R6AH7G.js";
6
6
  import "../chunk-YYIGUZNZ.js";
7
7
  import "../chunk-PAESAL23.js";
8
- import "../chunk-3KG2HTZ3.js";
8
+ import "../chunk-73OREOHT.js";
9
9
  import "../chunk-KYDXF7SU.js";
10
10
  import "../chunk-JQWKLXW6.js";
11
11
  import "../chunk-GFH3VWOC.js";
@@ -61,17 +61,6 @@ function hexToRgb(hex) {
61
61
  b: Number.parseInt(result[3], 16)
62
62
  } : null;
63
63
  }
64
- var isDark = (hex) => {
65
- const rgb = hexToRgb(hex);
66
- if (!rgb) {
67
- return null;
68
- }
69
- const { r, g, b } = rgb;
70
- if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
71
- return true;
72
- }
73
- return false;
74
- };
75
64
  var evalCode = (code) => {
76
65
  try {
77
66
  return eval(code);
@@ -14,12 +14,12 @@ import {
14
14
  isQuestionElement,
15
15
  isRestrictedType,
16
16
  processQuestionElements
17
- } from "../chunk-2TMOS3DN.js";
17
+ } from "../chunk-RQ4UE7ZB.js";
18
18
  import "../chunk-7ODE2AIC.js";
19
- import "../chunk-SIG4WTEF.js";
19
+ import "../chunk-X6R6AH7G.js";
20
20
  import "../chunk-YYIGUZNZ.js";
21
21
  import "../chunk-PAESAL23.js";
22
- import "../chunk-3KG2HTZ3.js";
22
+ import "../chunk-73OREOHT.js";
23
23
  import "../chunk-KYDXF7SU.js";
24
24
  import "../chunk-JQWKLXW6.js";
25
25
  import "../chunk-GFH3VWOC.js";
@@ -31,17 +31,6 @@ function hexToRgb(hex) {
31
31
  b: Number.parseInt(result[3], 16)
32
32
  } : null;
33
33
  }
34
- var isDark = (hex) => {
35
- const rgb = hexToRgb(hex);
36
- if (!rgb) {
37
- return null;
38
- }
39
- const { r, g, b } = rgb;
40
- if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
41
- return true;
42
- }
43
- return false;
44
- };
45
34
  var evalCode = (code) => {
46
35
  try {
47
36
  return eval(code);
@@ -73,7 +62,6 @@ export {
73
62
  absoluteUrl,
74
63
  uuidV4,
75
64
  hexToRgb,
76
- isDark,
77
65
  evalCode,
78
66
  getRandomColor
79
67
  };
@@ -0,0 +1,133 @@
1
+ // src/color.ts
2
+ import chroma from "chroma-js";
3
+ function hexToHSLString(hexColor) {
4
+ try {
5
+ const color = chroma(hexColor);
6
+ const [h, s, l] = color.hsl();
7
+ const hDeg = Math.round(h || 0);
8
+ const sPct = Math.round(s * 100);
9
+ const lPct = Math.round(l * 100);
10
+ return `${hDeg} ${sPct}% ${lPct}%`;
11
+ } catch (error) {
12
+ console.warn(`Failed to convert ${hexColor} to HSL string:`, error);
13
+ return "0 0% 0%";
14
+ }
15
+ }
16
+ var hexToRGBStr = (hex) => {
17
+ try {
18
+ const color = chroma(hex);
19
+ const [r, g, b] = color.rgb();
20
+ return `${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}`;
21
+ } catch (error) {
22
+ console.warn(`Failed to convert ${hex} to RGB string:`, error);
23
+ return "0, 0, 0";
24
+ }
25
+ };
26
+ function hexToRgb(hex) {
27
+ if (!hex)
28
+ return [0, 0, 0];
29
+ if (hex.match(/^#[0-9a-f]{6}$/i)) {
30
+ return [
31
+ Number.parseInt(hex.substring(1, 3), 16),
32
+ Number.parseInt(hex.substring(3, 5), 16),
33
+ Number.parseInt(hex.substring(5, 7), 16)
34
+ ];
35
+ }
36
+ if (hex.match(/^#[0-9a-f]{3}$/i)) {
37
+ return [
38
+ Number.parseInt(hex.substring(1, 2).repeat(2), 16),
39
+ Number.parseInt(hex.substring(2, 3).repeat(2), 16),
40
+ Number.parseInt(hex.substring(3, 4).repeat(2), 16)
41
+ ];
42
+ }
43
+ return [0, 0, 0];
44
+ }
45
+ function rgbToHex([r, g, b]) {
46
+ const rHex = r.toString(16).padStart(2, "0");
47
+ const gHex = g.toString(16).padStart(2, "0");
48
+ const bHex = b.toString(16).padStart(2, "0");
49
+ return `#${rHex}${gHex}${bHex}`;
50
+ }
51
+ function rgbToHsl([r, g, b]) {
52
+ const rNorm = r / 255;
53
+ const gNorm = g / 255;
54
+ const bNorm = b / 255;
55
+ const max = Math.max(rNorm, gNorm, bNorm);
56
+ const min = Math.min(rNorm, gNorm, bNorm);
57
+ const l = (max + min) / 2;
58
+ let h = 0;
59
+ let s = 0;
60
+ if (max !== min) {
61
+ const d = max - min;
62
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
63
+ switch (max) {
64
+ case rNorm:
65
+ h = (gNorm - bNorm) / d + (gNorm < bNorm ? 6 : 0);
66
+ break;
67
+ case gNorm:
68
+ h = (bNorm - rNorm) / d + 2;
69
+ break;
70
+ default:
71
+ h = (rNorm - gNorm) / d + 4;
72
+ break;
73
+ }
74
+ h /= 6;
75
+ }
76
+ return [h, s, l];
77
+ }
78
+ function getLabLuminance([r, g, b]) {
79
+ function linearize(channel) {
80
+ const c = channel / 255;
81
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
82
+ }
83
+ const y = 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b);
84
+ function yToLabL(yVal) {
85
+ return yVal <= 216 / 24389 ? yVal * (24389 / 27) : yVal ** (1 / 3) * 116 - 16;
86
+ }
87
+ return Math.round(yToLabL(y) * 10) / 1e3;
88
+ }
89
+ function invertColor([r, g, b]) {
90
+ return [Math.round(255 - r), Math.round(255 - g), Math.round(255 - b)];
91
+ }
92
+ function mixRgb(color1, color2, ratio) {
93
+ return [
94
+ Math.max(0, Math.min(255, Math.round(color1[0] + (color2[0] - color1[0]) * ratio))),
95
+ Math.max(0, Math.min(255, Math.round(color1[1] + (color2[1] - color1[1]) * ratio))),
96
+ Math.max(0, Math.min(255, Math.round(color1[2] + (color2[2] - color1[2]) * ratio)))
97
+ ];
98
+ }
99
+ function calculateMixRatio(foreground, background) {
100
+ const fgLuminance = getLabLuminance(foreground);
101
+ const bgLuminance = getLabLuminance(background);
102
+ const minRatio = 0.05;
103
+ const baseRatio = (1 - (bgLuminance - fgLuminance)) / 2 * (0.18 - minRatio) + minRatio;
104
+ const luminanceSimilarity = 1 - Math.abs(bgLuminance - fgLuminance);
105
+ const adjustment = ((1 - baseRatio) * luminanceSimilarity) ** 4;
106
+ const finalRatio = baseRatio + adjustment;
107
+ return Math.round(finalRatio * 1e3) / 1e3;
108
+ }
109
+ function generateStateColors(backgroundColor, foregroundColor) {
110
+ const bgRgb = hexToRgb(backgroundColor);
111
+ const fgRgb = hexToRgb(foregroundColor);
112
+ const bgHsl = rgbToHsl(bgRgb);
113
+ const hoverRatio = calculateMixRatio(fgRgb, bgRgb);
114
+ let activeRatio = hoverRatio * 2;
115
+ let activeMixColor = fgRgb;
116
+ const midToneThreshold = 0.2;
117
+ if (bgHsl[2] > midToneThreshold && bgHsl[2] < 1 - midToneThreshold) {
118
+ activeMixColor = invertColor(fgRgb);
119
+ activeRatio = calculateMixRatio(activeMixColor, bgRgb);
120
+ }
121
+ const hoverRgb = mixRgb(bgRgb, fgRgb, hoverRatio);
122
+ const activeRgb = mixRgb(bgRgb, activeMixColor, activeRatio);
123
+ return {
124
+ hover: rgbToHex(hoverRgb),
125
+ active: rgbToHex(activeRgb)
126
+ };
127
+ }
128
+
129
+ export {
130
+ hexToHSLString,
131
+ hexToRGBStr,
132
+ generateStateColors
133
+ };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  regenerateConditionIds
3
- } from "./chunk-SIG4WTEF.js";
3
+ } from "./chunk-X6R6AH7G.js";
4
4
  import {
5
5
  cuid,
6
6
  uuidV4
7
- } from "./chunk-3KG2HTZ3.js";
7
+ } from "./chunk-73OREOHT.js";
8
8
  import {
9
9
  isArray,
10
10
  isEmptyString,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  hexToHSLString,
3
3
  hexToRGBStr
4
- } from "./chunk-XMAPBUWT.js";
4
+ } from "./chunk-FZFHBCB6.js";
5
5
  import {
6
6
  isUndefined
7
7
  } from "./chunk-GFH3VWOC.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-YYIGUZNZ.js";
4
4
  import {
5
5
  cuid
6
- } from "./chunk-3KG2HTZ3.js";
6
+ } from "./chunk-73OREOHT.js";
7
7
  import {
8
8
  evaluateAttributeCondition
9
9
  } from "./chunk-KYDXF7SU.js";
package/dist/color.cjs CHANGED
@@ -30,7 +30,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/color.ts
31
31
  var color_exports = {};
32
32
  __export(color_exports, {
33
- generateAutoStateColors: () => generateAutoStateColors,
34
33
  generateStateColors: () => generateStateColors,
35
34
  hexToHSLString: () => hexToHSLString,
36
35
  hexToRGBStr: () => hexToRGBStr
@@ -60,54 +59,110 @@ var hexToRGBStr = (hex) => {
60
59
  return "0, 0, 0";
61
60
  }
62
61
  };
63
- function generateAutoStateColors(baseColor, brandColor, hoverRatio = 0.12, activeRatio = 0.24) {
64
- const isBaseLight = (0, import_chroma_js.default)(baseColor).luminance() > 0.8;
65
- const isBaseBrand = import_chroma_js.default.distance(baseColor, brandColor) < 10;
66
- let hover;
67
- let active;
68
- if (isBaseBrand) {
69
- hover = import_chroma_js.default.mix(baseColor, "#fff", hoverRatio, "rgb").hex();
70
- active = import_chroma_js.default.mix(baseColor, "#fff", activeRatio, "rgb").hex();
71
- } else if (isBaseLight) {
72
- hover = import_chroma_js.default.mix(baseColor, brandColor, hoverRatio, "rgb").hex();
73
- active = import_chroma_js.default.mix(baseColor, brandColor, activeRatio, "rgb").hex();
74
- } else {
75
- hover = import_chroma_js.default.mix(baseColor, brandColor, hoverRatio, "rgb").hex();
76
- active = import_chroma_js.default.mix(baseColor, brandColor, activeRatio, "rgb").hex();
62
+ function hexToRgb(hex) {
63
+ if (!hex)
64
+ return [0, 0, 0];
65
+ if (hex.match(/^#[0-9a-f]{6}$/i)) {
66
+ return [
67
+ Number.parseInt(hex.substring(1, 3), 16),
68
+ Number.parseInt(hex.substring(3, 5), 16),
69
+ Number.parseInt(hex.substring(5, 7), 16)
70
+ ];
77
71
  }
78
- return { hover, active };
72
+ if (hex.match(/^#[0-9a-f]{3}$/i)) {
73
+ return [
74
+ Number.parseInt(hex.substring(1, 2).repeat(2), 16),
75
+ Number.parseInt(hex.substring(2, 3).repeat(2), 16),
76
+ Number.parseInt(hex.substring(3, 4).repeat(2), 16)
77
+ ];
78
+ }
79
+ return [0, 0, 0];
80
+ }
81
+ function rgbToHex([r, g, b]) {
82
+ const rHex = r.toString(16).padStart(2, "0");
83
+ const gHex = g.toString(16).padStart(2, "0");
84
+ const bHex = b.toString(16).padStart(2, "0");
85
+ return `#${rHex}${gHex}${bHex}`;
86
+ }
87
+ function rgbToHsl([r, g, b]) {
88
+ const rNorm = r / 255;
89
+ const gNorm = g / 255;
90
+ const bNorm = b / 255;
91
+ const max = Math.max(rNorm, gNorm, bNorm);
92
+ const min = Math.min(rNorm, gNorm, bNorm);
93
+ const l = (max + min) / 2;
94
+ let h = 0;
95
+ let s = 0;
96
+ if (max !== min) {
97
+ const d = max - min;
98
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
99
+ switch (max) {
100
+ case rNorm:
101
+ h = (gNorm - bNorm) / d + (gNorm < bNorm ? 6 : 0);
102
+ break;
103
+ case gNorm:
104
+ h = (bNorm - rNorm) / d + 2;
105
+ break;
106
+ default:
107
+ h = (rNorm - gNorm) / d + 4;
108
+ break;
109
+ }
110
+ h /= 6;
111
+ }
112
+ return [h, s, l];
113
+ }
114
+ function getLabLuminance([r, g, b]) {
115
+ function linearize(channel) {
116
+ const c = channel / 255;
117
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
118
+ }
119
+ const y = 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b);
120
+ function yToLabL(yVal) {
121
+ return yVal <= 216 / 24389 ? yVal * (24389 / 27) : yVal ** (1 / 3) * 116 - 16;
122
+ }
123
+ return Math.round(yToLabL(y) * 10) / 1e3;
124
+ }
125
+ function invertColor([r, g, b]) {
126
+ return [Math.round(255 - r), Math.round(255 - g), Math.round(255 - b)];
127
+ }
128
+ function mixRgb(color1, color2, ratio) {
129
+ return [
130
+ Math.max(0, Math.min(255, Math.round(color1[0] + (color2[0] - color1[0]) * ratio))),
131
+ Math.max(0, Math.min(255, Math.round(color1[1] + (color2[1] - color1[1]) * ratio))),
132
+ Math.max(0, Math.min(255, Math.round(color1[2] + (color2[2] - color1[2]) * ratio)))
133
+ ];
134
+ }
135
+ function calculateMixRatio(foreground, background) {
136
+ const fgLuminance = getLabLuminance(foreground);
137
+ const bgLuminance = getLabLuminance(background);
138
+ const minRatio = 0.05;
139
+ const baseRatio = (1 - (bgLuminance - fgLuminance)) / 2 * (0.18 - minRatio) + minRatio;
140
+ const luminanceSimilarity = 1 - Math.abs(bgLuminance - fgLuminance);
141
+ const adjustment = ((1 - baseRatio) * luminanceSimilarity) ** 4;
142
+ const finalRatio = baseRatio + adjustment;
143
+ return Math.round(finalRatio * 1e3) / 1e3;
79
144
  }
80
- function generateStateColors(baseColor, brandColor, options = {}) {
81
- const {
82
- brandHoverRatio = 0.175,
83
- brandActiveRatio = 0.14,
84
- lightHoverRatio = 0.11,
85
- lightActiveRatio = 0.225
86
- } = options;
87
- const baseLuminance = (0, import_chroma_js.default)(baseColor).luminance();
88
- const isBaseLight = baseLuminance > 0.8;
89
- const isBaseDark = baseLuminance < 0.2;
90
- const isBaseBrand = import_chroma_js.default.distance(baseColor, brandColor) < 10;
91
- let hover;
92
- let active;
93
- if (isBaseBrand) {
94
- hover = import_chroma_js.default.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
95
- active = import_chroma_js.default.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
96
- } else if (isBaseLight) {
97
- hover = import_chroma_js.default.mix(baseColor, brandColor, lightHoverRatio, "rgb").hex();
98
- active = import_chroma_js.default.mix(baseColor, brandColor, lightActiveRatio, "rgb").hex();
99
- } else if (isBaseDark) {
100
- hover = import_chroma_js.default.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
101
- active = import_chroma_js.default.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
102
- } else {
103
- hover = import_chroma_js.default.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
104
- active = import_chroma_js.default.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
145
+ function generateStateColors(backgroundColor, foregroundColor) {
146
+ const bgRgb = hexToRgb(backgroundColor);
147
+ const fgRgb = hexToRgb(foregroundColor);
148
+ const bgHsl = rgbToHsl(bgRgb);
149
+ const hoverRatio = calculateMixRatio(fgRgb, bgRgb);
150
+ let activeRatio = hoverRatio * 2;
151
+ let activeMixColor = fgRgb;
152
+ const midToneThreshold = 0.2;
153
+ if (bgHsl[2] > midToneThreshold && bgHsl[2] < 1 - midToneThreshold) {
154
+ activeMixColor = invertColor(fgRgb);
155
+ activeRatio = calculateMixRatio(activeMixColor, bgRgb);
105
156
  }
106
- return { hover, active };
157
+ const hoverRgb = mixRgb(bgRgb, fgRgb, hoverRatio);
158
+ const activeRgb = mixRgb(bgRgb, activeMixColor, activeRatio);
159
+ return {
160
+ hover: rgbToHex(hoverRgb),
161
+ active: rgbToHex(activeRgb)
162
+ };
107
163
  }
108
164
  // Annotate the CommonJS export names for ESM import in node:
109
165
  0 && (module.exports = {
110
- generateAutoStateColors,
111
166
  generateStateColors,
112
167
  hexToHSLString,
113
168
  hexToRGBStr
package/dist/color.d.cts CHANGED
@@ -11,60 +11,42 @@ declare function hexToHSLString(hexColor: string): string;
11
11
  */
12
12
  declare const hexToRGBStr: (hex: string) => string;
13
13
  /**
14
- * Automatically generate hover and active colors based on baseColor and brandColor.
15
- * If baseColor is similar to brandColor, hover is mixed with white (LAB), active is darkened.
16
- * If baseColor is light (e.g., white), hover/active are mixed with brandColor (LAB).
17
- * Otherwise, hover is mixed with brandColor (LAB), active is darkened.
18
- * @param baseColor - The base color (e.g., button or content background)
19
- * @param brandColor - The brand color
20
- * @param hoverRatio - Mix ratio for hover state (default 0.15)
21
- * @param activeDarken - Darken factor for active state (default 0.12)
22
- * @returns An object with hover and active color hex strings
23
- * @deprecated Use generateStateColors instead
24
- */
25
- declare function generateAutoStateColors(baseColor: string, brandColor: string, hoverRatio?: number, activeRatio?: number): {
26
- hover: string;
27
- active: string;
28
- };
29
- /**
30
- * Configuration options for state color generation
31
- */
32
- interface StateColorOptions {
33
- /** Mix ratio for hover state when base is brand color (default 0.175) */
34
- brandHoverRatio?: number;
35
- /** Mix ratio for active/click state when base is brand color (default 0.14) */
36
- brandActiveRatio?: number;
37
- /** Mix ratio for hover state when base is light color (default 0.11) */
38
- lightHoverRatio?: number;
39
- /** Mix ratio for active/click state when base is light color (default 0.225) */
40
- lightActiveRatio?: number;
41
- }
42
- /**
43
- * Generate hover and active state colors based on base color and brand color.
14
+ * Generate hover and active state colors based on background and foreground colors.
44
15
  *
45
- * Logic:
46
- * - Brand color base: hover = tint (mix with white), active = shade (mix with black)
47
- * - Light color base (e.g., white): hover/active = mix with brand color
48
- * - Dark color base: hover = tint (mix with white), active = shade (mix with black)
16
+ * Algorithm:
17
+ * 1. Calculate dynamic mix ratio based on Lab luminance difference
18
+ * 2. Hover = background mixed with foreground at calculated ratio
19
+ * 3. Active = background mixed with foreground (or its inverse) at 2x ratio
20
+ * 4. For mid-tone backgrounds (lightness 0.2-0.8), active uses inverted foreground
21
+ * to create more distinct visual feedback
49
22
  *
50
- * @param baseColor - The base background color
51
- * @param brandColor - The brand/primary color
52
- * @param options - Optional configuration for mix ratios
23
+ * @param backgroundColor - The base background color (hex)
24
+ * @param foregroundColor - The foreground/brand color to mix with (hex)
53
25
  * @returns Object containing hover and active color hex strings
54
26
  *
55
27
  * @example
56
- * // Brand color button
57
- * generateStateColors('#2563eb', '#2563eb');
58
- * // Returns: { hover: '#4b7eee', active: '#2055c9' }
28
+ * // Brand color button (green on green)
29
+ * generateStateColors('#65a30d', '#f8fafc');
30
+ * // Returns: { hover: '#86b643', active: '#5c940c' }
31
+ *
32
+ * @example
33
+ * // White background with blue brand
34
+ * generateStateColors('#ffffff', '#155eef');
35
+ * // Returns: { hover: '#e6eefd', active: '#ccdcfc' }
36
+ *
37
+ * @example
38
+ * // Pink background with green brand
39
+ * generateStateColors('#fecaca', '#65a30d');
40
+ * // Returns: { hover: '#cfbe90', active: '#a0b256' }
59
41
  *
60
42
  * @example
61
- * // White background content
62
- * generateStateColors('#ffffff', '#2563eb');
63
- * // Returns: { hover: '#e7eefd', active: '#cedcfb' }
43
+ * // Green background with green brand (uses inverse for active)
44
+ * generateStateColors('#4ade80', '#65a30d');
45
+ * // Returns: { hover: '#55c753', active: '#61b8a1' }
64
46
  */
65
- declare function generateStateColors(baseColor: string, brandColor: string, options?: StateColorOptions): {
47
+ declare function generateStateColors(backgroundColor: string, foregroundColor: string): {
66
48
  hover: string;
67
49
  active: string;
68
50
  };
69
51
 
70
- export { type StateColorOptions, generateAutoStateColors, generateStateColors, hexToHSLString, hexToRGBStr };
52
+ export { generateStateColors, hexToHSLString, hexToRGBStr };
package/dist/color.d.ts CHANGED
@@ -11,60 +11,42 @@ declare function hexToHSLString(hexColor: string): string;
11
11
  */
12
12
  declare const hexToRGBStr: (hex: string) => string;
13
13
  /**
14
- * Automatically generate hover and active colors based on baseColor and brandColor.
15
- * If baseColor is similar to brandColor, hover is mixed with white (LAB), active is darkened.
16
- * If baseColor is light (e.g., white), hover/active are mixed with brandColor (LAB).
17
- * Otherwise, hover is mixed with brandColor (LAB), active is darkened.
18
- * @param baseColor - The base color (e.g., button or content background)
19
- * @param brandColor - The brand color
20
- * @param hoverRatio - Mix ratio for hover state (default 0.15)
21
- * @param activeDarken - Darken factor for active state (default 0.12)
22
- * @returns An object with hover and active color hex strings
23
- * @deprecated Use generateStateColors instead
24
- */
25
- declare function generateAutoStateColors(baseColor: string, brandColor: string, hoverRatio?: number, activeRatio?: number): {
26
- hover: string;
27
- active: string;
28
- };
29
- /**
30
- * Configuration options for state color generation
31
- */
32
- interface StateColorOptions {
33
- /** Mix ratio for hover state when base is brand color (default 0.175) */
34
- brandHoverRatio?: number;
35
- /** Mix ratio for active/click state when base is brand color (default 0.14) */
36
- brandActiveRatio?: number;
37
- /** Mix ratio for hover state when base is light color (default 0.11) */
38
- lightHoverRatio?: number;
39
- /** Mix ratio for active/click state when base is light color (default 0.225) */
40
- lightActiveRatio?: number;
41
- }
42
- /**
43
- * Generate hover and active state colors based on base color and brand color.
14
+ * Generate hover and active state colors based on background and foreground colors.
44
15
  *
45
- * Logic:
46
- * - Brand color base: hover = tint (mix with white), active = shade (mix with black)
47
- * - Light color base (e.g., white): hover/active = mix with brand color
48
- * - Dark color base: hover = tint (mix with white), active = shade (mix with black)
16
+ * Algorithm:
17
+ * 1. Calculate dynamic mix ratio based on Lab luminance difference
18
+ * 2. Hover = background mixed with foreground at calculated ratio
19
+ * 3. Active = background mixed with foreground (or its inverse) at 2x ratio
20
+ * 4. For mid-tone backgrounds (lightness 0.2-0.8), active uses inverted foreground
21
+ * to create more distinct visual feedback
49
22
  *
50
- * @param baseColor - The base background color
51
- * @param brandColor - The brand/primary color
52
- * @param options - Optional configuration for mix ratios
23
+ * @param backgroundColor - The base background color (hex)
24
+ * @param foregroundColor - The foreground/brand color to mix with (hex)
53
25
  * @returns Object containing hover and active color hex strings
54
26
  *
55
27
  * @example
56
- * // Brand color button
57
- * generateStateColors('#2563eb', '#2563eb');
58
- * // Returns: { hover: '#4b7eee', active: '#2055c9' }
28
+ * // Brand color button (green on green)
29
+ * generateStateColors('#65a30d', '#f8fafc');
30
+ * // Returns: { hover: '#86b643', active: '#5c940c' }
31
+ *
32
+ * @example
33
+ * // White background with blue brand
34
+ * generateStateColors('#ffffff', '#155eef');
35
+ * // Returns: { hover: '#e6eefd', active: '#ccdcfc' }
36
+ *
37
+ * @example
38
+ * // Pink background with green brand
39
+ * generateStateColors('#fecaca', '#65a30d');
40
+ * // Returns: { hover: '#cfbe90', active: '#a0b256' }
59
41
  *
60
42
  * @example
61
- * // White background content
62
- * generateStateColors('#ffffff', '#2563eb');
63
- * // Returns: { hover: '#e7eefd', active: '#cedcfb' }
43
+ * // Green background with green brand (uses inverse for active)
44
+ * generateStateColors('#4ade80', '#65a30d');
45
+ * // Returns: { hover: '#55c753', active: '#61b8a1' }
64
46
  */
65
- declare function generateStateColors(baseColor: string, brandColor: string, options?: StateColorOptions): {
47
+ declare function generateStateColors(backgroundColor: string, foregroundColor: string): {
66
48
  hover: string;
67
49
  active: string;
68
50
  };
69
51
 
70
- export { type StateColorOptions, generateAutoStateColors, generateStateColors, hexToHSLString, hexToRGBStr };
52
+ export { generateStateColors, hexToHSLString, hexToRGBStr };
package/dist/color.js CHANGED
@@ -1,12 +1,10 @@
1
1
  import {
2
- generateAutoStateColors,
3
2
  generateStateColors,
4
3
  hexToHSLString,
5
4
  hexToRGBStr
6
- } from "./chunk-XMAPBUWT.js";
5
+ } from "./chunk-FZFHBCB6.js";
7
6
  import "./chunk-XEO3YXBM.js";
8
7
  export {
9
- generateAutoStateColors,
10
8
  generateStateColors,
11
9
  hexToHSLString,
12
10
  hexToRGBStr
@@ -466,17 +466,6 @@ function hexToRgb(hex) {
466
466
  b: Number.parseInt(result[3], 16)
467
467
  } : null;
468
468
  }
469
- var isDark = (hex) => {
470
- const rgb = hexToRgb(hex);
471
- if (!rgb) {
472
- return null;
473
- }
474
- const { r, g, b } = rgb;
475
- if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
476
- return true;
477
- }
478
- return false;
479
- };
480
469
  var evalCode = (code) => {
481
470
  try {
482
471
  return eval(code);
@@ -8,10 +8,10 @@ import {
8
8
  isConditionsActived,
9
9
  isEqual,
10
10
  regenerateConditionIds
11
- } from "../chunk-SIG4WTEF.js";
11
+ } from "../chunk-X6R6AH7G.js";
12
12
  import "../chunk-YYIGUZNZ.js";
13
13
  import "../chunk-PAESAL23.js";
14
- import "../chunk-3KG2HTZ3.js";
14
+ import "../chunk-73OREOHT.js";
15
15
  import "../chunk-KYDXF7SU.js";
16
16
  import "../chunk-JQWKLXW6.js";
17
17
  import "../chunk-GFH3VWOC.js";
@@ -511,17 +511,6 @@ function hexToRgb(hex) {
511
511
  b: Number.parseInt(result[3], 16)
512
512
  } : null;
513
513
  }
514
- var isDark = (hex) => {
515
- const rgb = hexToRgb(hex);
516
- if (!rgb) {
517
- return null;
518
- }
519
- const { r, g, b } = rgb;
520
- if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
521
- return true;
522
- }
523
- return false;
524
- };
525
514
  var evalCode = (code) => {
526
515
  try {
527
516
  return eval(code);
@@ -9,13 +9,13 @@ import {
9
9
  isConditionsActived,
10
10
  isEqual,
11
11
  regenerateConditionIds
12
- } from "../chunk-SIG4WTEF.js";
12
+ } from "../chunk-X6R6AH7G.js";
13
13
  import {
14
14
  evaluateUrlCondition,
15
15
  isMatchUrlPattern
16
16
  } from "../chunk-YYIGUZNZ.js";
17
17
  import "../chunk-PAESAL23.js";
18
- import "../chunk-3KG2HTZ3.js";
18
+ import "../chunk-73OREOHT.js";
19
19
  import {
20
20
  evaluateAttributeCondition
21
21
  } from "../chunk-KYDXF7SU.js";
@@ -82,17 +82,6 @@ function hexToRgb(hex) {
82
82
  b: Number.parseInt(result[3], 16)
83
83
  } : null;
84
84
  }
85
- var isDark = (hex) => {
86
- const rgb = hexToRgb(hex);
87
- if (!rgb) {
88
- return null;
89
- }
90
- const { r, g, b } = rgb;
91
- if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
92
- return true;
93
- }
94
- return false;
95
- };
96
85
  var evalCode = (code) => {
97
86
  try {
98
87
  return eval(code);
@@ -14,12 +14,12 @@ import {
14
14
  isQuestionElement,
15
15
  isRestrictedType,
16
16
  processQuestionElements
17
- } from "./chunk-2TMOS3DN.js";
17
+ } from "./chunk-RQ4UE7ZB.js";
18
18
  import "./chunk-7ODE2AIC.js";
19
- import "./chunk-SIG4WTEF.js";
19
+ import "./chunk-X6R6AH7G.js";
20
20
  import "./chunk-YYIGUZNZ.js";
21
21
  import "./chunk-PAESAL23.js";
22
- import "./chunk-3KG2HTZ3.js";
22
+ import "./chunk-73OREOHT.js";
23
23
  import "./chunk-KYDXF7SU.js";
24
24
  import "./chunk-JQWKLXW6.js";
25
25
  import "./chunk-GFH3VWOC.js";
@@ -2,8 +2,8 @@ import {
2
2
  convertSettings,
3
3
  convertToCssVars,
4
4
  mergeThemeDefaultSettings
5
- } from "./chunk-G73OLXRF.js";
6
- import "./chunk-XMAPBUWT.js";
5
+ } from "./chunk-SR6B3UAJ.js";
6
+ import "./chunk-FZFHBCB6.js";
7
7
  import "./chunk-GFH3VWOC.js";
8
8
  import "./chunk-XEO3YXBM.js";
9
9
  export {
package/dist/helper.cjs CHANGED
@@ -27,7 +27,6 @@ __export(helper_exports, {
27
27
  formatDate: () => formatDate,
28
28
  getRandomColor: () => getRandomColor,
29
29
  hexToRgb: () => hexToRgb,
30
- isDark: () => isDark,
31
30
  uuidV4: () => uuidV4
32
31
  });
33
32
  module.exports = __toCommonJS(helper_exports);
@@ -63,17 +62,6 @@ function hexToRgb(hex) {
63
62
  b: Number.parseInt(result[3], 16)
64
63
  } : null;
65
64
  }
66
- var isDark = (hex) => {
67
- const rgb = hexToRgb(hex);
68
- if (!rgb) {
69
- return null;
70
- }
71
- const { r, g, b } = rgb;
72
- if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
73
- return true;
74
- }
75
- return false;
76
- };
77
65
  var evalCode = (code) => {
78
66
  try {
79
67
  return eval(code);
@@ -106,6 +94,5 @@ var getRandomColor = () => {
106
94
  formatDate,
107
95
  getRandomColor,
108
96
  hexToRgb,
109
- isDark,
110
97
  uuidV4
111
98
  });
package/dist/helper.d.cts CHANGED
@@ -10,8 +10,7 @@ declare function hexToRgb(hex: string): {
10
10
  g: number;
11
11
  b: number;
12
12
  } | null;
13
- declare const isDark: (hex: string) => boolean | null;
14
13
  declare const evalCode: (code: string) => any;
15
14
  declare const getRandomColor: () => string;
16
15
 
17
- export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, isDark, uuidV4 };
16
+ export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, uuidV4 };
package/dist/helper.d.ts CHANGED
@@ -10,8 +10,7 @@ declare function hexToRgb(hex: string): {
10
10
  g: number;
11
11
  b: number;
12
12
  } | null;
13
- declare const isDark: (hex: string) => boolean | null;
14
13
  declare const evalCode: (code: string) => any;
15
14
  declare const getRandomColor: () => string;
16
15
 
17
- export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, isDark, uuidV4 };
16
+ export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, uuidV4 };
package/dist/helper.js CHANGED
@@ -6,9 +6,8 @@ import {
6
6
  formatDate,
7
7
  getRandomColor,
8
8
  hexToRgb,
9
- isDark,
10
9
  uuidV4
11
- } from "./chunk-3KG2HTZ3.js";
10
+ } from "./chunk-73OREOHT.js";
12
11
  import "./chunk-XEO3YXBM.js";
13
12
  export {
14
13
  absoluteUrl,
@@ -18,6 +17,5 @@ export {
18
17
  formatDate,
19
18
  getRandomColor,
20
19
  hexToRgb,
21
- isDark,
22
20
  uuidV4
23
21
  };
package/dist/index.cjs CHANGED
@@ -73,7 +73,6 @@ __export(src_exports, {
73
73
  filterConditionsByType: () => filterConditionsByType,
74
74
  filterNullAttributes: () => filterNullAttributes,
75
75
  formatDate: () => formatDate,
76
- generateAutoStateColors: () => generateAutoStateColors,
77
76
  generateStateColors: () => generateStateColors,
78
77
  generateUniqueCopyName: () => generateUniqueCopyName,
79
78
  getAttributeType: () => getAttributeType,
@@ -97,12 +96,11 @@ __export(src_exports, {
97
96
  hasMissingRequiredData: () => hasMissingRequiredData,
98
97
  hexToHSLString: () => hexToHSLString,
99
98
  hexToRGBStr: () => hexToRGBStr,
100
- hexToRgb: () => hexToRgb,
99
+ hexToRgb: () => hexToRgb2,
101
100
  isArray: () => isArray,
102
101
  isBoolean: () => isBoolean,
103
102
  isClickableElement: () => isClickableElement,
104
103
  isConditionsActived: () => isConditionsActived,
105
- isDark: () => isDark,
106
104
  isDate: () => isDate,
107
105
  isDocument: () => isDocument,
108
106
  isEmptyObject: () => isEmptyObject,
@@ -177,50 +175,107 @@ var hexToRGBStr = (hex) => {
177
175
  return "0, 0, 0";
178
176
  }
179
177
  };
180
- function generateAutoStateColors(baseColor, brandColor, hoverRatio = 0.12, activeRatio = 0.24) {
181
- const isBaseLight = (0, import_chroma_js.default)(baseColor).luminance() > 0.8;
182
- const isBaseBrand = import_chroma_js.default.distance(baseColor, brandColor) < 10;
183
- let hover;
184
- let active;
185
- if (isBaseBrand) {
186
- hover = import_chroma_js.default.mix(baseColor, "#fff", hoverRatio, "rgb").hex();
187
- active = import_chroma_js.default.mix(baseColor, "#fff", activeRatio, "rgb").hex();
188
- } else if (isBaseLight) {
189
- hover = import_chroma_js.default.mix(baseColor, brandColor, hoverRatio, "rgb").hex();
190
- active = import_chroma_js.default.mix(baseColor, brandColor, activeRatio, "rgb").hex();
191
- } else {
192
- hover = import_chroma_js.default.mix(baseColor, brandColor, hoverRatio, "rgb").hex();
193
- active = import_chroma_js.default.mix(baseColor, brandColor, activeRatio, "rgb").hex();
178
+ function hexToRgb(hex) {
179
+ if (!hex)
180
+ return [0, 0, 0];
181
+ if (hex.match(/^#[0-9a-f]{6}$/i)) {
182
+ return [
183
+ Number.parseInt(hex.substring(1, 3), 16),
184
+ Number.parseInt(hex.substring(3, 5), 16),
185
+ Number.parseInt(hex.substring(5, 7), 16)
186
+ ];
187
+ }
188
+ if (hex.match(/^#[0-9a-f]{3}$/i)) {
189
+ return [
190
+ Number.parseInt(hex.substring(1, 2).repeat(2), 16),
191
+ Number.parseInt(hex.substring(2, 3).repeat(2), 16),
192
+ Number.parseInt(hex.substring(3, 4).repeat(2), 16)
193
+ ];
194
+ }
195
+ return [0, 0, 0];
196
+ }
197
+ function rgbToHex([r, g, b]) {
198
+ const rHex = r.toString(16).padStart(2, "0");
199
+ const gHex = g.toString(16).padStart(2, "0");
200
+ const bHex = b.toString(16).padStart(2, "0");
201
+ return `#${rHex}${gHex}${bHex}`;
202
+ }
203
+ function rgbToHsl([r, g, b]) {
204
+ const rNorm = r / 255;
205
+ const gNorm = g / 255;
206
+ const bNorm = b / 255;
207
+ const max = Math.max(rNorm, gNorm, bNorm);
208
+ const min = Math.min(rNorm, gNorm, bNorm);
209
+ const l = (max + min) / 2;
210
+ let h = 0;
211
+ let s = 0;
212
+ if (max !== min) {
213
+ const d = max - min;
214
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
215
+ switch (max) {
216
+ case rNorm:
217
+ h = (gNorm - bNorm) / d + (gNorm < bNorm ? 6 : 0);
218
+ break;
219
+ case gNorm:
220
+ h = (bNorm - rNorm) / d + 2;
221
+ break;
222
+ default:
223
+ h = (rNorm - gNorm) / d + 4;
224
+ break;
225
+ }
226
+ h /= 6;
194
227
  }
195
- return { hover, active };
228
+ return [h, s, l];
196
229
  }
197
- function generateStateColors(baseColor, brandColor, options = {}) {
198
- const {
199
- brandHoverRatio = 0.175,
200
- brandActiveRatio = 0.14,
201
- lightHoverRatio = 0.11,
202
- lightActiveRatio = 0.225
203
- } = options;
204
- const baseLuminance = (0, import_chroma_js.default)(baseColor).luminance();
205
- const isBaseLight = baseLuminance > 0.8;
206
- const isBaseDark = baseLuminance < 0.2;
207
- const isBaseBrand = import_chroma_js.default.distance(baseColor, brandColor) < 10;
208
- let hover;
209
- let active;
210
- if (isBaseBrand) {
211
- hover = import_chroma_js.default.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
212
- active = import_chroma_js.default.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
213
- } else if (isBaseLight) {
214
- hover = import_chroma_js.default.mix(baseColor, brandColor, lightHoverRatio, "rgb").hex();
215
- active = import_chroma_js.default.mix(baseColor, brandColor, lightActiveRatio, "rgb").hex();
216
- } else if (isBaseDark) {
217
- hover = import_chroma_js.default.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
218
- active = import_chroma_js.default.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
219
- } else {
220
- hover = import_chroma_js.default.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
221
- active = import_chroma_js.default.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
230
+ function getLabLuminance([r, g, b]) {
231
+ function linearize(channel) {
232
+ const c = channel / 255;
233
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
222
234
  }
223
- return { hover, active };
235
+ const y = 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b);
236
+ function yToLabL(yVal) {
237
+ return yVal <= 216 / 24389 ? yVal * (24389 / 27) : yVal ** (1 / 3) * 116 - 16;
238
+ }
239
+ return Math.round(yToLabL(y) * 10) / 1e3;
240
+ }
241
+ function invertColor([r, g, b]) {
242
+ return [Math.round(255 - r), Math.round(255 - g), Math.round(255 - b)];
243
+ }
244
+ function mixRgb(color1, color2, ratio) {
245
+ return [
246
+ Math.max(0, Math.min(255, Math.round(color1[0] + (color2[0] - color1[0]) * ratio))),
247
+ Math.max(0, Math.min(255, Math.round(color1[1] + (color2[1] - color1[1]) * ratio))),
248
+ Math.max(0, Math.min(255, Math.round(color1[2] + (color2[2] - color1[2]) * ratio)))
249
+ ];
250
+ }
251
+ function calculateMixRatio(foreground, background) {
252
+ const fgLuminance = getLabLuminance(foreground);
253
+ const bgLuminance = getLabLuminance(background);
254
+ const minRatio = 0.05;
255
+ const baseRatio = (1 - (bgLuminance - fgLuminance)) / 2 * (0.18 - minRatio) + minRatio;
256
+ const luminanceSimilarity = 1 - Math.abs(bgLuminance - fgLuminance);
257
+ const adjustment = ((1 - baseRatio) * luminanceSimilarity) ** 4;
258
+ const finalRatio = baseRatio + adjustment;
259
+ return Math.round(finalRatio * 1e3) / 1e3;
260
+ }
261
+ function generateStateColors(backgroundColor, foregroundColor) {
262
+ const bgRgb = hexToRgb(backgroundColor);
263
+ const fgRgb = hexToRgb(foregroundColor);
264
+ const bgHsl = rgbToHsl(bgRgb);
265
+ const hoverRatio = calculateMixRatio(fgRgb, bgRgb);
266
+ let activeRatio = hoverRatio * 2;
267
+ let activeMixColor = fgRgb;
268
+ const midToneThreshold = 0.2;
269
+ if (bgHsl[2] > midToneThreshold && bgHsl[2] < 1 - midToneThreshold) {
270
+ activeMixColor = invertColor(fgRgb);
271
+ activeRatio = calculateMixRatio(activeMixColor, bgRgb);
272
+ }
273
+ const hoverRgb = mixRgb(bgRgb, fgRgb, hoverRatio);
274
+ const activeRgb = mixRgb(bgRgb, activeMixColor, activeRatio);
275
+ return {
276
+ hover: rgbToHex(hoverRgb),
277
+ active: rgbToHex(activeRgb)
278
+ };
224
279
  }
225
280
 
226
281
  // src/convert-settings.ts
@@ -1250,7 +1305,7 @@ function absoluteUrl(path) {
1250
1305
  var uuidV4 = () => {
1251
1306
  return (0, import_uuid.v4)();
1252
1307
  };
1253
- function hexToRgb(hex) {
1308
+ function hexToRgb2(hex) {
1254
1309
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
1255
1310
  return result ? {
1256
1311
  r: Number.parseInt(result[1], 16),
@@ -1258,17 +1313,6 @@ function hexToRgb(hex) {
1258
1313
  b: Number.parseInt(result[3], 16)
1259
1314
  } : null;
1260
1315
  }
1261
- var isDark = (hex) => {
1262
- const rgb = hexToRgb(hex);
1263
- if (!rgb) {
1264
- return null;
1265
- }
1266
- const { r, g, b } = rgb;
1267
- if (r * 0.299 + g * 0.587 + b * 0.114 > 186) {
1268
- return true;
1269
- }
1270
- return false;
1271
- };
1272
1316
  var evalCode = (code) => {
1273
1317
  try {
1274
1318
  return eval(code);
@@ -1979,7 +2023,6 @@ var duplicateStep = (step) => {
1979
2023
  filterConditionsByType,
1980
2024
  filterNullAttributes,
1981
2025
  formatDate,
1982
- generateAutoStateColors,
1983
2026
  generateStateColors,
1984
2027
  generateUniqueCopyName,
1985
2028
  getAttributeType,
@@ -2008,7 +2051,6 @@ var duplicateStep = (step) => {
2008
2051
  isBoolean,
2009
2052
  isClickableElement,
2010
2053
  isConditionsActived,
2011
- isDark,
2012
2054
  isDate,
2013
2055
  isDocument,
2014
2056
  isEmptyObject,
package/dist/index.d.cts CHANGED
@@ -7,8 +7,8 @@ export { isUrl } from './is-url.cjs';
7
7
  export { AbortController, ArrayProto, XMLHttpRequest, assignableWindow, document, fetch, location, nativeForEach, nativeIndexOf, navigator, userAgent, window } from './globals.cjs';
8
8
  export { buildConfig, defaultContentConfig, extractLinkUrl, isPublishedAtLeastOneEnvironment, isPublishedInAllEnvironments, replaceUserAttr } from './content.cjs';
9
9
  export { deepClone, parseUrlParams, wait } from './utils.cjs';
10
- export { StateColorOptions, generateAutoStateColors, generateStateColors, hexToHSLString, hexToRGBStr } from './color.cjs';
11
- export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, isDark, uuidV4 } from './helper.cjs';
10
+ export { generateStateColors, hexToHSLString, hexToRGBStr } from './color.cjs';
11
+ export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, uuidV4 } from './helper.cjs';
12
12
  export { allConditionsHaveIds, assignConditionIds, conditionsIsSame, evaluateRule, evaluateRulesConditions, filterConditionsByType, isConditionsActived, regenerateConditionIds } from './conditions/condition.cjs';
13
13
  export { evaluateUrlCondition, isMatchUrlPattern } from './conditions/url.cjs';
14
14
  export { convertTimeConditionLegacyToV2, evaluateTimeCondition, isTimeConditionDataLegacy, isTimeConditionDataV2, normalizeTimeConditionData } from './conditions/time.cjs';
package/dist/index.d.ts CHANGED
@@ -7,8 +7,8 @@ export { isUrl } from './is-url.js';
7
7
  export { AbortController, ArrayProto, XMLHttpRequest, assignableWindow, document, fetch, location, nativeForEach, nativeIndexOf, navigator, userAgent, window } from './globals.js';
8
8
  export { buildConfig, defaultContentConfig, extractLinkUrl, isPublishedAtLeastOneEnvironment, isPublishedInAllEnvironments, replaceUserAttr } from './content.js';
9
9
  export { deepClone, parseUrlParams, wait } from './utils.js';
10
- export { StateColorOptions, generateAutoStateColors, generateStateColors, hexToHSLString, hexToRGBStr } from './color.js';
11
- export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, isDark, uuidV4 } from './helper.js';
10
+ export { generateStateColors, hexToHSLString, hexToRGBStr } from './color.js';
11
+ export { absoluteUrl, cn, cuid, evalCode, formatDate, getRandomColor, hexToRgb, uuidV4 } from './helper.js';
12
12
  export { allConditionsHaveIds, assignConditionIds, conditionsIsSame, evaluateRule, evaluateRulesConditions, filterConditionsByType, isConditionsActived, regenerateConditionIds } from './conditions/condition.js';
13
13
  export { evaluateUrlCondition, isMatchUrlPattern } from './conditions/url.js';
14
14
  export { convertTimeConditionLegacyToV2, evaluateTimeCondition, isTimeConditionDataLegacy, isTimeConditionDataV2, normalizeTimeConditionData } from './conditions/time.js';
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ import {
38
38
  isQuestionElement,
39
39
  isRestrictedType,
40
40
  processQuestionElements
41
- } from "./chunk-2TMOS3DN.js";
41
+ } from "./chunk-RQ4UE7ZB.js";
42
42
  import "./chunk-7ODE2AIC.js";
43
43
  import {
44
44
  allConditionsHaveIds,
@@ -50,7 +50,7 @@ import {
50
50
  isConditionsActived,
51
51
  isEqual,
52
52
  regenerateConditionIds
53
- } from "./chunk-SIG4WTEF.js";
53
+ } from "./chunk-X6R6AH7G.js";
54
54
  import {
55
55
  evaluateUrlCondition,
56
56
  isMatchUrlPattern
@@ -64,9 +64,8 @@ import {
64
64
  formatDate,
65
65
  getRandomColor,
66
66
  hexToRgb,
67
- isDark,
68
67
  uuidV4
69
- } from "./chunk-3KG2HTZ3.js";
68
+ } from "./chunk-73OREOHT.js";
70
69
  import {
71
70
  evaluateAttributeCondition
72
71
  } from "./chunk-KYDXF7SU.js";
@@ -82,13 +81,12 @@ import {
82
81
  convertSettings,
83
82
  convertToCssVars,
84
83
  mergeThemeDefaultSettings
85
- } from "./chunk-G73OLXRF.js";
84
+ } from "./chunk-SR6B3UAJ.js";
86
85
  import {
87
- generateAutoStateColors,
88
86
  generateStateColors,
89
87
  hexToHSLString,
90
88
  hexToRGBStr
91
- } from "./chunk-XMAPBUWT.js";
89
+ } from "./chunk-FZFHBCB6.js";
92
90
  import {
93
91
  getCodeError,
94
92
  getContentError,
@@ -186,7 +184,6 @@ export {
186
184
  filterConditionsByType,
187
185
  filterNullAttributes,
188
186
  formatDate,
189
- generateAutoStateColors,
190
187
  generateStateColors,
191
188
  generateUniqueCopyName,
192
189
  getAttributeType,
@@ -215,7 +212,6 @@ export {
215
212
  isBoolean,
216
213
  isClickableElement,
217
214
  isConditionsActived,
218
- isDark,
219
215
  isDate,
220
216
  isDocument,
221
217
  isEmptyObject,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usertour/helpers",
3
- "version": "0.0.54",
3
+ "version": "0.0.56",
4
4
  "type": "module",
5
5
  "description": "Utility functions and helpers shared across the UserTour project",
6
6
  "homepage": "https://www.usertour.io",
@@ -1,77 +0,0 @@
1
- // src/color.ts
2
- import chroma from "chroma-js";
3
- function hexToHSLString(hexColor) {
4
- try {
5
- const color = chroma(hexColor);
6
- const [h, s, l] = color.hsl();
7
- const hDeg = Math.round(h || 0);
8
- const sPct = Math.round(s * 100);
9
- const lPct = Math.round(l * 100);
10
- return `${hDeg} ${sPct}% ${lPct}%`;
11
- } catch (error) {
12
- console.warn(`Failed to convert ${hexColor} to HSL string:`, error);
13
- return "0 0% 0%";
14
- }
15
- }
16
- var hexToRGBStr = (hex) => {
17
- try {
18
- const color = chroma(hex);
19
- const [r, g, b] = color.rgb();
20
- return `${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}`;
21
- } catch (error) {
22
- console.warn(`Failed to convert ${hex} to RGB string:`, error);
23
- return "0, 0, 0";
24
- }
25
- };
26
- function generateAutoStateColors(baseColor, brandColor, hoverRatio = 0.12, activeRatio = 0.24) {
27
- const isBaseLight = chroma(baseColor).luminance() > 0.8;
28
- const isBaseBrand = chroma.distance(baseColor, brandColor) < 10;
29
- let hover;
30
- let active;
31
- if (isBaseBrand) {
32
- hover = chroma.mix(baseColor, "#fff", hoverRatio, "rgb").hex();
33
- active = chroma.mix(baseColor, "#fff", activeRatio, "rgb").hex();
34
- } else if (isBaseLight) {
35
- hover = chroma.mix(baseColor, brandColor, hoverRatio, "rgb").hex();
36
- active = chroma.mix(baseColor, brandColor, activeRatio, "rgb").hex();
37
- } else {
38
- hover = chroma.mix(baseColor, brandColor, hoverRatio, "rgb").hex();
39
- active = chroma.mix(baseColor, brandColor, activeRatio, "rgb").hex();
40
- }
41
- return { hover, active };
42
- }
43
- function generateStateColors(baseColor, brandColor, options = {}) {
44
- const {
45
- brandHoverRatio = 0.175,
46
- brandActiveRatio = 0.14,
47
- lightHoverRatio = 0.11,
48
- lightActiveRatio = 0.225
49
- } = options;
50
- const baseLuminance = chroma(baseColor).luminance();
51
- const isBaseLight = baseLuminance > 0.8;
52
- const isBaseDark = baseLuminance < 0.2;
53
- const isBaseBrand = chroma.distance(baseColor, brandColor) < 10;
54
- let hover;
55
- let active;
56
- if (isBaseBrand) {
57
- hover = chroma.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
58
- active = chroma.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
59
- } else if (isBaseLight) {
60
- hover = chroma.mix(baseColor, brandColor, lightHoverRatio, "rgb").hex();
61
- active = chroma.mix(baseColor, brandColor, lightActiveRatio, "rgb").hex();
62
- } else if (isBaseDark) {
63
- hover = chroma.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
64
- active = chroma.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
65
- } else {
66
- hover = chroma.mix(baseColor, "#ffffff", brandHoverRatio, "rgb").hex();
67
- active = chroma.mix(baseColor, "#000000", brandActiveRatio, "rgb").hex();
68
- }
69
- return { hover, active };
70
- }
71
-
72
- export {
73
- hexToHSLString,
74
- hexToRGBStr,
75
- generateAutoStateColors,
76
- generateStateColors
77
- };