@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
package/dist/index.d.cts
CHANGED
|
@@ -1,60 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
declare function isInOpenZone(x: number, viewportWidth: number): boolean;
|
|
16
|
-
declare function resolveSwipeIntent(start: SwipePoint, end: SwipePoint, drawerOpen: boolean, viewportWidth: number): SwipeIntent;
|
|
17
|
-
declare function isInsideHorizontalScroller(target: EventTarget | null): boolean;
|
|
18
|
-
|
|
19
|
-
type UseDrawerSwipeOptions = {
|
|
20
|
-
drawerOpen: boolean;
|
|
21
|
-
onOpen: () => void;
|
|
22
|
-
onClose: () => void;
|
|
23
|
-
enabled?: boolean;
|
|
24
|
-
maxViewportWidth?: number;
|
|
25
|
-
};
|
|
26
|
-
declare function useDrawerSwipe({ drawerOpen, onOpen, onClose, enabled, maxViewportWidth, }: UseDrawerSwipeOptions): void;
|
|
27
|
-
|
|
28
|
-
declare const FOCUSABLE_SELECTOR = "a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
|
|
29
|
-
declare function focusableWithin(container: HTMLElement): HTMLElement[];
|
|
30
|
-
/** The element Tab must be redirected to, or null when the browser's own move is fine. */
|
|
31
|
-
declare function nextFocusTarget(items: HTMLElement[], current: Element | null, shiftKey: boolean, container: HTMLElement): HTMLElement | null;
|
|
32
|
-
|
|
33
|
-
type UseFocusTrapOptions = {
|
|
34
|
-
active: boolean;
|
|
35
|
-
initialFocusRef?: RefObject<HTMLElement | null>;
|
|
36
|
-
/** Wins over the captured opener. Safari leaves <body> focused after a tap on a button. */
|
|
37
|
-
returnFocusRef?: RefObject<HTMLElement | null>;
|
|
38
|
-
restoreFocus?: boolean;
|
|
39
|
-
};
|
|
40
|
-
declare function useFocusTrap(containerRef: RefObject<HTMLElement | null>, { active, initialFocusRef, returnFocusRef, restoreFocus, }: UseFocusTrapOptions): void;
|
|
41
|
-
|
|
42
|
-
declare function useEscape(onEscape: () => void, active?: boolean): void;
|
|
43
|
-
|
|
44
|
-
type CopyResult = {
|
|
45
|
-
ok: true;
|
|
46
|
-
} | {
|
|
47
|
-
ok: false;
|
|
48
|
-
reason: 'unavailable' | 'denied';
|
|
49
|
-
};
|
|
50
|
-
declare function copyText(text: string): Promise<CopyResult>;
|
|
51
|
-
|
|
52
|
-
type CopyStatus = 'idle' | 'copied' | 'failed';
|
|
53
|
-
declare function useCopyFeedback({ resetMs }?: {
|
|
54
|
-
resetMs?: number;
|
|
55
|
-
}): {
|
|
56
|
-
copy: (text: string) => Promise<CopyResult>;
|
|
57
|
-
status: CopyStatus;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export { BACK_ZONE_PX, CLOSE_DISTANCE_PX, type CopyResult, type CopyStatus, FOCUSABLE_SELECTOR, FORWARD_ZONE_PX, MAX_SWIPE_DURATION_MS, OPEN_DISTANCE_PX, type SwipeIntent, type SwipePoint, type UseDrawerSwipeOptions, type UseFocusTrapOptions, VERTICAL_CANCEL_PX, copyText, focusableWithin, isInOpenZone, isInsideHorizontalScroller, nextFocusTarget, resolveSwipeIntent, useCopyFeedback, useDrawerSwipe, useEscape, useFocusTrap };
|
|
1
|
+
export { BACK_ZONE_PX, CLOSE_DISTANCE_PX, FORWARD_ZONE_PX, MAX_SWIPE_DURATION_MS, OPEN_DISTANCE_PX, SwipeIntent, SwipePoint, UseDrawerSwipeOptions, VERTICAL_CANCEL_PX, isInOpenZone, isInsideHorizontalScroller, resolveSwipeIntent, useDrawerSwipe } from './drawer-swipe.cjs';
|
|
2
|
+
export { FOCUSABLE_SELECTOR, UseFocusTrapOptions, focusableWithin, nextFocusTarget, useFocusTrap } from './focus-trap.cjs';
|
|
3
|
+
export { useEscape } from './escape.cjs';
|
|
4
|
+
export { CopyResult, CopyStatus, copyText, useCopyFeedback } from './clipboard.cjs';
|
|
5
|
+
export { lockScroll, unlockScroll, useScrollLock } from './scroll-lock.cjs';
|
|
6
|
+
export { COARSE_POINTER_QUERY, REDUCED_MOTION_QUERY, UseMediaQueryOptions, useCoarsePointer, useMediaQuery, useReducedMotion } from './media-query.cjs';
|
|
7
|
+
export { UseOutsidePressOptions, isOutside, isPrimaryPress, useOutsidePress } from './outside-press.cjs';
|
|
8
|
+
export { UseVisibilityPollingOptions, nextDelay, useVisibilityPolling } from './visibility-polling.cjs';
|
|
9
|
+
export { DebouncedCallback, Debouncer, createDebouncer, useDebouncedCallback, useDebouncedValue } from './debounce.cjs';
|
|
10
|
+
export { StorageKind, StorageStateSetter, UseStorageStateOptions, useStorageState } from './storage-state.cjs';
|
|
11
|
+
export { handleBeforeUnload, useUnsavedChangesGuard } from './unsaved-guard.cjs';
|
|
12
|
+
export { ParsedHotkey, UseHotkeyOptions, detectApple, isEditableTarget, matchHotkey, parseHotkey, useHotkey } from './hotkey.cjs';
|
|
13
|
+
export { NextHeight, UseAutoGrowTextareaOptions, nextHeight, useAutoGrowTextarea } from './auto-grow.cjs';
|
|
14
|
+
import 'react';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,60 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
declare function isInOpenZone(x: number, viewportWidth: number): boolean;
|
|
16
|
-
declare function resolveSwipeIntent(start: SwipePoint, end: SwipePoint, drawerOpen: boolean, viewportWidth: number): SwipeIntent;
|
|
17
|
-
declare function isInsideHorizontalScroller(target: EventTarget | null): boolean;
|
|
18
|
-
|
|
19
|
-
type UseDrawerSwipeOptions = {
|
|
20
|
-
drawerOpen: boolean;
|
|
21
|
-
onOpen: () => void;
|
|
22
|
-
onClose: () => void;
|
|
23
|
-
enabled?: boolean;
|
|
24
|
-
maxViewportWidth?: number;
|
|
25
|
-
};
|
|
26
|
-
declare function useDrawerSwipe({ drawerOpen, onOpen, onClose, enabled, maxViewportWidth, }: UseDrawerSwipeOptions): void;
|
|
27
|
-
|
|
28
|
-
declare const FOCUSABLE_SELECTOR = "a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
|
|
29
|
-
declare function focusableWithin(container: HTMLElement): HTMLElement[];
|
|
30
|
-
/** The element Tab must be redirected to, or null when the browser's own move is fine. */
|
|
31
|
-
declare function nextFocusTarget(items: HTMLElement[], current: Element | null, shiftKey: boolean, container: HTMLElement): HTMLElement | null;
|
|
32
|
-
|
|
33
|
-
type UseFocusTrapOptions = {
|
|
34
|
-
active: boolean;
|
|
35
|
-
initialFocusRef?: RefObject<HTMLElement | null>;
|
|
36
|
-
/** Wins over the captured opener. Safari leaves <body> focused after a tap on a button. */
|
|
37
|
-
returnFocusRef?: RefObject<HTMLElement | null>;
|
|
38
|
-
restoreFocus?: boolean;
|
|
39
|
-
};
|
|
40
|
-
declare function useFocusTrap(containerRef: RefObject<HTMLElement | null>, { active, initialFocusRef, returnFocusRef, restoreFocus, }: UseFocusTrapOptions): void;
|
|
41
|
-
|
|
42
|
-
declare function useEscape(onEscape: () => void, active?: boolean): void;
|
|
43
|
-
|
|
44
|
-
type CopyResult = {
|
|
45
|
-
ok: true;
|
|
46
|
-
} | {
|
|
47
|
-
ok: false;
|
|
48
|
-
reason: 'unavailable' | 'denied';
|
|
49
|
-
};
|
|
50
|
-
declare function copyText(text: string): Promise<CopyResult>;
|
|
51
|
-
|
|
52
|
-
type CopyStatus = 'idle' | 'copied' | 'failed';
|
|
53
|
-
declare function useCopyFeedback({ resetMs }?: {
|
|
54
|
-
resetMs?: number;
|
|
55
|
-
}): {
|
|
56
|
-
copy: (text: string) => Promise<CopyResult>;
|
|
57
|
-
status: CopyStatus;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export { BACK_ZONE_PX, CLOSE_DISTANCE_PX, type CopyResult, type CopyStatus, FOCUSABLE_SELECTOR, FORWARD_ZONE_PX, MAX_SWIPE_DURATION_MS, OPEN_DISTANCE_PX, type SwipeIntent, type SwipePoint, type UseDrawerSwipeOptions, type UseFocusTrapOptions, VERTICAL_CANCEL_PX, copyText, focusableWithin, isInOpenZone, isInsideHorizontalScroller, nextFocusTarget, resolveSwipeIntent, useCopyFeedback, useDrawerSwipe, useEscape, useFocusTrap };
|
|
1
|
+
export { BACK_ZONE_PX, CLOSE_DISTANCE_PX, FORWARD_ZONE_PX, MAX_SWIPE_DURATION_MS, OPEN_DISTANCE_PX, SwipeIntent, SwipePoint, UseDrawerSwipeOptions, VERTICAL_CANCEL_PX, isInOpenZone, isInsideHorizontalScroller, resolveSwipeIntent, useDrawerSwipe } from './drawer-swipe.js';
|
|
2
|
+
export { FOCUSABLE_SELECTOR, UseFocusTrapOptions, focusableWithin, nextFocusTarget, useFocusTrap } from './focus-trap.js';
|
|
3
|
+
export { useEscape } from './escape.js';
|
|
4
|
+
export { CopyResult, CopyStatus, copyText, useCopyFeedback } from './clipboard.js';
|
|
5
|
+
export { lockScroll, unlockScroll, useScrollLock } from './scroll-lock.js';
|
|
6
|
+
export { COARSE_POINTER_QUERY, REDUCED_MOTION_QUERY, UseMediaQueryOptions, useCoarsePointer, useMediaQuery, useReducedMotion } from './media-query.js';
|
|
7
|
+
export { UseOutsidePressOptions, isOutside, isPrimaryPress, useOutsidePress } from './outside-press.js';
|
|
8
|
+
export { UseVisibilityPollingOptions, nextDelay, useVisibilityPolling } from './visibility-polling.js';
|
|
9
|
+
export { DebouncedCallback, Debouncer, createDebouncer, useDebouncedCallback, useDebouncedValue } from './debounce.js';
|
|
10
|
+
export { StorageKind, StorageStateSetter, UseStorageStateOptions, useStorageState } from './storage-state.js';
|
|
11
|
+
export { handleBeforeUnload, useUnsavedChangesGuard } from './unsaved-guard.js';
|
|
12
|
+
export { ParsedHotkey, UseHotkeyOptions, detectApple, isEditableTarget, matchHotkey, parseHotkey, useHotkey } from './hotkey.js';
|
|
13
|
+
export { NextHeight, UseAutoGrowTextareaOptions, nextHeight, useAutoGrowTextarea } from './auto-grow.js';
|
|
14
|
+
import 'react';
|
package/dist/index.js
CHANGED
|
@@ -1,265 +1,115 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
function handleEnd(event) {
|
|
72
|
-
const origin = start.current;
|
|
73
|
-
start.current = null;
|
|
74
|
-
const touch = event.changedTouches[0];
|
|
75
|
-
if (!origin || !touch) return;
|
|
76
|
-
const { drawerOpen: drawerOpen2, onOpen: onOpen2, onClose: onClose2 } = handlers.current;
|
|
77
|
-
const intent = resolveSwipeIntent(
|
|
78
|
-
origin,
|
|
79
|
-
{ x: touch.clientX, y: touch.clientY, time: Date.now() },
|
|
80
|
-
drawerOpen2,
|
|
81
|
-
window.innerWidth
|
|
82
|
-
);
|
|
83
|
-
if (intent === "open") onOpen2();
|
|
84
|
-
if (intent === "close") onClose2();
|
|
85
|
-
}
|
|
86
|
-
function handleCancel() {
|
|
87
|
-
start.current = null;
|
|
88
|
-
}
|
|
89
|
-
document.addEventListener("touchstart", handleStart, { passive: true });
|
|
90
|
-
document.addEventListener("touchmove", handleMove, { passive: true });
|
|
91
|
-
document.addEventListener("touchend", handleEnd, { passive: true });
|
|
92
|
-
document.addEventListener("touchcancel", handleCancel, { passive: true });
|
|
93
|
-
return () => {
|
|
94
|
-
document.removeEventListener("touchstart", handleStart);
|
|
95
|
-
document.removeEventListener("touchmove", handleMove);
|
|
96
|
-
document.removeEventListener("touchend", handleEnd);
|
|
97
|
-
document.removeEventListener("touchcancel", handleCancel);
|
|
98
|
-
};
|
|
99
|
-
}, [enabled]);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// src/focus-trap/focusables.ts
|
|
103
|
-
var FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
104
|
-
function focusableWithin(container) {
|
|
105
|
-
return Array.from(
|
|
106
|
-
container.querySelectorAll(FOCUSABLE_SELECTOR)
|
|
107
|
-
).filter((el) => !el.closest("[hidden], [inert]"));
|
|
108
|
-
}
|
|
109
|
-
function nextFocusTarget(items, current, shiftKey, container) {
|
|
110
|
-
const first = items[0];
|
|
111
|
-
const last = items[items.length - 1];
|
|
112
|
-
if (!first || !last) return null;
|
|
113
|
-
if (!current || !container.contains(current)) return shiftKey ? last : first;
|
|
114
|
-
if (shiftKey && (current === first || current === container)) return last;
|
|
115
|
-
if (!shiftKey && current === last) return first;
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// src/focus-trap/use-focus-trap.ts
|
|
120
|
-
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
121
|
-
var activeTraps = [];
|
|
122
|
-
function useFocusTrap(containerRef, {
|
|
123
|
-
active,
|
|
124
|
-
initialFocusRef,
|
|
125
|
-
returnFocusRef,
|
|
126
|
-
restoreFocus = true
|
|
127
|
-
}) {
|
|
128
|
-
const openerRef = useRef2(null);
|
|
129
|
-
if (active && !openerRef.current && typeof document !== "undefined") {
|
|
130
|
-
openerRef.current = document.activeElement;
|
|
131
|
-
}
|
|
132
|
-
useEffect2(() => {
|
|
133
|
-
const container = containerRef.current;
|
|
134
|
-
if (!active || !container) return;
|
|
135
|
-
const token = {};
|
|
136
|
-
activeTraps.push(token);
|
|
137
|
-
if (!container.contains(document.activeElement)) {
|
|
138
|
-
const target = initialFocusRef?.current ?? focusableWithin(container)[0] ?? container;
|
|
139
|
-
if (target === container && !container.hasAttribute("tabindex")) {
|
|
140
|
-
container.setAttribute("tabindex", "-1");
|
|
141
|
-
}
|
|
142
|
-
target.focus();
|
|
143
|
-
}
|
|
144
|
-
function onKeyDown(event) {
|
|
145
|
-
if (event.key !== "Tab" || !container) return;
|
|
146
|
-
if (activeTraps[activeTraps.length - 1] !== token) return;
|
|
147
|
-
const items = focusableWithin(container);
|
|
148
|
-
if (items.length === 0) {
|
|
149
|
-
event.preventDefault();
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
const target = nextFocusTarget(
|
|
153
|
-
items,
|
|
154
|
-
document.activeElement,
|
|
155
|
-
event.shiftKey,
|
|
156
|
-
container
|
|
157
|
-
);
|
|
158
|
-
if (target) {
|
|
159
|
-
event.preventDefault();
|
|
160
|
-
target.focus();
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
document.addEventListener("keydown", onKeyDown);
|
|
164
|
-
return () => {
|
|
165
|
-
document.removeEventListener("keydown", onKeyDown);
|
|
166
|
-
activeTraps.splice(activeTraps.indexOf(token), 1);
|
|
167
|
-
const opener = returnFocusRef?.current ?? openerRef.current;
|
|
168
|
-
openerRef.current = null;
|
|
169
|
-
if (restoreFocus && opener?.isConnected) opener.focus();
|
|
170
|
-
};
|
|
171
|
-
}, [active, containerRef, initialFocusRef, returnFocusRef, restoreFocus]);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// src/escape/use-escape.ts
|
|
175
|
-
import { useEffect as useEffect3, useRef as useRef3 } from "react";
|
|
176
|
-
function useEscape(onEscape, active = true) {
|
|
177
|
-
const handlerRef = useRef3(onEscape);
|
|
178
|
-
useEffect3(() => {
|
|
179
|
-
handlerRef.current = onEscape;
|
|
180
|
-
});
|
|
181
|
-
useEffect3(() => {
|
|
182
|
-
if (!active) return;
|
|
183
|
-
function onKeyDown(event) {
|
|
184
|
-
if (event.key === "Escape") handlerRef.current();
|
|
185
|
-
}
|
|
186
|
-
document.addEventListener("keydown", onKeyDown);
|
|
187
|
-
return () => document.removeEventListener("keydown", onKeyDown);
|
|
188
|
-
}, [active]);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// src/clipboard/copy-text.ts
|
|
192
|
-
async function copyText(text) {
|
|
193
|
-
const hasClipboardApi = typeof navigator !== "undefined" && !!navigator.clipboard?.writeText && typeof window !== "undefined" && window.isSecureContext;
|
|
194
|
-
if (hasClipboardApi) {
|
|
195
|
-
try {
|
|
196
|
-
await navigator.clipboard.writeText(text);
|
|
197
|
-
return { ok: true };
|
|
198
|
-
} catch {
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
if (execCommandCopy(text)) return { ok: true };
|
|
202
|
-
return { ok: false, reason: hasClipboardApi ? "denied" : "unavailable" };
|
|
203
|
-
}
|
|
204
|
-
function execCommandCopy(text) {
|
|
205
|
-
if (typeof document === "undefined") return false;
|
|
206
|
-
const textarea = document.createElement("textarea");
|
|
207
|
-
textarea.value = text;
|
|
208
|
-
textarea.readOnly = true;
|
|
209
|
-
textarea.style.position = "fixed";
|
|
210
|
-
textarea.style.top = "-1000px";
|
|
211
|
-
textarea.style.left = "-1000px";
|
|
212
|
-
textarea.style.fontSize = "16px";
|
|
213
|
-
document.body.appendChild(textarea);
|
|
214
|
-
try {
|
|
215
|
-
textarea.select();
|
|
216
|
-
textarea.setSelectionRange(0, text.length);
|
|
217
|
-
return document.execCommand("copy");
|
|
218
|
-
} catch {
|
|
219
|
-
return false;
|
|
220
|
-
} finally {
|
|
221
|
-
document.body.removeChild(textarea);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// src/clipboard/use-copy-feedback.ts
|
|
226
|
-
import { useCallback, useEffect as useEffect4, useRef as useRef4, useState } from "react";
|
|
227
|
-
function useCopyFeedback({ resetMs = 1500 } = {}) {
|
|
228
|
-
const [status, setStatus] = useState("idle");
|
|
229
|
-
const timerRef = useRef4(void 0);
|
|
230
|
-
const clearTimer = useCallback(() => {
|
|
231
|
-
if (timerRef.current !== void 0) clearTimeout(timerRef.current);
|
|
232
|
-
timerRef.current = void 0;
|
|
233
|
-
}, []);
|
|
234
|
-
useEffect4(() => clearTimer, [clearTimer]);
|
|
235
|
-
const copy = useCallback(
|
|
236
|
-
async (text) => {
|
|
237
|
-
const result = await copyText(text);
|
|
238
|
-
clearTimer();
|
|
239
|
-
setStatus(result.ok ? "copied" : "failed");
|
|
240
|
-
timerRef.current = setTimeout(() => setStatus("idle"), resetMs);
|
|
241
|
-
return result;
|
|
242
|
-
},
|
|
243
|
-
[clearTimer, resetMs]
|
|
244
|
-
);
|
|
245
|
-
return { copy, status };
|
|
246
|
-
}
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
nextDelay,
|
|
4
|
+
useVisibilityPolling
|
|
5
|
+
} from "./chunk-UPVNSGIK.js";
|
|
6
|
+
import {
|
|
7
|
+
createDebouncer,
|
|
8
|
+
useDebouncedCallback,
|
|
9
|
+
useDebouncedValue
|
|
10
|
+
} from "./chunk-IWQDAJEP.js";
|
|
11
|
+
import {
|
|
12
|
+
useStorageState
|
|
13
|
+
} from "./chunk-5KIH2XLV.js";
|
|
14
|
+
import {
|
|
15
|
+
handleBeforeUnload,
|
|
16
|
+
useUnsavedChangesGuard
|
|
17
|
+
} from "./chunk-LZKAGDER.js";
|
|
18
|
+
import {
|
|
19
|
+
detectApple,
|
|
20
|
+
isEditableTarget,
|
|
21
|
+
matchHotkey,
|
|
22
|
+
parseHotkey,
|
|
23
|
+
useHotkey
|
|
24
|
+
} from "./chunk-NKLEB5TR.js";
|
|
25
|
+
import {
|
|
26
|
+
nextHeight,
|
|
27
|
+
useAutoGrowTextarea
|
|
28
|
+
} from "./chunk-5CA5RIMH.js";
|
|
29
|
+
import {
|
|
30
|
+
BACK_ZONE_PX,
|
|
31
|
+
CLOSE_DISTANCE_PX,
|
|
32
|
+
FORWARD_ZONE_PX,
|
|
33
|
+
MAX_SWIPE_DURATION_MS,
|
|
34
|
+
OPEN_DISTANCE_PX,
|
|
35
|
+
VERTICAL_CANCEL_PX,
|
|
36
|
+
isInOpenZone,
|
|
37
|
+
isInsideHorizontalScroller,
|
|
38
|
+
resolveSwipeIntent,
|
|
39
|
+
useDrawerSwipe
|
|
40
|
+
} from "./chunk-OZ4PU4E3.js";
|
|
41
|
+
import {
|
|
42
|
+
FOCUSABLE_SELECTOR,
|
|
43
|
+
focusableWithin,
|
|
44
|
+
nextFocusTarget,
|
|
45
|
+
useFocusTrap
|
|
46
|
+
} from "./chunk-DNU57XEJ.js";
|
|
47
|
+
import {
|
|
48
|
+
useEscape
|
|
49
|
+
} from "./chunk-S4YKMGQE.js";
|
|
50
|
+
import {
|
|
51
|
+
copyText,
|
|
52
|
+
useCopyFeedback
|
|
53
|
+
} from "./chunk-3CACI4OQ.js";
|
|
54
|
+
import {
|
|
55
|
+
lockScroll,
|
|
56
|
+
unlockScroll,
|
|
57
|
+
useScrollLock
|
|
58
|
+
} from "./chunk-6KCRVSLS.js";
|
|
59
|
+
import {
|
|
60
|
+
COARSE_POINTER_QUERY,
|
|
61
|
+
REDUCED_MOTION_QUERY,
|
|
62
|
+
useCoarsePointer,
|
|
63
|
+
useMediaQuery,
|
|
64
|
+
useReducedMotion
|
|
65
|
+
} from "./chunk-UZADAINO.js";
|
|
66
|
+
import {
|
|
67
|
+
isOutside,
|
|
68
|
+
isPrimaryPress,
|
|
69
|
+
useOutsidePress
|
|
70
|
+
} from "./chunk-3UGRXQIA.js";
|
|
247
71
|
export {
|
|
248
72
|
BACK_ZONE_PX,
|
|
249
73
|
CLOSE_DISTANCE_PX,
|
|
74
|
+
COARSE_POINTER_QUERY,
|
|
250
75
|
FOCUSABLE_SELECTOR,
|
|
251
76
|
FORWARD_ZONE_PX,
|
|
252
77
|
MAX_SWIPE_DURATION_MS,
|
|
253
78
|
OPEN_DISTANCE_PX,
|
|
79
|
+
REDUCED_MOTION_QUERY,
|
|
254
80
|
VERTICAL_CANCEL_PX,
|
|
255
81
|
copyText,
|
|
82
|
+
createDebouncer,
|
|
83
|
+
detectApple,
|
|
256
84
|
focusableWithin,
|
|
85
|
+
handleBeforeUnload,
|
|
86
|
+
isEditableTarget,
|
|
257
87
|
isInOpenZone,
|
|
258
88
|
isInsideHorizontalScroller,
|
|
89
|
+
isOutside,
|
|
90
|
+
isPrimaryPress,
|
|
91
|
+
lockScroll,
|
|
92
|
+
matchHotkey,
|
|
93
|
+
nextDelay,
|
|
259
94
|
nextFocusTarget,
|
|
95
|
+
nextHeight,
|
|
96
|
+
parseHotkey,
|
|
260
97
|
resolveSwipeIntent,
|
|
98
|
+
unlockScroll,
|
|
99
|
+
useAutoGrowTextarea,
|
|
100
|
+
useCoarsePointer,
|
|
261
101
|
useCopyFeedback,
|
|
102
|
+
useDebouncedCallback,
|
|
103
|
+
useDebouncedValue,
|
|
262
104
|
useDrawerSwipe,
|
|
263
105
|
useEscape,
|
|
264
|
-
useFocusTrap
|
|
106
|
+
useFocusTrap,
|
|
107
|
+
useHotkey,
|
|
108
|
+
useMediaQuery,
|
|
109
|
+
useOutsidePress,
|
|
110
|
+
useReducedMotion,
|
|
111
|
+
useScrollLock,
|
|
112
|
+
useStorageState,
|
|
113
|
+
useUnsavedChangesGuard,
|
|
114
|
+
useVisibilityPolling
|
|
265
115
|
};
|
|
@@ -0,0 +1,90 @@
|
|
|
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/media-query/index.ts
|
|
22
|
+
var media_query_exports = {};
|
|
23
|
+
__export(media_query_exports, {
|
|
24
|
+
COARSE_POINTER_QUERY: () => COARSE_POINTER_QUERY,
|
|
25
|
+
REDUCED_MOTION_QUERY: () => REDUCED_MOTION_QUERY,
|
|
26
|
+
useCoarsePointer: () => useCoarsePointer,
|
|
27
|
+
useMediaQuery: () => useMediaQuery,
|
|
28
|
+
useReducedMotion: () => useReducedMotion
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(media_query_exports);
|
|
31
|
+
|
|
32
|
+
// src/media-query/use-media-query.ts
|
|
33
|
+
var import_react = require("react");
|
|
34
|
+
|
|
35
|
+
// src/media-query/media-query.ts
|
|
36
|
+
var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
37
|
+
var COARSE_POINTER_QUERY = "(pointer: coarse)";
|
|
38
|
+
var lists = /* @__PURE__ */ new WeakMap();
|
|
39
|
+
function getList(query) {
|
|
40
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return null;
|
|
41
|
+
const owner = window.matchMedia;
|
|
42
|
+
let byQuery = lists.get(owner);
|
|
43
|
+
if (!byQuery) {
|
|
44
|
+
byQuery = /* @__PURE__ */ new Map();
|
|
45
|
+
lists.set(owner, byQuery);
|
|
46
|
+
}
|
|
47
|
+
let list = byQuery.get(query);
|
|
48
|
+
if (!list) {
|
|
49
|
+
list = owner.call(window, query);
|
|
50
|
+
byQuery.set(query, list);
|
|
51
|
+
}
|
|
52
|
+
return list;
|
|
53
|
+
}
|
|
54
|
+
function getMatches(query) {
|
|
55
|
+
return getList(query)?.matches ?? null;
|
|
56
|
+
}
|
|
57
|
+
function subscribe(query, onChange) {
|
|
58
|
+
const list = getList(query);
|
|
59
|
+
if (!list) return () => {
|
|
60
|
+
};
|
|
61
|
+
if (typeof list.addEventListener === "function") {
|
|
62
|
+
list.addEventListener("change", onChange);
|
|
63
|
+
return () => list.removeEventListener("change", onChange);
|
|
64
|
+
}
|
|
65
|
+
list.addListener(onChange);
|
|
66
|
+
return () => list.removeListener(onChange);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/media-query/use-media-query.ts
|
|
70
|
+
function useMediaQuery(query, options = {}) {
|
|
71
|
+
const serverDefault = options.serverDefault ?? false;
|
|
72
|
+
const subscribeToQuery = (0, import_react.useCallback)((onChange) => subscribe(query, onChange), [query]);
|
|
73
|
+
const getSnapshot = (0, import_react.useCallback)(() => getMatches(query) ?? serverDefault, [query, serverDefault]);
|
|
74
|
+
const getServerSnapshot = (0, import_react.useCallback)(() => serverDefault, [serverDefault]);
|
|
75
|
+
return (0, import_react.useSyncExternalStore)(subscribeToQuery, getSnapshot, getServerSnapshot);
|
|
76
|
+
}
|
|
77
|
+
function useReducedMotion(options) {
|
|
78
|
+
return useMediaQuery(REDUCED_MOTION_QUERY, options);
|
|
79
|
+
}
|
|
80
|
+
function useCoarsePointer(options) {
|
|
81
|
+
return useMediaQuery(COARSE_POINTER_QUERY, options);
|
|
82
|
+
}
|
|
83
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
84
|
+
0 && (module.exports = {
|
|
85
|
+
COARSE_POINTER_QUERY,
|
|
86
|
+
REDUCED_MOTION_QUERY,
|
|
87
|
+
useCoarsePointer,
|
|
88
|
+
useMediaQuery,
|
|
89
|
+
useReducedMotion
|
|
90
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface UseMediaQueryOptions {
|
|
2
|
+
/** Value on the server, during hydration, and where `matchMedia` is missing. Default `false`. */
|
|
3
|
+
serverDefault?: boolean;
|
|
4
|
+
}
|
|
5
|
+
declare function useMediaQuery(query: string, options?: UseMediaQueryOptions): boolean;
|
|
6
|
+
declare function useReducedMotion(options?: UseMediaQueryOptions): boolean;
|
|
7
|
+
declare function useCoarsePointer(options?: UseMediaQueryOptions): boolean;
|
|
8
|
+
|
|
9
|
+
declare const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
10
|
+
declare const COARSE_POINTER_QUERY = "(pointer: coarse)";
|
|
11
|
+
|
|
12
|
+
export { COARSE_POINTER_QUERY, REDUCED_MOTION_QUERY, type UseMediaQueryOptions, useCoarsePointer, useMediaQuery, useReducedMotion };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface UseMediaQueryOptions {
|
|
2
|
+
/** Value on the server, during hydration, and where `matchMedia` is missing. Default `false`. */
|
|
3
|
+
serverDefault?: boolean;
|
|
4
|
+
}
|
|
5
|
+
declare function useMediaQuery(query: string, options?: UseMediaQueryOptions): boolean;
|
|
6
|
+
declare function useReducedMotion(options?: UseMediaQueryOptions): boolean;
|
|
7
|
+
declare function useCoarsePointer(options?: UseMediaQueryOptions): boolean;
|
|
8
|
+
|
|
9
|
+
declare const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
10
|
+
declare const COARSE_POINTER_QUERY = "(pointer: coarse)";
|
|
11
|
+
|
|
12
|
+
export { COARSE_POINTER_QUERY, REDUCED_MOTION_QUERY, type UseMediaQueryOptions, useCoarsePointer, useMediaQuery, useReducedMotion };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
COARSE_POINTER_QUERY,
|
|
4
|
+
REDUCED_MOTION_QUERY,
|
|
5
|
+
useCoarsePointer,
|
|
6
|
+
useMediaQuery,
|
|
7
|
+
useReducedMotion
|
|
8
|
+
} from "./chunk-UZADAINO.js";
|
|
9
|
+
export {
|
|
10
|
+
COARSE_POINTER_QUERY,
|
|
11
|
+
REDUCED_MOTION_QUERY,
|
|
12
|
+
useCoarsePointer,
|
|
13
|
+
useMediaQuery,
|
|
14
|
+
useReducedMotion
|
|
15
|
+
};
|