@magmonium/one 0.4.29 → 0.4.31

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 (78) hide show
  1. package/assets/docs/en/app-release.md +0 -11
  2. package/assets/i18n/en.json +2 -0
  3. package/fesm2022/magmonium-one-attribute-value-CLBOZcme.mjs +255 -0
  4. package/fesm2022/magmonium-one-attribute-value-CLBOZcme.mjs.map +1 -0
  5. package/fesm2022/magmonium-one-base-checkbox-D7NYJdU3.mjs +77 -0
  6. package/fesm2022/magmonium-one-base-checkbox-D7NYJdU3.mjs.map +1 -0
  7. package/fesm2022/magmonium-one-base-dropdown-CEDsqaPz.mjs +604 -0
  8. package/fesm2022/magmonium-one-base-dropdown-CEDsqaPz.mjs.map +1 -0
  9. package/fesm2022/magmonium-one-base-input-BOaD-WIi.mjs +183 -0
  10. package/fesm2022/magmonium-one-base-input-BOaD-WIi.mjs.map +1 -0
  11. package/fesm2022/magmonium-one-base-text-D6p6_vsb.mjs +94 -0
  12. package/fesm2022/magmonium-one-base-text-D6p6_vsb.mjs.map +1 -0
  13. package/fesm2022/magmonium-one-button-rVNnp6G8.mjs +1281 -0
  14. package/fesm2022/magmonium-one-button-rVNnp6G8.mjs.map +1 -0
  15. package/fesm2022/magmonium-one-checkbox-rj4XHxb3.mjs +365 -0
  16. package/fesm2022/magmonium-one-checkbox-rj4XHxb3.mjs.map +1 -0
  17. package/fesm2022/magmonium-one-color-utl-CirPzUFk.mjs +449 -0
  18. package/fesm2022/magmonium-one-color-utl-CirPzUFk.mjs.map +1 -0
  19. package/fesm2022/magmonium-one-directives-DOBENX_K.mjs +1285 -0
  20. package/fesm2022/magmonium-one-directives-DOBENX_K.mjs.map +1 -0
  21. package/fesm2022/magmonium-one-file.service-Bo06pU3_.mjs +65 -0
  22. package/fesm2022/magmonium-one-file.service-Bo06pU3_.mjs.map +1 -0
  23. package/fesm2022/magmonium-one-group-Cue4x6tD.mjs +428 -0
  24. package/fesm2022/magmonium-one-group-Cue4x6tD.mjs.map +1 -0
  25. package/fesm2022/magmonium-one-header-DPVnaEOV.mjs +380 -0
  26. package/fesm2022/magmonium-one-header-DPVnaEOV.mjs.map +1 -0
  27. package/fesm2022/magmonium-one-icon-Dso-9RMN.mjs +833 -0
  28. package/fesm2022/magmonium-one-icon-Dso-9RMN.mjs.map +1 -0
  29. package/fesm2022/magmonium-one-image-editor-C7AtzEf6.mjs +438 -0
  30. package/fesm2022/magmonium-one-image-editor-C7AtzEf6.mjs.map +1 -0
  31. package/fesm2022/magmonium-one-image-frame-BTSaUSAi.mjs +116 -0
  32. package/fesm2022/magmonium-one-image-frame-BTSaUSAi.mjs.map +1 -0
  33. package/fesm2022/magmonium-one-input-DqHPorA1.mjs +39 -0
  34. package/fesm2022/magmonium-one-input-DqHPorA1.mjs.map +1 -0
  35. package/fesm2022/magmonium-one-label-B30Q4Vut.mjs +574 -0
  36. package/fesm2022/magmonium-one-label-B30Q4Vut.mjs.map +1 -0
  37. package/fesm2022/magmonium-one-m-ref-Dt0DCm8X.mjs +147 -0
  38. package/fesm2022/magmonium-one-m-ref-Dt0DCm8X.mjs.map +1 -0
  39. package/fesm2022/magmonium-one-menu-BBOnOK4M.mjs +887 -0
  40. package/fesm2022/magmonium-one-menu-BBOnOK4M.mjs.map +1 -0
  41. package/fesm2022/magmonium-one-multi-range-DCOwngql.mjs +458 -0
  42. package/fesm2022/magmonium-one-multi-range-DCOwngql.mjs.map +1 -0
  43. package/fesm2022/magmonium-one-options-asset-D8Gg1yNl.mjs +97 -0
  44. package/fesm2022/magmonium-one-options-asset-D8Gg1yNl.mjs.map +1 -0
  45. package/fesm2022/magmonium-one-otp-DLF7Pq94.mjs +261 -0
  46. package/fesm2022/magmonium-one-otp-DLF7Pq94.mjs.map +1 -0
  47. package/fesm2022/magmonium-one-password-BSOU4RI0.mjs +217 -0
  48. package/fesm2022/magmonium-one-password-BSOU4RI0.mjs.map +1 -0
  49. package/fesm2022/magmonium-one-radio-CYnWLXPZ.mjs +111 -0
  50. package/fesm2022/magmonium-one-radio-CYnWLXPZ.mjs.map +1 -0
  51. package/fesm2022/magmonium-one-range-CmmZAr57.mjs +216 -0
  52. package/fesm2022/magmonium-one-range-CmmZAr57.mjs.map +1 -0
  53. package/fesm2022/magmonium-one-rolldown-runtime-DpJrqANO.mjs +11 -0
  54. package/fesm2022/magmonium-one-selector-DDnBYNLr.mjs +1065 -0
  55. package/fesm2022/magmonium-one-selector-DDnBYNLr.mjs.map +1 -0
  56. package/fesm2022/magmonium-one-size-converter-B-UubQQ0.mjs +1057 -0
  57. package/fesm2022/magmonium-one-size-converter-B-UubQQ0.mjs.map +1 -0
  58. package/fesm2022/magmonium-one-text-FXb-RyBh.mjs +406 -0
  59. package/fesm2022/magmonium-one-text-FXb-RyBh.mjs.map +1 -0
  60. package/fesm2022/magmonium-one-text-output-D2XQWyL0.mjs +296 -0
  61. package/fesm2022/magmonium-one-text-output-D2XQWyL0.mjs.map +1 -0
  62. package/fesm2022/magmonium-one-theme-a7GlFbzE.mjs +1 -0
  63. package/fesm2022/magmonium-one-toggle-C0eTrtkt.mjs +231 -0
  64. package/fesm2022/magmonium-one-toggle-C0eTrtkt.mjs.map +1 -0
  65. package/fesm2022/magmonium-one.mjs +49231 -2
  66. package/fesm2022/magmonium-one.mjs.map +1 -1
  67. package/package.json +8 -8
  68. package/types/magmonium-one.d.ts +13801 -9510
  69. package/fesm2022/magmonium-one-image-editor-DYbS7fRP.mjs +0 -290
  70. package/fesm2022/magmonium-one-image-editor-DYbS7fRP.mjs.map +0 -1
  71. package/fesm2022/magmonium-one-magmonium-one-jBGfJvgl.mjs +0 -41576
  72. package/fesm2022/magmonium-one-magmonium-one-jBGfJvgl.mjs.map +0 -1
  73. package/fesm2022/magmonium-one-otp-DY1B1djA.mjs +0 -201
  74. package/fesm2022/magmonium-one-otp-DY1B1djA.mjs.map +0 -1
  75. package/fesm2022/magmonium-one-password-CzMwV84X.mjs +0 -105
  76. package/fesm2022/magmonium-one-password-CzMwV84X.mjs.map +0 -1
  77. package/fesm2022/magmonium-one-toggle-EoE3fKjl.mjs +0 -62
  78. package/fesm2022/magmonium-one-toggle-EoE3fKjl.mjs.map +0 -1
