mnfst 0.5.65 → 0.5.66

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.
@@ -0,0 +1,109 @@
1
+ /* Manifest Colors */
2
+
3
+ // Initialize plugin when either DOM is ready or Alpine is ready
4
+ function initializeColorsPlugin() {
5
+
6
+ // Initialize color mode state with Alpine reactivity
7
+ const colors = Alpine.reactive({
8
+ current: localStorage.getItem('theme') || 'system'
9
+ })
10
+
11
+ // Apply initial color mode
12
+ applyColorMode(colors.current)
13
+
14
+ // Setup system color mode listener
15
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
16
+ mediaQuery.addEventListener('change', () => {
17
+ if (colors.current === 'system') {
18
+ applyColorMode('system')
19
+ }
20
+ })
21
+
22
+ // Register colors directive
23
+ Alpine.directive('colors', (el, { expression }, { evaluate, cleanup }) => {
24
+
25
+ const handleClick = () => {
26
+ const newMode = expression === 'toggle'
27
+ ? (document.documentElement.classList.contains('dark') ? 'light' : 'dark')
28
+ : evaluate(expression)
29
+ setColorMode(newMode)
30
+ }
31
+
32
+ el.addEventListener('click', handleClick)
33
+ cleanup(() => el.removeEventListener('click', handleClick))
34
+ })
35
+
36
+ // Add $colors magic method
37
+ Alpine.magic('colors', () => ({
38
+ get current() {
39
+ return colors.current
40
+ },
41
+ set current(value) {
42
+ setColorMode(value)
43
+ }
44
+ }))
45
+
46
+ function setColorMode(newMode) {
47
+ if (newMode === 'toggle') {
48
+ newMode = colors.current === 'light' ? 'dark' : 'light'
49
+ }
50
+
51
+ // Update color mode state
52
+ colors.current = newMode
53
+ localStorage.setItem('theme', newMode)
54
+
55
+ // Apply color mode
56
+ applyColorMode(newMode)
57
+ }
58
+
59
+ function applyColorMode(mode) {
60
+ const isDark = mode === 'system'
61
+ ? window.matchMedia('(prefers-color-scheme: dark)').matches
62
+ : mode === 'dark'
63
+
64
+ // Update document classes
65
+ document.documentElement.classList.remove('light', 'dark')
66
+ document.documentElement.classList.add(isDark ? 'dark' : 'light')
67
+
68
+ // Update meta theme-color
69
+ const metaThemeColor = document.querySelector('meta[name="theme-color"]')
70
+ if (metaThemeColor) {
71
+ metaThemeColor.setAttribute('content', isDark ? '#000000' : '#FFFFFF')
72
+ }
73
+ }
74
+ }
75
+
76
+ // Track initialization to prevent duplicates
77
+ let colorsPluginInitialized = false;
78
+
79
+ function ensureColorsPluginInitialized() {
80
+ if (colorsPluginInitialized) return;
81
+ if (!window.Alpine || typeof window.Alpine.directive !== 'function') return;
82
+
83
+ colorsPluginInitialized = true;
84
+ initializeColorsPlugin();
85
+ }
86
+
87
+ // Expose on window for loader to call if needed
88
+ window.ensureColorsPluginInitialized = ensureColorsPluginInitialized;
89
+
90
+ // Handle both DOMContentLoaded and alpine:init
91
+ if (document.readyState === 'loading') {
92
+ document.addEventListener('DOMContentLoaded', ensureColorsPluginInitialized);
93
+ }
94
+
95
+ document.addEventListener('alpine:init', ensureColorsPluginInitialized);
96
+
97
+ // If Alpine is already initialized when this script loads, initialize immediately
98
+ if (window.Alpine && typeof window.Alpine.directive === 'function') {
99
+ setTimeout(ensureColorsPluginInitialized, 0);
100
+ } else {
101
+ // If document is already loaded but Alpine isn't ready yet, wait for it
102
+ const checkAlpine = setInterval(() => {
103
+ if (window.Alpine && typeof window.Alpine.directive === 'function') {
104
+ clearInterval(checkAlpine);
105
+ ensureColorsPluginInitialized();
106
+ }
107
+ }, 10);
108
+ setTimeout(() => clearInterval(checkAlpine), 5000);
109
+ }
@@ -162,7 +162,7 @@ window.ManifestComponentsProcessor = {
162
162
  }
163
163
  if (element.hasAttribute('data-pre-rendered') || element.hasAttribute('data-processed')) {
164
164
  // Pre-rendered components skip re-fetching, but hydrate-marked content
165
- // still needs Alpine initialization (x-data, @click, :class, x-theme etc.).
165
+ // still needs Alpine initialization (x-data, @click, :class, x-colors etc.).
166
166
  if (element.hasAttribute('data-pre-rendered') && window.Alpine && typeof window.Alpine.initTree === 'function') {
167
167
  try { window.Alpine.initTree(element); } catch (e) { /* graceful */ }
168
168
  }
package/lib/manifest.js CHANGED
@@ -191,7 +191,7 @@
191
191
  'markdown',
192
192
  'svg',
193
193
  'code',
194
- 'themes',
194
+ 'colors',
195
195
  'toasts',
196
196
  'tooltips',
197
197
  'dropdowns',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst",
3
- "version": "0.5.65",
3
+ "version": "0.5.66",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",
@@ -68,4 +68,4 @@
68
68
  "bugs": {
69
69
  "url": "https://github.com/Manifest-X/Manifest/issues"
70
70
  }
71
- }
71
+ }