@marianmeres/stuic 3.89.0 → 3.90.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,21 @@
1
+ type Scheme = "dark" | "light";
1
2
  /**
2
3
  * A utility class for managing light/dark color scheme preferences.
3
4
  *
4
5
  * Handles system preferences, localStorage persistence, and DOM class toggling.
5
6
  * Works with Tailwind CSS dark mode (class-based strategy).
6
7
  *
8
+ * The `ColorScheme.current` getter is reactive (Svelte 5 `$state`): reading it
9
+ * inside a `$derived`/`$effect`/template will react to toggles, cross-tab
10
+ * `storage` events, and OS-level system-preference changes.
11
+ *
7
12
  * @example
8
13
  * ```ts
9
- * // Get current color scheme (local preference or system default)
10
- * const scheme = ColorScheme.getValue(); // 'light' or 'dark'
14
+ * // Reactive current value (use in templates / $derived / $effect):
15
+ * const scheme = ColorScheme.current; // 'light' or 'dark'
16
+ *
17
+ * // Backward-compatible non-reactive read:
18
+ * const v = ColorScheme.getValue();
11
19
  *
12
20
  * // Toggle between light and dark
13
21
  * ColorScheme.toggle();
@@ -28,18 +36,24 @@ export declare class ColorScheme {
28
36
  static readonly KEY: "stuic-color-scheme";
29
37
  static readonly DARK: "dark";
30
38
  static readonly LIGHT: "light";
39
+ /**
40
+ * Reactive current value. Read inside `$derived`, `$effect`, or a Svelte
41
+ * template to react to scheme changes (including cross-tab `storage`
42
+ * events and OS-level system-preference changes).
43
+ */
44
+ static get current(): Scheme;
31
45
  /**
32
46
  * Reads the `prefers-color-scheme` system setting
33
47
  */
34
- static getSystemValue(): "dark" | "light";
48
+ static getSystemValue(): Scheme;
35
49
  /**
36
50
  * Reads locally (localStorage) saved value
37
51
  */
38
- static getLocalValue(fallback?: "dark" | "light"): "dark" | "light";
52
+ static getLocalValue(fallback?: Scheme): Scheme;
39
53
  /**
40
- * Tries local first, fallbacks to system
54
+ * Tries local first, fallbacks to system. Backward-compatible alias for `current`.
41
55
  */
42
- static getValue(): "dark" | "light";
56
+ static getValue(): Scheme;
43
57
  /**
44
58
  * Sets and saves the opposite of current.
45
59
  */
@@ -49,3 +63,4 @@ export declare class ColorScheme {
49
63
  */
50
64
  static reset(): void;
51
65
  }
66
+ export {};
@@ -1,13 +1,29 @@
1
+ let _current = $state("light");
2
+ function _compute() {
3
+ return ColorScheme.getLocalValue(ColorScheme.getSystemValue());
4
+ }
5
+ function _sync() {
6
+ const next = _compute();
7
+ if (next !== _current)
8
+ _current = next;
9
+ }
1
10
  /**
2
11
  * A utility class for managing light/dark color scheme preferences.
3
12
  *
4
13
  * Handles system preferences, localStorage persistence, and DOM class toggling.
5
14
  * Works with Tailwind CSS dark mode (class-based strategy).
6
15
  *
16
+ * The `ColorScheme.current` getter is reactive (Svelte 5 `$state`): reading it
17
+ * inside a `$derived`/`$effect`/template will react to toggles, cross-tab
18
+ * `storage` events, and OS-level system-preference changes.
19
+ *
7
20
  * @example
8
21
  * ```ts
9
- * // Get current color scheme (local preference or system default)
10
- * const scheme = ColorScheme.getValue(); // 'light' or 'dark'
22
+ * // Reactive current value (use in templates / $derived / $effect):
23
+ * const scheme = ColorScheme.current; // 'light' or 'dark'
24
+ *
25
+ * // Backward-compatible non-reactive read:
26
+ * const v = ColorScheme.getValue();
11
27
  *
12
28
  * // Toggle between light and dark
13
29
  * ColorScheme.toggle();
@@ -28,6 +44,14 @@ export class ColorScheme {
28
44
  static KEY = "stuic-color-scheme";
29
45
  static DARK = "dark";
30
46
  static LIGHT = "light";
47
+ /**
48
+ * Reactive current value. Read inside `$derived`, `$effect`, or a Svelte
49
+ * template to react to scheme changes (including cross-tab `storage`
50
+ * events and OS-level system-preference changes).
51
+ */
52
+ static get current() {
53
+ return _current;
54
+ }
31
55
  /**
32
56
  * Reads the `prefers-color-scheme` system setting
33
57
  */
