@almadar/ui 1.0.29 → 1.0.31

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.
@@ -56,6 +56,8 @@ interface ThemeProviderProps {
56
56
  defaultTheme?: string;
57
57
  /** Default color mode */
58
58
  defaultMode?: ColorMode;
59
+ /** Optional target element ref — when provided, theme attributes are applied to this element instead of document.documentElement */
60
+ targetRef?: React__default.RefObject<HTMLElement>;
59
61
  }
60
62
  /**
61
63
  * Unified ThemeProvider component
@@ -118,7 +118,8 @@ var ThemeProvider = ({
118
118
  children,
119
119
  themes = [],
120
120
  defaultTheme = "wireframe",
121
- defaultMode = "system"
121
+ defaultMode = "system",
122
+ targetRef
122
123
  }) => {
123
124
  const availableThemes = useMemo(() => {
124
125
  const themeMap = /* @__PURE__ */ new Map();
@@ -126,8 +127,9 @@ var ThemeProvider = ({
126
127
  themes.forEach((t) => themeMap.set(t.name, t));
127
128
  return Array.from(themeMap.values());
128
129
  }, [themes]);
130
+ const isScoped = !!targetRef;
129
131
  const [theme, setThemeState] = useState(() => {
130
- if (typeof window === "undefined") return defaultTheme;
132
+ if (isScoped || typeof window === "undefined") return defaultTheme;
131
133
  const stored = localStorage.getItem(THEME_STORAGE_KEY);
132
134
  const validThemes = [
133
135
  ...BUILT_IN_THEMES.map((t) => t.name),
@@ -139,7 +141,7 @@ var ThemeProvider = ({
139
141
  return defaultTheme;
140
142
  });
141
143
  const [mode, setModeState] = useState(() => {
142
- if (typeof window === "undefined") return defaultMode;
144
+ if (isScoped || typeof window === "undefined") return defaultMode;
143
145
  const stored = localStorage.getItem(MODE_STORAGE_KEY);
144
146
  if (stored === "light" || stored === "dark" || stored === "system") {
145
147
  return stored;
@@ -167,17 +169,25 @@ var ThemeProvider = ({
167
169
  return void 0;
168
170
  }, [mode]);
169
171
  useEffect(() => {
172
+ if (isScoped) {
173
+ if (targetRef?.current) {
174
+ targetRef.current.setAttribute("data-theme", appliedTheme);
175
+ targetRef.current.classList.remove("light", "dark");
176
+ targetRef.current.classList.add(resolvedMode);
177
+ }
178
+ return;
179
+ }
170
180
  const root = document.documentElement;
171
181
  root.setAttribute("data-theme", appliedTheme);
172
182
  root.classList.remove("light", "dark");
173
183
  root.classList.add(resolvedMode);
174
- }, [appliedTheme, resolvedMode]);
184
+ }, [appliedTheme, resolvedMode, targetRef, isScoped]);
175
185
  const setTheme = useCallback(
176
186
  (newTheme) => {
177
187
  const validTheme = availableThemes.find((t) => t.name === newTheme);
178
188
  if (validTheme) {
179
189
  setThemeState(newTheme);
180
- if (typeof window !== "undefined") {
190
+ if (!isScoped && typeof window !== "undefined") {
181
191
  localStorage.setItem(THEME_STORAGE_KEY, newTheme);
182
192
  }
183
193
  } else {
@@ -190,7 +200,7 @@ var ThemeProvider = ({
190
200
  );
191
201
  const setMode = useCallback((newMode) => {
192
202
  setModeState(newMode);
193
- if (typeof window !== "undefined") {
203
+ if (!isScoped && typeof window !== "undefined") {
194
204
  localStorage.setItem(MODE_STORAGE_KEY, newMode);
195
205
  }
196
206
  }, []);
@@ -0,0 +1,186 @@
1
+ import { createContext, useContext, useRef, useEffect, useCallback, useMemo } from 'react';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // providers/EventBusProvider.tsx
5
+ function setGlobalEventBus(bus) {
6
+ if (typeof window !== "undefined") {
7
+ window.__kflowEventBus = bus;
8
+ }
9
+ }
10
+ function getGlobalEventBus() {
11
+ if (typeof window !== "undefined") {
12
+ return window.__kflowEventBus ?? null;
13
+ }
14
+ return null;
15
+ }
16
+ var fallbackListeners = /* @__PURE__ */ new Map();
17
+ var fallbackEventBus = {
18
+ emit: (type, payload) => {
19
+ const event = {
20
+ type,
21
+ payload,
22
+ timestamp: Date.now()
23
+ };
24
+ const handlers = fallbackListeners.get(type);
25
+ if (handlers) {
26
+ handlers.forEach((handler) => {
27
+ try {
28
+ handler(event);
29
+ } catch (error) {
30
+ console.error(`[EventBus] Error in listener for '${type}':`, error);
31
+ }
32
+ });
33
+ }
34
+ },
35
+ on: (type, listener) => {
36
+ if (!fallbackListeners.has(type)) {
37
+ fallbackListeners.set(type, /* @__PURE__ */ new Set());
38
+ }
39
+ fallbackListeners.get(type).add(listener);
40
+ return () => {
41
+ const handlers = fallbackListeners.get(type);
42
+ if (handlers) {
43
+ handlers.delete(listener);
44
+ if (handlers.size === 0) {
45
+ fallbackListeners.delete(type);
46
+ }
47
+ }
48
+ };
49
+ },
50
+ once: (type, listener) => {
51
+ const wrappedListener = (event) => {
52
+ fallbackListeners.get(type)?.delete(wrappedListener);
53
+ listener(event);
54
+ };
55
+ return fallbackEventBus.on(type, wrappedListener);
56
+ },
57
+ hasListeners: (type) => {
58
+ const handlers = fallbackListeners.get(type);
59
+ return handlers !== void 0 && handlers.size > 0;
60
+ }
61
+ };
62
+ function useEventBus() {
63
+ const context = useContext(EventBusContext);
64
+ return context ?? getGlobalEventBus() ?? fallbackEventBus;
65
+ }
66
+ function useEventListener(event, handler) {
67
+ const eventBus = useEventBus();
68
+ const handlerRef = useRef(handler);
69
+ handlerRef.current = handler;
70
+ useEffect(() => {
71
+ const wrappedHandler = (evt) => {
72
+ handlerRef.current(evt);
73
+ };
74
+ const unsub = eventBus.on(event, wrappedHandler);
75
+ return () => {
76
+ if (typeof unsub === "function") unsub();
77
+ };
78
+ }, [event, eventBus]);
79
+ }
80
+ function useEmitEvent() {
81
+ const eventBus = useEventBus();
82
+ return useCallback(
83
+ (type, payload) => {
84
+ eventBus.emit(type, payload);
85
+ },
86
+ [eventBus]
87
+ );
88
+ }
89
+ var EventBusContext = createContext(null);
90
+ function EventBusProvider({ children, debug = false }) {
91
+ const listenersRef = useRef(/* @__PURE__ */ new Map());
92
+ const deprecationWarningShown = useRef(false);
93
+ const getSelectedEntity = useCallback(() => {
94
+ if (!deprecationWarningShown.current) {
95
+ console.warn(
96
+ "[EventBus] getSelectedEntity is deprecated. Use SelectionProvider and useSelection hook instead. See SelectionProvider.tsx for migration guide."
97
+ );
98
+ deprecationWarningShown.current = true;
99
+ }
100
+ return null;
101
+ }, []);
102
+ const clearSelectedEntity = useCallback(() => {
103
+ if (!deprecationWarningShown.current) {
104
+ console.warn(
105
+ "[EventBus] clearSelectedEntity is deprecated. Use SelectionProvider and useSelection hook instead. See SelectionProvider.tsx for migration guide."
106
+ );
107
+ deprecationWarningShown.current = true;
108
+ }
109
+ }, []);
110
+ const emit = useCallback((type, payload) => {
111
+ const event = {
112
+ type,
113
+ payload,
114
+ timestamp: Date.now()
115
+ };
116
+ const listeners = listenersRef.current.get(type);
117
+ const listenerCount = listeners?.size ?? 0;
118
+ if (debug) {
119
+ if (listenerCount > 0) {
120
+ console.log(`[EventBus] Emit: ${type} \u2192 ${listenerCount} listener(s)`, payload);
121
+ } else {
122
+ console.warn(`[EventBus] Emit: ${type} (NO LISTENERS - event may be lost!)`, payload);
123
+ }
124
+ }
125
+ if (listeners) {
126
+ const listenersCopy = Array.from(listeners);
127
+ for (const listener of listenersCopy) {
128
+ try {
129
+ listener(event);
130
+ } catch (error) {
131
+ console.error(`[EventBus] Error in listener for '${type}':`, error);
132
+ }
133
+ }
134
+ }
135
+ }, [debug]);
136
+ const on = useCallback((type, listener) => {
137
+ if (!listenersRef.current.has(type)) {
138
+ listenersRef.current.set(type, /* @__PURE__ */ new Set());
139
+ }
140
+ const listeners = listenersRef.current.get(type);
141
+ listeners.add(listener);
142
+ if (debug) {
143
+ console.log(`[EventBus] Subscribed to '${type}', total: ${listeners.size}`);
144
+ }
145
+ return () => {
146
+ listeners.delete(listener);
147
+ if (debug) {
148
+ console.log(`[EventBus] Unsubscribed from '${type}', remaining: ${listeners.size}`);
149
+ }
150
+ if (listeners.size === 0) {
151
+ listenersRef.current.delete(type);
152
+ }
153
+ };
154
+ }, [debug]);
155
+ const once = useCallback((type, listener) => {
156
+ const wrappedListener = (event) => {
157
+ listenersRef.current.get(type)?.delete(wrappedListener);
158
+ listener(event);
159
+ };
160
+ return on(type, wrappedListener);
161
+ }, [on]);
162
+ const hasListeners = useCallback((type) => {
163
+ const listeners = listenersRef.current.get(type);
164
+ return listeners !== void 0 && listeners.size > 0;
165
+ }, []);
166
+ const contextValue = useMemo(
167
+ () => ({
168
+ emit,
169
+ on,
170
+ once,
171
+ hasListeners,
172
+ getSelectedEntity,
173
+ clearSelectedEntity
174
+ }),
175
+ [emit, on, once, hasListeners, getSelectedEntity, clearSelectedEntity]
176
+ );
177
+ useEffect(() => {
178
+ setGlobalEventBus(contextValue);
179
+ return () => {
180
+ setGlobalEventBus(null);
181
+ };
182
+ }, [contextValue]);
183
+ return /* @__PURE__ */ jsx(EventBusContext.Provider, { value: contextValue, children });
184
+ }
185
+
186
+ export { EventBusContext, EventBusProvider, useEmitEvent, useEventBus, useEventListener };
@@ -1,193 +1,13 @@
1
- import React2, { createContext, useContext, useRef, useEffect, useCallback, useMemo, useState } from 'react';
1
+ import { useEventBus } from './chunk-RUGU4MSK.js';
2
+ import React, { createContext, useContext, useMemo, useState, useEffect, useCallback } from 'react';
2
3
  import { jsx } from 'react/jsx-runtime';
3
4
 
4
- // providers/EventBusProvider.tsx
5
- function setGlobalEventBus(bus) {
6
- if (typeof window !== "undefined") {
7
- window.__kflowEventBus = bus;
8
- }
9
- }
10
- function getGlobalEventBus() {
11
- if (typeof window !== "undefined") {
12
- return window.__kflowEventBus ?? null;
13
- }
14
- return null;
15
- }
16
- var fallbackListeners = /* @__PURE__ */ new Map();
17
- var fallbackEventBus = {
18
- emit: (type, payload) => {
19
- const event = {
20
- type,
21
- payload,
22
- timestamp: Date.now()
23
- };
24
- const handlers = fallbackListeners.get(type);
25
- if (handlers) {
26
- handlers.forEach((handler) => {
27
- try {
28
- handler(event);
29
- } catch (error) {
30
- console.error(`[EventBus] Error in listener for '${type}':`, error);
31
- }
32
- });
33
- }
34
- },
35
- on: (type, listener) => {
36
- if (!fallbackListeners.has(type)) {
37
- fallbackListeners.set(type, /* @__PURE__ */ new Set());
38
- }
39
- fallbackListeners.get(type).add(listener);
40
- return () => {
41
- const handlers = fallbackListeners.get(type);
42
- if (handlers) {
43
- handlers.delete(listener);
44
- if (handlers.size === 0) {
45
- fallbackListeners.delete(type);
46
- }
47
- }
48
- };
49
- },
50
- once: (type, listener) => {
51
- const wrappedListener = (event) => {
52
- fallbackListeners.get(type)?.delete(wrappedListener);
53
- listener(event);
54
- };
55
- return fallbackEventBus.on(type, wrappedListener);
56
- },
57
- hasListeners: (type) => {
58
- const handlers = fallbackListeners.get(type);
59
- return handlers !== void 0 && handlers.size > 0;
60
- }
61
- };
62
- function useEventBus() {
63
- const context = useContext(EventBusContext);
64
- return context ?? getGlobalEventBus() ?? fallbackEventBus;
65
- }
66
- function useEventListener(event, handler) {
67
- const eventBus = useEventBus();
68
- const handlerRef = useRef(handler);
69
- handlerRef.current = handler;
70
- useEffect(() => {
71
- const wrappedHandler = (evt) => {
72
- handlerRef.current(evt);
73
- };
74
- const unsub = eventBus.on(event, wrappedHandler);
75
- return () => {
76
- if (typeof unsub === "function") unsub();
77
- };
78
- }, [event, eventBus]);
79
- }
80
- function useEmitEvent() {
81
- const eventBus = useEventBus();
82
- return useCallback(
83
- (type, payload) => {
84
- eventBus.emit(type, payload);
85
- },
86
- [eventBus]
87
- );
88
- }
89
- var EventBusContext = createContext(null);
90
- function EventBusProvider({ children, debug = false }) {
91
- const listenersRef = useRef(/* @__PURE__ */ new Map());
92
- const deprecationWarningShown = useRef(false);
93
- const getSelectedEntity = useCallback(() => {
94
- if (!deprecationWarningShown.current) {
95
- console.warn(
96
- "[EventBus] getSelectedEntity is deprecated. Use SelectionProvider and useSelection hook instead. See SelectionProvider.tsx for migration guide."
97
- );
98
- deprecationWarningShown.current = true;
99
- }
100
- return null;
101
- }, []);
102
- const clearSelectedEntity = useCallback(() => {
103
- if (!deprecationWarningShown.current) {
104
- console.warn(
105
- "[EventBus] clearSelectedEntity is deprecated. Use SelectionProvider and useSelection hook instead. See SelectionProvider.tsx for migration guide."
106
- );
107
- deprecationWarningShown.current = true;
108
- }
109
- }, []);
110
- const emit = useCallback((type, payload) => {
111
- const event = {
112
- type,
113
- payload,
114
- timestamp: Date.now()
115
- };
116
- const listeners = listenersRef.current.get(type);
117
- const listenerCount = listeners?.size ?? 0;
118
- if (debug) {
119
- if (listenerCount > 0) {
120
- console.log(`[EventBus] Emit: ${type} \u2192 ${listenerCount} listener(s)`, payload);
121
- } else {
122
- console.warn(`[EventBus] Emit: ${type} (NO LISTENERS - event may be lost!)`, payload);
123
- }
124
- }
125
- if (listeners) {
126
- const listenersCopy = Array.from(listeners);
127
- for (const listener of listenersCopy) {
128
- try {
129
- listener(event);
130
- } catch (error) {
131
- console.error(`[EventBus] Error in listener for '${type}':`, error);
132
- }
133
- }
134
- }
135
- }, [debug]);
136
- const on = useCallback((type, listener) => {
137
- if (!listenersRef.current.has(type)) {
138
- listenersRef.current.set(type, /* @__PURE__ */ new Set());
139
- }
140
- const listeners = listenersRef.current.get(type);
141
- listeners.add(listener);
142
- if (debug) {
143
- console.log(`[EventBus] Subscribed to '${type}', total: ${listeners.size}`);
144
- }
145
- return () => {
146
- listeners.delete(listener);
147
- if (debug) {
148
- console.log(`[EventBus] Unsubscribed from '${type}', remaining: ${listeners.size}`);
149
- }
150
- if (listeners.size === 0) {
151
- listenersRef.current.delete(type);
152
- }
153
- };
154
- }, [debug]);
155
- const once = useCallback((type, listener) => {
156
- const wrappedListener = (event) => {
157
- listenersRef.current.get(type)?.delete(wrappedListener);
158
- listener(event);
159
- };
160
- return on(type, wrappedListener);
161
- }, [on]);
162
- const hasListeners = useCallback((type) => {
163
- const listeners = listenersRef.current.get(type);
164
- return listeners !== void 0 && listeners.size > 0;
165
- }, []);
166
- const contextValue = useMemo(
167
- () => ({
168
- emit,
169
- on,
170
- once,
171
- hasListeners,
172
- getSelectedEntity,
173
- clearSelectedEntity
174
- }),
175
- [emit, on, once, hasListeners, getSelectedEntity, clearSelectedEntity]
176
- );
177
- useEffect(() => {
178
- setGlobalEventBus(contextValue);
179
- return () => {
180
- setGlobalEventBus(null);
181
- };
182
- }, [contextValue]);
183
- return /* @__PURE__ */ jsx(EventBusContext.Provider, { value: contextValue, children });
184
- }
185
5
  var EntityDataContext = createContext(null);
186
6
  function EntityDataProvider({
187
7
  adapter,
188
8
  children
189
9
  }) {
190
- return React2.createElement(
10
+ return React.createElement(
191
11
  EntityDataContext.Provider,
192
12
  { value: adapter },
193
13
  children
@@ -416,4 +236,4 @@ function useSelectionOptional() {
416
236
  return context;
417
237
  }
418
238
 
419
- export { EntityDataProvider, EventBusContext, EventBusProvider, SelectionContext, SelectionProvider, entityDataKeys, useEmitEvent, useEntity, useEntityDataAdapter, useEntityDetail, useEntityList, useEventBus, useEventListener, usePaginatedEntityList, useSelection, useSelectionOptional };
239
+ export { EntityDataProvider, SelectionContext, SelectionProvider, entityDataKeys, useEntity, useEntityDataAdapter, useEntityDetail, useEntityList, usePaginatedEntityList, useSelection, useSelectionOptional };
@@ -1,7 +1,8 @@
1
1
  import { apiClient } from './chunk-XSEDIUM6.js';
2
- import { useEventBus, SelectionContext, entityDataKeys } from './chunk-HY5EFCOK.js';
2
+ import { SelectionContext, entityDataKeys } from './chunk-VLWZZA6A.js';
3
3
  import { subscribe, getSnapshot, clearEntities, removeEntity, updateSingleton, updateEntity, spawnEntity, getSingleton, getAllEntities, getByType, getEntity } from './chunk-N7MVUW4R.js';
4
- import { useCallback, useState, useEffect, useMemo, useContext, useSyncExternalStore } from 'react';
4
+ import { useEventBus } from './chunk-RUGU4MSK.js';
5
+ import { createContext, useCallback, useState, useEffect, useMemo, useContext, useSyncExternalStore } from 'react';
5
6
  import { useQueryClient, useMutation, useQuery } from '@tanstack/react-query';
6
7
 
7
8
  function useOrbitalHistory(options) {
@@ -1388,6 +1389,28 @@ function useInput() {
1388
1389
  }, [input?.id]);
1389
1390
  return { input, updateInput: update };
1390
1391
  }
1392
+ var I18nContext = createContext({
1393
+ locale: "en",
1394
+ direction: "ltr",
1395
+ t: (key) => key
1396
+ // passthrough fallback
1397
+ });
1398
+ I18nContext.displayName = "I18nContext";
1399
+ var I18nProvider = I18nContext.Provider;
1400
+ function useTranslate() {
1401
+ return useContext(I18nContext);
1402
+ }
1403
+ function createTranslate(messages) {
1404
+ return (key, params) => {
1405
+ let msg = messages[key] ?? key;
1406
+ if (params) {
1407
+ for (const [k, v] of Object.entries(params)) {
1408
+ msg = msg.split(`{{${k}}}`).join(String(v));
1409
+ }
1410
+ }
1411
+ return msg;
1412
+ };
1413
+ }
1391
1414
 
1392
1415
  // hooks/useAuthContext.ts
1393
1416
  function useAuthContext() {
@@ -1474,4 +1497,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
1474
1497
  });
1475
1498
  }
1476
1499
 
1477
- export { ENTITY_EVENTS, parseQueryBinding, useAgentChat, useAuthContext, useCompile, useConnectGitHub, useCreateEntity, useDeepAgentGeneration, useDeleteEntity, useDisconnectGitHub, useEntities, useEntitiesByType, useEntity, useEntityMutations, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInput, useOrbitalHistory, useOrbitalMutations, usePhysics, usePlayer, usePreview, useQuerySingleton, useSelectedEntity, useSendOrbitalEvent, useSingletonEntity, useUIEvents, useUpdateEntity, useValidation };
1500
+ export { ENTITY_EVENTS, I18nProvider, createTranslate, parseQueryBinding, useAgentChat, useAuthContext, useCompile, useConnectGitHub, useCreateEntity, useDeepAgentGeneration, useDeleteEntity, useDisconnectGitHub, useEntities, useEntitiesByType, useEntity, useEntityMutations, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInput, useOrbitalHistory, useOrbitalMutations, usePhysics, usePlayer, usePreview, useQuerySingleton, useSelectedEntity, useSendOrbitalEvent, useSingletonEntity, useTranslate, useUIEvents, useUpdateEntity, useValidation };