@breadstone/mosaik-themes 0.0.182 → 0.0.183

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.0.182 (2025-11-30)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **themes:** refactor theme generator strategies and update build process ([55859a854f](https://github.com/RueDeRennes/mosaik/commit/55859a854f))
6
+
1
7
  ## 0.0.181 (2025-11-30)
2
8
 
3
9
  ### 🚀 Features
package/index.cjs CHANGED
@@ -2367,6 +2367,80 @@ exports.IThemePalette = void 0;
2367
2367
  ITheme2.getPaletteColor = getPaletteColor;
2368
2368
  })(exports.ITheme || (exports.ITheme = {}));
2369
2369
  exports.ITheme = void 0;
2370
+
2371
+ // src/Theming/Adapters/BrowserPlatformAdapter.ts
2372
+ var BrowserPlatformAdapter = class {
2373
+ static {
2374
+ __name(this, "BrowserPlatformAdapter");
2375
+ }
2376
+ // #region Methods
2377
+ matchMedia(query) {
2378
+ return window.matchMedia(query).matches;
2379
+ }
2380
+ setDocumentAttribute(name, value) {
2381
+ document.documentElement.setAttribute(name, value);
2382
+ }
2383
+ getDocumentAttribute(name) {
2384
+ return document.documentElement.getAttribute(name);
2385
+ }
2386
+ observeDocumentAttributes(attributes, callback) {
2387
+ const observer = new MutationObserver((mutations) => {
2388
+ mutations.forEach((mutation) => {
2389
+ if (mutation.type === "attributes" && mutation.attributeName) {
2390
+ const newValue = document.documentElement.getAttribute(mutation.attributeName);
2391
+ callback(mutation.attributeName, newValue);
2392
+ }
2393
+ });
2394
+ });
2395
+ observer.observe(document.documentElement, {
2396
+ attributes: true,
2397
+ attributeFilter: attributes
2398
+ });
2399
+ return () => observer.disconnect();
2400
+ }
2401
+ };
2402
+
2403
+ // src/Theming/Adapters/NodePlatformAdapter.ts
2404
+ var NodePlatformAdapter = class {
2405
+ static {
2406
+ __name(this, "NodePlatformAdapter");
2407
+ }
2408
+ // #region Methods
2409
+ matchMedia(_query) {
2410
+ return false;
2411
+ }
2412
+ setDocumentAttribute(_name, _value) {
2413
+ }
2414
+ getDocumentAttribute(_name) {
2415
+ return null;
2416
+ }
2417
+ observeDocumentAttributes(_attributes, _callback) {
2418
+ return () => {
2419
+ };
2420
+ }
2421
+ };
2422
+
2423
+ // src/Theming/Adapters/PlatformAdapterFactory.ts
2424
+ var PlatformAdapterFactory = class {
2425
+ static {
2426
+ __name(this, "PlatformAdapterFactory");
2427
+ }
2428
+ // #region Methods
2429
+ /**
2430
+ * Creates the appropriate platform adapter based on the current environment.
2431
+ * Automatically detects if running in browser or Node.js.
2432
+ *
2433
+ * @public
2434
+ */
2435
+ static create() {
2436
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
2437
+ return new BrowserPlatformAdapter();
2438
+ }
2439
+ return new NodePlatformAdapter();
2440
+ }
2441
+ };
2442
+
2443
+ // src/Theming/ThemeObserver.ts
2370
2444
  function isThemeMode(value) {
2371
2445
  return value === "system" || value === "dark" || value === "light";
2372
2446
  }
