@flamingo-stack/openframe-frontend-core 0.0.263 → 0.0.264
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.
- package/dist/{chunk-C3FAOQAH.cjs → chunk-3LWUHLPK.cjs} +28 -28
- package/dist/{chunk-C3FAOQAH.cjs.map → chunk-3LWUHLPK.cjs.map} +1 -1
- package/dist/{chunk-U7UDESAU.js → chunk-6ZEKKAAL.js} +2 -2
- package/dist/{chunk-YC357BPF.js → chunk-JOUI6TQY.js} +3 -3
- package/dist/{chunk-2XUWR7AH.cjs → chunk-P67D545X.cjs} +11 -11
- package/dist/{chunk-2XUWR7AH.cjs.map → chunk-P67D545X.cjs.map} +1 -1
- package/dist/{chunk-3DC6MHW6.cjs → chunk-QLWBBCI5.cjs} +491 -391
- package/dist/chunk-QLWBBCI5.cjs.map +1 -0
- package/dist/{chunk-36HLBLDK.cjs → chunk-SIYHXLFH.cjs} +462 -454
- package/dist/chunk-SIYHXLFH.cjs.map +1 -0
- package/dist/{chunk-ALEKX56R.js → chunk-SSUUMPAQ.js} +2 -2
- package/dist/{chunk-6AIXHYBZ.js → chunk-VYTU7JZR.js} +64 -56
- package/dist/chunk-VYTU7JZR.js.map +1 -0
- package/dist/{chunk-6GBA6YJN.js → chunk-ZMFT5XOB.js} +576 -476
- package/dist/chunk-ZMFT5XOB.js.map +1 -0
- package/dist/{chunk-XKA7UFED.cjs → chunk-ZOOTBYZO.cjs} +30 -30
- package/dist/{chunk-XKA7UFED.cjs.map → chunk-ZOOTBYZO.cjs.map} +1 -1
- package/dist/components/chat/index.cjs +3 -3
- package/dist/components/chat/index.js +2 -2
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/contact/index.js +3 -3
- package/dist/components/features/index.cjs +3 -3
- package/dist/components/features/index.js +2 -2
- package/dist/components/features/notifications/notification-drawer.d.ts.map +1 -1
- package/dist/components/features/notifications/notifications-context.d.ts +9 -1
- package/dist/components/features/notifications/notifications-context.d.ts.map +1 -1
- package/dist/components/index.cjs +50 -50
- package/dist/components/index.js +4 -4
- package/dist/components/navigation/index.cjs +3 -3
- package/dist/components/navigation/index.js +2 -2
- package/dist/components/navigation/sliding-sidebar.d.ts.map +1 -1
- package/dist/components/related-content/index.cjs +4 -4
- package/dist/components/related-content/index.js +3 -3
- package/dist/components/tickets/index.cjs +58 -58
- package/dist/components/tickets/index.js +4 -4
- package/dist/components/ui/drawer.d.ts +5 -0
- package/dist/components/ui/drawer.d.ts.map +1 -1
- package/dist/components/ui/index.cjs +3 -3
- package/dist/components/ui/index.js +2 -2
- package/dist/hooks/index.cjs +6 -2
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +5 -1
- package/dist/hooks/ui/index.d.ts +6 -4
- package/dist/hooks/ui/index.d.ts.map +1 -1
- package/dist/hooks/ui/use-header-height.d.ts +8 -0
- package/dist/hooks/ui/use-header-height.d.ts.map +1 -0
- package/dist/hooks/ui/use-horizontal-scrollbar.d.ts.map +1 -1
- package/dist/hooks/ui/use-notification-permission.d.ts +14 -0
- package/dist/hooks/ui/use-notification-permission.d.ts.map +1 -0
- package/dist/index.cjs +7 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -2
- package/package.json +1 -1
- package/src/components/features/notifications/notification-drawer.tsx +51 -2
- package/src/components/features/notifications/notifications-context.tsx +26 -0
- package/src/components/navigation/sliding-sidebar.tsx +3 -82
- package/src/components/ui/drawer.tsx +17 -6
- package/src/hooks/ui/index.ts +6 -4
- package/src/hooks/ui/use-header-height.ts +55 -0
- package/src/hooks/ui/use-horizontal-scrollbar.ts +19 -2
- package/src/hooks/ui/use-notification-permission.ts +64 -0
- package/dist/chunk-36HLBLDK.cjs.map +0 -1
- package/dist/chunk-3DC6MHW6.cjs.map +0 -1
- package/dist/chunk-6AIXHYBZ.js.map +0 -1
- package/dist/chunk-6GBA6YJN.js.map +0 -1
- /package/dist/{chunk-U7UDESAU.js.map → chunk-6ZEKKAAL.js.map} +0 -0
- /package/dist/{chunk-YC357BPF.js.map → chunk-JOUI6TQY.js.map} +0 -0
- /package/dist/{chunk-ALEKX56R.js.map → chunk-SSUUMPAQ.js.map} +0 -0
|
@@ -33,355 +33,46 @@ var _chunkFIG2RKZFcjs = require('./chunk-FIG2RKZF.cjs');
|
|
|
33
33
|
|
|
34
34
|
var _chunkC6ASEPZLcjs = require('./chunk-C6ASEPZL.cjs');
|
|
35
35
|
|
|
36
|
-
// src/hooks/ui/use-
|
|
37
|
-
var _react = require('react'); var React = _interopRequireWildcard(_react);
|
|
38
|
-
function
|
|
39
|
-
const [
|
|
40
|
-
try {
|
|
41
|
-
if (typeof window !== "undefined") {
|
|
42
|
-
const item = window.localStorage.getItem(key);
|
|
43
|
-
return item ? JSON.parse(item) : initialValue;
|
|
44
|
-
}
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error(`Error reading localStorage key "${key}":`, error);
|
|
47
|
-
}
|
|
48
|
-
return initialValue;
|
|
49
|
-
});
|
|
50
|
-
const isInitialized = _react.useRef.call(void 0, true);
|
|
51
|
-
const isFromStorageEvent = _react.useRef.call(void 0, false);
|
|
52
|
-
_react.useEffect.call(void 0, () => {
|
|
53
|
-
if (!isInitialized.current) return;
|
|
54
|
-
const handleStorageChange = (e) => {
|
|
55
|
-
if (e.key === key && e.newValue !== null) {
|
|
56
|
-
try {
|
|
57
|
-
const newValue = JSON.parse(e.newValue);
|
|
58
|
-
isFromStorageEvent.current = true;
|
|
59
|
-
setStoredValue(newValue);
|
|
60
|
-
console.log(`\u{1F504} Updated localStorage key "${key}" from storage event`);
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.error(`Error parsing storage event for key "${key}":`, error);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
const handleCustomStorageUpdate = (e) => {
|
|
67
|
-
if (e.detail.key === key) {
|
|
68
|
-
try {
|
|
69
|
-
if (e.detail.newValue === null || e.detail.newValue === void 0) {
|
|
70
|
-
isFromStorageEvent.current = true;
|
|
71
|
-
setStoredValue(initialValue);
|
|
72
|
-
console.log(`\u{1F504} Cleared localStorage key "${key}" from custom storage event`);
|
|
73
|
-
} else {
|
|
74
|
-
const newValue = JSON.parse(e.detail.newValue);
|
|
75
|
-
isFromStorageEvent.current = true;
|
|
76
|
-
setStoredValue(newValue);
|
|
77
|
-
console.log(`\u{1F504} Updated localStorage key "${key}" from custom storage event`);
|
|
78
|
-
}
|
|
79
|
-
} catch (error) {
|
|
80
|
-
console.error(`Error parsing custom storage event for key "${key}":`, error);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
window.addEventListener("storage", handleStorageChange);
|
|
85
|
-
window.addEventListener("localStorageUpdate", handleCustomStorageUpdate);
|
|
86
|
-
return () => {
|
|
87
|
-
window.removeEventListener("storage", handleStorageChange);
|
|
88
|
-
window.removeEventListener("localStorageUpdate", handleCustomStorageUpdate);
|
|
89
|
-
};
|
|
90
|
-
}, [key]);
|
|
91
|
-
_react.useEffect.call(void 0, () => {
|
|
92
|
-
if (!isInitialized.current) return;
|
|
93
|
-
if (isFromStorageEvent.current) {
|
|
94
|
-
isFromStorageEvent.current = false;
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
try {
|
|
98
|
-
if (typeof window !== "undefined") {
|
|
99
|
-
window.localStorage.setItem(key, JSON.stringify(storedValue));
|
|
100
|
-
}
|
|
101
|
-
} catch (error) {
|
|
102
|
-
console.error(`Error writing to localStorage key "${key}":`, error);
|
|
103
|
-
}
|
|
104
|
-
}, [key, storedValue]);
|
|
105
|
-
const setValue = (value) => {
|
|
106
|
-
try {
|
|
107
|
-
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
108
|
-
setStoredValue(valueToStore);
|
|
109
|
-
} catch (error) {
|
|
110
|
-
console.error(`Error setting value for localStorage key "${key}":`, error);
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
return [storedValue, setValue];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// src/hooks/ui/use-media-query.ts
|
|
117
|
-
|
|
118
|
-
function useMediaQuery(query) {
|
|
119
|
-
const [matches, setMatches] = _react.useState.call(void 0, void 0);
|
|
120
|
-
_react.useLayoutEffect.call(void 0, () => {
|
|
121
|
-
const matchMedia = window.matchMedia(query);
|
|
122
|
-
const handleChange = () => {
|
|
123
|
-
setMatches(matchMedia.matches);
|
|
124
|
-
};
|
|
125
|
-
handleChange();
|
|
126
|
-
matchMedia.addEventListener("change", handleChange);
|
|
127
|
-
return () => {
|
|
128
|
-
matchMedia.removeEventListener("change", handleChange);
|
|
129
|
-
};
|
|
130
|
-
}, [query]);
|
|
131
|
-
return matches;
|
|
132
|
-
}
|
|
133
|
-
var breakpoints = {
|
|
134
|
-
md: "(min-width: 800px)",
|
|
135
|
-
// Tablet: 50rem
|
|
136
|
-
lg: "(min-width: 1280px)"
|
|
137
|
-
// Desktop: 80rem
|
|
138
|
-
};
|
|
139
|
-
function useSmUp() {
|
|
140
|
-
return useMdUp();
|
|
141
|
-
}
|
|
142
|
-
function useMdUp() {
|
|
143
|
-
const matches = useMediaQuery(breakpoints.md);
|
|
144
|
-
return matches === void 0 ? void 0 : matches;
|
|
145
|
-
}
|
|
146
|
-
function useLgUp() {
|
|
147
|
-
const matches = useMediaQuery(breakpoints.lg);
|
|
148
|
-
return matches === void 0 ? void 0 : matches;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// src/hooks/ui/use-memoized-callback.ts
|
|
152
|
-
|
|
153
|
-
function useMemoizedCallback(callback, dependencies) {
|
|
154
|
-
const callbackRef = _react.useRef.call(void 0, callback);
|
|
155
|
-
const dependenciesRef = _react.useRef.call(void 0, dependencies);
|
|
156
|
-
callbackRef.current = callback;
|
|
157
|
-
const depsChanged = dependencies.some((dep, i) => !Object.is(dep, dependenciesRef.current[i]));
|
|
158
|
-
if (depsChanged) {
|
|
159
|
-
dependenciesRef.current = dependencies;
|
|
160
|
-
}
|
|
161
|
-
return _react.useCallback.call(void 0, ((...args) => callbackRef.current(...args)), [depsChanged]);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// src/hooks/ui/use-onboarding-state.ts
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
// src/utils/onboarding-storage.ts
|
|
168
|
-
var DEFAULT_STATE = {
|
|
169
|
-
completedSteps: [],
|
|
170
|
-
skippedSteps: [],
|
|
171
|
-
dismissed: false,
|
|
172
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
173
|
-
};
|
|
174
|
-
function saveOnboardingState(key, state) {
|
|
175
|
-
if (typeof window === "undefined") return;
|
|
176
|
-
try {
|
|
177
|
-
localStorage.setItem(key, JSON.stringify(state));
|
|
178
|
-
console.log("\u{1F4BE} Saved onboarding state:", state);
|
|
179
|
-
if (typeof window !== "undefined") {
|
|
180
|
-
window.dispatchEvent(
|
|
181
|
-
new CustomEvent("localStorageUpdate", {
|
|
182
|
-
detail: { key, newValue: JSON.stringify(state) }
|
|
183
|
-
})
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
} catch (err) {
|
|
187
|
-
console.warn("[onboarding-storage] Failed saving to localStorage:", err);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
function loadOnboardingState(key) {
|
|
191
|
-
if (typeof window === "undefined") return DEFAULT_STATE;
|
|
192
|
-
try {
|
|
193
|
-
const raw = localStorage.getItem(key);
|
|
194
|
-
if (!raw) return DEFAULT_STATE;
|
|
195
|
-
const parsed = JSON.parse(raw);
|
|
196
|
-
return parsed;
|
|
197
|
-
} catch (err) {
|
|
198
|
-
console.warn("[onboarding-storage] Failed parsing localStorage data:", err);
|
|
199
|
-
return DEFAULT_STATE;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function markMultipleComplete(key, stepIds) {
|
|
203
|
-
const state = loadOnboardingState(key);
|
|
204
|
-
const newState = {
|
|
205
|
-
...state,
|
|
206
|
-
completedSteps: [.../* @__PURE__ */ new Set([...state.completedSteps, ...stepIds])],
|
|
207
|
-
skippedSteps: state.skippedSteps.filter((id) => !stepIds.includes(id)),
|
|
208
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
209
|
-
};
|
|
210
|
-
saveOnboardingState(key, newState);
|
|
211
|
-
return newState;
|
|
212
|
-
}
|
|
213
|
-
function markStepComplete(key, stepId) {
|
|
214
|
-
return markMultipleComplete(key, [stepId]);
|
|
215
|
-
}
|
|
216
|
-
function markStepSkipped(key, stepId) {
|
|
217
|
-
const state = loadOnboardingState(key);
|
|
218
|
-
const newState = {
|
|
219
|
-
...state,
|
|
220
|
-
skippedSteps: [.../* @__PURE__ */ new Set([...state.skippedSteps, stepId])],
|
|
221
|
-
completedSteps: state.completedSteps.filter((id) => id !== stepId),
|
|
222
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
223
|
-
};
|
|
224
|
-
saveOnboardingState(key, newState);
|
|
225
|
-
return newState;
|
|
226
|
-
}
|
|
227
|
-
function dismissOnboarding(key) {
|
|
228
|
-
const state = loadOnboardingState(key);
|
|
229
|
-
const newState = {
|
|
230
|
-
...state,
|
|
231
|
-
dismissed: true,
|
|
232
|
-
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
233
|
-
};
|
|
234
|
-
saveOnboardingState(key, newState);
|
|
235
|
-
return newState;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// src/hooks/ui/use-onboarding-state.ts
|
|
239
|
-
function useOnboardingState(storageKey = "openframe-onboarding-state") {
|
|
240
|
-
const [state, setState] = _react.useState.call(void 0, () => loadOnboardingState(storageKey));
|
|
241
|
-
const [, forceUpdate] = _react.useState.call(void 0, 0);
|
|
242
|
-
_react.useEffect.call(void 0, () => {
|
|
243
|
-
const handleStorageUpdate = (e) => {
|
|
244
|
-
if (e.detail.key === storageKey) {
|
|
245
|
-
const newState = loadOnboardingState(storageKey);
|
|
246
|
-
setState(newState);
|
|
247
|
-
forceUpdate((prev) => prev + 1);
|
|
248
|
-
console.log("\u{1F504} State updated from storage event:", newState);
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
window.addEventListener("localStorageUpdate", handleStorageUpdate);
|
|
252
|
-
return () => {
|
|
253
|
-
window.removeEventListener("localStorageUpdate", handleStorageUpdate);
|
|
254
|
-
};
|
|
255
|
-
}, [storageKey]);
|
|
256
|
-
const markComplete = _react.useCallback.call(void 0, (stepId) => {
|
|
257
|
-
console.log(`\u{1F3AF} markComplete called for: "${stepId}"`);
|
|
258
|
-
const newState = markStepComplete(storageKey, stepId);
|
|
259
|
-
setState(newState);
|
|
260
|
-
forceUpdate((prev) => prev + 1);
|
|
261
|
-
}, [storageKey]);
|
|
262
|
-
const markSkipped = _react.useCallback.call(void 0, (stepId) => {
|
|
263
|
-
console.log(`\u23ED\uFE0F markSkipped called for: "${stepId}"`);
|
|
264
|
-
const newState = markStepSkipped(storageKey, stepId);
|
|
265
|
-
setState(newState);
|
|
266
|
-
forceUpdate((prev) => prev + 1);
|
|
267
|
-
}, [storageKey]);
|
|
268
|
-
const dismissOnboarding2 = _react.useCallback.call(void 0, () => {
|
|
269
|
-
console.log(`\u{1F6AB} dismissOnboarding called`);
|
|
270
|
-
const newState = dismissOnboarding(storageKey);
|
|
271
|
-
setState(newState);
|
|
272
|
-
forceUpdate((prev) => prev + 1);
|
|
273
|
-
}, [storageKey]);
|
|
274
|
-
const markMultipleComplete2 = _react.useCallback.call(void 0, (stepIds) => {
|
|
275
|
-
console.log(`\u{1F3AF} markMultipleComplete called for:`, stepIds);
|
|
276
|
-
const newState = markMultipleComplete(storageKey, stepIds);
|
|
277
|
-
setState(newState);
|
|
278
|
-
forceUpdate((prev) => prev + 1);
|
|
279
|
-
console.log(`\u{1F4DD} State after batch:`, newState);
|
|
280
|
-
}, [storageKey]);
|
|
281
|
-
const isStepComplete = _react.useCallback.call(void 0, (stepId) => {
|
|
282
|
-
return state.completedSteps.includes(stepId);
|
|
283
|
-
}, [state.completedSteps]);
|
|
284
|
-
const isStepSkipped = _react.useCallback.call(void 0, (stepId) => {
|
|
285
|
-
return state.skippedSteps.includes(stepId);
|
|
286
|
-
}, [state.skippedSteps]);
|
|
287
|
-
const allStepsComplete = _react.useCallback.call(void 0, (steps) => {
|
|
288
|
-
return steps.every((step) => isStepComplete(step.id) || isStepSkipped(step.id));
|
|
289
|
-
}, [isStepComplete, isStepSkipped]);
|
|
290
|
-
return {
|
|
291
|
-
state,
|
|
292
|
-
markComplete,
|
|
293
|
-
markSkipped,
|
|
294
|
-
dismissOnboarding: dismissOnboarding2,
|
|
295
|
-
isStepComplete,
|
|
296
|
-
isStepSkipped,
|
|
297
|
-
allStepsComplete,
|
|
298
|
-
markMultipleComplete: markMultipleComplete2
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// src/hooks/ui/use-table-pagination.ts
|
|
303
|
-
|
|
304
|
-
function useTablePagination(config) {
|
|
305
|
-
return _react.useMemo.call(void 0, () => {
|
|
306
|
-
if (!config) return void 0;
|
|
307
|
-
if (config.type === "client") {
|
|
308
|
-
if (config.totalPages <= 1) return void 0;
|
|
309
|
-
return {
|
|
310
|
-
hasNextPage: config.currentPage < config.totalPages,
|
|
311
|
-
hasPreviousPage: config.currentPage > 1,
|
|
312
|
-
isFirstPage: config.currentPage === 1,
|
|
313
|
-
startCursor: (config.currentPage - 1).toString(),
|
|
314
|
-
endCursor: config.currentPage.toString(),
|
|
315
|
-
currentCount: config.itemCount,
|
|
316
|
-
itemName: config.itemName || "items",
|
|
317
|
-
onNext: () => config.onNext(),
|
|
318
|
-
onPrevious: () => config.onPrevious(),
|
|
319
|
-
showInfo: _nullishCoalesce(config.showInfo, () => ( true))
|
|
320
|
-
};
|
|
321
|
-
} else {
|
|
322
|
-
return {
|
|
323
|
-
hasNextPage: config.hasNextPage,
|
|
324
|
-
hasPreviousPage: config.hasLoadedBeyondFirst,
|
|
325
|
-
isFirstPage: !config.hasLoadedBeyondFirst,
|
|
326
|
-
startCursor: config.startCursor,
|
|
327
|
-
endCursor: config.endCursor,
|
|
328
|
-
currentCount: config.itemCount,
|
|
329
|
-
itemName: config.itemName || "items",
|
|
330
|
-
onNext: config.onNext,
|
|
331
|
-
onPrevious: config.onReset,
|
|
332
|
-
// Previous button goes back to first page
|
|
333
|
-
showInfo: _nullishCoalesce(config.showInfo, () => ( true))
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
}, [config]);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// src/hooks/ui/use-throttle.ts
|
|
340
|
-
|
|
341
|
-
function useThrottle(value, limit = 200) {
|
|
342
|
-
const [throttledValue, setThrottledValue] = _react.useState.call(void 0, value);
|
|
343
|
-
const lastUpdated = _react.useRef.call(void 0, Date.now());
|
|
36
|
+
// src/hooks/ui/use-header-height.ts
|
|
37
|
+
var _react = require('react'); var React = _interopRequireWildcard(_react);
|
|
38
|
+
function useHeaderHeight(defaultHeight = 64) {
|
|
39
|
+
const [height, setHeight] = _react.useState.call(void 0, defaultHeight);
|
|
344
40
|
_react.useEffect.call(void 0, () => {
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
setThrottledValue(value);
|
|
353
|
-
lastUpdated.current = Date.now();
|
|
354
|
-
}, limit - elapsed);
|
|
355
|
-
return () => {
|
|
356
|
-
clearTimeout(timerId);
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
}, [value, limit]);
|
|
360
|
-
return throttledValue;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// src/hooks/ui/use-window-size.ts
|
|
364
|
-
|
|
365
|
-
function useWindowSize() {
|
|
366
|
-
const [windowSize, setWindowSize] = _react.useState.call(void 0, {
|
|
367
|
-
width: 0,
|
|
368
|
-
height: 0
|
|
369
|
-
});
|
|
370
|
-
const [isClient, setIsClient] = _react.useState.call(void 0, false);
|
|
371
|
-
_react.useLayoutEffect.call(void 0, () => {
|
|
372
|
-
setIsClient(true);
|
|
373
|
-
if (!isClient) return;
|
|
374
|
-
const handleResize = () => {
|
|
375
|
-
setWindowSize({
|
|
376
|
-
width: window.innerWidth,
|
|
377
|
-
height: window.innerHeight
|
|
378
|
-
});
|
|
41
|
+
const measure = () => {
|
|
42
|
+
let total = 0;
|
|
43
|
+
const header2 = document.querySelector("header");
|
|
44
|
+
if (header2) total += header2.offsetHeight;
|
|
45
|
+
const bar2 = document.querySelector("[data-announcement-bar]");
|
|
46
|
+
if (bar2 instanceof HTMLElement) total += bar2.offsetHeight;
|
|
47
|
+
setHeight(total > 0 ? total : defaultHeight);
|
|
379
48
|
};
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
49
|
+
measure();
|
|
50
|
+
const resizeObserver = new ResizeObserver(measure);
|
|
51
|
+
const header = document.querySelector("header");
|
|
52
|
+
if (header) resizeObserver.observe(header);
|
|
53
|
+
const bar = document.querySelector("[data-announcement-bar]");
|
|
54
|
+
if (bar) resizeObserver.observe(bar);
|
|
55
|
+
const mutationObserver = new MutationObserver((mutations) => {
|
|
56
|
+
for (const mutation of mutations) {
|
|
57
|
+
if (mutation.type === "childList" || mutation.type === "attributes") {
|
|
58
|
+
measure();
|
|
59
|
+
const newBar = document.querySelector("[data-announcement-bar]");
|
|
60
|
+
if (newBar) resizeObserver.observe(newBar);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
mutationObserver.observe(document.body, {
|
|
65
|
+
childList: true,
|
|
66
|
+
subtree: true,
|
|
67
|
+
attributes: true,
|
|
68
|
+
attributeFilter: ["data-announcement-bar"]
|
|
69
|
+
});
|
|
70
|
+
return () => {
|
|
71
|
+
resizeObserver.disconnect();
|
|
72
|
+
mutationObserver.disconnect();
|
|
73
|
+
};
|
|
74
|
+
}, [defaultHeight]);
|
|
75
|
+
return height;
|
|
385
76
|
}
|
|
386
77
|
|
|
387
78
|
// src/hooks/ui/use-horizontal-scrollbar.ts
|
|
@@ -391,6 +82,7 @@ function useHorizontalScrollbar() {
|
|
|
391
82
|
const trackRef = _react.useRef.call(void 0, null);
|
|
392
83
|
const thumbRef = _react.useRef.call(void 0, null);
|
|
393
84
|
const roRef = _react.useRef.call(void 0, null);
|
|
85
|
+
const moRef = _react.useRef.call(void 0, null);
|
|
394
86
|
const [thumbRatio, setThumbRatio] = _react.useState.call(void 0, 0);
|
|
395
87
|
const [canScrollLeft, setCanScrollLeft] = _react.useState.call(void 0, false);
|
|
396
88
|
const [canScrollRight, setCanScrollRight] = _react.useState.call(void 0, false);
|
|
@@ -453,6 +145,10 @@ function useHorizontalScrollbar() {
|
|
|
453
145
|
roRef.current.disconnect();
|
|
454
146
|
roRef.current = null;
|
|
455
147
|
}
|
|
148
|
+
if (moRef.current) {
|
|
149
|
+
moRef.current.disconnect();
|
|
150
|
+
moRef.current = null;
|
|
151
|
+
}
|
|
456
152
|
if (rafIdRef.current) {
|
|
457
153
|
cancelAnimationFrame(rafIdRef.current);
|
|
458
154
|
rafIdRef.current = 0;
|
|
@@ -461,8 +157,19 @@ function useHorizontalScrollbar() {
|
|
|
461
157
|
if (node) {
|
|
462
158
|
const ratio = node.clientWidth / node.scrollWidth;
|
|
463
159
|
setThumbRatio(ratio >= 1 ? 0 : ratio);
|
|
464
|
-
|
|
465
|
-
roRef.current
|
|
160
|
+
const ro = new ResizeObserver(measure);
|
|
161
|
+
roRef.current = ro;
|
|
162
|
+
const observeAll = () => {
|
|
163
|
+
ro.disconnect();
|
|
164
|
+
ro.observe(node);
|
|
165
|
+
for (const child of Array.from(node.children)) ro.observe(child);
|
|
166
|
+
};
|
|
167
|
+
observeAll();
|
|
168
|
+
moRef.current = new MutationObserver(() => {
|
|
169
|
+
observeAll();
|
|
170
|
+
measure();
|
|
171
|
+
});
|
|
172
|
+
moRef.current.observe(node, { childList: true });
|
|
466
173
|
requestAnimationFrame(() => {
|
|
467
174
|
syncThumbToDOM();
|
|
468
175
|
syncEdgeFades();
|
|
@@ -602,48 +309,354 @@ function extractEdgeColor(img) {
|
|
|
602
309
|
buckets.set(key, { r: r2, g: g2, b: b2, count: 1 });
|
|
603
310
|
}
|
|
604
311
|
}
|
|
605
|
-
}
|
|
606
|
-
if (buckets.size === 0) return "#000000";
|
|
607
|
-
let bestBucket = null;
|
|
608
|
-
for (const bucket of buckets.values()) {
|
|
609
|
-
if (!bestBucket || bucket.count > bestBucket.count) {
|
|
610
|
-
bestBucket = bucket;
|
|
312
|
+
}
|
|
313
|
+
if (buckets.size === 0) return "#000000";
|
|
314
|
+
let bestBucket = null;
|
|
315
|
+
for (const bucket of buckets.values()) {
|
|
316
|
+
if (!bestBucket || bucket.count > bestBucket.count) {
|
|
317
|
+
bestBucket = bucket;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (!bestBucket || bestBucket.count === 0) return "#000000";
|
|
321
|
+
const r = Math.round(bestBucket.r / bestBucket.count);
|
|
322
|
+
const g = Math.round(bestBucket.g / bestBucket.count);
|
|
323
|
+
const b = Math.round(bestBucket.b / bestBucket.count);
|
|
324
|
+
return `rgb(${r}, ${g}, ${b})`;
|
|
325
|
+
}
|
|
326
|
+
function useImageEdgeColor(imageUrl, fallback = "#000000") {
|
|
327
|
+
const [color, setColor] = _react.useState.call(void 0, fallback);
|
|
328
|
+
_react.useEffect.call(void 0, () => {
|
|
329
|
+
if (!imageUrl) {
|
|
330
|
+
setColor(fallback);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
let cancelled = false;
|
|
334
|
+
const img = new Image();
|
|
335
|
+
img.crossOrigin = "anonymous";
|
|
336
|
+
img.onload = () => {
|
|
337
|
+
if (cancelled) return;
|
|
338
|
+
try {
|
|
339
|
+
setColor(extractEdgeColor(img));
|
|
340
|
+
} catch (e2) {
|
|
341
|
+
setColor(fallback);
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
img.onerror = () => {
|
|
345
|
+
if (cancelled) return;
|
|
346
|
+
setColor(fallback);
|
|
347
|
+
};
|
|
348
|
+
img.src = imageUrl;
|
|
349
|
+
return () => {
|
|
350
|
+
cancelled = true;
|
|
351
|
+
};
|
|
352
|
+
}, [imageUrl, fallback]);
|
|
353
|
+
return color;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/hooks/ui/use-local-storage.ts
|
|
357
|
+
|
|
358
|
+
function useLocalStorage(key, initialValue) {
|
|
359
|
+
const [storedValue, setStoredValue] = _react.useState.call(void 0, () => {
|
|
360
|
+
try {
|
|
361
|
+
if (typeof window !== "undefined") {
|
|
362
|
+
const item = window.localStorage.getItem(key);
|
|
363
|
+
return item ? JSON.parse(item) : initialValue;
|
|
364
|
+
}
|
|
365
|
+
} catch (error) {
|
|
366
|
+
console.error(`Error reading localStorage key "${key}":`, error);
|
|
367
|
+
}
|
|
368
|
+
return initialValue;
|
|
369
|
+
});
|
|
370
|
+
const isInitialized = _react.useRef.call(void 0, true);
|
|
371
|
+
const isFromStorageEvent = _react.useRef.call(void 0, false);
|
|
372
|
+
_react.useEffect.call(void 0, () => {
|
|
373
|
+
if (!isInitialized.current) return;
|
|
374
|
+
const handleStorageChange = (e) => {
|
|
375
|
+
if (e.key === key && e.newValue !== null) {
|
|
376
|
+
try {
|
|
377
|
+
const newValue = JSON.parse(e.newValue);
|
|
378
|
+
isFromStorageEvent.current = true;
|
|
379
|
+
setStoredValue(newValue);
|
|
380
|
+
console.log(`\u{1F504} Updated localStorage key "${key}" from storage event`);
|
|
381
|
+
} catch (error) {
|
|
382
|
+
console.error(`Error parsing storage event for key "${key}":`, error);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
const handleCustomStorageUpdate = (e) => {
|
|
387
|
+
if (e.detail.key === key) {
|
|
388
|
+
try {
|
|
389
|
+
if (e.detail.newValue === null || e.detail.newValue === void 0) {
|
|
390
|
+
isFromStorageEvent.current = true;
|
|
391
|
+
setStoredValue(initialValue);
|
|
392
|
+
console.log(`\u{1F504} Cleared localStorage key "${key}" from custom storage event`);
|
|
393
|
+
} else {
|
|
394
|
+
const newValue = JSON.parse(e.detail.newValue);
|
|
395
|
+
isFromStorageEvent.current = true;
|
|
396
|
+
setStoredValue(newValue);
|
|
397
|
+
console.log(`\u{1F504} Updated localStorage key "${key}" from custom storage event`);
|
|
398
|
+
}
|
|
399
|
+
} catch (error) {
|
|
400
|
+
console.error(`Error parsing custom storage event for key "${key}":`, error);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
window.addEventListener("storage", handleStorageChange);
|
|
405
|
+
window.addEventListener("localStorageUpdate", handleCustomStorageUpdate);
|
|
406
|
+
return () => {
|
|
407
|
+
window.removeEventListener("storage", handleStorageChange);
|
|
408
|
+
window.removeEventListener("localStorageUpdate", handleCustomStorageUpdate);
|
|
409
|
+
};
|
|
410
|
+
}, [key]);
|
|
411
|
+
_react.useEffect.call(void 0, () => {
|
|
412
|
+
if (!isInitialized.current) return;
|
|
413
|
+
if (isFromStorageEvent.current) {
|
|
414
|
+
isFromStorageEvent.current = false;
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
try {
|
|
418
|
+
if (typeof window !== "undefined") {
|
|
419
|
+
window.localStorage.setItem(key, JSON.stringify(storedValue));
|
|
420
|
+
}
|
|
421
|
+
} catch (error) {
|
|
422
|
+
console.error(`Error writing to localStorage key "${key}":`, error);
|
|
423
|
+
}
|
|
424
|
+
}, [key, storedValue]);
|
|
425
|
+
const setValue = (value) => {
|
|
426
|
+
try {
|
|
427
|
+
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
428
|
+
setStoredValue(valueToStore);
|
|
429
|
+
} catch (error) {
|
|
430
|
+
console.error(`Error setting value for localStorage key "${key}":`, error);
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
return [storedValue, setValue];
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// src/hooks/ui/use-media-query.ts
|
|
437
|
+
|
|
438
|
+
function useMediaQuery(query) {
|
|
439
|
+
const [matches, setMatches] = _react.useState.call(void 0, void 0);
|
|
440
|
+
_react.useLayoutEffect.call(void 0, () => {
|
|
441
|
+
const matchMedia = window.matchMedia(query);
|
|
442
|
+
const handleChange = () => {
|
|
443
|
+
setMatches(matchMedia.matches);
|
|
444
|
+
};
|
|
445
|
+
handleChange();
|
|
446
|
+
matchMedia.addEventListener("change", handleChange);
|
|
447
|
+
return () => {
|
|
448
|
+
matchMedia.removeEventListener("change", handleChange);
|
|
449
|
+
};
|
|
450
|
+
}, [query]);
|
|
451
|
+
return matches;
|
|
452
|
+
}
|
|
453
|
+
var breakpoints = {
|
|
454
|
+
md: "(min-width: 800px)",
|
|
455
|
+
// Tablet: 50rem
|
|
456
|
+
lg: "(min-width: 1280px)"
|
|
457
|
+
// Desktop: 80rem
|
|
458
|
+
};
|
|
459
|
+
function useSmUp() {
|
|
460
|
+
return useMdUp();
|
|
461
|
+
}
|
|
462
|
+
function useMdUp() {
|
|
463
|
+
const matches = useMediaQuery(breakpoints.md);
|
|
464
|
+
return matches === void 0 ? void 0 : matches;
|
|
465
|
+
}
|
|
466
|
+
function useLgUp() {
|
|
467
|
+
const matches = useMediaQuery(breakpoints.lg);
|
|
468
|
+
return matches === void 0 ? void 0 : matches;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// src/hooks/ui/use-memoized-callback.ts
|
|
472
|
+
|
|
473
|
+
function useMemoizedCallback(callback, dependencies) {
|
|
474
|
+
const callbackRef = _react.useRef.call(void 0, callback);
|
|
475
|
+
const dependenciesRef = _react.useRef.call(void 0, dependencies);
|
|
476
|
+
callbackRef.current = callback;
|
|
477
|
+
const depsChanged = dependencies.some((dep, i) => !Object.is(dep, dependenciesRef.current[i]));
|
|
478
|
+
if (depsChanged) {
|
|
479
|
+
dependenciesRef.current = dependencies;
|
|
480
|
+
}
|
|
481
|
+
return _react.useCallback.call(void 0, ((...args) => callbackRef.current(...args)), [depsChanged]);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// src/hooks/ui/use-notification-permission.ts
|
|
485
|
+
|
|
486
|
+
function useNotificationPermission() {
|
|
487
|
+
const [supported, setSupported] = _react.useState.call(void 0, false);
|
|
488
|
+
const [permission, setPermission] = _react.useState.call(void 0, "default");
|
|
489
|
+
_react.useEffect.call(void 0, () => {
|
|
490
|
+
if (typeof window === "undefined" || !("Notification" in window)) return;
|
|
491
|
+
setSupported(true);
|
|
492
|
+
const sync = () => setPermission(Notification.permission);
|
|
493
|
+
sync();
|
|
494
|
+
let cancelled = false;
|
|
495
|
+
let status;
|
|
496
|
+
_optionalChain([navigator, 'access', _2 => _2.permissions, 'optionalAccess', _3 => _3.query, 'call', _4 => _4({ name: "notifications" }), 'access', _5 => _5.then, 'call', _6 => _6((s) => {
|
|
497
|
+
if (cancelled) return;
|
|
498
|
+
status = s;
|
|
499
|
+
s.addEventListener("change", sync);
|
|
500
|
+
}), 'access', _7 => _7.catch, 'call', _8 => _8(() => void 0)]);
|
|
501
|
+
document.addEventListener("visibilitychange", sync);
|
|
502
|
+
window.addEventListener("focus", sync);
|
|
503
|
+
return () => {
|
|
504
|
+
cancelled = true;
|
|
505
|
+
_optionalChain([status, 'optionalAccess', _9 => _9.removeEventListener, 'call', _10 => _10("change", sync)]);
|
|
506
|
+
document.removeEventListener("visibilitychange", sync);
|
|
507
|
+
window.removeEventListener("focus", sync);
|
|
508
|
+
};
|
|
509
|
+
}, []);
|
|
510
|
+
const request = _react.useCallback.call(void 0, async () => {
|
|
511
|
+
if (typeof window === "undefined" || !("Notification" in window)) {
|
|
512
|
+
return "denied";
|
|
513
|
+
}
|
|
514
|
+
const result = await new Promise((resolve) => {
|
|
515
|
+
const maybePromise = Notification.requestPermission(resolve);
|
|
516
|
+
if (maybePromise && typeof maybePromise.then === "function") void maybePromise.then(resolve);
|
|
517
|
+
});
|
|
518
|
+
setPermission(Notification.permission);
|
|
519
|
+
return result;
|
|
520
|
+
}, []);
|
|
521
|
+
return { supported, permission, request };
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// src/hooks/ui/use-onboarding-state.ts
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
// src/utils/onboarding-storage.ts
|
|
528
|
+
var DEFAULT_STATE = {
|
|
529
|
+
completedSteps: [],
|
|
530
|
+
skippedSteps: [],
|
|
531
|
+
dismissed: false,
|
|
532
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
533
|
+
};
|
|
534
|
+
function saveOnboardingState(key, state) {
|
|
535
|
+
if (typeof window === "undefined") return;
|
|
536
|
+
try {
|
|
537
|
+
localStorage.setItem(key, JSON.stringify(state));
|
|
538
|
+
console.log("\u{1F4BE} Saved onboarding state:", state);
|
|
539
|
+
if (typeof window !== "undefined") {
|
|
540
|
+
window.dispatchEvent(
|
|
541
|
+
new CustomEvent("localStorageUpdate", {
|
|
542
|
+
detail: { key, newValue: JSON.stringify(state) }
|
|
543
|
+
})
|
|
544
|
+
);
|
|
611
545
|
}
|
|
546
|
+
} catch (err) {
|
|
547
|
+
console.warn("[onboarding-storage] Failed saving to localStorage:", err);
|
|
612
548
|
}
|
|
613
|
-
if (!bestBucket || bestBucket.count === 0) return "#000000";
|
|
614
|
-
const r = Math.round(bestBucket.r / bestBucket.count);
|
|
615
|
-
const g = Math.round(bestBucket.g / bestBucket.count);
|
|
616
|
-
const b = Math.round(bestBucket.b / bestBucket.count);
|
|
617
|
-
return `rgb(${r}, ${g}, ${b})`;
|
|
618
549
|
}
|
|
619
|
-
function
|
|
620
|
-
|
|
550
|
+
function loadOnboardingState(key) {
|
|
551
|
+
if (typeof window === "undefined") return DEFAULT_STATE;
|
|
552
|
+
try {
|
|
553
|
+
const raw = localStorage.getItem(key);
|
|
554
|
+
if (!raw) return DEFAULT_STATE;
|
|
555
|
+
const parsed = JSON.parse(raw);
|
|
556
|
+
return parsed;
|
|
557
|
+
} catch (err) {
|
|
558
|
+
console.warn("[onboarding-storage] Failed parsing localStorage data:", err);
|
|
559
|
+
return DEFAULT_STATE;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
function markMultipleComplete(key, stepIds) {
|
|
563
|
+
const state = loadOnboardingState(key);
|
|
564
|
+
const newState = {
|
|
565
|
+
...state,
|
|
566
|
+
completedSteps: [.../* @__PURE__ */ new Set([...state.completedSteps, ...stepIds])],
|
|
567
|
+
skippedSteps: state.skippedSteps.filter((id) => !stepIds.includes(id)),
|
|
568
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
569
|
+
};
|
|
570
|
+
saveOnboardingState(key, newState);
|
|
571
|
+
return newState;
|
|
572
|
+
}
|
|
573
|
+
function markStepComplete(key, stepId) {
|
|
574
|
+
return markMultipleComplete(key, [stepId]);
|
|
575
|
+
}
|
|
576
|
+
function markStepSkipped(key, stepId) {
|
|
577
|
+
const state = loadOnboardingState(key);
|
|
578
|
+
const newState = {
|
|
579
|
+
...state,
|
|
580
|
+
skippedSteps: [.../* @__PURE__ */ new Set([...state.skippedSteps, stepId])],
|
|
581
|
+
completedSteps: state.completedSteps.filter((id) => id !== stepId),
|
|
582
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
583
|
+
};
|
|
584
|
+
saveOnboardingState(key, newState);
|
|
585
|
+
return newState;
|
|
586
|
+
}
|
|
587
|
+
function dismissOnboarding(key) {
|
|
588
|
+
const state = loadOnboardingState(key);
|
|
589
|
+
const newState = {
|
|
590
|
+
...state,
|
|
591
|
+
dismissed: true,
|
|
592
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
593
|
+
};
|
|
594
|
+
saveOnboardingState(key, newState);
|
|
595
|
+
return newState;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// src/hooks/ui/use-onboarding-state.ts
|
|
599
|
+
function useOnboardingState(storageKey = "openframe-onboarding-state") {
|
|
600
|
+
const [state, setState] = _react.useState.call(void 0, () => loadOnboardingState(storageKey));
|
|
601
|
+
const [, forceUpdate] = _react.useState.call(void 0, 0);
|
|
621
602
|
_react.useEffect.call(void 0, () => {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
img.crossOrigin = "anonymous";
|
|
629
|
-
img.onload = () => {
|
|
630
|
-
if (cancelled) return;
|
|
631
|
-
try {
|
|
632
|
-
setColor(extractEdgeColor(img));
|
|
633
|
-
} catch (e2) {
|
|
634
|
-
setColor(fallback);
|
|
603
|
+
const handleStorageUpdate = (e) => {
|
|
604
|
+
if (e.detail.key === storageKey) {
|
|
605
|
+
const newState = loadOnboardingState(storageKey);
|
|
606
|
+
setState(newState);
|
|
607
|
+
forceUpdate((prev) => prev + 1);
|
|
608
|
+
console.log("\u{1F504} State updated from storage event:", newState);
|
|
635
609
|
}
|
|
636
610
|
};
|
|
637
|
-
|
|
638
|
-
if (cancelled) return;
|
|
639
|
-
setColor(fallback);
|
|
640
|
-
};
|
|
641
|
-
img.src = imageUrl;
|
|
611
|
+
window.addEventListener("localStorageUpdate", handleStorageUpdate);
|
|
642
612
|
return () => {
|
|
643
|
-
|
|
613
|
+
window.removeEventListener("localStorageUpdate", handleStorageUpdate);
|
|
644
614
|
};
|
|
645
|
-
}, [
|
|
646
|
-
|
|
615
|
+
}, [storageKey]);
|
|
616
|
+
const markComplete = _react.useCallback.call(void 0, (stepId) => {
|
|
617
|
+
console.log(`\u{1F3AF} markComplete called for: "${stepId}"`);
|
|
618
|
+
const newState = markStepComplete(storageKey, stepId);
|
|
619
|
+
setState(newState);
|
|
620
|
+
forceUpdate((prev) => prev + 1);
|
|
621
|
+
}, [storageKey]);
|
|
622
|
+
const markSkipped = _react.useCallback.call(void 0, (stepId) => {
|
|
623
|
+
console.log(`\u23ED\uFE0F markSkipped called for: "${stepId}"`);
|
|
624
|
+
const newState = markStepSkipped(storageKey, stepId);
|
|
625
|
+
setState(newState);
|
|
626
|
+
forceUpdate((prev) => prev + 1);
|
|
627
|
+
}, [storageKey]);
|
|
628
|
+
const dismissOnboarding2 = _react.useCallback.call(void 0, () => {
|
|
629
|
+
console.log(`\u{1F6AB} dismissOnboarding called`);
|
|
630
|
+
const newState = dismissOnboarding(storageKey);
|
|
631
|
+
setState(newState);
|
|
632
|
+
forceUpdate((prev) => prev + 1);
|
|
633
|
+
}, [storageKey]);
|
|
634
|
+
const markMultipleComplete2 = _react.useCallback.call(void 0, (stepIds) => {
|
|
635
|
+
console.log(`\u{1F3AF} markMultipleComplete called for:`, stepIds);
|
|
636
|
+
const newState = markMultipleComplete(storageKey, stepIds);
|
|
637
|
+
setState(newState);
|
|
638
|
+
forceUpdate((prev) => prev + 1);
|
|
639
|
+
console.log(`\u{1F4DD} State after batch:`, newState);
|
|
640
|
+
}, [storageKey]);
|
|
641
|
+
const isStepComplete = _react.useCallback.call(void 0, (stepId) => {
|
|
642
|
+
return state.completedSteps.includes(stepId);
|
|
643
|
+
}, [state.completedSteps]);
|
|
644
|
+
const isStepSkipped = _react.useCallback.call(void 0, (stepId) => {
|
|
645
|
+
return state.skippedSteps.includes(stepId);
|
|
646
|
+
}, [state.skippedSteps]);
|
|
647
|
+
const allStepsComplete = _react.useCallback.call(void 0, (steps) => {
|
|
648
|
+
return steps.every((step) => isStepComplete(step.id) || isStepSkipped(step.id));
|
|
649
|
+
}, [isStepComplete, isStepSkipped]);
|
|
650
|
+
return {
|
|
651
|
+
state,
|
|
652
|
+
markComplete,
|
|
653
|
+
markSkipped,
|
|
654
|
+
dismissOnboarding: dismissOnboarding2,
|
|
655
|
+
isStepComplete,
|
|
656
|
+
isStepSkipped,
|
|
657
|
+
allStepsComplete,
|
|
658
|
+
markMultipleComplete: markMultipleComplete2
|
|
659
|
+
};
|
|
647
660
|
}
|
|
648
661
|
|
|
649
662
|
// src/hooks/ui/use-search.ts
|
|
@@ -694,6 +707,91 @@ function useSearch(config) {
|
|
|
694
707
|
return { query, setQuery, results, isLoading, error, clearResults };
|
|
695
708
|
}
|
|
696
709
|
|
|
710
|
+
// src/hooks/ui/use-table-pagination.ts
|
|
711
|
+
|
|
712
|
+
function useTablePagination(config) {
|
|
713
|
+
return _react.useMemo.call(void 0, () => {
|
|
714
|
+
if (!config) return void 0;
|
|
715
|
+
if (config.type === "client") {
|
|
716
|
+
if (config.totalPages <= 1) return void 0;
|
|
717
|
+
return {
|
|
718
|
+
hasNextPage: config.currentPage < config.totalPages,
|
|
719
|
+
hasPreviousPage: config.currentPage > 1,
|
|
720
|
+
isFirstPage: config.currentPage === 1,
|
|
721
|
+
startCursor: (config.currentPage - 1).toString(),
|
|
722
|
+
endCursor: config.currentPage.toString(),
|
|
723
|
+
currentCount: config.itemCount,
|
|
724
|
+
itemName: config.itemName || "items",
|
|
725
|
+
onNext: () => config.onNext(),
|
|
726
|
+
onPrevious: () => config.onPrevious(),
|
|
727
|
+
showInfo: _nullishCoalesce(config.showInfo, () => ( true))
|
|
728
|
+
};
|
|
729
|
+
} else {
|
|
730
|
+
return {
|
|
731
|
+
hasNextPage: config.hasNextPage,
|
|
732
|
+
hasPreviousPage: config.hasLoadedBeyondFirst,
|
|
733
|
+
isFirstPage: !config.hasLoadedBeyondFirst,
|
|
734
|
+
startCursor: config.startCursor,
|
|
735
|
+
endCursor: config.endCursor,
|
|
736
|
+
currentCount: config.itemCount,
|
|
737
|
+
itemName: config.itemName || "items",
|
|
738
|
+
onNext: config.onNext,
|
|
739
|
+
onPrevious: config.onReset,
|
|
740
|
+
// Previous button goes back to first page
|
|
741
|
+
showInfo: _nullishCoalesce(config.showInfo, () => ( true))
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
}, [config]);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// src/hooks/ui/use-throttle.ts
|
|
748
|
+
|
|
749
|
+
function useThrottle(value, limit = 200) {
|
|
750
|
+
const [throttledValue, setThrottledValue] = _react.useState.call(void 0, value);
|
|
751
|
+
const lastUpdated = _react.useRef.call(void 0, Date.now());
|
|
752
|
+
_react.useEffect.call(void 0, () => {
|
|
753
|
+
const now = Date.now();
|
|
754
|
+
const elapsed = now - lastUpdated.current;
|
|
755
|
+
if (elapsed >= limit) {
|
|
756
|
+
setThrottledValue(value);
|
|
757
|
+
lastUpdated.current = now;
|
|
758
|
+
} else {
|
|
759
|
+
const timerId = setTimeout(() => {
|
|
760
|
+
setThrottledValue(value);
|
|
761
|
+
lastUpdated.current = Date.now();
|
|
762
|
+
}, limit - elapsed);
|
|
763
|
+
return () => {
|
|
764
|
+
clearTimeout(timerId);
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
}, [value, limit]);
|
|
768
|
+
return throttledValue;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// src/hooks/ui/use-window-size.ts
|
|
772
|
+
|
|
773
|
+
function useWindowSize() {
|
|
774
|
+
const [windowSize, setWindowSize] = _react.useState.call(void 0, {
|
|
775
|
+
width: 0,
|
|
776
|
+
height: 0
|
|
777
|
+
});
|
|
778
|
+
const [isClient, setIsClient] = _react.useState.call(void 0, false);
|
|
779
|
+
_react.useLayoutEffect.call(void 0, () => {
|
|
780
|
+
setIsClient(true);
|
|
781
|
+
if (!isClient) return;
|
|
782
|
+
const handleResize = () => {
|
|
783
|
+
setWindowSize({
|
|
784
|
+
width: window.innerWidth,
|
|
785
|
+
height: window.innerHeight
|
|
786
|
+
});
|
|
787
|
+
};
|
|
788
|
+
handleResize();
|
|
789
|
+
window.addEventListener("resize", handleResize);
|
|
790
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
791
|
+
}, [isClient]);
|
|
792
|
+
return windowSize;
|
|
793
|
+
}
|
|
794
|
+
|
|
697
795
|
// src/hooks/platform/use-platform-config.ts
|
|
698
796
|
|
|
699
797
|
|
|
@@ -995,7 +1093,7 @@ var toolIconMap = {
|
|
|
995
1093
|
[ToolTypeValues.OSQUERY]: (size, className) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkC6ASEPZLcjs.OsqueryLogoGreyIcon, { size, className }),
|
|
996
1094
|
[ToolTypeValues.SYSTEM]: () => null
|
|
997
1095
|
};
|
|
998
|
-
var ToolIcon = ({ toolType, size = 16, className }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: _nullishCoalesce(_optionalChain([toolIconMap, 'access',
|
|
1096
|
+
var ToolIcon = ({ toolType, size = 16, className }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: _nullishCoalesce(_optionalChain([toolIconMap, 'access', _11 => _11[toolType], 'optionalCall', _12 => _12(size, className)]), () => ( null)) });
|
|
999
1097
|
ToolIcon.displayName = "ToolIcon";
|
|
1000
1098
|
|
|
1001
1099
|
// src/components/ui/toaster.tsx
|
|
@@ -1114,11 +1212,11 @@ function CommandApprovalToast({
|
|
|
1114
1212
|
}) {
|
|
1115
1213
|
const [expanded, setExpanded] = React.useState(defaultExpanded);
|
|
1116
1214
|
const handleApprove = () => {
|
|
1117
|
-
_optionalChain([onApprove, 'optionalCall',
|
|
1215
|
+
_optionalChain([onApprove, 'optionalCall', _13 => _13()]);
|
|
1118
1216
|
_sonner.toast.dismiss(id);
|
|
1119
1217
|
};
|
|
1120
1218
|
const handleReject = () => {
|
|
1121
|
-
_optionalChain([onReject, 'optionalCall',
|
|
1219
|
+
_optionalChain([onReject, 'optionalCall', _14 => _14()]);
|
|
1122
1220
|
_sonner.toast.dismiss(id);
|
|
1123
1221
|
};
|
|
1124
1222
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
@@ -1972,7 +2070,7 @@ function setNestedValue(obj, path, value) {
|
|
|
1972
2070
|
}
|
|
1973
2071
|
function getNestedValue(obj, path) {
|
|
1974
2072
|
return path.split(".").reduce((current, key) => {
|
|
1975
|
-
return _optionalChain([current, 'optionalAccess',
|
|
2073
|
+
return _optionalChain([current, 'optionalAccess', _15 => _15[key]]);
|
|
1976
2074
|
}, obj);
|
|
1977
2075
|
}
|
|
1978
2076
|
function mergeVariables(currentVariables, updates, schema) {
|
|
@@ -2828,7 +2926,7 @@ function evaluateHumanitySignals(body, opts) {
|
|
|
2828
2926
|
if (elapsedMs !== null && elapsedMs < opts.minFillMs) return { ok: false, reason: "too_fast" };
|
|
2829
2927
|
return { ok: true };
|
|
2830
2928
|
}
|
|
2831
|
-
var splitCsvEnv = (s) => _nullishCoalesce(_optionalChain([s, 'optionalAccess',
|
|
2929
|
+
var splitCsvEnv = (s) => _nullishCoalesce(_optionalChain([s, 'optionalAccess', _16 => _16.split, 'call', _17 => _17(","), 'access', _18 => _18.map, 'call', _19 => _19((t) => t.trim()), 'access', _20 => _20.filter, 'call', _21 => _21(Boolean)]), () => ( []));
|
|
2832
2930
|
|
|
2833
2931
|
// src/hooks/use-humanity-signals.ts
|
|
2834
2932
|
function useHumanitySignals() {
|
|
@@ -2836,7 +2934,7 @@ function useHumanitySignals() {
|
|
|
2836
2934
|
const mountedAt = _react.useRef.call(void 0, typeof performance !== "undefined" ? performance.now() : 0);
|
|
2837
2935
|
const getSignals = _react.useCallback.call(void 0,
|
|
2838
2936
|
() => ({
|
|
2839
|
-
[HONEYPOT_FIELD]: _nullishCoalesce(_optionalChain([ref, 'access',
|
|
2937
|
+
[HONEYPOT_FIELD]: _nullishCoalesce(_optionalChain([ref, 'access', _22 => _22.current, 'optionalAccess', _23 => _23.value]), () => ( "")),
|
|
2840
2938
|
[ELAPSED_MS_FIELD]: typeof performance !== "undefined" ? Math.round(performance.now() - mountedAt.current) : 0
|
|
2841
2939
|
}),
|
|
2842
2940
|
[]
|
|
@@ -2938,5 +3036,7 @@ function useHumanitySignals() {
|
|
|
2938
3036
|
|
|
2939
3037
|
|
|
2940
3038
|
|
|
2941
|
-
|
|
2942
|
-
|
|
3039
|
+
|
|
3040
|
+
|
|
3041
|
+
exports.useHeaderHeight = useHeaderHeight; exports.useHorizontalScrollbar = useHorizontalScrollbar; exports.useImageEdgeColor = useImageEdgeColor; exports.useLocalStorage = useLocalStorage; exports.useMediaQuery = useMediaQuery; exports.breakpoints = breakpoints; exports.useSmUp = useSmUp; exports.useMdUp = useMdUp; exports.useLgUp = useLgUp; exports.useMemoizedCallback = useMemoizedCallback; exports.useNotificationPermission = useNotificationPermission; exports.useOnboardingState = useOnboardingState; exports.useSearch = useSearch; exports.useTablePagination = useTablePagination; exports.useThrottle = useThrottle; exports.useWindowSize = useWindowSize; exports.platformIcons = platformIcons; exports.platformColors = platformColors; exports.platformDisplayNames = platformDisplayNames; exports.platformDescriptions = platformDescriptions; exports.platformSlogans = platformSlogans; exports.platformHexColors = platformHexColors; exports.platformIconNames = platformIconNames; exports.getDefaultColorForPlatform = getDefaultColorForPlatform; exports.getDefaultIconForPlatform = getDefaultIconForPlatform; exports.transformPlatformConfigsToOptions = transformPlatformConfigsToOptions; exports.getPlatformIcon = getPlatformIcon; exports.getPlatformColor = getPlatformColor; exports.getPlatformDisplayName = getPlatformDisplayName; exports.getPlatformDescription = getPlatformDescription; exports.getPlatformSlogan = getPlatformSlogan; exports.getSmallPlatformIcon = getSmallPlatformIcon; exports.getPlatformIconComponent = getPlatformIconComponent; exports.usePlatformConfig = usePlatformConfig; exports.usePlatformByValue = usePlatformByValue; exports.useValidatePlatform = useValidatePlatform; exports.ToolTypeValues = ToolTypeValues; exports.toolLabels = toolLabels; exports.ToolIcon = ToolIcon; exports.dotColorByVariant = dotColorByVariant; exports.progressColorByVariant = progressColorByVariant; exports.ToastCard = ToastCard; exports.CommandApprovalToast = CommandApprovalToast; exports.Toaster = Toaster; exports.showToast = showToast; exports.showCommandApprovalToast = showCommandApprovalToast; exports.toast = toast; exports.useToast = useToast; exports.useContactSubmission = useContactSubmission; exports.useQuickActionHint = useQuickActionHint; exports.useCopyToClipboard = useCopyToClipboard; exports.configureBatchImageFetch = configureBatchImageFetch; exports.batchFetchAuthenticatedImages = batchFetchAuthenticatedImages; exports.useBatchImages = useBatchImages; exports.configureAuthenticatedImage = configureAuthenticatedImage; exports.useAuthenticatedImage = useAuthenticatedImage; exports.extractVariablesFromQuery = extractVariablesFromQuery; exports.isScalarType = isScalarType; exports.isInputObjectType = isInputObjectType; exports.flattenQueryVariables = flattenQueryVariables; exports.mergeDefaults = mergeDefaults; exports.validateSchema = validateSchema; exports.getArrayParams = getArrayParams; exports.getRequiredParams = getRequiredParams; exports.shouldIncludeInUrl = shouldIncludeInUrl; exports.urlParamsToVariables = urlParamsToVariables; exports.variablesToUrlParams = variablesToUrlParams; exports.coerceValue = coerceValue; exports.setNestedValue = setNestedValue; exports.getNestedValue = getNestedValue; exports.mergeVariables = mergeVariables; exports.clearParams = clearParams; exports.validateVariables = validateVariables; exports.GraphQLIntrospector = GraphQLIntrospector; exports.introspector = introspector; exports.useQueryParams = useQueryParams; exports.useApiParams = useApiParams; exports.createSearchParams = createSearchParams; exports.useCursorPaginationState = useCursorPaginationState; exports.useNatsClient = useNatsClient; exports.validateAccessCode = validateAccessCode; exports.consumeAccessCode = consumeAccessCode; exports.validateAndConsumeAccessCode = validateAndConsumeAccessCode; exports.useAccessCodeIntegration = useAccessCodeIntegration; exports.HONEYPOT_FIELD = HONEYPOT_FIELD; exports.ELAPSED_MS_FIELD = ELAPSED_MS_FIELD; exports.DEFAULT_MIN_FILL_MS = DEFAULT_MIN_FILL_MS; exports.extractHumanitySignals = extractHumanitySignals; exports.evaluateHumanitySignals = evaluateHumanitySignals; exports.splitCsvEnv = splitCsvEnv; exports.useHumanitySignals = useHumanitySignals;
|
|
3042
|
+
//# sourceMappingURL=chunk-QLWBBCI5.cjs.map
|