tempest-react-sdk 0.48.0 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audio/sfx-pool.cjs +1 -1
- package/dist/audio/sfx-pool.cjs.map +1 -1
- package/dist/audio/sfx-pool.js +16 -7
- package/dist/audio/sfx-pool.js.map +1 -1
- package/dist/audio/use-sfx-pool.cjs +1 -1
- package/dist/audio/use-sfx-pool.cjs.map +1 -1
- package/dist/audio/use-sfx-pool.js +3 -8
- package/dist/audio/use-sfx-pool.js.map +1 -1
- package/dist/auth/passkey.cjs +1 -1
- package/dist/auth/passkey.cjs.map +1 -1
- package/dist/auth/passkey.js +79 -81
- package/dist/auth/passkey.js.map +1 -1
- package/dist/charts.cjs +1 -1
- package/dist/charts.js +4 -4
- package/dist/components/BarList/BarList.cjs +1 -1
- package/dist/components/BarList/BarList.cjs.map +1 -1
- package/dist/components/BarList/BarList.js +31 -24
- package/dist/components/BarList/BarList.js.map +1 -1
- package/dist/components/BarList/bar-list-model.cjs +1 -1
- package/dist/components/BarList/bar-list-model.cjs.map +1 -1
- package/dist/components/BarList/bar-list-model.js +5 -5
- package/dist/components/BarList/bar-list-model.js.map +1 -1
- package/dist/components/ClickOutside/ClickOutside.cjs +1 -1
- package/dist/components/ClickOutside/ClickOutside.cjs.map +1 -1
- package/dist/components/ClickOutside/ClickOutside.js +13 -14
- package/dist/components/ClickOutside/ClickOutside.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js +99 -95
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/use-dev-warnings.cjs +1 -1
- package/dist/components/DataTable/use-dev-warnings.cjs.map +1 -1
- package/dist/components/DataTable/use-dev-warnings.js +5 -3
- package/dist/components/DataTable/use-dev-warnings.js.map +1 -1
- package/dist/components/FilterBar/filter-apply.cjs +1 -1
- package/dist/components/FilterBar/filter-apply.cjs.map +1 -1
- package/dist/components/FilterBar/filter-apply.js +35 -38
- package/dist/components/FilterBar/filter-apply.js.map +1 -1
- package/dist/components/FilterBar/filter-query.cjs +1 -1
- package/dist/components/FilterBar/filter-query.cjs.map +1 -1
- package/dist/components/FilterBar/filter-query.js +16 -13
- package/dist/components/FilterBar/filter-query.js.map +1 -1
- package/dist/geo/use-position-tracker.cjs +1 -1
- package/dist/geo/use-position-tracker.cjs.map +1 -1
- package/dist/geo/use-position-tracker.js +25 -26
- package/dist/geo/use-position-tracker.js.map +1 -1
- package/dist/hooks/use-async.cjs +1 -1
- package/dist/hooks/use-async.cjs.map +1 -1
- package/dist/hooks/use-async.js +27 -30
- package/dist/hooks/use-async.js.map +1 -1
- package/dist/hooks/use-click-outside.cjs +1 -1
- package/dist/hooks/use-click-outside.cjs.map +1 -1
- package/dist/hooks/use-click-outside.js +8 -9
- package/dist/hooks/use-click-outside.js.map +1 -1
- package/dist/hooks/use-countdown.cjs +1 -1
- package/dist/hooks/use-countdown.cjs.map +1 -1
- package/dist/hooks/use-countdown.js +8 -13
- package/dist/hooks/use-countdown.js.map +1 -1
- package/dist/hooks/use-event-listener.cjs +1 -1
- package/dist/hooks/use-event-listener.cjs.map +1 -1
- package/dist/hooks/use-event-listener.js +6 -6
- package/dist/hooks/use-event-listener.js.map +1 -1
- package/dist/hooks/use-interval.cjs +1 -1
- package/dist/hooks/use-interval.cjs.map +1 -1
- package/dist/hooks/use-interval.js +5 -6
- package/dist/hooks/use-interval.js.map +1 -1
- package/dist/hooks/use-latest-ref.cjs.map +1 -1
- package/dist/hooks/use-latest-ref.js.map +1 -1
- package/dist/hooks/use-long-press-handlers.cjs +1 -1
- package/dist/hooks/use-long-press-handlers.cjs.map +1 -1
- package/dist/hooks/use-long-press-handlers.js +8 -10
- package/dist/hooks/use-long-press-handlers.js.map +1 -1
- package/dist/hooks/use-long-press.cjs +1 -1
- package/dist/hooks/use-long-press.cjs.map +1 -1
- package/dist/hooks/use-long-press.js +6 -6
- package/dist/hooks/use-long-press.js.map +1 -1
- package/dist/hooks/use-online.cjs +1 -1
- package/dist/hooks/use-online.cjs.map +1 -1
- package/dist/hooks/use-online.js +10 -10
- package/dist/hooks/use-online.js.map +1 -1
- package/dist/hooks/use-service-worker-update.cjs +1 -1
- package/dist/hooks/use-service-worker-update.cjs.map +1 -1
- package/dist/hooks/use-service-worker-update.js +24 -25
- package/dist/hooks/use-service-worker-update.js.map +1 -1
- package/dist/hooks/use-stable-callback.cjs +1 -1
- package/dist/hooks/use-stable-callback.cjs.map +1 -1
- package/dist/hooks/use-stable-callback.js +4 -3
- package/dist/hooks/use-stable-callback.js.map +1 -1
- package/dist/hooks/use-timeout.cjs +1 -1
- package/dist/hooks/use-timeout.cjs.map +1 -1
- package/dist/hooks/use-timeout.js +5 -6
- package/dist/hooks/use-timeout.js.map +1 -1
- package/dist/hooks/use-typewriter.cjs +1 -1
- package/dist/hooks/use-typewriter.cjs.map +1 -1
- package/dist/hooks/use-typewriter.js +9 -18
- package/dist/hooks/use-typewriter.js.map +1 -1
- package/dist/http/api-client.cjs +1 -1
- package/dist/http/api-client.cjs.map +1 -1
- package/dist/http/api-client.js +11 -16
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/describe-api-error.cjs +1 -1
- package/dist/http/describe-api-error.cjs.map +1 -1
- package/dist/http/describe-api-error.js +12 -15
- package/dist/http/describe-api-error.js.map +1 -1
- package/dist/http/errors.cjs +1 -1
- package/dist/http/errors.cjs.map +1 -1
- package/dist/http/errors.js +18 -6
- package/dist/http/errors.js.map +1 -1
- package/dist/http/resumable-upload.cjs +1 -1
- package/dist/http/resumable-upload.cjs.map +1 -1
- package/dist/http/resumable-upload.js +125 -118
- package/dist/http/resumable-upload.js.map +1 -1
- package/dist/http/retry.cjs +1 -1
- package/dist/http/retry.cjs.map +1 -1
- package/dist/http/retry.js +20 -16
- package/dist/http/retry.js.map +1 -1
- package/dist/http/use-describe-api-error.cjs +1 -1
- package/dist/http/use-describe-api-error.cjs.map +1 -1
- package/dist/http/use-describe-api-error.js +2 -2
- package/dist/http/use-describe-api-error.js.map +1 -1
- package/dist/i18n/create-i18n.cjs +1 -1
- package/dist/i18n/create-i18n.cjs.map +1 -1
- package/dist/i18n/create-i18n.js +6 -6
- package/dist/i18n/create-i18n.js.map +1 -1
- package/dist/icons/material-symbols.cjs +1 -1
- package/dist/icons/material-symbols.cjs.map +1 -1
- package/dist/icons/material-symbols.js +136 -5
- package/dist/icons/material-symbols.js.map +1 -1
- package/dist/icons.d.ts +17 -5
- package/dist/offline/create-offline-sync.cjs +1 -1
- package/dist/offline/create-offline-sync.cjs.map +1 -1
- package/dist/offline/create-offline-sync.js +17 -9
- package/dist/offline/create-offline-sync.js.map +1 -1
- package/dist/offline/use-offline-sync.cjs +1 -1
- package/dist/offline/use-offline-sync.cjs.map +1 -1
- package/dist/offline/use-offline-sync.js +7 -8
- package/dist/offline/use-offline-sync.js.map +1 -1
- package/dist/push/use-push-subscription.cjs +1 -1
- package/dist/push/use-push-subscription.cjs.map +1 -1
- package/dist/push/use-push-subscription.js +13 -12
- package/dist/push/use-push-subscription.js.map +1 -1
- package/dist/query/retry-policy.cjs +1 -1
- package/dist/query/retry-policy.cjs.map +1 -1
- package/dist/query/retry-policy.js +3 -3
- package/dist/query/retry-policy.js.map +1 -1
- package/dist/sse/use-event-stream.cjs +1 -1
- package/dist/sse/use-event-stream.cjs.map +1 -1
- package/dist/sse/use-event-stream.js +19 -20
- package/dist/sse/use-event-stream.js.map +1 -1
- package/dist/tabular/use-tabular-predictor.cjs +1 -1
- package/dist/tabular/use-tabular-predictor.cjs.map +1 -1
- package/dist/tabular/use-tabular-predictor.js +20 -17
- package/dist/tabular/use-tabular-predictor.js.map +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +381 -143
- package/dist/tempest-react-sdk.js +143 -143
- package/dist/theme/ThemeProvider.cjs +1 -1
- package/dist/theme/ThemeProvider.cjs.map +1 -1
- package/dist/theme/ThemeProvider.js +12 -17
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/utils/base64.cjs +2 -0
- package/dist/utils/base64.cjs.map +1 -0
- package/dist/utils/base64.js +16 -0
- package/dist/utils/base64.js.map +1 -0
- package/dist/utils/compare-values.cjs +1 -1
- package/dist/utils/compare-values.cjs.map +1 -1
- package/dist/utils/compare-values.js +4 -3
- package/dist/utils/compare-values.js.map +1 -1
- package/dist/utils/compressed-storage.cjs +1 -1
- package/dist/utils/compressed-storage.cjs.map +1 -1
- package/dist/utils/compressed-storage.js +16 -46
- package/dist/utils/compressed-storage.js.map +1 -1
- package/dist/utils/storage.cjs +1 -1
- package/dist/utils/storage.cjs.map +1 -1
- package/dist/utils/storage.js +37 -17
- package/dist/utils/storage.js.map +1 -1
- package/dist/vision/use-camera-stream.cjs +1 -1
- package/dist/vision/use-camera-stream.cjs.map +1 -1
- package/dist/vision/use-camera-stream.js +34 -33
- package/dist/vision/use-camera-stream.js.map +1 -1
- package/dist/vite/base-url.cjs +2 -0
- package/dist/vite/base-url.cjs.map +1 -0
- package/dist/vite/base-url.js +8 -0
- package/dist/vite/base-url.js.map +1 -0
- package/dist/vite/tempest-pwa-dev-sw.cjs +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.js +54 -29
- package/dist/vite/tempest-pwa-dev-sw.js.map +1 -1
- package/dist/vite/tempest-pwa-manifest.cjs +2 -2
- package/dist/vite/tempest-pwa-manifest.cjs.map +1 -1
- package/dist/vite/tempest-pwa-manifest.js +15 -14
- package/dist/vite/tempest-pwa-manifest.js.map +1 -1
- package/dist/vite.d.ts +2 -2
- package/dist/ws/use-web-socket.cjs +1 -1
- package/dist/ws/use-web-socket.cjs.map +1 -1
- package/dist/ws/use-web-socket.js +40 -42
- package/dist/ws/use-web-socket.js.map +1 -1
- package/package.json +1 -1
package/dist/hooks/use-async.js
CHANGED
|
@@ -1,60 +1,57 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "./use-latest-ref.js";
|
|
2
|
+
import { useCallback as t, useEffect as n, useRef as r, useState as i } from "react";
|
|
2
3
|
//#region src/hooks/use-async.ts
|
|
3
|
-
function
|
|
4
|
-
let { immediate:
|
|
4
|
+
function a(a, o = [], s = {}) {
|
|
5
|
+
let { immediate: c = !1 } = s, [l, u] = i({
|
|
5
6
|
status: "idle",
|
|
6
7
|
data: void 0,
|
|
7
8
|
error: void 0
|
|
8
|
-
}),
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}, [i]);
|
|
12
|
-
let d = n(0), f = n(!0);
|
|
13
|
-
t(() => (f.current = !0, () => {
|
|
14
|
-
f.current = !1;
|
|
9
|
+
}), d = e(a), f = r(0), p = r(!0);
|
|
10
|
+
n(() => (p.current = !0, () => {
|
|
11
|
+
p.current = !1;
|
|
15
12
|
}), []);
|
|
16
|
-
let
|
|
17
|
-
let e = ++
|
|
18
|
-
|
|
13
|
+
let m = t(async () => {
|
|
14
|
+
let e = ++f.current;
|
|
15
|
+
u((e) => ({
|
|
19
16
|
...e,
|
|
20
17
|
status: "pending",
|
|
21
18
|
error: void 0
|
|
22
19
|
}));
|
|
23
20
|
try {
|
|
24
|
-
let t = await
|
|
25
|
-
return
|
|
21
|
+
let t = await d.current();
|
|
22
|
+
return p.current && f.current === e && u({
|
|
26
23
|
status: "success",
|
|
27
24
|
data: t,
|
|
28
25
|
error: void 0
|
|
29
26
|
}), t;
|
|
30
27
|
} catch (t) {
|
|
31
|
-
throw
|
|
28
|
+
throw p.current && f.current === e && u({
|
|
32
29
|
status: "error",
|
|
33
30
|
data: void 0,
|
|
34
31
|
error: t
|
|
35
32
|
}), t;
|
|
36
33
|
}
|
|
37
|
-
}, []),
|
|
38
|
-
|
|
34
|
+
}, [d]), h = t(() => {
|
|
35
|
+
f.current++, u({
|
|
39
36
|
status: "idle",
|
|
40
37
|
data: void 0,
|
|
41
38
|
error: void 0
|
|
42
39
|
});
|
|
43
40
|
}, []);
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
}, [
|
|
47
|
-
status:
|
|
48
|
-
data:
|
|
49
|
-
error:
|
|
50
|
-
isPending:
|
|
51
|
-
isSuccess:
|
|
52
|
-
isError:
|
|
53
|
-
run:
|
|
54
|
-
reset:
|
|
41
|
+
return n(() => {
|
|
42
|
+
c && m().catch(() => {});
|
|
43
|
+
}, [c, ...o]), {
|
|
44
|
+
status: l.status,
|
|
45
|
+
data: l.data,
|
|
46
|
+
error: l.error,
|
|
47
|
+
isPending: l.status === "pending",
|
|
48
|
+
isSuccess: l.status === "success",
|
|
49
|
+
isError: l.status === "error",
|
|
50
|
+
run: m,
|
|
51
|
+
reset: h
|
|
55
52
|
};
|
|
56
53
|
}
|
|
57
54
|
//#endregion
|
|
58
|
-
export {
|
|
55
|
+
export { a as useAsync };
|
|
59
56
|
|
|
60
57
|
//# sourceMappingURL=use-async.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-async.js","names":[],"sources":["../../src/hooks/use-async.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type AsyncStatus = \"idle\" | \"pending\" | \"success\" | \"error\";\n\nexport interface UseAsyncResult<T> {\n status: AsyncStatus;\n data: T | undefined;\n error: unknown;\n isPending: boolean;\n isSuccess: boolean;\n isError: boolean;\n /** Trigger the async function. Resolves with the new data or rejects. */\n run: () => Promise<T>;\n /** Reset state back to idle. */\n reset: () => void;\n}\n\n/**\n * Run an async function and track its `idle/pending/success/error` state.\n *\n * - Discards results from stale runs (race-condition safe).\n * - `immediate` (default `false`) triggers the function on mount and when\n * `deps` change. With `false`, call `run()` manually.\n * - Returns a stable object so callers can destructure or pass around safely.\n *\n * For server data with caching, prefer React Query — `useAsync` is the\n * minimal one-shot primitive without dependencies.\n */\nexport function useAsync<T>(\n asyncFn: () => Promise<T>,\n deps: ReadonlyArray<unknown> = [],\n options: { immediate?: boolean } = {},\n): UseAsyncResult<T> {\n const { immediate = false } = options;\n const [state, setState] = useState<{\n status: AsyncStatus;\n data: T | undefined;\n error: unknown;\n }>({ status: \"idle\", data: undefined, error: undefined });\n\n const fnRef =
|
|
1
|
+
{"version":3,"file":"use-async.js","names":[],"sources":["../../src/hooks/use-async.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\n\nexport type AsyncStatus = \"idle\" | \"pending\" | \"success\" | \"error\";\n\nexport interface UseAsyncResult<T> {\n status: AsyncStatus;\n data: T | undefined;\n error: unknown;\n isPending: boolean;\n isSuccess: boolean;\n isError: boolean;\n /** Trigger the async function. Resolves with the new data or rejects. */\n run: () => Promise<T>;\n /** Reset state back to idle. */\n reset: () => void;\n}\n\n/**\n * Run an async function and track its `idle/pending/success/error` state.\n *\n * - Discards results from stale runs (race-condition safe).\n * - `immediate` (default `false`) triggers the function on mount and when\n * `deps` change. With `false`, call `run()` manually.\n * - Returns a stable object so callers can destructure or pass around safely.\n *\n * For server data with caching, prefer React Query — `useAsync` is the\n * minimal one-shot primitive without dependencies.\n */\nexport function useAsync<T>(\n asyncFn: () => Promise<T>,\n deps: ReadonlyArray<unknown> = [],\n options: { immediate?: boolean } = {},\n): UseAsyncResult<T> {\n const { immediate = false } = options;\n const [state, setState] = useState<{\n status: AsyncStatus;\n data: T | undefined;\n error: unknown;\n }>({ status: \"idle\", data: undefined, error: undefined });\n\n const fnRef = useLatestRef(asyncFn);\n const callIdRef = useRef<number>(0);\n const mountedRef = useRef<boolean>(true);\n\n useEffect(() => {\n mountedRef.current = true;\n return () => {\n mountedRef.current = false;\n };\n }, []);\n\n const run = useCallback(async (): Promise<T> => {\n const callId = ++callIdRef.current;\n setState((current) => ({ ...current, status: \"pending\", error: undefined }));\n try {\n const data = await fnRef.current();\n if (mountedRef.current && callIdRef.current === callId) {\n setState({ status: \"success\", data, error: undefined });\n }\n return data;\n } catch (error) {\n if (mountedRef.current && callIdRef.current === callId) {\n setState({ status: \"error\", data: undefined, error });\n }\n throw error;\n }\n }, [fnRef]);\n\n const reset = useCallback((): void => {\n callIdRef.current++;\n setState({ status: \"idle\", data: undefined, error: undefined });\n }, []);\n\n useEffect(() => {\n if (!immediate) return;\n run().catch(() => {\n /* error already captured in state */\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [immediate, ...deps]);\n\n return {\n status: state.status,\n data: state.data,\n error: state.error,\n isPending: state.status === \"pending\",\n isSuccess: state.status === \"success\",\n isError: state.status === \"error\",\n run,\n reset,\n };\n}\n"],"mappings":";;;AA6BA,SAAgB,EACZ,GACA,IAA+B,CAAC,GAChC,IAAmC,CAAC,GACnB;CACjB,IAAM,EAAE,eAAY,OAAU,GACxB,CAAC,GAAO,KAAY,EAIvB;EAAE,QAAQ;EAAQ,MAAM,KAAA;EAAW,OAAO,KAAA;CAAU,CAAC,GAElD,IAAQ,EAAa,CAAO,GAC5B,IAAY,EAAe,CAAC,GAC5B,IAAa,EAAgB,EAAI;CAEvC,SACI,EAAW,UAAU,UACR;EACT,EAAW,UAAU;CACzB,IACD,CAAC,CAAC;CAEL,IAAM,IAAM,EAAY,YAAwB;EAC5C,IAAM,IAAS,EAAE,EAAU;EAC3B,GAAU,OAAa;GAAE,GAAG;GAAS,QAAQ;GAAW,OAAO,KAAA;EAAU,EAAE;EAC3E,IAAI;GACA,IAAM,IAAO,MAAM,EAAM,QAAQ;GAIjC,OAHI,EAAW,WAAW,EAAU,YAAY,KAC5C,EAAS;IAAE,QAAQ;IAAW;IAAM,OAAO,KAAA;GAAU,CAAC,GAEnD;EACX,SAAS,GAAO;GAIZ,MAHI,EAAW,WAAW,EAAU,YAAY,KAC5C,EAAS;IAAE,QAAQ;IAAS,MAAM,KAAA;IAAW;GAAM,CAAC,GAElD;EACV;CACJ,GAAG,CAAC,CAAK,CAAC,GAEJ,IAAQ,QAAwB;EAElC,AADA,EAAU,WACV,EAAS;GAAE,QAAQ;GAAQ,MAAM,KAAA;GAAW,OAAO,KAAA;EAAU,CAAC;CAClE,GAAG,CAAC,CAAC;CAUL,OARA,QAAgB;EACP,KACL,EAAI,CAAC,CAAC,YAAY,CAElB,CAAC;CAEL,GAAG,CAAC,GAAW,GAAG,CAAI,CAAC,GAEhB;EACH,QAAQ,EAAM;EACd,MAAM,EAAM;EACZ,OAAO,EAAM;EACb,WAAW,EAAM,WAAW;EAC5B,WAAW,EAAM,WAAW;EAC5B,SAAS,EAAM,WAAW;EAC1B;EACA;CACJ;AACJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./use-latest-ref.cjs");let t=require("react");function n(n){let r=(0,t.useRef)(null),i=e.useLatestRef(n);return(0,t.useEffect)(()=>{if(typeof document>`u`)return;let e=e=>{let t=e.target;!r.current||t&&r.current.contains(t)||i.current()};return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[i]),r}exports.useClickOutside=n;
|
|
2
2
|
//# sourceMappingURL=use-click-outside.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-click-outside.cjs","names":[],"sources":["../../src/hooks/use-click-outside.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport type { RefObject } from \"react\";\n\n/**\n * Call `handler` when a `mousedown` / `touchstart` occurs outside the returned\n * ref's element. SSR-safe — listeners are only attached in the browser.\n *\n * @typeParam T - element type to attach the ref to.\n * @param handler - invoked on an outside interaction.\n * @returns A ref to attach to the element treated as \"inside\".\n */\nexport function useClickOutside<T extends HTMLElement = HTMLElement>(\n handler: () => void,\n): RefObject<T | null> {\n const ref = useRef<T>(null);\n const handlerRef =
|
|
1
|
+
{"version":3,"file":"use-click-outside.cjs","names":[],"sources":["../../src/hooks/use-click-outside.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\nimport type { RefObject } from \"react\";\n\n/**\n * Call `handler` when a `mousedown` / `touchstart` occurs outside the returned\n * ref's element. SSR-safe — listeners are only attached in the browser.\n *\n * @typeParam T - element type to attach the ref to.\n * @param handler - invoked on an outside interaction.\n * @returns A ref to attach to the element treated as \"inside\".\n */\nexport function useClickOutside<T extends HTMLElement = HTMLElement>(\n handler: () => void,\n): RefObject<T | null> {\n const ref = useRef<T>(null);\n const handlerRef = useLatestRef(handler);\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n\n const listener = (event: MouseEvent | TouchEvent): void => {\n const target = event.target as Node | null;\n if (!ref.current || (target && ref.current.contains(target))) return;\n handlerRef.current();\n };\n\n document.addEventListener(\"mousedown\", listener);\n document.addEventListener(\"touchstart\", listener);\n return () => {\n document.removeEventListener(\"mousedown\", listener);\n document.removeEventListener(\"touchstart\", listener);\n };\n }, [handlerRef]);\n\n return ref;\n}\n"],"mappings":"+DAYA,SAAgB,EACZ,EACmB,CACnB,IAAM,GAAA,EAAM,EAAA,OAAA,CAAU,IAAI,EACpB,EAAa,EAAA,aAAa,CAAO,EAmBvC,OAjBA,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,OAAO,SAAa,IAAa,OAErC,IAAM,EAAY,GAAyC,CACvD,IAAM,EAAS,EAAM,OACjB,CAAC,EAAI,SAAY,GAAU,EAAI,QAAQ,SAAS,CAAM,GAC1D,EAAW,QAAQ,CACvB,EAIA,OAFA,SAAS,iBAAiB,YAAa,CAAQ,EAC/C,SAAS,iBAAiB,aAAc,CAAQ,MACnC,CACT,SAAS,oBAAoB,YAAa,CAAQ,EAClD,SAAS,oBAAoB,aAAc,CAAQ,CACvD,CACJ,EAAG,CAAC,CAAU,CAAC,EAER,CACX"}
|
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "./use-latest-ref.js";
|
|
2
|
+
import { useEffect as t, useRef as n } from "react";
|
|
2
3
|
//#region src/hooks/use-click-outside.ts
|
|
3
|
-
function
|
|
4
|
-
let
|
|
5
|
-
return
|
|
6
|
-
i.current = n;
|
|
7
|
-
}, [n]), e(() => {
|
|
4
|
+
function r(r) {
|
|
5
|
+
let i = n(null), a = e(r);
|
|
6
|
+
return t(() => {
|
|
8
7
|
if (typeof document > "u") return;
|
|
9
8
|
let e = (e) => {
|
|
10
9
|
let t = e.target;
|
|
11
|
-
!
|
|
10
|
+
!i.current || t && i.current.contains(t) || a.current();
|
|
12
11
|
};
|
|
13
12
|
return document.addEventListener("mousedown", e), document.addEventListener("touchstart", e), () => {
|
|
14
13
|
document.removeEventListener("mousedown", e), document.removeEventListener("touchstart", e);
|
|
15
14
|
};
|
|
16
|
-
}, []),
|
|
15
|
+
}, [a]), i;
|
|
17
16
|
}
|
|
18
17
|
//#endregion
|
|
19
|
-
export {
|
|
18
|
+
export { r as useClickOutside };
|
|
20
19
|
|
|
21
20
|
//# sourceMappingURL=use-click-outside.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-click-outside.js","names":[],"sources":["../../src/hooks/use-click-outside.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport type { RefObject } from \"react\";\n\n/**\n * Call `handler` when a `mousedown` / `touchstart` occurs outside the returned\n * ref's element. SSR-safe — listeners are only attached in the browser.\n *\n * @typeParam T - element type to attach the ref to.\n * @param handler - invoked on an outside interaction.\n * @returns A ref to attach to the element treated as \"inside\".\n */\nexport function useClickOutside<T extends HTMLElement = HTMLElement>(\n handler: () => void,\n): RefObject<T | null> {\n const ref = useRef<T>(null);\n const handlerRef =
|
|
1
|
+
{"version":3,"file":"use-click-outside.js","names":[],"sources":["../../src/hooks/use-click-outside.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\nimport type { RefObject } from \"react\";\n\n/**\n * Call `handler` when a `mousedown` / `touchstart` occurs outside the returned\n * ref's element. SSR-safe — listeners are only attached in the browser.\n *\n * @typeParam T - element type to attach the ref to.\n * @param handler - invoked on an outside interaction.\n * @returns A ref to attach to the element treated as \"inside\".\n */\nexport function useClickOutside<T extends HTMLElement = HTMLElement>(\n handler: () => void,\n): RefObject<T | null> {\n const ref = useRef<T>(null);\n const handlerRef = useLatestRef(handler);\n\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n\n const listener = (event: MouseEvent | TouchEvent): void => {\n const target = event.target as Node | null;\n if (!ref.current || (target && ref.current.contains(target))) return;\n handlerRef.current();\n };\n\n document.addEventListener(\"mousedown\", listener);\n document.addEventListener(\"touchstart\", listener);\n return () => {\n document.removeEventListener(\"mousedown\", listener);\n document.removeEventListener(\"touchstart\", listener);\n };\n }, [handlerRef]);\n\n return ref;\n}\n"],"mappings":";;;AAYA,SAAgB,EACZ,GACmB;CACnB,IAAM,IAAM,EAAU,IAAI,GACpB,IAAa,EAAa,CAAO;CAmBvC,OAjBA,QAAgB;EACZ,IAAI,OAAO,WAAa,KAAa;EAErC,IAAM,KAAY,MAAyC;GACvD,IAAM,IAAS,EAAM;GACjB,CAAC,EAAI,WAAY,KAAU,EAAI,QAAQ,SAAS,CAAM,KAC1D,EAAW,QAAQ;EACvB;EAIA,OAFA,SAAS,iBAAiB,aAAa,CAAQ,GAC/C,SAAS,iBAAiB,cAAc,CAAQ,SACnC;GAET,AADA,SAAS,oBAAoB,aAAa,CAAQ,GAClD,SAAS,oBAAoB,cAAc,CAAQ;EACvD;CACJ,GAAG,CAAC,CAAU,CAAC,GAER;AACX"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./use-interval.cjs");let t=require("react");function n(n,r,i={}){let{tickMs:a=1e3}=i,o=(0,t.useCallback)(()=>Math.max(0,n-(Date.now()-r)),[n,r]),[s,c]=(0,t.useState)(o);return(0,t.useEffect)(()=>{c(o())},[o]),e.useInterval(()=>c(o()),s>0?a:null),s}exports.useCountdown=n;
|
|
2
2
|
//# sourceMappingURL=use-countdown.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-countdown.cjs","names":[],"sources":["../../src/hooks/use-countdown.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\n\n/** Options for {@link useCountdown}. */\nexport interface UseCountdownOptions {\n /**\n * How often the remaining time is recomputed, in ms. Default `1000`, which\n * suits a \"try again in 3s\" label; drop it to ~50 to drive a progress bar.\n */\n tickMs?: number;\n}\n\n/**\n * Counts down the time left on a window that started at a known instant.\n *\n * Written around a timestamp rather than a decrementing counter on purpose: the\n * remaining time is recomputed from `Date.now()` on every tick, so a throttled\n * background tab, a slow frame or a `setInterval` that drifts cannot make the\n * countdown disagree with the clock. Remounting recovers the correct value too,\n * which a counter held in state cannot do.\n *\n * The interval stops once it reaches zero instead of ticking forever behind a\n * clamp.\n *\n * @param durationMs - Length of the window.\n * @param startedAt - Epoch ms the window opened (`Date.now()` when it started).\n * @param options - Tick cadence.\n * @returns Milliseconds remaining, never below `0`.\n *\n * @example\n * const remaining = useCountdown(60_000, lastSentAt);\n *\n * <button disabled={remaining > 0}>\n * {remaining > 0 ? `Reenviar em ${Math.ceil(remaining / 1000)}s` : \"Reenviar código\"}\n * </button>\n */\nexport function useCountdown(\n durationMs: number,\n startedAt: number,\n options: UseCountdownOptions = {},\n): number {\n const { tickMs = 1000 } = options;\n\n const compute = useCallback(\n () => Math.max(0, durationMs - (Date.now() - startedAt)),\n [durationMs, startedAt],\n );\n\n const [remaining, setRemaining] = useState(compute);\n\n useEffect(() => {\n
|
|
1
|
+
{"version":3,"file":"use-countdown.cjs","names":[],"sources":["../../src/hooks/use-countdown.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { useInterval } from \"./use-interval\";\n\n/** Options for {@link useCountdown}. */\nexport interface UseCountdownOptions {\n /**\n * How often the remaining time is recomputed, in ms. Default `1000`, which\n * suits a \"try again in 3s\" label; drop it to ~50 to drive a progress bar.\n */\n tickMs?: number;\n}\n\n/**\n * Counts down the time left on a window that started at a known instant.\n *\n * Written around a timestamp rather than a decrementing counter on purpose: the\n * remaining time is recomputed from `Date.now()` on every tick, so a throttled\n * background tab, a slow frame or a `setInterval` that drifts cannot make the\n * countdown disagree with the clock. Remounting recovers the correct value too,\n * which a counter held in state cannot do.\n *\n * The interval stops once it reaches zero instead of ticking forever behind a\n * clamp — `useInterval` pauses on a `null` delay, so reaching zero is what tears\n * the timer down.\n *\n * @param durationMs - Length of the window.\n * @param startedAt - Epoch ms the window opened (`Date.now()` when it started).\n * @param options - Tick cadence.\n * @returns Milliseconds remaining, never below `0`.\n *\n * @example\n * const remaining = useCountdown(60_000, lastSentAt);\n *\n * <button disabled={remaining > 0}>\n * {remaining > 0 ? `Reenviar em ${Math.ceil(remaining / 1000)}s` : \"Reenviar código\"}\n * </button>\n */\nexport function useCountdown(\n durationMs: number,\n startedAt: number,\n options: UseCountdownOptions = {},\n): number {\n const { tickMs = 1000 } = options;\n\n const compute = useCallback(\n () => Math.max(0, durationMs - (Date.now() - startedAt)),\n [durationMs, startedAt],\n );\n\n const [remaining, setRemaining] = useState(compute);\n\n useEffect(() => {\n setRemaining(compute());\n }, [compute]);\n\n useInterval(() => setRemaining(compute()), remaining > 0 ? tickMs : null);\n\n return remaining;\n}\n"],"mappings":"6DAqCA,SAAgB,EACZ,EACA,EACA,EAA+B,CAAC,EAC1B,CACN,GAAM,CAAE,SAAS,KAAS,EAEpB,GAAA,EAAU,EAAA,YAAA,KACN,KAAK,IAAI,EAAG,GAAc,KAAK,IAAI,EAAI,EAAU,EACvD,CAAC,EAAY,CAAS,CAC1B,EAEM,CAAC,EAAW,IAAA,EAAgB,EAAA,SAAA,CAAS,CAAO,EAQlD,OANA,EAAA,EAAA,UAAA,KAAgB,CACZ,EAAa,EAAQ,CAAC,CAC1B,EAAG,CAAC,CAAO,CAAC,EAEZ,EAAA,gBAAkB,EAAa,EAAQ,CAAC,EAAG,EAAY,EAAI,EAAS,IAAI,EAEjE,CACX"}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useInterval as e } from "./use-interval.js";
|
|
2
|
+
import { useCallback as t, useEffect as n, useState as r } from "react";
|
|
2
3
|
//#region src/hooks/use-countdown.ts
|
|
3
|
-
function
|
|
4
|
-
let { tickMs:
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
let t = setInterval(() => {
|
|
9
|
-
let e = s();
|
|
10
|
-
l(e), e <= 0 && clearInterval(t);
|
|
11
|
-
}, o);
|
|
12
|
-
return () => clearInterval(t);
|
|
13
|
-
}, [s, o]), c;
|
|
4
|
+
function i(i, a, o = {}) {
|
|
5
|
+
let { tickMs: s = 1e3 } = o, c = t(() => Math.max(0, i - (Date.now() - a)), [i, a]), [l, u] = r(c);
|
|
6
|
+
return n(() => {
|
|
7
|
+
u(c());
|
|
8
|
+
}, [c]), e(() => u(c()), l > 0 ? s : null), l;
|
|
14
9
|
}
|
|
15
10
|
//#endregion
|
|
16
|
-
export {
|
|
11
|
+
export { i as useCountdown };
|
|
17
12
|
|
|
18
13
|
//# sourceMappingURL=use-countdown.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-countdown.js","names":[],"sources":["../../src/hooks/use-countdown.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\n\n/** Options for {@link useCountdown}. */\nexport interface UseCountdownOptions {\n /**\n * How often the remaining time is recomputed, in ms. Default `1000`, which\n * suits a \"try again in 3s\" label; drop it to ~50 to drive a progress bar.\n */\n tickMs?: number;\n}\n\n/**\n * Counts down the time left on a window that started at a known instant.\n *\n * Written around a timestamp rather than a decrementing counter on purpose: the\n * remaining time is recomputed from `Date.now()` on every tick, so a throttled\n * background tab, a slow frame or a `setInterval` that drifts cannot make the\n * countdown disagree with the clock. Remounting recovers the correct value too,\n * which a counter held in state cannot do.\n *\n * The interval stops once it reaches zero instead of ticking forever behind a\n * clamp.\n *\n * @param durationMs - Length of the window.\n * @param startedAt - Epoch ms the window opened (`Date.now()` when it started).\n * @param options - Tick cadence.\n * @returns Milliseconds remaining, never below `0`.\n *\n * @example\n * const remaining = useCountdown(60_000, lastSentAt);\n *\n * <button disabled={remaining > 0}>\n * {remaining > 0 ? `Reenviar em ${Math.ceil(remaining / 1000)}s` : \"Reenviar código\"}\n * </button>\n */\nexport function useCountdown(\n durationMs: number,\n startedAt: number,\n options: UseCountdownOptions = {},\n): number {\n const { tickMs = 1000 } = options;\n\n const compute = useCallback(\n () => Math.max(0, durationMs - (Date.now() - startedAt)),\n [durationMs, startedAt],\n );\n\n const [remaining, setRemaining] = useState(compute);\n\n useEffect(() => {\n
|
|
1
|
+
{"version":3,"file":"use-countdown.js","names":[],"sources":["../../src/hooks/use-countdown.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport { useInterval } from \"./use-interval\";\n\n/** Options for {@link useCountdown}. */\nexport interface UseCountdownOptions {\n /**\n * How often the remaining time is recomputed, in ms. Default `1000`, which\n * suits a \"try again in 3s\" label; drop it to ~50 to drive a progress bar.\n */\n tickMs?: number;\n}\n\n/**\n * Counts down the time left on a window that started at a known instant.\n *\n * Written around a timestamp rather than a decrementing counter on purpose: the\n * remaining time is recomputed from `Date.now()` on every tick, so a throttled\n * background tab, a slow frame or a `setInterval` that drifts cannot make the\n * countdown disagree with the clock. Remounting recovers the correct value too,\n * which a counter held in state cannot do.\n *\n * The interval stops once it reaches zero instead of ticking forever behind a\n * clamp — `useInterval` pauses on a `null` delay, so reaching zero is what tears\n * the timer down.\n *\n * @param durationMs - Length of the window.\n * @param startedAt - Epoch ms the window opened (`Date.now()` when it started).\n * @param options - Tick cadence.\n * @returns Milliseconds remaining, never below `0`.\n *\n * @example\n * const remaining = useCountdown(60_000, lastSentAt);\n *\n * <button disabled={remaining > 0}>\n * {remaining > 0 ? `Reenviar em ${Math.ceil(remaining / 1000)}s` : \"Reenviar código\"}\n * </button>\n */\nexport function useCountdown(\n durationMs: number,\n startedAt: number,\n options: UseCountdownOptions = {},\n): number {\n const { tickMs = 1000 } = options;\n\n const compute = useCallback(\n () => Math.max(0, durationMs - (Date.now() - startedAt)),\n [durationMs, startedAt],\n );\n\n const [remaining, setRemaining] = useState(compute);\n\n useEffect(() => {\n setRemaining(compute());\n }, [compute]);\n\n useInterval(() => setRemaining(compute()), remaining > 0 ? tickMs : null);\n\n return remaining;\n}\n"],"mappings":";;;AAqCA,SAAgB,EACZ,GACA,GACA,IAA+B,CAAC,GAC1B;CACN,IAAM,EAAE,YAAS,QAAS,GAEpB,IAAU,QACN,KAAK,IAAI,GAAG,KAAc,KAAK,IAAI,IAAI,EAAU,GACvD,CAAC,GAAY,CAAS,CAC1B,GAEM,CAAC,GAAW,KAAgB,EAAS,CAAO;CAQlD,OANA,QAAgB;EACZ,EAAa,EAAQ,CAAC;CAC1B,GAAG,CAAC,CAAO,CAAC,GAEZ,QAAkB,EAAa,EAAQ,CAAC,GAAG,IAAY,IAAI,IAAS,IAAI,GAEjE;AACX"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./use-latest-ref.cjs");let t=require("react");function n(n,r,i,a){let o=e.useLatestRef(r);(0,t.useEffect)(()=>{let e=i===void 0?typeof window>`u`?null:window:`current`in i?i.current??null:i;if(!e?.addEventListener)return;let t=e=>o.current(e);return e.addEventListener(n,t,a),()=>e.removeEventListener(n,t,a)},[n,i,a,o])}exports.useEventListener=n;
|
|
2
2
|
//# sourceMappingURL=use-event-listener.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-event-listener.cjs","names":[],"sources":["../../src/hooks/use-event-listener.ts"],"sourcesContent":["import { useEffect
|
|
1
|
+
{"version":3,"file":"use-event-listener.cjs","names":[],"sources":["../../src/hooks/use-event-listener.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\n\ntype AnyEventTarget = EventTarget | { current: EventTarget | null } | null | undefined;\n\n/**\n * Subscribe to a DOM event with React-friendly semantics.\n *\n * - Handler is stored in a ref so callers can pass inline functions without\n * resubscribing on every render.\n * - `target` defaults to `window`. Accepts a raw `EventTarget` (window, document,\n * element) OR a ref pointing at one.\n * - Returns nothing — cleanup is automatic on unmount or when `eventName`/`target` change.\n *\n * @tempest-limits param-count — deliberately the same positional shape as\n * `addEventListener(type, listener, options)`, with the target inserted where React\n * needs it. A hook that mirrors a DOM API is read by everyone who already knows the\n * DOM API; a bespoke options bag would make the familiar call unfamiliar.\n */\nexport function useEventListener<K extends keyof WindowEventMap>(\n eventName: K,\n handler: (event: WindowEventMap[K]) => void,\n target?: AnyEventTarget,\n options?: AddEventListenerOptions | boolean,\n): void;\nexport function useEventListener<K extends keyof DocumentEventMap>(\n eventName: K,\n handler: (event: DocumentEventMap[K]) => void,\n target?: AnyEventTarget,\n options?: AddEventListenerOptions | boolean,\n): void;\nexport function useEventListener<K extends keyof HTMLElementEventMap>(\n eventName: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n target?: AnyEventTarget,\n options?: AddEventListenerOptions | boolean,\n): void;\nexport function useEventListener(\n eventName: string,\n handler: (event: Event) => void,\n target?: AnyEventTarget,\n options?: AddEventListenerOptions | boolean,\n): void {\n const handlerRef = useLatestRef(handler);\n\n useEffect(() => {\n const resolvedTarget: EventTarget | null =\n target === undefined\n ? typeof window === \"undefined\"\n ? null\n : window\n : \"current\" in (target as { current: unknown })\n ? ((target as { current: EventTarget | null }).current ?? null)\n : (target as EventTarget | null);\n\n if (!resolvedTarget?.addEventListener) return;\n\n const listener: EventListener = (event) => handlerRef.current(event);\n resolvedTarget.addEventListener(eventName, listener, options);\n return () => resolvedTarget.removeEventListener(eventName, listener, options);\n }, [eventName, target, options, handlerRef]);\n}\n"],"mappings":"+DAqCA,SAAgB,EACZ,EACA,EACA,EACA,EACI,CACJ,IAAM,EAAa,EAAA,aAAa,CAAO,GAEvC,EAAA,EAAA,UAAA,KAAgB,CACZ,IAAM,EACF,IAAW,IAAA,GACL,OAAO,OAAW,IACd,KACA,OACJ,YAAc,EACV,EAA2C,SAAW,KACvD,EAEb,GAAI,CAAC,GAAgB,iBAAkB,OAEvC,IAAM,EAA2B,GAAU,EAAW,QAAQ,CAAK,EAEnE,OADA,EAAe,iBAAiB,EAAW,EAAU,CAAO,MAC/C,EAAe,oBAAoB,EAAW,EAAU,CAAO,CAChF,EAAG,CAAC,EAAW,EAAQ,EAAS,CAAU,CAAC,CAC/C"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "./use-latest-ref.js";
|
|
2
|
+
import { useEffect as t } from "react";
|
|
2
3
|
//#region src/hooks/use-event-listener.ts
|
|
3
4
|
function n(n, r, i, a) {
|
|
4
|
-
let o =
|
|
5
|
-
|
|
6
|
-
o.current = r;
|
|
7
|
-
}, [r]), e(() => {
|
|
5
|
+
let o = e(r);
|
|
6
|
+
t(() => {
|
|
8
7
|
let e = i === void 0 ? typeof window > "u" ? null : window : "current" in i ? i.current ?? null : i;
|
|
9
8
|
if (!e?.addEventListener) return;
|
|
10
9
|
let t = (e) => o.current(e);
|
|
@@ -12,7 +11,8 @@ function n(n, r, i, a) {
|
|
|
12
11
|
}, [
|
|
13
12
|
n,
|
|
14
13
|
i,
|
|
15
|
-
a
|
|
14
|
+
a,
|
|
15
|
+
o
|
|
16
16
|
]);
|
|
17
17
|
}
|
|
18
18
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-event-listener.js","names":[],"sources":["../../src/hooks/use-event-listener.ts"],"sourcesContent":["import { useEffect
|
|
1
|
+
{"version":3,"file":"use-event-listener.js","names":[],"sources":["../../src/hooks/use-event-listener.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\n\ntype AnyEventTarget = EventTarget | { current: EventTarget | null } | null | undefined;\n\n/**\n * Subscribe to a DOM event with React-friendly semantics.\n *\n * - Handler is stored in a ref so callers can pass inline functions without\n * resubscribing on every render.\n * - `target` defaults to `window`. Accepts a raw `EventTarget` (window, document,\n * element) OR a ref pointing at one.\n * - Returns nothing — cleanup is automatic on unmount or when `eventName`/`target` change.\n *\n * @tempest-limits param-count — deliberately the same positional shape as\n * `addEventListener(type, listener, options)`, with the target inserted where React\n * needs it. A hook that mirrors a DOM API is read by everyone who already knows the\n * DOM API; a bespoke options bag would make the familiar call unfamiliar.\n */\nexport function useEventListener<K extends keyof WindowEventMap>(\n eventName: K,\n handler: (event: WindowEventMap[K]) => void,\n target?: AnyEventTarget,\n options?: AddEventListenerOptions | boolean,\n): void;\nexport function useEventListener<K extends keyof DocumentEventMap>(\n eventName: K,\n handler: (event: DocumentEventMap[K]) => void,\n target?: AnyEventTarget,\n options?: AddEventListenerOptions | boolean,\n): void;\nexport function useEventListener<K extends keyof HTMLElementEventMap>(\n eventName: K,\n handler: (event: HTMLElementEventMap[K]) => void,\n target?: AnyEventTarget,\n options?: AddEventListenerOptions | boolean,\n): void;\nexport function useEventListener(\n eventName: string,\n handler: (event: Event) => void,\n target?: AnyEventTarget,\n options?: AddEventListenerOptions | boolean,\n): void {\n const handlerRef = useLatestRef(handler);\n\n useEffect(() => {\n const resolvedTarget: EventTarget | null =\n target === undefined\n ? typeof window === \"undefined\"\n ? null\n : window\n : \"current\" in (target as { current: unknown })\n ? ((target as { current: EventTarget | null }).current ?? null)\n : (target as EventTarget | null);\n\n if (!resolvedTarget?.addEventListener) return;\n\n const listener: EventListener = (event) => handlerRef.current(event);\n resolvedTarget.addEventListener(eventName, listener, options);\n return () => resolvedTarget.removeEventListener(eventName, listener, options);\n }, [eventName, target, options, handlerRef]);\n}\n"],"mappings":";;;AAqCA,SAAgB,EACZ,GACA,GACA,GACA,GACI;CACJ,IAAM,IAAa,EAAa,CAAO;CAEvC,QAAgB;EACZ,IAAM,IACF,MAAW,KAAA,IACL,OAAO,SAAW,MACd,OACA,SACJ,aAAc,IACV,EAA2C,WAAW,OACvD;EAEb,IAAI,CAAC,GAAgB,kBAAkB;EAEvC,IAAM,KAA2B,MAAU,EAAW,QAAQ,CAAK;EAEnE,OADA,EAAe,iBAAiB,GAAW,GAAU,CAAO,SAC/C,EAAe,oBAAoB,GAAW,GAAU,CAAO;CAChF,GAAG;EAAC;EAAW;EAAQ;EAAS;CAAU,CAAC;AAC/C"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./use-latest-ref.cjs");let t=require("react");function n(n,r){let i=e.useLatestRef(n);(0,t.useEffect)(()=>{if(r===null)return;let e=setInterval(()=>i.current(),r);return()=>clearInterval(e)},[r,i])}exports.useInterval=n;
|
|
2
2
|
//# sourceMappingURL=use-interval.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-interval.cjs","names":[],"sources":["../../src/hooks/use-interval.ts"],"sourcesContent":["import { useEffect
|
|
1
|
+
{"version":3,"file":"use-interval.cjs","names":[],"sources":["../../src/hooks/use-interval.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\n\n/**\n * Reactive `setInterval`. Pass `null` as `delay` to pause. `fn` is stored in\n * a ref so inline callbacks don't reset the interval on every render.\n *\n * @example\n * useInterval(() => poll(), enabled ? 5000 : null);\n */\nexport function useInterval(fn: () => void, delay: number | null): void {\n const fnRef = useLatestRef(fn);\n\n useEffect(() => {\n if (delay === null) return;\n const id = setInterval(() => fnRef.current(), delay);\n return () => clearInterval(id);\n }, [delay, fnRef]);\n}\n"],"mappings":"+DAUA,SAAgB,EAAY,EAAgB,EAA4B,CACpE,IAAM,EAAQ,EAAA,aAAa,CAAE,GAE7B,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,IAAU,KAAM,OACpB,IAAM,EAAK,gBAAkB,EAAM,QAAQ,EAAG,CAAK,EACnD,UAAa,cAAc,CAAE,CACjC,EAAG,CAAC,EAAO,CAAK,CAAC,CACrB"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "./use-latest-ref.js";
|
|
2
|
+
import { useEffect as t } from "react";
|
|
2
3
|
//#region src/hooks/use-interval.ts
|
|
3
4
|
function n(n, r) {
|
|
4
|
-
let i =
|
|
5
|
-
|
|
6
|
-
i.current = n;
|
|
7
|
-
}, [n]), e(() => {
|
|
5
|
+
let i = e(n);
|
|
6
|
+
t(() => {
|
|
8
7
|
if (r === null) return;
|
|
9
8
|
let e = setInterval(() => i.current(), r);
|
|
10
9
|
return () => clearInterval(e);
|
|
11
|
-
}, [r]);
|
|
10
|
+
}, [r, i]);
|
|
12
11
|
}
|
|
13
12
|
//#endregion
|
|
14
13
|
export { n as useInterval };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-interval.js","names":[],"sources":["../../src/hooks/use-interval.ts"],"sourcesContent":["import { useEffect
|
|
1
|
+
{"version":3,"file":"use-interval.js","names":[],"sources":["../../src/hooks/use-interval.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\n\n/**\n * Reactive `setInterval`. Pass `null` as `delay` to pause. `fn` is stored in\n * a ref so inline callbacks don't reset the interval on every render.\n *\n * @example\n * useInterval(() => poll(), enabled ? 5000 : null);\n */\nexport function useInterval(fn: () => void, delay: number | null): void {\n const fnRef = useLatestRef(fn);\n\n useEffect(() => {\n if (delay === null) return;\n const id = setInterval(() => fnRef.current(), delay);\n return () => clearInterval(id);\n }, [delay, fnRef]);\n}\n"],"mappings":";;;AAUA,SAAgB,EAAY,GAAgB,GAA4B;CACpE,IAAM,IAAQ,EAAa,CAAE;CAE7B,QAAgB;EACZ,IAAI,MAAU,MAAM;EACpB,IAAM,IAAK,kBAAkB,EAAM,QAAQ,GAAG,CAAK;EACnD,aAAa,cAAc,CAAE;CACjC,GAAG,CAAC,GAAO,CAAK,CAAC;AACrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-latest-ref.cjs","names":[],"sources":["../../src/hooks/use-latest-ref.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- writing at render time is deliberate; an effect would add a staleness window (see the docstring) */\nimport { useRef, type RefObject } from \"react\";\n\n/**\n * Keeps a ref pointing at the most recent value it was given.\n *\n * The escape hatch for reading fresh state inside something that must not be\n * re-created when that state changes: an interval, a subscription, an event\n * listener registered once on mount. Listing the value in the effect's\n * dependencies would tear the effect down and set it back up on every change;\n * omitting it captures the value from the render that created the closure and\n * never sees another. The ref is neither — a stable object whose `current` is\n * always current.\n *\n * The assignment happens **during render**, for the same reason\n * {@link useStableCallback} does it: moving it into an effect opens a\n * one-commit staleness window, where an effect declared earlier in the same\n * commit reads the previous render's value.\n *\n * Reach for {@link useStableCallback} instead when the value is a function you\n * want to *call* — it hands back a callable with a stable identity, rather than\n * making every call site reach through `.current`.\n *\n * @typeParam T - The tracked value.\n * @param value - The value to track. Written on every render.\n * @returns A stable ref whose `current` holds the latest `value`.\n *\n * @example\n * const optionsRef = useLatestRef(options);\n *\n * useEffect(() => {\n * const id = setInterval(() => poll(optionsRef.current), 5_000);\n * return () => clearInterval(id);\n * }, []); // the interval survives every options change, and still reads the latest\n */\nexport function useLatestRef<T>(value: T): RefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-latest-ref.cjs","names":[],"sources":["../../src/hooks/use-latest-ref.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- writing at render time is deliberate; an effect would add a staleness window (see the docstring) */\nimport { useRef, type RefObject } from \"react\";\n\n/**\n * Keeps a ref pointing at the most recent value it was given.\n *\n * The escape hatch for reading fresh state inside something that must not be\n * re-created when that state changes: an interval, a subscription, an event\n * listener registered once on mount. Listing the value in the effect's\n * dependencies would tear the effect down and set it back up on every change;\n * omitting it captures the value from the render that created the closure and\n * never sees another. The ref is neither — a stable object whose `current` is\n * always current.\n *\n * The assignment happens **during render**, for the same reason\n * {@link useStableCallback} does it: moving it into an effect opens a\n * one-commit staleness window, where an effect declared earlier in the same\n * commit reads the previous render's value.\n *\n * Reach for {@link useStableCallback} instead when the value is a function you\n * want to *call* — it hands back a callable with a stable identity, rather than\n * making every call site reach through `.current`.\n *\n * **List the returned ref in your effect's dependencies.** It is a stable object,\n * so the effect never re-runs because of it, but `react-hooks/exhaustive-deps`\n * cannot prove that for a custom hook the way it does for a bare `useRef`.\n * Listing it lets the rule verify the array instead of taking an omission on\n * trust.\n *\n * **Not for holding the previous value.** The write happens during render, so\n * `.current` is already the current value by the time any effect reads it. A hook\n * that wants the value from the *previous* commit — `usePrevious` — needs the\n * effect-based write, and swapping it for this would make it return the present.\n *\n * @typeParam T - The tracked value.\n * @param value - The value to track. Written on every render.\n * @returns A stable ref whose `current` holds the latest `value`.\n *\n * @example\n * const optionsRef = useLatestRef(options);\n *\n * useEffect(() => {\n * const id = setInterval(() => poll(optionsRef.current), 5_000);\n * return () => clearInterval(id);\n * }, []); // the interval survives every options change, and still reads the latest\n */\nexport function useLatestRef<T>(value: T): RefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n"],"mappings":"uBA8CA,SAAgB,EAAgB,EAAwB,CACpD,IAAM,GAAA,EAAM,EAAA,OAAA,CAAO,CAAK,EAExB,MADA,GAAI,QAAU,EACP,CACX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-latest-ref.js","names":[],"sources":["../../src/hooks/use-latest-ref.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- writing at render time is deliberate; an effect would add a staleness window (see the docstring) */\nimport { useRef, type RefObject } from \"react\";\n\n/**\n * Keeps a ref pointing at the most recent value it was given.\n *\n * The escape hatch for reading fresh state inside something that must not be\n * re-created when that state changes: an interval, a subscription, an event\n * listener registered once on mount. Listing the value in the effect's\n * dependencies would tear the effect down and set it back up on every change;\n * omitting it captures the value from the render that created the closure and\n * never sees another. The ref is neither — a stable object whose `current` is\n * always current.\n *\n * The assignment happens **during render**, for the same reason\n * {@link useStableCallback} does it: moving it into an effect opens a\n * one-commit staleness window, where an effect declared earlier in the same\n * commit reads the previous render's value.\n *\n * Reach for {@link useStableCallback} instead when the value is a function you\n * want to *call* — it hands back a callable with a stable identity, rather than\n * making every call site reach through `.current`.\n *\n * @typeParam T - The tracked value.\n * @param value - The value to track. Written on every render.\n * @returns A stable ref whose `current` holds the latest `value`.\n *\n * @example\n * const optionsRef = useLatestRef(options);\n *\n * useEffect(() => {\n * const id = setInterval(() => poll(optionsRef.current), 5_000);\n * return () => clearInterval(id);\n * }, []); // the interval survives every options change, and still reads the latest\n */\nexport function useLatestRef<T>(value: T): RefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"use-latest-ref.js","names":[],"sources":["../../src/hooks/use-latest-ref.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- writing at render time is deliberate; an effect would add a staleness window (see the docstring) */\nimport { useRef, type RefObject } from \"react\";\n\n/**\n * Keeps a ref pointing at the most recent value it was given.\n *\n * The escape hatch for reading fresh state inside something that must not be\n * re-created when that state changes: an interval, a subscription, an event\n * listener registered once on mount. Listing the value in the effect's\n * dependencies would tear the effect down and set it back up on every change;\n * omitting it captures the value from the render that created the closure and\n * never sees another. The ref is neither — a stable object whose `current` is\n * always current.\n *\n * The assignment happens **during render**, for the same reason\n * {@link useStableCallback} does it: moving it into an effect opens a\n * one-commit staleness window, where an effect declared earlier in the same\n * commit reads the previous render's value.\n *\n * Reach for {@link useStableCallback} instead when the value is a function you\n * want to *call* — it hands back a callable with a stable identity, rather than\n * making every call site reach through `.current`.\n *\n * **List the returned ref in your effect's dependencies.** It is a stable object,\n * so the effect never re-runs because of it, but `react-hooks/exhaustive-deps`\n * cannot prove that for a custom hook the way it does for a bare `useRef`.\n * Listing it lets the rule verify the array instead of taking an omission on\n * trust.\n *\n * **Not for holding the previous value.** The write happens during render, so\n * `.current` is already the current value by the time any effect reads it. A hook\n * that wants the value from the *previous* commit — `usePrevious` — needs the\n * effect-based write, and swapping it for this would make it return the present.\n *\n * @typeParam T - The tracked value.\n * @param value - The value to track. Written on every render.\n * @returns A stable ref whose `current` holds the latest `value`.\n *\n * @example\n * const optionsRef = useLatestRef(options);\n *\n * useEffect(() => {\n * const id = setInterval(() => poll(optionsRef.current), 5_000);\n * return () => clearInterval(id);\n * }, []); // the interval survives every options change, and still reads the latest\n */\nexport function useLatestRef<T>(value: T): RefObject<T> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n"],"mappings":";;AA8CA,SAAgB,EAAgB,GAAwB;CACpD,IAAM,IAAM,EAAO,CAAK;CAExB,OADA,EAAI,UAAU,GACP;AACX"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./use-latest-ref.cjs");let t=require("react");function n(n,r={}){let{delayMs:i=500,disabled:a=!1}=r,o=(0,t.useRef)(null),s=(0,t.useRef)(!1),c=e.useLatestRef(n),l=(0,t.useCallback)(()=>{o.current!==null&&(window.clearTimeout(o.current),o.current=null)},[]),u=(0,t.useCallback)(()=>{a||(s.current=!1,l(),o.current=window.setTimeout(()=>{s.current=!0,c.current()},i))},[a,l,i,c]);return{onMouseDown:u,onMouseUp:l,onMouseLeave:l,onTouchStart:u,onTouchEnd:l,onTouchMove:l,onContextMenu:(0,t.useCallback)(e=>{a||(e.preventDefault(),s.current=!0,c.current())},[a,c]),wasLongPress:()=>s.current}}exports.useLongPressHandlers=n;
|
|
2
2
|
//# sourceMappingURL=use-long-press-handlers.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-long-press-handlers.cjs","names":[],"sources":["../../src/hooks/use-long-press-handlers.ts"],"sourcesContent":["import { useCallback,
|
|
1
|
+
{"version":3,"file":"use-long-press-handlers.cjs","names":[],"sources":["../../src/hooks/use-long-press-handlers.ts"],"sourcesContent":["import { useCallback, useRef } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\nimport type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from \"react\";\n\n/**\n * DOM event handlers produced by {@link useLongPressHandlers}, ready to spread\n * onto a JSX element (`<div {...handlers}>`).\n */\nexport interface LongPressHandlers {\n /** Starts the hold timer on mouse press. */\n onMouseDown: (event: ReactMouseEvent) => void;\n /** Cancels the pending hold when the mouse is released. */\n onMouseUp: () => void;\n /** Cancels the pending hold when the pointer leaves the element. */\n onMouseLeave: () => void;\n /** Starts the hold timer on touch start. */\n onTouchStart: (event: ReactTouchEvent) => void;\n /** Cancels the pending hold when the touch ends. */\n onTouchEnd: () => void;\n /** Cancels the pending hold when the finger moves. */\n onTouchMove: () => void;\n /** Fires the long-press immediately (desktop right-click parity). */\n onContextMenu: (event: ReactMouseEvent) => void;\n}\n\n/** Options accepted by {@link useLongPressHandlers}. */\nexport interface UseLongPressHandlersOptions {\n /** Hold duration in ms before `onLongPress` fires. Defaults to `500`. */\n delayMs?: number;\n /** When `true`, the hook is inert and every handler is a no-op. */\n disabled?: boolean;\n}\n\n/** Return shape of {@link useLongPressHandlers}. */\nexport type UseLongPressHandlersResult = LongPressHandlers & {\n /**\n * Reads whether the most recent interaction fired a long-press. Use it in\n * the element's `onClick` to suppress the click that follows a long-press.\n */\n wasLongPress: () => boolean;\n};\n\n/**\n * Returns DOM event handlers that detect a long press (touch or mouse hold)\n * and invoke `onLongPress` once after `delayMs`.\n *\n * Cancels on touch movement or pointer release. Also wires `contextmenu` to\n * fire `onLongPress` immediately so a right-click on desktop opens selection\n * mode the same way an Android long-press does on mobile.\n *\n * The hook does not `preventDefault` on the underlying click — the consumer\n * decides whether the subsequent click should still fire. Track that with the\n * returned `wasLongPress()` guard to tell \"long-press fired\" apart from a\n * \"regular click\".\n *\n * Unlike {@link useLongPress}, which attaches pointer listeners to a `ref`,\n * this variant returns handler props you spread directly onto an element and\n * exposes a `wasLongPress()` guard.\n *\n * @param onLongPress - Callback invoked once the hold threshold is reached.\n * @param options - Optional `delayMs` and `disabled` flags.\n * @returns The spreadable handlers plus a `wasLongPress()` guard.\n *\n * @example\n * const longPress = useLongPressHandlers(() => enterSelectionMode(), { delayMs: 600 });\n * <button {...longPress} onClick={() => { if (!longPress.wasLongPress()) navigate(); }}>\n * Item\n * </button>\n */\nexport function useLongPressHandlers(\n onLongPress: () => void,\n options: UseLongPressHandlersOptions = {},\n): UseLongPressHandlersResult {\n const { delayMs = 500, disabled = false } = options;\n const timerRef = useRef<number | null>(null);\n const firedRef = useRef<boolean>(false);\n const callbackRef = useLatestRef(onLongPress);\n\n const clear = useCallback((): void => {\n if (timerRef.current !== null) {\n window.clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n\n const start = useCallback((): void => {\n if (disabled) return;\n firedRef.current = false;\n clear();\n timerRef.current = window.setTimeout(() => {\n firedRef.current = true;\n callbackRef.current();\n }, delayMs);\n }, [disabled, clear, delayMs, callbackRef]);\n\n const onContextMenu = useCallback(\n (event: ReactMouseEvent): void => {\n if (disabled) return;\n event.preventDefault();\n firedRef.current = true;\n callbackRef.current();\n },\n [disabled, callbackRef],\n );\n\n return {\n onMouseDown: start,\n onMouseUp: clear,\n onMouseLeave: clear,\n onTouchStart: start,\n onTouchEnd: clear,\n onTouchMove: clear,\n onContextMenu,\n wasLongPress: () => firedRef.current,\n };\n}\n"],"mappings":"+DAqEA,SAAgB,EACZ,EACA,EAAuC,CAAC,EACd,CAC1B,GAAM,CAAE,UAAU,IAAK,WAAW,IAAU,EACtC,GAAA,EAAW,EAAA,OAAA,CAAsB,IAAI,EACrC,GAAA,EAAW,EAAA,OAAA,CAAgB,EAAK,EAChC,EAAc,EAAA,aAAa,CAAW,EAEtC,GAAA,EAAQ,EAAA,YAAA,KAAwB,CAC9B,EAAS,UAAY,OACrB,OAAO,aAAa,EAAS,OAAO,EACpC,EAAS,QAAU,KAE3B,EAAG,CAAC,CAAC,EAEC,GAAA,EAAQ,EAAA,YAAA,KAAwB,CAC9B,IACJ,EAAS,QAAU,GACnB,EAAM,EACN,EAAS,QAAU,OAAO,eAAiB,CACvC,EAAS,QAAU,GACnB,EAAY,QAAQ,CACxB,EAAG,CAAO,EACd,EAAG,CAAC,EAAU,EAAO,EAAS,CAAW,CAAC,EAY1C,MAAO,CACH,YAAa,EACb,UAAW,EACX,aAAc,EACd,aAAc,EACd,WAAY,EACZ,YAAa,EACb,eAAA,EAjBkB,EAAA,YAAA,CACjB,GAAiC,CAC1B,IACJ,EAAM,eAAe,EACrB,EAAS,QAAU,GACnB,EAAY,QAAQ,EACxB,EACA,CAAC,EAAU,CAAW,CAUtB,EACA,iBAAoB,EAAS,OACjC,CACJ"}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "./use-latest-ref.js";
|
|
2
|
+
import { useCallback as t, useRef as n } from "react";
|
|
2
3
|
//#region src/hooks/use-long-press-handlers.ts
|
|
3
4
|
function r(r, i = {}) {
|
|
4
|
-
let { delayMs: a = 500, disabled: o = !1 } = i, s = n(null), c = n(!1), l =
|
|
5
|
-
t(() => {
|
|
6
|
-
l.current = r;
|
|
7
|
-
}, [r]);
|
|
8
|
-
let u = e(() => {
|
|
5
|
+
let { delayMs: a = 500, disabled: o = !1 } = i, s = n(null), c = n(!1), l = e(r), u = t(() => {
|
|
9
6
|
s.current !== null && (window.clearTimeout(s.current), s.current = null);
|
|
10
|
-
}, []), d =
|
|
7
|
+
}, []), d = t(() => {
|
|
11
8
|
o || (c.current = !1, u(), s.current = window.setTimeout(() => {
|
|
12
9
|
c.current = !0, l.current();
|
|
13
10
|
}, a));
|
|
14
11
|
}, [
|
|
15
12
|
o,
|
|
16
13
|
u,
|
|
17
|
-
a
|
|
14
|
+
a,
|
|
15
|
+
l
|
|
18
16
|
]);
|
|
19
17
|
return {
|
|
20
18
|
onMouseDown: d,
|
|
@@ -23,9 +21,9 @@ function r(r, i = {}) {
|
|
|
23
21
|
onTouchStart: d,
|
|
24
22
|
onTouchEnd: u,
|
|
25
23
|
onTouchMove: u,
|
|
26
|
-
onContextMenu:
|
|
24
|
+
onContextMenu: t((e) => {
|
|
27
25
|
o || (e.preventDefault(), c.current = !0, l.current());
|
|
28
|
-
}, [o]),
|
|
26
|
+
}, [o, l]),
|
|
29
27
|
wasLongPress: () => c.current
|
|
30
28
|
};
|
|
31
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-long-press-handlers.js","names":[],"sources":["../../src/hooks/use-long-press-handlers.ts"],"sourcesContent":["import { useCallback,
|
|
1
|
+
{"version":3,"file":"use-long-press-handlers.js","names":[],"sources":["../../src/hooks/use-long-press-handlers.ts"],"sourcesContent":["import { useCallback, useRef } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\nimport type { MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent } from \"react\";\n\n/**\n * DOM event handlers produced by {@link useLongPressHandlers}, ready to spread\n * onto a JSX element (`<div {...handlers}>`).\n */\nexport interface LongPressHandlers {\n /** Starts the hold timer on mouse press. */\n onMouseDown: (event: ReactMouseEvent) => void;\n /** Cancels the pending hold when the mouse is released. */\n onMouseUp: () => void;\n /** Cancels the pending hold when the pointer leaves the element. */\n onMouseLeave: () => void;\n /** Starts the hold timer on touch start. */\n onTouchStart: (event: ReactTouchEvent) => void;\n /** Cancels the pending hold when the touch ends. */\n onTouchEnd: () => void;\n /** Cancels the pending hold when the finger moves. */\n onTouchMove: () => void;\n /** Fires the long-press immediately (desktop right-click parity). */\n onContextMenu: (event: ReactMouseEvent) => void;\n}\n\n/** Options accepted by {@link useLongPressHandlers}. */\nexport interface UseLongPressHandlersOptions {\n /** Hold duration in ms before `onLongPress` fires. Defaults to `500`. */\n delayMs?: number;\n /** When `true`, the hook is inert and every handler is a no-op. */\n disabled?: boolean;\n}\n\n/** Return shape of {@link useLongPressHandlers}. */\nexport type UseLongPressHandlersResult = LongPressHandlers & {\n /**\n * Reads whether the most recent interaction fired a long-press. Use it in\n * the element's `onClick` to suppress the click that follows a long-press.\n */\n wasLongPress: () => boolean;\n};\n\n/**\n * Returns DOM event handlers that detect a long press (touch or mouse hold)\n * and invoke `onLongPress` once after `delayMs`.\n *\n * Cancels on touch movement or pointer release. Also wires `contextmenu` to\n * fire `onLongPress` immediately so a right-click on desktop opens selection\n * mode the same way an Android long-press does on mobile.\n *\n * The hook does not `preventDefault` on the underlying click — the consumer\n * decides whether the subsequent click should still fire. Track that with the\n * returned `wasLongPress()` guard to tell \"long-press fired\" apart from a\n * \"regular click\".\n *\n * Unlike {@link useLongPress}, which attaches pointer listeners to a `ref`,\n * this variant returns handler props you spread directly onto an element and\n * exposes a `wasLongPress()` guard.\n *\n * @param onLongPress - Callback invoked once the hold threshold is reached.\n * @param options - Optional `delayMs` and `disabled` flags.\n * @returns The spreadable handlers plus a `wasLongPress()` guard.\n *\n * @example\n * const longPress = useLongPressHandlers(() => enterSelectionMode(), { delayMs: 600 });\n * <button {...longPress} onClick={() => { if (!longPress.wasLongPress()) navigate(); }}>\n * Item\n * </button>\n */\nexport function useLongPressHandlers(\n onLongPress: () => void,\n options: UseLongPressHandlersOptions = {},\n): UseLongPressHandlersResult {\n const { delayMs = 500, disabled = false } = options;\n const timerRef = useRef<number | null>(null);\n const firedRef = useRef<boolean>(false);\n const callbackRef = useLatestRef(onLongPress);\n\n const clear = useCallback((): void => {\n if (timerRef.current !== null) {\n window.clearTimeout(timerRef.current);\n timerRef.current = null;\n }\n }, []);\n\n const start = useCallback((): void => {\n if (disabled) return;\n firedRef.current = false;\n clear();\n timerRef.current = window.setTimeout(() => {\n firedRef.current = true;\n callbackRef.current();\n }, delayMs);\n }, [disabled, clear, delayMs, callbackRef]);\n\n const onContextMenu = useCallback(\n (event: ReactMouseEvent): void => {\n if (disabled) return;\n event.preventDefault();\n firedRef.current = true;\n callbackRef.current();\n },\n [disabled, callbackRef],\n );\n\n return {\n onMouseDown: start,\n onMouseUp: clear,\n onMouseLeave: clear,\n onTouchStart: start,\n onTouchEnd: clear,\n onTouchMove: clear,\n onContextMenu,\n wasLongPress: () => firedRef.current,\n };\n}\n"],"mappings":";;;AAqEA,SAAgB,EACZ,GACA,IAAuC,CAAC,GACd;CAC1B,IAAM,EAAE,aAAU,KAAK,cAAW,OAAU,GACtC,IAAW,EAAsB,IAAI,GACrC,IAAW,EAAgB,EAAK,GAChC,IAAc,EAAa,CAAW,GAEtC,IAAQ,QAAwB;EAClC,AAAI,EAAS,YAAY,SACrB,OAAO,aAAa,EAAS,OAAO,GACpC,EAAS,UAAU;CAE3B,GAAG,CAAC,CAAC,GAEC,IAAQ,QAAwB;EAC9B,MACJ,EAAS,UAAU,IACnB,EAAM,GACN,EAAS,UAAU,OAAO,iBAAiB;GAEvC,AADA,EAAS,UAAU,IACnB,EAAY,QAAQ;EACxB,GAAG,CAAO;CACd,GAAG;EAAC;EAAU;EAAO;EAAS;CAAW,CAAC;CAY1C,OAAO;EACH,aAAa;EACb,WAAW;EACX,cAAc;EACd,cAAc;EACd,YAAY;EACZ,aAAa;EACb,eAjBkB,GACjB,MAAiC;GAC1B,MACJ,EAAM,eAAe,GACrB,EAAS,UAAU,IACnB,EAAY,QAAQ;EACxB,GACA,CAAC,GAAU,CAAW,CAUtB;EACA,oBAAoB,EAAS;CACjC;AACJ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./use-latest-ref.cjs");let t=require("react");function n(n,r,i={}){let{delay:a=500,moveThreshold:o=10}=i,s=e.useLatestRef(r);(0,t.useEffect)(()=>{let e=n.current;if(!e)return;let t=null,r=0,i=0,c=()=>{t&&=(clearTimeout(t),null)},l=e=>{r=e.clientX,i=e.clientY,c(),t=setTimeout(()=>{t=null,s.current()},a)},u=e=>{if(t===null)return;let n=e.clientX-r,a=e.clientY-i;Math.hypot(n,a)>o&&c()};return e.addEventListener(`pointerdown`,l),e.addEventListener(`pointermove`,u),e.addEventListener(`pointerup`,c),e.addEventListener(`pointercancel`,c),e.addEventListener(`pointerleave`,c),()=>{c(),e.removeEventListener(`pointerdown`,l),e.removeEventListener(`pointermove`,u),e.removeEventListener(`pointerup`,c),e.removeEventListener(`pointercancel`,c),e.removeEventListener(`pointerleave`,c)}},[n,a,o,s])}exports.useLongPress=n;
|
|
2
2
|
//# sourceMappingURL=use-long-press.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-long-press.cjs","names":[],"sources":["../../src/hooks/use-long-press.ts"],"sourcesContent":["import { useEffect
|
|
1
|
+
{"version":3,"file":"use-long-press.cjs","names":[],"sources":["../../src/hooks/use-long-press.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\nimport type { RefObject } from \"react\";\n\nexport interface UseLongPressOptions {\n /** Press duration in ms. Default `500`. */\n delay?: number;\n /** Pixel threshold — finger/mouse movement beyond this cancels the press. Default `10`. */\n moveThreshold?: number;\n}\n\n/**\n * Detect long-press / long-tap gestures. Fires `fn` after `delay` ms\n * while the element is held. Cancels on move beyond `moveThreshold` or\n * pointer up before `delay`.\n *\n * @example\n * const ref = useRef<HTMLDivElement>(null);\n * useLongPress(ref, () => openContextMenu(), { delay: 600 });\n */\nexport function useLongPress<T extends HTMLElement>(\n ref: RefObject<T | null>,\n fn: () => void,\n options: UseLongPressOptions = {},\n): void {\n const { delay = 500, moveThreshold = 10 } = options;\n const fnRef = useLatestRef(fn);\n\n useEffect(() => {\n const node = ref.current;\n if (!node) return;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let startX = 0;\n let startY = 0;\n\n const cancel = (): void => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n\n const onDown = (event: PointerEvent): void => {\n startX = event.clientX;\n startY = event.clientY;\n cancel();\n timer = setTimeout(() => {\n timer = null;\n fnRef.current();\n }, delay);\n };\n\n const onMove = (event: PointerEvent): void => {\n if (timer === null) return;\n const dx = event.clientX - startX;\n const dy = event.clientY - startY;\n if (Math.hypot(dx, dy) > moveThreshold) cancel();\n };\n\n node.addEventListener(\"pointerdown\", onDown);\n node.addEventListener(\"pointermove\", onMove);\n node.addEventListener(\"pointerup\", cancel);\n node.addEventListener(\"pointercancel\", cancel);\n node.addEventListener(\"pointerleave\", cancel);\n return () => {\n cancel();\n node.removeEventListener(\"pointerdown\", onDown);\n node.removeEventListener(\"pointermove\", onMove);\n node.removeEventListener(\"pointerup\", cancel);\n node.removeEventListener(\"pointercancel\", cancel);\n node.removeEventListener(\"pointerleave\", cancel);\n };\n }, [ref, delay, moveThreshold, fnRef]);\n}\n"],"mappings":"+DAoBA,SAAgB,EACZ,EACA,EACA,EAA+B,CAAC,EAC5B,CACJ,GAAM,CAAE,QAAQ,IAAK,gBAAgB,IAAO,EACtC,EAAQ,EAAA,aAAa,CAAE,GAE7B,EAAA,EAAA,UAAA,KAAgB,CACZ,IAAM,EAAO,EAAI,QACjB,GAAI,CAAC,EAAM,OACX,IAAI,EAA8C,KAC9C,EAAS,EACT,EAAS,EAEP,MAAqB,CACvB,AAEI,KADA,aAAa,CAAK,EACV,KAEhB,EAEM,EAAU,GAA8B,CAC1C,EAAS,EAAM,QACf,EAAS,EAAM,QACf,EAAO,EACP,EAAQ,eAAiB,CACrB,EAAQ,KACR,EAAM,QAAQ,CAClB,EAAG,CAAK,CACZ,EAEM,EAAU,GAA8B,CAC1C,GAAI,IAAU,KAAM,OACpB,IAAM,EAAK,EAAM,QAAU,EACrB,EAAK,EAAM,QAAU,EACvB,KAAK,MAAM,EAAI,CAAE,EAAI,GAAe,EAAO,CACnD,EAOA,OALA,EAAK,iBAAiB,cAAe,CAAM,EAC3C,EAAK,iBAAiB,cAAe,CAAM,EAC3C,EAAK,iBAAiB,YAAa,CAAM,EACzC,EAAK,iBAAiB,gBAAiB,CAAM,EAC7C,EAAK,iBAAiB,eAAgB,CAAM,MAC/B,CACT,EAAO,EACP,EAAK,oBAAoB,cAAe,CAAM,EAC9C,EAAK,oBAAoB,cAAe,CAAM,EAC9C,EAAK,oBAAoB,YAAa,CAAM,EAC5C,EAAK,oBAAoB,gBAAiB,CAAM,EAChD,EAAK,oBAAoB,eAAgB,CAAM,CACnD,CACJ,EAAG,CAAC,EAAK,EAAO,EAAe,CAAK,CAAC,CACzC"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useLatestRef as e } from "./use-latest-ref.js";
|
|
2
|
+
import { useEffect as t } from "react";
|
|
2
3
|
//#region src/hooks/use-long-press.ts
|
|
3
4
|
function n(n, r, i = {}) {
|
|
4
|
-
let { delay: a = 500, moveThreshold: o = 10 } = i, s =
|
|
5
|
-
|
|
6
|
-
s.current = r;
|
|
7
|
-
}, [r]), e(() => {
|
|
5
|
+
let { delay: a = 500, moveThreshold: o = 10 } = i, s = e(r);
|
|
6
|
+
t(() => {
|
|
8
7
|
let e = n.current;
|
|
9
8
|
if (!e) return;
|
|
10
9
|
let t = null, r = 0, i = 0, c = () => {
|
|
@@ -24,7 +23,8 @@ function n(n, r, i = {}) {
|
|
|
24
23
|
}, [
|
|
25
24
|
n,
|
|
26
25
|
a,
|
|
27
|
-
o
|
|
26
|
+
o,
|
|
27
|
+
s
|
|
28
28
|
]);
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-long-press.js","names":[],"sources":["../../src/hooks/use-long-press.ts"],"sourcesContent":["import { useEffect
|
|
1
|
+
{"version":3,"file":"use-long-press.js","names":[],"sources":["../../src/hooks/use-long-press.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\nimport type { RefObject } from \"react\";\n\nexport interface UseLongPressOptions {\n /** Press duration in ms. Default `500`. */\n delay?: number;\n /** Pixel threshold — finger/mouse movement beyond this cancels the press. Default `10`. */\n moveThreshold?: number;\n}\n\n/**\n * Detect long-press / long-tap gestures. Fires `fn` after `delay` ms\n * while the element is held. Cancels on move beyond `moveThreshold` or\n * pointer up before `delay`.\n *\n * @example\n * const ref = useRef<HTMLDivElement>(null);\n * useLongPress(ref, () => openContextMenu(), { delay: 600 });\n */\nexport function useLongPress<T extends HTMLElement>(\n ref: RefObject<T | null>,\n fn: () => void,\n options: UseLongPressOptions = {},\n): void {\n const { delay = 500, moveThreshold = 10 } = options;\n const fnRef = useLatestRef(fn);\n\n useEffect(() => {\n const node = ref.current;\n if (!node) return;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let startX = 0;\n let startY = 0;\n\n const cancel = (): void => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n };\n\n const onDown = (event: PointerEvent): void => {\n startX = event.clientX;\n startY = event.clientY;\n cancel();\n timer = setTimeout(() => {\n timer = null;\n fnRef.current();\n }, delay);\n };\n\n const onMove = (event: PointerEvent): void => {\n if (timer === null) return;\n const dx = event.clientX - startX;\n const dy = event.clientY - startY;\n if (Math.hypot(dx, dy) > moveThreshold) cancel();\n };\n\n node.addEventListener(\"pointerdown\", onDown);\n node.addEventListener(\"pointermove\", onMove);\n node.addEventListener(\"pointerup\", cancel);\n node.addEventListener(\"pointercancel\", cancel);\n node.addEventListener(\"pointerleave\", cancel);\n return () => {\n cancel();\n node.removeEventListener(\"pointerdown\", onDown);\n node.removeEventListener(\"pointermove\", onMove);\n node.removeEventListener(\"pointerup\", cancel);\n node.removeEventListener(\"pointercancel\", cancel);\n node.removeEventListener(\"pointerleave\", cancel);\n };\n }, [ref, delay, moveThreshold, fnRef]);\n}\n"],"mappings":";;;AAoBA,SAAgB,EACZ,GACA,GACA,IAA+B,CAAC,GAC5B;CACJ,IAAM,EAAE,WAAQ,KAAK,mBAAgB,OAAO,GACtC,IAAQ,EAAa,CAAE;CAE7B,QAAgB;EACZ,IAAM,IAAO,EAAI;EACjB,IAAI,CAAC,GAAM;EACX,IAAI,IAA8C,MAC9C,IAAS,GACT,IAAS,GAEP,UAAqB;GACvB,AAEI,OADA,aAAa,CAAK,GACV;EAEhB,GAEM,KAAU,MAA8B;GAI1C,AAHA,IAAS,EAAM,SACf,IAAS,EAAM,SACf,EAAO,GACP,IAAQ,iBAAiB;IAErB,AADA,IAAQ,MACR,EAAM,QAAQ;GAClB,GAAG,CAAK;EACZ,GAEM,KAAU,MAA8B;GAC1C,IAAI,MAAU,MAAM;GACpB,IAAM,IAAK,EAAM,UAAU,GACrB,IAAK,EAAM,UAAU;GAC3B,AAAI,KAAK,MAAM,GAAI,CAAE,IAAI,KAAe,EAAO;EACnD;EAOA,OALA,EAAK,iBAAiB,eAAe,CAAM,GAC3C,EAAK,iBAAiB,eAAe,CAAM,GAC3C,EAAK,iBAAiB,aAAa,CAAM,GACzC,EAAK,iBAAiB,iBAAiB,CAAM,GAC7C,EAAK,iBAAiB,gBAAgB,CAAM,SAC/B;GAMT,AALA,EAAO,GACP,EAAK,oBAAoB,eAAe,CAAM,GAC9C,EAAK,oBAAoB,eAAe,CAAM,GAC9C,EAAK,oBAAoB,aAAa,CAAM,GAC5C,EAAK,oBAAoB,iBAAiB,CAAM,GAChD,EAAK,oBAAoB,gBAAgB,CAAM;EACnD;CACJ,GAAG;EAAC;EAAK;EAAO;EAAe;CAAK,CAAC;AACzC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
const e=require("./use-latest-ref.cjs");let t=require("react");function n(n={}){let{pingUrl:r,intervalMs:i=3e4,timeoutMs:a=5e3}=n,[o,s]=(0,t.useState)(()=>typeof navigator>`u`||navigator.onLine),[c,l]=(0,t.useState)(!0),u=e.useLatestRef({pingUrl:r,timeoutMs:a});return(0,t.useEffect)(()=>{if(typeof window>`u`)return;let e=()=>s(!0),t=()=>s(!1);return window.addEventListener(`online`,e),window.addEventListener(`offline`,t),()=>{window.removeEventListener(`online`,e),window.removeEventListener(`offline`,t)}},[]),(0,t.useEffect)(()=>{if(!r||typeof window>`u`)return;let e=!1,t=async()=>{if(typeof navigator<`u`&&!navigator.onLine){e||l(!1);return}let t=new AbortController,n=window.setTimeout(()=>t.abort(),u.current.timeoutMs);try{await fetch(u.current.pingUrl,{method:`HEAD`,cache:`no-store`,signal:t.signal}),e||l(!0)}catch{e||l(!1)}finally{window.clearTimeout(n)}};t();let n=window.setInterval(()=>void t(),i),a=()=>void t();return window.addEventListener(`online`,a),document.addEventListener(`visibilitychange`,a),()=>{e=!0,window.clearInterval(n),window.removeEventListener(`online`,a),document.removeEventListener(`visibilitychange`,a)}},[r,i,u]),r?o&&c:o}exports.useOnline=n;
|
|
2
2
|
//# sourceMappingURL=use-online.cjs.map
|