@pathscale/ui 1.1.22 → 1.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/colorpicker/ColorWheelFlower.js +19 -1
- package/dist/components/theme-color-picker/ThemeColorPicker.d.ts +4 -2
- package/dist/components/theme-color-picker/ThemeColorPicker.js +12 -18
- package/dist/components/theme-color-picker/hueShift.d.ts +6 -6
- package/dist/components/theme-color-picker/hueShift.js +67 -452
- package/package.json +1 -1
|
@@ -36,6 +36,9 @@ const createColorItem = (id, rgb, offsetX, offsetY, options)=>{
|
|
|
36
36
|
id,
|
|
37
37
|
rgb,
|
|
38
38
|
hex: (0, __WEBPACK_EXTERNAL_MODULE__ColorUtils_js_8c38ee50__.rgbToHex)(r, g, b).toUpperCase(),
|
|
39
|
+
r,
|
|
40
|
+
g,
|
|
41
|
+
b,
|
|
39
42
|
offsetX,
|
|
40
43
|
offsetY,
|
|
41
44
|
hue: hsl.hue,
|
|
@@ -453,7 +456,22 @@ const ColorWheelFlower = (props)=>{
|
|
|
453
456
|
}
|
|
454
457
|
setSelectedIndex(index);
|
|
455
458
|
if (item.isCenter) return void context.onChange((0, __WEBPACK_EXTERNAL_MODULE__ColorUtils_js_8c38ee50__.createColorFromHsl)(0, 0, 100, context.color().hsl.a));
|
|
456
|
-
|
|
459
|
+
const alpha = context.color().hsl.a;
|
|
460
|
+
context.onChange({
|
|
461
|
+
rgb: {
|
|
462
|
+
r: item.r,
|
|
463
|
+
g: item.g,
|
|
464
|
+
b: item.b,
|
|
465
|
+
a: alpha
|
|
466
|
+
},
|
|
467
|
+
hsl: {
|
|
468
|
+
h: item.hue,
|
|
469
|
+
s: item.saturation,
|
|
470
|
+
l: item.lightness,
|
|
471
|
+
a: alpha
|
|
472
|
+
},
|
|
473
|
+
hex: item.hex
|
|
474
|
+
});
|
|
457
475
|
};
|
|
458
476
|
(0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createEffect)(()=>{
|
|
459
477
|
const selected = selectedIndex();
|
|
@@ -2,12 +2,14 @@ import { type Component, type JSX } from "solid-js";
|
|
|
2
2
|
import type { IComponentBaseProps } from "../types";
|
|
3
3
|
export interface ThemeColorPickerProps extends IComponentBaseProps {
|
|
4
4
|
/**
|
|
5
|
-
* Prefix for localStorage keys (e.g., "myapp" becomes "
|
|
5
|
+
* Prefix for localStorage keys (e.g., "myapp" becomes "myapp_theme_color")
|
|
6
6
|
* @default "theme"
|
|
7
7
|
*/
|
|
8
8
|
storagePrefix?: string;
|
|
9
9
|
/**
|
|
10
|
-
* Callback when color changes
|
|
10
|
+
* Callback when color changes. Passes the hex string (or null on reset).
|
|
11
|
+
* Kept with legacy `(hue, saturation)` signature for backward compatibility —
|
|
12
|
+
* hue is derived from the picked hex, saturation is forwarded as-is.
|
|
11
13
|
*/
|
|
12
14
|
onColorChange?: (hue: number | null, saturation: number) => void;
|
|
13
15
|
/**
|
|
@@ -8,9 +8,9 @@ import * as __WEBPACK_EXTERNAL_MODULE__button_index_js_557db1f7__ from "../butto
|
|
|
8
8
|
import * as __WEBPACK_EXTERNAL_MODULE__icon_index_js_1f7a158c__ from "../icon/index.js";
|
|
9
9
|
import * as __WEBPACK_EXTERNAL_MODULE__hueShift_js_ca4235e5__ from "./hueShift.js";
|
|
10
10
|
var _tmpl$ = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.template)('<div class="flex items-center gap-3"><div class="flex justify-center"></div><div class="flex flex-col gap-1.5">'), _tmpl$2 = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.template)('<div class="absolute right-0 z-50 mt-2 rounded-lg bg-base-200/80 p-4 shadow-xl backdrop-blur-sm">'), _tmpl$3 = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.template)("<div>"), _tmpl$4 = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_solid_js_web_35d951b7__.template)('<button type=button class="h-6 w-6 rounded-full border border-white/20 transition-transform hover:scale-110">');
|
|
11
|
-
function
|
|
12
|
-
if (null ===
|
|
13
|
-
return (0, __WEBPACK_EXTERNAL_MODULE__colorpicker_ColorUtils_js_79ac07b0__.createColorFromHsl)(
|
|
11
|
+
function hexToColorValue(hex) {
|
|
12
|
+
if (null === hex) return (0, __WEBPACK_EXTERNAL_MODULE__colorpicker_ColorUtils_js_79ac07b0__.createColorFromHsl)(0, 0, 100, 1);
|
|
13
|
+
return (0, __WEBPACK_EXTERNAL_MODULE__colorpicker_ColorUtils_js_79ac07b0__.parseColor)(hex) ?? (0, __WEBPACK_EXTERNAL_MODULE__colorpicker_ColorUtils_js_79ac07b0__.createColorFromHsl)(0, 0, 100, 1);
|
|
14
14
|
}
|
|
15
15
|
const ThemeColorPicker_ThemeColorPicker = (props)=>{
|
|
16
16
|
const [local, others] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.splitProps)(props, [
|
|
@@ -28,22 +28,16 @@ const ThemeColorPicker_ThemeColorPicker = (props)=>{
|
|
|
28
28
|
const [featureAvailable, setFeatureAvailable] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(true);
|
|
29
29
|
let containerRef;
|
|
30
30
|
const store = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createMemo)(()=>(0, __WEBPACK_EXTERNAL_MODULE__hueShift_js_ca4235e5__.createHueShiftStore)(local.storagePrefix ?? "theme"));
|
|
31
|
-
const colorValue = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createMemo)(()=>
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
const colorValue = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createMemo)(()=>hexToColorValue(store().themeColor()));
|
|
32
|
+
const handleColorChange = (color)=>{
|
|
33
|
+
const { s, l } = color.hsl;
|
|
34
|
+
if (s < 10 && l > 90) {
|
|
35
|
+
store().setThemeColor(null);
|
|
35
36
|
local.onColorChange?.(null, 100);
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
store().setHueShift(normalizedHue, normalizedSaturation);
|
|
41
|
-
local.onColorChange?.(normalizedHue, normalizedSaturation);
|
|
42
|
-
};
|
|
43
|
-
const handleColorChange = (color)=>{
|
|
44
|
-
const { h, s, l } = color.hsl;
|
|
45
|
-
if (s < 10 && l > 90) return void setThemeColor(null, 100);
|
|
46
|
-
setThemeColor(h, s);
|
|
39
|
+
store().setThemeColor(color.hex);
|
|
40
|
+
local.onColorChange?.(color.hsl.h, color.hsl.s);
|
|
47
41
|
};
|
|
48
42
|
const GRAYSCALE_SWATCHES = [
|
|
49
43
|
{
|
|
@@ -72,7 +66,7 @@ const ThemeColorPicker_ThemeColorPicker = (props)=>{
|
|
|
72
66
|
}
|
|
73
67
|
];
|
|
74
68
|
const handleGrayscale = (lightnessOffset)=>{
|
|
75
|
-
store().
|
|
69
|
+
store().setThemeColor(null);
|
|
76
70
|
local.onColorChange?.(null, 0);
|
|
77
71
|
if (lightnessOffset >= 5) local.onThemeSwitch?.("light");
|
|
78
72
|
else if (lightnessOffset <= -10) local.onThemeSwitch?.("dark");
|
|
@@ -141,7 +135,7 @@ const ThemeColorPicker_ThemeColorPicker = (props)=>{
|
|
|
141
135
|
width: 16,
|
|
142
136
|
height: 16,
|
|
143
137
|
get ["class"] () {
|
|
144
|
-
return null !== store().
|
|
138
|
+
return null !== store().themeColor() ? "text-primary" : void 0;
|
|
145
139
|
}
|
|
146
140
|
});
|
|
147
141
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
declare function resetHueShift(): void;
|
|
2
2
|
export interface HueShiftStore {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/** Current theme color as a hex string, or null when no override is active. */
|
|
4
|
+
themeColor: () => string | null;
|
|
5
|
+
/** Set (or clear with null) the theme color. Hex strings only. */
|
|
6
|
+
setThemeColor: (color: string | null) => void;
|
|
7
7
|
isAvailable: () => boolean;
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
10
|
-
* Creates a
|
|
11
|
-
* @param storagePrefix - Prefix for localStorage keys (e.g., "myapp" becomes "
|
|
10
|
+
* Creates a theme color store with configurable storage prefix.
|
|
11
|
+
* @param storagePrefix - Prefix for localStorage keys (e.g., "myapp" becomes "myapp_theme_color")
|
|
12
12
|
*/
|
|
13
13
|
export declare function createHueShiftStore(storagePrefix: string): HueShiftStore;
|
|
14
14
|
export declare function getDefaultHueShiftStore(): HueShiftStore;
|
|
@@ -13,478 +13,95 @@ const checkCspAllowsInlineStyles = ()=>{
|
|
|
13
13
|
} catch {
|
|
14
14
|
cspAllowsInlineStyles = false;
|
|
15
15
|
}
|
|
16
|
-
if (!cspAllowsInlineStyles) console.info("[
|
|
16
|
+
if (!cspAllowsInlineStyles) console.info("[themeColor] CSP blocks inline styles - theme color customization disabled");
|
|
17
17
|
return cspAllowsInlineStyles;
|
|
18
18
|
};
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
],
|
|
43
|
-
[
|
|
44
|
-
240,
|
|
45
|
-
265
|
|
46
|
-
],
|
|
47
|
-
[
|
|
48
|
-
300,
|
|
49
|
-
330
|
|
50
|
-
],
|
|
51
|
-
[
|
|
52
|
-
360,
|
|
53
|
-
389
|
|
54
|
-
]
|
|
55
|
-
];
|
|
56
|
-
for(let i = 0; i < controlPoints.length - 1; i++){
|
|
57
|
-
const [h1, o1] = controlPoints[i];
|
|
58
|
-
const [h2, o2] = controlPoints[i + 1];
|
|
59
|
-
if (h >= h1 && h <= h2) {
|
|
60
|
-
const t = (h - h1) / (h2 - h1);
|
|
61
|
-
const oklchHue = o1 + t * (o2 - o1);
|
|
62
|
-
return (oklchHue % 360 + 360) % 360;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return h;
|
|
66
|
-
}
|
|
67
|
-
const PRIMARY_SETTINGS = {
|
|
68
|
-
light: {
|
|
69
|
-
"--color-primary": {
|
|
70
|
-
l: 58,
|
|
71
|
-
c: 0.22
|
|
72
|
-
},
|
|
73
|
-
"--color-primary-content": {
|
|
74
|
-
l: 98,
|
|
75
|
-
c: 0.02
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
dark: {
|
|
79
|
-
"--color-primary": {
|
|
80
|
-
l: 75,
|
|
81
|
-
c: 0.18
|
|
82
|
-
},
|
|
83
|
-
"--color-primary-content": {
|
|
84
|
-
l: 15,
|
|
85
|
-
c: 0.02
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
const HARMONY_OFFSETS = {
|
|
90
|
-
secondary: 108,
|
|
91
|
-
accent: -94
|
|
92
|
-
};
|
|
93
|
-
const HARMONY_SETTINGS = {
|
|
94
|
-
light: {
|
|
95
|
-
"--color-secondary": {
|
|
96
|
-
l: 68,
|
|
97
|
-
c: 0.162
|
|
98
|
-
},
|
|
99
|
-
"--color-secondary-content": {
|
|
100
|
-
l: 98,
|
|
101
|
-
c: 0.026
|
|
102
|
-
},
|
|
103
|
-
"--color-accent": {
|
|
104
|
-
l: 62,
|
|
105
|
-
c: 0.2
|
|
106
|
-
},
|
|
107
|
-
"--color-accent-content": {
|
|
108
|
-
l: 98,
|
|
109
|
-
c: 0.014
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
dark: {
|
|
113
|
-
"--color-secondary": {
|
|
114
|
-
l: 72,
|
|
115
|
-
c: 0.16
|
|
116
|
-
},
|
|
117
|
-
"--color-secondary-content": {
|
|
118
|
-
l: 15,
|
|
119
|
-
c: 0.013
|
|
120
|
-
},
|
|
121
|
-
"--color-accent": {
|
|
122
|
-
l: 78,
|
|
123
|
-
c: 0.12
|
|
124
|
-
},
|
|
125
|
-
"--color-accent-content": {
|
|
126
|
-
l: 15,
|
|
127
|
-
c: 0.014
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
const SEMANTIC_BASE_HUES = {
|
|
132
|
-
success: 140,
|
|
133
|
-
warning: 55,
|
|
134
|
-
error: 10,
|
|
135
|
-
info: 220
|
|
136
|
-
};
|
|
137
|
-
const SEMANTIC_TINT_FACTOR = 0.12;
|
|
138
|
-
const SEMANTIC_SETTINGS = {
|
|
139
|
-
light: {
|
|
140
|
-
"--color-success": {
|
|
141
|
-
l: 72,
|
|
142
|
-
c: 0.219
|
|
143
|
-
},
|
|
144
|
-
"--color-success-content": {
|
|
145
|
-
l: 98,
|
|
146
|
-
c: 0.018
|
|
147
|
-
},
|
|
148
|
-
"--color-warning": {
|
|
149
|
-
l: 70,
|
|
150
|
-
c: 0.213
|
|
151
|
-
},
|
|
152
|
-
"--color-warning-content": {
|
|
153
|
-
l: 98,
|
|
154
|
-
c: 0.016
|
|
155
|
-
},
|
|
156
|
-
"--color-error": {
|
|
157
|
-
l: 65,
|
|
158
|
-
c: 0.241
|
|
159
|
-
},
|
|
160
|
-
"--color-error-content": {
|
|
161
|
-
l: 97,
|
|
162
|
-
c: 0.014
|
|
163
|
-
},
|
|
164
|
-
"--color-info": {
|
|
165
|
-
l: 68,
|
|
166
|
-
c: 0.169
|
|
167
|
-
},
|
|
168
|
-
"--color-info-content": {
|
|
169
|
-
l: 97,
|
|
170
|
-
c: 0.013
|
|
171
|
-
}
|
|
172
|
-
},
|
|
173
|
-
dark: {
|
|
174
|
-
"--color-success": {
|
|
175
|
-
l: 76,
|
|
176
|
-
c: 0.233
|
|
177
|
-
},
|
|
178
|
-
"--color-success-content": {
|
|
179
|
-
l: 98,
|
|
180
|
-
c: 0.031
|
|
181
|
-
},
|
|
182
|
-
"--color-warning": {
|
|
183
|
-
l: 79,
|
|
184
|
-
c: 0.184
|
|
185
|
-
},
|
|
186
|
-
"--color-warning-content": {
|
|
187
|
-
l: 98,
|
|
188
|
-
c: 0.026
|
|
189
|
-
},
|
|
190
|
-
"--color-error": {
|
|
191
|
-
l: 64,
|
|
192
|
-
c: 0.246
|
|
193
|
-
},
|
|
194
|
-
"--color-error-content": {
|
|
195
|
-
l: 96,
|
|
196
|
-
c: 0.015
|
|
197
|
-
},
|
|
198
|
-
"--color-info": {
|
|
199
|
-
l: 71,
|
|
200
|
-
c: 0.143
|
|
201
|
-
},
|
|
202
|
-
"--color-info-content": {
|
|
203
|
-
l: 98,
|
|
204
|
-
c: 0.019
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
const NF_ACCENT_SETTINGS = {
|
|
209
|
-
light: {
|
|
210
|
-
"--nf-accent": {
|
|
211
|
-
l: 58,
|
|
212
|
-
c: 0.22
|
|
213
|
-
},
|
|
214
|
-
"--nf-on-accent": {
|
|
215
|
-
l: 98,
|
|
216
|
-
c: 0.02
|
|
217
|
-
},
|
|
218
|
-
"--color-nf-accent": {
|
|
219
|
-
l: 58,
|
|
220
|
-
c: 0.22
|
|
221
|
-
},
|
|
222
|
-
"--color-nf-on-accent": {
|
|
223
|
-
l: 98,
|
|
224
|
-
c: 0.02
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
dark: {
|
|
228
|
-
"--nf-accent": {
|
|
229
|
-
l: 75,
|
|
230
|
-
c: 0.18
|
|
231
|
-
},
|
|
232
|
-
"--nf-on-accent": {
|
|
233
|
-
l: 15,
|
|
234
|
-
c: 0.02
|
|
235
|
-
},
|
|
236
|
-
"--color-nf-accent": {
|
|
237
|
-
l: 75,
|
|
238
|
-
c: 0.18
|
|
239
|
-
},
|
|
240
|
-
"--color-nf-on-accent": {
|
|
241
|
-
l: 15,
|
|
242
|
-
c: 0.02
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
const BASE_COLORS = {
|
|
247
|
-
light: {
|
|
248
|
-
"--color-base-100": {
|
|
249
|
-
l: 98,
|
|
250
|
-
c: 0.001,
|
|
251
|
-
h: 106.423
|
|
252
|
-
},
|
|
253
|
-
"--color-base-200": {
|
|
254
|
-
l: 97,
|
|
255
|
-
c: 0.001,
|
|
256
|
-
h: 106.424
|
|
257
|
-
},
|
|
258
|
-
"--color-base-300": {
|
|
259
|
-
l: 92,
|
|
260
|
-
c: 0.003,
|
|
261
|
-
h: 48.717
|
|
262
|
-
}
|
|
263
|
-
},
|
|
264
|
-
dark: {
|
|
265
|
-
"--color-base-100": {
|
|
266
|
-
l: 13,
|
|
267
|
-
c: 0.028,
|
|
268
|
-
h: 261.692
|
|
269
|
-
},
|
|
270
|
-
"--color-base-200": {
|
|
271
|
-
l: 21,
|
|
272
|
-
c: 0.034,
|
|
273
|
-
h: 264.665
|
|
274
|
-
},
|
|
275
|
-
"--color-base-300": {
|
|
276
|
-
l: 27,
|
|
277
|
-
c: 0.033,
|
|
278
|
-
h: 256.848
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
};
|
|
282
|
-
const BASE_CHROMA_BOOST = {
|
|
283
|
-
light: 0,
|
|
284
|
-
dark: 0.025
|
|
285
|
-
};
|
|
286
|
-
const GRADIENT_COLORS = {
|
|
287
|
-
light: {
|
|
288
|
-
"--gradient-start": {
|
|
289
|
-
h: 347,
|
|
290
|
-
s: 8,
|
|
291
|
-
l: 96
|
|
292
|
-
},
|
|
293
|
-
"--gradient-end": {
|
|
294
|
-
h: 199,
|
|
295
|
-
s: 8,
|
|
296
|
-
l: 97
|
|
297
|
-
}
|
|
298
|
-
},
|
|
299
|
-
dark: {
|
|
300
|
-
"--gradient-start": {
|
|
301
|
-
h: 261,
|
|
302
|
-
s: 38,
|
|
303
|
-
l: 15
|
|
304
|
-
},
|
|
305
|
-
"--gradient-end": {
|
|
306
|
-
h: 220,
|
|
307
|
-
s: 54,
|
|
308
|
-
l: 8
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
};
|
|
312
|
-
function toOklch(l, c, h) {
|
|
313
|
-
const normalizedH = (h % 360 + 360) % 360;
|
|
314
|
-
return `oklch(${l}% ${c} ${normalizedH})`;
|
|
315
|
-
}
|
|
316
|
-
function hslToHex(h, s, l) {
|
|
317
|
-
const normalizedH = (h % 360 + 360) % 360;
|
|
318
|
-
const sNorm = s / 100;
|
|
319
|
-
const lNorm = l / 100;
|
|
320
|
-
const c = (1 - Math.abs(2 * lNorm - 1)) * sNorm;
|
|
321
|
-
const x = c * (1 - Math.abs(normalizedH / 60 % 2 - 1));
|
|
322
|
-
const m = lNorm - c / 2;
|
|
323
|
-
let r = 0, g = 0, b = 0;
|
|
324
|
-
if (normalizedH < 60) {
|
|
325
|
-
r = c;
|
|
326
|
-
g = x;
|
|
327
|
-
b = 0;
|
|
328
|
-
} else if (normalizedH < 120) {
|
|
329
|
-
r = x;
|
|
330
|
-
g = c;
|
|
331
|
-
b = 0;
|
|
332
|
-
} else if (normalizedH < 180) {
|
|
333
|
-
r = 0;
|
|
334
|
-
g = c;
|
|
335
|
-
b = x;
|
|
336
|
-
} else if (normalizedH < 240) {
|
|
337
|
-
r = 0;
|
|
338
|
-
g = x;
|
|
339
|
-
b = c;
|
|
340
|
-
} else if (normalizedH < 300) {
|
|
341
|
-
r = x;
|
|
342
|
-
g = 0;
|
|
343
|
-
b = c;
|
|
344
|
-
} else {
|
|
345
|
-
r = c;
|
|
346
|
-
g = 0;
|
|
347
|
-
b = x;
|
|
348
|
-
}
|
|
349
|
-
const toHex = (n)=>{
|
|
350
|
-
const hex = Math.round((n + m) * 255).toString(16);
|
|
351
|
-
return 1 === hex.length ? "0" + hex : hex;
|
|
19
|
+
const PRIMARY_VARS = [
|
|
20
|
+
"--color-primary",
|
|
21
|
+
"--nf-accent",
|
|
22
|
+
"--color-nf-accent"
|
|
23
|
+
];
|
|
24
|
+
const CONTENT_VARS = [
|
|
25
|
+
"--color-primary-content",
|
|
26
|
+
"--nf-on-accent",
|
|
27
|
+
"--color-nf-on-accent"
|
|
28
|
+
];
|
|
29
|
+
function parseHex(hex) {
|
|
30
|
+
let h = hex.trim();
|
|
31
|
+
if (h.startsWith("#")) h = h.slice(1);
|
|
32
|
+
if (3 === h.length) h = h.split("").map((c)=>c + c).join("");
|
|
33
|
+
if (6 !== h.length) return null;
|
|
34
|
+
const r = Number.parseInt(h.slice(0, 2), 16);
|
|
35
|
+
const g = Number.parseInt(h.slice(2, 4), 16);
|
|
36
|
+
const b = Number.parseInt(h.slice(4, 6), 16);
|
|
37
|
+
if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) return null;
|
|
38
|
+
return {
|
|
39
|
+
r,
|
|
40
|
+
g,
|
|
41
|
+
b
|
|
352
42
|
};
|
|
353
|
-
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
354
43
|
}
|
|
355
|
-
function
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
44
|
+
function relativeLuminance(r, g, b) {
|
|
45
|
+
const toLin = (c)=>{
|
|
46
|
+
const s = c / 255;
|
|
47
|
+
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
|
48
|
+
};
|
|
49
|
+
return 0.2126 * toLin(r) + 0.7152 * toLin(g) + 0.0722 * toLin(b);
|
|
360
50
|
}
|
|
361
|
-
function
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
51
|
+
function pickContentColor(r, g, b) {
|
|
52
|
+
const bgL = relativeLuminance(r, g, b);
|
|
53
|
+
const whiteL = 1;
|
|
54
|
+
const darkL = relativeLuminance(0x11, 0x11, 0x11);
|
|
55
|
+
const contrastWithWhite = (whiteL + 0.05) / (bgL + 0.05);
|
|
56
|
+
const contrastWithDark = (bgL + 0.05) / (darkL + 0.05);
|
|
57
|
+
return contrastWithWhite >= contrastWithDark ? "#ffffff" : "#111111";
|
|
366
58
|
}
|
|
367
|
-
function
|
|
59
|
+
function applyThemeColor(hex) {
|
|
368
60
|
if (!checkCspAllowsInlineStyles()) return;
|
|
61
|
+
const rgb = parseHex(hex);
|
|
62
|
+
if (!rgb) return;
|
|
369
63
|
const root = document.documentElement;
|
|
370
|
-
const
|
|
371
|
-
const
|
|
372
|
-
const
|
|
373
|
-
const clampL = (l)=>Math.max(0, Math.min(100, l + lightnessOffset));
|
|
374
|
-
const primarySettings = PRIMARY_SETTINGS[resolvedTheme];
|
|
375
|
-
for (const [varName, settings] of Object.entries(primarySettings)){
|
|
376
|
-
const scaledChroma = settings.c * chromaScale;
|
|
377
|
-
root.style.setProperty(varName, toOklch(clampL(settings.l), scaledChroma, oklchHue));
|
|
378
|
-
}
|
|
379
|
-
const harmonySettings = HARMONY_SETTINGS[resolvedTheme];
|
|
380
|
-
for (const [varName, settings] of Object.entries(harmonySettings)){
|
|
381
|
-
let hue = oklchHue;
|
|
382
|
-
if (varName.includes("secondary")) hue = oklchHue + HARMONY_OFFSETS.secondary;
|
|
383
|
-
else if (varName.includes("accent")) hue = oklchHue + HARMONY_OFFSETS.accent;
|
|
384
|
-
const scaledChroma = settings.c * chromaScale;
|
|
385
|
-
root.style.setProperty(varName, toOklch(clampL(settings.l), scaledChroma, hue));
|
|
386
|
-
}
|
|
387
|
-
const semanticSettings = SEMANTIC_SETTINGS[resolvedTheme];
|
|
388
|
-
for (const [varName, settings] of Object.entries(semanticSettings)){
|
|
389
|
-
let baseHue = 0;
|
|
390
|
-
if (varName.includes("success")) baseHue = SEMANTIC_BASE_HUES.success;
|
|
391
|
-
else if (varName.includes("warning")) baseHue = SEMANTIC_BASE_HUES.warning;
|
|
392
|
-
else if (varName.includes("error")) baseHue = SEMANTIC_BASE_HUES.error;
|
|
393
|
-
else if (varName.includes("info")) baseHue = SEMANTIC_BASE_HUES.info;
|
|
394
|
-
const tintedHue = getTintedHue(baseHue, oklchHue);
|
|
395
|
-
const semanticChromaScale = 0 === saturation ? 0 : MIN_CHROMA_SCALE + (1 - MIN_CHROMA_SCALE) * Math.sqrt(saturation / 100);
|
|
396
|
-
const scaledChroma = settings.c * semanticChromaScale;
|
|
397
|
-
root.style.setProperty(varName, toOklch(clampL(settings.l), scaledChroma, tintedHue));
|
|
398
|
-
}
|
|
399
|
-
const gradients = GRADIENT_COLORS[resolvedTheme];
|
|
400
|
-
for (const [varName, color] of Object.entries(gradients)){
|
|
401
|
-
const scaledSat = color.s * (saturation / 100);
|
|
402
|
-
const shifted = hslToHex(targetHue + (varName.includes("end") ? 40 : 0), scaledSat, color.l);
|
|
403
|
-
root.style.setProperty(varName, shifted);
|
|
404
|
-
}
|
|
405
|
-
const baseColors = BASE_COLORS[resolvedTheme];
|
|
406
|
-
const baseBoost = BASE_CHROMA_BOOST[resolvedTheme];
|
|
407
|
-
for (const [varName, color] of Object.entries(baseColors)){
|
|
408
|
-
const baseChroma = Math.max(color.c, baseBoost);
|
|
409
|
-
const scaledChroma = baseChroma * chromaScale;
|
|
410
|
-
const hue = baseBoost > 0 ? oklchHue : color.h;
|
|
411
|
-
const shifted = toOklch(clampL(color.l), scaledChroma, hue);
|
|
412
|
-
root.style.setProperty(varName, shifted);
|
|
413
|
-
}
|
|
414
|
-
const nfAccentSettings = NF_ACCENT_SETTINGS[resolvedTheme];
|
|
415
|
-
for (const [varName, settings] of Object.entries(nfAccentSettings)){
|
|
416
|
-
const scaledChroma = settings.c * chromaScale;
|
|
417
|
-
root.style.setProperty(varName, toOklch(clampL(settings.l), scaledChroma, oklchHue));
|
|
418
|
-
}
|
|
64
|
+
const content = pickContentColor(rgb.r, rgb.g, rgb.b);
|
|
65
|
+
for (const varName of PRIMARY_VARS)root.style.setProperty(varName, hex);
|
|
66
|
+
for (const varName of CONTENT_VARS)root.style.setProperty(varName, content);
|
|
419
67
|
}
|
|
420
68
|
function resetHueShift() {
|
|
421
69
|
if (!checkCspAllowsInlineStyles()) return;
|
|
422
70
|
const root = document.documentElement;
|
|
423
|
-
for (const varName of
|
|
424
|
-
for (const varName of
|
|
425
|
-
for (const varName of Object.keys(SEMANTIC_SETTINGS.light))root.style.removeProperty(varName);
|
|
426
|
-
for (const varName of Object.keys(GRADIENT_COLORS.light))root.style.removeProperty(varName);
|
|
427
|
-
for (const varName of Object.keys(BASE_COLORS.light))root.style.removeProperty(varName);
|
|
428
|
-
for (const varName of Object.keys(NF_ACCENT_SETTINGS.light))root.style.removeProperty(varName);
|
|
71
|
+
for (const varName of PRIMARY_VARS)root.style.removeProperty(varName);
|
|
72
|
+
for (const varName of CONTENT_VARS)root.style.removeProperty(varName);
|
|
429
73
|
}
|
|
430
74
|
function createHueShiftStore(storagePrefix) {
|
|
431
|
-
const STORAGE_KEY = `${storagePrefix}
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
75
|
+
const STORAGE_KEY = `${storagePrefix}_theme_color`;
|
|
76
|
+
const LEGACY_KEYS = [
|
|
77
|
+
`${storagePrefix}_hue_shift`,
|
|
78
|
+
`${storagePrefix}_hue_saturation`,
|
|
79
|
+
`${storagePrefix}_hue_lightness`
|
|
80
|
+
];
|
|
81
|
+
const getInitial = ()=>{
|
|
435
82
|
if ("undefined" == typeof window) return null;
|
|
83
|
+
for (const key of LEGACY_KEYS)localStorage.removeItem(key);
|
|
436
84
|
const saved = localStorage.getItem(STORAGE_KEY);
|
|
437
|
-
if (
|
|
438
|
-
const parsed = parseFloat(saved);
|
|
439
|
-
if (!isNaN(parsed)) return parsed;
|
|
440
|
-
}
|
|
85
|
+
if (saved && parseHex(saved)) return saved;
|
|
441
86
|
return null;
|
|
442
87
|
};
|
|
443
|
-
const
|
|
444
|
-
if ("undefined" == typeof window) return 100;
|
|
445
|
-
const saved = localStorage.getItem(STORAGE_KEY_SAT);
|
|
446
|
-
if (null !== saved) {
|
|
447
|
-
const parsed = parseFloat(saved);
|
|
448
|
-
if (!isNaN(parsed)) return parsed;
|
|
449
|
-
}
|
|
450
|
-
return 100;
|
|
451
|
-
};
|
|
452
|
-
const getInitialLightness = ()=>{
|
|
453
|
-
if ("undefined" == typeof window) return 0;
|
|
454
|
-
const saved = localStorage.getItem(STORAGE_KEY_LIT);
|
|
455
|
-
if (null !== saved) {
|
|
456
|
-
const parsed = parseFloat(saved);
|
|
457
|
-
if (!isNaN(parsed)) return parsed;
|
|
458
|
-
}
|
|
459
|
-
return 0;
|
|
460
|
-
};
|
|
461
|
-
const [hueShift, setHueShiftInternal] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(getInitialHueShift());
|
|
462
|
-
const [hueSaturation, setHueSaturationInternal] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(getInitialSaturation());
|
|
463
|
-
const [hueLightness, setHueLightnessInternal] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(getInitialLightness());
|
|
88
|
+
const [themeColor, setThemeColorInternal] = (0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createSignal)(getInitial());
|
|
464
89
|
(0, __WEBPACK_EXTERNAL_MODULE_solid_js_aeefcc6d__.createEffect)(()=>{
|
|
465
|
-
const
|
|
466
|
-
const sat = hueSaturation();
|
|
467
|
-
const lit = hueLightness();
|
|
90
|
+
const color = themeColor();
|
|
468
91
|
if ("undefined" == typeof window) return;
|
|
469
|
-
if (null ===
|
|
92
|
+
if (null === color) {
|
|
470
93
|
localStorage.removeItem(STORAGE_KEY);
|
|
471
|
-
localStorage.removeItem(STORAGE_KEY_SAT);
|
|
472
|
-
localStorage.removeItem(STORAGE_KEY_LIT);
|
|
473
94
|
resetHueShift();
|
|
474
95
|
} else {
|
|
475
|
-
localStorage.setItem(STORAGE_KEY,
|
|
476
|
-
|
|
477
|
-
localStorage.setItem(STORAGE_KEY_LIT, String(lit));
|
|
478
|
-
applyHueShift(shift, sat, lit);
|
|
96
|
+
localStorage.setItem(STORAGE_KEY, color);
|
|
97
|
+
applyThemeColor(color);
|
|
479
98
|
}
|
|
480
99
|
});
|
|
481
100
|
if ("undefined" != typeof window) {
|
|
482
101
|
const observer = new MutationObserver((mutations)=>{
|
|
483
102
|
for (const mutation of mutations)if ("attributes" === mutation.type && "data-theme" === mutation.attributeName) {
|
|
484
|
-
const
|
|
485
|
-
|
|
486
|
-
const lit = hueLightness();
|
|
487
|
-
if (null !== shift) requestAnimationFrame(()=>applyHueShift(shift, sat, lit));
|
|
103
|
+
const color = themeColor();
|
|
104
|
+
if (null !== color) requestAnimationFrame(()=>applyThemeColor(color));
|
|
488
105
|
}
|
|
489
106
|
});
|
|
490
107
|
observer.observe(document.documentElement, {
|
|
@@ -494,16 +111,14 @@ function createHueShiftStore(storagePrefix) {
|
|
|
494
111
|
]
|
|
495
112
|
});
|
|
496
113
|
}
|
|
497
|
-
const
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
114
|
+
const setThemeColor = (color)=>{
|
|
115
|
+
if (null === color) return void setThemeColorInternal(null);
|
|
116
|
+
if (!parseHex(color)) return;
|
|
117
|
+
setThemeColorInternal(color);
|
|
501
118
|
};
|
|
502
119
|
return {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
hueLightness,
|
|
506
|
-
setHueShift,
|
|
120
|
+
themeColor,
|
|
121
|
+
setThemeColor,
|
|
507
122
|
isAvailable: ()=>checkCspAllowsInlineStyles()
|
|
508
123
|
};
|
|
509
124
|
}
|