@fictjs/hooks 0.1.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.
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/index.cjs +2548 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +744 -0
- package/dist/index.d.ts +744 -0
- package/dist/index.js +2483 -0
- package/dist/index.js.map +1 -0
- package/package.json +88 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2548 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
useAsyncState: () => useAsyncState,
|
|
24
|
+
useClickOutside: () => useClickOutside,
|
|
25
|
+
useClipboard: () => useClipboard,
|
|
26
|
+
useCounter: () => useCounter,
|
|
27
|
+
useDebounceFn: () => useDebounceFn,
|
|
28
|
+
useDocumentVisibility: () => useDocumentVisibility,
|
|
29
|
+
useEventListener: () => useEventListener,
|
|
30
|
+
useFetch: () => useFetch,
|
|
31
|
+
useFocusWithin: () => useFocusWithin,
|
|
32
|
+
useFullscreen: () => useFullscreen,
|
|
33
|
+
useGeolocation: () => useGeolocation,
|
|
34
|
+
useHover: () => useHover,
|
|
35
|
+
useIdle: () => useIdle,
|
|
36
|
+
useIntersectionObserver: () => useIntersectionObserver,
|
|
37
|
+
useIntervalFn: () => useIntervalFn,
|
|
38
|
+
useKeyPress: () => useKeyPress,
|
|
39
|
+
useLocalStorage: () => useLocalStorage,
|
|
40
|
+
useMediaQuery: () => useMediaQuery,
|
|
41
|
+
useMount: () => useMount,
|
|
42
|
+
useMutationObserver: () => useMutationObserver,
|
|
43
|
+
useNetwork: () => useNetwork,
|
|
44
|
+
usePermission: () => usePermission,
|
|
45
|
+
usePrevious: () => usePrevious,
|
|
46
|
+
useRafFn: () => useRafFn,
|
|
47
|
+
useRequest: () => useRequest,
|
|
48
|
+
useResizeObserver: () => useResizeObserver,
|
|
49
|
+
useScroll: () => useScroll,
|
|
50
|
+
useSessionStorage: () => useSessionStorage,
|
|
51
|
+
useSize: () => useSize,
|
|
52
|
+
useStorage: () => useStorage,
|
|
53
|
+
useThrottleFn: () => useThrottleFn,
|
|
54
|
+
useTimeoutFn: () => useTimeoutFn,
|
|
55
|
+
useTitle: () => useTitle,
|
|
56
|
+
useToggle: () => useToggle,
|
|
57
|
+
useUnmount: () => useUnmount,
|
|
58
|
+
useVirtualList: () => useVirtualList,
|
|
59
|
+
useWebSocket: () => useWebSocket,
|
|
60
|
+
useWindowScroll: () => useWindowScroll,
|
|
61
|
+
useWindowSize: () => useWindowSize
|
|
62
|
+
});
|
|
63
|
+
module.exports = __toCommonJS(index_exports);
|
|
64
|
+
|
|
65
|
+
// src/lifecycle/useMount.ts
|
|
66
|
+
var import_runtime = require("@fictjs/runtime");
|
|
67
|
+
function useMount(callback) {
|
|
68
|
+
(0, import_runtime.onMount)(callback);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// src/lifecycle/useUnmount.ts
|
|
72
|
+
var import_runtime2 = require("@fictjs/runtime");
|
|
73
|
+
function useUnmount(callback) {
|
|
74
|
+
(0, import_runtime2.onDestroy)(callback);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/async/useAsyncState.ts
|
|
78
|
+
var import_advanced = require("@fictjs/runtime/advanced");
|
|
79
|
+
function useAsyncState(executor, initialState, options = {}) {
|
|
80
|
+
const state = (0, import_advanced.createSignal)(initialState);
|
|
81
|
+
const isLoading = (0, import_advanced.createSignal)(false);
|
|
82
|
+
const error = (0, import_advanced.createSignal)(null);
|
|
83
|
+
let callId = 0;
|
|
84
|
+
const execute = async (...args) => {
|
|
85
|
+
const id = ++callId;
|
|
86
|
+
if (options.resetOnExecute) {
|
|
87
|
+
state(initialState);
|
|
88
|
+
}
|
|
89
|
+
isLoading(true);
|
|
90
|
+
error(null);
|
|
91
|
+
try {
|
|
92
|
+
const result = await executor(...args);
|
|
93
|
+
if (id === callId) {
|
|
94
|
+
state(result);
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
} catch (err) {
|
|
98
|
+
if (id === callId) {
|
|
99
|
+
error(err);
|
|
100
|
+
}
|
|
101
|
+
options.onError?.(err);
|
|
102
|
+
throw err;
|
|
103
|
+
} finally {
|
|
104
|
+
if (id === callId) {
|
|
105
|
+
isLoading(false);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
if (options.immediate) {
|
|
110
|
+
void execute(...[]).catch(() => {
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
state,
|
|
115
|
+
isLoading,
|
|
116
|
+
error,
|
|
117
|
+
execute
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/async/useFetch.ts
|
|
122
|
+
var import_advanced2 = require("@fictjs/runtime/advanced");
|
|
123
|
+
|
|
124
|
+
// src/internal/value.ts
|
|
125
|
+
function toValue(value) {
|
|
126
|
+
return typeof value === "function" ? value() : value;
|
|
127
|
+
}
|
|
128
|
+
function toArray(value) {
|
|
129
|
+
return Array.isArray(value) ? value : [value];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/async/useFetch.ts
|
|
133
|
+
async function defaultParse(response) {
|
|
134
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
135
|
+
if (contentType.includes("application/json")) {
|
|
136
|
+
return await response.json();
|
|
137
|
+
}
|
|
138
|
+
return await response.text();
|
|
139
|
+
}
|
|
140
|
+
function useFetch(input, options = {}) {
|
|
141
|
+
const data = (0, import_advanced2.createSignal)(options.initialData ?? null);
|
|
142
|
+
const error = (0, import_advanced2.createSignal)(null);
|
|
143
|
+
const isLoading = (0, import_advanced2.createSignal)(false);
|
|
144
|
+
const status = (0, import_advanced2.createSignal)(null);
|
|
145
|
+
const aborted = (0, import_advanced2.createSignal)(false);
|
|
146
|
+
const fetcher = options.fetch ?? fetch;
|
|
147
|
+
const parse = options.parse ?? defaultParse;
|
|
148
|
+
let requestId = 0;
|
|
149
|
+
let controller;
|
|
150
|
+
const abort = () => {
|
|
151
|
+
if (controller) {
|
|
152
|
+
controller.abort();
|
|
153
|
+
controller = void 0;
|
|
154
|
+
aborted(true);
|
|
155
|
+
isLoading(false);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
const execute = async (init) => {
|
|
159
|
+
const id = ++requestId;
|
|
160
|
+
abort();
|
|
161
|
+
error(null);
|
|
162
|
+
isLoading(true);
|
|
163
|
+
aborted(false);
|
|
164
|
+
controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
165
|
+
try {
|
|
166
|
+
const response = await fetcher(toValue(input), {
|
|
167
|
+
...options.init,
|
|
168
|
+
...init,
|
|
169
|
+
signal: controller?.signal
|
|
170
|
+
});
|
|
171
|
+
if (id !== requestId) {
|
|
172
|
+
return data();
|
|
173
|
+
}
|
|
174
|
+
status(response.status);
|
|
175
|
+
if (!response.ok) {
|
|
176
|
+
throw new Error(`Fetch failed with status ${response.status}`);
|
|
177
|
+
}
|
|
178
|
+
const parsed = await parse(response);
|
|
179
|
+
data(parsed);
|
|
180
|
+
return parsed;
|
|
181
|
+
} catch (err) {
|
|
182
|
+
if (id !== requestId) {
|
|
183
|
+
return data();
|
|
184
|
+
}
|
|
185
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
186
|
+
aborted(true);
|
|
187
|
+
return data();
|
|
188
|
+
}
|
|
189
|
+
error(err);
|
|
190
|
+
options.onError?.(err);
|
|
191
|
+
return data();
|
|
192
|
+
} finally {
|
|
193
|
+
if (id === requestId) {
|
|
194
|
+
isLoading(false);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
if (options.immediate ?? true) {
|
|
199
|
+
void execute();
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
data,
|
|
203
|
+
error,
|
|
204
|
+
isLoading,
|
|
205
|
+
status,
|
|
206
|
+
aborted,
|
|
207
|
+
execute,
|
|
208
|
+
abort
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/async/useRequest.ts
|
|
213
|
+
var import_runtime3 = require("@fictjs/runtime");
|
|
214
|
+
var import_advanced3 = require("@fictjs/runtime/advanced");
|
|
215
|
+
var requestCache = /* @__PURE__ */ new Map();
|
|
216
|
+
function delay(ms) {
|
|
217
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
218
|
+
}
|
|
219
|
+
function useRequest(service, options = {}) {
|
|
220
|
+
const data = (0, import_advanced3.createSignal)(void 0);
|
|
221
|
+
const error = (0, import_advanced3.createSignal)(null);
|
|
222
|
+
const loading = (0, import_advanced3.createSignal)(false);
|
|
223
|
+
const params = (0, import_advanced3.createSignal)(options.defaultParams);
|
|
224
|
+
let callId = 0;
|
|
225
|
+
let pollingTimer;
|
|
226
|
+
const applyCache = () => {
|
|
227
|
+
if (!options.cacheKey) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const entry = requestCache.get(options.cacheKey);
|
|
231
|
+
if (!entry) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const staleTime = options.staleTime ?? 0;
|
|
235
|
+
if (staleTime > 0 && Date.now() - entry.timestamp > staleTime) {
|
|
236
|
+
requestCache.delete(options.cacheKey);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
data(entry.data);
|
|
240
|
+
};
|
|
241
|
+
const saveCache = (value) => {
|
|
242
|
+
if (!options.cacheKey) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
requestCache.set(options.cacheKey, {
|
|
246
|
+
data: value,
|
|
247
|
+
timestamp: Date.now()
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
const stopPolling = () => {
|
|
251
|
+
if (pollingTimer) {
|
|
252
|
+
clearTimeout(pollingTimer);
|
|
253
|
+
pollingTimer = void 0;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
const schedulePolling = (currentParams) => {
|
|
257
|
+
stopPolling();
|
|
258
|
+
if (!options.pollingInterval || options.pollingInterval <= 0) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
pollingTimer = setTimeout(() => {
|
|
262
|
+
void runAsync(...currentParams);
|
|
263
|
+
}, options.pollingInterval);
|
|
264
|
+
};
|
|
265
|
+
const runWithRetry = async (currentParams, currentId) => {
|
|
266
|
+
const retryCount = options.retryCount ?? 0;
|
|
267
|
+
const retryInterval = options.retryInterval ?? 1e3;
|
|
268
|
+
let attempt = 0;
|
|
269
|
+
while (true) {
|
|
270
|
+
try {
|
|
271
|
+
return await service(...currentParams);
|
|
272
|
+
} catch (err) {
|
|
273
|
+
if (currentId !== callId) {
|
|
274
|
+
throw err;
|
|
275
|
+
}
|
|
276
|
+
if (attempt >= retryCount) {
|
|
277
|
+
throw err;
|
|
278
|
+
}
|
|
279
|
+
attempt += 1;
|
|
280
|
+
await delay(retryInterval);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
const runAsync = async (...currentParams) => {
|
|
285
|
+
const id = ++callId;
|
|
286
|
+
stopPolling();
|
|
287
|
+
loading(true);
|
|
288
|
+
error(null);
|
|
289
|
+
params(currentParams);
|
|
290
|
+
try {
|
|
291
|
+
const result = await runWithRetry(currentParams, id);
|
|
292
|
+
if (id !== callId) {
|
|
293
|
+
return data();
|
|
294
|
+
}
|
|
295
|
+
data(result);
|
|
296
|
+
saveCache(result);
|
|
297
|
+
options.onSuccess?.(result, currentParams);
|
|
298
|
+
schedulePolling(currentParams);
|
|
299
|
+
return result;
|
|
300
|
+
} catch (err) {
|
|
301
|
+
if (id !== callId) {
|
|
302
|
+
return data();
|
|
303
|
+
}
|
|
304
|
+
error(err);
|
|
305
|
+
options.onError?.(err, currentParams);
|
|
306
|
+
schedulePolling(currentParams);
|
|
307
|
+
return data();
|
|
308
|
+
} finally {
|
|
309
|
+
if (id === callId) {
|
|
310
|
+
loading(false);
|
|
311
|
+
}
|
|
312
|
+
options.onFinally?.(currentParams, data(), error());
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
const run = (...currentParams) => {
|
|
316
|
+
void runAsync(...currentParams);
|
|
317
|
+
};
|
|
318
|
+
const cancel = () => {
|
|
319
|
+
callId += 1;
|
|
320
|
+
loading(false);
|
|
321
|
+
stopPolling();
|
|
322
|
+
};
|
|
323
|
+
const refresh = async () => {
|
|
324
|
+
const currentParams = params() ?? options.defaultParams;
|
|
325
|
+
if (!currentParams) {
|
|
326
|
+
return data();
|
|
327
|
+
}
|
|
328
|
+
return runAsync(...currentParams);
|
|
329
|
+
};
|
|
330
|
+
const mutate = (value) => {
|
|
331
|
+
const next = typeof value === "function" ? value(data()) : value;
|
|
332
|
+
data(next);
|
|
333
|
+
saveCache(next);
|
|
334
|
+
};
|
|
335
|
+
applyCache();
|
|
336
|
+
if (!options.manual && options.defaultParams) {
|
|
337
|
+
void runAsync(...options.defaultParams);
|
|
338
|
+
}
|
|
339
|
+
(0, import_runtime3.onDestroy)(cancel);
|
|
340
|
+
return {
|
|
341
|
+
data,
|
|
342
|
+
error,
|
|
343
|
+
loading,
|
|
344
|
+
params,
|
|
345
|
+
run,
|
|
346
|
+
runAsync,
|
|
347
|
+
cancel,
|
|
348
|
+
refresh,
|
|
349
|
+
mutate
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// src/clipboard/useClipboard.ts
|
|
354
|
+
var import_runtime4 = require("@fictjs/runtime");
|
|
355
|
+
var import_advanced4 = require("@fictjs/runtime/advanced");
|
|
356
|
+
|
|
357
|
+
// src/internal/env.ts
|
|
358
|
+
var isClient = typeof window !== "undefined" && typeof document !== "undefined";
|
|
359
|
+
var defaultWindow = isClient ? window : void 0;
|
|
360
|
+
var defaultDocument = isClient ? document : void 0;
|
|
361
|
+
var defaultNavigator = typeof navigator !== "undefined" ? navigator : void 0;
|
|
362
|
+
|
|
363
|
+
// src/clipboard/useClipboard.ts
|
|
364
|
+
function fallbackCopy(value, documentRef) {
|
|
365
|
+
const textarea = documentRef.createElement("textarea");
|
|
366
|
+
textarea.value = value;
|
|
367
|
+
textarea.setAttribute("readonly", "true");
|
|
368
|
+
textarea.style.position = "absolute";
|
|
369
|
+
textarea.style.left = "-9999px";
|
|
370
|
+
documentRef.body.appendChild(textarea);
|
|
371
|
+
textarea.select();
|
|
372
|
+
let ok = false;
|
|
373
|
+
try {
|
|
374
|
+
ok = documentRef.execCommand("copy");
|
|
375
|
+
} catch {
|
|
376
|
+
ok = false;
|
|
377
|
+
}
|
|
378
|
+
documentRef.body.removeChild(textarea);
|
|
379
|
+
return ok;
|
|
380
|
+
}
|
|
381
|
+
function useClipboard(options = {}) {
|
|
382
|
+
const navigatorRef = options.navigator === void 0 ? defaultNavigator : options.navigator;
|
|
383
|
+
const documentRef = options.document === void 0 ? defaultDocument : options.document;
|
|
384
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
385
|
+
const text = (0, import_advanced4.createSignal)("");
|
|
386
|
+
const copied = (0, import_advanced4.createSignal)(false);
|
|
387
|
+
const isSupported = (0, import_advanced4.createSignal)(
|
|
388
|
+
!!navigatorRef?.clipboard?.writeText || !!documentRef?.execCommand
|
|
389
|
+
);
|
|
390
|
+
const copiedDuring = options.copiedDuring ?? 1500;
|
|
391
|
+
let timer;
|
|
392
|
+
const resetCopiedLater = () => {
|
|
393
|
+
if (!windowRef) {
|
|
394
|
+
copied(false);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (timer) {
|
|
398
|
+
clearTimeout(timer);
|
|
399
|
+
}
|
|
400
|
+
timer = windowRef.setTimeout(() => {
|
|
401
|
+
copied(false);
|
|
402
|
+
timer = void 0;
|
|
403
|
+
}, copiedDuring);
|
|
404
|
+
};
|
|
405
|
+
const copy = async (value) => {
|
|
406
|
+
text(value);
|
|
407
|
+
if (navigatorRef?.clipboard?.writeText) {
|
|
408
|
+
try {
|
|
409
|
+
await navigatorRef.clipboard.writeText(value);
|
|
410
|
+
copied(true);
|
|
411
|
+
resetCopiedLater();
|
|
412
|
+
return true;
|
|
413
|
+
} catch {
|
|
414
|
+
copied(false);
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (documentRef) {
|
|
419
|
+
const ok = fallbackCopy(value, documentRef);
|
|
420
|
+
copied(ok);
|
|
421
|
+
if (ok) {
|
|
422
|
+
resetCopiedLater();
|
|
423
|
+
}
|
|
424
|
+
return ok;
|
|
425
|
+
}
|
|
426
|
+
copied(false);
|
|
427
|
+
return false;
|
|
428
|
+
};
|
|
429
|
+
(0, import_runtime4.onDestroy)(() => {
|
|
430
|
+
if (timer) {
|
|
431
|
+
clearTimeout(timer);
|
|
432
|
+
timer = void 0;
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
return {
|
|
436
|
+
text,
|
|
437
|
+
copied,
|
|
438
|
+
isSupported,
|
|
439
|
+
copy
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// src/event/useEventListener.ts
|
|
444
|
+
var import_runtime5 = require("@fictjs/runtime");
|
|
445
|
+
var import_advanced5 = require("@fictjs/runtime/advanced");
|
|
446
|
+
|
|
447
|
+
// src/internal/target.ts
|
|
448
|
+
function resolveTarget(target) {
|
|
449
|
+
if (target == null) {
|
|
450
|
+
return void 0;
|
|
451
|
+
}
|
|
452
|
+
if (typeof target === "function") {
|
|
453
|
+
return target() ?? void 0;
|
|
454
|
+
}
|
|
455
|
+
if (typeof target === "object" && "current" in target) {
|
|
456
|
+
return target.current ?? void 0;
|
|
457
|
+
}
|
|
458
|
+
return target;
|
|
459
|
+
}
|
|
460
|
+
function resolveMaybeTarget(target) {
|
|
461
|
+
const resolved = toValue(target);
|
|
462
|
+
return resolveTarget(resolved);
|
|
463
|
+
}
|
|
464
|
+
function resolveTargetList(target) {
|
|
465
|
+
return toArray(target).map((item) => resolveMaybeTarget(item)).filter((item) => item != null);
|
|
466
|
+
}
|
|
467
|
+
function resolveIgnoreElement(ignore, doc) {
|
|
468
|
+
if (typeof ignore === "string") {
|
|
469
|
+
return Array.from(doc.querySelectorAll(ignore));
|
|
470
|
+
}
|
|
471
|
+
return resolveMaybeTarget(ignore);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// src/internal/event.ts
|
|
475
|
+
function addEventListeners(targets, events, listener, options) {
|
|
476
|
+
const resolvedTargets = resolveTargetList(targets);
|
|
477
|
+
const names = toArray(events);
|
|
478
|
+
for (const target of resolvedTargets) {
|
|
479
|
+
for (const name of names) {
|
|
480
|
+
target.addEventListener(name, listener, options);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
let active = true;
|
|
484
|
+
return {
|
|
485
|
+
stop() {
|
|
486
|
+
if (!active) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
active = false;
|
|
490
|
+
for (const target of resolvedTargets) {
|
|
491
|
+
for (const name of names) {
|
|
492
|
+
target.removeEventListener(name, listener, options);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// src/event/useEventListener.ts
|
|
500
|
+
function useEventListener(target, event, handler, options = {}) {
|
|
501
|
+
const active = (0, import_advanced5.createSignal)(options.immediate ?? true);
|
|
502
|
+
let stopCurrent = () => {
|
|
503
|
+
};
|
|
504
|
+
const bind = () => {
|
|
505
|
+
const targets = resolveTargetList(target);
|
|
506
|
+
const eventNames = toArray(toValue(event));
|
|
507
|
+
if (targets.length === 0 || eventNames.length === 0) {
|
|
508
|
+
return void 0;
|
|
509
|
+
}
|
|
510
|
+
const listener = (eventObject) => {
|
|
511
|
+
handler(eventObject);
|
|
512
|
+
};
|
|
513
|
+
const listenerOptions = {
|
|
514
|
+
capture: options.capture,
|
|
515
|
+
once: options.once,
|
|
516
|
+
passive: options.passive
|
|
517
|
+
};
|
|
518
|
+
const controller = addEventListeners(targets, eventNames, listener, listenerOptions);
|
|
519
|
+
return () => controller.stop();
|
|
520
|
+
};
|
|
521
|
+
(0, import_runtime5.createEffect)(() => {
|
|
522
|
+
stopCurrent();
|
|
523
|
+
stopCurrent = () => {
|
|
524
|
+
};
|
|
525
|
+
if (!active()) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
const stop = bind();
|
|
529
|
+
if (!stop) {
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
stopCurrent = () => {
|
|
533
|
+
stop();
|
|
534
|
+
stopCurrent = () => {
|
|
535
|
+
};
|
|
536
|
+
};
|
|
537
|
+
(0, import_runtime5.onCleanup)(() => {
|
|
538
|
+
stopCurrent();
|
|
539
|
+
});
|
|
540
|
+
});
|
|
541
|
+
return {
|
|
542
|
+
start() {
|
|
543
|
+
if (!active()) {
|
|
544
|
+
active(true);
|
|
545
|
+
const stop = bind();
|
|
546
|
+
if (stop) {
|
|
547
|
+
stopCurrent = () => {
|
|
548
|
+
stop();
|
|
549
|
+
stopCurrent = () => {
|
|
550
|
+
};
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
stop() {
|
|
556
|
+
if (!active()) {
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
active(false);
|
|
560
|
+
stopCurrent();
|
|
561
|
+
},
|
|
562
|
+
active
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/event/useClickOutside.ts
|
|
567
|
+
function isNodeInside(elements, node) {
|
|
568
|
+
return elements.some((element) => element.contains(node));
|
|
569
|
+
}
|
|
570
|
+
function useClickOutside(target, handler, options = {}) {
|
|
571
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
572
|
+
const documentRef = options.document === void 0 ? defaultDocument : options.document;
|
|
573
|
+
const ignoreTargets = options.ignore ? toArray(options.ignore) : [];
|
|
574
|
+
let pointerDownOutside = false;
|
|
575
|
+
const isOutside = (event) => {
|
|
576
|
+
const node = event.target;
|
|
577
|
+
if (!node || !documentRef) {
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
const targetElements = resolveTargetList(target);
|
|
581
|
+
if (targetElements.length === 0) {
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
const ignoreElements = ignoreTargets.flatMap((item) => {
|
|
585
|
+
const resolved = resolveIgnoreElement(item, documentRef);
|
|
586
|
+
if (!resolved) {
|
|
587
|
+
return [];
|
|
588
|
+
}
|
|
589
|
+
return Array.isArray(resolved) ? resolved : [resolved];
|
|
590
|
+
});
|
|
591
|
+
if (isNodeInside(targetElements, node) || isNodeInside(ignoreElements, node)) {
|
|
592
|
+
return false;
|
|
593
|
+
}
|
|
594
|
+
return true;
|
|
595
|
+
};
|
|
596
|
+
const onPointerDown = (event) => {
|
|
597
|
+
pointerDownOutside = isOutside(event);
|
|
598
|
+
};
|
|
599
|
+
const onClick = (event) => {
|
|
600
|
+
if (pointerDownOutside && isOutside(event)) {
|
|
601
|
+
handler(event);
|
|
602
|
+
}
|
|
603
|
+
pointerDownOutside = false;
|
|
604
|
+
};
|
|
605
|
+
const downControls = useEventListener(windowRef, "pointerdown", onPointerDown, {
|
|
606
|
+
capture: options.capture ?? true,
|
|
607
|
+
passive: true
|
|
608
|
+
});
|
|
609
|
+
const clickControls = useEventListener(windowRef, "click", onClick, {
|
|
610
|
+
capture: options.capture ?? true,
|
|
611
|
+
passive: true
|
|
612
|
+
});
|
|
613
|
+
return {
|
|
614
|
+
start() {
|
|
615
|
+
downControls.start();
|
|
616
|
+
clickControls.start();
|
|
617
|
+
},
|
|
618
|
+
stop() {
|
|
619
|
+
downControls.stop();
|
|
620
|
+
clickControls.stop();
|
|
621
|
+
},
|
|
622
|
+
active() {
|
|
623
|
+
return downControls.active() && clickControls.active();
|
|
624
|
+
},
|
|
625
|
+
trigger(event) {
|
|
626
|
+
handler(event ?? new Event("click"));
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// src/event/useFocusWithin.ts
|
|
632
|
+
var import_runtime6 = require("@fictjs/runtime");
|
|
633
|
+
var import_advanced6 = require("@fictjs/runtime/advanced");
|
|
634
|
+
function useFocusWithin(target, options = {}) {
|
|
635
|
+
const initialValue = options.initialValue ?? false;
|
|
636
|
+
const focused = (0, import_advanced6.createSignal)(initialValue);
|
|
637
|
+
let previousTarget;
|
|
638
|
+
useEventListener(target, "focusin", () => {
|
|
639
|
+
focused(true);
|
|
640
|
+
});
|
|
641
|
+
useEventListener(target, "focusout", (event) => {
|
|
642
|
+
const targetElement = resolveMaybeTarget(target);
|
|
643
|
+
if (!targetElement) {
|
|
644
|
+
focused(false);
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
const relatedTarget = event.relatedTarget;
|
|
648
|
+
if (relatedTarget && targetElement.contains(relatedTarget)) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
focused(false);
|
|
652
|
+
});
|
|
653
|
+
(0, import_runtime6.createEffect)(() => {
|
|
654
|
+
const currentTarget = resolveMaybeTarget(target);
|
|
655
|
+
if (currentTarget !== previousTarget) {
|
|
656
|
+
previousTarget = currentTarget;
|
|
657
|
+
focused(initialValue);
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
return { focused };
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// src/event/useHover.ts
|
|
664
|
+
var import_runtime7 = require("@fictjs/runtime");
|
|
665
|
+
var import_advanced7 = require("@fictjs/runtime/advanced");
|
|
666
|
+
function useHover(target, options = {}) {
|
|
667
|
+
const initialValue = options.initialValue ?? false;
|
|
668
|
+
const hovered = (0, import_advanced7.createSignal)(initialValue);
|
|
669
|
+
let previousTarget;
|
|
670
|
+
useEventListener(target, "pointerenter", () => {
|
|
671
|
+
hovered(true);
|
|
672
|
+
});
|
|
673
|
+
useEventListener(target, "pointerleave", () => {
|
|
674
|
+
hovered(false);
|
|
675
|
+
});
|
|
676
|
+
(0, import_runtime7.createEffect)(() => {
|
|
677
|
+
const currentTarget = resolveMaybeTarget(target);
|
|
678
|
+
if (currentTarget !== previousTarget) {
|
|
679
|
+
previousTarget = currentTarget;
|
|
680
|
+
hovered(initialValue);
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
return { hovered };
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// src/event/useKeyPress.ts
|
|
687
|
+
var modifierAliases = {
|
|
688
|
+
ctrl: "ctrl",
|
|
689
|
+
control: "ctrl",
|
|
690
|
+
alt: "alt",
|
|
691
|
+
option: "alt",
|
|
692
|
+
shift: "shift",
|
|
693
|
+
meta: "meta",
|
|
694
|
+
cmd: "meta",
|
|
695
|
+
command: "meta"
|
|
696
|
+
};
|
|
697
|
+
var keyAliases = {
|
|
698
|
+
esc: "escape",
|
|
699
|
+
return: "enter",
|
|
700
|
+
del: "delete",
|
|
701
|
+
space: " ",
|
|
702
|
+
spacebar: " "
|
|
703
|
+
};
|
|
704
|
+
function normalizeToken(token) {
|
|
705
|
+
return token.trim().toLowerCase();
|
|
706
|
+
}
|
|
707
|
+
function normalizeKey(key) {
|
|
708
|
+
const normalized = normalizeToken(key);
|
|
709
|
+
return keyAliases[normalized] ?? normalized;
|
|
710
|
+
}
|
|
711
|
+
function parseCombo(combo) {
|
|
712
|
+
return combo.split(/[.+]/g).map((part) => normalizeToken(part)).filter(Boolean);
|
|
713
|
+
}
|
|
714
|
+
function isModifierToken(token) {
|
|
715
|
+
return token in modifierAliases;
|
|
716
|
+
}
|
|
717
|
+
function isModifierActive(modifier, event) {
|
|
718
|
+
if (modifier === "ctrl") return event.ctrlKey;
|
|
719
|
+
if (modifier === "alt") return event.altKey;
|
|
720
|
+
if (modifier === "shift") return event.shiftKey;
|
|
721
|
+
return event.metaKey;
|
|
722
|
+
}
|
|
723
|
+
function activeModifierCount(event) {
|
|
724
|
+
return Number(event.ctrlKey) + Number(event.altKey) + Number(event.shiftKey) + Number(event.metaKey);
|
|
725
|
+
}
|
|
726
|
+
function matchesCombo(event, combo, exactMatch) {
|
|
727
|
+
const tokens = parseCombo(combo);
|
|
728
|
+
if (tokens.length === 0) {
|
|
729
|
+
return false;
|
|
730
|
+
}
|
|
731
|
+
const modifiers = tokens.filter(isModifierToken).map((token) => modifierAliases[token]);
|
|
732
|
+
const nonModifiers = tokens.filter((token) => !isModifierToken(token));
|
|
733
|
+
for (const modifier of modifiers) {
|
|
734
|
+
if (!isModifierActive(modifier, event)) {
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
const keyMatched = nonModifiers.length === 0 || nonModifiers.some((token) => normalizeKey(token) === normalizeKey(event.key));
|
|
739
|
+
if (!keyMatched) {
|
|
740
|
+
return false;
|
|
741
|
+
}
|
|
742
|
+
if (!exactMatch) {
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
745
|
+
const expectedModifierCount = new Set(modifiers).size;
|
|
746
|
+
return activeModifierCount(event) === expectedModifierCount;
|
|
747
|
+
}
|
|
748
|
+
function matchesFilter(event, filter, exactMatch) {
|
|
749
|
+
if (typeof filter === "function") {
|
|
750
|
+
return filter(event);
|
|
751
|
+
}
|
|
752
|
+
const combos = toArray(filter);
|
|
753
|
+
return combos.some((combo) => matchesCombo(event, combo, exactMatch));
|
|
754
|
+
}
|
|
755
|
+
function useKeyPress(filter, handler, options = {}) {
|
|
756
|
+
const events = toArray(options.events ?? "keydown");
|
|
757
|
+
const exactMatch = options.exactMatch ?? false;
|
|
758
|
+
const target = options.target === void 0 ? defaultWindow : options.target;
|
|
759
|
+
const passive = options.preventDefault ? false : options.passive;
|
|
760
|
+
return useEventListener(
|
|
761
|
+
target,
|
|
762
|
+
events,
|
|
763
|
+
(event) => {
|
|
764
|
+
const keyboardEvent = event;
|
|
765
|
+
if (!matchesFilter(keyboardEvent, filter, exactMatch)) {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
if (options.preventDefault) {
|
|
769
|
+
keyboardEvent.preventDefault();
|
|
770
|
+
}
|
|
771
|
+
handler(keyboardEvent);
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
passive,
|
|
775
|
+
capture: options.capture,
|
|
776
|
+
immediate: options.immediate
|
|
777
|
+
}
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// src/internal/timing.ts
|
|
782
|
+
var import_runtime8 = require("@fictjs/runtime");
|
|
783
|
+
function createDebouncedFn(fn, wait, options = {}) {
|
|
784
|
+
const leading = options.leading ?? false;
|
|
785
|
+
const trailing = options.trailing ?? true;
|
|
786
|
+
const maxWait = options.maxWait;
|
|
787
|
+
let timer;
|
|
788
|
+
let maxTimer;
|
|
789
|
+
let lastArgs;
|
|
790
|
+
let pending = false;
|
|
791
|
+
const clearTimers = () => {
|
|
792
|
+
if (timer) {
|
|
793
|
+
clearTimeout(timer);
|
|
794
|
+
timer = void 0;
|
|
795
|
+
}
|
|
796
|
+
if (maxTimer) {
|
|
797
|
+
clearTimeout(maxTimer);
|
|
798
|
+
maxTimer = void 0;
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
const invoke = () => {
|
|
802
|
+
if (!lastArgs) {
|
|
803
|
+
pending = false;
|
|
804
|
+
clearTimers();
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
const args = lastArgs;
|
|
808
|
+
lastArgs = void 0;
|
|
809
|
+
pending = false;
|
|
810
|
+
clearTimers();
|
|
811
|
+
fn(...args);
|
|
812
|
+
};
|
|
813
|
+
const scheduleTimers = () => {
|
|
814
|
+
if (timer) {
|
|
815
|
+
clearTimeout(timer);
|
|
816
|
+
}
|
|
817
|
+
timer = setTimeout(() => {
|
|
818
|
+
if (trailing) {
|
|
819
|
+
invoke();
|
|
820
|
+
} else {
|
|
821
|
+
pending = false;
|
|
822
|
+
clearTimers();
|
|
823
|
+
}
|
|
824
|
+
}, wait);
|
|
825
|
+
if (maxWait != null && maxWait >= 0 && !maxTimer) {
|
|
826
|
+
maxTimer = setTimeout(() => {
|
|
827
|
+
invoke();
|
|
828
|
+
}, maxWait);
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
const run = (...args) => {
|
|
832
|
+
const shouldCallLeading = leading && !timer;
|
|
833
|
+
lastArgs = args;
|
|
834
|
+
pending = true;
|
|
835
|
+
if (shouldCallLeading) {
|
|
836
|
+
fn(...args);
|
|
837
|
+
if (!trailing) {
|
|
838
|
+
lastArgs = void 0;
|
|
839
|
+
pending = false;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
scheduleTimers();
|
|
843
|
+
};
|
|
844
|
+
const cancel = () => {
|
|
845
|
+
pending = false;
|
|
846
|
+
lastArgs = void 0;
|
|
847
|
+
clearTimers();
|
|
848
|
+
};
|
|
849
|
+
const flush = () => {
|
|
850
|
+
if (pending) {
|
|
851
|
+
invoke();
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
(0, import_runtime8.onDestroy)(cancel);
|
|
855
|
+
return {
|
|
856
|
+
run,
|
|
857
|
+
cancel,
|
|
858
|
+
flush,
|
|
859
|
+
pending: () => pending
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
function createThrottledFn(fn, wait, options = {}) {
|
|
863
|
+
const leading = options.leading ?? true;
|
|
864
|
+
const trailing = options.trailing ?? true;
|
|
865
|
+
let timer;
|
|
866
|
+
let lastArgs;
|
|
867
|
+
let pending = false;
|
|
868
|
+
const invoke = (args) => {
|
|
869
|
+
fn(...args);
|
|
870
|
+
};
|
|
871
|
+
const tick = () => {
|
|
872
|
+
if (trailing && lastArgs) {
|
|
873
|
+
const args = lastArgs;
|
|
874
|
+
lastArgs = void 0;
|
|
875
|
+
pending = false;
|
|
876
|
+
invoke(args);
|
|
877
|
+
timer = setTimeout(tick, wait);
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
timer = void 0;
|
|
881
|
+
pending = false;
|
|
882
|
+
};
|
|
883
|
+
const run = (...args) => {
|
|
884
|
+
if (!timer) {
|
|
885
|
+
if (leading) {
|
|
886
|
+
invoke(args);
|
|
887
|
+
} else if (trailing) {
|
|
888
|
+
lastArgs = args;
|
|
889
|
+
pending = true;
|
|
890
|
+
}
|
|
891
|
+
timer = setTimeout(tick, wait);
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
if (trailing) {
|
|
895
|
+
lastArgs = args;
|
|
896
|
+
pending = true;
|
|
897
|
+
}
|
|
898
|
+
};
|
|
899
|
+
const cancel = () => {
|
|
900
|
+
if (timer) {
|
|
901
|
+
clearTimeout(timer);
|
|
902
|
+
timer = void 0;
|
|
903
|
+
}
|
|
904
|
+
lastArgs = void 0;
|
|
905
|
+
pending = false;
|
|
906
|
+
};
|
|
907
|
+
const flush = () => {
|
|
908
|
+
if (lastArgs) {
|
|
909
|
+
const args = lastArgs;
|
|
910
|
+
lastArgs = void 0;
|
|
911
|
+
pending = false;
|
|
912
|
+
invoke(args);
|
|
913
|
+
}
|
|
914
|
+
if (timer) {
|
|
915
|
+
clearTimeout(timer);
|
|
916
|
+
timer = void 0;
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
(0, import_runtime8.onDestroy)(cancel);
|
|
920
|
+
return {
|
|
921
|
+
run,
|
|
922
|
+
cancel,
|
|
923
|
+
flush,
|
|
924
|
+
pending: () => pending
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// src/timing/useDebounceFn.ts
|
|
929
|
+
function useDebounceFn(fn, wait, options = {}) {
|
|
930
|
+
return createDebouncedFn(fn, wait, options);
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
// src/timing/useIntervalFn.ts
|
|
934
|
+
var import_runtime9 = require("@fictjs/runtime");
|
|
935
|
+
var import_advanced8 = require("@fictjs/runtime/advanced");
|
|
936
|
+
function useIntervalFn(callback, interval) {
|
|
937
|
+
const pending = (0, import_advanced8.createSignal)(false);
|
|
938
|
+
let timer;
|
|
939
|
+
const cancel = () => {
|
|
940
|
+
if (timer) {
|
|
941
|
+
clearInterval(timer);
|
|
942
|
+
timer = void 0;
|
|
943
|
+
}
|
|
944
|
+
pending(false);
|
|
945
|
+
};
|
|
946
|
+
const run = () => {
|
|
947
|
+
cancel();
|
|
948
|
+
const wait = Math.max(0, toValue(interval));
|
|
949
|
+
pending(true);
|
|
950
|
+
timer = setInterval(() => {
|
|
951
|
+
callback();
|
|
952
|
+
}, wait);
|
|
953
|
+
};
|
|
954
|
+
const flush = () => {
|
|
955
|
+
callback();
|
|
956
|
+
};
|
|
957
|
+
(0, import_runtime9.onDestroy)(cancel);
|
|
958
|
+
run();
|
|
959
|
+
return {
|
|
960
|
+
run,
|
|
961
|
+
cancel,
|
|
962
|
+
flush,
|
|
963
|
+
pending
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// src/timing/useRafFn.ts
|
|
968
|
+
var import_runtime10 = require("@fictjs/runtime");
|
|
969
|
+
var import_advanced9 = require("@fictjs/runtime/advanced");
|
|
970
|
+
function useRafFn(callback, options = {}) {
|
|
971
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
972
|
+
const active = (0, import_advanced9.createSignal)(options.immediate ?? true);
|
|
973
|
+
let rafId = 0;
|
|
974
|
+
let lastTimestamp;
|
|
975
|
+
const loop = (timestamp) => {
|
|
976
|
+
if (!active()) {
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
const delta = lastTimestamp == null ? 0 : timestamp - lastTimestamp;
|
|
980
|
+
lastTimestamp = timestamp;
|
|
981
|
+
callback(delta, timestamp);
|
|
982
|
+
if (windowRef?.requestAnimationFrame) {
|
|
983
|
+
rafId = windowRef.requestAnimationFrame(loop);
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
const start = () => {
|
|
987
|
+
if (active()) {
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
active(true);
|
|
991
|
+
if (windowRef?.requestAnimationFrame) {
|
|
992
|
+
rafId = windowRef.requestAnimationFrame(loop);
|
|
993
|
+
}
|
|
994
|
+
};
|
|
995
|
+
const stop = () => {
|
|
996
|
+
active(false);
|
|
997
|
+
lastTimestamp = void 0;
|
|
998
|
+
if (rafId && windowRef?.cancelAnimationFrame) {
|
|
999
|
+
windowRef.cancelAnimationFrame(rafId);
|
|
1000
|
+
rafId = 0;
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
if (active() && windowRef?.requestAnimationFrame) {
|
|
1004
|
+
rafId = windowRef.requestAnimationFrame(loop);
|
|
1005
|
+
}
|
|
1006
|
+
(0, import_runtime10.onDestroy)(stop);
|
|
1007
|
+
return {
|
|
1008
|
+
active,
|
|
1009
|
+
start,
|
|
1010
|
+
stop
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
// src/timing/useThrottleFn.ts
|
|
1015
|
+
function useThrottleFn(fn, wait, options = {}) {
|
|
1016
|
+
return createThrottledFn(fn, wait, options);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// src/timing/useTimeoutFn.ts
|
|
1020
|
+
var import_advanced10 = require("@fictjs/runtime/advanced");
|
|
1021
|
+
var import_runtime11 = require("@fictjs/runtime");
|
|
1022
|
+
function useTimeoutFn(callback, delay2) {
|
|
1023
|
+
const pending = (0, import_advanced10.createSignal)(false);
|
|
1024
|
+
let timer;
|
|
1025
|
+
const cancel = () => {
|
|
1026
|
+
if (timer) {
|
|
1027
|
+
clearTimeout(timer);
|
|
1028
|
+
timer = void 0;
|
|
1029
|
+
}
|
|
1030
|
+
pending(false);
|
|
1031
|
+
};
|
|
1032
|
+
const run = () => {
|
|
1033
|
+
cancel();
|
|
1034
|
+
const wait = Math.max(0, toValue(delay2));
|
|
1035
|
+
pending(true);
|
|
1036
|
+
timer = setTimeout(() => {
|
|
1037
|
+
timer = void 0;
|
|
1038
|
+
pending(false);
|
|
1039
|
+
callback();
|
|
1040
|
+
}, wait);
|
|
1041
|
+
};
|
|
1042
|
+
const flush = () => {
|
|
1043
|
+
if (!pending()) {
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
cancel();
|
|
1047
|
+
callback();
|
|
1048
|
+
};
|
|
1049
|
+
(0, import_runtime11.onDestroy)(cancel);
|
|
1050
|
+
run();
|
|
1051
|
+
return {
|
|
1052
|
+
run,
|
|
1053
|
+
cancel,
|
|
1054
|
+
flush,
|
|
1055
|
+
pending
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// src/internal/storage.ts
|
|
1060
|
+
var import_advanced11 = require("@fictjs/runtime/advanced");
|
|
1061
|
+
var import_runtime12 = require("@fictjs/runtime");
|
|
1062
|
+
var syncEvent = "fict-storage-sync";
|
|
1063
|
+
var jsonSerializer = {
|
|
1064
|
+
read: (raw) => JSON.parse(raw),
|
|
1065
|
+
write: (value) => JSON.stringify(value)
|
|
1066
|
+
};
|
|
1067
|
+
function inferSerializer(initial) {
|
|
1068
|
+
const kind = typeof initial;
|
|
1069
|
+
if (kind === "string") {
|
|
1070
|
+
return {
|
|
1071
|
+
read: (raw) => raw,
|
|
1072
|
+
write: (value) => String(value)
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
if (kind === "number") {
|
|
1076
|
+
return {
|
|
1077
|
+
read: (raw) => Number(raw),
|
|
1078
|
+
write: (value) => String(value)
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
if (kind === "boolean") {
|
|
1082
|
+
return {
|
|
1083
|
+
read: (raw) => raw === "true",
|
|
1084
|
+
write: (value) => String(value)
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
if (initial instanceof Date) {
|
|
1088
|
+
return {
|
|
1089
|
+
read: (raw) => new Date(raw),
|
|
1090
|
+
write: (value) => value.toISOString()
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
if (initial instanceof Map) {
|
|
1094
|
+
return {
|
|
1095
|
+
read: (raw) => new Map(JSON.parse(raw)),
|
|
1096
|
+
write: (value) => JSON.stringify(Array.from(value.entries()))
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
if (initial instanceof Set) {
|
|
1100
|
+
return {
|
|
1101
|
+
read: (raw) => new Set(JSON.parse(raw)),
|
|
1102
|
+
write: (value) => JSON.stringify(Array.from(value.values()))
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
return jsonSerializer;
|
|
1106
|
+
}
|
|
1107
|
+
function safeCall(onError, error) {
|
|
1108
|
+
if (!onError) {
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
onError(error);
|
|
1112
|
+
}
|
|
1113
|
+
function resolveNextValue(next, prev) {
|
|
1114
|
+
if (typeof next === "function") {
|
|
1115
|
+
return next(prev);
|
|
1116
|
+
}
|
|
1117
|
+
return next;
|
|
1118
|
+
}
|
|
1119
|
+
function createStorageHook(storage, key, initial, options = {}) {
|
|
1120
|
+
const windowRef = options.window ?? defaultWindow;
|
|
1121
|
+
const serializer = options.serializer ?? inferSerializer(initial);
|
|
1122
|
+
const emitSync = windowRef != null;
|
|
1123
|
+
const readStorage = () => {
|
|
1124
|
+
if (!storage) {
|
|
1125
|
+
return initial;
|
|
1126
|
+
}
|
|
1127
|
+
try {
|
|
1128
|
+
const raw = storage.getItem(key);
|
|
1129
|
+
if (raw == null) {
|
|
1130
|
+
if (options.writeDefaults ?? true) {
|
|
1131
|
+
storage.setItem(key, serializer.write(initial));
|
|
1132
|
+
}
|
|
1133
|
+
return initial;
|
|
1134
|
+
}
|
|
1135
|
+
return serializer.read(raw);
|
|
1136
|
+
} catch (error) {
|
|
1137
|
+
safeCall(options.onError, error);
|
|
1138
|
+
return initial;
|
|
1139
|
+
}
|
|
1140
|
+
};
|
|
1141
|
+
const state = (0, import_advanced11.createSignal)(readStorage());
|
|
1142
|
+
let paused = false;
|
|
1143
|
+
const writeState = (next) => {
|
|
1144
|
+
state(next);
|
|
1145
|
+
};
|
|
1146
|
+
const set = (next) => {
|
|
1147
|
+
const prev = state();
|
|
1148
|
+
const value = resolveNextValue(next, prev);
|
|
1149
|
+
if (!storage) {
|
|
1150
|
+
writeState(value);
|
|
1151
|
+
return;
|
|
1152
|
+
}
|
|
1153
|
+
try {
|
|
1154
|
+
const serialized = serializer.write(value);
|
|
1155
|
+
const current = storage.getItem(key);
|
|
1156
|
+
if (current === serialized) {
|
|
1157
|
+
writeState(value);
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
paused = true;
|
|
1161
|
+
storage.setItem(key, serialized);
|
|
1162
|
+
writeState(value);
|
|
1163
|
+
if (emitSync) {
|
|
1164
|
+
windowRef.dispatchEvent(
|
|
1165
|
+
new CustomEvent(syncEvent, {
|
|
1166
|
+
detail: {
|
|
1167
|
+
key,
|
|
1168
|
+
value: serialized
|
|
1169
|
+
}
|
|
1170
|
+
})
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
} catch (error) {
|
|
1174
|
+
safeCall(options.onError, error);
|
|
1175
|
+
} finally {
|
|
1176
|
+
paused = false;
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
const remove = () => {
|
|
1180
|
+
if (!storage) {
|
|
1181
|
+
writeState(initial);
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
try {
|
|
1185
|
+
paused = true;
|
|
1186
|
+
storage.removeItem(key);
|
|
1187
|
+
writeState(initial);
|
|
1188
|
+
if (emitSync) {
|
|
1189
|
+
windowRef.dispatchEvent(
|
|
1190
|
+
new CustomEvent(syncEvent, {
|
|
1191
|
+
detail: {
|
|
1192
|
+
key,
|
|
1193
|
+
value: null
|
|
1194
|
+
}
|
|
1195
|
+
})
|
|
1196
|
+
);
|
|
1197
|
+
}
|
|
1198
|
+
} catch (error) {
|
|
1199
|
+
safeCall(options.onError, error);
|
|
1200
|
+
} finally {
|
|
1201
|
+
paused = false;
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
const syncFromRaw = (raw) => {
|
|
1205
|
+
if (paused) {
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
if (raw == null) {
|
|
1209
|
+
state(initial);
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
try {
|
|
1213
|
+
state(serializer.read(raw));
|
|
1214
|
+
} catch (error) {
|
|
1215
|
+
safeCall(options.onError, error);
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
const listenToStorageChanges = options.listenToStorageChanges ?? true;
|
|
1219
|
+
if (windowRef && storage && listenToStorageChanges) {
|
|
1220
|
+
const storageListener = (event) => {
|
|
1221
|
+
if (event.storageArea !== storage || event.key !== key) {
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1224
|
+
syncFromRaw(event.newValue);
|
|
1225
|
+
};
|
|
1226
|
+
const customListener = (event) => {
|
|
1227
|
+
const custom = event;
|
|
1228
|
+
if (custom.detail?.key !== key) {
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
syncFromRaw(custom.detail.value);
|
|
1232
|
+
};
|
|
1233
|
+
windowRef.addEventListener("storage", storageListener);
|
|
1234
|
+
windowRef.addEventListener(syncEvent, customListener);
|
|
1235
|
+
(0, import_runtime12.onDestroy)(() => {
|
|
1236
|
+
windowRef.removeEventListener("storage", storageListener);
|
|
1237
|
+
windowRef.removeEventListener(syncEvent, customListener);
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1240
|
+
return {
|
|
1241
|
+
value: state,
|
|
1242
|
+
set,
|
|
1243
|
+
remove
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
// src/storage/useLocalStorage.ts
|
|
1248
|
+
function useLocalStorage(key, initial, options = {}) {
|
|
1249
|
+
const windowRef = options.window ?? defaultWindow;
|
|
1250
|
+
return createStorageHook(windowRef?.localStorage, key, initial, {
|
|
1251
|
+
...options,
|
|
1252
|
+
window: windowRef
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
// src/storage/useSessionStorage.ts
|
|
1257
|
+
function useSessionStorage(key, initial, options = {}) {
|
|
1258
|
+
const windowRef = options.window ?? defaultWindow;
|
|
1259
|
+
return createStorageHook(windowRef?.sessionStorage, key, initial, {
|
|
1260
|
+
...options,
|
|
1261
|
+
window: windowRef
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// src/storage/useStorage.ts
|
|
1266
|
+
function useStorage(key, initial, options = {}) {
|
|
1267
|
+
const windowRef = options.window ?? defaultWindow;
|
|
1268
|
+
const storage = options.storage === void 0 ? windowRef?.localStorage : options.storage;
|
|
1269
|
+
return createStorageHook(storage ?? void 0, key, initial, {
|
|
1270
|
+
window: windowRef,
|
|
1271
|
+
serializer: options.serializer,
|
|
1272
|
+
onError: options.onError,
|
|
1273
|
+
listenToStorageChanges: options.listenToStorageChanges,
|
|
1274
|
+
writeDefaults: options.writeDefaults
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// src/observer/useIntersectionObserver.ts
|
|
1279
|
+
var import_runtime13 = require("@fictjs/runtime");
|
|
1280
|
+
var import_advanced12 = require("@fictjs/runtime/advanced");
|
|
1281
|
+
function useIntersectionObserver(target, callback, options = {}) {
|
|
1282
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
1283
|
+
const observerCtor = windowRef?.IntersectionObserver ?? globalThis.IntersectionObserver;
|
|
1284
|
+
const entries = (0, import_advanced12.createSignal)([]);
|
|
1285
|
+
const isSupported = (0, import_advanced12.createSignal)(!!observerCtor);
|
|
1286
|
+
const active = (0, import_advanced12.createSignal)(true);
|
|
1287
|
+
let cleanup = () => {
|
|
1288
|
+
};
|
|
1289
|
+
const setup = () => {
|
|
1290
|
+
const Observer = observerCtor;
|
|
1291
|
+
if (!Observer) {
|
|
1292
|
+
isSupported(false);
|
|
1293
|
+
return;
|
|
1294
|
+
}
|
|
1295
|
+
isSupported(true);
|
|
1296
|
+
const rootElement = options.root ? resolveMaybeTarget(options.root) : void 0;
|
|
1297
|
+
const observer = new Observer(
|
|
1298
|
+
(nextEntries, currentObserver) => {
|
|
1299
|
+
entries(nextEntries);
|
|
1300
|
+
callback?.(nextEntries, currentObserver);
|
|
1301
|
+
},
|
|
1302
|
+
{
|
|
1303
|
+
root: rootElement ?? null,
|
|
1304
|
+
rootMargin: options.rootMargin,
|
|
1305
|
+
threshold: options.threshold
|
|
1306
|
+
}
|
|
1307
|
+
);
|
|
1308
|
+
const targets = resolveTargetList(target);
|
|
1309
|
+
for (const element of targets) {
|
|
1310
|
+
observer.observe(element);
|
|
1311
|
+
}
|
|
1312
|
+
cleanup = () => {
|
|
1313
|
+
observer.disconnect();
|
|
1314
|
+
cleanup = () => {
|
|
1315
|
+
};
|
|
1316
|
+
};
|
|
1317
|
+
};
|
|
1318
|
+
(0, import_runtime13.createEffect)(() => {
|
|
1319
|
+
cleanup();
|
|
1320
|
+
if (!active()) {
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1323
|
+
setup();
|
|
1324
|
+
(0, import_runtime13.onCleanup)(() => {
|
|
1325
|
+
cleanup();
|
|
1326
|
+
});
|
|
1327
|
+
});
|
|
1328
|
+
return {
|
|
1329
|
+
entries,
|
|
1330
|
+
isSupported,
|
|
1331
|
+
start() {
|
|
1332
|
+
active(true);
|
|
1333
|
+
},
|
|
1334
|
+
stop() {
|
|
1335
|
+
active(false);
|
|
1336
|
+
cleanup();
|
|
1337
|
+
},
|
|
1338
|
+
active
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
// src/observer/useMutationObserver.ts
|
|
1343
|
+
var import_runtime14 = require("@fictjs/runtime");
|
|
1344
|
+
var import_advanced13 = require("@fictjs/runtime/advanced");
|
|
1345
|
+
function useMutationObserver(target, callback, options = {}) {
|
|
1346
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
1347
|
+
const observerCtor = windowRef?.MutationObserver ?? globalThis.MutationObserver;
|
|
1348
|
+
const records = (0, import_advanced13.createSignal)([]);
|
|
1349
|
+
const isSupported = (0, import_advanced13.createSignal)(!!observerCtor);
|
|
1350
|
+
const active = (0, import_advanced13.createSignal)(true);
|
|
1351
|
+
let cleanup = () => {
|
|
1352
|
+
};
|
|
1353
|
+
(0, import_runtime14.createEffect)(() => {
|
|
1354
|
+
cleanup();
|
|
1355
|
+
if (!active()) {
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
const Observer = observerCtor;
|
|
1359
|
+
if (!Observer) {
|
|
1360
|
+
isSupported(false);
|
|
1361
|
+
return;
|
|
1362
|
+
}
|
|
1363
|
+
isSupported(true);
|
|
1364
|
+
const observer = new Observer(
|
|
1365
|
+
(nextRecords, currentObserver) => {
|
|
1366
|
+
records(nextRecords);
|
|
1367
|
+
callback?.(nextRecords, currentObserver);
|
|
1368
|
+
}
|
|
1369
|
+
);
|
|
1370
|
+
const targets = resolveTargetList(target);
|
|
1371
|
+
const observeOptions = {
|
|
1372
|
+
subtree: options.subtree ?? true,
|
|
1373
|
+
childList: options.childList ?? true,
|
|
1374
|
+
attributes: options.attributes,
|
|
1375
|
+
characterData: options.characterData,
|
|
1376
|
+
attributeFilter: options.attributeFilter,
|
|
1377
|
+
attributeOldValue: options.attributeOldValue,
|
|
1378
|
+
characterDataOldValue: options.characterDataOldValue
|
|
1379
|
+
};
|
|
1380
|
+
for (const element of targets) {
|
|
1381
|
+
observer.observe(element, observeOptions);
|
|
1382
|
+
}
|
|
1383
|
+
cleanup = () => {
|
|
1384
|
+
observer.disconnect();
|
|
1385
|
+
cleanup = () => {
|
|
1386
|
+
};
|
|
1387
|
+
};
|
|
1388
|
+
(0, import_runtime14.onCleanup)(() => {
|
|
1389
|
+
cleanup();
|
|
1390
|
+
});
|
|
1391
|
+
});
|
|
1392
|
+
return {
|
|
1393
|
+
records,
|
|
1394
|
+
isSupported,
|
|
1395
|
+
active,
|
|
1396
|
+
start() {
|
|
1397
|
+
active(true);
|
|
1398
|
+
},
|
|
1399
|
+
stop() {
|
|
1400
|
+
active(false);
|
|
1401
|
+
cleanup();
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
// src/observer/useResizeObserver.ts
|
|
1407
|
+
var import_runtime15 = require("@fictjs/runtime");
|
|
1408
|
+
var import_advanced14 = require("@fictjs/runtime/advanced");
|
|
1409
|
+
function useResizeObserver(target, callback, options = {}) {
|
|
1410
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
1411
|
+
const observerCtor = windowRef?.ResizeObserver ?? globalThis.ResizeObserver;
|
|
1412
|
+
const entries = (0, import_advanced14.createSignal)([]);
|
|
1413
|
+
const isSupported = (0, import_advanced14.createSignal)(!!observerCtor);
|
|
1414
|
+
const active = (0, import_advanced14.createSignal)(true);
|
|
1415
|
+
let cleanup = () => {
|
|
1416
|
+
};
|
|
1417
|
+
(0, import_runtime15.createEffect)(() => {
|
|
1418
|
+
cleanup();
|
|
1419
|
+
if (!active()) {
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
const Observer = observerCtor;
|
|
1423
|
+
if (!Observer) {
|
|
1424
|
+
isSupported(false);
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
isSupported(true);
|
|
1428
|
+
const observer = new Observer(
|
|
1429
|
+
(nextEntries, currentObserver) => {
|
|
1430
|
+
entries(nextEntries);
|
|
1431
|
+
callback?.(nextEntries, currentObserver);
|
|
1432
|
+
}
|
|
1433
|
+
);
|
|
1434
|
+
const targets = resolveTargetList(target);
|
|
1435
|
+
for (const element of targets) {
|
|
1436
|
+
observer.observe(element, options.box ? { box: options.box } : void 0);
|
|
1437
|
+
}
|
|
1438
|
+
cleanup = () => {
|
|
1439
|
+
observer.disconnect();
|
|
1440
|
+
cleanup = () => {
|
|
1441
|
+
};
|
|
1442
|
+
};
|
|
1443
|
+
(0, import_runtime15.onCleanup)(() => {
|
|
1444
|
+
cleanup();
|
|
1445
|
+
});
|
|
1446
|
+
});
|
|
1447
|
+
return {
|
|
1448
|
+
entries,
|
|
1449
|
+
isSupported,
|
|
1450
|
+
active,
|
|
1451
|
+
start() {
|
|
1452
|
+
active(true);
|
|
1453
|
+
},
|
|
1454
|
+
stop() {
|
|
1455
|
+
active(false);
|
|
1456
|
+
cleanup();
|
|
1457
|
+
}
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
// src/state/useCounter.ts
|
|
1462
|
+
var import_advanced15 = require("@fictjs/runtime/advanced");
|
|
1463
|
+
function clamp(value, min, max) {
|
|
1464
|
+
let next = value;
|
|
1465
|
+
if (min != null) {
|
|
1466
|
+
next = Math.max(min, next);
|
|
1467
|
+
}
|
|
1468
|
+
if (max != null) {
|
|
1469
|
+
next = Math.min(max, next);
|
|
1470
|
+
}
|
|
1471
|
+
return next;
|
|
1472
|
+
}
|
|
1473
|
+
function useCounter(initial = 0, options = {}) {
|
|
1474
|
+
const start = clamp(initial, options.min, options.max);
|
|
1475
|
+
const count = (0, import_advanced15.createSignal)(start);
|
|
1476
|
+
return {
|
|
1477
|
+
count,
|
|
1478
|
+
set(next) {
|
|
1479
|
+
count(clamp(next, options.min, options.max));
|
|
1480
|
+
},
|
|
1481
|
+
inc(delta = 1) {
|
|
1482
|
+
count(clamp(count() + delta, options.min, options.max));
|
|
1483
|
+
},
|
|
1484
|
+
dec(delta = 1) {
|
|
1485
|
+
count(clamp(count() - delta, options.min, options.max));
|
|
1486
|
+
},
|
|
1487
|
+
reset() {
|
|
1488
|
+
count(start);
|
|
1489
|
+
}
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
// src/state/usePrevious.ts
|
|
1494
|
+
var import_runtime16 = require("@fictjs/runtime");
|
|
1495
|
+
var import_advanced16 = require("@fictjs/runtime/advanced");
|
|
1496
|
+
function usePrevious(value) {
|
|
1497
|
+
const previous = (0, import_advanced16.createSignal)(void 0);
|
|
1498
|
+
let lastValue;
|
|
1499
|
+
let initialized = false;
|
|
1500
|
+
(0, import_runtime16.createEffect)(() => {
|
|
1501
|
+
const current = toValue(value);
|
|
1502
|
+
if (initialized) {
|
|
1503
|
+
previous(lastValue);
|
|
1504
|
+
}
|
|
1505
|
+
lastValue = current;
|
|
1506
|
+
initialized = true;
|
|
1507
|
+
});
|
|
1508
|
+
return previous;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
// src/state/useToggle.ts
|
|
1512
|
+
var import_advanced17 = require("@fictjs/runtime/advanced");
|
|
1513
|
+
function useToggle(initial = false) {
|
|
1514
|
+
const value = (0, import_advanced17.createSignal)(initial);
|
|
1515
|
+
return {
|
|
1516
|
+
value,
|
|
1517
|
+
toggle() {
|
|
1518
|
+
value(!value());
|
|
1519
|
+
},
|
|
1520
|
+
set(next) {
|
|
1521
|
+
value(next);
|
|
1522
|
+
},
|
|
1523
|
+
setTrue() {
|
|
1524
|
+
value(true);
|
|
1525
|
+
},
|
|
1526
|
+
setFalse() {
|
|
1527
|
+
value(false);
|
|
1528
|
+
}
|
|
1529
|
+
};
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
// src/state/useVirtualList.ts
|
|
1533
|
+
var import_runtime17 = require("@fictjs/runtime");
|
|
1534
|
+
var import_advanced18 = require("@fictjs/runtime/advanced");
|
|
1535
|
+
function useVirtualList(source, options) {
|
|
1536
|
+
const overscan = options.overscan ?? 2;
|
|
1537
|
+
const itemHeight = options.itemHeight;
|
|
1538
|
+
const scrollTop = (0, import_advanced18.createSignal)(options.initialScrollTop ?? 0);
|
|
1539
|
+
const totalHeight = (0, import_runtime17.createMemo)(() => toValue(source).length * itemHeight);
|
|
1540
|
+
const start = (0, import_runtime17.createMemo)(() => {
|
|
1541
|
+
const base = Math.floor(scrollTop() / itemHeight) - overscan;
|
|
1542
|
+
return Math.max(0, base);
|
|
1543
|
+
});
|
|
1544
|
+
const end = (0, import_runtime17.createMemo)(() => {
|
|
1545
|
+
const items = toValue(source);
|
|
1546
|
+
const containerHeight = toValue(options.containerHeight);
|
|
1547
|
+
const visibleCount = Math.ceil(containerHeight / itemHeight) + overscan * 2;
|
|
1548
|
+
return Math.min(items.length, start() + visibleCount);
|
|
1549
|
+
});
|
|
1550
|
+
const list = (0, import_runtime17.createMemo)(() => {
|
|
1551
|
+
const items = toValue(source);
|
|
1552
|
+
const from = start();
|
|
1553
|
+
const to = end();
|
|
1554
|
+
const result = [];
|
|
1555
|
+
for (let index = from; index < to; index += 1) {
|
|
1556
|
+
result.push({
|
|
1557
|
+
index,
|
|
1558
|
+
data: items[index],
|
|
1559
|
+
start: index * itemHeight,
|
|
1560
|
+
end: (index + 1) * itemHeight
|
|
1561
|
+
});
|
|
1562
|
+
}
|
|
1563
|
+
return result;
|
|
1564
|
+
});
|
|
1565
|
+
const setScrollTop = (value) => {
|
|
1566
|
+
scrollTop(Math.max(0, value));
|
|
1567
|
+
};
|
|
1568
|
+
const scrollTo = (index) => {
|
|
1569
|
+
setScrollTop(index * itemHeight);
|
|
1570
|
+
};
|
|
1571
|
+
const onScroll = (event) => {
|
|
1572
|
+
const element = event.target;
|
|
1573
|
+
if (!element) {
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
setScrollTop(element.scrollTop);
|
|
1577
|
+
};
|
|
1578
|
+
return {
|
|
1579
|
+
list,
|
|
1580
|
+
totalHeight,
|
|
1581
|
+
start,
|
|
1582
|
+
end,
|
|
1583
|
+
scrollTop,
|
|
1584
|
+
setScrollTop,
|
|
1585
|
+
scrollTo,
|
|
1586
|
+
onScroll
|
|
1587
|
+
};
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
// src/browser/useDocumentVisibility.ts
|
|
1591
|
+
var import_runtime18 = require("@fictjs/runtime");
|
|
1592
|
+
var import_advanced19 = require("@fictjs/runtime/advanced");
|
|
1593
|
+
function useDocumentVisibility(options = {}) {
|
|
1594
|
+
const documentRef = options.document === void 0 ? defaultDocument : options.document;
|
|
1595
|
+
const fallback = options.initialVisibility ?? "visible";
|
|
1596
|
+
const visibility = (0, import_advanced19.createSignal)(documentRef?.visibilityState ?? fallback);
|
|
1597
|
+
const update = () => {
|
|
1598
|
+
visibility(documentRef?.visibilityState ?? fallback);
|
|
1599
|
+
};
|
|
1600
|
+
useEventListener(documentRef, "visibilitychange", update, { passive: true });
|
|
1601
|
+
const hidden = (0, import_runtime18.createMemo)(() => visibility() !== "visible");
|
|
1602
|
+
return {
|
|
1603
|
+
visibility,
|
|
1604
|
+
hidden
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
// src/browser/useMediaQuery.ts
|
|
1609
|
+
var import_runtime19 = require("@fictjs/runtime");
|
|
1610
|
+
var import_advanced20 = require("@fictjs/runtime/advanced");
|
|
1611
|
+
function useMediaQuery(mediaQuery, options = {}) {
|
|
1612
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
1613
|
+
const fallback = options.initialValue ?? false;
|
|
1614
|
+
const matches = (0, import_advanced20.createSignal)(fallback);
|
|
1615
|
+
const query = (0, import_advanced20.createSignal)(typeof mediaQuery === "string" ? mediaQuery : "");
|
|
1616
|
+
const isSupported = (0, import_advanced20.createSignal)(!!windowRef?.matchMedia);
|
|
1617
|
+
(0, import_runtime19.createEffect)(() => {
|
|
1618
|
+
const nextQuery = toValue(mediaQuery);
|
|
1619
|
+
query(nextQuery);
|
|
1620
|
+
if (!windowRef?.matchMedia) {
|
|
1621
|
+
isSupported(false);
|
|
1622
|
+
matches(fallback);
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
isSupported(true);
|
|
1626
|
+
const mql = windowRef.matchMedia(nextQuery);
|
|
1627
|
+
matches(mql.matches);
|
|
1628
|
+
const listener = (event) => {
|
|
1629
|
+
matches(event.matches);
|
|
1630
|
+
};
|
|
1631
|
+
mql.addEventListener("change", listener);
|
|
1632
|
+
(0, import_runtime19.onCleanup)(() => {
|
|
1633
|
+
mql.removeEventListener("change", listener);
|
|
1634
|
+
});
|
|
1635
|
+
});
|
|
1636
|
+
return {
|
|
1637
|
+
matches,
|
|
1638
|
+
query,
|
|
1639
|
+
isSupported
|
|
1640
|
+
};
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
// src/browser/useNetwork.ts
|
|
1644
|
+
var import_advanced21 = require("@fictjs/runtime/advanced");
|
|
1645
|
+
function resolveConnection(navigatorRef) {
|
|
1646
|
+
return navigatorRef?.connection ?? navigatorRef?.mozConnection ?? navigatorRef?.webkitConnection;
|
|
1647
|
+
}
|
|
1648
|
+
function useNetwork(options = {}) {
|
|
1649
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
1650
|
+
const navigatorRef = options.navigator === void 0 ? defaultNavigator : options.navigator;
|
|
1651
|
+
const connection = resolveConnection(navigatorRef);
|
|
1652
|
+
const online = (0, import_advanced21.createSignal)(navigatorRef?.onLine ?? true);
|
|
1653
|
+
const downlink = (0, import_advanced21.createSignal)(connection?.downlink ?? null);
|
|
1654
|
+
const effectiveType = (0, import_advanced21.createSignal)(connection?.effectiveType ?? null);
|
|
1655
|
+
const rtt = (0, import_advanced21.createSignal)(connection?.rtt ?? null);
|
|
1656
|
+
const saveData = (0, import_advanced21.createSignal)(connection?.saveData ?? false);
|
|
1657
|
+
const type = (0, import_advanced21.createSignal)(connection?.type ?? null);
|
|
1658
|
+
const isSupported = (0, import_advanced21.createSignal)(navigatorRef != null);
|
|
1659
|
+
const update = () => {
|
|
1660
|
+
const nextConnection = resolveConnection(navigatorRef);
|
|
1661
|
+
online(navigatorRef?.onLine ?? true);
|
|
1662
|
+
downlink(nextConnection?.downlink ?? null);
|
|
1663
|
+
effectiveType(nextConnection?.effectiveType ?? null);
|
|
1664
|
+
rtt(nextConnection?.rtt ?? null);
|
|
1665
|
+
saveData(nextConnection?.saveData ?? false);
|
|
1666
|
+
type(nextConnection?.type ?? null);
|
|
1667
|
+
};
|
|
1668
|
+
useEventListener(windowRef, "online", update, { passive: true });
|
|
1669
|
+
useEventListener(windowRef, "offline", update, { passive: true });
|
|
1670
|
+
if (connection) {
|
|
1671
|
+
useEventListener(connection, "change", update, { passive: true });
|
|
1672
|
+
}
|
|
1673
|
+
update();
|
|
1674
|
+
return {
|
|
1675
|
+
online,
|
|
1676
|
+
downlink,
|
|
1677
|
+
effectiveType,
|
|
1678
|
+
rtt,
|
|
1679
|
+
saveData,
|
|
1680
|
+
type,
|
|
1681
|
+
isSupported
|
|
1682
|
+
};
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
// src/browser/useScroll.ts
|
|
1686
|
+
var import_runtime20 = require("@fictjs/runtime");
|
|
1687
|
+
var import_advanced22 = require("@fictjs/runtime/advanced");
|
|
1688
|
+
function isWindowLike(target) {
|
|
1689
|
+
if (!target || typeof target !== "object") {
|
|
1690
|
+
return false;
|
|
1691
|
+
}
|
|
1692
|
+
return ("pageXOffset" in target || "scrollX" in target) && ("pageYOffset" in target || "scrollY" in target);
|
|
1693
|
+
}
|
|
1694
|
+
function readDocumentScrollPosition(documentRef, windowRef) {
|
|
1695
|
+
const view = documentRef.defaultView ?? windowRef;
|
|
1696
|
+
if (view) {
|
|
1697
|
+
return {
|
|
1698
|
+
x: view.pageXOffset ?? view.scrollX ?? 0,
|
|
1699
|
+
y: view.pageYOffset ?? view.scrollY ?? 0
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
const scrolling = documentRef.scrollingElement ?? documentRef.documentElement ?? documentRef.body;
|
|
1703
|
+
return {
|
|
1704
|
+
x: scrolling?.scrollLeft ?? 0,
|
|
1705
|
+
y: scrolling?.scrollTop ?? 0
|
|
1706
|
+
};
|
|
1707
|
+
}
|
|
1708
|
+
function readScrollPosition(target, windowRef, fallback) {
|
|
1709
|
+
if (!target) {
|
|
1710
|
+
return fallback;
|
|
1711
|
+
}
|
|
1712
|
+
if ("documentElement" in target) {
|
|
1713
|
+
return readDocumentScrollPosition(target, windowRef ?? void 0);
|
|
1714
|
+
}
|
|
1715
|
+
if (isWindowLike(target)) {
|
|
1716
|
+
return {
|
|
1717
|
+
x: target.pageXOffset ?? target.scrollX ?? 0,
|
|
1718
|
+
y: target.pageYOffset ?? target.scrollY ?? 0
|
|
1719
|
+
};
|
|
1720
|
+
}
|
|
1721
|
+
return {
|
|
1722
|
+
x: target.scrollLeft ?? 0,
|
|
1723
|
+
y: target.scrollTop ?? 0
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1726
|
+
function useScroll(options = {}) {
|
|
1727
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
1728
|
+
const fallback = {
|
|
1729
|
+
x: options.initialX ?? 0,
|
|
1730
|
+
y: options.initialY ?? 0
|
|
1731
|
+
};
|
|
1732
|
+
const x = (0, import_advanced22.createSignal)(fallback.x);
|
|
1733
|
+
const y = (0, import_advanced22.createSignal)(fallback.y);
|
|
1734
|
+
let previous = { ...fallback };
|
|
1735
|
+
const resolveScrollTarget = () => {
|
|
1736
|
+
if (options.target === null) {
|
|
1737
|
+
return void 0;
|
|
1738
|
+
}
|
|
1739
|
+
if (options.target === void 0) {
|
|
1740
|
+
return windowRef ?? void 0;
|
|
1741
|
+
}
|
|
1742
|
+
return resolveMaybeTarget(options.target);
|
|
1743
|
+
};
|
|
1744
|
+
const update = () => {
|
|
1745
|
+
const next = readScrollPosition(resolveScrollTarget(), windowRef, fallback);
|
|
1746
|
+
const shouldUpdate = options.shouldUpdate?.(next, previous) ?? true;
|
|
1747
|
+
if (!shouldUpdate) {
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
if (next.x === previous.x && next.y === previous.y) {
|
|
1751
|
+
return;
|
|
1752
|
+
}
|
|
1753
|
+
previous = next;
|
|
1754
|
+
x(next.x);
|
|
1755
|
+
y(next.y);
|
|
1756
|
+
};
|
|
1757
|
+
useEventListener(() => resolveScrollTarget(), "scroll", update, {
|
|
1758
|
+
passive: options.passive ?? true,
|
|
1759
|
+
capture: options.capture
|
|
1760
|
+
});
|
|
1761
|
+
(0, import_runtime20.createEffect)(() => {
|
|
1762
|
+
update();
|
|
1763
|
+
});
|
|
1764
|
+
return {
|
|
1765
|
+
x,
|
|
1766
|
+
y
|
|
1767
|
+
};
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
// src/browser/usePermission.ts
|
|
1771
|
+
var import_runtime21 = require("@fictjs/runtime");
|
|
1772
|
+
var import_advanced23 = require("@fictjs/runtime/advanced");
|
|
1773
|
+
function normalizePermission(input) {
|
|
1774
|
+
if (typeof input === "string") {
|
|
1775
|
+
return { name: input };
|
|
1776
|
+
}
|
|
1777
|
+
return input;
|
|
1778
|
+
}
|
|
1779
|
+
function usePermission(permission, options = {}) {
|
|
1780
|
+
const navigatorRef = options.navigator === void 0 ? defaultNavigator : options.navigator;
|
|
1781
|
+
const initialState = options.initialState ?? "prompt";
|
|
1782
|
+
const isSupported = (0, import_advanced23.createSignal)(!!navigatorRef?.permissions?.query);
|
|
1783
|
+
const state = (0, import_advanced23.createSignal)(initialState);
|
|
1784
|
+
let activePermission = normalizePermission(toValue(permission));
|
|
1785
|
+
let cleanup = () => {
|
|
1786
|
+
};
|
|
1787
|
+
const bindStatus = (nextStatus) => {
|
|
1788
|
+
cleanup();
|
|
1789
|
+
state(nextStatus.state);
|
|
1790
|
+
const onChange = () => {
|
|
1791
|
+
state(nextStatus.state);
|
|
1792
|
+
};
|
|
1793
|
+
nextStatus.addEventListener("change", onChange);
|
|
1794
|
+
cleanup = () => {
|
|
1795
|
+
nextStatus.removeEventListener("change", onChange);
|
|
1796
|
+
cleanup = () => {
|
|
1797
|
+
};
|
|
1798
|
+
};
|
|
1799
|
+
};
|
|
1800
|
+
const query = async () => {
|
|
1801
|
+
if (!navigatorRef?.permissions?.query) {
|
|
1802
|
+
isSupported(false);
|
|
1803
|
+
return null;
|
|
1804
|
+
}
|
|
1805
|
+
isSupported(true);
|
|
1806
|
+
try {
|
|
1807
|
+
const nextStatus = await navigatorRef.permissions.query(activePermission);
|
|
1808
|
+
bindStatus(nextStatus);
|
|
1809
|
+
return nextStatus;
|
|
1810
|
+
} catch {
|
|
1811
|
+
state(initialState);
|
|
1812
|
+
return null;
|
|
1813
|
+
}
|
|
1814
|
+
};
|
|
1815
|
+
(0, import_runtime21.createEffect)(() => {
|
|
1816
|
+
activePermission = normalizePermission(toValue(permission));
|
|
1817
|
+
if (options.immediate ?? true) {
|
|
1818
|
+
void query();
|
|
1819
|
+
}
|
|
1820
|
+
});
|
|
1821
|
+
(0, import_runtime21.onDestroy)(() => {
|
|
1822
|
+
cleanup();
|
|
1823
|
+
});
|
|
1824
|
+
return {
|
|
1825
|
+
state,
|
|
1826
|
+
isSupported,
|
|
1827
|
+
query
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
// src/browser/useGeolocation.ts
|
|
1832
|
+
var import_runtime22 = require("@fictjs/runtime");
|
|
1833
|
+
var import_advanced24 = require("@fictjs/runtime/advanced");
|
|
1834
|
+
function createInitialCoords() {
|
|
1835
|
+
return {
|
|
1836
|
+
accuracy: 0,
|
|
1837
|
+
latitude: Number.POSITIVE_INFINITY,
|
|
1838
|
+
longitude: Number.POSITIVE_INFINITY,
|
|
1839
|
+
altitude: null,
|
|
1840
|
+
altitudeAccuracy: null,
|
|
1841
|
+
heading: null,
|
|
1842
|
+
speed: null
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
function useGeolocation(options = {}) {
|
|
1846
|
+
const navigatorRef = options.navigator === void 0 ? defaultNavigator : options.navigator;
|
|
1847
|
+
const geolocationRef = navigatorRef?.geolocation;
|
|
1848
|
+
const isSupported = (0, import_advanced24.createSignal)(!!geolocationRef);
|
|
1849
|
+
const coords = (0, import_advanced24.createSignal)(createInitialCoords());
|
|
1850
|
+
const locatedAt = (0, import_advanced24.createSignal)(null);
|
|
1851
|
+
const error = (0, import_advanced24.createSignal)(null);
|
|
1852
|
+
const active = (0, import_advanced24.createSignal)(false);
|
|
1853
|
+
let watchId = null;
|
|
1854
|
+
const resume = () => {
|
|
1855
|
+
if (!geolocationRef || active()) {
|
|
1856
|
+
if (!geolocationRef) {
|
|
1857
|
+
isSupported(false);
|
|
1858
|
+
}
|
|
1859
|
+
return;
|
|
1860
|
+
}
|
|
1861
|
+
watchId = geolocationRef.watchPosition(
|
|
1862
|
+
(position) => {
|
|
1863
|
+
coords({
|
|
1864
|
+
accuracy: position.coords.accuracy,
|
|
1865
|
+
latitude: position.coords.latitude,
|
|
1866
|
+
longitude: position.coords.longitude,
|
|
1867
|
+
altitude: position.coords.altitude,
|
|
1868
|
+
altitudeAccuracy: position.coords.altitudeAccuracy,
|
|
1869
|
+
heading: position.coords.heading,
|
|
1870
|
+
speed: position.coords.speed
|
|
1871
|
+
});
|
|
1872
|
+
locatedAt(position.timestamp);
|
|
1873
|
+
error(null);
|
|
1874
|
+
},
|
|
1875
|
+
(nextError) => {
|
|
1876
|
+
error(nextError);
|
|
1877
|
+
},
|
|
1878
|
+
{
|
|
1879
|
+
enableHighAccuracy: options.enableHighAccuracy,
|
|
1880
|
+
timeout: options.timeout,
|
|
1881
|
+
maximumAge: options.maximumAge
|
|
1882
|
+
}
|
|
1883
|
+
);
|
|
1884
|
+
active(true);
|
|
1885
|
+
};
|
|
1886
|
+
const pause = () => {
|
|
1887
|
+
if (!geolocationRef || watchId == null) {
|
|
1888
|
+
active(false);
|
|
1889
|
+
return;
|
|
1890
|
+
}
|
|
1891
|
+
geolocationRef.clearWatch(watchId);
|
|
1892
|
+
watchId = null;
|
|
1893
|
+
active(false);
|
|
1894
|
+
};
|
|
1895
|
+
if (options.immediate ?? true) {
|
|
1896
|
+
resume();
|
|
1897
|
+
}
|
|
1898
|
+
(0, import_runtime22.onDestroy)(() => {
|
|
1899
|
+
pause();
|
|
1900
|
+
});
|
|
1901
|
+
return {
|
|
1902
|
+
isSupported,
|
|
1903
|
+
coords,
|
|
1904
|
+
locatedAt,
|
|
1905
|
+
error,
|
|
1906
|
+
active,
|
|
1907
|
+
resume,
|
|
1908
|
+
pause
|
|
1909
|
+
};
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
// src/browser/useIdle.ts
|
|
1913
|
+
var import_runtime23 = require("@fictjs/runtime");
|
|
1914
|
+
var import_advanced25 = require("@fictjs/runtime/advanced");
|
|
1915
|
+
var DEFAULT_IDLE_EVENTS = [
|
|
1916
|
+
"mousemove",
|
|
1917
|
+
"mousedown",
|
|
1918
|
+
"resize",
|
|
1919
|
+
"keydown",
|
|
1920
|
+
"touchstart",
|
|
1921
|
+
"wheel",
|
|
1922
|
+
"pointerdown"
|
|
1923
|
+
];
|
|
1924
|
+
function useIdle(options = {}) {
|
|
1925
|
+
const timeout = options.timeout ?? 6e4;
|
|
1926
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
1927
|
+
const documentRef = options.document === void 0 ? defaultDocument : options.document;
|
|
1928
|
+
const events = options.events ?? [...DEFAULT_IDLE_EVENTS];
|
|
1929
|
+
const listenForVisibilityChange = options.listenForVisibilityChange ?? true;
|
|
1930
|
+
const idle = (0, import_advanced25.createSignal)(options.initialState ?? false);
|
|
1931
|
+
const lastActive = (0, import_advanced25.createSignal)(null);
|
|
1932
|
+
const isSupported = (0, import_advanced25.createSignal)(!!windowRef);
|
|
1933
|
+
const active = (0, import_advanced25.createSignal)(false);
|
|
1934
|
+
let timer = null;
|
|
1935
|
+
const clearTimer = () => {
|
|
1936
|
+
if (timer == null) {
|
|
1937
|
+
return;
|
|
1938
|
+
}
|
|
1939
|
+
clearTimeout(timer);
|
|
1940
|
+
timer = null;
|
|
1941
|
+
};
|
|
1942
|
+
const scheduleIdle = () => {
|
|
1943
|
+
clearTimer();
|
|
1944
|
+
if (!active() || !isSupported()) {
|
|
1945
|
+
return;
|
|
1946
|
+
}
|
|
1947
|
+
timer = setTimeout(() => {
|
|
1948
|
+
idle(true);
|
|
1949
|
+
}, timeout);
|
|
1950
|
+
};
|
|
1951
|
+
const markActive = () => {
|
|
1952
|
+
idle(false);
|
|
1953
|
+
lastActive(Date.now());
|
|
1954
|
+
scheduleIdle();
|
|
1955
|
+
};
|
|
1956
|
+
const activityListener = useEventListener(windowRef, events, markActive, {
|
|
1957
|
+
passive: true,
|
|
1958
|
+
immediate: false
|
|
1959
|
+
});
|
|
1960
|
+
const visibilityListener = useEventListener(
|
|
1961
|
+
documentRef,
|
|
1962
|
+
"visibilitychange",
|
|
1963
|
+
() => {
|
|
1964
|
+
if (!documentRef || documentRef.visibilityState !== "visible") {
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
markActive();
|
|
1968
|
+
},
|
|
1969
|
+
{
|
|
1970
|
+
passive: true,
|
|
1971
|
+
immediate: false
|
|
1972
|
+
}
|
|
1973
|
+
);
|
|
1974
|
+
const pause = () => {
|
|
1975
|
+
if (!active()) {
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
active(false);
|
|
1979
|
+
activityListener.stop();
|
|
1980
|
+
visibilityListener.stop();
|
|
1981
|
+
clearTimer();
|
|
1982
|
+
};
|
|
1983
|
+
const resume = () => {
|
|
1984
|
+
if (!windowRef || active()) {
|
|
1985
|
+
if (!windowRef) {
|
|
1986
|
+
isSupported(false);
|
|
1987
|
+
}
|
|
1988
|
+
return;
|
|
1989
|
+
}
|
|
1990
|
+
isSupported(true);
|
|
1991
|
+
active(true);
|
|
1992
|
+
activityListener.start();
|
|
1993
|
+
if (listenForVisibilityChange) {
|
|
1994
|
+
visibilityListener.start();
|
|
1995
|
+
}
|
|
1996
|
+
markActive();
|
|
1997
|
+
};
|
|
1998
|
+
const reset = () => {
|
|
1999
|
+
markActive();
|
|
2000
|
+
};
|
|
2001
|
+
if (options.immediate ?? true) {
|
|
2002
|
+
resume();
|
|
2003
|
+
}
|
|
2004
|
+
(0, import_runtime23.onDestroy)(() => {
|
|
2005
|
+
pause();
|
|
2006
|
+
});
|
|
2007
|
+
return {
|
|
2008
|
+
idle,
|
|
2009
|
+
lastActive,
|
|
2010
|
+
isSupported,
|
|
2011
|
+
active,
|
|
2012
|
+
reset,
|
|
2013
|
+
pause,
|
|
2014
|
+
resume
|
|
2015
|
+
};
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
// src/browser/useSize.ts
|
|
2019
|
+
var import_runtime24 = require("@fictjs/runtime");
|
|
2020
|
+
var import_advanced26 = require("@fictjs/runtime/advanced");
|
|
2021
|
+
function readRect(target) {
|
|
2022
|
+
const rect = target.getBoundingClientRect();
|
|
2023
|
+
return {
|
|
2024
|
+
width: rect.width,
|
|
2025
|
+
height: rect.height,
|
|
2026
|
+
top: rect.top,
|
|
2027
|
+
left: rect.left,
|
|
2028
|
+
x: rect.x ?? rect.left,
|
|
2029
|
+
y: rect.y ?? rect.top
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2032
|
+
function useSize(target, options = {}) {
|
|
2033
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
2034
|
+
const observerCtor = windowRef?.ResizeObserver ?? globalThis.ResizeObserver;
|
|
2035
|
+
const width = (0, import_advanced26.createSignal)(options.initialWidth ?? 0);
|
|
2036
|
+
const height = (0, import_advanced26.createSignal)(options.initialHeight ?? 0);
|
|
2037
|
+
const top = (0, import_advanced26.createSignal)(options.initialTop ?? 0);
|
|
2038
|
+
const left = (0, import_advanced26.createSignal)(options.initialLeft ?? 0);
|
|
2039
|
+
const x = (0, import_advanced26.createSignal)(options.initialX ?? options.initialLeft ?? 0);
|
|
2040
|
+
const y = (0, import_advanced26.createSignal)(options.initialY ?? options.initialTop ?? 0);
|
|
2041
|
+
const isSupported = (0, import_advanced26.createSignal)(!!observerCtor);
|
|
2042
|
+
const active = (0, import_advanced26.createSignal)(options.immediate ?? true);
|
|
2043
|
+
let observer = null;
|
|
2044
|
+
const applyRect = (nextTarget) => {
|
|
2045
|
+
const rect = readRect(nextTarget);
|
|
2046
|
+
width(rect.width);
|
|
2047
|
+
height(rect.height);
|
|
2048
|
+
top(rect.top);
|
|
2049
|
+
left(rect.left);
|
|
2050
|
+
x(rect.x);
|
|
2051
|
+
y(rect.y);
|
|
2052
|
+
};
|
|
2053
|
+
const update = () => {
|
|
2054
|
+
const nextTarget = resolveMaybeTarget(target);
|
|
2055
|
+
if (!nextTarget) {
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
2058
|
+
applyRect(nextTarget);
|
|
2059
|
+
};
|
|
2060
|
+
const resizeListener = useEventListener(windowRef, "resize", update, {
|
|
2061
|
+
passive: true,
|
|
2062
|
+
immediate: false
|
|
2063
|
+
});
|
|
2064
|
+
const stopObserver = () => {
|
|
2065
|
+
if (!observer) {
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
observer.disconnect();
|
|
2069
|
+
observer = null;
|
|
2070
|
+
};
|
|
2071
|
+
(0, import_runtime24.createEffect)(() => {
|
|
2072
|
+
stopObserver();
|
|
2073
|
+
const nextTarget = target ? resolveMaybeTarget(target) : void 0;
|
|
2074
|
+
if (!active() || !nextTarget) {
|
|
2075
|
+
resizeListener.stop();
|
|
2076
|
+
return;
|
|
2077
|
+
}
|
|
2078
|
+
applyRect(nextTarget);
|
|
2079
|
+
if (windowRef) {
|
|
2080
|
+
resizeListener.start();
|
|
2081
|
+
}
|
|
2082
|
+
const Observer = observerCtor;
|
|
2083
|
+
if (!Observer) {
|
|
2084
|
+
isSupported(false);
|
|
2085
|
+
return;
|
|
2086
|
+
}
|
|
2087
|
+
isSupported(true);
|
|
2088
|
+
observer = new Observer((entries) => {
|
|
2089
|
+
const entry = entries[0];
|
|
2090
|
+
if (entry?.contentRect) {
|
|
2091
|
+
width(entry.contentRect.width);
|
|
2092
|
+
height(entry.contentRect.height);
|
|
2093
|
+
applyRect(nextTarget);
|
|
2094
|
+
return;
|
|
2095
|
+
}
|
|
2096
|
+
applyRect(nextTarget);
|
|
2097
|
+
});
|
|
2098
|
+
observer.observe(nextTarget, options.box ? { box: options.box } : void 0);
|
|
2099
|
+
(0, import_runtime24.onCleanup)(() => {
|
|
2100
|
+
stopObserver();
|
|
2101
|
+
});
|
|
2102
|
+
});
|
|
2103
|
+
return {
|
|
2104
|
+
width,
|
|
2105
|
+
height,
|
|
2106
|
+
top,
|
|
2107
|
+
left,
|
|
2108
|
+
x,
|
|
2109
|
+
y,
|
|
2110
|
+
isSupported,
|
|
2111
|
+
active,
|
|
2112
|
+
update,
|
|
2113
|
+
start() {
|
|
2114
|
+
active(true);
|
|
2115
|
+
},
|
|
2116
|
+
stop() {
|
|
2117
|
+
active(false);
|
|
2118
|
+
resizeListener.stop();
|
|
2119
|
+
stopObserver();
|
|
2120
|
+
}
|
|
2121
|
+
};
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2124
|
+
// src/browser/useWebSocket.ts
|
|
2125
|
+
var import_runtime25 = require("@fictjs/runtime");
|
|
2126
|
+
var import_advanced27 = require("@fictjs/runtime/advanced");
|
|
2127
|
+
function normalizeReconnectOptions(value) {
|
|
2128
|
+
if (!value) {
|
|
2129
|
+
return null;
|
|
2130
|
+
}
|
|
2131
|
+
if (value === true) {
|
|
2132
|
+
return { retries: Infinity, delay: 1e3 };
|
|
2133
|
+
}
|
|
2134
|
+
return {
|
|
2135
|
+
retries: value.retries ?? Infinity,
|
|
2136
|
+
delay: value.delay ?? 1e3
|
|
2137
|
+
};
|
|
2138
|
+
}
|
|
2139
|
+
function toStatus(value, socket) {
|
|
2140
|
+
switch (value) {
|
|
2141
|
+
case socket.CONNECTING:
|
|
2142
|
+
return "CONNECTING";
|
|
2143
|
+
case socket.OPEN:
|
|
2144
|
+
return "OPEN";
|
|
2145
|
+
case socket.CLOSING:
|
|
2146
|
+
return "CLOSING";
|
|
2147
|
+
default:
|
|
2148
|
+
return "CLOSED";
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
function useWebSocket(url, options = {}) {
|
|
2152
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
2153
|
+
const windowSocketCtor = windowRef?.WebSocket;
|
|
2154
|
+
const webSocketCtor = options.webSocket === void 0 ? windowSocketCtor ?? globalThis.WebSocket : options.webSocket;
|
|
2155
|
+
const reconnectOptions = normalizeReconnectOptions(options.autoReconnect);
|
|
2156
|
+
const data = (0, import_advanced27.createSignal)(options.initialData ?? null);
|
|
2157
|
+
const error = (0, import_advanced27.createSignal)(null);
|
|
2158
|
+
const status = (0, import_advanced27.createSignal)("CLOSED");
|
|
2159
|
+
const isSupported = (0, import_advanced27.createSignal)(!!webSocketCtor);
|
|
2160
|
+
const reconnectCount = (0, import_advanced27.createSignal)(0);
|
|
2161
|
+
const serialize = options.serialize ?? ((payload) => payload);
|
|
2162
|
+
const deserialize = options.deserialize ?? ((event) => event.data);
|
|
2163
|
+
let socket = null;
|
|
2164
|
+
let manuallyClosed = false;
|
|
2165
|
+
let reconnectTimer = null;
|
|
2166
|
+
let reconnectAttempts = 0;
|
|
2167
|
+
let cleanupSocket = () => {
|
|
2168
|
+
};
|
|
2169
|
+
const stopReconnectTimer = () => {
|
|
2170
|
+
if (reconnectTimer == null) {
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
clearTimeout(reconnectTimer);
|
|
2174
|
+
reconnectTimer = null;
|
|
2175
|
+
};
|
|
2176
|
+
const resetReconnectAttempts = () => {
|
|
2177
|
+
reconnectAttempts = 0;
|
|
2178
|
+
reconnectCount(0);
|
|
2179
|
+
};
|
|
2180
|
+
const scheduleReconnect = () => {
|
|
2181
|
+
if (!reconnectOptions) {
|
|
2182
|
+
return;
|
|
2183
|
+
}
|
|
2184
|
+
const retries = reconnectOptions.retries ?? Infinity;
|
|
2185
|
+
if (reconnectAttempts >= retries) {
|
|
2186
|
+
return;
|
|
2187
|
+
}
|
|
2188
|
+
reconnectAttempts += 1;
|
|
2189
|
+
reconnectCount(reconnectAttempts);
|
|
2190
|
+
const delayValue = reconnectOptions.delay ?? 1e3;
|
|
2191
|
+
const delay2 = typeof delayValue === "function" ? delayValue(reconnectAttempts) : delayValue;
|
|
2192
|
+
stopReconnectTimer();
|
|
2193
|
+
reconnectTimer = setTimeout(
|
|
2194
|
+
() => {
|
|
2195
|
+
reconnectTimer = null;
|
|
2196
|
+
open();
|
|
2197
|
+
},
|
|
2198
|
+
Math.max(0, delay2)
|
|
2199
|
+
);
|
|
2200
|
+
};
|
|
2201
|
+
const open = () => {
|
|
2202
|
+
const resolvedUrl = toValue(url);
|
|
2203
|
+
if (!webSocketCtor || !resolvedUrl) {
|
|
2204
|
+
isSupported(false);
|
|
2205
|
+
return false;
|
|
2206
|
+
}
|
|
2207
|
+
if (socket && (socket.readyState === socket.CONNECTING || socket.readyState === socket.OPEN)) {
|
|
2208
|
+
return true;
|
|
2209
|
+
}
|
|
2210
|
+
stopReconnectTimer();
|
|
2211
|
+
manuallyClosed = false;
|
|
2212
|
+
error(null);
|
|
2213
|
+
let currentSocket;
|
|
2214
|
+
try {
|
|
2215
|
+
currentSocket = new webSocketCtor(resolvedUrl, options.protocols);
|
|
2216
|
+
} catch (nextError) {
|
|
2217
|
+
error(nextError);
|
|
2218
|
+
status("CLOSED");
|
|
2219
|
+
scheduleReconnect();
|
|
2220
|
+
return false;
|
|
2221
|
+
}
|
|
2222
|
+
socket = currentSocket;
|
|
2223
|
+
status(toStatus(currentSocket.readyState, currentSocket));
|
|
2224
|
+
if (options.binaryType) {
|
|
2225
|
+
currentSocket.binaryType = options.binaryType;
|
|
2226
|
+
}
|
|
2227
|
+
const onOpen = (event) => {
|
|
2228
|
+
if (socket !== currentSocket) {
|
|
2229
|
+
return;
|
|
2230
|
+
}
|
|
2231
|
+
status("OPEN");
|
|
2232
|
+
resetReconnectAttempts();
|
|
2233
|
+
options.onOpen?.(event);
|
|
2234
|
+
};
|
|
2235
|
+
const onMessage = (event) => {
|
|
2236
|
+
if (socket !== currentSocket) {
|
|
2237
|
+
return;
|
|
2238
|
+
}
|
|
2239
|
+
const messageEvent = event;
|
|
2240
|
+
const nextData = deserialize(messageEvent);
|
|
2241
|
+
data(nextData);
|
|
2242
|
+
options.onMessage?.(nextData, messageEvent);
|
|
2243
|
+
};
|
|
2244
|
+
const onError = (event) => {
|
|
2245
|
+
if (socket !== currentSocket) {
|
|
2246
|
+
return;
|
|
2247
|
+
}
|
|
2248
|
+
error(event);
|
|
2249
|
+
options.onError?.(event);
|
|
2250
|
+
};
|
|
2251
|
+
const onClose = (event) => {
|
|
2252
|
+
if (socket !== currentSocket) {
|
|
2253
|
+
return;
|
|
2254
|
+
}
|
|
2255
|
+
socket = null;
|
|
2256
|
+
cleanupSocket();
|
|
2257
|
+
status("CLOSED");
|
|
2258
|
+
options.onClose?.(event);
|
|
2259
|
+
if (!manuallyClosed) {
|
|
2260
|
+
scheduleReconnect();
|
|
2261
|
+
}
|
|
2262
|
+
};
|
|
2263
|
+
currentSocket.addEventListener("open", onOpen);
|
|
2264
|
+
currentSocket.addEventListener("message", onMessage);
|
|
2265
|
+
currentSocket.addEventListener("error", onError);
|
|
2266
|
+
currentSocket.addEventListener("close", onClose);
|
|
2267
|
+
cleanupSocket = () => {
|
|
2268
|
+
currentSocket.removeEventListener("open", onOpen);
|
|
2269
|
+
currentSocket.removeEventListener("message", onMessage);
|
|
2270
|
+
currentSocket.removeEventListener("error", onError);
|
|
2271
|
+
currentSocket.removeEventListener("close", onClose);
|
|
2272
|
+
cleanupSocket = () => {
|
|
2273
|
+
};
|
|
2274
|
+
};
|
|
2275
|
+
return true;
|
|
2276
|
+
};
|
|
2277
|
+
const close = (code, reason) => {
|
|
2278
|
+
stopReconnectTimer();
|
|
2279
|
+
resetReconnectAttempts();
|
|
2280
|
+
manuallyClosed = true;
|
|
2281
|
+
const currentSocket = socket;
|
|
2282
|
+
if (!currentSocket) {
|
|
2283
|
+
status("CLOSED");
|
|
2284
|
+
return;
|
|
2285
|
+
}
|
|
2286
|
+
socket = null;
|
|
2287
|
+
cleanupSocket();
|
|
2288
|
+
status("CLOSING");
|
|
2289
|
+
currentSocket.close(code, reason);
|
|
2290
|
+
status("CLOSED");
|
|
2291
|
+
};
|
|
2292
|
+
const reconnect = () => {
|
|
2293
|
+
stopReconnectTimer();
|
|
2294
|
+
if (socket) {
|
|
2295
|
+
const currentSocket = socket;
|
|
2296
|
+
socket = null;
|
|
2297
|
+
cleanupSocket();
|
|
2298
|
+
manuallyClosed = true;
|
|
2299
|
+
currentSocket.close();
|
|
2300
|
+
}
|
|
2301
|
+
manuallyClosed = false;
|
|
2302
|
+
return open();
|
|
2303
|
+
};
|
|
2304
|
+
const send = (payload) => {
|
|
2305
|
+
const currentSocket = socket;
|
|
2306
|
+
if (!currentSocket || currentSocket.readyState !== currentSocket.OPEN) {
|
|
2307
|
+
return false;
|
|
2308
|
+
}
|
|
2309
|
+
try {
|
|
2310
|
+
currentSocket.send(serialize(payload));
|
|
2311
|
+
return true;
|
|
2312
|
+
} catch (nextError) {
|
|
2313
|
+
error(nextError);
|
|
2314
|
+
return false;
|
|
2315
|
+
}
|
|
2316
|
+
};
|
|
2317
|
+
if (options.immediate ?? true) {
|
|
2318
|
+
open();
|
|
2319
|
+
}
|
|
2320
|
+
(0, import_runtime25.onDestroy)(() => {
|
|
2321
|
+
stopReconnectTimer();
|
|
2322
|
+
close();
|
|
2323
|
+
});
|
|
2324
|
+
return {
|
|
2325
|
+
data,
|
|
2326
|
+
error,
|
|
2327
|
+
status,
|
|
2328
|
+
isSupported,
|
|
2329
|
+
reconnectCount,
|
|
2330
|
+
open,
|
|
2331
|
+
close,
|
|
2332
|
+
reconnect,
|
|
2333
|
+
send
|
|
2334
|
+
};
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
// src/browser/useWindowSize.ts
|
|
2338
|
+
var import_advanced28 = require("@fictjs/runtime/advanced");
|
|
2339
|
+
function useWindowSize(options = {}) {
|
|
2340
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
2341
|
+
const width = (0, import_advanced28.createSignal)(windowRef?.innerWidth ?? options.initialWidth ?? 0);
|
|
2342
|
+
const height = (0, import_advanced28.createSignal)(windowRef?.innerHeight ?? options.initialHeight ?? 0);
|
|
2343
|
+
const update = () => {
|
|
2344
|
+
if (!windowRef) {
|
|
2345
|
+
return;
|
|
2346
|
+
}
|
|
2347
|
+
width(windowRef.innerWidth);
|
|
2348
|
+
height(windowRef.innerHeight);
|
|
2349
|
+
};
|
|
2350
|
+
useEventListener(windowRef, "resize", update, { passive: true });
|
|
2351
|
+
if (windowRef) {
|
|
2352
|
+
update();
|
|
2353
|
+
}
|
|
2354
|
+
return {
|
|
2355
|
+
width,
|
|
2356
|
+
height
|
|
2357
|
+
};
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
// src/browser/useWindowScroll.ts
|
|
2361
|
+
function useWindowScroll(options = {}) {
|
|
2362
|
+
const windowRef = options.window === void 0 ? defaultWindow : options.window;
|
|
2363
|
+
return useScroll({
|
|
2364
|
+
...options,
|
|
2365
|
+
window: windowRef,
|
|
2366
|
+
target: windowRef
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
// src/browser/useTitle.ts
|
|
2371
|
+
var import_runtime26 = require("@fictjs/runtime");
|
|
2372
|
+
var import_advanced29 = require("@fictjs/runtime/advanced");
|
|
2373
|
+
function useTitle(value, options = {}) {
|
|
2374
|
+
const documentRef = options.document === void 0 ? defaultDocument : options.document;
|
|
2375
|
+
const initialTitle = documentRef?.title ?? "";
|
|
2376
|
+
const title = (0, import_advanced29.createSignal)(documentRef?.title ?? toValue(value));
|
|
2377
|
+
(0, import_runtime26.createEffect)(() => {
|
|
2378
|
+
const nextTitle = toValue(value);
|
|
2379
|
+
title(nextTitle);
|
|
2380
|
+
if (documentRef) {
|
|
2381
|
+
documentRef.title = nextTitle;
|
|
2382
|
+
}
|
|
2383
|
+
});
|
|
2384
|
+
if (options.restoreOnUnmount) {
|
|
2385
|
+
(0, import_runtime26.onDestroy)(() => {
|
|
2386
|
+
if (documentRef) {
|
|
2387
|
+
documentRef.title = initialTitle;
|
|
2388
|
+
}
|
|
2389
|
+
});
|
|
2390
|
+
}
|
|
2391
|
+
return { title };
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
// src/browser/useFullscreen.ts
|
|
2395
|
+
var import_runtime27 = require("@fictjs/runtime");
|
|
2396
|
+
var import_advanced30 = require("@fictjs/runtime/advanced");
|
|
2397
|
+
function getFullscreenElement(documentRef) {
|
|
2398
|
+
return documentRef.fullscreenElement ?? documentRef.webkitFullscreenElement ?? documentRef.mozFullScreenElement ?? documentRef.msFullscreenElement ?? null;
|
|
2399
|
+
}
|
|
2400
|
+
function isFullscreenSupported(documentRef) {
|
|
2401
|
+
if (!documentRef) {
|
|
2402
|
+
return false;
|
|
2403
|
+
}
|
|
2404
|
+
if (documentRef.fullscreenEnabled || documentRef.webkitFullscreenEnabled || documentRef.mozFullScreenEnabled || documentRef.msFullscreenEnabled) {
|
|
2405
|
+
return true;
|
|
2406
|
+
}
|
|
2407
|
+
return typeof documentRef.exitFullscreen === "function" || typeof documentRef.webkitExitFullscreen === "function" || typeof documentRef.mozCancelFullScreen === "function" || typeof documentRef.msExitFullscreen === "function";
|
|
2408
|
+
}
|
|
2409
|
+
function resolveRequestMethod(target) {
|
|
2410
|
+
return target.requestFullscreen ?? target.webkitRequestFullscreen ?? target.webkitRequestFullScreen ?? target.mozRequestFullScreen ?? target.msRequestFullscreen;
|
|
2411
|
+
}
|
|
2412
|
+
function resolveExitMethod(documentRef) {
|
|
2413
|
+
return documentRef.exitFullscreen ?? documentRef.webkitExitFullscreen ?? documentRef.mozCancelFullScreen ?? documentRef.msExitFullscreen;
|
|
2414
|
+
}
|
|
2415
|
+
function resolveTargetElement(options, documentRef) {
|
|
2416
|
+
if (!documentRef) {
|
|
2417
|
+
return void 0;
|
|
2418
|
+
}
|
|
2419
|
+
if (options.target === null) {
|
|
2420
|
+
return void 0;
|
|
2421
|
+
}
|
|
2422
|
+
if (options.target === void 0) {
|
|
2423
|
+
return documentRef.documentElement ?? void 0;
|
|
2424
|
+
}
|
|
2425
|
+
return resolveMaybeTarget(options.target);
|
|
2426
|
+
}
|
|
2427
|
+
function useFullscreen(options = {}) {
|
|
2428
|
+
const documentRef = options.document === void 0 ? defaultDocument : options.document;
|
|
2429
|
+
const isSupported = (0, import_advanced30.createSignal)(isFullscreenSupported(documentRef));
|
|
2430
|
+
const isFullscreen = (0, import_advanced30.createSignal)(false);
|
|
2431
|
+
const update = () => {
|
|
2432
|
+
if (!documentRef) {
|
|
2433
|
+
isFullscreen(false);
|
|
2434
|
+
isSupported(false);
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2437
|
+
isSupported(isFullscreenSupported(documentRef));
|
|
2438
|
+
const target = resolveTargetElement(options, documentRef);
|
|
2439
|
+
const fullscreenElement = getFullscreenElement(documentRef);
|
|
2440
|
+
isFullscreen(!!target && !!fullscreenElement && fullscreenElement === target);
|
|
2441
|
+
};
|
|
2442
|
+
useEventListener(
|
|
2443
|
+
documentRef,
|
|
2444
|
+
["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"],
|
|
2445
|
+
update,
|
|
2446
|
+
{ passive: true }
|
|
2447
|
+
);
|
|
2448
|
+
(0, import_runtime27.createEffect)(() => {
|
|
2449
|
+
resolveTargetElement(options, documentRef);
|
|
2450
|
+
update();
|
|
2451
|
+
});
|
|
2452
|
+
const enter = async () => {
|
|
2453
|
+
if (!documentRef || !isSupported()) {
|
|
2454
|
+
return false;
|
|
2455
|
+
}
|
|
2456
|
+
const target = resolveTargetElement(options, documentRef);
|
|
2457
|
+
if (!target) {
|
|
2458
|
+
return false;
|
|
2459
|
+
}
|
|
2460
|
+
const request = resolveRequestMethod(target);
|
|
2461
|
+
if (!request) {
|
|
2462
|
+
return false;
|
|
2463
|
+
}
|
|
2464
|
+
try {
|
|
2465
|
+
await request.call(target);
|
|
2466
|
+
update();
|
|
2467
|
+
return true;
|
|
2468
|
+
} catch {
|
|
2469
|
+
update();
|
|
2470
|
+
return false;
|
|
2471
|
+
}
|
|
2472
|
+
};
|
|
2473
|
+
const exit = async () => {
|
|
2474
|
+
if (!documentRef || !isSupported()) {
|
|
2475
|
+
return false;
|
|
2476
|
+
}
|
|
2477
|
+
const exitMethod = resolveExitMethod(documentRef);
|
|
2478
|
+
if (!exitMethod) {
|
|
2479
|
+
return false;
|
|
2480
|
+
}
|
|
2481
|
+
try {
|
|
2482
|
+
await exitMethod.call(documentRef);
|
|
2483
|
+
update();
|
|
2484
|
+
return true;
|
|
2485
|
+
} catch {
|
|
2486
|
+
update();
|
|
2487
|
+
return false;
|
|
2488
|
+
}
|
|
2489
|
+
};
|
|
2490
|
+
const toggle = async () => {
|
|
2491
|
+
return isFullscreen() ? exit() : enter();
|
|
2492
|
+
};
|
|
2493
|
+
if (options.autoExit) {
|
|
2494
|
+
(0, import_runtime27.onDestroy)(() => {
|
|
2495
|
+
void exit();
|
|
2496
|
+
});
|
|
2497
|
+
}
|
|
2498
|
+
return {
|
|
2499
|
+
isSupported,
|
|
2500
|
+
isFullscreen,
|
|
2501
|
+
enter,
|
|
2502
|
+
exit,
|
|
2503
|
+
toggle
|
|
2504
|
+
};
|
|
2505
|
+
}
|
|
2506
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2507
|
+
0 && (module.exports = {
|
|
2508
|
+
useAsyncState,
|
|
2509
|
+
useClickOutside,
|
|
2510
|
+
useClipboard,
|
|
2511
|
+
useCounter,
|
|
2512
|
+
useDebounceFn,
|
|
2513
|
+
useDocumentVisibility,
|
|
2514
|
+
useEventListener,
|
|
2515
|
+
useFetch,
|
|
2516
|
+
useFocusWithin,
|
|
2517
|
+
useFullscreen,
|
|
2518
|
+
useGeolocation,
|
|
2519
|
+
useHover,
|
|
2520
|
+
useIdle,
|
|
2521
|
+
useIntersectionObserver,
|
|
2522
|
+
useIntervalFn,
|
|
2523
|
+
useKeyPress,
|
|
2524
|
+
useLocalStorage,
|
|
2525
|
+
useMediaQuery,
|
|
2526
|
+
useMount,
|
|
2527
|
+
useMutationObserver,
|
|
2528
|
+
useNetwork,
|
|
2529
|
+
usePermission,
|
|
2530
|
+
usePrevious,
|
|
2531
|
+
useRafFn,
|
|
2532
|
+
useRequest,
|
|
2533
|
+
useResizeObserver,
|
|
2534
|
+
useScroll,
|
|
2535
|
+
useSessionStorage,
|
|
2536
|
+
useSize,
|
|
2537
|
+
useStorage,
|
|
2538
|
+
useThrottleFn,
|
|
2539
|
+
useTimeoutFn,
|
|
2540
|
+
useTitle,
|
|
2541
|
+
useToggle,
|
|
2542
|
+
useUnmount,
|
|
2543
|
+
useVirtualList,
|
|
2544
|
+
useWebSocket,
|
|
2545
|
+
useWindowScroll,
|
|
2546
|
+
useWindowSize
|
|
2547
|
+
});
|
|
2548
|
+
//# sourceMappingURL=index.cjs.map
|