@@ -43,10 +67,10 @@ export class ColorScheme {
43
67
  return (globalThis.localStorage?.getItem(ColorScheme.KEY) || fallback);
44
68
  }
45
69
  /**
46
- * Tries local first, fallbacks to system
70
+ * Tries local first, fallbacks to system. Backward-compatible alias for `current`.
47
71
  */
48
72
  static getValue() {
49
- return ColorScheme.getLocalValue(ColorScheme.getSystemValue());
73
+ return ColorScheme.current;
50
74
  }
51
75
  /**
52
76
  * Sets and saves the opposite of current.
@@ -55,6 +79,7 @@ export class ColorScheme {
55
79
  // returns bool, indicating whether token is in the list after the call or not.
56
80
  const isDark = globalThis?.document?.documentElement.classList.toggle(ColorScheme.DARK);
57
81
  globalThis.localStorage?.setItem(ColorScheme.KEY, isDark ? ColorScheme.DARK : ColorScheme.LIGHT);
82
+ _sync();
58
83
  }
59
84
  /**
60
85
  * Resets color scheme to system preference by removing localStorage value and classes.
@@ -62,5 +87,16 @@ export class ColorScheme {
62
87
  static reset() {
63
88
  globalThis.localStorage?.removeItem(ColorScheme.KEY);
64
89
  globalThis?.document?.documentElement.classList.remove(ColorScheme.DARK, ColorScheme.LIGHT);
90
+ _sync();
65
91
  }
66
92
  }
93
+ if (typeof window !== "undefined") {
94
+ _current = _compute();
95
+ window.addEventListener("storage", (e) => {
96
+ if (e.key === ColorScheme.KEY)
97
+ _sync();
98
+ });
99
+ window
100
+ .matchMedia?.(`(prefers-color-scheme: ${ColorScheme.DARK})`)
101
+ .addEventListener("change", () => _sync());
102
+ }
@@ -1,3 +1,3 @@
1
- export * from "./color-scheme.js";
1
+ export * from "./color-scheme.svelte.js";
2
2
  export { default as ColorSchemeLocal, type Props as ColorSchemeLocalProps, } from "./ColorSchemeLocal.svelte";
3
3
  export { default as ColorSchemeSystemAware, type Props as ColorSchemeSystemAwareProps, } from "./ColorSchemeSystemAware.svelte";
@@ -1,3 +1,3 @@
1
- export * from "./color-scheme.js";
1
+ export * from "./color-scheme.svelte.js";
2
2
  export { default as ColorSchemeLocal, } from "./ColorSchemeLocal.svelte";
3
3
  export { default as ColorSchemeSystemAware, } from "./ColorSchemeSystemAware.svelte";
@@ -205,14 +205,13 @@
205
205
  colorScheme === false ? false : cs.enabled !== false /* default true */
206
206
  );
207
207
 
208
- function readIsDark(): boolean {
209
- return cs.isDark ? cs.isDark() : ColorScheme.getValue() === "dark";
210
- }
211
-
212
- let isDark = $state(false);
213
- $effect(() => {
214
- if (csEnabled) isDark = readIsDark();
215
- });
208
+ const isDark = $derived(
209
+ csEnabled
210
+ ? cs.isDark
211
+ ? cs.isDark()
212
+ : ColorScheme.current === "dark"
213
+ : false
214
+ );
216
215
 
217
216
  function toggleColorScheme() {
218
217
  if (cs.onToggle) {
@@ -220,7 +219,6 @@
220
219
  } else {
221
220
  ColorScheme.toggle();
222
221
  }
223
- isDark = readIsDark();
224
222
  }
225
223
 
226
224
  // Default labels (English)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "3.89.0",
3
+ "version": "3.90.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && pnpm run prepack",