@r2digisolutions/components 0.6.10 → 0.7.1

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,12 +1,16 @@
1
1
  /**
2
- * Theme store — Light/Dark mode management for R2DigiSolutions components.
2
+ * Theme store — light/dark + gray palette for R2DigiSolutions components.
3
+ *
4
+ * Mode: `class="dark"` on `<html>`
5
+ * Palette: `data-theme="slate" | "neutral"` on `<html>`
3
6
  *
4
7
  * - Persists preference to localStorage
5
8
  * - Detects system preference via prefers-color-scheme
6
- * - Applies 'dark' class to <html> element
7
9
  * - Reactive via Svelte 5 runes ($state)
8
10
  */
9
11
  const STORAGE_KEY = 'r2-theme';
12
+ const PALETTE_KEY = 'r2-theme-palette';
13
+ const DEFAULT_PALETTE = 'slate';
10
14
  function getSystemTheme() {
11
15
  if (typeof window === 'undefined')
12
16
  return 'light';
@@ -17,23 +21,46 @@ function getStoredTheme() {
17
21
  return 'system';
18
22
  return localStorage.getItem(STORAGE_KEY) ?? 'system';
19
23
  }
20
- function applyTheme(theme) {
24
+ function isPalette(value) {
25
+ return value === 'slate' || value === 'neutral';
26
+ }
27
+ function getStoredPalette() {
28
+ if (typeof localStorage === 'undefined')
29
+ return DEFAULT_PALETTE;
30
+ const stored = localStorage.getItem(PALETTE_KEY);
31
+ if (isPalette(stored))
32
+ return stored;
33
+ if (typeof document !== 'undefined') {
34
+ const attr = document.documentElement.getAttribute('data-theme');
35
+ if (isPalette(attr))
36
+ return attr;
37
+ }
38
+ return DEFAULT_PALETTE;
39
+ }
40
+ function applyMode(theme) {
21
41
  if (typeof document === 'undefined')
22
42
  return;
23
43
  const resolved = theme === 'system' ? getSystemTheme() : theme;
24
44
  document.documentElement.classList.toggle('dark', resolved === 'dark');
25
45
  }
46
+ function applyPalette(palette) {
47
+ if (typeof document === 'undefined')
48
+ return;
49
+ document.documentElement.setAttribute('data-theme', palette);
50
+ }
26
51
  class ThemeStore {
27
52
  #theme = $state('system');
53
+ #palette = $state(DEFAULT_PALETTE);
28
54
  #resolved = $derived(this.#theme === 'system' ? getSystemTheme() : this.#theme);
29
55
  constructor() {
30
56
  if (typeof window !== 'undefined') {
31
57
  this.#theme = getStoredTheme();
32
- applyTheme(this.#theme);
33
- // Listen for system theme changes
58
+ this.#palette = getStoredPalette();
59
+ applyMode(this.#theme);
60
+ applyPalette(this.#palette);
34
61
  window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
35
62
  if (this.#theme === 'system') {
36
- applyTheme('system');
63
+ applyMode('system');
37
64
  }
38
65
  });
39
66
  }
@@ -41,6 +68,9 @@ class ThemeStore {
41
68
  get theme() {
42
69
  return this.#theme;
43
70
  }
71
+ get palette() {
72
+ return this.#palette;
73
+ }
44
74
  get resolved() {
45
75
  return this.#resolved;
46
76
  }
@@ -52,7 +82,21 @@ class ThemeStore {
52
82
  if (typeof localStorage !== 'undefined') {
53
83
  localStorage.setItem(STORAGE_KEY, theme);
54
84
  }
55
- applyTheme(theme);
85
+ applyMode(theme);
86
+ }
87
+ /**
88
+ * Gray family for surfaces, borders and body text.
89
+ * `slate` = cool (hue 265). `neutral` = chroma 0, no blue cast.
90
+ *
91
+ * Pass `{ persist: false }` for a page-level override that does not
92
+ * stick in localStorage.
93
+ */
94
+ setPalette(palette, opts) {
95
+ this.#palette = palette;
96
+ if (opts?.persist !== false && typeof localStorage !== 'undefined') {
97
+ localStorage.setItem(PALETTE_KEY, palette);
98
+ }
99
+ applyPalette(palette);
56
100
  }
57
101
  toggle() {
58
102
  this.set(this.isDark ? 'light' : 'dark');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@r2digisolutions/components",
3
- "version": "0.6.10",
3
+ "version": "0.7.1",
4
4
  "private": false,
5
5
  "description": "R2DigiSolutions Svelte 5 component library — Atomic Design, Tailwind 4, Light/Dark mode",
6
6
  "license": "MIT",
@@ -81,8 +81,8 @@
81
81
  "@tailwindcss/vite": "^4.3.3",
82
82
  "@types/node": "^26.2.0",
83
83
  "@vitest/browser-playwright": "^4.1.11",
84
- "bumpp": "~11.1.0",
85
- "eslint": "^10.8.1",
84
+ "bumpp": "~12.2.1",
85
+ "eslint": "^10.9.0",
86
86
  "eslint-config-prettier": "^10.1.8",
87
87
  "eslint-plugin-svelte": "^3.23.0",
88
88
  "globals": "^17.11.0",
@@ -93,7 +93,7 @@
93
93
  "prettier-plugin-tailwindcss": "^0.8.1",
94
94
  "publint": "^0.3.24",
95
95
  "storybook": "^10.5.10",
96
- "svelte": "^5.56.9",
96
+ "svelte": "^5.56.10",
97
97
  "svelte-check": "^4.7.6",
98
98
  "tailwindcss": "^4.3.3",
99
99
  "typescript": "6.0.3",
@@ -113,4 +113,4 @@
113
113
  "dependencies": {
114
114
  "@xyflow/svelte": "^1.6.3"
115
115
  }
116
- }
116
+ }