@mantine/hooks 9.5.2 → 9.6.1
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/cjs/use-click-outside/use-click-outside.cjs.map +1 -1
- package/cjs/use-clipboard/use-clipboard.cjs.map +1 -1
- package/cjs/use-collapse/use-collapse.cjs +33 -6
- package/cjs/use-collapse/use-collapse.cjs.map +1 -1
- package/cjs/use-collapse/use-horizontal-collapse.cjs +30 -6
- package/cjs/use-collapse/use-horizontal-collapse.cjs.map +1 -1
- package/cjs/use-counter/use-counter.cjs.map +1 -1
- package/cjs/use-debounced-callback/use-debounced-callback.cjs.map +1 -1
- package/cjs/use-debounced-state/use-debounced-state.cjs.map +1 -1
- package/cjs/use-debounced-value/use-debounced-value.cjs.map +1 -1
- package/cjs/use-did-update/use-did-update.cjs +17 -5
- package/cjs/use-did-update/use-did-update.cjs.map +1 -1
- package/cjs/use-disclosure/use-disclosure.cjs.map +1 -1
- package/cjs/use-document-visibility/use-document-visibility.cjs.map +1 -1
- package/cjs/use-drag/use-drag.cjs.map +1 -1
- package/cjs/use-event-listener/use-event-listener.cjs.map +1 -1
- package/cjs/use-eye-dropper/use-eye-dropper.cjs.map +1 -1
- package/cjs/use-favicon/use-favicon.cjs.map +1 -1
- package/cjs/use-fetch/use-fetch.cjs.map +1 -1
- package/cjs/use-file-dialog/use-file-dialog.cjs.map +1 -1
- package/cjs/use-floating-window/use-floating-window.cjs.map +1 -1
- package/cjs/use-focus-return/use-focus-return.cjs.map +1 -1
- package/cjs/use-focus-trap/use-focus-trap.cjs.map +1 -1
- package/cjs/use-focus-within/use-focus-within.cjs.map +1 -1
- package/cjs/use-force-update/use-force-update.cjs.map +1 -1
- package/cjs/use-fullscreen/use-fullscreen.cjs.map +1 -1
- package/cjs/use-hash/use-hash.cjs.map +1 -1
- package/cjs/use-headroom/use-headroom.cjs.map +1 -1
- package/cjs/use-hotkeys/parse-hotkey.cjs.map +1 -1
- package/cjs/use-hotkeys/use-hotkeys.cjs.map +1 -1
- package/cjs/use-hover/use-hover.cjs.map +1 -1
- package/cjs/use-id/use-id.cjs +2 -1
- package/cjs/use-id/use-id.cjs.map +1 -1
- package/cjs/use-idle/use-idle.cjs.map +1 -1
- package/cjs/use-in-viewport/use-in-viewport.cjs.map +1 -1
- package/cjs/use-input-state/use-input-state.cjs.map +1 -1
- package/cjs/use-intersection/use-intersection.cjs.map +1 -1
- package/cjs/use-interval/use-interval.cjs +5 -9
- package/cjs/use-interval/use-interval.cjs.map +1 -1
- package/cjs/use-is-first-render/use-is-first-render.cjs.map +1 -1
- package/cjs/use-list-state/use-list-state.cjs.map +1 -1
- package/cjs/use-local-storage/create-storage.cjs.map +1 -1
- package/cjs/use-long-press/use-long-press.cjs +2 -1
- package/cjs/use-long-press/use-long-press.cjs.map +1 -1
- package/cjs/use-map/use-map.cjs.map +1 -1
- package/cjs/use-mask/use-mask.cjs +9 -7
- package/cjs/use-mask/use-mask.cjs.map +1 -1
- package/cjs/use-media-query/use-media-query.cjs.map +1 -1
- package/cjs/use-merged-ref/use-merged-ref.cjs.map +1 -1
- package/cjs/use-mounted/use-mounted.cjs.map +1 -1
- package/cjs/use-mouse/use-mouse.cjs.map +1 -1
- package/cjs/use-move/use-move.cjs.map +1 -1
- package/cjs/use-mutation-observer/use-mutation-observer.cjs.map +1 -1
- package/cjs/use-network/use-network.cjs.map +1 -1
- package/cjs/use-orientation/use-orientation.cjs.map +1 -1
- package/cjs/use-os/use-os.cjs.map +1 -1
- package/cjs/use-page-leave/use-page-leave.cjs.map +1 -1
- package/cjs/use-pagination/use-pagination.cjs.map +1 -1
- package/cjs/use-previous/use-previous.cjs.map +1 -1
- package/cjs/use-queue/use-queue.cjs.map +1 -1
- package/cjs/use-radial-move/use-radial-move.cjs.map +1 -1
- package/cjs/use-resize-observer/use-resize-observer.cjs.map +1 -1
- package/cjs/use-roving-index/use-roving-index.cjs +11 -14
- package/cjs/use-roving-index/use-roving-index.cjs.map +1 -1
- package/cjs/use-scroll-direction/use-scroll-direction.cjs.map +1 -1
- package/cjs/use-scroll-into-view/use-scroll-into-view.cjs.map +1 -1
- package/cjs/use-scroll-spy/use-scroll-spy.cjs.map +1 -1
- package/cjs/use-scroller/use-scroller.cjs.map +1 -1
- package/cjs/use-selection/use-selection.cjs.map +1 -1
- package/cjs/use-set/use-set.cjs.map +1 -1
- package/cjs/use-set-state/use-set-state.cjs.map +1 -1
- package/cjs/use-shallow-effect/use-shallow-effect.cjs.map +1 -1
- package/cjs/use-splitter/use-splitter.cjs.map +1 -1
- package/cjs/use-state-history/use-state-history.cjs.map +1 -1
- package/cjs/use-text-selection/use-text-selection.cjs.map +1 -1
- package/cjs/use-throttled-callback/use-throttled-callback.cjs.map +1 -1
- package/cjs/use-throttled-state/use-throttled-state.cjs.map +1 -1
- package/cjs/use-throttled-value/use-throttled-value.cjs.map +1 -1
- package/cjs/use-timeout/use-timeout.cjs.map +1 -1
- package/cjs/use-toggle/use-toggle.cjs.map +1 -1
- package/cjs/use-uncontrolled/use-uncontrolled.cjs.map +1 -1
- package/cjs/use-validated-state/use-validated-state.cjs.map +1 -1
- package/cjs/use-viewport-size/use-viewport-size.cjs.map +1 -1
- package/cjs/use-window-event/use-window-event.cjs.map +1 -1
- package/cjs/use-window-scroll/use-window-scroll.cjs.map +1 -1
- package/cjs/utils/use-callback-ref/use-callback-ref.cjs.map +1 -1
- package/esm/use-collapse/use-collapse.mjs +33 -7
- package/esm/use-collapse/use-collapse.mjs.map +1 -1
- package/esm/use-collapse/use-horizontal-collapse.mjs +30 -6
- package/esm/use-collapse/use-horizontal-collapse.mjs.map +1 -1
- package/esm/use-did-update/use-did-update.mjs +17 -5
- package/esm/use-did-update/use-did-update.mjs.map +1 -1
- package/esm/use-hotkeys/parse-hotkey.mjs.map +1 -1
- package/esm/use-id/use-id.mjs +2 -1
- package/esm/use-id/use-id.mjs.map +1 -1
- package/esm/use-interval/use-interval.mjs +5 -9
- package/esm/use-interval/use-interval.mjs.map +1 -1
- package/esm/use-local-storage/create-storage.mjs.map +1 -1
- package/esm/use-long-press/use-long-press.mjs +2 -1
- package/esm/use-long-press/use-long-press.mjs.map +1 -1
- package/esm/use-mask/use-mask.mjs +9 -7
- package/esm/use-mask/use-mask.mjs.map +1 -1
- package/esm/use-roving-index/use-roving-index.mjs +11 -14
- package/esm/use-roving-index/use-roving-index.mjs.map +1 -1
- package/lib/use-collapse/use-collapse.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-click-outside.cjs","names":[],"sources":["../../src/use-click-outside/use-click-outside.ts"],"sourcesContent":["import { useEffect, useEffectEvent, useRef } from 'react';\n\ntype EventType = MouseEvent | TouchEvent;\n\nconst DEFAULT_EVENTS = ['mousedown', 'touchstart'];\n\nexport function useClickOutside<T extends HTMLElement = any>(\n callback: (event: EventType) => void,\n events?: string[] | null,\n nodes?: (HTMLElement | null)[],\n enabled: boolean = true\n) {\n const ref = useRef<T>(null);\n const eventsList = events || DEFAULT_EVENTS;\n\n const listener = useEffectEvent((event: Event) => {\n const { target } = event ?? {};\n const shouldIgnore =\n !document.body.contains(target as Node) && (target as Element)?.tagName !== 'HTML';\n\n if (shouldIgnore) {\n return;\n }\n\n const path = event.composedPath();\n\n if (Array.isArray(nodes)) {\n const shouldTrigger = nodes.every((node) => !!node && !path.includes(node));\n shouldTrigger && callback(event as EventType);\n } else if (ref.current && !path.includes(ref.current)) {\n callback(event as EventType);\n }\n });\n\n const eventsKey = eventsList.join(',');\n\n useEffect(() => {\n if (!enabled) {\n return undefined;\n }\n\n const events = eventsKey.split(',');\n events.forEach((fn) => document.addEventListener(fn, listener));\n\n return () => {\n events.forEach((fn) => document.removeEventListener(fn, listener));\n };\n }, [eventsKey, enabled]);\n\n return ref;\n}\n"],"mappings":";;;AAIA,MAAM,iBAAiB,CAAC,aAAa,YAAY;AAEjD,SAAgB,gBACd,UACA,QACA,OACA,UAAmB,MACnB;CACA,MAAM,OAAA,
|
|
1
|
+
{"version":3,"file":"use-click-outside.cjs","names":["useRef","useEffectEvent"],"sources":["../../src/use-click-outside/use-click-outside.ts"],"sourcesContent":["import { useEffect, useEffectEvent, useRef } from 'react';\n\ntype EventType = MouseEvent | TouchEvent;\n\nconst DEFAULT_EVENTS = ['mousedown', 'touchstart'];\n\nexport function useClickOutside<T extends HTMLElement = any>(\n callback: (event: EventType) => void,\n events?: string[] | null,\n nodes?: (HTMLElement | null)[],\n enabled: boolean = true\n) {\n const ref = useRef<T>(null);\n const eventsList = events || DEFAULT_EVENTS;\n\n const listener = useEffectEvent((event: Event) => {\n const { target } = event ?? {};\n const shouldIgnore =\n !document.body.contains(target as Node) && (target as Element)?.tagName !== 'HTML';\n\n if (shouldIgnore) {\n return;\n }\n\n const path = event.composedPath();\n\n if (Array.isArray(nodes)) {\n const shouldTrigger = nodes.every((node) => !!node && !path.includes(node));\n shouldTrigger && callback(event as EventType);\n } else if (ref.current && !path.includes(ref.current)) {\n callback(event as EventType);\n }\n });\n\n const eventsKey = eventsList.join(',');\n\n useEffect(() => {\n if (!enabled) {\n return undefined;\n }\n\n const events = eventsKey.split(',');\n events.forEach((fn) => document.addEventListener(fn, listener));\n\n return () => {\n events.forEach((fn) => document.removeEventListener(fn, listener));\n };\n }, [eventsKey, enabled]);\n\n return ref;\n}\n"],"mappings":";;;AAIA,MAAM,iBAAiB,CAAC,aAAa,YAAY;AAEjD,SAAgB,gBACd,UACA,QACA,OACA,UAAmB,MACnB;CACA,MAAM,OAAA,GAAMA,MAAAA,OAAAA,CAAU,IAAI;CAC1B,MAAM,aAAa,UAAU;CAE7B,MAAM,YAAA,GAAWC,MAAAA,eAAAA,EAAgB,UAAiB;EAChD,MAAM,EAAE,WAAW,SAAS,CAAC;EAI7B,IAFE,CAAC,SAAS,KAAK,SAAS,MAAc,KAAM,QAAoB,YAAY,QAG5E;EAGF,MAAM,OAAO,MAAM,aAAa;EAEhC,IAAI,MAAM,QAAQ,KAAK,GAErB,MAD4B,OAAO,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,SAAS,IAAI,CAC7D,KAAK,SAAS,KAAkB;OACvC,IAAI,IAAI,WAAW,CAAC,KAAK,SAAS,IAAI,OAAO,GAClD,SAAS,KAAkB;CAE/B,CAAC;CAED,MAAM,YAAY,WAAW,KAAK,GAAG;CAErC,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,CAAC,SACH;EAGF,MAAM,SAAS,UAAU,MAAM,GAAG;EAClC,OAAO,SAAS,OAAO,SAAS,iBAAiB,IAAI,QAAQ,CAAC;EAE9D,aAAa;GACX,OAAO,SAAS,OAAO,SAAS,oBAAoB,IAAI,QAAQ,CAAC;EACnE;CACF,GAAG,CAAC,WAAW,OAAO,CAAC;CAEvB,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-clipboard.cjs","names":[],"sources":["../../src/use-clipboard/use-clipboard.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nexport interface UseClipboardInput {\n /** Time in ms after which the copied state will reset, `2000` by default */\n timeout?: number;\n}\n\nexport interface UseClipboardReturnValue {\n /** Function to copy value to clipboard */\n copy: (value: any) => void;\n\n /** Function to reset copied state and error */\n reset: () => void;\n\n /** Error if copying failed */\n error: Error | null;\n\n /** Boolean indicating if the value was copied successfully */\n copied: boolean;\n}\n\nexport function useClipboard(options: UseClipboardInput = {}): UseClipboardReturnValue {\n const timeout = options.timeout ?? 2000;\n const [error, setError] = useState<Error | null>(null);\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<number | null>(null);\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current!);\n },\n []\n );\n\n const handleCopyResult = (value: boolean) => {\n window.clearTimeout(timeoutRef.current!);\n timeoutRef.current = window.setTimeout(() => setCopied(false), timeout);\n setCopied(value);\n };\n\n const copy = (value: any) => {\n if ('clipboard' in navigator) {\n navigator.clipboard\n .writeText(value)\n .then(() => {\n setError(null);\n handleCopyResult(true);\n })\n .catch((err) => setError(err));\n } else {\n setError(new Error('useClipboard: navigator.clipboard is not supported'));\n }\n };\n\n const reset = () => {\n setCopied(false);\n setError(null);\n window.clearTimeout(timeoutRef.current!);\n };\n\n return { copy, reset, error, copied };\n}\n\nexport namespace useClipboard {\n export type Input = UseClipboardInput;\n export type ReturnValue = UseClipboardReturnValue;\n}\n"],"mappings":";;;AAqBA,SAAgB,aAAa,UAA6B,CAAC,GAA4B;CACrF,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,CAAC,OAAO,aAAA,
|
|
1
|
+
{"version":3,"file":"use-clipboard.cjs","names":["useState","useRef"],"sources":["../../src/use-clipboard/use-clipboard.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react';\n\nexport interface UseClipboardInput {\n /** Time in ms after which the copied state will reset, `2000` by default */\n timeout?: number;\n}\n\nexport interface UseClipboardReturnValue {\n /** Function to copy value to clipboard */\n copy: (value: any) => void;\n\n /** Function to reset copied state and error */\n reset: () => void;\n\n /** Error if copying failed */\n error: Error | null;\n\n /** Boolean indicating if the value was copied successfully */\n copied: boolean;\n}\n\nexport function useClipboard(options: UseClipboardInput = {}): UseClipboardReturnValue {\n const timeout = options.timeout ?? 2000;\n const [error, setError] = useState<Error | null>(null);\n const [copied, setCopied] = useState(false);\n const timeoutRef = useRef<number | null>(null);\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current!);\n },\n []\n );\n\n const handleCopyResult = (value: boolean) => {\n window.clearTimeout(timeoutRef.current!);\n timeoutRef.current = window.setTimeout(() => setCopied(false), timeout);\n setCopied(value);\n };\n\n const copy = (value: any) => {\n if ('clipboard' in navigator) {\n navigator.clipboard\n .writeText(value)\n .then(() => {\n setError(null);\n handleCopyResult(true);\n })\n .catch((err) => setError(err));\n } else {\n setError(new Error('useClipboard: navigator.clipboard is not supported'));\n }\n };\n\n const reset = () => {\n setCopied(false);\n setError(null);\n window.clearTimeout(timeoutRef.current!);\n };\n\n return { copy, reset, error, copied };\n}\n\nexport namespace useClipboard {\n export type Input = UseClipboardInput;\n export type ReturnValue = UseClipboardReturnValue;\n}\n"],"mappings":";;;AAqBA,SAAgB,aAAa,UAA6B,CAAC,GAA4B;CACrF,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAuB,IAAI;CACrD,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAS,KAAK;CAC1C,MAAM,cAAA,GAAaC,MAAAA,OAAAA,CAAsB,IAAI;CAE7C,CAAA,GAAA,MAAA,UAAA,aACc;EACV,OAAO,aAAa,WAAW,OAAQ;CACzC,GACA,CAAC,CACH;CAEA,MAAM,oBAAoB,UAAmB;EAC3C,OAAO,aAAa,WAAW,OAAQ;EACvC,WAAW,UAAU,OAAO,iBAAiB,UAAU,KAAK,GAAG,OAAO;EACtE,UAAU,KAAK;CACjB;CAEA,MAAM,QAAQ,UAAe;EAC3B,IAAI,eAAe,WACjB,UAAU,UACP,UAAU,KAAK,CAAC,CAChB,WAAW;GACV,SAAS,IAAI;GACb,iBAAiB,IAAI;EACvB,CAAC,CAAC,CACD,OAAO,QAAQ,SAAS,GAAG,CAAC;OAE/B,yBAAS,IAAI,MAAM,oDAAoD,CAAC;CAE5E;CAEA,MAAM,cAAc;EAClB,UAAU,KAAK;EACf,SAAS,IAAI;EACb,OAAO,aAAa,WAAW,OAAQ;CACzC;CAEA,OAAO;EAAE;EAAM;EAAO;EAAO;CAAO;AACtC"}
|
|
@@ -12,6 +12,9 @@ function getAutoHeightDuration(height) {
|
|
|
12
12
|
function getElementHeight(elementRef) {
|
|
13
13
|
return elementRef.current ? elementRef.current.scrollHeight : "auto";
|
|
14
14
|
}
|
|
15
|
+
function isMeasured(size) {
|
|
16
|
+
return typeof size === "number" && size > 0;
|
|
17
|
+
}
|
|
15
18
|
function useCollapse({ transitionDuration, transitionTimingFunction = "ease", onTransitionEnd, onTransitionStart, expanded, keepMounted }) {
|
|
16
19
|
const collapsedStyles = {
|
|
17
20
|
height: 0,
|
|
@@ -19,6 +22,7 @@ function useCollapse({ transitionDuration, transitionTimingFunction = "ease", on
|
|
|
19
22
|
...keepMounted ? {} : { display: "none" }
|
|
20
23
|
};
|
|
21
24
|
const onTransitionStartEvent = (0, react.useEffectEvent)(() => onTransitionStart?.());
|
|
25
|
+
const onTransitionEndEvent = (0, react.useEffectEvent)(() => onTransitionEnd?.());
|
|
22
26
|
const elementRef = (0, react.useRef)(null);
|
|
23
27
|
const [styles, setStylesRaw] = (0, react.useState)(expanded ? {} : collapsedStyles);
|
|
24
28
|
const [state, setState] = (0, react.useState)(expanded ? "entered" : "exited");
|
|
@@ -35,9 +39,14 @@ function useCollapse({ transitionDuration, transitionTimingFunction = "ease", on
|
|
|
35
39
|
const duration = transitionDuration ?? getAutoHeightDuration(height);
|
|
36
40
|
return { transition: `height ${duration}ms ${transitionTimingFunction}, opacity ${duration}ms ${transitionTimingFunction}` };
|
|
37
41
|
};
|
|
42
|
+
const transitionRef = (0, react.useRef)(0);
|
|
38
43
|
require_use_did_update.useDidUpdate(() => {
|
|
44
|
+
transitionRef.current += 1;
|
|
45
|
+
const transitionId = transitionRef.current;
|
|
46
|
+
const isCurrentTransition = () => transitionRef.current === transitionId;
|
|
39
47
|
if (transitionDuration !== 0) onTransitionStartEvent();
|
|
40
48
|
if (expanded) window.requestAnimationFrame(() => {
|
|
49
|
+
if (!isCurrentTransition() || !elementRef.current) return;
|
|
41
50
|
(0, react_dom.flushSync)(() => setState("entering"));
|
|
42
51
|
mergeStyles({
|
|
43
52
|
willChange: "height",
|
|
@@ -45,7 +54,14 @@ function useCollapse({ transitionDuration, transitionTimingFunction = "ease", on
|
|
|
45
54
|
overflow: "hidden"
|
|
46
55
|
});
|
|
47
56
|
window.requestAnimationFrame(() => {
|
|
57
|
+
if (!isCurrentTransition() || !elementRef.current) return;
|
|
48
58
|
const height = getElementHeight(elementRef);
|
|
59
|
+
if (!isMeasured(height)) {
|
|
60
|
+
setStyles({});
|
|
61
|
+
setState("entered");
|
|
62
|
+
onTransitionEndEvent();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
49
65
|
mergeStyles({
|
|
50
66
|
...getTransitionStyles(height),
|
|
51
67
|
height
|
|
@@ -53,17 +69,27 @@ function useCollapse({ transitionDuration, transitionTimingFunction = "ease", on
|
|
|
53
69
|
});
|
|
54
70
|
});
|
|
55
71
|
else window.requestAnimationFrame(() => {
|
|
72
|
+
if (!isCurrentTransition() || !elementRef.current) return;
|
|
56
73
|
(0, react_dom.flushSync)(() => setState("exiting"));
|
|
57
74
|
const height = getElementHeight(elementRef);
|
|
75
|
+
if (!isMeasured(height)) {
|
|
76
|
+
setStyles(collapsedStyles);
|
|
77
|
+
setState("exited");
|
|
78
|
+
onTransitionEndEvent();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
58
81
|
mergeStyles({
|
|
59
82
|
...getTransitionStyles(height),
|
|
60
83
|
willChange: "height",
|
|
61
84
|
height
|
|
62
85
|
});
|
|
63
|
-
window.requestAnimationFrame(() =>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
86
|
+
window.requestAnimationFrame(() => {
|
|
87
|
+
if (!isCurrentTransition() || !elementRef.current) return;
|
|
88
|
+
mergeStyles({
|
|
89
|
+
height: 0,
|
|
90
|
+
overflow: "hidden"
|
|
91
|
+
});
|
|
92
|
+
});
|
|
67
93
|
});
|
|
68
94
|
}, [expanded]);
|
|
69
95
|
const handleTransitionEnd = (event) => {
|
|
@@ -73,11 +99,11 @@ function useCollapse({ transitionDuration, transitionTimingFunction = "ease", on
|
|
|
73
99
|
if (height === styles.height) setStyles({});
|
|
74
100
|
else mergeStyles({ height });
|
|
75
101
|
setState("entered");
|
|
76
|
-
|
|
102
|
+
onTransitionEndEvent();
|
|
77
103
|
} else if (styles.height === 0) {
|
|
78
104
|
setStyles(collapsedStyles);
|
|
79
105
|
setState("exited");
|
|
80
|
-
|
|
106
|
+
onTransitionEndEvent();
|
|
81
107
|
}
|
|
82
108
|
};
|
|
83
109
|
return {
|
|
@@ -97,6 +123,7 @@ function useCollapse({ transitionDuration, transitionTimingFunction = "ease", on
|
|
|
97
123
|
}
|
|
98
124
|
//#endregion
|
|
99
125
|
exports.getElementHeight = getElementHeight;
|
|
126
|
+
exports.isMeasured = isMeasured;
|
|
100
127
|
exports.useCollapse = useCollapse;
|
|
101
128
|
|
|
102
129
|
//# sourceMappingURL=use-collapse.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-collapse.cjs","names":["mergeRefs"],"sources":["../../src/use-collapse/use-collapse.ts"],"sourcesContent":["import React, { CSSProperties, useEffectEvent, useRef, useState } from 'react';\nimport { flushSync } from 'react-dom';\nimport { useDidUpdate } from '../use-did-update/use-did-update';\nimport { mergeRefs } from '../use-merged-ref/use-merged-ref';\n\nfunction getAutoHeightDuration(height: number | string) {\n if (!height || typeof height === 'string') {\n return 0;\n }\n const constant = height / 36;\n return Math.round((4 + 15 * constant ** 0.25 + constant / 5) * 10);\n}\n\nexport function getElementHeight(elementRef: React.RefObject<HTMLElement | null>) {\n return elementRef.current ? elementRef.current.scrollHeight : 'auto';\n}\n\nexport interface UseCollapseInput {\n /** Expanded state */\n expanded: boolean;\n\n /** Transition duration in milliseconds, by default calculated based on content height */\n transitionDuration?: number;\n\n /** Transition timing function, `ease` by default */\n transitionTimingFunction?: string;\n\n /** Called when transition ends */\n onTransitionEnd?: () => void;\n\n /** Called when transition starts */\n onTransitionStart?: () => void;\n\n /** If true, collapsed content is kept in the DOM and hidden with `display: none` styles */\n keepMounted?: boolean;\n}\n\ninterface GetCollapsePropsInput {\n style?: CSSProperties;\n ref?: React.Ref<HTMLDivElement>;\n}\n\ninterface GetCollapsePropsReturnValue {\n 'aria-hidden': boolean;\n inert: boolean;\n ref: React.RefCallback<HTMLDivElement>;\n onTransitionEnd: (event: React.TransitionEvent<Element>) => void;\n style: React.CSSProperties;\n}\n\nexport type UseCollapseState = 'entering' | 'entered' | 'exiting' | 'exited';\n\nexport interface UseCollapseReturnValue {\n /** Current transition state */\n state: UseCollapseState;\n\n /** Props to pass down to the collapsible element */\n getCollapseProps: (input?: GetCollapsePropsInput) => GetCollapsePropsReturnValue;\n}\n\nexport function useCollapse({\n transitionDuration,\n transitionTimingFunction = 'ease',\n onTransitionEnd,\n onTransitionStart,\n expanded,\n keepMounted,\n}: UseCollapseInput): UseCollapseReturnValue {\n const collapsedStyles = {\n height: 0,\n overflow: 'hidden',\n ...(keepMounted ? {} : { display: 'none' }),\n };\n\n const onTransitionStartEvent = useEffectEvent(() => onTransitionStart?.());\n\n const elementRef = useRef<HTMLElement>(null);\n const [styles, setStylesRaw] = useState<CSSProperties>(expanded ? {} : collapsedStyles);\n const [state, setState] = useState<UseCollapseState>(expanded ? 'entered' : 'exited');\n const setStyles = (newStyles: React.SetStateAction<CSSProperties>) => {\n flushSync(() => setStylesRaw(newStyles));\n };\n\n const mergeStyles = (newStyles: CSSProperties) => {\n setStyles((oldStyles) => ({ ...oldStyles, ...newStyles }));\n };\n\n const getTransitionStyles = (height: number | string) => {\n const duration = transitionDuration ?? getAutoHeightDuration(height);\n return {\n transition: `height ${duration}ms ${transitionTimingFunction}, opacity ${duration}ms ${transitionTimingFunction}`,\n };\n };\n\n useDidUpdate(() => {\n const shouldTransition = transitionDuration !== 0;\n\n if (shouldTransition) {\n onTransitionStartEvent();\n }\n\n if (expanded) {\n window.requestAnimationFrame(() => {\n flushSync(() => setState('entering'));\n mergeStyles({ willChange: 'height', display: 'block', overflow: 'hidden' });\n window.requestAnimationFrame(() => {\n const height = getElementHeight(elementRef);\n mergeStyles({ ...getTransitionStyles(height), height });\n });\n });\n } else {\n window.requestAnimationFrame(() => {\n flushSync(() => setState('exiting'));\n const height = getElementHeight(elementRef);\n mergeStyles({ ...getTransitionStyles(height), willChange: 'height', height });\n window.requestAnimationFrame(() => mergeStyles({ height: 0, overflow: 'hidden' }));\n });\n }\n }, [expanded]);\n\n const handleTransitionEnd = (event: React.TransitionEvent): void => {\n if (event.target !== elementRef.current || event.propertyName !== 'height') {\n return;\n }\n\n if (expanded) {\n const height = getElementHeight(elementRef);\n\n if (height === styles.height) {\n setStyles({});\n } else {\n mergeStyles({ height });\n }\n\n setState('entered');\n
|
|
1
|
+
{"version":3,"file":"use-collapse.cjs","names":["useEffectEvent","useRef","useState","mergeRefs"],"sources":["../../src/use-collapse/use-collapse.ts"],"sourcesContent":["import React, { CSSProperties, useEffectEvent, useRef, useState } from 'react';\nimport { flushSync } from 'react-dom';\nimport { useDidUpdate } from '../use-did-update/use-did-update';\nimport { mergeRefs } from '../use-merged-ref/use-merged-ref';\n\nfunction getAutoHeightDuration(height: number | string) {\n if (!height || typeof height === 'string') {\n return 0;\n }\n const constant = height / 36;\n return Math.round((4 + 15 * constant ** 0.25 + constant / 5) * 10);\n}\n\nexport function getElementHeight(elementRef: React.RefObject<HTMLElement | null>) {\n return elementRef.current ? elementRef.current.scrollHeight : 'auto';\n}\n\nexport function isMeasured(size: number | string): size is number {\n return typeof size === 'number' && size > 0;\n}\n\nexport interface UseCollapseInput {\n /** Expanded state */\n expanded: boolean;\n\n /** Transition duration in milliseconds, by default calculated based on content height */\n transitionDuration?: number;\n\n /** Transition timing function, `ease` by default */\n transitionTimingFunction?: string;\n\n /** Called when transition ends */\n onTransitionEnd?: () => void;\n\n /** Called when transition starts */\n onTransitionStart?: () => void;\n\n /** If true, collapsed content is kept in the DOM and hidden with `display: none` styles */\n keepMounted?: boolean;\n}\n\ninterface GetCollapsePropsInput {\n style?: CSSProperties;\n ref?: React.Ref<HTMLDivElement>;\n}\n\ninterface GetCollapsePropsReturnValue {\n 'aria-hidden': boolean;\n inert: boolean;\n ref: React.RefCallback<HTMLDivElement>;\n onTransitionEnd: (event: React.TransitionEvent<Element>) => void;\n style: React.CSSProperties;\n}\n\nexport type UseCollapseState = 'entering' | 'entered' | 'exiting' | 'exited';\n\nexport interface UseCollapseReturnValue {\n /** Current transition state */\n state: UseCollapseState;\n\n /** Props to pass down to the collapsible element */\n getCollapseProps: (input?: GetCollapsePropsInput) => GetCollapsePropsReturnValue;\n}\n\nexport function useCollapse({\n transitionDuration,\n transitionTimingFunction = 'ease',\n onTransitionEnd,\n onTransitionStart,\n expanded,\n keepMounted,\n}: UseCollapseInput): UseCollapseReturnValue {\n const collapsedStyles = {\n height: 0,\n overflow: 'hidden',\n ...(keepMounted ? {} : { display: 'none' }),\n };\n\n const onTransitionStartEvent = useEffectEvent(() => onTransitionStart?.());\n const onTransitionEndEvent = useEffectEvent(() => onTransitionEnd?.());\n\n const elementRef = useRef<HTMLElement>(null);\n const [styles, setStylesRaw] = useState<CSSProperties>(expanded ? {} : collapsedStyles);\n const [state, setState] = useState<UseCollapseState>(expanded ? 'entered' : 'exited');\n const setStyles = (newStyles: React.SetStateAction<CSSProperties>) => {\n flushSync(() => setStylesRaw(newStyles));\n };\n\n const mergeStyles = (newStyles: CSSProperties) => {\n setStyles((oldStyles) => ({ ...oldStyles, ...newStyles }));\n };\n\n const getTransitionStyles = (height: number | string) => {\n const duration = transitionDuration ?? getAutoHeightDuration(height);\n return {\n transition: `height ${duration}ms ${transitionTimingFunction}, opacity ${duration}ms ${transitionTimingFunction}`,\n };\n };\n\n const transitionRef = useRef(0);\n\n useDidUpdate(() => {\n transitionRef.current += 1;\n const transitionId = transitionRef.current;\n const isCurrentTransition = () => transitionRef.current === transitionId;\n const shouldTransition = transitionDuration !== 0;\n\n if (shouldTransition) {\n onTransitionStartEvent();\n }\n\n if (expanded) {\n window.requestAnimationFrame(() => {\n if (!isCurrentTransition() || !elementRef.current) {\n return;\n }\n\n flushSync(() => setState('entering'));\n mergeStyles({ willChange: 'height', display: 'block', overflow: 'hidden' });\n window.requestAnimationFrame(() => {\n if (!isCurrentTransition() || !elementRef.current) {\n return;\n }\n\n const height = getElementHeight(elementRef);\n\n if (!isMeasured(height)) {\n setStyles({});\n setState('entered');\n onTransitionEndEvent();\n return;\n }\n\n mergeStyles({ ...getTransitionStyles(height), height });\n });\n });\n } else {\n window.requestAnimationFrame(() => {\n if (!isCurrentTransition() || !elementRef.current) {\n return;\n }\n\n flushSync(() => setState('exiting'));\n const height = getElementHeight(elementRef);\n\n if (!isMeasured(height)) {\n setStyles(collapsedStyles);\n setState('exited');\n onTransitionEndEvent();\n return;\n }\n\n mergeStyles({ ...getTransitionStyles(height), willChange: 'height', height });\n window.requestAnimationFrame(() => {\n if (!isCurrentTransition() || !elementRef.current) {\n return;\n }\n\n mergeStyles({ height: 0, overflow: 'hidden' });\n });\n });\n }\n }, [expanded]);\n\n const handleTransitionEnd = (event: React.TransitionEvent): void => {\n if (event.target !== elementRef.current || event.propertyName !== 'height') {\n return;\n }\n\n if (expanded) {\n const height = getElementHeight(elementRef);\n\n if (height === styles.height) {\n setStyles({});\n } else {\n mergeStyles({ height });\n }\n\n setState('entered');\n onTransitionEndEvent();\n } else if (styles.height === 0) {\n setStyles(collapsedStyles);\n setState('exited');\n onTransitionEndEvent();\n }\n };\n\n return {\n state,\n getCollapseProps: (input) => ({\n 'aria-hidden': !expanded,\n inert: !expanded,\n ref: mergeRefs(elementRef, input?.ref),\n onTransitionEnd: handleTransitionEnd,\n style: { boxSizing: 'border-box', ...input?.style, ...styles },\n }),\n };\n}\n\nexport namespace useCollapse {\n export type Input = UseCollapseInput;\n export type ReturnValue = UseCollapseReturnValue;\n export type State = UseCollapseState;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
const require_use_did_update = require("../use-did-update/use-did-update.cjs");
|
|
3
3
|
const require_use_merged_ref = require("../use-merged-ref/use-merged-ref.cjs");
|
|
4
|
+
const require_use_collapse = require("./use-collapse.cjs");
|
|
4
5
|
let react = require("react");
|
|
5
6
|
let react_dom = require("react-dom");
|
|
6
7
|
//#region packages/@mantine/hooks/src/use-collapse/use-horizontal-collapse.ts
|
|
@@ -19,6 +20,7 @@ function useHorizontalCollapse({ transitionDuration, transitionTimingFunction =
|
|
|
19
20
|
...keepMounted ? {} : { display: "none" }
|
|
20
21
|
};
|
|
21
22
|
const onTransitionStartEvent = (0, react.useEffectEvent)(() => onTransitionStart?.());
|
|
23
|
+
const onTransitionEndEvent = (0, react.useEffectEvent)(() => onTransitionEnd?.());
|
|
22
24
|
const elementRef = (0, react.useRef)(null);
|
|
23
25
|
const [styles, setStylesRaw] = (0, react.useState)(expanded ? {} : collapsedStyles);
|
|
24
26
|
const [state, setState] = (0, react.useState)(expanded ? "entered" : "exited");
|
|
@@ -35,9 +37,14 @@ function useHorizontalCollapse({ transitionDuration, transitionTimingFunction =
|
|
|
35
37
|
const duration = transitionDuration ?? getAutoWidthDuration(width);
|
|
36
38
|
return { transition: `width ${duration}ms ${transitionTimingFunction}, opacity ${duration}ms ${transitionTimingFunction}` };
|
|
37
39
|
};
|
|
40
|
+
const transitionRef = (0, react.useRef)(0);
|
|
38
41
|
require_use_did_update.useDidUpdate(() => {
|
|
42
|
+
transitionRef.current += 1;
|
|
43
|
+
const transitionId = transitionRef.current;
|
|
44
|
+
const isCurrentTransition = () => transitionRef.current === transitionId;
|
|
39
45
|
if (transitionDuration !== 0) onTransitionStartEvent();
|
|
40
46
|
if (expanded) window.requestAnimationFrame(() => {
|
|
47
|
+
if (!isCurrentTransition() || !elementRef.current) return;
|
|
41
48
|
(0, react_dom.flushSync)(() => setState("entering"));
|
|
42
49
|
mergeStyles({
|
|
43
50
|
willChange: "width",
|
|
@@ -45,7 +52,14 @@ function useHorizontalCollapse({ transitionDuration, transitionTimingFunction =
|
|
|
45
52
|
overflow: "hidden"
|
|
46
53
|
});
|
|
47
54
|
window.requestAnimationFrame(() => {
|
|
55
|
+
if (!isCurrentTransition() || !elementRef.current) return;
|
|
48
56
|
const width = getElementWidth(elementRef);
|
|
57
|
+
if (!require_use_collapse.isMeasured(width)) {
|
|
58
|
+
setStyles({});
|
|
59
|
+
setState("entered");
|
|
60
|
+
onTransitionEndEvent();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
49
63
|
mergeStyles({
|
|
50
64
|
...getTransitionStyles(width),
|
|
51
65
|
width
|
|
@@ -53,17 +67,27 @@ function useHorizontalCollapse({ transitionDuration, transitionTimingFunction =
|
|
|
53
67
|
});
|
|
54
68
|
});
|
|
55
69
|
else window.requestAnimationFrame(() => {
|
|
70
|
+
if (!isCurrentTransition() || !elementRef.current) return;
|
|
56
71
|
(0, react_dom.flushSync)(() => setState("exiting"));
|
|
57
72
|
const width = getElementWidth(elementRef);
|
|
73
|
+
if (!require_use_collapse.isMeasured(width)) {
|
|
74
|
+
setStyles(collapsedStyles);
|
|
75
|
+
setState("exited");
|
|
76
|
+
onTransitionEndEvent();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
58
79
|
mergeStyles({
|
|
59
80
|
...getTransitionStyles(width),
|
|
60
81
|
willChange: "width",
|
|
61
82
|
width
|
|
62
83
|
});
|
|
63
|
-
window.requestAnimationFrame(() =>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
84
|
+
window.requestAnimationFrame(() => {
|
|
85
|
+
if (!isCurrentTransition() || !elementRef.current) return;
|
|
86
|
+
mergeStyles({
|
|
87
|
+
width: 0,
|
|
88
|
+
overflow: "hidden"
|
|
89
|
+
});
|
|
90
|
+
});
|
|
67
91
|
});
|
|
68
92
|
}, [expanded]);
|
|
69
93
|
const handleTransitionEnd = (event) => {
|
|
@@ -73,11 +97,11 @@ function useHorizontalCollapse({ transitionDuration, transitionTimingFunction =
|
|
|
73
97
|
if (width === styles.width) setStyles({});
|
|
74
98
|
else mergeStyles({ width });
|
|
75
99
|
setState("entered");
|
|
76
|
-
|
|
100
|
+
onTransitionEndEvent();
|
|
77
101
|
} else if (styles.width === 0) {
|
|
78
102
|
setStyles(collapsedStyles);
|
|
79
103
|
setState("exited");
|
|
80
|
-
|
|
104
|
+
onTransitionEndEvent();
|
|
81
105
|
}
|
|
82
106
|
};
|
|
83
107
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-horizontal-collapse.cjs","names":["mergeRefs"],"sources":["../../src/use-collapse/use-horizontal-collapse.ts"],"sourcesContent":["import React, { CSSProperties, useEffectEvent, useRef, useState } from 'react';\nimport { flushSync } from 'react-dom';\nimport { useDidUpdate } from '../use-did-update/use-did-update';\nimport { mergeRefs } from '../use-merged-ref/use-merged-ref';\n\nfunction getAutoWidthDuration(width: number | string) {\n if (!width || typeof width === 'string') {\n return 0;\n }\n const constant = width / 36;\n return Math.round((4 + 15 * constant ** 0.25 + constant / 5) * 10);\n}\n\nexport function getElementWidth(elementRef: React.RefObject<HTMLElement | null>) {\n return elementRef.current ? elementRef.current.scrollWidth : 'auto';\n}\n\nexport interface UseHorizontalCollapseInput {\n /** Expanded state */\n expanded: boolean;\n\n /** Transition duration in milliseconds, by default calculated based on content width */\n transitionDuration?: number;\n\n /** Transition timing function, `ease` by default */\n transitionTimingFunction?: string;\n\n /** Called when transition ends */\n onTransitionEnd?: () => void;\n\n /** Called when transition starts */\n onTransitionStart?: () => void;\n\n /** If true, collapsed content is kept in the DOM and hidden with `display: none` styles */\n keepMounted?: boolean;\n}\n\ninterface GetHorizontalCollapsePropsInput {\n style?: CSSProperties;\n ref?: React.Ref<HTMLDivElement>;\n}\n\ninterface GetHorizontalCollapsePropsReturnValue {\n 'aria-hidden': boolean;\n inert: boolean;\n ref: React.RefCallback<HTMLDivElement>;\n onTransitionEnd: (event: React.TransitionEvent<Element>) => void;\n style: React.CSSProperties;\n}\n\nexport type UseHorizontalCollapseState = 'entering' | 'entered' | 'exiting' | 'exited';\n\nexport interface UseHorizontalCollapseReturnValue {\n /** Current transition state */\n state: UseHorizontalCollapseState;\n\n /** Props to pass down to the collapsible element */\n getCollapseProps: (\n input?: GetHorizontalCollapsePropsInput\n ) => GetHorizontalCollapsePropsReturnValue;\n}\n\nexport function useHorizontalCollapse({\n transitionDuration,\n transitionTimingFunction = 'ease',\n onTransitionEnd,\n onTransitionStart,\n expanded,\n keepMounted,\n}: UseHorizontalCollapseInput): UseHorizontalCollapseReturnValue {\n const collapsedStyles = {\n width: 0,\n overflow: 'hidden',\n ...(keepMounted ? {} : { display: 'none' }),\n };\n\n const onTransitionStartEvent = useEffectEvent(() => onTransitionStart?.());\n\n const elementRef = useRef<HTMLElement>(null);\n const [styles, setStylesRaw] = useState<CSSProperties>(expanded ? {} : collapsedStyles);\n const [state, setState] = useState<UseHorizontalCollapseState>(expanded ? 'entered' : 'exited');\n const setStyles = (newStyles: React.SetStateAction<CSSProperties>) => {\n flushSync(() => setStylesRaw(newStyles));\n };\n\n const mergeStyles = (newStyles: CSSProperties) => {\n setStyles((oldStyles) => ({ ...oldStyles, ...newStyles }));\n };\n\n const getTransitionStyles = (width: number | string) => {\n const duration = transitionDuration ?? getAutoWidthDuration(width);\n return {\n transition: `width ${duration}ms ${transitionTimingFunction}, opacity ${duration}ms ${transitionTimingFunction}`,\n };\n };\n\n useDidUpdate(() => {\n const shouldTransition = transitionDuration !== 0;\n\n if (shouldTransition) {\n onTransitionStartEvent();\n }\n\n if (expanded) {\n window.requestAnimationFrame(() => {\n flushSync(() => setState('entering'));\n mergeStyles({ willChange: 'width', display: 'block', overflow: 'hidden' });\n window.requestAnimationFrame(() => {\n const width = getElementWidth(elementRef);\n mergeStyles({ ...getTransitionStyles(width), width });\n });\n });\n } else {\n window.requestAnimationFrame(() => {\n flushSync(() => setState('exiting'));\n const width = getElementWidth(elementRef);\n mergeStyles({ ...getTransitionStyles(width), willChange: 'width', width });\n window.requestAnimationFrame(() => mergeStyles({ width: 0, overflow: 'hidden' }));\n });\n }\n }, [expanded]);\n\n const handleTransitionEnd = (event: React.TransitionEvent): void => {\n if (event.target !== elementRef.current || event.propertyName !== 'width') {\n return;\n }\n\n if (expanded) {\n const width = getElementWidth(elementRef);\n\n if (width === styles.width) {\n setStyles({});\n } else {\n mergeStyles({ width });\n }\n\n setState('entered');\n
|
|
1
|
+
{"version":3,"file":"use-horizontal-collapse.cjs","names":["useEffectEvent","useRef","useState","isMeasured","mergeRefs"],"sources":["../../src/use-collapse/use-horizontal-collapse.ts"],"sourcesContent":["import React, { CSSProperties, useEffectEvent, useRef, useState } from 'react';\nimport { flushSync } from 'react-dom';\nimport { useDidUpdate } from '../use-did-update/use-did-update';\nimport { mergeRefs } from '../use-merged-ref/use-merged-ref';\nimport { isMeasured } from './use-collapse';\n\nfunction getAutoWidthDuration(width: number | string) {\n if (!width || typeof width === 'string') {\n return 0;\n }\n const constant = width / 36;\n return Math.round((4 + 15 * constant ** 0.25 + constant / 5) * 10);\n}\n\nexport function getElementWidth(elementRef: React.RefObject<HTMLElement | null>) {\n return elementRef.current ? elementRef.current.scrollWidth : 'auto';\n}\n\nexport interface UseHorizontalCollapseInput {\n /** Expanded state */\n expanded: boolean;\n\n /** Transition duration in milliseconds, by default calculated based on content width */\n transitionDuration?: number;\n\n /** Transition timing function, `ease` by default */\n transitionTimingFunction?: string;\n\n /** Called when transition ends */\n onTransitionEnd?: () => void;\n\n /** Called when transition starts */\n onTransitionStart?: () => void;\n\n /** If true, collapsed content is kept in the DOM and hidden with `display: none` styles */\n keepMounted?: boolean;\n}\n\ninterface GetHorizontalCollapsePropsInput {\n style?: CSSProperties;\n ref?: React.Ref<HTMLDivElement>;\n}\n\ninterface GetHorizontalCollapsePropsReturnValue {\n 'aria-hidden': boolean;\n inert: boolean;\n ref: React.RefCallback<HTMLDivElement>;\n onTransitionEnd: (event: React.TransitionEvent<Element>) => void;\n style: React.CSSProperties;\n}\n\nexport type UseHorizontalCollapseState = 'entering' | 'entered' | 'exiting' | 'exited';\n\nexport interface UseHorizontalCollapseReturnValue {\n /** Current transition state */\n state: UseHorizontalCollapseState;\n\n /** Props to pass down to the collapsible element */\n getCollapseProps: (\n input?: GetHorizontalCollapsePropsInput\n ) => GetHorizontalCollapsePropsReturnValue;\n}\n\nexport function useHorizontalCollapse({\n transitionDuration,\n transitionTimingFunction = 'ease',\n onTransitionEnd,\n onTransitionStart,\n expanded,\n keepMounted,\n}: UseHorizontalCollapseInput): UseHorizontalCollapseReturnValue {\n const collapsedStyles = {\n width: 0,\n overflow: 'hidden',\n ...(keepMounted ? {} : { display: 'none' }),\n };\n\n const onTransitionStartEvent = useEffectEvent(() => onTransitionStart?.());\n const onTransitionEndEvent = useEffectEvent(() => onTransitionEnd?.());\n\n const elementRef = useRef<HTMLElement>(null);\n const [styles, setStylesRaw] = useState<CSSProperties>(expanded ? {} : collapsedStyles);\n const [state, setState] = useState<UseHorizontalCollapseState>(expanded ? 'entered' : 'exited');\n const setStyles = (newStyles: React.SetStateAction<CSSProperties>) => {\n flushSync(() => setStylesRaw(newStyles));\n };\n\n const mergeStyles = (newStyles: CSSProperties) => {\n setStyles((oldStyles) => ({ ...oldStyles, ...newStyles }));\n };\n\n const getTransitionStyles = (width: number | string) => {\n const duration = transitionDuration ?? getAutoWidthDuration(width);\n return {\n transition: `width ${duration}ms ${transitionTimingFunction}, opacity ${duration}ms ${transitionTimingFunction}`,\n };\n };\n\n const transitionRef = useRef(0);\n\n useDidUpdate(() => {\n transitionRef.current += 1;\n const transitionId = transitionRef.current;\n const isCurrentTransition = () => transitionRef.current === transitionId;\n const shouldTransition = transitionDuration !== 0;\n\n if (shouldTransition) {\n onTransitionStartEvent();\n }\n\n if (expanded) {\n window.requestAnimationFrame(() => {\n if (!isCurrentTransition() || !elementRef.current) {\n return;\n }\n\n flushSync(() => setState('entering'));\n mergeStyles({ willChange: 'width', display: 'block', overflow: 'hidden' });\n window.requestAnimationFrame(() => {\n if (!isCurrentTransition() || !elementRef.current) {\n return;\n }\n\n const width = getElementWidth(elementRef);\n\n if (!isMeasured(width)) {\n setStyles({});\n setState('entered');\n onTransitionEndEvent();\n return;\n }\n\n mergeStyles({ ...getTransitionStyles(width), width });\n });\n });\n } else {\n window.requestAnimationFrame(() => {\n if (!isCurrentTransition() || !elementRef.current) {\n return;\n }\n\n flushSync(() => setState('exiting'));\n const width = getElementWidth(elementRef);\n\n if (!isMeasured(width)) {\n setStyles(collapsedStyles);\n setState('exited');\n onTransitionEndEvent();\n return;\n }\n\n mergeStyles({ ...getTransitionStyles(width), willChange: 'width', width });\n window.requestAnimationFrame(() => {\n if (!isCurrentTransition() || !elementRef.current) {\n return;\n }\n\n mergeStyles({ width: 0, overflow: 'hidden' });\n });\n });\n }\n }, [expanded]);\n\n const handleTransitionEnd = (event: React.TransitionEvent): void => {\n if (event.target !== elementRef.current || event.propertyName !== 'width') {\n return;\n }\n\n if (expanded) {\n const width = getElementWidth(elementRef);\n\n if (width === styles.width) {\n setStyles({});\n } else {\n mergeStyles({ width });\n }\n\n setState('entered');\n onTransitionEndEvent();\n } else if (styles.width === 0) {\n setStyles(collapsedStyles);\n setState('exited');\n onTransitionEndEvent();\n }\n };\n\n return {\n state,\n getCollapseProps: (input) => ({\n 'aria-hidden': !expanded,\n inert: !expanded,\n ref: mergeRefs(elementRef, input?.ref),\n onTransitionEnd: handleTransitionEnd,\n style: { boxSizing: 'border-box', ...input?.style, ...styles },\n }),\n };\n}\n\nexport namespace useHorizontalCollapse {\n export type Input = UseHorizontalCollapseInput;\n export type ReturnValue = UseHorizontalCollapseReturnValue;\n export type State = UseHorizontalCollapseState;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-counter.cjs","names":["clamp"],"sources":["../../src/use-counter/use-counter.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { clamp } from '../utils';\n\nconst DEFAULT_OPTIONS = {\n min: -Infinity,\n max: Infinity,\n};\n\nexport interface UseCounterOptions {\n min?: number;\n max?: number;\n step?: number;\n}\n\nexport interface UseCounterHandlers {\n increment: () => void;\n decrement: () => void;\n set: (value: number) => void;\n reset: () => void;\n}\n\nexport type UseCounterReturnValue = [number, UseCounterHandlers];\n\nexport function useCounter(initialValue = 0, options?: UseCounterOptions): UseCounterReturnValue {\n const { min, max, step: _step = 1 } = { ...DEFAULT_OPTIONS, ...options };\n const step = Math.abs(_step);\n const [count, setCount] = useState<number>(clamp(initialValue, min, max));\n\n const increment = useCallback(\n () => setCount((current) => clamp(current + step, min, max)),\n [min, max, step]\n );\n\n const decrement = useCallback(\n () => setCount((current) => clamp(current - step, min, max)),\n [min, max, step]\n );\n\n const set = useCallback((value: number) => setCount(clamp(value, min, max)), [min, max]);\n\n const reset = useCallback(\n () => setCount(clamp(initialValue, min, max)),\n [initialValue, min, max]\n );\n\n return [count, { increment, decrement, set, reset }];\n}\n\nexport namespace useCounter {\n export type Options = UseCounterOptions;\n export type Handlers = UseCounterHandlers;\n export type ReturnValue = UseCounterReturnValue;\n}\n"],"mappings":";;;;AAGA,MAAM,kBAAkB;CACtB,KAAK;CACL,KAAK;AACP;AAiBA,SAAgB,WAAW,eAAe,GAAG,SAAoD;CAC/F,MAAM,EAAE,KAAK,KAAK,MAAM,QAAQ,MAAM;EAAE,GAAG;EAAiB,GAAG;CAAQ;CACvE,MAAM,OAAO,KAAK,IAAI,KAAK;CAC3B,MAAM,CAAC,OAAO,aAAA,
|
|
1
|
+
{"version":3,"file":"use-counter.cjs","names":["useState","clamp","useCallback"],"sources":["../../src/use-counter/use-counter.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { clamp } from '../utils';\n\nconst DEFAULT_OPTIONS = {\n min: -Infinity,\n max: Infinity,\n};\n\nexport interface UseCounterOptions {\n min?: number;\n max?: number;\n step?: number;\n}\n\nexport interface UseCounterHandlers {\n increment: () => void;\n decrement: () => void;\n set: (value: number) => void;\n reset: () => void;\n}\n\nexport type UseCounterReturnValue = [number, UseCounterHandlers];\n\nexport function useCounter(initialValue = 0, options?: UseCounterOptions): UseCounterReturnValue {\n const { min, max, step: _step = 1 } = { ...DEFAULT_OPTIONS, ...options };\n const step = Math.abs(_step);\n const [count, setCount] = useState<number>(clamp(initialValue, min, max));\n\n const increment = useCallback(\n () => setCount((current) => clamp(current + step, min, max)),\n [min, max, step]\n );\n\n const decrement = useCallback(\n () => setCount((current) => clamp(current - step, min, max)),\n [min, max, step]\n );\n\n const set = useCallback((value: number) => setCount(clamp(value, min, max)), [min, max]);\n\n const reset = useCallback(\n () => setCount(clamp(initialValue, min, max)),\n [initialValue, min, max]\n );\n\n return [count, { increment, decrement, set, reset }];\n}\n\nexport namespace useCounter {\n export type Options = UseCounterOptions;\n export type Handlers = UseCounterHandlers;\n export type ReturnValue = UseCounterReturnValue;\n}\n"],"mappings":";;;;AAGA,MAAM,kBAAkB;CACtB,KAAK;CACL,KAAK;AACP;AAiBA,SAAgB,WAAW,eAAe,GAAG,SAAoD;CAC/F,MAAM,EAAE,KAAK,KAAK,MAAM,QAAQ,MAAM;EAAE,GAAG;EAAiB,GAAG;CAAQ;CACvE,MAAM,OAAO,KAAK,IAAI,KAAK;CAC3B,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAiBC,cAAAA,MAAM,cAAc,KAAK,GAAG,CAAC;CAmBxE,OAAO,CAAC,OAAO;EAAE,YAAA,GAjBCC,MAAAA,YAAAA,OACV,UAAU,YAAYD,cAAAA,MAAM,UAAU,MAAM,KAAK,GAAG,CAAC,GAC3D;GAAC;GAAK;GAAK;EAAI,CAeQ;EAAG,YAAA,GAZVC,MAAAA,YAAAA,OACV,UAAU,YAAYD,cAAAA,MAAM,UAAU,MAAM,KAAK,GAAG,CAAC,GAC3D;GAAC;GAAK;GAAK;EAAI,CAUmB;EAAG,MAAA,GAP3BC,MAAAA,YAAAA,EAAa,UAAkB,SAASD,cAAAA,MAAM,OAAO,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,CAO7C;EAAG,QAAA,GAL9BC,MAAAA,YAAAA,OACN,SAASD,cAAAA,MAAM,cAAc,KAAK,GAAG,CAAC,GAC5C;GAAC;GAAc;GAAK;EAAG,CAGuB;CAAE,CAAC;AACrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-debounced-callback.cjs","names":["useCallbackRef"],"sources":["../../src/use-debounced-callback/use-debounced-callback.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react';\nimport { useCallbackRef } from '../utils';\n\nexport interface UseDebouncedCallbackOptions {\n delay: number;\n flushOnUnmount?: boolean;\n leading?: boolean;\n maxWait?: number;\n}\n\nexport type UseDebouncedCallbackReturnValue<T extends (...args: any[]) => any> = ((\n ...args: Parameters<T>\n) => void) & { flush: () => void; cancel: () => void; isPending: () => boolean };\n\nexport function useDebouncedCallback<T extends (...args: any[]) => any>(\n callback: T,\n options: number | UseDebouncedCallbackOptions\n) {\n const { delay, flushOnUnmount, leading, maxWait } =\n typeof options === 'number'\n ? {\n delay: options,\n flushOnUnmount: false,\n leading: false,\n maxWait: undefined as number | undefined,\n }\n : options;\n\n const handleCallback = useCallbackRef(callback);\n const debounceTimerRef = useRef(0);\n const maxWaitTimerRef = useRef(0);\n const latestArgsRef = useRef<Parameters<T> | null>(null);\n\n const lastCallback = useMemo(() => {\n const currentCallback = Object.assign(\n (...args: Parameters<T>) => {\n window.clearTimeout(debounceTimerRef.current);\n latestArgsRef.current = args;\n\n const isFirstCall = currentCallback._isFirstCall;\n currentCallback._isFirstCall = false;\n\n function clearTimeoutAndLeadingRef() {\n window.clearTimeout(debounceTimerRef.current);\n window.clearTimeout(maxWaitTimerRef.current);\n debounceTimerRef.current = 0;\n maxWaitTimerRef.current = 0;\n currentCallback._isFirstCall = true;\n currentCallback._hasPendingCallback = false;\n }\n\n function startMaxWaitTimer() {\n if (maxWait !== undefined && maxWaitTimerRef.current === 0) {\n maxWaitTimerRef.current = window.setTimeout(() => {\n if (debounceTimerRef.current !== 0) {\n const latestArgs = latestArgsRef.current!;\n clearTimeoutAndLeadingRef();\n handleCallback(...latestArgs);\n }\n }, maxWait);\n }\n }\n\n if (leading && isFirstCall) {\n handleCallback(...args);\n\n const resetLeadingState = () => {\n clearTimeoutAndLeadingRef();\n };\n\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n debounceTimerRef.current = window.setTimeout(resetLeadingState, delay);\n startMaxWaitTimer();\n return;\n }\n\n if (leading && !isFirstCall) {\n currentCallback._hasPendingCallback = true;\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n\n const resetLeadingState = () => {\n clearTimeoutAndLeadingRef();\n };\n debounceTimerRef.current = window.setTimeout(resetLeadingState, delay);\n startMaxWaitTimer();\n return;\n }\n\n currentCallback._hasPendingCallback = true;\n\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n debounceTimerRef.current = window.setTimeout(flush, delay);\n startMaxWaitTimer();\n },\n {\n flush: () => {},\n cancel: () => {},\n isPending: () => currentCallback._hasPendingCallback,\n _isFirstCall: true,\n _hasPendingCallback: false,\n }\n );\n return currentCallback;\n }, [handleCallback, delay, leading, maxWait]);\n\n useEffect(\n () => () => {\n if (flushOnUnmount) {\n lastCallback.flush();\n } else {\n lastCallback.cancel();\n }\n },\n [lastCallback, flushOnUnmount]\n );\n\n return lastCallback;\n}\n\nexport namespace useDebouncedCallback {\n export type Options = UseDebouncedCallbackOptions;\n export type ReturnValue<T extends (...args: any[]) => any> = UseDebouncedCallbackReturnValue<T>;\n}\n"],"mappings":";;;;AAcA,SAAgB,qBACd,UACA,SACA;CACA,MAAM,EAAE,OAAO,gBAAgB,SAAS,YACtC,OAAO,YAAY,WACf;EACE,OAAO;EACP,gBAAgB;EAChB,SAAS;EACT,SAAS,KAAA;CACX,IACA;CAEN,MAAM,iBAAiBA,yBAAAA,eAAe,QAAQ;CAC9C,MAAM,oBAAA,
|
|
1
|
+
{"version":3,"file":"use-debounced-callback.cjs","names":["useCallbackRef","useRef","useMemo"],"sources":["../../src/use-debounced-callback/use-debounced-callback.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from 'react';\nimport { useCallbackRef } from '../utils';\n\nexport interface UseDebouncedCallbackOptions {\n delay: number;\n flushOnUnmount?: boolean;\n leading?: boolean;\n maxWait?: number;\n}\n\nexport type UseDebouncedCallbackReturnValue<T extends (...args: any[]) => any> = ((\n ...args: Parameters<T>\n) => void) & { flush: () => void; cancel: () => void; isPending: () => boolean };\n\nexport function useDebouncedCallback<T extends (...args: any[]) => any>(\n callback: T,\n options: number | UseDebouncedCallbackOptions\n) {\n const { delay, flushOnUnmount, leading, maxWait } =\n typeof options === 'number'\n ? {\n delay: options,\n flushOnUnmount: false,\n leading: false,\n maxWait: undefined as number | undefined,\n }\n : options;\n\n const handleCallback = useCallbackRef(callback);\n const debounceTimerRef = useRef(0);\n const maxWaitTimerRef = useRef(0);\n const latestArgsRef = useRef<Parameters<T> | null>(null);\n\n const lastCallback = useMemo(() => {\n const currentCallback = Object.assign(\n (...args: Parameters<T>) => {\n window.clearTimeout(debounceTimerRef.current);\n latestArgsRef.current = args;\n\n const isFirstCall = currentCallback._isFirstCall;\n currentCallback._isFirstCall = false;\n\n function clearTimeoutAndLeadingRef() {\n window.clearTimeout(debounceTimerRef.current);\n window.clearTimeout(maxWaitTimerRef.current);\n debounceTimerRef.current = 0;\n maxWaitTimerRef.current = 0;\n currentCallback._isFirstCall = true;\n currentCallback._hasPendingCallback = false;\n }\n\n function startMaxWaitTimer() {\n if (maxWait !== undefined && maxWaitTimerRef.current === 0) {\n maxWaitTimerRef.current = window.setTimeout(() => {\n if (debounceTimerRef.current !== 0) {\n const latestArgs = latestArgsRef.current!;\n clearTimeoutAndLeadingRef();\n handleCallback(...latestArgs);\n }\n }, maxWait);\n }\n }\n\n if (leading && isFirstCall) {\n handleCallback(...args);\n\n const resetLeadingState = () => {\n clearTimeoutAndLeadingRef();\n };\n\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n debounceTimerRef.current = window.setTimeout(resetLeadingState, delay);\n startMaxWaitTimer();\n return;\n }\n\n if (leading && !isFirstCall) {\n currentCallback._hasPendingCallback = true;\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n\n const resetLeadingState = () => {\n clearTimeoutAndLeadingRef();\n };\n debounceTimerRef.current = window.setTimeout(resetLeadingState, delay);\n startMaxWaitTimer();\n return;\n }\n\n currentCallback._hasPendingCallback = true;\n\n const flush = () => {\n if (debounceTimerRef.current !== 0) {\n clearTimeoutAndLeadingRef();\n handleCallback(...args);\n }\n };\n\n const cancel = () => {\n clearTimeoutAndLeadingRef();\n };\n\n currentCallback.flush = flush;\n currentCallback.cancel = cancel;\n debounceTimerRef.current = window.setTimeout(flush, delay);\n startMaxWaitTimer();\n },\n {\n flush: () => {},\n cancel: () => {},\n isPending: () => currentCallback._hasPendingCallback,\n _isFirstCall: true,\n _hasPendingCallback: false,\n }\n );\n return currentCallback;\n }, [handleCallback, delay, leading, maxWait]);\n\n useEffect(\n () => () => {\n if (flushOnUnmount) {\n lastCallback.flush();\n } else {\n lastCallback.cancel();\n }\n },\n [lastCallback, flushOnUnmount]\n );\n\n return lastCallback;\n}\n\nexport namespace useDebouncedCallback {\n export type Options = UseDebouncedCallbackOptions;\n export type ReturnValue<T extends (...args: any[]) => any> = UseDebouncedCallbackReturnValue<T>;\n}\n"],"mappings":";;;;AAcA,SAAgB,qBACd,UACA,SACA;CACA,MAAM,EAAE,OAAO,gBAAgB,SAAS,YACtC,OAAO,YAAY,WACf;EACE,OAAO;EACP,gBAAgB;EAChB,SAAS;EACT,SAAS,KAAA;CACX,IACA;CAEN,MAAM,iBAAiBA,yBAAAA,eAAe,QAAQ;CAC9C,MAAM,oBAAA,GAAmBC,MAAAA,OAAAA,CAAO,CAAC;CACjC,MAAM,mBAAA,GAAkBA,MAAAA,OAAAA,CAAO,CAAC;CAChC,MAAM,iBAAA,GAAgBA,MAAAA,OAAAA,CAA6B,IAAI;CAEvD,MAAM,gBAAA,GAAeC,MAAAA,QAAAA,OAAc;EACjC,MAAM,kBAAkB,OAAO,QAC5B,GAAG,SAAwB;GAC1B,OAAO,aAAa,iBAAiB,OAAO;GAC5C,cAAc,UAAU;GAExB,MAAM,cAAc,gBAAgB;GACpC,gBAAgB,eAAe;GAE/B,SAAS,4BAA4B;IACnC,OAAO,aAAa,iBAAiB,OAAO;IAC5C,OAAO,aAAa,gBAAgB,OAAO;IAC3C,iBAAiB,UAAU;IAC3B,gBAAgB,UAAU;IAC1B,gBAAgB,eAAe;IAC/B,gBAAgB,sBAAsB;GACxC;GAEA,SAAS,oBAAoB;IAC3B,IAAI,YAAY,KAAA,KAAa,gBAAgB,YAAY,GACvD,gBAAgB,UAAU,OAAO,iBAAiB;KAChD,IAAI,iBAAiB,YAAY,GAAG;MAClC,MAAM,aAAa,cAAc;MACjC,0BAA0B;MAC1B,eAAe,GAAG,UAAU;KAC9B;IACF,GAAG,OAAO;GAEd;GAEA,IAAI,WAAW,aAAa;IAC1B,eAAe,GAAG,IAAI;IAEtB,MAAM,0BAA0B;KAC9B,0BAA0B;IAC5B;IAEA,MAAM,cAAc;KAClB,IAAI,iBAAiB,YAAY,GAAG;MAClC,0BAA0B;MAC1B,eAAe,GAAG,IAAI;KACxB;IACF;IAEA,MAAM,eAAe;KACnB,0BAA0B;IAC5B;IAEA,gBAAgB,QAAQ;IACxB,gBAAgB,SAAS;IACzB,iBAAiB,UAAU,OAAO,WAAW,mBAAmB,KAAK;IACrE,kBAAkB;IAClB;GACF;GAEA,IAAI,WAAW,CAAC,aAAa;IAC3B,gBAAgB,sBAAsB;IACtC,MAAM,cAAc;KAClB,IAAI,iBAAiB,YAAY,GAAG;MAClC,0BAA0B;MAC1B,eAAe,GAAG,IAAI;KACxB;IACF;IAEA,MAAM,eAAe;KACnB,0BAA0B;IAC5B;IAEA,gBAAgB,QAAQ;IACxB,gBAAgB,SAAS;IAEzB,MAAM,0BAA0B;KAC9B,0BAA0B;IAC5B;IACA,iBAAiB,UAAU,OAAO,WAAW,mBAAmB,KAAK;IACrE,kBAAkB;IAClB;GACF;GAEA,gBAAgB,sBAAsB;GAEtC,MAAM,cAAc;IAClB,IAAI,iBAAiB,YAAY,GAAG;KAClC,0BAA0B;KAC1B,eAAe,GAAG,IAAI;IACxB;GACF;GAEA,MAAM,eAAe;IACnB,0BAA0B;GAC5B;GAEA,gBAAgB,QAAQ;GACxB,gBAAgB,SAAS;GACzB,iBAAiB,UAAU,OAAO,WAAW,OAAO,KAAK;GACzD,kBAAkB;EACpB,GACA;GACE,aAAa,CAAC;GACd,cAAc,CAAC;GACf,iBAAiB,gBAAgB;GACjC,cAAc;GACd,qBAAqB;EACvB,CACF;EACA,OAAO;CACT,GAAG;EAAC;EAAgB;EAAO;EAAS;CAAO,CAAC;CAE5C,CAAA,GAAA,MAAA,UAAA,aACc;EACV,IAAI,gBACF,aAAa,MAAM;OAEnB,aAAa,OAAO;CAExB,GACA,CAAC,cAAc,cAAc,CAC/B;CAEA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-debounced-state.cjs","names":[],"sources":["../../src/use-debounced-state/use-debounced-state.ts"],"sourcesContent":["import { SetStateAction, useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseDebouncedStateOptions {\n leading?: boolean;\n}\n\nexport type UseDebouncedStateReturnValue<T> = [T, (newValue: SetStateAction<T>) => void];\n\nexport function useDebouncedState<T = any>(\n defaultValue: T,\n wait: number,\n options: UseDebouncedStateOptions = { leading: false }\n): UseDebouncedStateReturnValue<T> {\n const [value, setValue] = useState(defaultValue);\n const timeoutRef = useRef<number | null>(null);\n const leadingRef = useRef(true);\n\n const clearTimeout = () => window.clearTimeout(timeoutRef.current!);\n useEffect(() => clearTimeout, []);\n\n const debouncedSetValue = useCallback(\n (newValue: SetStateAction<T>) => {\n clearTimeout();\n if (leadingRef.current && options.leading) {\n setValue(newValue);\n } else {\n timeoutRef.current = window.setTimeout(() => {\n leadingRef.current = true;\n setValue(newValue);\n }, wait);\n }\n leadingRef.current = false;\n },\n [options.leading, wait]\n );\n\n return [value, debouncedSetValue] as const;\n}\n\nexport namespace useDebouncedState {\n export type Options = UseDebouncedStateOptions;\n export type ReturnValue<T> = UseDebouncedStateReturnValue<T>;\n}\n"],"mappings":";;;AAQA,SAAgB,kBACd,cACA,MACA,UAAoC,EAAE,SAAS,MAAM,GACpB;CACjC,MAAM,CAAC,OAAO,aAAA,
|
|
1
|
+
{"version":3,"file":"use-debounced-state.cjs","names":["useState","useRef","useCallback"],"sources":["../../src/use-debounced-state/use-debounced-state.ts"],"sourcesContent":["import { SetStateAction, useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseDebouncedStateOptions {\n leading?: boolean;\n}\n\nexport type UseDebouncedStateReturnValue<T> = [T, (newValue: SetStateAction<T>) => void];\n\nexport function useDebouncedState<T = any>(\n defaultValue: T,\n wait: number,\n options: UseDebouncedStateOptions = { leading: false }\n): UseDebouncedStateReturnValue<T> {\n const [value, setValue] = useState(defaultValue);\n const timeoutRef = useRef<number | null>(null);\n const leadingRef = useRef(true);\n\n const clearTimeout = () => window.clearTimeout(timeoutRef.current!);\n useEffect(() => clearTimeout, []);\n\n const debouncedSetValue = useCallback(\n (newValue: SetStateAction<T>) => {\n clearTimeout();\n if (leadingRef.current && options.leading) {\n setValue(newValue);\n } else {\n timeoutRef.current = window.setTimeout(() => {\n leadingRef.current = true;\n setValue(newValue);\n }, wait);\n }\n leadingRef.current = false;\n },\n [options.leading, wait]\n );\n\n return [value, debouncedSetValue] as const;\n}\n\nexport namespace useDebouncedState {\n export type Options = UseDebouncedStateOptions;\n export type ReturnValue<T> = UseDebouncedStateReturnValue<T>;\n}\n"],"mappings":";;;AAQA,SAAgB,kBACd,cACA,MACA,UAAoC,EAAE,SAAS,MAAM,GACpB;CACjC,MAAM,CAAC,OAAO,aAAA,GAAYA,MAAAA,SAAAA,CAAS,YAAY;CAC/C,MAAM,cAAA,GAAaC,MAAAA,OAAAA,CAAsB,IAAI;CAC7C,MAAM,cAAA,GAAaA,MAAAA,OAAAA,CAAO,IAAI;CAE9B,MAAM,qBAAqB,OAAO,aAAa,WAAW,OAAQ;CAClE,CAAA,GAAA,MAAA,UAAA,OAAgB,cAAc,CAAC,CAAC;CAkBhC,OAAO,CAAC,QAAA,GAhBkBC,MAAAA,YAAAA,EACvB,aAAgC;EAC/B,aAAa;EACb,IAAI,WAAW,WAAW,QAAQ,SAChC,SAAS,QAAQ;OAEjB,WAAW,UAAU,OAAO,iBAAiB;GAC3C,WAAW,UAAU;GACrB,SAAS,QAAQ;EACnB,GAAG,IAAI;EAET,WAAW,UAAU;CACvB,GACA,CAAC,QAAQ,SAAS,IAAI,CAGO,CAAC;AAClC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-debounced-value.cjs","names":[],"sources":["../../src/use-debounced-value/use-debounced-value.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseDebouncedValueOptions {\n leading?: boolean;\n}\n\nexport interface UseDebouncedValueHandlers {\n cancel: () => void;\n flush: () => void;\n}\n\nexport type UseDebouncedValueReturnValue<T> = [T, () => void, UseDebouncedValueHandlers];\n\nexport function useDebouncedValue<T = any>(\n value: T,\n wait: number,\n options: UseDebouncedValueOptions = { leading: false }\n): UseDebouncedValueReturnValue<T> {\n const [_value, setValue] = useState(value);\n const mountedRef = useRef(false);\n const timeoutRef = useRef<number | null>(null);\n const cooldownRef = useRef(false);\n\n const latestValueRef = useRef(value);\n latestValueRef.current = value;\n\n const clearTimer = useCallback(() => {\n window.clearTimeout(timeoutRef.current!);\n timeoutRef.current = null;\n }, []);\n\n const cancel = useCallback(() => {\n clearTimer();\n cooldownRef.current = false;\n }, []);\n\n const flush = useCallback(() => {\n if (timeoutRef.current) {\n cancel();\n cooldownRef.current = false;\n setValue(latestValueRef.current);\n }\n }, []);\n\n useEffect(() => {\n if (mountedRef.current) {\n clearTimer();\n\n if (!cooldownRef.current && options.leading) {\n cooldownRef.current = true;\n setValue(value);\n timeoutRef.current = window.setTimeout(() => {\n cooldownRef.current = false;\n }, wait);\n } else {\n timeoutRef.current = window.setTimeout(() => {\n cooldownRef.current = false;\n setValue(value);\n }, wait);\n }\n }\n }, [value, options.leading, wait]);\n\n useEffect(() => {\n mountedRef.current = true;\n return cancel;\n }, []);\n\n return [_value, cancel, { cancel, flush }];\n}\n\nexport namespace useDebouncedValue {\n export type Handlers = UseDebouncedValueHandlers;\n export type Options = UseDebouncedValueOptions;\n export type ReturnValue<T> = UseDebouncedValueReturnValue<T>;\n}\n"],"mappings":";;;AAaA,SAAgB,kBACd,OACA,MACA,UAAoC,EAAE,SAAS,MAAM,GACpB;CACjC,MAAM,CAAC,QAAQ,aAAA,
|
|
1
|
+
{"version":3,"file":"use-debounced-value.cjs","names":["useState","useRef","useCallback"],"sources":["../../src/use-debounced-value/use-debounced-value.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nexport interface UseDebouncedValueOptions {\n leading?: boolean;\n}\n\nexport interface UseDebouncedValueHandlers {\n cancel: () => void;\n flush: () => void;\n}\n\nexport type UseDebouncedValueReturnValue<T> = [T, () => void, UseDebouncedValueHandlers];\n\nexport function useDebouncedValue<T = any>(\n value: T,\n wait: number,\n options: UseDebouncedValueOptions = { leading: false }\n): UseDebouncedValueReturnValue<T> {\n const [_value, setValue] = useState(value);\n const mountedRef = useRef(false);\n const timeoutRef = useRef<number | null>(null);\n const cooldownRef = useRef(false);\n\n const latestValueRef = useRef(value);\n latestValueRef.current = value;\n\n const clearTimer = useCallback(() => {\n window.clearTimeout(timeoutRef.current!);\n timeoutRef.current = null;\n }, []);\n\n const cancel = useCallback(() => {\n clearTimer();\n cooldownRef.current = false;\n }, []);\n\n const flush = useCallback(() => {\n if (timeoutRef.current) {\n cancel();\n cooldownRef.current = false;\n setValue(latestValueRef.current);\n }\n }, []);\n\n useEffect(() => {\n if (mountedRef.current) {\n clearTimer();\n\n if (!cooldownRef.current && options.leading) {\n cooldownRef.current = true;\n setValue(value);\n timeoutRef.current = window.setTimeout(() => {\n cooldownRef.current = false;\n }, wait);\n } else {\n timeoutRef.current = window.setTimeout(() => {\n cooldownRef.current = false;\n setValue(value);\n }, wait);\n }\n }\n }, [value, options.leading, wait]);\n\n useEffect(() => {\n mountedRef.current = true;\n return cancel;\n }, []);\n\n return [_value, cancel, { cancel, flush }];\n}\n\nexport namespace useDebouncedValue {\n export type Handlers = UseDebouncedValueHandlers;\n export type Options = UseDebouncedValueOptions;\n export type ReturnValue<T> = UseDebouncedValueReturnValue<T>;\n}\n"],"mappings":";;;AAaA,SAAgB,kBACd,OACA,MACA,UAAoC,EAAE,SAAS,MAAM,GACpB;CACjC,MAAM,CAAC,QAAQ,aAAA,GAAYA,MAAAA,SAAAA,CAAS,KAAK;CACzC,MAAM,cAAA,GAAaC,MAAAA,OAAAA,CAAO,KAAK;CAC/B,MAAM,cAAA,GAAaA,MAAAA,OAAAA,CAAsB,IAAI;CAC7C,MAAM,eAAA,GAAcA,MAAAA,OAAAA,CAAO,KAAK;CAEhC,MAAM,kBAAA,GAAiBA,MAAAA,OAAAA,CAAO,KAAK;CACnC,eAAe,UAAU;CAEzB,MAAM,cAAA,GAAaC,MAAAA,YAAAA,OAAkB;EACnC,OAAO,aAAa,WAAW,OAAQ;EACvC,WAAW,UAAU;CACvB,GAAG,CAAC,CAAC;CAEL,MAAM,UAAA,GAASA,MAAAA,YAAAA,OAAkB;EAC/B,WAAW;EACX,YAAY,UAAU;CACxB,GAAG,CAAC,CAAC;CAEL,MAAM,SAAA,GAAQA,MAAAA,YAAAA,OAAkB;EAC9B,IAAI,WAAW,SAAS;GACtB,OAAO;GACP,YAAY,UAAU;GACtB,SAAS,eAAe,OAAO;EACjC;CACF,GAAG,CAAC,CAAC;CAEL,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,IAAI,WAAW,SAAS;GACtB,WAAW;GAEX,IAAI,CAAC,YAAY,WAAW,QAAQ,SAAS;IAC3C,YAAY,UAAU;IACtB,SAAS,KAAK;IACd,WAAW,UAAU,OAAO,iBAAiB;KAC3C,YAAY,UAAU;IACxB,GAAG,IAAI;GACT,OACE,WAAW,UAAU,OAAO,iBAAiB;IAC3C,YAAY,UAAU;IACtB,SAAS,KAAK;GAChB,GAAG,IAAI;EAEX;CACF,GAAG;EAAC;EAAO,QAAQ;EAAS;CAAI,CAAC;CAEjC,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,WAAW,UAAU;EACrB,OAAO;CACT,GAAG,CAAC,CAAC;CAEL,OAAO;EAAC;EAAQ;EAAQ;GAAE;GAAQ;EAAM;CAAC;AAC3C"}
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
let react = require("react");
|
|
3
3
|
//#region packages/@mantine/hooks/src/use-did-update/use-did-update.ts
|
|
4
|
+
function dependenciesChanged(previous, next) {
|
|
5
|
+
return previous.length !== next.length || next.some((dep, index) => !Object.is(dep, previous[index]));
|
|
6
|
+
}
|
|
4
7
|
function useDidUpdate(fn, dependencies) {
|
|
5
8
|
const mounted = (0, react.useRef)(false);
|
|
6
|
-
(0, react.
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
+
const previousRender = (0, react.useRef)(null);
|
|
10
|
+
const previousDependencies = (0, react.useRef)(void 0);
|
|
11
|
+
const render = {};
|
|
9
12
|
(0, react.useEffect)(() => {
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
const isSameRender = previousRender.current === render;
|
|
14
|
+
const previous = previousDependencies.current;
|
|
15
|
+
previousRender.current = render;
|
|
16
|
+
previousDependencies.current = dependencies;
|
|
17
|
+
if (!mounted.current) {
|
|
18
|
+
mounted.current = true;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (isSameRender) return;
|
|
22
|
+
if (dependencies && previous && !dependenciesChanged(previous, dependencies)) return;
|
|
23
|
+
return fn();
|
|
12
24
|
}, dependencies);
|
|
13
25
|
}
|
|
14
26
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-did-update.cjs","names":[],"sources":["../../src/use-did-update/use-did-update.ts"],"sourcesContent":["import { DependencyList, EffectCallback, useEffect, useRef } from 'react';\n\nexport function useDidUpdate(fn: EffectCallback, dependencies?: DependencyList) {\n const mounted = useRef(false);\n
|
|
1
|
+
{"version":3,"file":"use-did-update.cjs","names":["useRef"],"sources":["../../src/use-did-update/use-did-update.ts"],"sourcesContent":["import { DependencyList, EffectCallback, useEffect, useRef } from 'react';\n\nfunction dependenciesChanged(previous: DependencyList, next: DependencyList) {\n return (\n previous.length !== next.length || next.some((dep, index) => !Object.is(dep, previous[index]))\n );\n}\n\nexport function useDidUpdate(fn: EffectCallback, dependencies?: DependencyList) {\n const mounted = useRef(false);\n const previousRender = useRef<object>(null);\n const previousDependencies = useRef<DependencyList | undefined>(undefined);\n const render = {};\n\n useEffect(() => {\n const isSameRender = previousRender.current === render;\n const previous = previousDependencies.current;\n\n previousRender.current = render;\n previousDependencies.current = dependencies;\n\n if (!mounted.current) {\n mounted.current = true;\n return undefined;\n }\n\n if (isSameRender) {\n return undefined;\n }\n\n if (dependencies && previous && !dependenciesChanged(previous, dependencies)) {\n return undefined;\n }\n\n return fn();\n }, dependencies);\n}\n"],"mappings":";;;AAEA,SAAS,oBAAoB,UAA0B,MAAsB;CAC3E,OACE,SAAS,WAAW,KAAK,UAAU,KAAK,MAAM,KAAK,UAAU,CAAC,OAAO,GAAG,KAAK,SAAS,MAAM,CAAC;AAEjG;AAEA,SAAgB,aAAa,IAAoB,cAA+B;CAC9E,MAAM,WAAA,GAAUA,MAAAA,OAAAA,CAAO,KAAK;CAC5B,MAAM,kBAAA,GAAiBA,MAAAA,OAAAA,CAAe,IAAI;CAC1C,MAAM,wBAAA,GAAuBA,MAAAA,OAAAA,CAAmC,KAAA,CAAS;CACzE,MAAM,SAAS,CAAC;CAEhB,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,MAAM,eAAe,eAAe,YAAY;EAChD,MAAM,WAAW,qBAAqB;EAEtC,eAAe,UAAU;EACzB,qBAAqB,UAAU;EAE/B,IAAI,CAAC,QAAQ,SAAS;GACpB,QAAQ,UAAU;GAClB;EACF;EAEA,IAAI,cACF;EAGF,IAAI,gBAAgB,YAAY,CAAC,oBAAoB,UAAU,YAAY,GACzE;EAGF,OAAO,GAAG;CACZ,GAAG,YAAY;AACjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-disclosure.cjs","names":[],"sources":["../../src/use-disclosure/use-disclosure.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\n\nexport interface UseDisclosureOptions {\n onOpen?: () => void;\n onClose?: () => void;\n}\n\nexport interface UseDisclosureHandlers {\n set: (value: boolean) => void;\n open: () => void;\n close: () => void;\n toggle: () => void;\n}\n\nexport type UseDisclosureReturnValue = [boolean, UseDisclosureHandlers];\n\nexport function useDisclosure(\n initialState = false,\n options: UseDisclosureOptions = {}\n): UseDisclosureReturnValue {\n const [opened, setOpened] = useState(initialState);\n\n const open = useCallback(() => {\n setOpened((isOpened) => {\n if (!isOpened) {\n options.onOpen?.();\n return true;\n }\n return isOpened;\n });\n }, [options.onOpen]);\n\n const close = useCallback(() => {\n setOpened((isOpened) => {\n if (isOpened) {\n options.onClose?.();\n return false;\n }\n return isOpened;\n });\n }, [options.onClose]);\n\n const toggle = useCallback(() => {\n opened ? close() : open();\n }, [close, open, opened]);\n\n return [opened, { open, close, toggle, set: setOpened }];\n}\n\nexport namespace useDisclosure {\n export type Options = UseDisclosureOptions;\n export type Handlers = UseDisclosureHandlers;\n export type ReturnValue = UseDisclosureReturnValue;\n}\n"],"mappings":";;;AAgBA,SAAgB,cACd,eAAe,OACf,UAAgC,CAAC,GACP;CAC1B,MAAM,CAAC,QAAQ,cAAA,
|
|
1
|
+
{"version":3,"file":"use-disclosure.cjs","names":["useState","useCallback"],"sources":["../../src/use-disclosure/use-disclosure.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\n\nexport interface UseDisclosureOptions {\n onOpen?: () => void;\n onClose?: () => void;\n}\n\nexport interface UseDisclosureHandlers {\n set: (value: boolean) => void;\n open: () => void;\n close: () => void;\n toggle: () => void;\n}\n\nexport type UseDisclosureReturnValue = [boolean, UseDisclosureHandlers];\n\nexport function useDisclosure(\n initialState = false,\n options: UseDisclosureOptions = {}\n): UseDisclosureReturnValue {\n const [opened, setOpened] = useState(initialState);\n\n const open = useCallback(() => {\n setOpened((isOpened) => {\n if (!isOpened) {\n options.onOpen?.();\n return true;\n }\n return isOpened;\n });\n }, [options.onOpen]);\n\n const close = useCallback(() => {\n setOpened((isOpened) => {\n if (isOpened) {\n options.onClose?.();\n return false;\n }\n return isOpened;\n });\n }, [options.onClose]);\n\n const toggle = useCallback(() => {\n opened ? close() : open();\n }, [close, open, opened]);\n\n return [opened, { open, close, toggle, set: setOpened }];\n}\n\nexport namespace useDisclosure {\n export type Options = UseDisclosureOptions;\n export type Handlers = UseDisclosureHandlers;\n export type ReturnValue = UseDisclosureReturnValue;\n}\n"],"mappings":";;;AAgBA,SAAgB,cACd,eAAe,OACf,UAAgC,CAAC,GACP;CAC1B,MAAM,CAAC,QAAQ,cAAA,GAAaA,MAAAA,SAAAA,CAAS,YAAY;CAEjD,MAAM,QAAA,GAAOC,MAAAA,YAAAA,OAAkB;EAC7B,WAAW,aAAa;GACtB,IAAI,CAAC,UAAU;IACb,QAAQ,SAAS;IACjB,OAAO;GACT;GACA,OAAO;EACT,CAAC;CACH,GAAG,CAAC,QAAQ,MAAM,CAAC;CAEnB,MAAM,SAAA,GAAQA,MAAAA,YAAAA,OAAkB;EAC9B,WAAW,aAAa;GACtB,IAAI,UAAU;IACZ,QAAQ,UAAU;IAClB,OAAO;GACT;GACA,OAAO;EACT,CAAC;CACH,GAAG,CAAC,QAAQ,OAAO,CAAC;CAMpB,OAAO,CAAC,QAAQ;EAAE;EAAM;EAAO,SAAA,GAJhBA,MAAAA,YAAAA,OAAkB;GAC/B,SAAS,MAAM,IAAI,KAAK;EAC1B,GAAG;GAAC;GAAO;GAAM;EAAM,CAEa;EAAG,KAAK;CAAU,CAAC;AACzD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-document-visibility.cjs","names":[],"sources":["../../src/use-document-visibility/use-document-visibility.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nexport function useDocumentVisibility(): DocumentVisibilityState {\n const [documentVisibility, setDocumentVisibility] = useState<DocumentVisibilityState>('visible');\n\n useEffect(() => {\n setDocumentVisibility(document.visibilityState);\n const listener = () => setDocumentVisibility(document.visibilityState);\n document.addEventListener('visibilitychange', listener);\n return () => document.removeEventListener('visibilitychange', listener);\n }, []);\n\n return documentVisibility;\n}\n"],"mappings":";;;AAEA,SAAgB,wBAAiD;CAC/D,MAAM,CAAC,oBAAoB,0BAAA,
|
|
1
|
+
{"version":3,"file":"use-document-visibility.cjs","names":["useState"],"sources":["../../src/use-document-visibility/use-document-visibility.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nexport function useDocumentVisibility(): DocumentVisibilityState {\n const [documentVisibility, setDocumentVisibility] = useState<DocumentVisibilityState>('visible');\n\n useEffect(() => {\n setDocumentVisibility(document.visibilityState);\n const listener = () => setDocumentVisibility(document.visibilityState);\n document.addEventListener('visibilitychange', listener);\n return () => document.removeEventListener('visibilitychange', listener);\n }, []);\n\n return documentVisibility;\n}\n"],"mappings":";;;AAEA,SAAgB,wBAAiD;CAC/D,MAAM,CAAC,oBAAoB,0BAAA,GAAyBA,MAAAA,SAAAA,CAAkC,SAAS;CAE/F,CAAA,GAAA,MAAA,UAAA,OAAgB;EACd,sBAAsB,SAAS,eAAe;EAC9C,MAAM,iBAAiB,sBAAsB,SAAS,eAAe;EACrE,SAAS,iBAAiB,oBAAoB,QAAQ;EACtD,aAAa,SAAS,oBAAoB,oBAAoB,QAAQ;CACxE,GAAG,CAAC,CAAC;CAEL,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-drag.cjs","names":[],"sources":["../../src/use-drag/use-drag.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\n/* eslint-disable @typescript-eslint/no-deprecated */\nimport { useCallback, useRef, useState } from 'react';\n\ntype Vector2 = [number, number];\n\nexport interface UseDragState {\n /** Current pointer position [x, y] */\n xy: Vector2;\n\n /** Position where the gesture started [x, y] */\n initial: Vector2;\n\n /** Displacement from start [x, y], respects axis constraint */\n movement: Vector2;\n\n /** Change since previous event [x, y] */\n delta: Vector2;\n\n /** Absolute distance per axis [x, y] */\n distance: Vector2;\n\n /** Movement direction per axis: -1, 0, or 1 */\n direction: Vector2;\n\n /** Speed per axis in px/ms */\n velocity: Vector2;\n\n /** Time since drag started in ms */\n elapsedTime: number;\n\n /** `true` on the first handler call after the threshold is met */\n first: boolean;\n\n /** `true` on the last handler call (pointer released or canceled) */\n last: boolean;\n\n /** `true` while the gesture is ongoing */\n active: boolean;\n\n /** `true` when the gesture qualifies as a tap (requires `filterTaps: true`) */\n tap: boolean;\n\n /** `true` when the gesture was interrupted by a `pointercancel` event */\n canceled: boolean;\n\n /** Function to programmatically cancel the current gesture */\n cancel: () => void;\n\n /** The source `PointerEvent` */\n event: PointerEvent;\n}\n\nexport interface UseDragOptions {\n /** Constrain movement to a specific axis. `'lock'` locks to whichever axis has more movement after `axisThreshold` is exceeded. */\n axis?: 'x' | 'y' | 'lock';\n\n /** Movement in px required to determine axis when `axis` is `'lock'`, `1` by default */\n axisThreshold?: number;\n\n /** When `true`, the last state includes `tap: true` when total distance is below `tapThreshold`, `false` by default */\n filterTaps?: boolean;\n\n /** Max displacement in px to still be considered a tap, `3` by default */\n tapThreshold?: number;\n\n /** Minimum displacement in px before the drag activates. Can be a number (both axes) or `[x, y]`. `0` by default */\n threshold?: number | Vector2;\n\n /** Enable or disable the hook, `true` by default */\n enabled?: boolean;\n}\n\nexport interface UseDragReturnValue<T extends HTMLElement = any> {\n /** Ref callback to attach to the draggable element */\n ref: React.RefCallback<T | null>;\n\n /** `true` while the element is being dragged */\n active: boolean;\n}\n\nconst VELOCITY_DECAY_MS = 100;\n\nfunction sign(n: number): -1 | 0 | 1 {\n if (n > 0) {\n return 1;\n }\n if (n < 0) {\n return -1;\n }\n return 0;\n}\n\nfunction getThresholdVector(threshold: number | Vector2 | undefined): Vector2 {\n const t = threshold ?? 0;\n if (typeof t === 'number') {\n return [t, t];\n }\n return t;\n}\n\ninterface DragInternalState {\n isActive: boolean;\n pointerId: number;\n startXY: Vector2;\n prevXY: Vector2;\n startTimestamp: number;\n prevTimestamp: number;\n thresholdMet: boolean;\n firstFired: boolean;\n lockedAxis: 'x' | 'y' | null;\n canceled: boolean;\n lastVelocity: Vector2;\n}\n\nfunction createInitialState(): DragInternalState {\n return {\n isActive: false,\n pointerId: -1,\n startXY: [0, 0],\n prevXY: [0, 0],\n startTimestamp: 0,\n prevTimestamp: 0,\n thresholdMet: false,\n firstFired: false,\n lockedAxis: null,\n canceled: false,\n lastVelocity: [0, 0],\n };\n}\n\nexport function useDrag<T extends HTMLElement = any>(\n handler: (state: UseDragState) => void,\n options: UseDragOptions = {}\n): UseDragReturnValue<T> {\n const [active, setActive] = useState(false);\n\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const stateRef = useRef<DragInternalState>(createInitialState());\n const documentControllerRef = useRef<AbortController | null>(null);\n\n const refCallback: React.RefCallback<T | null> = useCallback((node) => {\n if (!node) {\n return undefined;\n }\n\n const elementController = new AbortController();\n\n const applyAxisConstraint = (v: Vector2): Vector2 => {\n const opts = optionsRef.current;\n const s = stateRef.current;\n\n if (opts.axis === 'x') {\n return [v[0], 0];\n }\n if (opts.axis === 'y') {\n return [0, v[1]];\n }\n if (opts.axis === 'lock') {\n if (s.lockedAxis === null) {\n const t = opts.axisThreshold ?? 1;\n if (Math.abs(v[0]) > t || Math.abs(v[1]) > t) {\n s.lockedAxis = Math.abs(v[0]) >= Math.abs(v[1]) ? 'x' : 'y';\n }\n }\n if (s.lockedAxis === 'x') {\n return [v[0], 0];\n }\n if (s.lockedAxis === 'y') {\n return [0, v[1]];\n }\n }\n return v;\n };\n\n const resetDrag = () => {\n const s = stateRef.current;\n s.isActive = false;\n s.pointerId = -1;\n s.thresholdMet = false;\n s.firstFired = false;\n s.lockedAxis = null;\n s.canceled = false;\n setActive(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n };\n\n const cancel = () => {\n if (stateRef.current.isActive) {\n stateRef.current.canceled = true;\n resetDrag();\n }\n };\n\n const activateDrag = () => {\n setActive(true);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (optionsRef.current.enabled === false) {\n return;\n }\n if (event.button !== 0) {\n return;\n }\n if (stateRef.current.isActive) {\n return;\n }\n\n const s = stateRef.current;\n s.isActive = true;\n s.pointerId = event.pointerId;\n s.startXY = [event.clientX, event.clientY];\n s.prevXY = [event.clientX, event.clientY];\n s.startTimestamp = event.timeStamp;\n s.prevTimestamp = event.timeStamp;\n s.thresholdMet = false;\n s.firstFired = false;\n s.lockedAxis = null;\n s.canceled = false;\n s.lastVelocity = [0, 0];\n\n const [tx, ty] = getThresholdVector(optionsRef.current.threshold);\n if (tx === 0 && ty === 0) {\n s.thresholdMet = true;\n s.firstFired = true;\n activateDrag();\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [event.clientX, event.clientY],\n movement: [0, 0],\n delta: [0, 0],\n distance: [0, 0],\n direction: [0, 0],\n velocity: [0, 0],\n elapsedTime: 0,\n first: true,\n last: false,\n active: true,\n tap: false,\n canceled: false,\n cancel,\n event,\n });\n }\n\n documentControllerRef.current?.abort();\n documentControllerRef.current = new AbortController();\n const sig = documentControllerRef.current.signal;\n\n document.addEventListener('pointermove', onPointerMove, { signal: sig });\n document.addEventListener('pointerup', onPointerUp, { signal: sig });\n document.addEventListener('pointercancel', onPointerCancel, { signal: sig });\n };\n\n const onPointerMove = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n\n if (!s.thresholdMet) {\n const [tx, ty] = getThresholdVector(optionsRef.current.threshold);\n if (Math.abs(rawMovement[0]) < tx && Math.abs(rawMovement[1]) < ty) {\n s.prevXY = [event.clientX, event.clientY];\n s.prevTimestamp = event.timeStamp;\n return;\n }\n s.thresholdMet = true;\n activateDrag();\n }\n\n const movement = applyAxisConstraint(rawMovement);\n const rawDelta: Vector2 = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];\n const delta = applyAxisConstraint(rawDelta);\n const timeDelta = event.timeStamp - s.prevTimestamp;\n const velocity: Vector2 =\n timeDelta > 0\n ? [Math.abs(delta[0]) / timeDelta, Math.abs(delta[1]) / timeDelta]\n : s.lastVelocity;\n\n s.lastVelocity = velocity;\n const isFirst = !s.firstFired;\n s.firstFired = true;\n s.prevXY = [event.clientX, event.clientY];\n s.prevTimestamp = event.timeStamp;\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta,\n distance: [Math.abs(movement[0]), Math.abs(movement[1])],\n direction: [sign(delta[0]), sign(delta[1])],\n velocity,\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: isFirst,\n last: false,\n active: true,\n tap: false,\n canceled: false,\n cancel,\n event,\n });\n };\n\n const onPointerUp = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const opts = optionsRef.current;\n\n if (!s.thresholdMet) {\n if (opts.filterTaps) {\n const rawMov: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const mov = applyAxisConstraint(rawMov);\n const dist: Vector2 = [Math.abs(mov[0]), Math.abs(mov[1])];\n const maxDist = Math.max(dist[0], dist[1]);\n const isTap = maxDist < (opts.tapThreshold ?? 3);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement: mov,\n delta: mov,\n distance: dist,\n direction: [sign(mov[0]), sign(mov[1])],\n velocity: [0, 0],\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: true,\n last: true,\n active: false,\n tap: isTap,\n canceled: false,\n cancel,\n event,\n });\n }\n resetDrag();\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const movement = applyAxisConstraint(rawMovement);\n const distance: Vector2 = [Math.abs(movement[0]), Math.abs(movement[1])];\n const rawDelta: Vector2 = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];\n const delta = applyAxisConstraint(rawDelta);\n\n const timeSinceLastMove = event.timeStamp - s.prevTimestamp;\n const velocity: Vector2 = timeSinceLastMove > VELOCITY_DECAY_MS ? [0, 0] : s.lastVelocity;\n\n const maxDistance = Math.max(distance[0], distance[1]);\n const tap = opts.filterTaps === true && maxDistance < (opts.tapThreshold ?? 3);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta,\n distance,\n direction: [sign(delta[0]), sign(delta[1])],\n velocity,\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: !s.firstFired,\n last: true,\n active: false,\n tap,\n canceled: false,\n cancel,\n event,\n });\n\n resetDrag();\n };\n\n const onPointerCancel = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const movement = applyAxisConstraint(rawMovement);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta: [0, 0],\n distance: [Math.abs(movement[0]), Math.abs(movement[1])],\n direction: [0, 0],\n velocity: [0, 0],\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: !s.firstFired,\n last: true,\n active: false,\n tap: false,\n canceled: true,\n cancel,\n event,\n });\n\n resetDrag();\n };\n\n node.addEventListener('pointerdown', onPointerDown, {\n signal: elementController.signal,\n });\n\n return () => {\n elementController.abort();\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n if (stateRef.current.isActive) {\n stateRef.current.isActive = false;\n setActive(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n }\n };\n }, []);\n\n return { ref: refCallback, active };\n}\n\nexport namespace useDrag {\n export type State = UseDragState;\n export type Options = UseDragOptions;\n export type ReturnValue<T extends HTMLElement = any> = UseDragReturnValue<T>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-drag.cjs","names":["useState","useRef","useCallback"],"sources":["../../src/use-drag/use-drag.ts"],"sourcesContent":["// Required to disable for webkit-user-select, although deprecated, it is still required for Safari support\n/* eslint-disable @typescript-eslint/no-deprecated */\nimport { useCallback, useRef, useState } from 'react';\n\ntype Vector2 = [number, number];\n\nexport interface UseDragState {\n /** Current pointer position [x, y] */\n xy: Vector2;\n\n /** Position where the gesture started [x, y] */\n initial: Vector2;\n\n /** Displacement from start [x, y], respects axis constraint */\n movement: Vector2;\n\n /** Change since previous event [x, y] */\n delta: Vector2;\n\n /** Absolute distance per axis [x, y] */\n distance: Vector2;\n\n /** Movement direction per axis: -1, 0, or 1 */\n direction: Vector2;\n\n /** Speed per axis in px/ms */\n velocity: Vector2;\n\n /** Time since drag started in ms */\n elapsedTime: number;\n\n /** `true` on the first handler call after the threshold is met */\n first: boolean;\n\n /** `true` on the last handler call (pointer released or canceled) */\n last: boolean;\n\n /** `true` while the gesture is ongoing */\n active: boolean;\n\n /** `true` when the gesture qualifies as a tap (requires `filterTaps: true`) */\n tap: boolean;\n\n /** `true` when the gesture was interrupted by a `pointercancel` event */\n canceled: boolean;\n\n /** Function to programmatically cancel the current gesture */\n cancel: () => void;\n\n /** The source `PointerEvent` */\n event: PointerEvent;\n}\n\nexport interface UseDragOptions {\n /** Constrain movement to a specific axis. `'lock'` locks to whichever axis has more movement after `axisThreshold` is exceeded. */\n axis?: 'x' | 'y' | 'lock';\n\n /** Movement in px required to determine axis when `axis` is `'lock'`, `1` by default */\n axisThreshold?: number;\n\n /** When `true`, the last state includes `tap: true` when total distance is below `tapThreshold`, `false` by default */\n filterTaps?: boolean;\n\n /** Max displacement in px to still be considered a tap, `3` by default */\n tapThreshold?: number;\n\n /** Minimum displacement in px before the drag activates. Can be a number (both axes) or `[x, y]`. `0` by default */\n threshold?: number | Vector2;\n\n /** Enable or disable the hook, `true` by default */\n enabled?: boolean;\n}\n\nexport interface UseDragReturnValue<T extends HTMLElement = any> {\n /** Ref callback to attach to the draggable element */\n ref: React.RefCallback<T | null>;\n\n /** `true` while the element is being dragged */\n active: boolean;\n}\n\nconst VELOCITY_DECAY_MS = 100;\n\nfunction sign(n: number): -1 | 0 | 1 {\n if (n > 0) {\n return 1;\n }\n if (n < 0) {\n return -1;\n }\n return 0;\n}\n\nfunction getThresholdVector(threshold: number | Vector2 | undefined): Vector2 {\n const t = threshold ?? 0;\n if (typeof t === 'number') {\n return [t, t];\n }\n return t;\n}\n\ninterface DragInternalState {\n isActive: boolean;\n pointerId: number;\n startXY: Vector2;\n prevXY: Vector2;\n startTimestamp: number;\n prevTimestamp: number;\n thresholdMet: boolean;\n firstFired: boolean;\n lockedAxis: 'x' | 'y' | null;\n canceled: boolean;\n lastVelocity: Vector2;\n}\n\nfunction createInitialState(): DragInternalState {\n return {\n isActive: false,\n pointerId: -1,\n startXY: [0, 0],\n prevXY: [0, 0],\n startTimestamp: 0,\n prevTimestamp: 0,\n thresholdMet: false,\n firstFired: false,\n lockedAxis: null,\n canceled: false,\n lastVelocity: [0, 0],\n };\n}\n\nexport function useDrag<T extends HTMLElement = any>(\n handler: (state: UseDragState) => void,\n options: UseDragOptions = {}\n): UseDragReturnValue<T> {\n const [active, setActive] = useState(false);\n\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const stateRef = useRef<DragInternalState>(createInitialState());\n const documentControllerRef = useRef<AbortController | null>(null);\n\n const refCallback: React.RefCallback<T | null> = useCallback((node) => {\n if (!node) {\n return undefined;\n }\n\n const elementController = new AbortController();\n\n const applyAxisConstraint = (v: Vector2): Vector2 => {\n const opts = optionsRef.current;\n const s = stateRef.current;\n\n if (opts.axis === 'x') {\n return [v[0], 0];\n }\n if (opts.axis === 'y') {\n return [0, v[1]];\n }\n if (opts.axis === 'lock') {\n if (s.lockedAxis === null) {\n const t = opts.axisThreshold ?? 1;\n if (Math.abs(v[0]) > t || Math.abs(v[1]) > t) {\n s.lockedAxis = Math.abs(v[0]) >= Math.abs(v[1]) ? 'x' : 'y';\n }\n }\n if (s.lockedAxis === 'x') {\n return [v[0], 0];\n }\n if (s.lockedAxis === 'y') {\n return [0, v[1]];\n }\n }\n return v;\n };\n\n const resetDrag = () => {\n const s = stateRef.current;\n s.isActive = false;\n s.pointerId = -1;\n s.thresholdMet = false;\n s.firstFired = false;\n s.lockedAxis = null;\n s.canceled = false;\n setActive(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n };\n\n const cancel = () => {\n if (stateRef.current.isActive) {\n stateRef.current.canceled = true;\n resetDrag();\n }\n };\n\n const activateDrag = () => {\n setActive(true);\n document.body.style.userSelect = 'none';\n document.body.style.webkitUserSelect = 'none';\n };\n\n const onPointerDown = (event: PointerEvent) => {\n if (optionsRef.current.enabled === false) {\n return;\n }\n if (event.button !== 0) {\n return;\n }\n if (stateRef.current.isActive) {\n return;\n }\n\n const s = stateRef.current;\n s.isActive = true;\n s.pointerId = event.pointerId;\n s.startXY = [event.clientX, event.clientY];\n s.prevXY = [event.clientX, event.clientY];\n s.startTimestamp = event.timeStamp;\n s.prevTimestamp = event.timeStamp;\n s.thresholdMet = false;\n s.firstFired = false;\n s.lockedAxis = null;\n s.canceled = false;\n s.lastVelocity = [0, 0];\n\n const [tx, ty] = getThresholdVector(optionsRef.current.threshold);\n if (tx === 0 && ty === 0) {\n s.thresholdMet = true;\n s.firstFired = true;\n activateDrag();\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [event.clientX, event.clientY],\n movement: [0, 0],\n delta: [0, 0],\n distance: [0, 0],\n direction: [0, 0],\n velocity: [0, 0],\n elapsedTime: 0,\n first: true,\n last: false,\n active: true,\n tap: false,\n canceled: false,\n cancel,\n event,\n });\n }\n\n documentControllerRef.current?.abort();\n documentControllerRef.current = new AbortController();\n const sig = documentControllerRef.current.signal;\n\n document.addEventListener('pointermove', onPointerMove, { signal: sig });\n document.addEventListener('pointerup', onPointerUp, { signal: sig });\n document.addEventListener('pointercancel', onPointerCancel, { signal: sig });\n };\n\n const onPointerMove = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n\n if (!s.thresholdMet) {\n const [tx, ty] = getThresholdVector(optionsRef.current.threshold);\n if (Math.abs(rawMovement[0]) < tx && Math.abs(rawMovement[1]) < ty) {\n s.prevXY = [event.clientX, event.clientY];\n s.prevTimestamp = event.timeStamp;\n return;\n }\n s.thresholdMet = true;\n activateDrag();\n }\n\n const movement = applyAxisConstraint(rawMovement);\n const rawDelta: Vector2 = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];\n const delta = applyAxisConstraint(rawDelta);\n const timeDelta = event.timeStamp - s.prevTimestamp;\n const velocity: Vector2 =\n timeDelta > 0\n ? [Math.abs(delta[0]) / timeDelta, Math.abs(delta[1]) / timeDelta]\n : s.lastVelocity;\n\n s.lastVelocity = velocity;\n const isFirst = !s.firstFired;\n s.firstFired = true;\n s.prevXY = [event.clientX, event.clientY];\n s.prevTimestamp = event.timeStamp;\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta,\n distance: [Math.abs(movement[0]), Math.abs(movement[1])],\n direction: [sign(delta[0]), sign(delta[1])],\n velocity,\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: isFirst,\n last: false,\n active: true,\n tap: false,\n canceled: false,\n cancel,\n event,\n });\n };\n\n const onPointerUp = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const opts = optionsRef.current;\n\n if (!s.thresholdMet) {\n if (opts.filterTaps) {\n const rawMov: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const mov = applyAxisConstraint(rawMov);\n const dist: Vector2 = [Math.abs(mov[0]), Math.abs(mov[1])];\n const maxDist = Math.max(dist[0], dist[1]);\n const isTap = maxDist < (opts.tapThreshold ?? 3);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement: mov,\n delta: mov,\n distance: dist,\n direction: [sign(mov[0]), sign(mov[1])],\n velocity: [0, 0],\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: true,\n last: true,\n active: false,\n tap: isTap,\n canceled: false,\n cancel,\n event,\n });\n }\n resetDrag();\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const movement = applyAxisConstraint(rawMovement);\n const distance: Vector2 = [Math.abs(movement[0]), Math.abs(movement[1])];\n const rawDelta: Vector2 = [event.clientX - s.prevXY[0], event.clientY - s.prevXY[1]];\n const delta = applyAxisConstraint(rawDelta);\n\n const timeSinceLastMove = event.timeStamp - s.prevTimestamp;\n const velocity: Vector2 = timeSinceLastMove > VELOCITY_DECAY_MS ? [0, 0] : s.lastVelocity;\n\n const maxDistance = Math.max(distance[0], distance[1]);\n const tap = opts.filterTaps === true && maxDistance < (opts.tapThreshold ?? 3);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta,\n distance,\n direction: [sign(delta[0]), sign(delta[1])],\n velocity,\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: !s.firstFired,\n last: true,\n active: false,\n tap,\n canceled: false,\n cancel,\n event,\n });\n\n resetDrag();\n };\n\n const onPointerCancel = (event: PointerEvent) => {\n const s = stateRef.current;\n if (!s.isActive || event.pointerId !== s.pointerId) {\n return;\n }\n\n const rawMovement: Vector2 = [event.clientX - s.startXY[0], event.clientY - s.startXY[1]];\n const movement = applyAxisConstraint(rawMovement);\n\n handlerRef.current({\n xy: [event.clientX, event.clientY],\n initial: [...s.startXY],\n movement,\n delta: [0, 0],\n distance: [Math.abs(movement[0]), Math.abs(movement[1])],\n direction: [0, 0],\n velocity: [0, 0],\n elapsedTime: event.timeStamp - s.startTimestamp,\n first: !s.firstFired,\n last: true,\n active: false,\n tap: false,\n canceled: true,\n cancel,\n event,\n });\n\n resetDrag();\n };\n\n node.addEventListener('pointerdown', onPointerDown, {\n signal: elementController.signal,\n });\n\n return () => {\n elementController.abort();\n documentControllerRef.current?.abort();\n documentControllerRef.current = null;\n if (stateRef.current.isActive) {\n stateRef.current.isActive = false;\n setActive(false);\n document.body.style.userSelect = '';\n document.body.style.webkitUserSelect = '';\n }\n };\n }, []);\n\n return { ref: refCallback, active };\n}\n\nexport namespace useDrag {\n export type State = UseDragState;\n export type Options = UseDragOptions;\n export type ReturnValue<T extends HTMLElement = any> = UseDragReturnValue<T>;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-event-listener.cjs","names":[],"sources":["../../src/use-event-listener/use-event-listener.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\nexport function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = any>(\n type: K,\n listener: (this: T, ev: HTMLElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions\n): React.RefCallback<T | null> {\n const previousListener = useRef<Function | null>(null);\n const previousNode = useRef<T | null>(null);\n\n const callbackRef: React.RefCallback<T | null> = useCallback(\n (node) => {\n if (!node) {\n return;\n }\n\n if (previousNode.current && previousListener.current) {\n previousNode.current.removeEventListener(type, previousListener.current as any, options);\n }\n\n node.addEventListener(type, listener as any, options);\n previousNode.current = node;\n previousListener.current = listener;\n },\n [type, listener, options]\n );\n\n useEffect(\n () => () => {\n if (previousNode.current && previousListener.current) {\n previousNode.current.removeEventListener(type, previousListener.current as any, options);\n }\n },\n [type, options]\n );\n\n return callbackRef;\n}\n"],"mappings":";;;AAEA,SAAgB,iBACd,MACA,UACA,SAC6B;CAC7B,MAAM,oBAAA,
|
|
1
|
+
{"version":3,"file":"use-event-listener.cjs","names":["useRef","useCallback"],"sources":["../../src/use-event-listener/use-event-listener.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from 'react';\n\nexport function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement = any>(\n type: K,\n listener: (this: T, ev: HTMLElementEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions\n): React.RefCallback<T | null> {\n const previousListener = useRef<Function | null>(null);\n const previousNode = useRef<T | null>(null);\n\n const callbackRef: React.RefCallback<T | null> = useCallback(\n (node) => {\n if (!node) {\n return;\n }\n\n if (previousNode.current && previousListener.current) {\n previousNode.current.removeEventListener(type, previousListener.current as any, options);\n }\n\n node.addEventListener(type, listener as any, options);\n previousNode.current = node;\n previousListener.current = listener;\n },\n [type, listener, options]\n );\n\n useEffect(\n () => () => {\n if (previousNode.current && previousListener.current) {\n previousNode.current.removeEventListener(type, previousListener.current as any, options);\n }\n },\n [type, options]\n );\n\n return callbackRef;\n}\n"],"mappings":";;;AAEA,SAAgB,iBACd,MACA,UACA,SAC6B;CAC7B,MAAM,oBAAA,GAAmBA,MAAAA,OAAAA,CAAwB,IAAI;CACrD,MAAM,gBAAA,GAAeA,MAAAA,OAAAA,CAAiB,IAAI;CAE1C,MAAM,eAAA,GAA2CC,MAAAA,YAAAA,EAC9C,SAAS;EACR,IAAI,CAAC,MACH;EAGF,IAAI,aAAa,WAAW,iBAAiB,SAC3C,aAAa,QAAQ,oBAAoB,MAAM,iBAAiB,SAAgB,OAAO;EAGzF,KAAK,iBAAiB,MAAM,UAAiB,OAAO;EACpD,aAAa,UAAU;EACvB,iBAAiB,UAAU;CAC7B,GACA;EAAC;EAAM;EAAU;CAAO,CAC1B;CAEA,CAAA,GAAA,MAAA,UAAA,aACc;EACV,IAAI,aAAa,WAAW,iBAAiB,SAC3C,aAAa,QAAQ,oBAAoB,MAAM,iBAAiB,SAAgB,OAAO;CAE3F,GACA,CAAC,MAAM,OAAO,CAChB;CAEA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-eye-dropper.cjs","names":[],"sources":["../../src/use-eye-dropper/use-eye-dropper.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nexport interface EyeDropperOpenOptions {\n signal?: AbortSignal;\n}\n\nexport interface EyeDropperOpenReturnType {\n sRGBHex: string;\n}\n\nexport interface UseEyeDropperReturnValue {\n supported: boolean;\n open: (options?: EyeDropperOpenOptions) => Promise<EyeDropperOpenReturnType | undefined>;\n}\n\nexport function useEyeDropper(): UseEyeDropperReturnValue {\n const [supported, setSupported] = useState(false);\n\n useIsomorphicEffect(() => {\n setSupported(typeof window !== 'undefined' && !isOpera() && 'EyeDropper' in window);\n }, []);\n\n const open = useCallback(\n (options: EyeDropperOpenOptions = {}): Promise<EyeDropperOpenReturnType | undefined> => {\n if (supported) {\n const eyeDropper = new (window as any).EyeDropper();\n return eyeDropper.open(options);\n }\n\n return Promise.resolve(undefined);\n },\n [supported]\n );\n\n return { supported, open };\n}\n\nfunction isOpera() {\n return navigator.userAgent.includes('OPR');\n}\n"],"mappings":";;;;AAgBA,SAAgB,gBAA0C;CACxD,MAAM,CAAC,WAAW,iBAAA,
|
|
1
|
+
{"version":3,"file":"use-eye-dropper.cjs","names":["useState","useCallback"],"sources":["../../src/use-eye-dropper/use-eye-dropper.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nexport interface EyeDropperOpenOptions {\n signal?: AbortSignal;\n}\n\nexport interface EyeDropperOpenReturnType {\n sRGBHex: string;\n}\n\nexport interface UseEyeDropperReturnValue {\n supported: boolean;\n open: (options?: EyeDropperOpenOptions) => Promise<EyeDropperOpenReturnType | undefined>;\n}\n\nexport function useEyeDropper(): UseEyeDropperReturnValue {\n const [supported, setSupported] = useState(false);\n\n useIsomorphicEffect(() => {\n setSupported(typeof window !== 'undefined' && !isOpera() && 'EyeDropper' in window);\n }, []);\n\n const open = useCallback(\n (options: EyeDropperOpenOptions = {}): Promise<EyeDropperOpenReturnType | undefined> => {\n if (supported) {\n const eyeDropper = new (window as any).EyeDropper();\n return eyeDropper.open(options);\n }\n\n return Promise.resolve(undefined);\n },\n [supported]\n );\n\n return { supported, open };\n}\n\nfunction isOpera() {\n return navigator.userAgent.includes('OPR');\n}\n"],"mappings":";;;;AAgBA,SAAgB,gBAA0C;CACxD,MAAM,CAAC,WAAW,iBAAA,GAAgBA,MAAAA,SAAAA,CAAS,KAAK;CAEhD,8BAAA,0BAA0B;EACxB,aAAa,OAAO,WAAW,eAAe,CAAC,QAAQ,KAAK,gBAAgB,MAAM;CACpF,GAAG,CAAC,CAAC;CAcL,OAAO;EAAE;EAAW,OAAA,GAZPC,MAAAA,YAAAA,EACV,UAAiC,CAAC,MAAqD;GACtF,IAAI,WAEF,OAAO,IADiB,OAAe,WACvB,CAAC,CAAC,KAAK,OAAO;GAGhC,OAAO,QAAQ,QAAQ,KAAA,CAAS;EAClC,GACA,CAAC,SAAS,CAGW;CAAE;AAC3B;AAEA,SAAS,UAAU;CACjB,OAAO,UAAU,UAAU,SAAS,KAAK;AAC3C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-favicon.cjs","names":[],"sources":["../../src/use-favicon/use-favicon.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nconst MIME_TYPES: Record<string, string> = {\n ico: 'image/x-icon',\n png: 'image/png',\n svg: 'image/svg+xml',\n gif: 'image/gif',\n};\n\nexport function useFavicon(url: string) {\n const link = useRef<HTMLLinkElement>(null);\n\n useIsomorphicEffect(() => {\n if (!url) {\n return;\n }\n\n if (!link.current) {\n const existingElements = document.querySelectorAll<HTMLLinkElement>('link[rel*=\"icon\"]');\n existingElements.forEach((element) => document.head.removeChild(element));\n\n const element = document.createElement('link');\n element.rel = 'shortcut icon';\n link.current = element;\n document.querySelector('head')!.appendChild(element);\n }\n\n const splittedUrl = url.split('.');\n const extension = splittedUrl[splittedUrl.length - 1].toLowerCase();\n const mimeType = MIME_TYPES[extension];\n\n if (mimeType) {\n link.current.setAttribute('type', mimeType);\n } else {\n link.current.removeAttribute('type');\n }\n\n link.current.setAttribute('href', url);\n }, [url]);\n}\n"],"mappings":";;;;AAGA,MAAM,aAAqC;CACzC,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,SAAgB,WAAW,KAAa;CACtC,MAAM,QAAA,
|
|
1
|
+
{"version":3,"file":"use-favicon.cjs","names":["useRef"],"sources":["../../src/use-favicon/use-favicon.ts"],"sourcesContent":["import { useRef } from 'react';\nimport { useIsomorphicEffect } from '../use-isomorphic-effect/use-isomorphic-effect';\n\nconst MIME_TYPES: Record<string, string> = {\n ico: 'image/x-icon',\n png: 'image/png',\n svg: 'image/svg+xml',\n gif: 'image/gif',\n};\n\nexport function useFavicon(url: string) {\n const link = useRef<HTMLLinkElement>(null);\n\n useIsomorphicEffect(() => {\n if (!url) {\n return;\n }\n\n if (!link.current) {\n const existingElements = document.querySelectorAll<HTMLLinkElement>('link[rel*=\"icon\"]');\n existingElements.forEach((element) => document.head.removeChild(element));\n\n const element = document.createElement('link');\n element.rel = 'shortcut icon';\n link.current = element;\n document.querySelector('head')!.appendChild(element);\n }\n\n const splittedUrl = url.split('.');\n const extension = splittedUrl[splittedUrl.length - 1].toLowerCase();\n const mimeType = MIME_TYPES[extension];\n\n if (mimeType) {\n link.current.setAttribute('type', mimeType);\n } else {\n link.current.removeAttribute('type');\n }\n\n link.current.setAttribute('href', url);\n }, [url]);\n}\n"],"mappings":";;;;AAGA,MAAM,aAAqC;CACzC,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;AACP;AAEA,SAAgB,WAAW,KAAa;CACtC,MAAM,QAAA,GAAOA,MAAAA,OAAAA,CAAwB,IAAI;CAEzC,8BAAA,0BAA0B;EACxB,IAAI,CAAC,KACH;EAGF,IAAI,CAAC,KAAK,SAAS;GAEjB,SADkC,iBAAkC,qBACrD,CAAC,CAAC,SAAS,YAAY,SAAS,KAAK,YAAY,OAAO,CAAC;GAExE,MAAM,UAAU,SAAS,cAAc,MAAM;GAC7C,QAAQ,MAAM;GACd,KAAK,UAAU;GACf,SAAS,cAAc,MAAM,CAAC,CAAE,YAAY,OAAO;EACrD;EAEA,MAAM,cAAc,IAAI,MAAM,GAAG;EACjC,MAAM,YAAY,YAAY,YAAY,SAAS,EAAE,CAAC,YAAY;EAClE,MAAM,WAAW,WAAW;EAE5B,IAAI,UACF,KAAK,QAAQ,aAAa,QAAQ,QAAQ;OAE1C,KAAK,QAAQ,gBAAgB,MAAM;EAGrC,KAAK,QAAQ,aAAa,QAAQ,GAAG;CACvC,GAAG,CAAC,GAAG,CAAC;AACV"}
|