@@ -2378,17 +2452,21 @@ var ThemeObserver = class {
2378
2452
  // #region Fields
2379
2453
  _themeChanged;
2380
2454
  _themeModeChanged;
2455
+ _platformAdapter;
2381
2456
  _currentTheme;
2382
2457
  _currentThemeMode;
2458
+ _unsubscribe;
2383
2459
  // #region Ctor
2384
2460
  /**
2385
2461
  * Constructs a new instance of the `ThemeObserver` class.
2386
2462
  *
2463
+ * @param platformAdapter - Optional platform adapter. Auto-detects if not provided.
2387
2464
  * @public
2388
2465
  */
2389
- constructor() {
2466
+ constructor(platformAdapter) {
2390
2467
  this._themeChanged = new mosaikElements.PureEventEmitter();
2391
2468
  this._themeModeChanged = new mosaikElements.PureEventEmitter();
2469
+ this._platformAdapter = platformAdapter ?? PlatformAdapterFactory.create();
2392
2470
  this._currentTheme = null;
2393
2471
  this._currentThemeMode = null;
2394
2472
  this.observe({
@@ -2419,54 +2497,49 @@ var ThemeObserver = class {
2419
2497
  // #endregion
2420
2498
  // #region Methods
2421
2499
  applyTheme(theme, themeMode) {
2422
- document.documentElement.setAttribute("theme", theme);
2500
+ this._platformAdapter.setDocumentAttribute("theme", theme);
2423
2501
  switch (themeMode) {
2424
2502
  case "dark":
2425
2503
  case "light":
2426
- document.documentElement.setAttribute("theme-mode", themeMode);
2504
+ this._platformAdapter.setDocumentAttribute("theme-mode", themeMode);
2427
2505
  break;
2428
2506
  case "system":
2429
2507
  default:
2430
- if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
2431
- document.documentElement.setAttribute("theme-mode", "dark");
2432
- } else {
2433
- document.documentElement.setAttribute("theme-mode", "light");
2434
- }
2508
+ const isDark = this._platformAdapter.matchMedia("(prefers-color-scheme: dark)");
2509
+ this._platformAdapter.setDocumentAttribute("theme-mode", isDark ? "dark" : "light");
2435
2510
  break;
2436
2511
  }
2437
2512
  }
2513
+ dispose() {
2514
+ if (this._unsubscribe) {
2515
+ this._unsubscribe();
2516
+ this._unsubscribe = void 0;
2517
+ }
2518
+ }
2438
2519
  observe(cb) {
2439
- this._currentTheme = document.documentElement.getAttribute("theme");
2440
- this._currentThemeMode = document.documentElement.getAttribute("theme-mode");
2441
- const observer = new MutationObserver((mutations) => {
2442
- mutations.forEach((mutation) => {
2443
- if (mutation.type === "attributes") {
2444
- if (mutation.attributeName === "theme") {
2445
- const theme = document.documentElement.getAttribute("theme");
2446
- if (this._currentTheme !== theme) {
2447
- this._currentTheme = theme;
2448
- cb.themeChange(theme);
2449
- }
2450
- }
2451
- if (mutation.attributeName === "theme-mode") {
2452
- const themeMode = document.documentElement.getAttribute("theme-mode");
2453
- if (!isThemeMode(themeMode)) {
2454
- throw new Error(`Invalid theme mode: ${String(themeMode)}`);
2455
- }
2456
- if (this._currentThemeMode !== themeMode) {
2457
- this._currentThemeMode = themeMode;
2458
- cb.themeModeChange(themeMode);
2459
- }
2460
- }
2520
+ this._currentTheme = this._platformAdapter.getDocumentAttribute("theme");
2521
+ this._currentThemeMode = this._platformAdapter.getDocumentAttribute("theme-mode");
2522
+ this._unsubscribe = this._platformAdapter.observeDocumentAttributes([
2523
+ "theme",
2524
+ "theme-mode"
2525
+ ], (attributeName, newValue) => {
2526
+ if (attributeName === "theme") {
2527
+ const theme = newValue;
2528
+ if (this._currentTheme !== theme) {
2529
+ this._currentTheme = theme;
2530
+ cb.themeChange(theme);
2461
2531
  }
2462
- });
2463
- });
2464
- observer.observe(document.documentElement, {
2465
- attributes: true,
2466
- attributeFilter: [
2467
- "theme",
2468
- "theme-mode"
2469
- ]
2532
+ }
2533
+ if (attributeName === "theme-mode") {
2534
+ const themeMode = newValue;
2535
+ if (!isThemeMode(themeMode)) {
2536
+ throw new Error(`Invalid theme mode: ${String(themeMode)}`);
2537
+ }
2538
+ if (this._currentThemeMode !== themeMode) {
2539
+ this._currentThemeMode = themeMode;
2540
+ cb.themeModeChange(themeMode);
2541
+ }
2542
+ }
2470
2543
  });
2471
2544
  }
2472
2545
  };
@@ -2756,9 +2829,14 @@ var ThemeGenerator = class {
2756
2829
  }
2757
2830
  // #region Fields
2758
2831
  _strategies;
2832
+ _platformAdapter;
2759
2833
  // #endregion
2760
2834
  // #region Ctor
2761
- constructor() {
2835
+ /**
2836
+ * @param platformAdapter - Optional platform adapter. Auto-detects if not provided.
2837
+ * @public
2838
+ */
2839
+ constructor(platformAdapter) {
2762
2840
  this._strategies = /* @__PURE__ */ new Map([
2763
2841
  [
2764
2842
  "material",
@@ -2777,6 +2855,7 @@ var ThemeGenerator = class {
2777
2855
  new CosmopolitanThemeGeneratorStrategy()
2778
2856
  ]
2779
2857
  ]);
2858
+ this._platformAdapter = platformAdapter ?? PlatformAdapterFactory.create();
2780
2859
  }
2781
2860
  // #endregion
2782
2861
  // #region Methods
@@ -2792,7 +2871,8 @@ var ThemeGenerator = class {
2792
2871
  }
2793
2872
  resolveMode(mode) {
2794
2873
  if (mode === "system") {
2795
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
2874
+ const isDark = this._platformAdapter.matchMedia("(prefers-color-scheme: dark)");
2875
+ return isDark ? "dark" : "light";
2796
2876
  }
2797
2877
  return mode;
2798
2878
  }
@@ -2904,10 +2984,13 @@ function createTailwindTheme() {
2904
2984
  }
2905
2985
  __name(createTailwindTheme, "createTailwindTheme");
2906
2986
 
2987
+ exports.BrowserPlatformAdapter = BrowserPlatformAdapter;
2907
2988
  exports.CosmopolitanThemeGeneratorStrategy = CosmopolitanThemeGeneratorStrategy;
2908
2989
  exports.JoyThemeGeneratorStrategy = JoyThemeGeneratorStrategy;
2909
2990
  exports.MaterialThemeGeneratorStrategy = MaterialThemeGeneratorStrategy;
2910
2991
  exports.MemphisThemeGeneratorStrategy = MemphisThemeGeneratorStrategy;
2992
+ exports.NodePlatformAdapter = NodePlatformAdapter;
2993
+ exports.PlatformAdapterFactory = PlatformAdapterFactory;
2911
2994
  exports.TailwindThemeGeneratorStrategy = TailwindThemeGeneratorStrategy;
2912
2995
  exports.ThemeGenerator = ThemeGenerator;
2913
2996
  exports.ThemeGeneratorServiceLocator = ThemeGeneratorServiceLocator;