@omerdlw/base-framework 1.0.6 → 2.0.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.
Files changed (231) hide show
  1. package/dist/atoms/index.js +1 -103
  2. package/dist/atoms/index.js.map +1 -1
  3. package/dist/chunk-3BUP64Q6.js +105 -0
  4. package/dist/chunk-3BUP64Q6.js.map +1 -0
  5. package/dist/chunk-3MSK4XGK.js +9888 -0
  6. package/dist/chunk-3MSK4XGK.js.map +1 -0
  7. package/dist/chunk-4GMQKD6F.js +353 -0
  8. package/dist/chunk-4GMQKD6F.js.map +1 -0
  9. package/dist/chunk-65ZB4QTQ.js +888 -0
  10. package/dist/chunk-65ZB4QTQ.js.map +1 -0
  11. package/dist/chunk-6SG7V77J.js +577 -0
  12. package/dist/chunk-6SG7V77J.js.map +1 -0
  13. package/dist/chunk-7HQMXTNP.js +419 -0
  14. package/dist/chunk-7HQMXTNP.js.map +1 -0
  15. package/dist/chunk-7TAVYJ3A.js +371 -0
  16. package/dist/chunk-7TAVYJ3A.js.map +1 -0
  17. package/dist/chunk-AQ4BNXA2.js +349 -0
  18. package/dist/chunk-AQ4BNXA2.js.map +1 -0
  19. package/dist/chunk-CGHZSSFR.js +2166 -0
  20. package/dist/chunk-CGHZSSFR.js.map +1 -0
  21. package/dist/chunk-DGCQWQLZ.js +61 -0
  22. package/dist/chunk-DGCQWQLZ.js.map +1 -0
  23. package/dist/chunk-FIMPHODX.js +67 -0
  24. package/dist/chunk-FIMPHODX.js.map +1 -0
  25. package/dist/chunk-GF7TUX5I.js +1889 -0
  26. package/dist/chunk-GF7TUX5I.js.map +1 -0
  27. package/dist/chunk-JELG4JLT.js +454 -0
  28. package/dist/chunk-JELG4JLT.js.map +1 -0
  29. package/dist/chunk-K676GL7Z.js +51 -0
  30. package/dist/chunk-K676GL7Z.js.map +1 -0
  31. package/dist/chunk-KKQT46TP.js +26 -0
  32. package/dist/chunk-KKQT46TP.js.map +1 -0
  33. package/dist/chunk-QI3ALLIB.js +38 -0
  34. package/dist/chunk-QI3ALLIB.js.map +1 -0
  35. package/dist/chunk-QXR55VVS.js +1139 -0
  36. package/dist/chunk-QXR55VVS.js.map +1 -0
  37. package/dist/chunk-R2YGFJDJ.js +408 -0
  38. package/dist/chunk-R2YGFJDJ.js.map +1 -0
  39. package/dist/chunk-RFZQWLC5.js +27 -0
  40. package/dist/chunk-RFZQWLC5.js.map +1 -0
  41. package/dist/chunk-SYAVGTOX.js +521 -0
  42. package/dist/chunk-SYAVGTOX.js.map +1 -0
  43. package/dist/chunk-TV3WEF5G.js +784 -0
  44. package/dist/chunk-TV3WEF5G.js.map +1 -0
  45. package/dist/chunk-XASQT4CQ.js +280 -0
  46. package/dist/chunk-XASQT4CQ.js.map +1 -0
  47. package/dist/error/index.js +5 -682
  48. package/dist/error/index.js.map +1 -1
  49. package/dist/error/reporter.d.ts.map +1 -1
  50. package/dist/error/theme.d.ts +1 -1
  51. package/dist/error/theme.d.ts.map +1 -1
  52. package/dist/events.js +1 -7
  53. package/dist/events.js.map +1 -1
  54. package/dist/hooks/index.js +1 -358
  55. package/dist/hooks/index.js.map +1 -1
  56. package/dist/hooks/use-global-event.d.ts +1 -1
  57. package/dist/index.js +18 -20029
  58. package/dist/index.js.map +1 -1
  59. package/dist/kernel/index.js +2 -2035
  60. package/dist/kernel/index.js.map +1 -1
  61. package/dist/kernel/types.d.ts +1 -1
  62. package/dist/modules/ambient/analyze.d.ts +46 -0
  63. package/dist/modules/ambient/analyze.d.ts.map +1 -0
  64. package/dist/modules/ambient/constants.d.ts +1 -5
  65. package/dist/modules/ambient/constants.d.ts.map +1 -1
  66. package/dist/modules/ambient/context.d.ts.map +1 -1
  67. package/dist/modules/ambient/dom.d.ts +11 -12
  68. package/dist/modules/ambient/dom.d.ts.map +1 -1
  69. package/dist/modules/ambient/extractor.d.ts +10 -10
  70. package/dist/modules/ambient/extractor.d.ts.map +1 -1
  71. package/dist/modules/ambient/hooks.d.ts +1 -1
  72. package/dist/modules/ambient/hooks.d.ts.map +1 -1
  73. package/dist/modules/ambient/index.d.ts +6 -4
  74. package/dist/modules/ambient/index.d.ts.map +1 -1
  75. package/dist/modules/ambient/index.js +7 -762
  76. package/dist/modules/ambient/index.js.map +1 -1
  77. package/dist/modules/ambient/module.d.ts +1 -1
  78. package/dist/modules/ambient/module.d.ts.map +1 -1
  79. package/dist/modules/ambient/oklab.d.ts +36 -0
  80. package/dist/modules/ambient/oklab.d.ts.map +1 -0
  81. package/dist/modules/ambient/pipeline.d.ts +28 -0
  82. package/dist/modules/ambient/pipeline.d.ts.map +1 -0
  83. package/dist/modules/ambient/quantize.d.ts +22 -0
  84. package/dist/modules/ambient/quantize.d.ts.map +1 -0
  85. package/dist/modules/ambient/server/address.d.ts +8 -0
  86. package/dist/modules/ambient/server/address.d.ts.map +1 -0
  87. package/dist/modules/ambient/server/index.d.ts +53 -0
  88. package/dist/modules/ambient/server/index.d.ts.map +1 -0
  89. package/dist/modules/ambient/server/index.js +221 -0
  90. package/dist/modules/ambient/server/index.js.map +1 -0
  91. package/dist/modules/ambient/settings.d.ts +19 -0
  92. package/dist/modules/ambient/settings.d.ts.map +1 -0
  93. package/dist/modules/ambient/types.d.ts +105 -9
  94. package/dist/modules/ambient/types.d.ts.map +1 -1
  95. package/dist/modules/ambient/worker/index.d.ts +15 -0
  96. package/dist/modules/ambient/worker/index.d.ts.map +1 -0
  97. package/dist/modules/ambient/worker/index.js +114 -0
  98. package/dist/modules/ambient/worker/index.js.map +1 -0
  99. package/dist/modules/background/constants.d.ts +2 -2
  100. package/dist/modules/background/constants.d.ts.map +1 -1
  101. package/dist/modules/background/hooks.d.ts +1 -1
  102. package/dist/modules/background/index.js +6 -3078
  103. package/dist/modules/background/index.js.map +1 -1
  104. package/dist/modules/background/motion.d.ts +9 -7
  105. package/dist/modules/background/motion.d.ts.map +1 -1
  106. package/dist/modules/background/overlay.d.ts +3 -8
  107. package/dist/modules/background/overlay.d.ts.map +1 -1
  108. package/dist/modules/background/types.d.ts +16 -2
  109. package/dist/modules/background/types.d.ts.map +1 -1
  110. package/dist/modules/context-menu/constants.d.ts +2 -2
  111. package/dist/modules/context-menu/constants.d.ts.map +1 -1
  112. package/dist/modules/context-menu/hooks.d.ts +1 -1
  113. package/dist/modules/context-menu/index.js +10 -1896
  114. package/dist/modules/context-menu/index.js.map +1 -1
  115. package/dist/modules/context-menu/motion.d.ts +1 -8
  116. package/dist/modules/context-menu/motion.d.ts.map +1 -1
  117. package/dist/modules/context-menu/overlay.d.ts.map +1 -1
  118. package/dist/modules/context-menu/types.d.ts +16 -2
  119. package/dist/modules/context-menu/types.d.ts.map +1 -1
  120. package/dist/modules/controls/constants.d.ts +1 -1
  121. package/dist/modules/controls/constants.d.ts.map +1 -1
  122. package/dist/modules/controls/entries.d.ts +1 -1
  123. package/dist/modules/controls/hooks.d.ts +1 -1
  124. package/dist/modules/controls/index.js +4 -1110
  125. package/dist/modules/controls/index.js.map +1 -1
  126. package/dist/modules/controls/overlay.d.ts +1 -1
  127. package/dist/modules/controls/types.d.ts +2 -2
  128. package/dist/modules/dock/cards.d.ts +708 -24
  129. package/dist/modules/dock/cards.d.ts.map +1 -1
  130. package/dist/modules/dock/constants.d.ts +2 -2
  131. package/dist/modules/dock/constants.d.ts.map +1 -1
  132. package/dist/modules/dock/helpers.d.ts +2 -2
  133. package/dist/modules/dock/hooks.d.ts +2 -2
  134. package/dist/modules/dock/index.d.ts +1 -1
  135. package/dist/modules/dock/index.d.ts.map +1 -1
  136. package/dist/modules/dock/index.js +9 -12132
  137. package/dist/modules/dock/index.js.map +1 -1
  138. package/dist/modules/dock/module.d.ts +1 -1
  139. package/dist/modules/dock/motion.d.ts +41 -915
  140. package/dist/modules/dock/motion.d.ts.map +1 -1
  141. package/dist/modules/dock/overlay.d.ts.map +1 -1
  142. package/dist/modules/dock/runtime/dock.d.ts +1 -23
  143. package/dist/modules/dock/runtime/dock.d.ts.map +1 -1
  144. package/dist/modules/dock/styles.d.ts +4 -4
  145. package/dist/modules/dock/surface/hooks.d.ts +5 -20
  146. package/dist/modules/dock/surface/hooks.d.ts.map +1 -1
  147. package/dist/modules/dock/surface/machine.d.ts +4 -3
  148. package/dist/modules/dock/surface/machine.d.ts.map +1 -1
  149. package/dist/modules/dock/surface/stack.d.ts.map +1 -1
  150. package/dist/modules/dock/types.d.ts +158 -3
  151. package/dist/modules/dock/types.d.ts.map +1 -1
  152. package/dist/modules/index.js +16 -17883
  153. package/dist/modules/index.js.map +1 -1
  154. package/dist/modules/loading/constants.d.ts +1 -1
  155. package/dist/modules/loading/constants.d.ts.map +1 -1
  156. package/dist/modules/loading/context.d.ts +1 -1
  157. package/dist/modules/loading/hooks.d.ts +1 -1
  158. package/dist/modules/loading/index.js +5 -1153
  159. package/dist/modules/loading/index.js.map +1 -1
  160. package/dist/modules/loading/types.d.ts +2 -2
  161. package/dist/modules/media/context.d.ts +1 -1
  162. package/dist/modules/media/index.js +3 -570
  163. package/dist/modules/media/index.js.map +1 -1
  164. package/dist/modules/media/types.d.ts +2 -2
  165. package/dist/modules/modal/constants.d.ts +2 -2
  166. package/dist/modules/modal/constants.d.ts.map +1 -1
  167. package/dist/modules/modal/context.d.ts +1 -1
  168. package/dist/modules/modal/hooks.d.ts +3 -3
  169. package/dist/modules/modal/index.js +8 -2355
  170. package/dist/modules/modal/index.js.map +1 -1
  171. package/dist/modules/modal/motion.d.ts +3 -8
  172. package/dist/modules/modal/motion.d.ts.map +1 -1
  173. package/dist/modules/modal/overlay.d.ts.map +1 -1
  174. package/dist/modules/modal/types.d.ts +21 -0
  175. package/dist/modules/modal/types.d.ts.map +1 -1
  176. package/dist/modules/notification/constants.d.ts +2 -2
  177. package/dist/modules/notification/constants.d.ts.map +1 -1
  178. package/dist/modules/notification/context.d.ts +1 -1
  179. package/dist/modules/notification/hooks.d.ts +1 -1
  180. package/dist/modules/notification/index.js +4 -828
  181. package/dist/modules/notification/index.js.map +1 -1
  182. package/dist/modules/notification/motion.d.ts +1 -7
  183. package/dist/modules/notification/motion.d.ts.map +1 -1
  184. package/dist/modules/notification/overlay.d.ts.map +1 -1
  185. package/dist/modules/notification/types.d.ts +9 -1
  186. package/dist/modules/notification/types.d.ts.map +1 -1
  187. package/dist/overlay-TZ6L52A5.js +9 -0
  188. package/dist/overlay-TZ6L52A5.js.map +1 -0
  189. package/dist/provider.d.ts +1 -1
  190. package/dist/provider.d.ts.map +1 -1
  191. package/dist/provider.js +6 -1968
  192. package/dist/provider.js.map +1 -1
  193. package/dist/result.js +2 -63
  194. package/dist/result.js.map +1 -1
  195. package/dist/theme.d.ts +45 -8
  196. package/dist/theme.d.ts.map +1 -1
  197. package/dist/theme.js +3 -41
  198. package/dist/theme.js.map +1 -1
  199. package/dist/tokens/index.d.ts +1 -0
  200. package/dist/tokens/index.d.ts.map +1 -1
  201. package/dist/tokens/index.js +126 -155
  202. package/dist/tokens/index.js.map +1 -1
  203. package/dist/tokens/motion-config.d.ts +44 -0
  204. package/dist/tokens/motion-config.d.ts.map +1 -0
  205. package/dist/tokens/motion.d.ts +23 -174
  206. package/dist/tokens/motion.d.ts.map +1 -1
  207. package/dist/utils/index.js +4 -82
  208. package/dist/utils/index.js.map +1 -1
  209. package/dist/utils/report.d.ts.map +1 -1
  210. package/docs/README.md +1 -0
  211. package/docs/architecture-and-rules.md +4 -3
  212. package/docs/core-engine.md +7 -10
  213. package/docs/getting-started.md +4 -2
  214. package/docs/modules/ambient.md +194 -80
  215. package/docs/modules/background.md +3 -3
  216. package/docs/modules/context-menu.md +2 -2
  217. package/docs/modules/dock.md +8 -5
  218. package/docs/modules/modal.md +2 -2
  219. package/docs/modules/notification.md +2 -2
  220. package/docs/theming.md +81 -9
  221. package/package.json +22 -5
  222. package/templates/AGENTS.md +1 -1
  223. package/templates/motion/background.ts +17 -0
  224. package/templates/motion/context-menu.ts +63 -0
  225. package/templates/motion/dock.ts +327 -0
  226. package/templates/motion/modal.ts +79 -0
  227. package/templates/motion/notification.ts +27 -0
  228. package/templates/motion/tokens.ts +47 -0
  229. package/templates/tsconfig.json +7 -0
  230. package/dist/modules/ambient/color.d.ts +0 -21
  231. package/dist/modules/ambient/color.d.ts.map +0 -1
