@develemit/web-hooks 0.1.0 → 0.2.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/CHANGELOG.md +16 -0
- package/README.md +166 -0
- package/dist/auto-grow.cjs +60 -0
- package/dist/auto-grow.d.cts +14 -0
- package/dist/auto-grow.d.ts +14 -0
- package/dist/auto-grow.js +9 -0
- package/dist/chunk-3CACI4OQ.js +68 -0
- package/dist/chunk-3UGRXQIA.js +39 -0
- package/dist/chunk-5CA5RIMH.js +34 -0
- package/dist/chunk-5KIH2XLV.js +136 -0
- package/dist/chunk-6KCRVSLS.js +80 -0
- package/dist/chunk-DNU57XEJ.js +82 -0
- package/dist/chunk-IWQDAJEP.js +69 -0
- package/dist/chunk-LZKAGDER.js +22 -0
- package/dist/chunk-NKLEB5TR.js +98 -0
- package/dist/chunk-OZ4PU4E3.js +115 -0
- package/dist/chunk-S4YKMGQE.js +23 -0
- package/dist/chunk-UPVNSGIK.js +72 -0
- package/dist/chunk-UZADAINO.js +61 -0
- package/dist/clipboard.cjs +5 -0
- package/dist/clipboard.js +4 -57
- package/dist/debounce.cjs +96 -0
- package/dist/debounce.d.cts +21 -0
- package/dist/debounce.d.ts +21 -0
- package/dist/debounce.js +11 -0
- package/dist/drawer-swipe.js +12 -101
- package/dist/escape.cjs +1 -0
- package/dist/escape.js +3 -17
- package/dist/focus-trap.cjs +3 -1
- package/dist/focus-trap.js +6 -72
- package/dist/hotkey.cjs +127 -0
- package/dist/hotkey.d.cts +31 -0
- package/dist/hotkey.d.ts +31 -0
- package/dist/hotkey.js +15 -0
- package/dist/index.cjs +613 -3
- package/dist/index.d.cts +14 -60
- package/dist/index.d.ts +14 -60
- package/dist/index.js +97 -247
- package/dist/media-query.cjs +90 -0
- package/dist/media-query.d.cts +12 -0
- package/dist/media-query.d.ts +12 -0
- package/dist/media-query.js +15 -0
- package/dist/outside-press.cjs +66 -0
- package/dist/outside-press.d.cts +15 -0
- package/dist/outside-press.d.ts +15 -0
- package/dist/outside-press.js +11 -0
- package/dist/scroll-lock.cjs +107 -0
- package/dist/scroll-lock.d.cts +8 -0
- package/dist/scroll-lock.d.ts +8 -0
- package/dist/scroll-lock.js +11 -0
- package/dist/storage-state.cjs +161 -0
- package/dist/storage-state.d.cts +14 -0
- package/dist/storage-state.d.ts +14 -0
- package/dist/storage-state.js +7 -0
- package/dist/unsaved-guard.cjs +48 -0
- package/dist/unsaved-guard.d.cts +5 -0
- package/dist/unsaved-guard.d.ts +5 -0
- package/dist/unsaved-guard.js +9 -0
- package/dist/visibility-polling.cjs +98 -0
- package/dist/visibility-polling.d.cts +14 -0
- package/dist/visibility-polling.d.ts +14 -0
- package/dist/visibility-polling.js +9 -0
- package/package.json +55 -2
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/outside-press/index.ts
|
|
22
|
+
var outside_press_exports = {};
|
|
23
|
+
__export(outside_press_exports, {
|
|
24
|
+
isOutside: () => isOutside,
|
|
25
|
+
isPrimaryPress: () => isPrimaryPress,
|
|
26
|
+
useOutsidePress: () => useOutsidePress
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(outside_press_exports);
|
|
29
|
+
|
|
30
|
+
// src/outside-press/outside-press.ts
|
|
31
|
+
function isOutside(target, elements) {
|
|
32
|
+
if (!target) return false;
|
|
33
|
+
if (!target.isConnected) return false;
|
|
34
|
+
return !elements.some((el) => el?.contains(target));
|
|
35
|
+
}
|
|
36
|
+
function isPrimaryPress(event) {
|
|
37
|
+
return !(event.pointerType === "mouse" && event.button !== 0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/outside-press/use-outside-press.ts
|
|
41
|
+
var import_react = require("react");
|
|
42
|
+
function useOutsidePress(refs, onOutsidePress, { enabled = true } = {}) {
|
|
43
|
+
const refsRef = (0, import_react.useRef)(refs);
|
|
44
|
+
const handlerRef = (0, import_react.useRef)(onOutsidePress);
|
|
45
|
+
(0, import_react.useEffect)(() => {
|
|
46
|
+
refsRef.current = refs;
|
|
47
|
+
handlerRef.current = onOutsidePress;
|
|
48
|
+
});
|
|
49
|
+
(0, import_react.useEffect)(() => {
|
|
50
|
+
if (!enabled) return;
|
|
51
|
+
function onPointerDown(event) {
|
|
52
|
+
if (!isPrimaryPress(event)) return;
|
|
53
|
+
const list = Array.isArray(refsRef.current) ? refsRef.current : [refsRef.current];
|
|
54
|
+
const elements = list.map((ref) => ref.current);
|
|
55
|
+
if (isOutside(event.target, elements)) handlerRef.current(event);
|
|
56
|
+
}
|
|
57
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
58
|
+
return () => document.removeEventListener("pointerdown", onPointerDown, true);
|
|
59
|
+
}, [enabled]);
|
|
60
|
+
}
|
|
61
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
62
|
+
0 && (module.exports = {
|
|
63
|
+
isOutside,
|
|
64
|
+
isPrimaryPress,
|
|
65
|
+
useOutsidePress
|
|
66
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
declare function isOutside(target: Node | null, elements: (Element | null)[]): boolean;
|
|
4
|
+
declare function isPrimaryPress(event: {
|
|
5
|
+
button?: number;
|
|
6
|
+
pointerType?: string;
|
|
7
|
+
}): boolean;
|
|
8
|
+
|
|
9
|
+
type ElementRef = RefObject<Element | null>;
|
|
10
|
+
interface UseOutsidePressOptions {
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare function useOutsidePress(refs: ElementRef | ElementRef[], onOutsidePress: (event: PointerEvent) => void, { enabled }?: UseOutsidePressOptions): void;
|
|
14
|
+
|
|
15
|
+
export { type UseOutsidePressOptions, isOutside, isPrimaryPress, useOutsidePress };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
declare function isOutside(target: Node | null, elements: (Element | null)[]): boolean;
|
|
4
|
+
declare function isPrimaryPress(event: {
|
|
5
|
+
button?: number;
|
|
6
|
+
pointerType?: string;
|
|
7
|
+
}): boolean;
|
|
8
|
+
|
|
9
|
+
type ElementRef = RefObject<Element | null>;
|
|
10
|
+
interface UseOutsidePressOptions {
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare function useOutsidePress(refs: ElementRef | ElementRef[], onOutsidePress: (event: PointerEvent) => void, { enabled }?: UseOutsidePressOptions): void;
|
|
14
|
+
|
|
15
|
+
export { type UseOutsidePressOptions, isOutside, isPrimaryPress, useOutsidePress };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/scroll-lock/index.ts
|
|
22
|
+
var scroll_lock_exports = {};
|
|
23
|
+
__export(scroll_lock_exports, {
|
|
24
|
+
lockScroll: () => lockScroll,
|
|
25
|
+
unlockScroll: () => unlockScroll,
|
|
26
|
+
useScrollLock: () => useScrollLock
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(scroll_lock_exports);
|
|
29
|
+
|
|
30
|
+
// src/scroll-lock/use-scroll-lock.ts
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
|
|
33
|
+
// src/scroll-lock/lock-styles.ts
|
|
34
|
+
var LOCKED_PROPERTIES = [
|
|
35
|
+
"position",
|
|
36
|
+
"top",
|
|
37
|
+
"left",
|
|
38
|
+
"right",
|
|
39
|
+
"width",
|
|
40
|
+
"overflow",
|
|
41
|
+
"paddingRight"
|
|
42
|
+
];
|
|
43
|
+
function computeLockStyles({ scrollY, scrollbarWidth, existingPaddingRight }) {
|
|
44
|
+
const styles = {
|
|
45
|
+
position: "fixed",
|
|
46
|
+
top: `-${scrollY}px`,
|
|
47
|
+
left: "0",
|
|
48
|
+
right: "0",
|
|
49
|
+
width: "100%",
|
|
50
|
+
overflow: "hidden"
|
|
51
|
+
};
|
|
52
|
+
if (scrollbarWidth > 0) styles.paddingRight = `${existingPaddingRight + scrollbarWidth}px`;
|
|
53
|
+
return styles;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/scroll-lock/scroll-lock.ts
|
|
57
|
+
var count = 0;
|
|
58
|
+
var saved = null;
|
|
59
|
+
function applyFirstLock() {
|
|
60
|
+
const { body, documentElement } = document;
|
|
61
|
+
const inline = {};
|
|
62
|
+
for (const property of LOCKED_PROPERTIES) inline[property] = body.style[property];
|
|
63
|
+
saved = { scrollY: window.scrollY, inline };
|
|
64
|
+
const styles = computeLockStyles({
|
|
65
|
+
scrollY: saved.scrollY,
|
|
66
|
+
scrollbarWidth: Math.max(0, window.innerWidth - documentElement.clientWidth),
|
|
67
|
+
existingPaddingRight: parseFloat(getComputedStyle(body).paddingRight) || 0
|
|
68
|
+
});
|
|
69
|
+
Object.assign(body.style, styles);
|
|
70
|
+
}
|
|
71
|
+
function restoreLastLock() {
|
|
72
|
+
if (!saved) return;
|
|
73
|
+
const { scrollY, inline } = saved;
|
|
74
|
+
saved = null;
|
|
75
|
+
Object.assign(document.body.style, inline);
|
|
76
|
+
window.scrollTo(0, scrollY);
|
|
77
|
+
}
|
|
78
|
+
function lockScroll() {
|
|
79
|
+
if (count === 0) applyFirstLock();
|
|
80
|
+
count += 1;
|
|
81
|
+
let released = false;
|
|
82
|
+
return () => {
|
|
83
|
+
if (released) return;
|
|
84
|
+
released = true;
|
|
85
|
+
count -= 1;
|
|
86
|
+
if (count === 0) restoreLastLock();
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function unlockScroll() {
|
|
90
|
+
if (count === 0) return;
|
|
91
|
+
count -= 1;
|
|
92
|
+
if (count === 0) restoreLastLock();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/scroll-lock/use-scroll-lock.ts
|
|
96
|
+
function useScrollLock(active = true) {
|
|
97
|
+
(0, import_react.useEffect)(() => {
|
|
98
|
+
if (!active) return;
|
|
99
|
+
return lockScroll();
|
|
100
|
+
}, [active]);
|
|
101
|
+
}
|
|
102
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
103
|
+
0 && (module.exports = {
|
|
104
|
+
lockScroll,
|
|
105
|
+
unlockScroll,
|
|
106
|
+
useScrollLock
|
|
107
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare function useScrollLock(active?: boolean): void;
|
|
2
|
+
|
|
3
|
+
/** Locks page scroll. Locks are counted; the returned release is safe to call twice. */
|
|
4
|
+
declare function lockScroll(): () => void;
|
|
5
|
+
/** Releases one lock taken with `lockScroll()` that was not released through its own function. */
|
|
6
|
+
declare function unlockScroll(): void;
|
|
7
|
+
|
|
8
|
+
export { lockScroll, unlockScroll, useScrollLock };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare function useScrollLock(active?: boolean): void;
|
|
2
|
+
|
|
3
|
+
/** Locks page scroll. Locks are counted; the returned release is safe to call twice. */
|
|
4
|
+
declare function lockScroll(): () => void;
|
|
5
|
+
/** Releases one lock taken with `lockScroll()` that was not released through its own function. */
|
|
6
|
+
declare function unlockScroll(): void;
|
|
7
|
+
|
|
8
|
+
export { lockScroll, unlockScroll, useScrollLock };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/storage-state/index.ts
|
|
22
|
+
var storage_state_exports = {};
|
|
23
|
+
__export(storage_state_exports, {
|
|
24
|
+
useStorageState: () => useStorageState
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(storage_state_exports);
|
|
27
|
+
|
|
28
|
+
// src/storage-state/use-storage-state.ts
|
|
29
|
+
var import_react = require("react");
|
|
30
|
+
|
|
31
|
+
// src/storage-state/storage-store.ts
|
|
32
|
+
function getStorage(kind) {
|
|
33
|
+
try {
|
|
34
|
+
if (typeof window === "undefined") return null;
|
|
35
|
+
return kind === "session" ? window.sessionStorage : window.localStorage;
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function readRaw(storage, key) {
|
|
41
|
+
try {
|
|
42
|
+
return storage ? storage.getItem(key) : null;
|
|
43
|
+
} catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function writeRaw(storage, key, value) {
|
|
48
|
+
try {
|
|
49
|
+
if (!storage) return false;
|
|
50
|
+
storage.setItem(key, value);
|
|
51
|
+
return true;
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function removeRaw(storage, key) {
|
|
57
|
+
try {
|
|
58
|
+
if (!storage) return false;
|
|
59
|
+
storage.removeItem(key);
|
|
60
|
+
return true;
|
|
61
|
+
} catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function parseOr(raw, parse, fallback) {
|
|
66
|
+
if (raw === null) return fallback;
|
|
67
|
+
try {
|
|
68
|
+
return parse(raw);
|
|
69
|
+
} catch {
|
|
70
|
+
return fallback;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
var slot = (kind, key) => `${kind}\0${key}`;
|
|
74
|
+
var memory = /* @__PURE__ */ new Map();
|
|
75
|
+
var listeners = /* @__PURE__ */ new Map();
|
|
76
|
+
function readCurrent(kind, key) {
|
|
77
|
+
const held = memory.get(slot(kind, key));
|
|
78
|
+
if (held !== void 0) return held;
|
|
79
|
+
return readRaw(getStorage(kind), key);
|
|
80
|
+
}
|
|
81
|
+
function notify(id) {
|
|
82
|
+
for (const listener of [...listeners.get(id) ?? []]) listener();
|
|
83
|
+
}
|
|
84
|
+
function writeCurrent(kind, key, raw) {
|
|
85
|
+
const id = slot(kind, key);
|
|
86
|
+
if (writeRaw(getStorage(kind), key, raw)) memory.delete(id);
|
|
87
|
+
else memory.set(id, raw);
|
|
88
|
+
notify(id);
|
|
89
|
+
}
|
|
90
|
+
function removeCurrent(kind, key) {
|
|
91
|
+
const id = slot(kind, key);
|
|
92
|
+
if (removeRaw(getStorage(kind), key)) memory.delete(id);
|
|
93
|
+
else memory.set(id, null);
|
|
94
|
+
notify(id);
|
|
95
|
+
}
|
|
96
|
+
function onStorageEvent(event) {
|
|
97
|
+
const kinds = [];
|
|
98
|
+
if (!event.storageArea || event.storageArea === getStorage("local")) kinds.push("local");
|
|
99
|
+
if (!event.storageArea || event.storageArea === getStorage("session")) kinds.push("session");
|
|
100
|
+
for (const id of [...listeners.keys()]) {
|
|
101
|
+
const [kind, key] = id.split("\0");
|
|
102
|
+
if (!kinds.includes(kind)) continue;
|
|
103
|
+
if (event.key !== null && event.key !== key) continue;
|
|
104
|
+
memory.delete(id);
|
|
105
|
+
notify(id);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function subscribeToKey(kind, key, listener) {
|
|
109
|
+
const id = slot(kind, key);
|
|
110
|
+
const wasEmpty = listeners.size === 0;
|
|
111
|
+
let set = listeners.get(id);
|
|
112
|
+
if (!set) listeners.set(id, set = /* @__PURE__ */ new Set());
|
|
113
|
+
set.add(listener);
|
|
114
|
+
if (wasEmpty) window.addEventListener("storage", onStorageEvent);
|
|
115
|
+
return () => {
|
|
116
|
+
const current = listeners.get(id);
|
|
117
|
+
current?.delete(listener);
|
|
118
|
+
if (current?.size === 0) listeners.delete(id);
|
|
119
|
+
if (listeners.size === 0) window.removeEventListener("storage", onStorageEvent);
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/storage-state/use-storage-state.ts
|
|
124
|
+
function useStorageState(key, defaultValue, options = {}) {
|
|
125
|
+
const kind = options.storage ?? "local";
|
|
126
|
+
const serialize = options.serialize ?? JSON.stringify;
|
|
127
|
+
const parse = options.parse ?? JSON.parse;
|
|
128
|
+
const latest = (0, import_react.useRef)({ serialize, parse, defaultValue });
|
|
129
|
+
(0, import_react.useEffect)(() => {
|
|
130
|
+
latest.current = { serialize, parse, defaultValue };
|
|
131
|
+
});
|
|
132
|
+
const cache = (0, import_react.useRef)(null);
|
|
133
|
+
const subscribe = (0, import_react.useCallback)((onChange) => subscribeToKey(kind, key, onChange), [kind, key]);
|
|
134
|
+
const getSnapshot = (0, import_react.useCallback)(() => {
|
|
135
|
+
const raw = readCurrent(kind, key);
|
|
136
|
+
const hit = cache.current;
|
|
137
|
+
if (hit && hit.kind === kind && hit.key === key && hit.raw === raw && hit.parse === parse) return hit.value;
|
|
138
|
+
const value2 = parseOr(raw, parse, defaultValue);
|
|
139
|
+
cache.current = { kind, key, raw, parse, value: value2 };
|
|
140
|
+
return value2;
|
|
141
|
+
}, [kind, key, parse, defaultValue]);
|
|
142
|
+
const getServerSnapshot = (0, import_react.useCallback)(() => defaultValue, [defaultValue]);
|
|
143
|
+
const value = (0, import_react.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
|
|
144
|
+
const set = (0, import_react.useCallback)(
|
|
145
|
+
(next) => {
|
|
146
|
+
const { serialize: encode, parse: decode, defaultValue: fallback } = latest.current;
|
|
147
|
+
try {
|
|
148
|
+
const resolved = typeof next === "function" ? next(parseOr(readCurrent(kind, key), decode, fallback)) : next;
|
|
149
|
+
writeCurrent(kind, key, encode(resolved));
|
|
150
|
+
} catch {
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
[kind, key]
|
|
154
|
+
);
|
|
155
|
+
const remove = (0, import_react.useCallback)(() => removeCurrent(kind, key), [kind, key]);
|
|
156
|
+
return [value, set, remove];
|
|
157
|
+
}
|
|
158
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
159
|
+
0 && (module.exports = {
|
|
160
|
+
useStorageState
|
|
161
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type StorageKind = 'local' | 'session';
|
|
2
|
+
|
|
3
|
+
interface UseStorageStateOptions<T> {
|
|
4
|
+
/** `'local'` (default) or `'session'`. */
|
|
5
|
+
storage?: StorageKind;
|
|
6
|
+
/** Default `JSON.stringify`. */
|
|
7
|
+
serialize?: (value: T) => string;
|
|
8
|
+
/** Default `JSON.parse`. A throw returns `defaultValue`. */
|
|
9
|
+
parse?: (raw: string) => T;
|
|
10
|
+
}
|
|
11
|
+
type StorageStateSetter<T> = (next: T | ((prev: T) => T)) => void;
|
|
12
|
+
declare function useStorageState<T>(key: string, defaultValue: T, options?: UseStorageStateOptions<T>): readonly [T, StorageStateSetter<T>, () => void];
|
|
13
|
+
|
|
14
|
+
export { type StorageKind, type StorageStateSetter, type UseStorageStateOptions, useStorageState };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type StorageKind = 'local' | 'session';
|
|
2
|
+
|
|
3
|
+
interface UseStorageStateOptions<T> {
|
|
4
|
+
/** `'local'` (default) or `'session'`. */
|
|
5
|
+
storage?: StorageKind;
|
|
6
|
+
/** Default `JSON.stringify`. */
|
|
7
|
+
serialize?: (value: T) => string;
|
|
8
|
+
/** Default `JSON.parse`. A throw returns `defaultValue`. */
|
|
9
|
+
parse?: (raw: string) => T;
|
|
10
|
+
}
|
|
11
|
+
type StorageStateSetter<T> = (next: T | ((prev: T) => T)) => void;
|
|
12
|
+
declare function useStorageState<T>(key: string, defaultValue: T, options?: UseStorageStateOptions<T>): readonly [T, StorageStateSetter<T>, () => void];
|
|
13
|
+
|
|
14
|
+
export { type StorageKind, type StorageStateSetter, type UseStorageStateOptions, useStorageState };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/unsaved-guard/index.ts
|
|
22
|
+
var unsaved_guard_exports = {};
|
|
23
|
+
__export(unsaved_guard_exports, {
|
|
24
|
+
handleBeforeUnload: () => handleBeforeUnload,
|
|
25
|
+
useUnsavedChangesGuard: () => useUnsavedChangesGuard
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(unsaved_guard_exports);
|
|
28
|
+
|
|
29
|
+
// src/unsaved-guard/handle-before-unload.ts
|
|
30
|
+
function handleBeforeUnload(event) {
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
event.returnValue = "";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/unsaved-guard/use-unsaved-changes-guard.ts
|
|
36
|
+
var import_react = require("react");
|
|
37
|
+
function useUnsavedChangesGuard(dirty) {
|
|
38
|
+
(0, import_react.useEffect)(() => {
|
|
39
|
+
if (!dirty) return;
|
|
40
|
+
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
41
|
+
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
42
|
+
}, [dirty]);
|
|
43
|
+
}
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
handleBeforeUnload,
|
|
47
|
+
useUnsavedChangesGuard
|
|
48
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/visibility-polling/index.ts
|
|
22
|
+
var visibility_polling_exports = {};
|
|
23
|
+
__export(visibility_polling_exports, {
|
|
24
|
+
nextDelay: () => nextDelay,
|
|
25
|
+
useVisibilityPolling: () => useVisibilityPolling
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(visibility_polling_exports);
|
|
28
|
+
|
|
29
|
+
// src/visibility-polling/schedule.ts
|
|
30
|
+
function nextDelay(intervalMs, jitter, random) {
|
|
31
|
+
const fraction = Math.min(1, Math.max(0, jitter));
|
|
32
|
+
return intervalMs + random() * fraction * intervalMs;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/visibility-polling/use-visibility-polling.ts
|
|
36
|
+
var import_react = require("react");
|
|
37
|
+
var isHidden = () => document.visibilityState === "hidden";
|
|
38
|
+
function useVisibilityPolling(fn, intervalMs, { enabled = true, immediate = true, jitter = 0, runOnVisible = true } = {}) {
|
|
39
|
+
const fnRef = (0, import_react.useRef)(fn);
|
|
40
|
+
const optionsRef = (0, import_react.useRef)({ immediate, jitter, runOnVisible });
|
|
41
|
+
(0, import_react.useEffect)(() => {
|
|
42
|
+
fnRef.current = fn;
|
|
43
|
+
optionsRef.current = { immediate, jitter, runOnVisible };
|
|
44
|
+
});
|
|
45
|
+
const runningRef = (0, import_react.useRef)(false);
|
|
46
|
+
const scheduleRef = (0, import_react.useRef)(null);
|
|
47
|
+
(0, import_react.useEffect)(() => {
|
|
48
|
+
if (!enabled) return;
|
|
49
|
+
let active = true;
|
|
50
|
+
let timer = null;
|
|
51
|
+
function clearTimer() {
|
|
52
|
+
if (timer !== null) clearTimeout(timer);
|
|
53
|
+
timer = null;
|
|
54
|
+
}
|
|
55
|
+
function schedule() {
|
|
56
|
+
clearTimer();
|
|
57
|
+
if (!active || isHidden()) return;
|
|
58
|
+
timer = setTimeout(run, nextDelay(intervalMs, optionsRef.current.jitter, Math.random));
|
|
59
|
+
}
|
|
60
|
+
async function run() {
|
|
61
|
+
timer = null;
|
|
62
|
+
if (!active || runningRef.current || isHidden()) return;
|
|
63
|
+
runningRef.current = true;
|
|
64
|
+
try {
|
|
65
|
+
await fnRef.current();
|
|
66
|
+
} catch {
|
|
67
|
+
} finally {
|
|
68
|
+
runningRef.current = false;
|
|
69
|
+
}
|
|
70
|
+
scheduleRef.current?.();
|
|
71
|
+
}
|
|
72
|
+
function onVisibilityChange() {
|
|
73
|
+
if (isHidden()) {
|
|
74
|
+
clearTimer();
|
|
75
|
+
} else if (optionsRef.current.runOnVisible) {
|
|
76
|
+
clearTimer();
|
|
77
|
+
void run();
|
|
78
|
+
} else if (!runningRef.current) {
|
|
79
|
+
schedule();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
scheduleRef.current = schedule;
|
|
83
|
+
if (optionsRef.current.immediate && !isHidden()) void run();
|
|
84
|
+
else schedule();
|
|
85
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
86
|
+
return () => {
|
|
87
|
+
active = false;
|
|
88
|
+
scheduleRef.current = null;
|
|
89
|
+
clearTimer();
|
|
90
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
91
|
+
};
|
|
92
|
+
}, [enabled, intervalMs]);
|
|
93
|
+
}
|
|
94
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
95
|
+
0 && (module.exports = {
|
|
96
|
+
nextDelay,
|
|
97
|
+
useVisibilityPolling
|
|
98
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare function nextDelay(intervalMs: number, jitter: number, random: () => number): number;
|
|
2
|
+
|
|
3
|
+
interface UseVisibilityPollingOptions {
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
/** Run once on mount (when visible) before the first interval. */
|
|
6
|
+
immediate?: boolean;
|
|
7
|
+
/** 0–1 fraction of the interval added at random to each delay. */
|
|
8
|
+
jitter?: number;
|
|
9
|
+
/** Run once as soon as the page becomes visible again. */
|
|
10
|
+
runOnVisible?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare function useVisibilityPolling(fn: () => unknown, intervalMs: number, { enabled, immediate, jitter, runOnVisible }?: UseVisibilityPollingOptions): void;
|
|
13
|
+
|
|
14
|
+
export { type UseVisibilityPollingOptions, nextDelay, useVisibilityPolling };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare function nextDelay(intervalMs: number, jitter: number, random: () => number): number;
|
|
2
|
+
|
|
3
|
+
interface UseVisibilityPollingOptions {
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
/** Run once on mount (when visible) before the first interval. */
|
|
6
|
+
immediate?: boolean;
|
|
7
|
+
/** 0–1 fraction of the interval added at random to each delay. */
|
|
8
|
+
jitter?: number;
|
|
9
|
+
/** Run once as soon as the page becomes visible again. */
|
|
10
|
+
runOnVisible?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare function useVisibilityPolling(fn: () => unknown, intervalMs: number, { enabled, immediate, jitter, runOnVisible }?: UseVisibilityPollingOptions): void;
|
|
13
|
+
|
|
14
|
+
export { type UseVisibilityPollingOptions, nextDelay, useVisibilityPolling };
|