@@ -0,0 +1,449 @@
1
+ import { P as ASSET_BASE_URL, p as AssetStore, q as ONE_ASSET_BASE_URL } from "./magmonium-one-size-converter-B-UubQQ0.mjs";
2
+ import * as i0 from "@angular/core";
3
+ import { DOCUMENT, Injectable, computed, inject, signal } from "@angular/core";
4
+ import { catchError, forkJoin, map, of, pipe, tap } from "rxjs";
5
+ import { patchState, signalStore, withComputed, withHooks, withMethods, withState } from "@ngrx/signals";
6
+ import { rxMethod } from "@ngrx/signals/rxjs-interop";
7
+ import { map as map$1, switchMap as switchMap$1 } from "rxjs/operators";
8
+ var ThemeDataService = class ThemeDataService {
9
+ assetStore = inject(AssetStore);
10
+ fetchThemeList = (source) => this.assetStore.resolve("theme", "theme", source === "one").pipe(catchError(() => of([])));
11
+ fetchThemes = () => forkJoin({
12
+ one: this.fetchThemeList("one"),
13
+ local: this.fetchThemeList("host")
14
+ }).pipe(map(({ one, local }) => {
15
+ const themeMap = {};
16
+ const processList = (list, sourceKey) => {
17
+ if (!list || !Array.isArray(list)) return;
18
+ list.forEach((t) => {
19
+ const name = t.name || t.fileName;
20
+ if (name) {
21
+ if (themeMap[name]) {
22
+ if (!themeMap[name].sources.includes(sourceKey)) themeMap[name].sources.push(sourceKey);
23
+ } else themeMap[name] = {
24
+ ...t,
25
+ sources: [sourceKey]
26
+ };
27
+ }
28
+ });
29
+ };
30
+ processList(one, "one");
31
+ processList(local, "host");
32
+ return themeMap;
33
+ }));
34
+ fetchTheme = (theme, isOne = false) => theme.fileName ? this.assetStore.resolve("theme", theme.fileName, isOne).pipe(map((data) => ({
35
+ ...theme,
36
+ ...data
37
+ }))) : of(theme);
38
+ static ɵfac = i0.ɵɵngDeclareFactory({
39
+ minVersion: "12.0.0",
40
+ version: "22.2.1",
41
+ ngImport: i0,
42
+ type: ThemeDataService,
43
+ deps: [],
44
+ target: i0.ɵɵFactoryTarget.Injectable
45
+ });
46
+ static ɵprov = i0.ɵɵngDeclareInjectable({
47
+ minVersion: "12.0.0",
48
+ version: "22.2.1",
49
+ ngImport: i0,
50
+ type: ThemeDataService,
51
+ providedIn: "root"
52
+ });
53
+ };
54
+ i0.ɵɵngDeclareClassMetadata({
55
+ minVersion: "12.0.0",
56
+ version: "22.2.1",
57
+ ngImport: i0,
58
+ type: ThemeDataService,
59
+ decorators: [{
60
+ type: Injectable,
61
+ args: [{ providedIn: "root" }]
62
+ }]
63
+ });
64
+ var ThemeDetector = class ThemeDetector {
65
+ osTheme = signal("dark", ...ngDevMode ? [{ debugName: "osTheme" }] : /* istanbul ignore next */ []);
66
+ mediaQueryList;
67
+ onInit() {
68
+ this.mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)");
69
+ this.osTheme.set(this.mediaQueryList.matches ? "dark" : "light");
70
+ this.mediaQueryList.addEventListener("change", this.listener);
71
+ }
72
+ onDestroy() {
73
+ this.mediaQueryList.removeEventListener("change", this.listener);
74
+ }
75
+ listener = (event) => {
76
+ this.osTheme.set(event.matches ? "dark" : "light");
77
+ };
78
+ static ɵfac = i0.ɵɵngDeclareFactory({
79
+ minVersion: "12.0.0",
80
+ version: "22.2.1",
81
+ ngImport: i0,
82
+ type: ThemeDetector,
83
+ deps: [],
84
+ target: i0.ɵɵFactoryTarget.Injectable
85
+ });
86
+ static ɵprov = i0.ɵɵngDeclareInjectable({
87
+ minVersion: "12.0.0",
88
+ version: "22.2.1",
89
+ ngImport: i0,
90
+ type: ThemeDetector,
91
+ providedIn: "root"
92
+ });
93
+ };
94
+ i0.ɵɵngDeclareClassMetadata({
95
+ minVersion: "12.0.0",
96
+ version: "22.2.1",
97
+ ngImport: i0,
98
+ type: ThemeDetector,
99
+ decorators: [{
100
+ type: Injectable,
101
+ args: [{ providedIn: "root" }]
102
+ }]
103
+ });
104
+ const initialState = {
105
+ themeMap: {},
106
+ selected: "light",
107
+ userAdopted: void 0,
108
+ configDefault: void 0,
109
+ sources: [],
110
+ isReady: false
111
+ };
112
+ function toThemeCssVar(key) {
113
+ return "--m-" + key.replace(/([A-Z])/g, "-$1").toLowerCase();
114
+ }
115
+ function applyThemeVars(colors, target) {
116
+ Object.entries(colors).forEach(([key, value]) => {
117
+ target.style.setProperty(toThemeCssVar(key), value);
118
+ });
119
+ }
120
+ const ThemeStore = signalStore({ providedIn: "root" }, withState(initialState), withComputed((state, themeDetector = inject(ThemeDetector)) => {
121
+ const osTheme = computed(themeDetector.osTheme, ...ngDevMode ? [{ debugName: "osTheme" }] : /* istanbul ignore next */ []);
122
+ const theme = computed(() => {
123
+ const themeMap = state.themeMap();
124
+ const selected = state.selected();
125
+ return selected ? themeMap[selected] : void 0;
126
+ }, ...ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []);
127
+ return {
128
+ theme,
129
+ color: computed(() => theme()?.color, ...ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []),
130
+ osTheme
131
+ };
132
+ }), withMethods((state, themeDataService = inject(ThemeDataService), document = inject(DOCUMENT), themeDetector = inject(ThemeDetector), oneAssetBaseUrl = inject(ONE_ASSET_BASE_URL, { optional: true }) || "/assets/one", assetBaseUrl = inject(ASSET_BASE_URL, { optional: true }) || "/assets") => {
133
+ const renderTheme = (colors) => {
134
+ applyThemeVars(colors, document.documentElement);
135
+ };
136
+ const normalizeThemeSources = (themeMap) => {
137
+ const normalized = {};
138
+ for (const [name, theme] of Object.entries(themeMap)) normalized[name] = {
139
+ ...theme,
140
+ sources: theme.sources.map((s) => s === "one" ? oneAssetBaseUrl : s === "host" ? assetBaseUrl : s)
141
+ };
142
+ return normalized;
143
+ };
144
+ const fetchAndMergeTheme = (themeName) => {
145
+ const themeEntry = state.themeMap()[themeName];
146
+ if (!themeEntry || !themeEntry.sources.length) return of(void 0);
147
+ const requests = themeEntry.sources.map((source) => themeDataService.fetchTheme(themeEntry, source === oneAssetBaseUrl).pipe(catchError(() => of(void 0))));
148
+ return forkJoin(requests).pipe(map$1((results) => {
149
+ const validResults = results.filter((r) => !!r);
150
+ if (validResults.length === 0) return void 0;
151
+ const mergedColor = validResults.reduce((acc, curr) => ({
152
+ ...acc,
153
+ ...curr.color || {}
154
+ }), {});
155
+ return {
156
+ ...validResults[validResults.length - 1],
157
+ color: mergedColor,
158
+ sources: themeEntry.sources
159
+ };
160
+ }));
161
+ };
162
+ return {
163
+ applyTheme(colors) {
164
+ renderTheme(colors);
165
+ },
166
+ setConfigDefault(name) {
167
+ patchState(state, { configDefault: name });
168
+ if (!name || state.userAdopted()) return;
169
+ if (!state.themeMap()[name] || state.selected() === name) return;
170
+ patchState(state, { selected: name });
171
+ fetchAndMergeTheme(name).subscribe((fullTheme) => {
172
+ if (!fullTheme?.name) return;
173
+ patchState(state, {
174
+ themeMap: {
175
+ ...state.themeMap(),
176
+ [fullTheme.name]: fullTheme
177
+ },
178
+ isReady: true
179
+ });
180
+ if (fullTheme.color) renderTheme(fullTheme.color);
181
+ });
182
+ },
183
+ setTheme: rxMethod(pipe(tap((selected) => patchState(state, { selected })), switchMap$1((selected) => {
184
+ if (!selected) return of(void 0);
185
+ return fetchAndMergeTheme(selected);
186
+ }), tap((fullTheme) => {
187
+ if (fullTheme && fullTheme.name) {
188
+ patchState(state, { themeMap: {
189
+ ...state.themeMap(),
190
+ [fullTheme.name]: fullTheme
191
+ } });
192
+ if (fullTheme.color) renderTheme(fullTheme.color);
193
+ }
194
+ }))),
195
+ addSource: rxMethod(pipe(tap((baseUrl) => {
196
+ const sources = state.sources();
197
+ if (!sources.includes(baseUrl)) patchState(state, { sources: [...sources, baseUrl] });
198
+ }), switchMap$1((baseUrl) => {
199
+ const source = baseUrl === oneAssetBaseUrl ? "one" : "host";
200
+ return themeDataService.fetchThemeList(source).pipe(map$1((list) => ({
201
+ list,
202
+ baseUrl
203
+ })));
204
+ }), tap(({ list, baseUrl }) => {
205
+ const themeMap = { ...state.themeMap() };
206
+ list.forEach((t) => {
207
+ const name = t.name || t.fileName;
208
+ if (name) {
209
+ if (themeMap[name]) {
210
+ if (!themeMap[name].sources.includes(baseUrl)) themeMap[name].sources.push(baseUrl);
211
+ } else themeMap[name] = {
212
+ ...t,
213
+ sources: [baseUrl]
214
+ };
215
+ }
216
+ });
217
+ patchState(state, { themeMap });
218
+ const selected = state.selected();
219
+ if (selected && themeMap[selected]?.sources.includes(baseUrl)) fetchAndMergeTheme(selected).subscribe((fullTheme) => {
220
+ if (fullTheme && fullTheme.name) {
221
+ patchState(state, { themeMap: {
222
+ ...state.themeMap(),
223
+ [fullTheme.name]: fullTheme
224
+ } });
225
+ if (fullTheme.color) renderTheme(fullTheme.color);
226
+ }
227
+ });
228
+ }))),
229
+ init$: () => {
230
+ return themeDataService.fetchThemes().pipe(map$1((themeMap) => normalizeThemeSources(themeMap)), tap((themeMap) => {
231
+ patchState(state, { themeMap });
232
+ }));
233
+ },
234
+ init: rxMethod(pipe(switchMap$1(() => themeDataService.fetchThemes()), map$1((map) => normalizeThemeSources(map)), tap((map) => patchState(state, { themeMap: map })), switchMap$1((map) => {
235
+ if (state.userAdopted()) return of(void 0);
236
+ const declared = state.configDefault();
237
+ const preferred = themeDetector.osTheme();
238
+ const name = declared && map[declared] ? declared : preferred && map[preferred] ? preferred : Object.keys(map)[0];
239
+ if (!name) return of(void 0);
240
+ patchState(state, { selected: name });
241
+ return fetchAndMergeTheme(name);
242
+ }), tap((fullTheme) => {
243
+ if (fullTheme && fullTheme.name) {
244
+ patchState(state, { themeMap: {
245
+ ...state.themeMap(),
246
+ [fullTheme.name]: fullTheme
247
+ } });
248
+ if (fullTheme.color) renderTheme(fullTheme.color);
249
+ patchState(state, { isReady: true });
250
+ }
251
+ })))
252
+ };
253
+ }), withHooks((store) => {
254
+ const themeDetector = inject(ThemeDetector);
255
+ return {
256
+ onInit() {
257
+ themeDetector.onInit();
258
+ store.init$().subscribe((map) => {
259
+ if (!store.userAdopted()) {
260
+ const declared = store.configDefault();
261
+ const preferred = store.osTheme();
262
+ const name = declared && map[declared] ? declared : preferred && map[preferred] ? preferred : Object.keys(map)[0];
263
+ if (name) store.setTheme(name);
264
+ }
265
+ });
266
+ },
267
+ onDestroy() {
268
+ themeDetector.onDestroy();
269
+ }
270
+ };
271
+ }));
272
+ function derivePropertyName(inputString, type) {
273
+ const match = inputString.toLowerCase().match(/^m(?:-one)?-(.+)$/);
274
+ if (match) return `--m-${match[1]}-${type}`;
275
+ else return `--m-${type}`;
276
+ }
277
+ function setProperty(element, key, value) {
278
+ element.style.setProperty(key, value);
279
+ }
280
+ function getProperty(element, key) {
281
+ return getComputedStyle(element).getPropertyValue(key);
282
+ }
283
+ function parseColor(color) {
284
+ const trimmedColor = color.trim();
285
+ if (trimmedColor.startsWith("#")) return hexToRgb(trimmedColor);
286
+ const rgbMatch = trimmedColor.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);
287
+ if (rgbMatch) return {
288
+ r: parseInt(rgbMatch[1], 10),
289
+ g: parseInt(rgbMatch[2], 10),
290
+ b: parseInt(rgbMatch[3], 10)
291
+ };
292
+ const rgbaMatch = trimmedColor.match(/rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*[\d.]+\s*\)/);
293
+ if (rgbaMatch) return {
294
+ r: parseInt(rgbaMatch[1], 10),
295
+ g: parseInt(rgbaMatch[2], 10),
296
+ b: parseInt(rgbaMatch[3], 10)
297
+ };
298
+ const hslMatch = trimmedColor.match(/hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/);
299
+ if (hslMatch) return hslToRgb({
300
+ h: parseInt(hslMatch[1], 10),
301
+ s: parseInt(hslMatch[2], 10),
302
+ l: parseInt(hslMatch[3], 10)
303
+ });
304
+ return null;
305
+ }
306
+ function hexToRgb(hex) {
307
+ const cleanHex = hex.replace("#", "");
308
+ if (cleanHex.length === 3) return {
309
+ r: parseInt(cleanHex[0] + cleanHex[0], 16),
310
+ g: parseInt(cleanHex[1] + cleanHex[1], 16),
311
+ b: parseInt(cleanHex[2] + cleanHex[2], 16)
312
+ };
313
+ else if (cleanHex.length === 6) return {
314
+ r: parseInt(cleanHex.slice(0, 2), 16),
315
+ g: parseInt(cleanHex.slice(2, 4), 16),
316
+ b: parseInt(cleanHex.slice(4, 6), 16)
317
+ };
318
+ return null;
319
+ }
320
+ function hslToRgb(hsl) {
321
+ const h = hsl.h % 360 / 360;
322
+ const s = Math.max(0, Math.min(100, hsl.s)) / 100;
323
+ const l = Math.max(0, Math.min(100, hsl.l)) / 100;
324
+ const hue2rgb = (p, q, t) => {
325
+ if (t < 0) t += 1;
326
+ if (t > 1) t -= 1;
327
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
328
+ if (t < 1 / 2) return q;
329
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
330
+ return p;
331
+ };
332
+ let r, g, b;
333
+ if (s === 0) r = g = b = l;
334
+ else {
335
+ const q = l < .5 ? l * (1 + s) : l + s - l * s;
336
+ const p = 2 * l - q;
337
+ r = hue2rgb(p, q, h + 1 / 3);
338
+ g = hue2rgb(p, q, h);
339
+ b = hue2rgb(p, q, h - 1 / 3);
340
+ }
341
+ return {
342
+ r: Math.round(Math.max(0, Math.min(255, r * 255))),
343
+ g: Math.round(Math.max(0, Math.min(255, g * 255))),
344
+ b: Math.round(Math.max(0, Math.min(255, b * 255)))
345
+ };
346
+ }
347
+ function rgbToHex(rgb) {
348
+ const toHex = (n) => {
349
+ const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
350
+ return hex.length === 1 ? "0" + hex : hex;
351
+ };
352
+ return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
353
+ }
354
+ function rgbToHsl(rgb) {
355
+ const r = rgb.r / 255;
356
+ const g = rgb.g / 255;
357
+ const b = rgb.b / 255;
358
+ const max = Math.max(r, g, b);
359
+ const min = Math.min(r, g, b);
360
+ let h = 0;
361
+ let s = 0;
362
+ const l = (max + min) / 2;
363
+ if (max !== min) {
364
+ const d = max - min;
365
+ s = l > .5 ? d / (2 - max - min) : d / (max + min);
366
+ switch (max) {
367
+ case r:
368
+ h = (g - b) / d + (g < b ? 6 : 0);
369
+ break;
370
+ case g:
371
+ h = (b - r) / d + 2;
372
+ break;
373
+ case b: h = (r - g) / d + 4;
374
+ }
375
+ h /= 6;
376
+ }
377
+ return {
378
+ h: h * 360,
379
+ s: s * 100,
380
+ l: l * 100
381
+ };
382
+ }
383
+ function calculateLuminance(rgb) {
384
+ const toLinear = (c) => {
385
+ const normalized = c / 255;
386
+ return normalized <= .03928 ? normalized / 12.92 : Math.pow((normalized + .055) / 1.055, 2.4);
387
+ };
388
+ const r = toLinear(rgb.r);
389
+ const g = toLinear(rgb.g);
390
+ const b = toLinear(rgb.b);
391
+ return .2126 * r + .7152 * g + .0722 * b;
392
+ }
393
+ function deriveContrastColor(color) {
394
+ try {
395
+ if (!color || color.trim() === "") return "#ffffff";
396
+ const rgb = parseColor(color);
397
+ if (!rgb) return "#ffffff";
398
+ if (rgb.r < 0 || rgb.r > 255 || rgb.g < 0 || rgb.g > 255 || rgb.b < 0 || rgb.b > 255) return "#ffffff";
399
+ return calculateLuminance(rgb) > .5 ? "#000000" : "#ffffff";
400
+ } catch (error) {
401
+ console.warn("Error in deriveContrastColor:", error);
402
+ return "#ffffff";
403
+ }
404
+ }
405
+ function deriveOppositeColor(color) {
406
+ try {
407
+ if (!color || color.trim() === "") return color;
408
+ const rgb = parseColor(color);
409
+ if (!rgb) return color;
410
+ if (rgb.r < 0 || rgb.r > 255 || rgb.g < 0 || rgb.g > 255 || rgb.b < 0 || rgb.b > 255) return color;
411
+ const hsl = rgbToHsl(rgb);
412
+ return rgbToHex(hslToRgb({
413
+ h: (hsl.h + 180) % 360,
414
+ s: hsl.s,
415
+ l: hsl.l
416
+ }));
417
+ } catch (error) {
418
+ console.warn("Error in deriveOppositeColor:", error);
419
+ return color;
420
+ }
421
+ }
422
+ const colorPalletMap = /* @__PURE__ */ new Map();
423
+ function resolvePallet(currentColor, themeColors) {
424
+ const key = currentColor || "mm";
425
+ let color = themeColors?.[key] ?? key;
426
+ if (/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(color)) color = `#${color}`;
427
+ const savedPallet = colorPalletMap.get(color);
428
+ if (savedPallet) return savedPallet;
429
+ const pallet = {
430
+ color,
431
+ contrastColor: deriveContrastColor(color),
432
+ oppositeColor: deriveOppositeColor(color)
433
+ };
434
+ colorPalletMap.set(color, pallet);
435
+ return pallet;
436
+ }
437
+ function applyColorsToElement(inputColor = "mm", themeColors, element) {
438
+ const pallet = resolvePallet(inputColor, themeColors), { color, contrastColor, oppositeColor } = pallet;
439
+ const colorProp = derivePropertyName(element.tagName, "color");
440
+ const contrastProp = derivePropertyName(element.tagName, "color-contrast");
441
+ const oppositeProp = derivePropertyName(element.tagName, "color-opposite");
442
+ element.style.setProperty(colorProp, color);
443
+ element.style.setProperty(contrastProp, contrastColor);
444
+ element.style.setProperty(oppositeProp, oppositeColor);
445
+ return pallet;
446
+ }
447
+ export { calculateLuminance as a, hexToRgb as c, derivePropertyName as d, getProperty as f, ThemeDataService as h, deriveOppositeColor as i, hslToRgb as l, ThemeStore as m, resolvePallet as n, rgbToHex as o, setProperty as p, deriveContrastColor as r, rgbToHsl as s, applyColorsToElement as t, parseColor as u };
448
+
449
+ //# sourceMappingURL=magmonium-one-color-utl-CirPzUFk.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"magmonium-one-color-utl-CirPzUFk.mjs","names":["map","switchMap"],"sources":["../../../../libs/one/src/lib/shared/lib/theme/api/theme-data.ts","../../../../libs/one/src/lib/shared/lib/theme/lib/theme-detector.ts","../../../../libs/one/src/lib/shared/lib/theme/type/state.ts","../../../../libs/one/src/lib/shared/lib/theme/lib/theme-store.ts","../../../../libs/one/src/lib/shared/functions/css/property-names.ts","../../../../libs/one/src/lib/shared/functions/color/parsers.ts","../../../../libs/one/src/lib/shared/functions/color/converters.ts","../../../../libs/one/src/lib/shared/functions/color/operations.ts","../../../../libs/one/src/lib/shared/lib/theme/lib/color-utl.ts"],"sourcesContent":["import { inject, Injectable } from '@angular/core';\nimport { catchError, forkJoin, map, of } from 'rxjs';\nimport { Theme, ThemeList } from '@magmonium/cli';\nimport { AssetStore } from '../../../stores/asset.store';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ThemeDataService {\n private readonly assetStore = inject(AssetStore);\n\n public fetchThemeList = (source: 'one' | 'host') =>\n this.assetStore\n .resolve<ThemeList>('theme', 'theme', source === 'one')\n .pipe(catchError(() => of(<ThemeList>[])));\n\n public fetchThemes = () =>\n forkJoin({\n one: this.fetchThemeList('one'),\n local: this.fetchThemeList('host'),\n }).pipe(\n map(({ one, local }) => {\n const themeMap: Record<string, Theme & { sources: string[] }> = {};\n\n const processList = (list: ThemeList, sourceKey: string) => {\n if (!list || !Array.isArray(list)) return;\n list.forEach((t) => {\n const name = t.name || t.fileName;\n if (name) {\n if (themeMap[name]) {\n if (!themeMap[name].sources.includes(sourceKey)) {\n themeMap[name].sources.push(sourceKey);\n }\n } else {\n themeMap[name] = { ...t, sources: [sourceKey] } as Theme & {\n sources: string[];\n };\n }\n }\n });\n };\n\n processList(one, 'one');\n processList(local, 'host');\n\n return themeMap;\n })\n );\n\n public fetchTheme = (theme: Theme, isOne = false) =>\n theme.fileName\n ? this.assetStore\n .resolve<Theme>('theme', theme.fileName, isOne)\n .pipe(map((data: Theme) => ({ ...theme, ...data })))\n : of(theme);\n}\n","import { Injectable, signal } from '@angular/core';\nimport { OsTheme } from '../type/state';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ThemeDetector {\n public readonly osTheme = signal<OsTheme>('dark');\n private mediaQueryList!: MediaQueryList;\n\n public onInit(): void {\n this.mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');\n this.osTheme.set(this.mediaQueryList.matches ? 'dark' : 'light');\n this.mediaQueryList.addEventListener('change', this.listener);\n }\n\n public onDestroy(): void {\n this.mediaQueryList.removeEventListener('change', this.listener);\n }\n\n private listener = (event: MediaQueryListEvent) => {\n this.osTheme.set(event.matches ? 'dark' : 'light');\n };\n}\n","import { Theme } from '@magmonium/cli';\n\nexport type OsTheme = 'light' | 'dark';\n\nexport type ThemeState = {\n themeMap: Record<string, Theme>;\n selected: string | undefined;\n userAdopted: true | undefined;\n // The theme the app declares it boots with — `theme:` on its\n // WebComponentConfig, read out of `app-wc.json` at bootstrap. Stands in for\n // the OS auto-match rather than for the person's own pick: `userAdopted`\n // still wins, and an app that declares nothing keeps the OS behaviour.\n configDefault: string | undefined;\n sources: string[];\n isReady: boolean;\n};\n\nexport const initialState: ThemeState = {\n themeMap: {},\n selected: 'light',\n userAdopted: undefined,\n configDefault: undefined,\n sources: [],\n isReady: false,\n};\n","import {\n patchState,\n signalStore,\n withComputed,\n withHooks,\n withMethods,\n withState,\n} from '@ngrx/signals';\nimport { computed, DOCUMENT, inject } from '@angular/core';\nimport { ThemeDataService } from '../api/theme-data';\nimport { rxMethod } from '@ngrx/signals/rxjs-interop';\nimport { forkJoin, of, pipe, tap, catchError } from 'rxjs';\nimport { switchMap, map } from 'rxjs/operators';\nimport { Theme } from '@magmonium/cli';\nimport { ThemeDetector } from './theme-detector';\nimport { initialState } from '../type/state';\nimport { ASSET_BASE_URL, ONE_ASSET_BASE_URL } from '../../../config/tokens';\n\nfunction toThemeCssVar(key: string): string {\n return '--m-' + key.replace(/([A-Z])/g, '-$1').toLowerCase();\n}\n\nfunction applyThemeVars(\n colors: Record<string, string>,\n target: HTMLElement\n): void {\n Object.entries(colors).forEach(([key, value]) => {\n target.style.setProperty(toThemeCssVar(key), value);\n });\n}\n\nexport const ThemeStore = signalStore(\n { providedIn: 'root' },\n withState(initialState),\n withComputed((state, themeDetector = inject(ThemeDetector)) => {\n const osTheme = computed(themeDetector.osTheme);\n const theme = computed<Theme | undefined>(() => {\n const themeMap = state.themeMap();\n const selected = state.selected();\n return selected ? themeMap[selected] : undefined;\n });\n const color = computed(() => theme()?.color);\n return {\n theme,\n color,\n osTheme,\n };\n }),\n withMethods(\n (\n state,\n themeDataService = inject(ThemeDataService),\n document = inject(DOCUMENT),\n themeDetector = inject(ThemeDetector),\n oneAssetBaseUrl = inject(ONE_ASSET_BASE_URL, { optional: true }) ||\n '/assets/one',\n assetBaseUrl = inject(ASSET_BASE_URL, { optional: true }) || '/assets'\n ) => {\n const renderTheme = (colors: Record<string, string>) => {\n applyThemeVars(colors, document.documentElement);\n };\n\n const normalizeThemeSources = (\n themeMap: Record<string, Theme & { sources: string[] }>\n ) => {\n const normalized: Record<string, Theme & { sources: string[] }> = {};\n for (const [name, theme] of Object.entries(themeMap)) {\n normalized[name] = {\n ...theme,\n sources: theme.sources.map((s) =>\n s === 'one' ? oneAssetBaseUrl : s === 'host' ? assetBaseUrl : s\n ),\n };\n }\n return normalized;\n };\n\n const fetchAndMergeTheme = (themeName: string) => {\n const themeEntry = state.themeMap()[themeName] as\n | (Theme & { sources: string[] })\n | undefined;\n if (!themeEntry || !themeEntry.sources.length) return of(undefined);\n\n const requests = themeEntry.sources.map((source) =>\n themeDataService\n .fetchTheme(themeEntry, source === oneAssetBaseUrl)\n .pipe(catchError(() => of(undefined)))\n );\n\n return forkJoin(requests).pipe(\n map((results) => {\n const validResults = results.filter((r) => !!r) as Theme[];\n if (validResults.length === 0) return undefined;\n\n const mergedColor = validResults.reduce(\n (acc, curr) => ({\n ...acc,\n ...(curr.color || {}),\n }),\n {} as Record<string, unknown>\n );\n\n return {\n ...validResults[validResults.length - 1],\n color: mergedColor,\n sources: themeEntry.sources,\n } as Theme & { sources: string[] };\n })\n );\n };\n\n return {\n /**\n * Paints a set of DesignTokens straight onto the page without a theme\n * behind them. What a visual editor needs to show a theme it holds in\n * memory and has not written anywhere yet — every other path here\n * resolves a name against an asset first, and an unsaved theme has no\n * asset to resolve.\n */\n applyTheme(colors: Record<string, string>): void {\n renderTheme(colors);\n },\n /**\n * The theme the app declares it boots with (`theme:` on its\n * WebComponentConfig). Read out of `app-wc.json` after bootstrap, so it\n * lands either side of `init` finishing — hence both halves: it is\n * recorded for `init` to prefer, and applied now in case `init` has\n * already chosen the OS theme.\n *\n * Never overrides a person who has picked for themselves: `userAdopted`\n * is checked here the same way `init` checks it.\n */\n setConfigDefault(name: string | undefined): void {\n patchState(state, { configDefault: name });\n if (!name || state.userAdopted()) return;\n if (!state.themeMap()[name] || state.selected() === name) return;\n patchState(state, { selected: name });\n fetchAndMergeTheme(name).subscribe((fullTheme) => {\n if (!fullTheme?.name) return;\n patchState(state, {\n themeMap: { ...state.themeMap(), [fullTheme.name]: fullTheme },\n isReady: true,\n });\n if (fullTheme.color) {\n renderTheme(fullTheme.color as Record<string, string>);\n }\n });\n },\n setTheme: rxMethod<string | undefined>(\n pipe(\n tap((selected) => patchState(state, { selected })),\n switchMap((selected) => {\n if (!selected) return of(undefined);\n return fetchAndMergeTheme(selected);\n }),\n tap((fullTheme: (Theme & { sources: string[] }) | undefined) => {\n if (fullTheme && fullTheme.name) {\n patchState(state, {\n themeMap: {\n ...state.themeMap(),\n [fullTheme.name]: fullTheme as Theme,\n },\n });\n if (fullTheme.color) {\n renderTheme(fullTheme.color as Record<string, string>);\n }\n }\n })\n )\n ),\n addSource: rxMethod<string>(\n pipe(\n tap((baseUrl) => {\n const sources = state.sources();\n if (!sources.includes(baseUrl)) {\n patchState(state, { sources: [...sources, baseUrl] });\n }\n }),\n switchMap((baseUrl) => {\n const source = baseUrl === oneAssetBaseUrl ? 'one' : 'host';\n return themeDataService\n .fetchThemeList(source)\n .pipe(map((list) => ({ list, baseUrl })));\n }),\n tap(({ list, baseUrl }) => {\n const themeMap = { ...state.themeMap() } as Record<\n string,\n Theme & { sources: string[] }\n >;\n list.forEach((t) => {\n const name = t.name || t.fileName;\n if (name) {\n if (themeMap[name]) {\n if (!themeMap[name].sources.includes(baseUrl)) {\n themeMap[name].sources.push(baseUrl);\n }\n } else {\n themeMap[name] = { ...t, sources: [baseUrl] } as Theme & {\n sources: string[];\n };\n }\n }\n });\n patchState(state, {\n themeMap: themeMap as Record<string, Theme>,\n });\n\n const selected = state.selected();\n if (selected && themeMap[selected]?.sources.includes(baseUrl)) {\n fetchAndMergeTheme(selected).subscribe(\n (fullTheme: (Theme & { sources: string[] }) | undefined) => {\n if (fullTheme && fullTheme.name) {\n patchState(state, {\n themeMap: {\n ...state.themeMap(),\n [fullTheme.name]: fullTheme as Theme,\n },\n });\n if (fullTheme.color) {\n renderTheme(fullTheme.color as Record<string, string>);\n }\n }\n }\n );\n }\n })\n )\n ),\n init$: () => {\n return themeDataService.fetchThemes().pipe(\n map((themeMap) =>\n normalizeThemeSources(\n themeMap as Record<string, Theme & { sources: string[] }>\n )\n ),\n tap((themeMap) => {\n patchState(state, {\n themeMap: themeMap as Record<string, Theme>,\n });\n })\n );\n },\n init: rxMethod<void>(\n pipe(\n switchMap(() => themeDataService.fetchThemes()),\n map((map) =>\n normalizeThemeSources(\n map as Record<string, Theme & { sources: string[] }>\n )\n ),\n tap((map) =>\n patchState(state, { themeMap: map as Record<string, Theme> })\n ),\n switchMap((map) => {\n if (state.userAdopted()) return of(undefined);\n // The app's own declaration stands in for the OS auto-match, and\n // only for it — a name naming nothing falls through to the OS\n // rather than leaving the app unthemed.\n const declared = state.configDefault();\n const preferred = themeDetector.osTheme();\n const name =\n declared && map[declared]\n ? declared\n : preferred && map[preferred]\n ? preferred\n : Object.keys(map)[0];\n if (!name) return of(undefined);\n patchState(state, { selected: name });\n return fetchAndMergeTheme(name);\n }),\n tap((fullTheme: (Theme & { sources: string[] }) | undefined) => {\n if (fullTheme && fullTheme.name) {\n patchState(state, {\n themeMap: {\n ...state.themeMap(),\n [fullTheme.name]: fullTheme as Theme,\n },\n });\n if (fullTheme.color) {\n renderTheme(fullTheme.color as Record<string, string>);\n }\n patchState(state, { isReady: true });\n }\n })\n )\n ),\n };\n }\n ),\n withHooks((store) => {\n const themeDetector = inject(ThemeDetector);\n return {\n onInit() {\n themeDetector.onInit();\n\n store.init$().subscribe((map) => {\n if (!store.userAdopted()) {\n const declared = store.configDefault();\n const preferred = store.osTheme();\n const name =\n declared && map[declared]\n ? declared\n : preferred && map[preferred]\n ? preferred\n : Object.keys(map)[0];\n if (name) store.setTheme(name);\n }\n });\n },\n onDestroy() {\n themeDetector.onDestroy();\n },\n };\n })\n);\n","export type ColorPropertyType = 'color' | 'color-contrast' | 'color-opposite';\n\nexport function derivePropertyName(\n inputString: string,\n type: ColorPropertyType\n): string {\n const tagName = inputString.toLowerCase();\n\n const match = tagName.match(/^m(?:-one)?-(.+)$/);\n\n if (match) {\n const componentName = match[1];\n return `--m-${componentName}-${type}`;\n } else {\n return `--m-${type}`;\n }\n}\n\nexport function setProperty(\n element: HTMLElement,\n key: string,\n value: string | null\n) {\n element.style.setProperty(key, value);\n}\n\nexport function getProperty(element: HTMLElement, key: string) {\n return getComputedStyle(element).getPropertyValue(key);\n}\n","import { RgbColor, HslColor } from './types';\n\nexport function parseColor(color: string): RgbColor | null {\n const trimmedColor = color.trim();\n\n // Handle hex colors\n if (trimmedColor.startsWith('#')) {\n return hexToRgb(trimmedColor);\n }\n\n // Handle rgb() colors\n const rgbMatch = trimmedColor.match(\n /rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)/\n );\n if (rgbMatch) {\n return {\n r: parseInt(rgbMatch[1], 10),\n g: parseInt(rgbMatch[2], 10),\n b: parseInt(rgbMatch[3], 10),\n };\n }\n\n // Handle rgba() colors (ignore alpha)\n const rgbaMatch = trimmedColor.match(\n /rgba\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*[\\d.]+\\s*\\)/\n );\n if (rgbaMatch) {\n return {\n r: parseInt(rgbaMatch[1], 10),\n g: parseInt(rgbaMatch[2], 10),\n b: parseInt(rgbaMatch[3], 10),\n };\n }\n\n // Handle hsl() colors\n const hslMatch = trimmedColor.match(\n /hsl\\(\\s*(\\d+)\\s*,\\s*(\\d+)%\\s*,\\s*(\\d+)%\\s*\\)/\n );\n if (hslMatch) {\n const hsl: HslColor = {\n h: parseInt(hslMatch[1], 10),\n s: parseInt(hslMatch[2], 10),\n l: parseInt(hslMatch[3], 10),\n };\n return hslToRgb(hsl);\n }\n\n return null;\n}\n\nexport function hexToRgb(hex: string): RgbColor | null {\n const cleanHex = hex.replace('#', '');\n\n if (cleanHex.length === 3) {\n // Short hex format (e.g., #fff)\n return {\n r: parseInt(cleanHex[0] + cleanHex[0], 16),\n g: parseInt(cleanHex[1] + cleanHex[1], 16),\n b: parseInt(cleanHex[2] + cleanHex[2], 16),\n };\n } else if (cleanHex.length === 6) {\n // Long hex format (e.g., #ffffff)\n return {\n r: parseInt(cleanHex.slice(0, 2), 16),\n g: parseInt(cleanHex.slice(2, 4), 16),\n b: parseInt(cleanHex.slice(4, 6), 16),\n };\n }\n\n return null;\n}\n\nexport function hslToRgb(hsl: HslColor): RgbColor {\n // Normalize HSL values - handle both integer (0-360, 0-100, 0-100) and float inputs\n const h = (hsl.h % 360) / 360; // Ensure hue is in 0-1 range\n const s = Math.max(0, Math.min(100, hsl.s)) / 100; // Clamp saturation to 0-100, then normalize\n const l = Math.max(0, Math.min(100, hsl.l)) / 100; // Clamp lightness to 0-100, then normalize\n\n const hue2rgb = (p: number, q: number, t: number): number => {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n\n let r: number, g: number, b: number;\n\n if (s === 0) {\n r = g = b = l; // achromatic\n } else {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return {\n r: Math.round(Math.max(0, Math.min(255, r * 255))),\n g: Math.round(Math.max(0, Math.min(255, g * 255))),\n b: Math.round(Math.max(0, Math.min(255, b * 255))),\n };\n}\n","import { RgbColor, HslColor } from './types';\n\nexport function rgbToHex(rgb: RgbColor): string {\n const toHex = (n: number) => {\n const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);\n return hex.length === 1 ? '0' + hex : hex;\n };\n\n return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;\n}\n\nexport function rgbToHsl(rgb: RgbColor): HslColor {\n const r = rgb.r / 255;\n const g = rgb.g / 255;\n const b = rgb.b / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h = 0;\n let s = 0;\n const l = (max + min) / 2;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return {\n h: h * 360,\n s: s * 100,\n l: l * 100,\n };\n}\n\nexport function calculateLuminance(rgb: RgbColor): number {\n // Convert to linear RGB\n const toLinear = (c: number): number => {\n const normalized = c / 255;\n return normalized <= 0.03928\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n };\n\n const r = toLinear(rgb.r);\n const g = toLinear(rgb.g);\n const b = toLinear(rgb.b);\n\n // Calculate relative luminance using WCAG formula\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n","import { parseColor } from './parsers';\nimport { rgbToHex, rgbToHsl, calculateLuminance } from './converters';\nimport { hslToRgb } from './parsers';\n\nexport function deriveContrastColor(color: string): string {\n try {\n // Input validation\n if (!color || color.trim() === '') {\n return '#ffffff'; // fallback to white for invalid input\n }\n\n const rgb = parseColor(color);\n if (!rgb) {\n return '#ffffff'; // fallback to white if parsing fails\n }\n\n // Validate RGB values\n if (\n rgb.r < 0 ||\n rgb.r > 255 ||\n rgb.g < 0 ||\n rgb.g > 255 ||\n rgb.b < 0 ||\n rgb.b > 255\n ) {\n return '#ffffff'; // fallback to white for invalid RGB values\n }\n\n // Calculate relative luminance using WCAG formula\n const luminance = calculateLuminance(rgb);\n\n // WCAG contrast ratio threshold: use white text on dark backgrounds, black on light\n return luminance > 0.5 ? '#000000' : '#ffffff';\n } catch (error) {\n console.warn('Error in deriveContrastColor:', error);\n return '#ffffff'; // fallback to white on error\n }\n}\n\nexport function deriveOppositeColor(color: string): string {\n try {\n // Input validation\n if (!color || color.trim() === '') {\n return color; // return original for invalid input\n }\n\n const rgb = parseColor(color);\n if (!rgb) {\n return color; // return original if parsing fails\n }\n\n // Validate RGB values\n if (\n rgb.r < 0 ||\n rgb.r > 255 ||\n rgb.g < 0 ||\n rgb.g > 255 ||\n rgb.b < 0 ||\n rgb.b > 255\n ) {\n return color; // return original if invalid RGB values\n }\n\n const hsl = rgbToHsl(rgb);\n\n // Rotate hue 180 degrees for complementary color\n // Handle the floating-point hue value properly\n const oppositeHsl = {\n h: (hsl.h + 180) % 360,\n s: hsl.s,\n l: hsl.l,\n };\n\n const oppositeRgb = hslToRgb(oppositeHsl);\n return rgbToHex(oppositeRgb);\n } catch (error) {\n console.warn('Error in deriveOppositeColor:', error);\n return color; // return original on error\n }\n}\n","import { ThemeColor } from '@magmonium/cli';\nimport {\n ColorPropertyType,\n derivePropertyName,\n} from '../../../functions/css/property-names';\nimport {\n deriveContrastColor,\n deriveOppositeColor,\n} from '../../../functions/color/operations';\n\nconst colorPalletMap = new Map();\n\nexport interface ColorPallet {\n color: string;\n contrastColor: string;\n oppositeColor: string;\n}\n\nexport function resolvePallet(\n currentColor: string | keyof ThemeColor,\n themeColors?: ThemeColor\n): ColorPallet {\n // An unset colour is `mm` *before* the theme lookup, not after: falling back\n // afterwards leaves the literal key `mm` as the resolved colour, which is not\n // a CSS colour — the element then keeps whatever it painted last, and picking\n // `default` in a colour dropdown reads as the change not landing.\n const key = (currentColor || 'mm') as keyof ThemeColor;\n let color = (themeColors?.[key] ?? key) as string;\n\n // Prepend # if it's a hex code without the hash\n if (/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(color)) {\n color = `#${color}`;\n }\n\n const savedPallet = colorPalletMap.get(color);\n if (savedPallet) {\n return savedPallet;\n }\n const pallet = {\n color,\n contrastColor: deriveContrastColor(color),\n oppositeColor: deriveOppositeColor(color),\n };\n colorPalletMap.set(color, pallet);\n return pallet;\n}\n\nexport function applyColorsToElement(\n inputColor: keyof ThemeColor | string = 'mm',\n themeColors: ThemeColor | undefined,\n element: HTMLElement\n): ColorPallet | undefined {\n const pallet = resolvePallet(inputColor, themeColors),\n { color, contrastColor, oppositeColor } = pallet;\n \n const colorProp = derivePropertyName(element.tagName, 'color');\n const contrastProp = derivePropertyName(element.tagName, 'color-contrast');\n const oppositeProp = derivePropertyName(element.tagName, 'color-opposite');\n\n element.style.setProperty(colorProp, color);\n element.style.setProperty(contrastProp, contrastColor);\n element.style.setProperty(oppositeProp, oppositeColor);\n\n return pallet;\n}\n\nexport function addColorProperty(\n key: ColorPropertyType,\n value: string,\n element: HTMLElement\n): void {\n const inputString = element.tagName;\n element.style.setProperty(derivePropertyName(inputString, key), value);\n}\n"],"mappings":"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"}