@@ -1,765 +1,10 @@
1
1
  "use client";
2
- import { createContext, useState, useMemo, useEffect, use, useRef, useContext, useCallback, useSyncExternalStore } from 'react';
3
- import { jsx } from 'react/jsx-runtime';
4
- import 'next/navigation';
5
-
6
- function getOrCreateGlobalContext(name, defaultValue) {
7
- const sym = /* @__PURE__ */ Symbol.for(`@omerdlw/base-framework/context/${name}`);
8
- const store = globalThis;
9
- if (!store[sym]) {
10
- store[sym] = createContext(defaultValue);
11
- }
12
- return store[sym];
13
- }
14
-
15
- // src/utils/object.ts
16
- function shallowEqual(a, b) {
17
- if (Object.is(a, b)) return true;
18
- if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
19
- return false;
20
- }
21
- const keysA = Object.keys(a);
22
- const keysB = Object.keys(b);
23
- if (keysA.length !== keysB.length) return false;
24
- for (const key of keysA) {
25
- if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(
26
- a[key],
27
- b[key]
28
- )) {
29
- return false;
30
- }
31
- }
32
- return true;
33
- }
34
- function report(scope, error, level = "error") {
35
- if (process.env.NODE_ENV === "production" && typeof window !== "undefined") {
36
- return;
37
- }
38
- console[level](`[${scope}]`, error);
39
- }
40
-
41
- // src/utils/store.ts
42
- function freezeStoreSnapshot(state) {
43
- if (process.env.NODE_ENV === "production" || !state || typeof state !== "object") {
44
- return state;
45
- }
46
- const seen = /* @__PURE__ */ new WeakSet();
47
- const freeze = (value) => {
48
- if (seen.has(value) || Object.isFrozen(value)) return;
49
- seen.add(value);
50
- const prototype = Object.getPrototypeOf(value);
51
- if (Array.isArray(value) || prototype === Object.prototype || prototype === null) {
52
- for (const key of Reflect.ownKeys(value)) {
53
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
54
- if (descriptor && "value" in descriptor && descriptor.value !== null) {
55
- if (typeof descriptor.value === "object") freeze(descriptor.value);
56
- }
57
- }
58
- }
59
- Object.freeze(value);
60
- };
61
- freeze(state);
62
- return state;
63
- }
64
- function createStore(initialState, { freezeSnapshots = true } = {}) {
65
- const listeners = /* @__PURE__ */ new Set();
66
- const prepare = freezeSnapshots ? freezeStoreSnapshot : (state) => state;
67
- let snapshot = prepare(initialState);
68
- const publish = (nextStateOrUpdater) => {
69
- const nextState = typeof nextStateOrUpdater === "function" ? nextStateOrUpdater(snapshot) : nextStateOrUpdater;
70
- if (Object.is(snapshot, nextState)) return false;
71
- snapshot = prepare(nextState);
72
- for (const listener of listeners) {
73
- try {
74
- listener();
75
- } catch (error) {
76
- report("CoreStore subscriber", error, "warn");
77
- }
78
- }
79
- return true;
80
- };
81
- const setState = (updater) => {
82
- if (typeof updater === "function") {
83
- return publish(updater);
84
- }
85
- if (snapshot && typeof snapshot === "object" && updater && typeof updater === "object") {
86
- return publish({ ...snapshot, ...updater });
87
- }
88
- return publish(updater);
89
- };
90
- return Object.freeze({
91
- getSnapshot() {
92
- return snapshot;
93
- },
94
- publish,
95
- setState,
96
- subscribe(listener) {
97
- if (typeof listener !== "function") return () => {
98
- };
99
- listeners.add(listener);
100
- return () => listeners.delete(listener);
101
- }
102
- });
103
- }
104
- function useRequiredContext(context, hookName, providerName) {
105
- const value = use(context);
106
- if (value === null) {
107
- throw new Error(`${hookName} must be used within ${providerName}`);
108
- }
109
- return value;
110
- }
111
- function useStore(store, selector = (state) => state, isEqual = Object.is) {
112
- const cacheRef = useRef({
113
- isEqual: null,
114
- selected: void 0,
115
- selector: null,
116
- snapshot: null
117
- });
118
- const getSelectedSnapshot = useCallback(() => {
119
- const snapshot = store.getSnapshot();
120
- const cache = cacheRef.current;
121
- if (cache.snapshot === snapshot && cache.selector === selector && cache.isEqual === isEqual) {
122
- return cache.selected;
123
- }
124
- const selected = selector(snapshot);
125
- if (cache.snapshot !== null && cache.isEqual === isEqual && isEqual(cache.selected, selected)) {
126
- cache.snapshot = snapshot;
127
- cache.selector = selector;
128
- return cache.selected;
129
- }
130
- cacheRef.current = {
131
- isEqual,
132
- selected,
133
- selector,
134
- snapshot
135
- };
136
- return selected;
137
- }, [isEqual, selector, store]);
138
- return useSyncExternalStore(
139
- store.subscribe,
140
- getSelectedSnapshot,
141
- getSelectedSnapshot
142
- );
143
- }
144
- function defineModule(coreModule) {
145
- return Object.freeze({ ...coreModule });
146
- }
147
- createStore(void 0);
148
-
149
- // src/theme.tsx
150
- function defineThemeSpec(id) {
151
- return Object.freeze({ id });
152
- }
153
- var EMPTY = /* @__PURE__ */ new Map();
154
- var ThemeContext = getOrCreateGlobalContext("ThemeContext", EMPTY);
155
- function useTheme(spec) {
156
- const config = useContext(ThemeContext).get(spec.id);
157
- if (!config) {
158
- throw new Error(
159
- `Theme "${spec.id}" is missing. Ensure its theme configuration is provided to <ThemeProvider themes={[...]}> (e.g. in src/config/ or your theme setup).`
160
- );
161
- }
162
- return {
163
- slots: config.slots,
164
- styles: config.styles ?? {}
165
- };
166
- }
167
-
168
- // src/modules/ambient/constants.ts
169
- var AMBIENT_DEFAULTS = Object.freeze({
170
- primary: "#101010",
171
- black: "#0b0b0b"
172
- });
173
- var ambientTheme = defineThemeSpec("ambient");
174
-
175
- // src/modules/ambient/color.ts
176
- var COLOR_EXTRACT_CONFIG = Object.freeze({
177
- blackChromaFactor: 0.35,
178
- blackLightness: 0.15,
179
- cacheLimit: 100,
180
- chromaGain: 9.4,
181
- hueBins: 36,
182
- maxBlackChroma: 0.055,
183
- maxChroma: 0.28,
184
- maxPrimaryChroma: 0.24,
185
- minPixelChroma: 0.03,
186
- minPresence: 0.04,
187
- neutralChroma: 0.012,
188
- primaryLightness: 0.74,
189
- sampleSize: 64
190
- });
191
- function srgbToLinear(c) {
192
- const v = c / 255;
193
- return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
194
- }
195
- function rgbToOklch(r, g, b) {
196
- const lr = srgbToLinear(r);
197
- const lg = srgbToLinear(g);
198
- const lb = srgbToLinear(b);
199
- const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;
200
- const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;
201
- const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;
202
- const l_ = Math.cbrt(l);
203
- const m_ = Math.cbrt(m);
204
- const s_ = Math.cbrt(s);
205
- const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
206
- const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
207
- const bOklab = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
208
- const C = Math.sqrt(a * a + bOklab * bOklab);
209
- const H = (Math.atan2(bOklab, a) * (180 / Math.PI) + 360) % 360;
210
- return {
211
- c: Math.max(0, Number(C.toFixed(3))),
212
- h: Math.max(0, Number(H.toFixed(1))),
213
- l: Math.max(0, Math.min(1, Number(L.toFixed(3))))
214
- };
215
- }
216
- function oklchToString(l, c, h, alpha = 1) {
217
- const safeL = Math.max(0, Math.min(1, Number(l) || 0)).toFixed(3);
218
- const safeC = Math.max(0, Number(c) || 0).toFixed(3);
219
- const safeH = (Number(h) || 0).toFixed(1);
220
- const numericAlpha = Number(alpha);
221
- if (Number.isFinite(numericAlpha) && numericAlpha < 1 && numericAlpha >= 0) {
222
- return `oklch(${safeL} ${safeC} ${safeH} / ${numericAlpha})`;
223
- }
224
- return `oklch(${safeL} ${safeC} ${safeH})`;
225
- }
226
- function clamp(value, min, max) {
227
- return Math.max(min, Math.min(max, value));
228
- }
229
- function derivePalette(sampled) {
230
- const {
231
- blackChromaFactor,
232
- blackLightness,
233
- chromaGain,
234
- maxBlackChroma,
235
- maxChroma,
236
- maxPrimaryChroma,
237
- neutralChroma,
238
- primaryLightness
239
- } = COLOR_EXTRACT_CONFIG;
240
- const chroma = sampled.c < neutralChroma ? 0 : clamp(sampled.c, 0, maxChroma);
241
- const hue = chroma === 0 ? 0 : sampled.h;
242
- const primaryChroma = maxPrimaryChroma * (1 - Math.exp(-chroma * chromaGain));
243
- const primaryL = clamp(
244
- primaryLightness + (sampled.l - 0.6) * 0.5,
245
- 0.6,
246
- 0.86
247
- );
248
- const blackChroma = Math.min(maxBlackChroma, chroma * blackChromaFactor);
249
- const blackL = clamp(blackLightness + (sampled.l - 0.6) * 0.06, 0.12, 0.18);
250
- return {
251
- black: oklchToString(blackL, blackChroma, hue),
252
- primary: oklchToString(primaryL, primaryChroma, hue)
253
- };
254
- }
255
-
256
- // src/modules/ambient/extractor.ts
257
- function sampleImageData(imageData) {
258
- const { hueBins, minPixelChroma, minPresence } = COLOR_EXTRACT_CONFIG;
259
- const data = imageData.data;
260
- const binAngle = 360 / hueBins;
261
- const bins = Array.from({ length: hueBins }, () => ({
262
- cos: 0,
263
- sin: 0,
264
- sumC: 0,
265
- sumL: 0,
266
- weight: 0
267
- }));
268
- let opaqueCount = 0;
269
- let opaqueSumL = 0;
270
- let chromaticCount = 0;
271
- let midNeutralCount = 0;
272
- for (let i = 0; i < data.length; i += 4) {
273
- if (data[i + 3] < 128) continue;
274
- const { c, h, l } = rgbToOklch(data[i], data[i + 1], data[i + 2]);
275
- opaqueCount++;
276
- opaqueSumL += l;
277
- if (l < 0.06 || l > 0.96) continue;
278
- if (c < minPixelChroma) {
279
- midNeutralCount++;
280
- continue;
281
- }
282
- const usable = 1 - 0.7 * Math.min(1, Math.abs(l - 0.62) / 0.62);
283
- const weight2 = c * c * usable;
284
- const rad = h * (Math.PI / 180);
285
- const bin = bins[Math.floor(h / binAngle) % hueBins];
286
- bin.weight += weight2;
287
- bin.sumC += c * weight2;
288
- bin.sumL += l * weight2;
289
- bin.cos += Math.cos(rad) * weight2;
290
- bin.sin += Math.sin(rad) * weight2;
291
- chromaticCount++;
292
- }
293
- const averageL = opaqueCount > 0 ? opaqueSumL / opaqueCount : 0.5;
294
- const neutral = { c: 0, h: 0, l: Number(averageL.toFixed(3)) };
295
- const presence = chromaticCount / Math.max(1, chromaticCount + midNeutralCount);
296
- if (chromaticCount === 0 || presence < minPresence) return neutral;
297
- let bestIndex = 0;
298
- let bestScore = -1;
299
- for (let i = 0; i < hueBins; i++) {
300
- const prev = bins[(i - 1 + hueBins) % hueBins];
301
- const next = bins[(i + 1) % hueBins];
302
- const score = prev.weight * 0.5 + bins[i].weight + next.weight * 0.5;
303
- if (score > bestScore) {
304
- bestScore = score;
305
- bestIndex = i;
306
- }
307
- }
308
- const window2 = [
309
- bins[(bestIndex - 1 + hueBins) % hueBins],
310
- bins[bestIndex],
311
- bins[(bestIndex + 1) % hueBins]
312
- ];
313
- const weight = window2.reduce((sum, bin) => sum + bin.weight, 0);
314
- if (weight === 0) return neutral;
315
- const sumC = window2.reduce((sum, bin) => sum + bin.sumC, 0);
316
- const sumL = window2.reduce((sum, bin) => sum + bin.sumL, 0);
317
- const sin = window2.reduce((sum, bin) => sum + bin.sin, 0);
318
- const cos = window2.reduce((sum, bin) => sum + bin.cos, 0);
319
- const dilution = 0.45 + 0.55 * Math.min(1, presence / 0.3);
320
- return {
321
- c: Number((sumC / weight * dilution).toFixed(3)),
322
- h: Number(((Math.atan2(sin, cos) * (180 / Math.PI) + 360) % 360).toFixed(1)),
323
- l: Number((sumL / weight).toFixed(3))
324
- };
325
- }
326
- function createDefaultPalette(fallback) {
327
- return {
328
- black: fallback?.black || AMBIENT_DEFAULTS.black,
329
- primary: fallback?.primary || AMBIENT_DEFAULTS.primary
330
- };
331
- }
332
- var paletteCache = /* @__PURE__ */ new Map();
333
- var inFlight = /* @__PURE__ */ new Map();
334
- async function fetchObjectUrl(src) {
335
- if (typeof fetch !== "function" || !src.startsWith("http")) return null;
336
- const corsUrl = src.includes("cors=") ? src : `${src}${src.includes("?") ? "&" : "?"}cors=1`;
337
- const attempts = [
338
- [corsUrl, { mode: "cors" }],
339
- [`/api/ambient/proxy?url=${encodeURIComponent(src)}`]
340
- ];
341
- for (const [url, init] of attempts) {
342
- try {
343
- const response = await fetch(url, init);
344
- if (response.ok) return URL.createObjectURL(await response.blob());
345
- } catch {
346
- }
347
- }
348
- return null;
349
- }
350
- function loadImage(url, crossOrigin) {
351
- return new Promise((resolve) => {
352
- const image = new Image();
353
- if (crossOrigin) image.crossOrigin = "anonymous";
354
- image.onload = () => resolve(image);
355
- image.onerror = () => resolve(null);
356
- image.src = url;
357
- });
358
- }
359
- function readPalette(image) {
360
- const size = COLOR_EXTRACT_CONFIG.sampleSize;
361
- const canvas = document.createElement("canvas");
362
- canvas.width = size;
363
- canvas.height = size;
364
- const context = canvas.getContext("2d", { willReadFrequently: true });
365
- if (!context) return null;
366
- context.drawImage(image, 0, 0, size, size);
367
- return derivePalette(sampleImageData(context.getImageData(0, 0, size, size)));
368
- }
369
- async function extractPalette(src) {
370
- const objectUrl = await fetchObjectUrl(src);
371
- try {
372
- const image = await loadImage(objectUrl ?? src, !objectUrl);
373
- return image ? readPalette(image) : null;
374
- } catch {
375
- return null;
376
- } finally {
377
- if (objectUrl) URL.revokeObjectURL(objectUrl);
378
- }
379
- }
380
- function cachePalette(src, palette) {
381
- if (paletteCache.size >= COLOR_EXTRACT_CONFIG.cacheLimit) {
382
- const oldest = paletteCache.keys().next().value;
383
- if (oldest) paletteCache.delete(oldest);
384
- }
385
- paletteCache.set(src, palette);
386
- }
387
- async function extractPaletteFromImage(imageSource, options = {}) {
388
- const fallback = createDefaultPalette(
389
- options.initialPalette || options.fallbackPalette
390
- );
391
- const src = typeof imageSource === "string" ? imageSource : imageSource?.src;
392
- if (!src || typeof window === "undefined") return fallback;
393
- const cached = paletteCache.get(src);
394
- if (cached) return cached;
395
- let pending = inFlight.get(src);
396
- if (!pending) {
397
- pending = extractPalette(src).then((palette) => {
398
- if (palette) cachePalette(src, palette);
399
- return palette;
400
- }).finally(() => inFlight.delete(src));
401
- inFlight.set(src, pending);
402
- }
403
- return await pending ?? fallback;
404
- }
405
-
406
- // src/modules/ambient/dom.ts
407
- var AMBIENT_CSS_VARS = Object.freeze({
408
- ambientGlow: "--color-ambient-glow",
409
- colorPrimary: "--color-primary",
410
- primary: "--primary",
411
- black: "--black",
412
- white: "--white"
413
- });
414
- function resolveTargetElement(target) {
415
- if (typeof document === "undefined") return null;
416
- if (!target) return document.documentElement;
417
- if (typeof target === "string") {
418
- return document.querySelector(target);
419
- }
420
- return "current" in target ? target.current : target;
421
- }
422
- function normalizeColorMap(colors) {
423
- const cssVars = AMBIENT_CSS_VARS;
424
- const result = {};
425
- for (const [key, value] of Object.entries(colors)) {
426
- if (!value) continue;
427
- const name = cssVars[key] || (key.startsWith("--") ? key : cssVars[key.toLowerCase()] || `--color-${key}`);
428
- result[name] = value;
429
- }
430
- return result;
431
- }
432
- function applyScopedCssVariables(element, varMap) {
433
- const previous = /* @__PURE__ */ new Map();
434
- for (const [name, value] of Object.entries(varMap)) {
435
- if (!name || !value) continue;
436
- previous.set(name, {
437
- priority: element.style.getPropertyPriority(name),
438
- value: element.style.getPropertyValue(name)
439
- });
440
- element.style.setProperty(name, value);
441
- }
442
- return () => {
443
- for (const [name, { priority, value }] of previous) {
444
- if (value) element.style.setProperty(name, value, priority);
445
- else element.style.removeProperty(name);
446
- }
447
- };
448
- }
449
- function resolveAmbientVarMap({
450
- colors = null,
451
- extractedBlack = "",
452
- extractedPrimary = "",
453
- image = null,
454
- tintGlobals = true
455
- }) {
456
- const varMap = {};
457
- if (image) {
458
- if (extractedPrimary) {
459
- varMap[AMBIENT_CSS_VARS.primary] = extractedPrimary;
460
- varMap[AMBIENT_CSS_VARS.ambientGlow] = extractedPrimary;
461
- if (tintGlobals) varMap[AMBIENT_CSS_VARS.colorPrimary] = extractedPrimary;
462
- }
463
- if (extractedBlack) varMap[AMBIENT_CSS_VARS.black] = extractedBlack;
464
- }
465
- if (colors) Object.assign(varMap, normalizeColorMap(colors));
466
- return varMap;
467
- }
468
-
469
- // src/modules/background/state.ts
470
- var DEFAULT_BACKGROUND = Object.freeze({
471
- animation: null,
472
- className: "",
473
- fadeEdges: null,
474
- fit: null,
475
- image: null,
476
- imageStyle: {},
477
- isPlaying: false,
478
- noiseStyle: {},
479
- overlay: false,
480
- overlayColor: "var(--black)",
481
- overlayOpacity: 0,
482
- position: "center",
483
- video: null,
484
- videoClassName: "",
485
- videoElement: null,
486
- videoOptions: {
487
- autoplay: true,
488
- className: "",
489
- corp: 0,
490
- loop: false,
491
- muted: true,
492
- playbackRate: 1,
493
- width: null
494
- },
495
- videoStyle: {},
496
- width: null
497
- });
498
- var DEFAULT_BACKGROUND_COMPUTED = Object.freeze({
499
- ...DEFAULT_BACKGROUND,
500
- hasBackground: false,
501
- isVideo: false,
502
- isYouTube: false,
503
- posterUrl: null,
504
- youtubeVideoId: null
505
- });
506
- var BackgroundContext = getOrCreateGlobalContext(
507
- "BackgroundContext",
508
- null
509
- );
510
-
511
- // src/modules/background/hooks.ts
512
- var NOOP_BACKGROUND_STORE = createStore(
513
- DEFAULT_BACKGROUND_COMPUTED
514
- );
515
- function useOptionalBackgroundState(selector, isEqual) {
516
- const ctx = useContext(BackgroundContext);
517
- return useStore(
518
- ctx?.store ?? NOOP_BACKGROUND_STORE,
519
- selector,
520
- isEqual
521
- );
522
- }
523
- var AmbientContext = getOrCreateGlobalContext("AmbientContext", null);
524
- function AmbientProvider({
525
- children,
526
- initialPalette = null
527
- }) {
528
- const [store] = useState(
529
- () => createStore(
530
- { isExtracting: false, palette: initialPalette || AMBIENT_DEFAULTS },
531
- { freezeSnapshots: false }
532
- )
533
- );
534
- const value = useMemo(
535
- () => ({
536
- actions: {
537
- setIsExtracting: (next) => store.publish((state) => {
538
- const isExtracting = typeof next === "function" ? next(state.isExtracting) : next;
539
- return isExtracting === state.isExtracting ? state : { ...state, isExtracting };
540
- }),
541
- setPalette: (next) => store.publish((state) => {
542
- const palette = typeof next === "function" ? next(state.palette) : next;
543
- return palette === state.palette ? state : { ...state, palette };
544
- })
545
- },
546
- store
547
- }),
548
- [store]
549
- );
550
- return /* @__PURE__ */ jsx(AmbientContext, { value, children });
551
- }
552
- function useStableObject(value) {
553
- const ref = useRef(value);
554
- if (!shallowEqual(ref.current, value)) {
555
- ref.current = value;
556
- }
557
- return ref.current;
558
- }
559
- function useAmbientColor(imageSource, options = null) {
560
- const stableOptions = useStableObject(options);
561
- const initialPalette = useStableObject(
562
- options?.initialPalette || options?.fallbackPalette || null
563
- );
564
- const [extractedData, setExtractedData] = useState(
565
- () => initialPalette
566
- );
567
- const srcKey = typeof imageSource === "string" ? imageSource : imageSource?.src;
568
- const isExtracting = Boolean(
569
- imageSource && (!extractedData || extractedData.source !== srcKey)
570
- );
571
- useEffect(() => {
572
- if (!imageSource) return;
573
- let active = true;
574
- void extractPaletteFromImage(imageSource, {
575
- fallbackPalette: initialPalette,
576
- ...stableOptions || {}
577
- }).then((extracted) => {
578
- if (active) {
579
- setExtractedData({ ...extracted, source: srcKey });
580
- }
581
- }).catch(() => {
582
- if (active) {
583
- setExtractedData({
584
- black: initialPalette?.black || AMBIENT_DEFAULTS.black,
585
- primary: initialPalette?.primary || AMBIENT_DEFAULTS.primary,
586
- source: srcKey
587
- });
588
- }
589
- });
590
- return () => {
591
- active = false;
592
- };
593
- }, [imageSource, initialPalette, srcKey, stableOptions]);
594
- const palette = imageSource && extractedData && extractedData.source === srcKey ? extractedData : initialPalette || AMBIENT_DEFAULTS;
595
- return { isExtracting, palette };
596
- }
597
- function useAmbientTheme(config = null) {
598
- const ambientActions = use(AmbientContext)?.actions ?? null;
599
- const normalizedConfig = typeof config === "string" ? { image: config } : config || {};
600
- const {
601
- colors = null,
602
- image = null,
603
- initialPalette = null,
604
- options = null,
605
- scope = null,
606
- tintGlobals = true,
607
- transition = true
608
- } = normalizedConfig;
609
- const stableInitialPalette = useStableObject(initialPalette);
610
- const stableOptions = useStableObject(options);
611
- const stableColors = useStableObject(colors);
612
- const resolvedOptions = useMemo(
613
- () => ({
614
- ...stableOptions || {},
615
- ...stableInitialPalette ? { initialPalette: stableInitialPalette } : {}
616
- }),
617
- [stableInitialPalette, stableOptions]
618
- );
619
- const { palette: extractedPalette, isExtracting } = useAmbientColor(
620
- image,
621
- resolvedOptions
622
- );
623
- const hasActiveConfig = Boolean(image || stableColors);
624
- useEffect(() => {
625
- if (!hasActiveConfig || !ambientActions) return;
626
- ambientActions.setIsExtracting(isExtracting);
627
- ambientActions.setPalette(
628
- (prev) => shallowEqual(prev, extractedPalette) ? prev : extractedPalette
629
- );
630
- }, [ambientActions, extractedPalette, hasActiveConfig, isExtracting]);
631
- const extractedPrimary = extractedPalette?.primary || "";
632
- const extractedBlack = extractedPalette?.black || "";
633
- const transitionClasses = useTheme(ambientTheme).slots.transition.split(/\s+/).filter(Boolean);
634
- const transitionKey = transitionClasses.join(" ");
635
- const resolvedVarMap = useMemo(
636
- () => resolveAmbientVarMap({
637
- colors: stableColors,
638
- extractedBlack,
639
- extractedPrimary,
640
- image,
641
- tintGlobals
642
- }),
643
- [extractedBlack, extractedPrimary, image, stableColors, tintGlobals]
644
- );
645
- useEffect(() => {
646
- if (Object.keys(resolvedVarMap).length === 0) return;
647
- const targetEl = resolveTargetElement(scope);
648
- if (!targetEl) return;
649
- if (transition) {
650
- targetEl.classList.add(...transitionKey.split(" ").filter(Boolean));
651
- }
652
- const restoreVariables = applyScopedCssVariables(targetEl, resolvedVarMap);
653
- return () => {
654
- restoreVariables();
655
- if (transition && scope) {
656
- targetEl.classList.remove(...transitionKey.split(" ").filter(Boolean));
657
- }
658
- };
659
- }, [resolvedVarMap, scope, transition, transitionKey]);
660
- return { isExtracting, palette: extractedPalette };
661
- }
662
- function useAmbient(configOrImage) {
663
- const { actions, store } = useRequiredContext(
664
- AmbientContext,
665
- "useAmbient",
666
- "AmbientProvider"
667
- );
668
- const shared = useStore(store);
669
- const ctx = useMemo(
670
- () => ({ ...shared, ...actions }),
671
- [actions, shared]
672
- );
673
- const { isExtracting, palette } = useAmbientTheme(configOrImage ?? null);
674
- const themeState = useMemo(
675
- () => ({ isExtracting, palette }),
676
- [isExtracting, palette]
677
- );
678
- return useMemo(
679
- () => configOrImage ? { ...ctx, ...themeState } : ctx,
680
- [configOrImage, ctx, themeState]
681
- );
682
- }
683
-
684
- // src/modules/ambient/module.tsx
685
- var firstString = (...values) => values.find((value) => typeof value === "string" && value) ?? null;
686
- function resolvePageAmbientTheme(slice, posterUrl) {
687
- const ambient = slice?.ambient;
688
- const banner = slice?.banner ?? null;
689
- const defaultImage = banner ?? posterUrl;
690
- if (ambient === false) return null;
691
- if (ambient === true || typeof ambient === "string") {
692
- return {
693
- image: typeof ambient === "string" ? ambient : defaultImage,
694
- tintGlobals: true
695
- };
696
- }
697
- if (ambient && typeof ambient === "object") {
698
- return { image: ambient.image ?? defaultImage, ...ambient };
699
- }
700
- if (banner && !posterUrl) return { image: banner, tintGlobals: true };
701
- return null;
702
- }
703
- function selectPageAmbient(config) {
704
- return {
705
- ambient: config.ambient,
706
- banner: firstString(config.dock?.banner, config.dock?.bannerUrl)
707
- };
708
- }
709
- function useAmbientPage(slice, page) {
710
- const posterUrl = useOptionalBackgroundState(
711
- (background) => background.posterUrl
712
- );
713
- const theme = useMemo(
714
- () => resolvePageAmbientTheme(slice, posterUrl),
715
- [posterUrl, slice]
716
- );
717
- useAmbientTheme(theme);
718
- return useMemo(
719
- () => ({ set: (ambient) => page.set({ ambient }) }),
720
- [page]
721
- );
722
- }
723
- var ambientModule = defineModule({
724
- id: "ambient",
725
- context: AmbientContext,
726
- Provider: AmbientProvider,
727
- uses: ["background"],
728
- page: {
729
- select: selectPageAmbient,
730
- use: useAmbientPage
731
- }
732
- });
733
- function resolveValue(value, props) {
734
- return typeof value === "function" ? value(props) : value;
735
- }
736
- function defineAmbient(definition = {}) {
737
- const { defaultProps, id = "ambient-theme", ...config } = definition;
738
- const create = (props = {}, { id: overrideId, ...overrides } = {}) => {
739
- const mergedProps = { ...defaultProps, ...props };
740
- const merged = { ...config, ...overrides };
741
- return {
742
- ...merged,
743
- colors: resolveValue(merged.colors ?? null, mergedProps) ?? null,
744
- id: overrideId ?? id,
745
- image: resolveValue(merged.image ?? null, mergedProps),
746
- initialPalette: merged.initialPalette ?? null,
747
- options: { ...config.options, ...overrides.options },
748
- props: mergedProps,
749
- scope: merged.scope ?? null,
750
- transition: merged.transition ?? true
751
- };
752
- };
753
- return Object.freeze({
754
- config: definition,
755
- create,
756
- id,
757
- use: function useDefinedAmbient(props, overrides) {
758
- return useAmbientTheme(create(props, overrides));
759
- }
760
- });
761
- }
762
-
763
- export { AMBIENT_CSS_VARS, AMBIENT_DEFAULTS, AmbientContext, AmbientProvider, COLOR_EXTRACT_CONFIG, ambientModule, ambientTheme, applyScopedCssVariables, createDefaultPalette, defineAmbient, derivePalette, extractPaletteFromImage, normalizeColorMap, oklchToString, resolveAmbientVarMap, resolvePageAmbientTheme, resolveTargetElement, rgbToOklch, sampleImageData, srgbToLinear, useAmbient, useAmbientColor, useAmbientTheme };
2
+ export { AMBIENT_REGIONS, AMBIENT_ROLES, AMBIENT_TONES, AmbientContext, AmbientProvider, DEFAULT_ANALYSIS, DEFAULT_CSS_VAR_NAMES, ambientModule, ambientTheme, analyzeAmbientPixels, applyScopedCssVariables, configureAmbient, contrastRatio, defineAmbient, extractPaletteFromImage, findContentBounds, formatOklch, getAmbientSettings, getCachedAmbientPalette, maxChroma, normalizeColorMap, onColorFor, paletteVarMap, primeAmbientPalette, resolveAmbientVarMap, resolveCssVarNames, resolvePageAmbientTheme, resolveTargetElement, srgbToOklab, toneOf, useAmbient, useAmbientColor, useAmbientTheme } from '../../chunk-QXR55VVS.js';
3
+ import '../../chunk-CGHZSSFR.js';
4
+ import '../../chunk-R2YGFJDJ.js';
5
+ import '../../chunk-7TAVYJ3A.js';
6
+ import '../../chunk-GF7TUX5I.js';
7
+ import '../../chunk-TV3WEF5G.js';
8
+ import '../../chunk-3BUP64Q6.js';
764
9
  //# sourceMappingURL=index.js.map
765
10
  //# sourceMappingURL=index.js.map