@dxos/react-hooks 0.6.10-main.bbdfaa4 → 0.6.10-staging.3cfcc89
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/lib/browser/index.mjs +64 -34
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +57 -29
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/index.d.ts +3 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/useAsyncCallback.d.ts +2 -0
- package/dist/types/src/useAsyncCallback.d.ts.map +1 -0
- package/dist/types/src/useControlledValue.d.ts.map +1 -1
- package/dist/types/src/useDynamicRef.d.ts +2 -0
- package/dist/types/src/useDynamicRef.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/index.ts +3 -1
- package/src/useAsyncCallback.ts +19 -0
- package/src/useControlledValue.ts +3 -1
- package/src/useDynamicRef.ts +13 -0
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
// packages/ui/primitives/react-hooks/src/
|
|
1
|
+
// packages/ui/primitives/react-hooks/src/useAsyncCallback.ts
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
|
-
var
|
|
4
|
-
const [value, setValue] = useState(
|
|
3
|
+
var useAsyncCallback = (cb) => {
|
|
4
|
+
const [value, setValue] = useState();
|
|
5
5
|
useEffect(() => {
|
|
6
|
-
|
|
6
|
+
const t = setTimeout(async () => {
|
|
7
|
+
const data = await cb();
|
|
8
|
+
setValue(data);
|
|
9
|
+
});
|
|
10
|
+
return () => clearTimeout(t);
|
|
11
|
+
}, []);
|
|
12
|
+
return value;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// packages/ui/primitives/react-hooks/src/useControlledValue.ts
|
|
16
|
+
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
17
|
+
var useControlledValue = (controlledValue) => {
|
|
18
|
+
const [value, setValue] = useState2(controlledValue);
|
|
19
|
+
useEffect2(() => {
|
|
20
|
+
if (controlledValue !== void 0) {
|
|
21
|
+
setValue(controlledValue);
|
|
22
|
+
}
|
|
7
23
|
}, [
|
|
8
24
|
controlledValue
|
|
9
25
|
]);
|
|
@@ -14,17 +30,29 @@ var useControlledValue = (controlledValue) => {
|
|
|
14
30
|
};
|
|
15
31
|
|
|
16
32
|
// packages/ui/primitives/react-hooks/src/useDefaultValue.ts
|
|
17
|
-
import { useEffect as
|
|
33
|
+
import { useEffect as useEffect3, useState as useState3, useMemo } from "react";
|
|
18
34
|
var useDefaultValue = (reactiveValue, defaultValue) => {
|
|
19
35
|
const stableDefaultValue = useMemo(() => defaultValue, []);
|
|
20
|
-
const [value, setValue] =
|
|
21
|
-
|
|
36
|
+
const [value, setValue] = useState3(reactiveValue ?? stableDefaultValue);
|
|
37
|
+
useEffect3(() => setValue(reactiveValue ?? stableDefaultValue), [
|
|
22
38
|
reactiveValue,
|
|
23
39
|
stableDefaultValue
|
|
24
40
|
]);
|
|
25
41
|
return value;
|
|
26
42
|
};
|
|
27
43
|
|
|
44
|
+
// packages/ui/primitives/react-hooks/src/useDynamicRef.ts
|
|
45
|
+
import { useEffect as useEffect4, useRef } from "react";
|
|
46
|
+
var useDynamicRef = (value) => {
|
|
47
|
+
const ref = useRef(value);
|
|
48
|
+
useEffect4(() => {
|
|
49
|
+
ref.current = value;
|
|
50
|
+
}, [
|
|
51
|
+
value
|
|
52
|
+
]);
|
|
53
|
+
return ref;
|
|
54
|
+
};
|
|
55
|
+
|
|
28
56
|
// packages/ui/primitives/react-hooks/src/useFileDownload.ts
|
|
29
57
|
import { useMemo as useMemo2 } from "react";
|
|
30
58
|
var useFileDownload = () => {
|
|
@@ -39,10 +67,10 @@ var useFileDownload = () => {
|
|
|
39
67
|
};
|
|
40
68
|
|
|
41
69
|
// packages/ui/primitives/react-hooks/src/useForwardedRef.ts
|
|
42
|
-
import { useRef, useEffect as
|
|
70
|
+
import { useRef as useRef2, useEffect as useEffect5 } from "react";
|
|
43
71
|
var useForwardedRef = (ref) => {
|
|
44
|
-
const innerRef =
|
|
45
|
-
|
|
72
|
+
const innerRef = useRef2(null);
|
|
73
|
+
useEffect5(() => {
|
|
46
74
|
if (!ref) {
|
|
47
75
|
return;
|
|
48
76
|
}
|
|
@@ -66,12 +94,12 @@ var useId = (namespace, propsId, opts) => useMemo3(() => propsId ?? `${namespace
|
|
|
66
94
|
]);
|
|
67
95
|
|
|
68
96
|
// packages/ui/primitives/react-hooks/src/useIsFocused.ts
|
|
69
|
-
import { useEffect as
|
|
97
|
+
import { useEffect as useEffect6, useRef as useRef3, useState as useState4 } from "react";
|
|
70
98
|
var useIsFocused = (inputRef) => {
|
|
71
|
-
const [isFocused, setIsFocused] =
|
|
72
|
-
const isFocusedRef =
|
|
99
|
+
const [isFocused, setIsFocused] = useState4(void 0);
|
|
100
|
+
const isFocusedRef = useRef3(isFocused);
|
|
73
101
|
isFocusedRef.current = isFocused;
|
|
74
|
-
|
|
102
|
+
useEffect6(() => {
|
|
75
103
|
const input = inputRef.current;
|
|
76
104
|
if (!input) {
|
|
77
105
|
return;
|
|
@@ -95,7 +123,7 @@ var useIsFocused = (inputRef) => {
|
|
|
95
123
|
};
|
|
96
124
|
|
|
97
125
|
// packages/ui/primitives/react-hooks/src/useMediaQuery.ts
|
|
98
|
-
import { useEffect as
|
|
126
|
+
import { useEffect as useEffect7, useState as useState5 } from "react";
|
|
99
127
|
var breakpointMediaQueries = {
|
|
100
128
|
sm: "(min-width: 640px)",
|
|
101
129
|
md: "(min-width: 768px)",
|
|
@@ -112,13 +140,13 @@ var useMediaQuery = (query, options = {}) => {
|
|
|
112
140
|
fallback
|
|
113
141
|
];
|
|
114
142
|
fallbackValues = fallbackValues.filter((v) => v != null);
|
|
115
|
-
const [value, setValue] =
|
|
143
|
+
const [value, setValue] = useState5(() => {
|
|
116
144
|
return queries.map((query2, index) => ({
|
|
117
145
|
media: query2,
|
|
118
146
|
matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query2).matches
|
|
119
147
|
}));
|
|
120
148
|
});
|
|
121
|
-
|
|
149
|
+
useEffect7(() => {
|
|
122
150
|
setValue(queries.map((query2) => ({
|
|
123
151
|
media: query2,
|
|
124
152
|
matches: document.defaultView?.matchMedia(query2).matches
|
|
@@ -159,15 +187,25 @@ var useMediaQuery = (query, options = {}) => {
|
|
|
159
187
|
return value.map((item) => !!item.matches);
|
|
160
188
|
};
|
|
161
189
|
|
|
190
|
+
// packages/ui/primitives/react-hooks/src/useRefCallback.ts
|
|
191
|
+
import { useState as useState6 } from "react";
|
|
192
|
+
var useRefCallback = () => {
|
|
193
|
+
const [value, setValue] = useState6(null);
|
|
194
|
+
return {
|
|
195
|
+
refCallback: (value2) => setValue(value2),
|
|
196
|
+
value
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
|
|
162
200
|
// packages/ui/primitives/react-hooks/src/useTransitions.ts
|
|
163
|
-
import { useRef as
|
|
201
|
+
import { useRef as useRef4, useEffect as useEffect8, useState as useState7 } from "react";
|
|
164
202
|
var isFunction = (functionToCheck) => {
|
|
165
203
|
return functionToCheck instanceof Function;
|
|
166
204
|
};
|
|
167
205
|
var useDidTransition = (currentValue, fromValue, toValue) => {
|
|
168
|
-
const [hasTransitioned, setHasTransitioned] =
|
|
169
|
-
const previousValue =
|
|
170
|
-
|
|
206
|
+
const [hasTransitioned, setHasTransitioned] = useState7(false);
|
|
207
|
+
const previousValue = useRef4(currentValue);
|
|
208
|
+
useEffect8(() => {
|
|
171
209
|
const toValueValid = isFunction(toValue) ? toValue(currentValue) : toValue === currentValue;
|
|
172
210
|
const fromValueValid = isFunction(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
|
|
173
211
|
const transitioned = fromValueValid && toValueValid;
|
|
@@ -187,15 +225,15 @@ var useDidTransition = (currentValue, fromValue, toValue) => {
|
|
|
187
225
|
return hasTransitioned;
|
|
188
226
|
};
|
|
189
227
|
var useOnTransition = (currentValue, fromValue, toValue, callback) => {
|
|
190
|
-
const dirty =
|
|
228
|
+
const dirty = useRef4(false);
|
|
191
229
|
const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);
|
|
192
|
-
|
|
230
|
+
useEffect8(() => {
|
|
193
231
|
dirty.current = false;
|
|
194
232
|
}, [
|
|
195
233
|
currentValue,
|
|
196
234
|
dirty
|
|
197
235
|
]);
|
|
198
|
-
|
|
236
|
+
useEffect8(() => {
|
|
199
237
|
if (hasTransitioned && !dirty.current) {
|
|
200
238
|
callback();
|
|
201
239
|
dirty.current = true;
|
|
@@ -206,21 +244,13 @@ var useOnTransition = (currentValue, fromValue, toValue, callback) => {
|
|
|
206
244
|
callback
|
|
207
245
|
]);
|
|
208
246
|
};
|
|
209
|
-
|
|
210
|
-
// packages/ui/primitives/react-hooks/src/useRefCallback.ts
|
|
211
|
-
import { useState as useState6 } from "react";
|
|
212
|
-
var useRefCallback = () => {
|
|
213
|
-
const [value, setValue] = useState6(null);
|
|
214
|
-
return {
|
|
215
|
-
refCallback: (value2) => setValue(value2),
|
|
216
|
-
value
|
|
217
|
-
};
|
|
218
|
-
};
|
|
219
247
|
export {
|
|
220
248
|
randomString,
|
|
249
|
+
useAsyncCallback,
|
|
221
250
|
useControlledValue,
|
|
222
251
|
useDefaultValue,
|
|
223
252
|
useDidTransition,
|
|
253
|
+
useDynamicRef,
|
|
224
254
|
useFileDownload,
|
|
225
255
|
useForwardedRef,
|
|
226
256
|
useId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/useControlledValue.ts", "../../../src/useDefaultValue.ts", "../../../src/useFileDownload.ts", "../../../src/useForwardedRef.ts", "../../../src/useId.ts", "../../../src/useIsFocused.ts", "../../../src/useMediaQuery.ts", "../../../src/
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Dispatch, type SetStateAction, useEffect, useState } from 'react';\n\n/**\n * A stateful hook with a controlled value.\n */\nexport const useControlledValue = <TValue>(controlledValue: TValue): [TValue, Dispatch<SetStateAction<TValue>>] => {\n const [value, setValue] = useState<TValue>(controlledValue);\n useEffect(() => {\n setValue(controlledValue);\n }, [controlledValue]);\n\n return [value, setValue];\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState, useMemo } from 'react';\n\n/**\n * A custom React hook that provides a stable default value for a potentially undefined reactive value.\n * The defaultValue is memoized upon component mount and remains unchanged until the component unmounts,\n * ensuring stability across all re-renders, even if the defaultValue prop changes.\n *\n * Note: The defaultValue is not reactive. It retains the same value from the component's mount to unmount.\n *\n * @param reactiveValue - The value that may change over time.\n * @param defaultValue - The initial value used when the reactiveValue is undefined. This value is not reactive.\n * @returns - The reactiveValue if it's defined, otherwise the defaultValue.\n */\nexport const useDefaultValue = <T>(reactiveValue: T | undefined | null, defaultValue: T): T => {\n // Memoize defaultValue with an empty dependency array.\n // This ensures that the defaultValue instance remains stable across all re-renders,\n // regardless of whether the defaultValue changes.\n const stableDefaultValue = useMemo(() => defaultValue, []);\n const [value, setValue] = useState(reactiveValue ?? stableDefaultValue);\n\n useEffect(() => setValue(reactiveValue ?? stableDefaultValue), [reactiveValue, stableDefaultValue]);\n\n return value;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\n/**\n * File download anchor.\n *\n * ```\n * const download = useDownload();\n * const handleDownload = (data: string) => {\n * download(new Blob([data], { type: 'text/plain' }), 'test.txt');\n * };\n * ```\n */\nexport const useFileDownload = (): ((data: Blob | string, filename: string) => void) => {\n return useMemo(\n () => (data: Blob | string, filename: string) => {\n const url = typeof data === 'string' ? data : URL.createObjectURL(data);\n const element = document.createElement('a');\n element.setAttribute('href', url);\n element.setAttribute('download', filename);\n element.setAttribute('target', 'download');\n element.click();\n },\n [],\n );\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type ForwardedRef, useRef, useEffect } from 'react';\n\nexport const useForwardedRef = <T>(ref: ForwardedRef<T>) => {\n const innerRef = useRef<T>(null);\n\n useEffect(() => {\n if (!ref) {\n return;\n }\n\n if (typeof ref === 'function') {\n ref(innerRef.current);\n } else {\n ref.current = innerRef.current;\n }\n });\n\n return innerRef;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport alea from 'alea';\nimport { useMemo } from 'react';\n\ninterface PrngFactory {\n new (seed?: string): () => number;\n}\n\nconst Alea: PrngFactory = alea as unknown as PrngFactory;\n\nconst prng = new Alea('@dxos/react-hooks');\n\n// TODO(burdon): Replace with PublicKey.random().\nexport const randomString = (n = 4) =>\n prng()\n .toString(16)\n .slice(2, n + 2);\n\nexport const useId = (namespace: string, propsId?: string, opts?: Partial<{ n: number }>) =>\n useMemo(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [propsId]);\n", "//\n// Copyright 2022 DXOS.org\n//\n\n// Based upon the useIsFocused hook which is part of the `rci` project:\n/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused\n\nimport { useEffect, useRef, useState, type RefObject } from 'react';\n\nexport const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {\n const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);\n const isFocusedRef = useRef<boolean | undefined>(isFocused);\n\n isFocusedRef.current = isFocused;\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const onFocus = () => setIsFocused(true);\n const onBlur = () => setIsFocused(false);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n\n if (isFocusedRef.current === undefined) {\n setIsFocused(document.activeElement === input);\n }\n\n return () => {\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n };\n }, [inputRef, setIsFocused]);\n\n return isFocused;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// This hook is based on Chakra UI’s `useMediaQuery`: https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/media-query/src/use-media-query.ts\n\nimport { useEffect, useState } from 'react';\n\nexport type UseMediaQueryOptions = {\n fallback?: boolean | boolean[];\n ssr?: boolean;\n};\n\n// TODO(thure): This should be derived from the same source of truth as the Tailwind theme config\nconst breakpointMediaQueries: Record<string, string> = {\n sm: '(min-width: 640px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 1024px)',\n xl: '(min-width: 1280px)',\n '2xl': '(min-width: 1536px)',\n};\n\n/**\n * React hook that tracks state of a CSS media query\n *\n * @param query the media query to match, or a recognized breakpoint token\n * @param options the media query options { fallback, ssr }\n *\n * @see Docs https://chakra-ui.com/docs/hooks/use-media-query\n */\nexport const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {\n const { ssr = true, fallback } = options;\n\n const queries = (Array.isArray(query) ? query : [query]).map((query) =>\n query in breakpointMediaQueries ? breakpointMediaQueries[query] : query,\n );\n\n let fallbackValues = Array.isArray(fallback) ? fallback : [fallback];\n fallbackValues = fallbackValues.filter((v) => v != null) as boolean[];\n\n const [value, setValue] = useState(() => {\n return queries.map((query, index) => ({\n media: query,\n matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query).matches,\n }));\n });\n\n useEffect(() => {\n setValue(\n queries.map((query) => ({\n media: query,\n matches: document.defaultView?.matchMedia(query).matches,\n })),\n );\n\n const mql = queries.map((query) => document.defaultView?.matchMedia(query));\n\n const handler = (evt: MediaQueryListEvent) => {\n setValue((prev) => {\n return prev.slice().map((item) => {\n if (item.media === evt.media) {\n return { ...item, matches: evt.matches };\n }\n return item;\n });\n });\n };\n\n mql.forEach((mql) => {\n if (typeof mql?.addListener === 'function') {\n mql?.addListener(handler);\n } else {\n mql?.addEventListener('change', handler);\n }\n });\n\n return () => {\n mql.forEach((mql) => {\n if (typeof mql?.removeListener === 'function') {\n mql?.removeListener(handler);\n } else {\n mql?.removeEventListener('change', handler);\n }\n });\n };\n }, [document.defaultView]);\n\n return value.map((item) => !!item.matches);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useRef, useEffect, useState } from 'react';\n\nconst isFunction = <T>(functionToCheck: any): functionToCheck is (value: T) => boolean => {\n return functionToCheck instanceof Function;\n};\n\n/**\n * This is an internal custom hook that checks if a value has transitioned from a specified 'from' value to a 'to' value.\n *\n * @param currentValue - The value that is being monitored for transitions.\n * @param fromValue - The *from* value or a predicate function that determines the start of the transition.\n * @param toValue - The *to* value or a predicate function that determines the end of the transition.\n * @returns A boolean indicating whether the transition from *fromValue* to *toValue* has occurred.\n *\n * @internal Consider using `useOnTransition` for handling transitions instead of this hook.\n */\nexport const useDidTransition = <T>(\n currentValue: T,\n fromValue: T | ((value: T) => boolean),\n toValue: T | ((value: T) => boolean),\n) => {\n const [hasTransitioned, setHasTransitioned] = useState(false);\n const previousValue = useRef<T>(currentValue);\n\n useEffect(() => {\n const toValueValid = isFunction<T>(toValue) ? toValue(currentValue) : toValue === currentValue;\n\n const fromValueValid = isFunction<T>(fromValue)\n ? fromValue(previousValue.current)\n : fromValue === previousValue.current;\n\n const transitioned = fromValueValid && toValueValid;\n\n if (transitioned) {\n setHasTransitioned(true);\n } else {\n setHasTransitioned(false);\n }\n\n previousValue.current = currentValue;\n }, [currentValue, fromValue, toValue, setHasTransitioned, previousValue]);\n\n return hasTransitioned;\n};\n\n/**\n * Executes a callback function when a specified transition occurs in a value.\n *\n * This function utilizes the `useDidTransition` hook to monitor changes in `currentValue`.\n * When `currentValue` transitions from `fromValue` to `toValue`, the provided `callback` function is executed. */\nexport const useOnTransition = <T>(\n currentValue: T,\n fromValue: T | ((value: T) => boolean),\n toValue: ((value: T) => boolean) | T,\n callback: () => void,\n) => {\n const dirty = useRef(false);\n const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);\n\n useEffect(() => {\n dirty.current = false;\n }, [currentValue, dirty]);\n\n useEffect(() => {\n if (hasTransitioned && !dirty.current) {\n callback();\n dirty.current = true;\n }\n }, [hasTransitioned, dirty, callback]);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type RefCallback, useState } from 'react';\n\n/**\n * Custom React Hook that creates a ref callback and a state variable.\n * The ref callback sets the state variable when the ref changes.\n *\n * @returns An object containing the ref callback and the current value of the ref.\n */\nexport const useRefCallback = <T = any>(): { refCallback: RefCallback<T>; value: T | null } => {\n const [value, setValue] = useState<T | null>(null);\n return { refCallback: (value: T) => setValue(value), value };\n};\n"],
|
|
5
|
-
"mappings": ";AAIA,
|
|
6
|
-
"names": ["useEffect", "useState", "useControlledValue", "controlledValue", "value", "setValue", "useState", "useEffect", "useEffect", "useState", "useMemo", "useDefaultValue", "reactiveValue", "defaultValue", "stableDefaultValue", "useMemo", "value", "setValue", "useState", "useEffect", "useMemo", "useFileDownload", "useMemo", "data", "filename", "url", "URL", "createObjectURL", "element", "document", "createElement", "setAttribute", "click", "useRef", "useEffect", "useForwardedRef", "ref", "innerRef", "useRef", "useEffect", "current", "alea", "useMemo", "Alea", "alea", "prng", "randomString", "n", "toString", "slice", "useId", "namespace", "propsId", "opts", "useMemo", "useEffect", "useRef", "useState", "useIsFocused", "inputRef", "isFocused", "setIsFocused", "useState", "undefined", "isFocusedRef", "useRef", "current", "useEffect", "input", "onFocus", "onBlur", "addEventListener", "document", "activeElement", "removeEventListener", "useEffect", "useState", "breakpointMediaQueries", "sm", "md", "lg", "xl", "useMediaQuery", "query", "options", "ssr", "fallback", "queries", "Array", "isArray", "map", "fallbackValues", "filter", "v", "value", "setValue", "useState", "index", "media", "matches", "document", "defaultView", "matchMedia", "useEffect", "mql", "handler", "evt", "prev", "slice", "item", "forEach", "addListener", "addEventListener", "removeListener", "removeEventListener", "
|
|
3
|
+
"sources": ["../../../src/useAsyncCallback.ts", "../../../src/useControlledValue.ts", "../../../src/useDefaultValue.ts", "../../../src/useDynamicRef.ts", "../../../src/useFileDownload.ts", "../../../src/useForwardedRef.ts", "../../../src/useId.ts", "../../../src/useIsFocused.ts", "../../../src/useMediaQuery.ts", "../../../src/useRefCallback.ts", "../../../src/useTransitions.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nexport const useAsyncCallback = <T>(cb: () => Promise<T>): T | undefined => {\n const [value, setValue] = useState<T | undefined>();\n useEffect(() => {\n const t = setTimeout(async () => {\n const data = await cb();\n setValue(data);\n });\n\n return () => clearTimeout(t);\n }, []);\n\n return value;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Dispatch, type SetStateAction, useEffect, useState } from 'react';\n\n/**\n * A stateful hook with a controlled value.\n */\nexport const useControlledValue = <TValue>(controlledValue: TValue): [TValue, Dispatch<SetStateAction<TValue>>] => {\n const [value, setValue] = useState<TValue>(controlledValue);\n useEffect(() => {\n if (controlledValue !== undefined) {\n setValue(controlledValue);\n }\n }, [controlledValue]);\n\n return [value, setValue];\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState, useMemo } from 'react';\n\n/**\n * A custom React hook that provides a stable default value for a potentially undefined reactive value.\n * The defaultValue is memoized upon component mount and remains unchanged until the component unmounts,\n * ensuring stability across all re-renders, even if the defaultValue prop changes.\n *\n * Note: The defaultValue is not reactive. It retains the same value from the component's mount to unmount.\n *\n * @param reactiveValue - The value that may change over time.\n * @param defaultValue - The initial value used when the reactiveValue is undefined. This value is not reactive.\n * @returns - The reactiveValue if it's defined, otherwise the defaultValue.\n */\nexport const useDefaultValue = <T>(reactiveValue: T | undefined | null, defaultValue: T): T => {\n // Memoize defaultValue with an empty dependency array.\n // This ensures that the defaultValue instance remains stable across all re-renders,\n // regardless of whether the defaultValue changes.\n const stableDefaultValue = useMemo(() => defaultValue, []);\n const [value, setValue] = useState(reactiveValue ?? stableDefaultValue);\n\n useEffect(() => setValue(reactiveValue ?? stableDefaultValue), [reactiveValue, stableDefaultValue]);\n\n return value;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useRef } from 'react';\n\nexport const useDynamicRef = <T>(value: T) => {\n const ref = useRef<T>(value);\n useEffect(() => {\n ref.current = value;\n }, [value]);\n return ref;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\n/**\n * File download anchor.\n *\n * ```\n * const download = useDownload();\n * const handleDownload = (data: string) => {\n * download(new Blob([data], { type: 'text/plain' }), 'test.txt');\n * };\n * ```\n */\nexport const useFileDownload = (): ((data: Blob | string, filename: string) => void) => {\n return useMemo(\n () => (data: Blob | string, filename: string) => {\n const url = typeof data === 'string' ? data : URL.createObjectURL(data);\n const element = document.createElement('a');\n element.setAttribute('href', url);\n element.setAttribute('download', filename);\n element.setAttribute('target', 'download');\n element.click();\n },\n [],\n );\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type ForwardedRef, useRef, useEffect } from 'react';\n\nexport const useForwardedRef = <T>(ref: ForwardedRef<T>) => {\n const innerRef = useRef<T>(null);\n\n useEffect(() => {\n if (!ref) {\n return;\n }\n\n if (typeof ref === 'function') {\n ref(innerRef.current);\n } else {\n ref.current = innerRef.current;\n }\n });\n\n return innerRef;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport alea from 'alea';\nimport { useMemo } from 'react';\n\ninterface PrngFactory {\n new (seed?: string): () => number;\n}\n\nconst Alea: PrngFactory = alea as unknown as PrngFactory;\n\nconst prng = new Alea('@dxos/react-hooks');\n\n// TODO(burdon): Replace with PublicKey.random().\nexport const randomString = (n = 4) =>\n prng()\n .toString(16)\n .slice(2, n + 2);\n\nexport const useId = (namespace: string, propsId?: string, opts?: Partial<{ n: number }>) =>\n useMemo(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [propsId]);\n", "//\n// Copyright 2022 DXOS.org\n//\n\n// Based upon the useIsFocused hook which is part of the `rci` project:\n/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused\n\nimport { useEffect, useRef, useState, type RefObject } from 'react';\n\nexport const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {\n const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);\n const isFocusedRef = useRef<boolean | undefined>(isFocused);\n\n isFocusedRef.current = isFocused;\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const onFocus = () => setIsFocused(true);\n const onBlur = () => setIsFocused(false);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n\n if (isFocusedRef.current === undefined) {\n setIsFocused(document.activeElement === input);\n }\n\n return () => {\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n };\n }, [inputRef, setIsFocused]);\n\n return isFocused;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// This hook is based on Chakra UI’s `useMediaQuery`: https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/media-query/src/use-media-query.ts\n\nimport { useEffect, useState } from 'react';\n\nexport type UseMediaQueryOptions = {\n fallback?: boolean | boolean[];\n ssr?: boolean;\n};\n\n// TODO(thure): This should be derived from the same source of truth as the Tailwind theme config\nconst breakpointMediaQueries: Record<string, string> = {\n sm: '(min-width: 640px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 1024px)',\n xl: '(min-width: 1280px)',\n '2xl': '(min-width: 1536px)',\n};\n\n/**\n * React hook that tracks state of a CSS media query\n *\n * @param query the media query to match, or a recognized breakpoint token\n * @param options the media query options { fallback, ssr }\n *\n * @see Docs https://chakra-ui.com/docs/hooks/use-media-query\n */\nexport const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {\n const { ssr = true, fallback } = options;\n\n const queries = (Array.isArray(query) ? query : [query]).map((query) =>\n query in breakpointMediaQueries ? breakpointMediaQueries[query] : query,\n );\n\n let fallbackValues = Array.isArray(fallback) ? fallback : [fallback];\n fallbackValues = fallbackValues.filter((v) => v != null) as boolean[];\n\n const [value, setValue] = useState(() => {\n return queries.map((query, index) => ({\n media: query,\n matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query).matches,\n }));\n });\n\n useEffect(() => {\n setValue(\n queries.map((query) => ({\n media: query,\n matches: document.defaultView?.matchMedia(query).matches,\n })),\n );\n\n const mql = queries.map((query) => document.defaultView?.matchMedia(query));\n\n const handler = (evt: MediaQueryListEvent) => {\n setValue((prev) => {\n return prev.slice().map((item) => {\n if (item.media === evt.media) {\n return { ...item, matches: evt.matches };\n }\n return item;\n });\n });\n };\n\n mql.forEach((mql) => {\n if (typeof mql?.addListener === 'function') {\n mql?.addListener(handler);\n } else {\n mql?.addEventListener('change', handler);\n }\n });\n\n return () => {\n mql.forEach((mql) => {\n if (typeof mql?.removeListener === 'function') {\n mql?.removeListener(handler);\n } else {\n mql?.removeEventListener('change', handler);\n }\n });\n };\n }, [document.defaultView]);\n\n return value.map((item) => !!item.matches);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type RefCallback, useState } from 'react';\n\n/**\n * Custom React Hook that creates a ref callback and a state variable.\n * The ref callback sets the state variable when the ref changes.\n *\n * @returns An object containing the ref callback and the current value of the ref.\n */\nexport const useRefCallback = <T = any>(): { refCallback: RefCallback<T>; value: T | null } => {\n const [value, setValue] = useState<T | null>(null);\n return { refCallback: (value: T) => setValue(value), value };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useRef, useEffect, useState } from 'react';\n\nconst isFunction = <T>(functionToCheck: any): functionToCheck is (value: T) => boolean => {\n return functionToCheck instanceof Function;\n};\n\n/**\n * This is an internal custom hook that checks if a value has transitioned from a specified 'from' value to a 'to' value.\n *\n * @param currentValue - The value that is being monitored for transitions.\n * @param fromValue - The *from* value or a predicate function that determines the start of the transition.\n * @param toValue - The *to* value or a predicate function that determines the end of the transition.\n * @returns A boolean indicating whether the transition from *fromValue* to *toValue* has occurred.\n *\n * @internal Consider using `useOnTransition` for handling transitions instead of this hook.\n */\nexport const useDidTransition = <T>(\n currentValue: T,\n fromValue: T | ((value: T) => boolean),\n toValue: T | ((value: T) => boolean),\n) => {\n const [hasTransitioned, setHasTransitioned] = useState(false);\n const previousValue = useRef<T>(currentValue);\n\n useEffect(() => {\n const toValueValid = isFunction<T>(toValue) ? toValue(currentValue) : toValue === currentValue;\n\n const fromValueValid = isFunction<T>(fromValue)\n ? fromValue(previousValue.current)\n : fromValue === previousValue.current;\n\n const transitioned = fromValueValid && toValueValid;\n\n if (transitioned) {\n setHasTransitioned(true);\n } else {\n setHasTransitioned(false);\n }\n\n previousValue.current = currentValue;\n }, [currentValue, fromValue, toValue, setHasTransitioned, previousValue]);\n\n return hasTransitioned;\n};\n\n/**\n * Executes a callback function when a specified transition occurs in a value.\n *\n * This function utilizes the `useDidTransition` hook to monitor changes in `currentValue`.\n * When `currentValue` transitions from `fromValue` to `toValue`, the provided `callback` function is executed. */\nexport const useOnTransition = <T>(\n currentValue: T,\n fromValue: T | ((value: T) => boolean),\n toValue: ((value: T) => boolean) | T,\n callback: () => void,\n) => {\n const dirty = useRef(false);\n const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);\n\n useEffect(() => {\n dirty.current = false;\n }, [currentValue, dirty]);\n\n useEffect(() => {\n if (hasTransitioned && !dirty.current) {\n callback();\n dirty.current = true;\n }\n }, [hasTransitioned, dirty, callback]);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["useEffect", "useState", "useAsyncCallback", "cb", "value", "setValue", "useState", "useEffect", "t", "setTimeout", "data", "clearTimeout", "useEffect", "useState", "useControlledValue", "controlledValue", "value", "setValue", "useState", "useEffect", "undefined", "useEffect", "useState", "useMemo", "useDefaultValue", "reactiveValue", "defaultValue", "stableDefaultValue", "useMemo", "value", "setValue", "useState", "useEffect", "useEffect", "useRef", "useDynamicRef", "value", "ref", "useRef", "useEffect", "current", "useMemo", "useFileDownload", "useMemo", "data", "filename", "url", "URL", "createObjectURL", "element", "document", "createElement", "setAttribute", "click", "useRef", "useEffect", "useForwardedRef", "ref", "innerRef", "useRef", "useEffect", "current", "alea", "useMemo", "Alea", "alea", "prng", "randomString", "n", "toString", "slice", "useId", "namespace", "propsId", "opts", "useMemo", "useEffect", "useRef", "useState", "useIsFocused", "inputRef", "isFocused", "setIsFocused", "useState", "undefined", "isFocusedRef", "useRef", "current", "useEffect", "input", "onFocus", "onBlur", "addEventListener", "document", "activeElement", "removeEventListener", "useEffect", "useState", "breakpointMediaQueries", "sm", "md", "lg", "xl", "useMediaQuery", "query", "options", "ssr", "fallback", "queries", "Array", "isArray", "map", "fallbackValues", "filter", "v", "value", "setValue", "useState", "index", "media", "matches", "document", "defaultView", "matchMedia", "useEffect", "mql", "handler", "evt", "prev", "slice", "item", "forEach", "addListener", "addEventListener", "removeListener", "removeEventListener", "useState", "useRefCallback", "value", "setValue", "useState", "refCallback", "useRef", "useEffect", "useState", "isFunction", "functionToCheck", "Function", "useDidTransition", "currentValue", "fromValue", "toValue", "hasTransitioned", "setHasTransitioned", "useState", "previousValue", "useRef", "useEffect", "toValueValid", "fromValueValid", "current", "transitioned", "useOnTransition", "callback", "dirty"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/primitives/react-hooks/src/useControlledValue.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/primitives/react-hooks/src/useAsyncCallback.ts":{"bytes":1751,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useControlledValue.ts":{"bytes":1974,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useDefaultValue.ts":{"bytes":4059,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useDynamicRef.ts":{"bytes":1247,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useFileDownload.ts":{"bytes":2740,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytes":1783,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytes":2163,"imports":[{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytes":3990,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytes":9390,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useRefCallback.ts":{"bytes":1879,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useTransitions.ts":{"bytes":7797,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/index.ts":{"bytes":1572,"imports":[{"path":"packages/ui/primitives/react-hooks/src/useAsyncCallback.ts","kind":"import-statement","original":"./useAsyncCallback"},{"path":"packages/ui/primitives/react-hooks/src/useControlledValue.ts","kind":"import-statement","original":"./useControlledValue"},{"path":"packages/ui/primitives/react-hooks/src/useDefaultValue.ts","kind":"import-statement","original":"./useDefaultValue"},{"path":"packages/ui/primitives/react-hooks/src/useDynamicRef.ts","kind":"import-statement","original":"./useDynamicRef"},{"path":"packages/ui/primitives/react-hooks/src/useFileDownload.ts","kind":"import-statement","original":"./useFileDownload"},{"path":"packages/ui/primitives/react-hooks/src/useForwardedRef.ts","kind":"import-statement","original":"./useForwardedRef"},{"path":"packages/ui/primitives/react-hooks/src/useId.ts","kind":"import-statement","original":"./useId"},{"path":"packages/ui/primitives/react-hooks/src/useIsFocused.ts","kind":"import-statement","original":"./useIsFocused"},{"path":"packages/ui/primitives/react-hooks/src/useMediaQuery.ts","kind":"import-statement","original":"./useMediaQuery"},{"path":"packages/ui/primitives/react-hooks/src/useRefCallback.ts","kind":"import-statement","original":"./useRefCallback"},{"path":"packages/ui/primitives/react-hooks/src/useTransitions.ts","kind":"import-statement","original":"./useTransitions"}],"format":"esm"}},"outputs":{"packages/ui/primitives/react-hooks/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18788},"packages/ui/primitives/react-hooks/dist/lib/browser/index.mjs":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["randomString","useAsyncCallback","useControlledValue","useDefaultValue","useDidTransition","useDynamicRef","useFileDownload","useForwardedRef","useId","useIsFocused","useMediaQuery","useOnTransition","useRefCallback"],"entryPoint":"packages/ui/primitives/react-hooks/src/index.ts","inputs":{"packages/ui/primitives/react-hooks/src/useAsyncCallback.ts":{"bytesInOutput":301},"packages/ui/primitives/react-hooks/src/index.ts":{"bytesInOutput":0},"packages/ui/primitives/react-hooks/src/useControlledValue.ts":{"bytesInOutput":350},"packages/ui/primitives/react-hooks/src/useDefaultValue.ts":{"bytesInOutput":411},"packages/ui/primitives/react-hooks/src/useDynamicRef.ts":{"bytesInOutput":205},"packages/ui/primitives/react-hooks/src/useFileDownload.ts":{"bytesInOutput":416},"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytesInOutput":343},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytesInOutput":326},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytesInOutput":833},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytesInOutput":1940},"packages/ui/primitives/react-hooks/src/useRefCallback.ts":{"bytesInOutput":197},"packages/ui/primitives/react-hooks/src/useTransitions.ts":{"bytesInOutput":1384}},"bytes":7649}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -29,9 +29,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var node_exports = {};
|
|
30
30
|
__export(node_exports, {
|
|
31
31
|
randomString: () => randomString,
|
|
32
|
+
useAsyncCallback: () => useAsyncCallback,
|
|
32
33
|
useControlledValue: () => useControlledValue,
|
|
33
34
|
useDefaultValue: () => useDefaultValue,
|
|
34
35
|
useDidTransition: () => useDidTransition,
|
|
36
|
+
useDynamicRef: () => useDynamicRef,
|
|
35
37
|
useFileDownload: () => useFileDownload,
|
|
36
38
|
useForwardedRef: () => useForwardedRef,
|
|
37
39
|
useId: () => useId,
|
|
@@ -45,16 +47,31 @@ var import_react = require("react");
|
|
|
45
47
|
var import_react2 = require("react");
|
|
46
48
|
var import_react3 = require("react");
|
|
47
49
|
var import_react4 = require("react");
|
|
48
|
-
var import_alea = __toESM(require("alea"));
|
|
49
50
|
var import_react5 = require("react");
|
|
50
51
|
var import_react6 = require("react");
|
|
52
|
+
var import_alea = __toESM(require("alea"));
|
|
51
53
|
var import_react7 = require("react");
|
|
52
54
|
var import_react8 = require("react");
|
|
53
55
|
var import_react9 = require("react");
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
+
var import_react10 = require("react");
|
|
57
|
+
var import_react11 = require("react");
|
|
58
|
+
var useAsyncCallback = (cb) => {
|
|
59
|
+
const [value, setValue] = (0, import_react.useState)();
|
|
56
60
|
(0, import_react.useEffect)(() => {
|
|
57
|
-
|
|
61
|
+
const t = setTimeout(async () => {
|
|
62
|
+
const data = await cb();
|
|
63
|
+
setValue(data);
|
|
64
|
+
});
|
|
65
|
+
return () => clearTimeout(t);
|
|
66
|
+
}, []);
|
|
67
|
+
return value;
|
|
68
|
+
};
|
|
69
|
+
var useControlledValue = (controlledValue) => {
|
|
70
|
+
const [value, setValue] = (0, import_react2.useState)(controlledValue);
|
|
71
|
+
(0, import_react2.useEffect)(() => {
|
|
72
|
+
if (controlledValue !== void 0) {
|
|
73
|
+
setValue(controlledValue);
|
|
74
|
+
}
|
|
58
75
|
}, [
|
|
59
76
|
controlledValue
|
|
60
77
|
]);
|
|
@@ -64,16 +81,25 @@ var useControlledValue = (controlledValue) => {
|
|
|
64
81
|
];
|
|
65
82
|
};
|
|
66
83
|
var useDefaultValue = (reactiveValue, defaultValue) => {
|
|
67
|
-
const stableDefaultValue = (0,
|
|
68
|
-
const [value, setValue] = (0,
|
|
69
|
-
(0,
|
|
84
|
+
const stableDefaultValue = (0, import_react3.useMemo)(() => defaultValue, []);
|
|
85
|
+
const [value, setValue] = (0, import_react3.useState)(reactiveValue ?? stableDefaultValue);
|
|
86
|
+
(0, import_react3.useEffect)(() => setValue(reactiveValue ?? stableDefaultValue), [
|
|
70
87
|
reactiveValue,
|
|
71
88
|
stableDefaultValue
|
|
72
89
|
]);
|
|
73
90
|
return value;
|
|
74
91
|
};
|
|
92
|
+
var useDynamicRef = (value) => {
|
|
93
|
+
const ref = (0, import_react4.useRef)(value);
|
|
94
|
+
(0, import_react4.useEffect)(() => {
|
|
95
|
+
ref.current = value;
|
|
96
|
+
}, [
|
|
97
|
+
value
|
|
98
|
+
]);
|
|
99
|
+
return ref;
|
|
100
|
+
};
|
|
75
101
|
var useFileDownload = () => {
|
|
76
|
-
return (0,
|
|
102
|
+
return (0, import_react5.useMemo)(() => (data, filename) => {
|
|
77
103
|
const url = typeof data === "string" ? data : URL.createObjectURL(data);
|
|
78
104
|
const element = document.createElement("a");
|
|
79
105
|
element.setAttribute("href", url);
|
|
@@ -83,8 +109,8 @@ var useFileDownload = () => {
|
|
|
83
109
|
}, []);
|
|
84
110
|
};
|
|
85
111
|
var useForwardedRef = (ref) => {
|
|
86
|
-
const innerRef = (0,
|
|
87
|
-
(0,
|
|
112
|
+
const innerRef = (0, import_react6.useRef)(null);
|
|
113
|
+
(0, import_react6.useEffect)(() => {
|
|
88
114
|
if (!ref) {
|
|
89
115
|
return;
|
|
90
116
|
}
|
|
@@ -99,14 +125,14 @@ var useForwardedRef = (ref) => {
|
|
|
99
125
|
var Alea = import_alea.default;
|
|
100
126
|
var prng = new Alea("@dxos/react-hooks");
|
|
101
127
|
var randomString = (n = 4) => prng().toString(16).slice(2, n + 2);
|
|
102
|
-
var useId = (namespace, propsId, opts) => (0,
|
|
128
|
+
var useId = (namespace, propsId, opts) => (0, import_react7.useMemo)(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [
|
|
103
129
|
propsId
|
|
104
130
|
]);
|
|
105
131
|
var useIsFocused = (inputRef) => {
|
|
106
|
-
const [isFocused, setIsFocused] = (0,
|
|
107
|
-
const isFocusedRef = (0,
|
|
132
|
+
const [isFocused, setIsFocused] = (0, import_react8.useState)(void 0);
|
|
133
|
+
const isFocusedRef = (0, import_react8.useRef)(isFocused);
|
|
108
134
|
isFocusedRef.current = isFocused;
|
|
109
|
-
(0,
|
|
135
|
+
(0, import_react8.useEffect)(() => {
|
|
110
136
|
const input = inputRef.current;
|
|
111
137
|
if (!input) {
|
|
112
138
|
return;
|
|
@@ -144,13 +170,13 @@ var useMediaQuery = (query, options = {}) => {
|
|
|
144
170
|
fallback
|
|
145
171
|
];
|
|
146
172
|
fallbackValues = fallbackValues.filter((v) => v != null);
|
|
147
|
-
const [value, setValue] = (0,
|
|
173
|
+
const [value, setValue] = (0, import_react9.useState)(() => {
|
|
148
174
|
return queries.map((query2, index) => ({
|
|
149
175
|
media: query2,
|
|
150
176
|
matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query2).matches
|
|
151
177
|
}));
|
|
152
178
|
});
|
|
153
|
-
(0,
|
|
179
|
+
(0, import_react9.useEffect)(() => {
|
|
154
180
|
setValue(queries.map((query2) => ({
|
|
155
181
|
media: query2,
|
|
156
182
|
matches: document.defaultView?.matchMedia(query2).matches
|
|
@@ -190,13 +216,20 @@ var useMediaQuery = (query, options = {}) => {
|
|
|
190
216
|
]);
|
|
191
217
|
return value.map((item) => !!item.matches);
|
|
192
218
|
};
|
|
219
|
+
var useRefCallback = () => {
|
|
220
|
+
const [value, setValue] = (0, import_react10.useState)(null);
|
|
221
|
+
return {
|
|
222
|
+
refCallback: (value2) => setValue(value2),
|
|
223
|
+
value
|
|
224
|
+
};
|
|
225
|
+
};
|
|
193
226
|
var isFunction = (functionToCheck) => {
|
|
194
227
|
return functionToCheck instanceof Function;
|
|
195
228
|
};
|
|
196
229
|
var useDidTransition = (currentValue, fromValue, toValue) => {
|
|
197
|
-
const [hasTransitioned, setHasTransitioned] = (0,
|
|
198
|
-
const previousValue = (0,
|
|
199
|
-
(0,
|
|
230
|
+
const [hasTransitioned, setHasTransitioned] = (0, import_react11.useState)(false);
|
|
231
|
+
const previousValue = (0, import_react11.useRef)(currentValue);
|
|
232
|
+
(0, import_react11.useEffect)(() => {
|
|
200
233
|
const toValueValid = isFunction(toValue) ? toValue(currentValue) : toValue === currentValue;
|
|
201
234
|
const fromValueValid = isFunction(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
|
|
202
235
|
const transitioned = fromValueValid && toValueValid;
|
|
@@ -216,15 +249,15 @@ var useDidTransition = (currentValue, fromValue, toValue) => {
|
|
|
216
249
|
return hasTransitioned;
|
|
217
250
|
};
|
|
218
251
|
var useOnTransition = (currentValue, fromValue, toValue, callback) => {
|
|
219
|
-
const dirty = (0,
|
|
252
|
+
const dirty = (0, import_react11.useRef)(false);
|
|
220
253
|
const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);
|
|
221
|
-
(0,
|
|
254
|
+
(0, import_react11.useEffect)(() => {
|
|
222
255
|
dirty.current = false;
|
|
223
256
|
}, [
|
|
224
257
|
currentValue,
|
|
225
258
|
dirty
|
|
226
259
|
]);
|
|
227
|
-
(0,
|
|
260
|
+
(0, import_react11.useEffect)(() => {
|
|
228
261
|
if (hasTransitioned && !dirty.current) {
|
|
229
262
|
callback();
|
|
230
263
|
dirty.current = true;
|
|
@@ -235,19 +268,14 @@ var useOnTransition = (currentValue, fromValue, toValue, callback) => {
|
|
|
235
268
|
callback
|
|
236
269
|
]);
|
|
237
270
|
};
|
|
238
|
-
var useRefCallback = () => {
|
|
239
|
-
const [value, setValue] = (0, import_react9.useState)(null);
|
|
240
|
-
return {
|
|
241
|
-
refCallback: (value2) => setValue(value2),
|
|
242
|
-
value
|
|
243
|
-
};
|
|
244
|
-
};
|
|
245
271
|
// Annotate the CommonJS export names for ESM import in node:
|
|
246
272
|
0 && (module.exports = {
|
|
247
273
|
randomString,
|
|
274
|
+
useAsyncCallback,
|
|
248
275
|
useControlledValue,
|
|
249
276
|
useDefaultValue,
|
|
250
277
|
useDidTransition,
|
|
278
|
+
useDynamicRef,
|
|
251
279
|
useFileDownload,
|
|
252
280
|
useForwardedRef,
|
|
253
281
|
useId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/useControlledValue.ts", "../../../src/useDefaultValue.ts", "../../../src/useFileDownload.ts", "../../../src/useForwardedRef.ts", "../../../src/useId.ts", "../../../src/useIsFocused.ts", "../../../src/useMediaQuery.ts", "../../../src/
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Dispatch, type SetStateAction, useEffect, useState } from 'react';\n\n/**\n * A stateful hook with a controlled value.\n */\nexport const useControlledValue = <TValue>(controlledValue: TValue): [TValue, Dispatch<SetStateAction<TValue>>] => {\n const [value, setValue] = useState<TValue>(controlledValue);\n useEffect(() => {\n setValue(controlledValue);\n }, [controlledValue]);\n\n return [value, setValue];\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState, useMemo } from 'react';\n\n/**\n * A custom React hook that provides a stable default value for a potentially undefined reactive value.\n * The defaultValue is memoized upon component mount and remains unchanged until the component unmounts,\n * ensuring stability across all re-renders, even if the defaultValue prop changes.\n *\n * Note: The defaultValue is not reactive. It retains the same value from the component's mount to unmount.\n *\n * @param reactiveValue - The value that may change over time.\n * @param defaultValue - The initial value used when the reactiveValue is undefined. This value is not reactive.\n * @returns - The reactiveValue if it's defined, otherwise the defaultValue.\n */\nexport const useDefaultValue = <T>(reactiveValue: T | undefined | null, defaultValue: T): T => {\n // Memoize defaultValue with an empty dependency array.\n // This ensures that the defaultValue instance remains stable across all re-renders,\n // regardless of whether the defaultValue changes.\n const stableDefaultValue = useMemo(() => defaultValue, []);\n const [value, setValue] = useState(reactiveValue ?? stableDefaultValue);\n\n useEffect(() => setValue(reactiveValue ?? stableDefaultValue), [reactiveValue, stableDefaultValue]);\n\n return value;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\n/**\n * File download anchor.\n *\n * ```\n * const download = useDownload();\n * const handleDownload = (data: string) => {\n * download(new Blob([data], { type: 'text/plain' }), 'test.txt');\n * };\n * ```\n */\nexport const useFileDownload = (): ((data: Blob | string, filename: string) => void) => {\n return useMemo(\n () => (data: Blob | string, filename: string) => {\n const url = typeof data === 'string' ? data : URL.createObjectURL(data);\n const element = document.createElement('a');\n element.setAttribute('href', url);\n element.setAttribute('download', filename);\n element.setAttribute('target', 'download');\n element.click();\n },\n [],\n );\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type ForwardedRef, useRef, useEffect } from 'react';\n\nexport const useForwardedRef = <T>(ref: ForwardedRef<T>) => {\n const innerRef = useRef<T>(null);\n\n useEffect(() => {\n if (!ref) {\n return;\n }\n\n if (typeof ref === 'function') {\n ref(innerRef.current);\n } else {\n ref.current = innerRef.current;\n }\n });\n\n return innerRef;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport alea from 'alea';\nimport { useMemo } from 'react';\n\ninterface PrngFactory {\n new (seed?: string): () => number;\n}\n\nconst Alea: PrngFactory = alea as unknown as PrngFactory;\n\nconst prng = new Alea('@dxos/react-hooks');\n\n// TODO(burdon): Replace with PublicKey.random().\nexport const randomString = (n = 4) =>\n prng()\n .toString(16)\n .slice(2, n + 2);\n\nexport const useId = (namespace: string, propsId?: string, opts?: Partial<{ n: number }>) =>\n useMemo(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [propsId]);\n", "//\n// Copyright 2022 DXOS.org\n//\n\n// Based upon the useIsFocused hook which is part of the `rci` project:\n/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused\n\nimport { useEffect, useRef, useState, type RefObject } from 'react';\n\nexport const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {\n const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);\n const isFocusedRef = useRef<boolean | undefined>(isFocused);\n\n isFocusedRef.current = isFocused;\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const onFocus = () => setIsFocused(true);\n const onBlur = () => setIsFocused(false);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n\n if (isFocusedRef.current === undefined) {\n setIsFocused(document.activeElement === input);\n }\n\n return () => {\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n };\n }, [inputRef, setIsFocused]);\n\n return isFocused;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// This hook is based on Chakra UI’s `useMediaQuery`: https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/media-query/src/use-media-query.ts\n\nimport { useEffect, useState } from 'react';\n\nexport type UseMediaQueryOptions = {\n fallback?: boolean | boolean[];\n ssr?: boolean;\n};\n\n// TODO(thure): This should be derived from the same source of truth as the Tailwind theme config\nconst breakpointMediaQueries: Record<string, string> = {\n sm: '(min-width: 640px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 1024px)',\n xl: '(min-width: 1280px)',\n '2xl': '(min-width: 1536px)',\n};\n\n/**\n * React hook that tracks state of a CSS media query\n *\n * @param query the media query to match, or a recognized breakpoint token\n * @param options the media query options { fallback, ssr }\n *\n * @see Docs https://chakra-ui.com/docs/hooks/use-media-query\n */\nexport const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {\n const { ssr = true, fallback } = options;\n\n const queries = (Array.isArray(query) ? query : [query]).map((query) =>\n query in breakpointMediaQueries ? breakpointMediaQueries[query] : query,\n );\n\n let fallbackValues = Array.isArray(fallback) ? fallback : [fallback];\n fallbackValues = fallbackValues.filter((v) => v != null) as boolean[];\n\n const [value, setValue] = useState(() => {\n return queries.map((query, index) => ({\n media: query,\n matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query).matches,\n }));\n });\n\n useEffect(() => {\n setValue(\n queries.map((query) => ({\n media: query,\n matches: document.defaultView?.matchMedia(query).matches,\n })),\n );\n\n const mql = queries.map((query) => document.defaultView?.matchMedia(query));\n\n const handler = (evt: MediaQueryListEvent) => {\n setValue((prev) => {\n return prev.slice().map((item) => {\n if (item.media === evt.media) {\n return { ...item, matches: evt.matches };\n }\n return item;\n });\n });\n };\n\n mql.forEach((mql) => {\n if (typeof mql?.addListener === 'function') {\n mql?.addListener(handler);\n } else {\n mql?.addEventListener('change', handler);\n }\n });\n\n return () => {\n mql.forEach((mql) => {\n if (typeof mql?.removeListener === 'function') {\n mql?.removeListener(handler);\n } else {\n mql?.removeEventListener('change', handler);\n }\n });\n };\n }, [document.defaultView]);\n\n return value.map((item) => !!item.matches);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useRef, useEffect, useState } from 'react';\n\nconst isFunction = <T>(functionToCheck: any): functionToCheck is (value: T) => boolean => {\n return functionToCheck instanceof Function;\n};\n\n/**\n * This is an internal custom hook that checks if a value has transitioned from a specified 'from' value to a 'to' value.\n *\n * @param currentValue - The value that is being monitored for transitions.\n * @param fromValue - The *from* value or a predicate function that determines the start of the transition.\n * @param toValue - The *to* value or a predicate function that determines the end of the transition.\n * @returns A boolean indicating whether the transition from *fromValue* to *toValue* has occurred.\n *\n * @internal Consider using `useOnTransition` for handling transitions instead of this hook.\n */\nexport const useDidTransition = <T>(\n currentValue: T,\n fromValue: T | ((value: T) => boolean),\n toValue: T | ((value: T) => boolean),\n) => {\n const [hasTransitioned, setHasTransitioned] = useState(false);\n const previousValue = useRef<T>(currentValue);\n\n useEffect(() => {\n const toValueValid = isFunction<T>(toValue) ? toValue(currentValue) : toValue === currentValue;\n\n const fromValueValid = isFunction<T>(fromValue)\n ? fromValue(previousValue.current)\n : fromValue === previousValue.current;\n\n const transitioned = fromValueValid && toValueValid;\n\n if (transitioned) {\n setHasTransitioned(true);\n } else {\n setHasTransitioned(false);\n }\n\n previousValue.current = currentValue;\n }, [currentValue, fromValue, toValue, setHasTransitioned, previousValue]);\n\n return hasTransitioned;\n};\n\n/**\n * Executes a callback function when a specified transition occurs in a value.\n *\n * This function utilizes the `useDidTransition` hook to monitor changes in `currentValue`.\n * When `currentValue` transitions from `fromValue` to `toValue`, the provided `callback` function is executed. */\nexport const useOnTransition = <T>(\n currentValue: T,\n fromValue: T | ((value: T) => boolean),\n toValue: ((value: T) => boolean) | T,\n callback: () => void,\n) => {\n const dirty = useRef(false);\n const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);\n\n useEffect(() => {\n dirty.current = false;\n }, [currentValue, dirty]);\n\n useEffect(() => {\n if (hasTransitioned && !dirty.current) {\n callback();\n dirty.current = true;\n }\n }, [hasTransitioned, dirty, callback]);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type RefCallback, useState } from 'react';\n\n/**\n * Custom React Hook that creates a ref callback and a state variable.\n * The ref callback sets the state variable when the ref changes.\n *\n * @returns An object containing the ref callback and the current value of the ref.\n */\nexport const useRefCallback = <T = any>(): { refCallback: RefCallback<T>; value: T | null } => {\n const [value, setValue] = useState<T | null>(null);\n return { refCallback: (value: T) => setValue(value), value };\n};\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": ["import_react", "
|
|
3
|
+
"sources": ["../../../src/useAsyncCallback.ts", "../../../src/useControlledValue.ts", "../../../src/useDefaultValue.ts", "../../../src/useDynamicRef.ts", "../../../src/useFileDownload.ts", "../../../src/useForwardedRef.ts", "../../../src/useId.ts", "../../../src/useIsFocused.ts", "../../../src/useMediaQuery.ts", "../../../src/useRefCallback.ts", "../../../src/useTransitions.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nexport const useAsyncCallback = <T>(cb: () => Promise<T>): T | undefined => {\n const [value, setValue] = useState<T | undefined>();\n useEffect(() => {\n const t = setTimeout(async () => {\n const data = await cb();\n setValue(data);\n });\n\n return () => clearTimeout(t);\n }, []);\n\n return value;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Dispatch, type SetStateAction, useEffect, useState } from 'react';\n\n/**\n * A stateful hook with a controlled value.\n */\nexport const useControlledValue = <TValue>(controlledValue: TValue): [TValue, Dispatch<SetStateAction<TValue>>] => {\n const [value, setValue] = useState<TValue>(controlledValue);\n useEffect(() => {\n if (controlledValue !== undefined) {\n setValue(controlledValue);\n }\n }, [controlledValue]);\n\n return [value, setValue];\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState, useMemo } from 'react';\n\n/**\n * A custom React hook that provides a stable default value for a potentially undefined reactive value.\n * The defaultValue is memoized upon component mount and remains unchanged until the component unmounts,\n * ensuring stability across all re-renders, even if the defaultValue prop changes.\n *\n * Note: The defaultValue is not reactive. It retains the same value from the component's mount to unmount.\n *\n * @param reactiveValue - The value that may change over time.\n * @param defaultValue - The initial value used when the reactiveValue is undefined. This value is not reactive.\n * @returns - The reactiveValue if it's defined, otherwise the defaultValue.\n */\nexport const useDefaultValue = <T>(reactiveValue: T | undefined | null, defaultValue: T): T => {\n // Memoize defaultValue with an empty dependency array.\n // This ensures that the defaultValue instance remains stable across all re-renders,\n // regardless of whether the defaultValue changes.\n const stableDefaultValue = useMemo(() => defaultValue, []);\n const [value, setValue] = useState(reactiveValue ?? stableDefaultValue);\n\n useEffect(() => setValue(reactiveValue ?? stableDefaultValue), [reactiveValue, stableDefaultValue]);\n\n return value;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useRef } from 'react';\n\nexport const useDynamicRef = <T>(value: T) => {\n const ref = useRef<T>(value);\n useEffect(() => {\n ref.current = value;\n }, [value]);\n return ref;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { useMemo } from 'react';\n\n/**\n * File download anchor.\n *\n * ```\n * const download = useDownload();\n * const handleDownload = (data: string) => {\n * download(new Blob([data], { type: 'text/plain' }), 'test.txt');\n * };\n * ```\n */\nexport const useFileDownload = (): ((data: Blob | string, filename: string) => void) => {\n return useMemo(\n () => (data: Blob | string, filename: string) => {\n const url = typeof data === 'string' ? data : URL.createObjectURL(data);\n const element = document.createElement('a');\n element.setAttribute('href', url);\n element.setAttribute('download', filename);\n element.setAttribute('target', 'download');\n element.click();\n },\n [],\n );\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { type ForwardedRef, useRef, useEffect } from 'react';\n\nexport const useForwardedRef = <T>(ref: ForwardedRef<T>) => {\n const innerRef = useRef<T>(null);\n\n useEffect(() => {\n if (!ref) {\n return;\n }\n\n if (typeof ref === 'function') {\n ref(innerRef.current);\n } else {\n ref.current = innerRef.current;\n }\n });\n\n return innerRef;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport alea from 'alea';\nimport { useMemo } from 'react';\n\ninterface PrngFactory {\n new (seed?: string): () => number;\n}\n\nconst Alea: PrngFactory = alea as unknown as PrngFactory;\n\nconst prng = new Alea('@dxos/react-hooks');\n\n// TODO(burdon): Replace with PublicKey.random().\nexport const randomString = (n = 4) =>\n prng()\n .toString(16)\n .slice(2, n + 2);\n\nexport const useId = (namespace: string, propsId?: string, opts?: Partial<{ n: number }>) =>\n useMemo(() => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`, [propsId]);\n", "//\n// Copyright 2022 DXOS.org\n//\n\n// Based upon the useIsFocused hook which is part of the `rci` project:\n/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused\n\nimport { useEffect, useRef, useState, type RefObject } from 'react';\n\nexport const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {\n const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);\n const isFocusedRef = useRef<boolean | undefined>(isFocused);\n\n isFocusedRef.current = isFocused;\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) {\n return;\n }\n\n const onFocus = () => setIsFocused(true);\n const onBlur = () => setIsFocused(false);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n\n if (isFocusedRef.current === undefined) {\n setIsFocused(document.activeElement === input);\n }\n\n return () => {\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n };\n }, [inputRef, setIsFocused]);\n\n return isFocused;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// This hook is based on Chakra UI’s `useMediaQuery`: https://github.com/chakra-ui/chakra-ui/blob/main/packages/components/media-query/src/use-media-query.ts\n\nimport { useEffect, useState } from 'react';\n\nexport type UseMediaQueryOptions = {\n fallback?: boolean | boolean[];\n ssr?: boolean;\n};\n\n// TODO(thure): This should be derived from the same source of truth as the Tailwind theme config\nconst breakpointMediaQueries: Record<string, string> = {\n sm: '(min-width: 640px)',\n md: '(min-width: 768px)',\n lg: '(min-width: 1024px)',\n xl: '(min-width: 1280px)',\n '2xl': '(min-width: 1536px)',\n};\n\n/**\n * React hook that tracks state of a CSS media query\n *\n * @param query the media query to match, or a recognized breakpoint token\n * @param options the media query options { fallback, ssr }\n *\n * @see Docs https://chakra-ui.com/docs/hooks/use-media-query\n */\nexport const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {\n const { ssr = true, fallback } = options;\n\n const queries = (Array.isArray(query) ? query : [query]).map((query) =>\n query in breakpointMediaQueries ? breakpointMediaQueries[query] : query,\n );\n\n let fallbackValues = Array.isArray(fallback) ? fallback : [fallback];\n fallbackValues = fallbackValues.filter((v) => v != null) as boolean[];\n\n const [value, setValue] = useState(() => {\n return queries.map((query, index) => ({\n media: query,\n matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query).matches,\n }));\n });\n\n useEffect(() => {\n setValue(\n queries.map((query) => ({\n media: query,\n matches: document.defaultView?.matchMedia(query).matches,\n })),\n );\n\n const mql = queries.map((query) => document.defaultView?.matchMedia(query));\n\n const handler = (evt: MediaQueryListEvent) => {\n setValue((prev) => {\n return prev.slice().map((item) => {\n if (item.media === evt.media) {\n return { ...item, matches: evt.matches };\n }\n return item;\n });\n });\n };\n\n mql.forEach((mql) => {\n if (typeof mql?.addListener === 'function') {\n mql?.addListener(handler);\n } else {\n mql?.addEventListener('change', handler);\n }\n });\n\n return () => {\n mql.forEach((mql) => {\n if (typeof mql?.removeListener === 'function') {\n mql?.removeListener(handler);\n } else {\n mql?.removeEventListener('change', handler);\n }\n });\n };\n }, [document.defaultView]);\n\n return value.map((item) => !!item.matches);\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { type RefCallback, useState } from 'react';\n\n/**\n * Custom React Hook that creates a ref callback and a state variable.\n * The ref callback sets the state variable when the ref changes.\n *\n * @returns An object containing the ref callback and the current value of the ref.\n */\nexport const useRefCallback = <T = any>(): { refCallback: RefCallback<T>; value: T | null } => {\n const [value, setValue] = useState<T | null>(null);\n return { refCallback: (value: T) => setValue(value), value };\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport { useRef, useEffect, useState } from 'react';\n\nconst isFunction = <T>(functionToCheck: any): functionToCheck is (value: T) => boolean => {\n return functionToCheck instanceof Function;\n};\n\n/**\n * This is an internal custom hook that checks if a value has transitioned from a specified 'from' value to a 'to' value.\n *\n * @param currentValue - The value that is being monitored for transitions.\n * @param fromValue - The *from* value or a predicate function that determines the start of the transition.\n * @param toValue - The *to* value or a predicate function that determines the end of the transition.\n * @returns A boolean indicating whether the transition from *fromValue* to *toValue* has occurred.\n *\n * @internal Consider using `useOnTransition` for handling transitions instead of this hook.\n */\nexport const useDidTransition = <T>(\n currentValue: T,\n fromValue: T | ((value: T) => boolean),\n toValue: T | ((value: T) => boolean),\n) => {\n const [hasTransitioned, setHasTransitioned] = useState(false);\n const previousValue = useRef<T>(currentValue);\n\n useEffect(() => {\n const toValueValid = isFunction<T>(toValue) ? toValue(currentValue) : toValue === currentValue;\n\n const fromValueValid = isFunction<T>(fromValue)\n ? fromValue(previousValue.current)\n : fromValue === previousValue.current;\n\n const transitioned = fromValueValid && toValueValid;\n\n if (transitioned) {\n setHasTransitioned(true);\n } else {\n setHasTransitioned(false);\n }\n\n previousValue.current = currentValue;\n }, [currentValue, fromValue, toValue, setHasTransitioned, previousValue]);\n\n return hasTransitioned;\n};\n\n/**\n * Executes a callback function when a specified transition occurs in a value.\n *\n * This function utilizes the `useDidTransition` hook to monitor changes in `currentValue`.\n * When `currentValue` transitions from `fromValue` to `toValue`, the provided `callback` function is executed. */\nexport const useOnTransition = <T>(\n currentValue: T,\n fromValue: T | ((value: T) => boolean),\n toValue: ((value: T) => boolean) | T,\n callback: () => void,\n) => {\n const dirty = useRef(false);\n const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);\n\n useEffect(() => {\n dirty.current = false;\n }, [currentValue, dirty]);\n\n useEffect(() => {\n if (hasTransitioned && !dirty.current) {\n callback();\n dirty.current = true;\n }\n }, [hasTransitioned, dirty, callback]);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["import_react", "useAsyncCallback", "cb", "value", "setValue", "useState", "useEffect", "t", "setTimeout", "data", "clearTimeout", "useControlledValue", "controlledValue", "undefined", "useDefaultValue", "reactiveValue", "defaultValue", "stableDefaultValue", "useMemo", "useDynamicRef", "ref", "useRef", "current", "useFileDownload", "filename", "url", "URL", "createObjectURL", "element", "document", "createElement", "setAttribute", "click", "useForwardedRef", "innerRef", "Alea", "alea", "prng", "randomString", "n", "toString", "slice", "useId", "namespace", "propsId", "opts", "useIsFocused", "inputRef", "isFocused", "setIsFocused", "isFocusedRef", "input", "onFocus", "onBlur", "addEventListener", "activeElement", "removeEventListener", "breakpointMediaQueries", "sm", "md", "lg", "xl", "useMediaQuery", "query", "options", "ssr", "fallback", "queries", "Array", "isArray", "map", "fallbackValues", "filter", "v", "index", "media", "matches", "defaultView", "matchMedia", "mql", "handler", "evt", "prev", "item", "forEach", "addListener", "removeListener", "useRefCallback", "refCallback", "isFunction", "functionToCheck", "Function", "useDidTransition", "currentValue", "fromValue", "toValue", "hasTransitioned", "setHasTransitioned", "previousValue", "toValueValid", "fromValueValid", "transitioned", "useOnTransition", "callback", "dirty"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/primitives/react-hooks/src/useControlledValue.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/primitives/react-hooks/src/useAsyncCallback.ts":{"bytes":1751,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useControlledValue.ts":{"bytes":1974,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useDefaultValue.ts":{"bytes":4059,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useDynamicRef.ts":{"bytes":1247,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useFileDownload.ts":{"bytes":2740,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytes":1783,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytes":2163,"imports":[{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytes":3990,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytes":9390,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useRefCallback.ts":{"bytes":1879,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/useTransitions.ts":{"bytes":7797,"imports":[{"path":"react","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/primitives/react-hooks/src/index.ts":{"bytes":1572,"imports":[{"path":"packages/ui/primitives/react-hooks/src/useAsyncCallback.ts","kind":"import-statement","original":"./useAsyncCallback"},{"path":"packages/ui/primitives/react-hooks/src/useControlledValue.ts","kind":"import-statement","original":"./useControlledValue"},{"path":"packages/ui/primitives/react-hooks/src/useDefaultValue.ts","kind":"import-statement","original":"./useDefaultValue"},{"path":"packages/ui/primitives/react-hooks/src/useDynamicRef.ts","kind":"import-statement","original":"./useDynamicRef"},{"path":"packages/ui/primitives/react-hooks/src/useFileDownload.ts","kind":"import-statement","original":"./useFileDownload"},{"path":"packages/ui/primitives/react-hooks/src/useForwardedRef.ts","kind":"import-statement","original":"./useForwardedRef"},{"path":"packages/ui/primitives/react-hooks/src/useId.ts","kind":"import-statement","original":"./useId"},{"path":"packages/ui/primitives/react-hooks/src/useIsFocused.ts","kind":"import-statement","original":"./useIsFocused"},{"path":"packages/ui/primitives/react-hooks/src/useMediaQuery.ts","kind":"import-statement","original":"./useMediaQuery"},{"path":"packages/ui/primitives/react-hooks/src/useRefCallback.ts","kind":"import-statement","original":"./useRefCallback"},{"path":"packages/ui/primitives/react-hooks/src/useTransitions.ts","kind":"import-statement","original":"./useTransitions"}],"format":"esm"}},"outputs":{"packages/ui/primitives/react-hooks/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":18788},"packages/ui/primitives/react-hooks/dist/lib/node/index.cjs":{"imports":[{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"alea","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true}],"exports":["randomString","useAsyncCallback","useControlledValue","useDefaultValue","useDidTransition","useDynamicRef","useFileDownload","useForwardedRef","useId","useIsFocused","useMediaQuery","useOnTransition","useRefCallback"],"entryPoint":"packages/ui/primitives/react-hooks/src/index.ts","inputs":{"packages/ui/primitives/react-hooks/src/useAsyncCallback.ts":{"bytesInOutput":301},"packages/ui/primitives/react-hooks/src/index.ts":{"bytesInOutput":0},"packages/ui/primitives/react-hooks/src/useControlledValue.ts":{"bytesInOutput":350},"packages/ui/primitives/react-hooks/src/useDefaultValue.ts":{"bytesInOutput":411},"packages/ui/primitives/react-hooks/src/useDynamicRef.ts":{"bytesInOutput":205},"packages/ui/primitives/react-hooks/src/useFileDownload.ts":{"bytesInOutput":416},"packages/ui/primitives/react-hooks/src/useForwardedRef.ts":{"bytesInOutput":343},"packages/ui/primitives/react-hooks/src/useId.ts":{"bytesInOutput":326},"packages/ui/primitives/react-hooks/src/useIsFocused.ts":{"bytesInOutput":833},"packages/ui/primitives/react-hooks/src/useMediaQuery.ts":{"bytesInOutput":1940},"packages/ui/primitives/react-hooks/src/useRefCallback.ts":{"bytesInOutput":197},"packages/ui/primitives/react-hooks/src/useTransitions.ts":{"bytesInOutput":1384}},"bytes":7649}}}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
export * from './useAsyncCallback';
|
|
1
2
|
export * from './useControlledValue';
|
|
2
3
|
export * from './useDefaultValue';
|
|
4
|
+
export * from './useDynamicRef';
|
|
3
5
|
export * from './useFileDownload';
|
|
4
6
|
export * from './useForwardedRef';
|
|
5
7
|
export * from './useId';
|
|
6
8
|
export * from './useIsFocused';
|
|
7
9
|
export * from './useMediaQuery';
|
|
8
|
-
export * from './useTransitions';
|
|
9
10
|
export * from './useRefCallback';
|
|
11
|
+
export * from './useTransitions';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAsyncCallback.d.ts","sourceRoot":"","sources":["../../../src/useAsyncCallback.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,gBAAgB,GAAI,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,CAAC,GAAG,SAY9D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useControlledValue.d.ts","sourceRoot":"","sources":["../../../src/useControlledValue.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,mBAAmB,MAAM,KAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"useControlledValue.d.ts","sourceRoot":"","sources":["../../../src/useControlledValue.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,mBAAmB,MAAM,KAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAS7G,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDynamicRef.d.ts","sourceRoot":"","sources":["../../../src/useDynamicRef.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,CAAC,wCAMxC,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
export * from './useAsyncCallback';
|
|
5
6
|
export * from './useControlledValue';
|
|
6
7
|
export * from './useDefaultValue';
|
|
8
|
+
export * from './useDynamicRef';
|
|
7
9
|
export * from './useFileDownload';
|
|
8
10
|
export * from './useForwardedRef';
|
|
9
11
|
export * from './useId';
|
|
10
12
|
export * from './useIsFocused';
|
|
11
13
|
export * from './useMediaQuery';
|
|
12
|
-
export * from './useTransitions';
|
|
13
14
|
export * from './useRefCallback';
|
|
15
|
+
export * from './useTransitions';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
export const useAsyncCallback = <T>(cb: () => Promise<T>): T | undefined => {
|
|
8
|
+
const [value, setValue] = useState<T | undefined>();
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const t = setTimeout(async () => {
|
|
11
|
+
const data = await cb();
|
|
12
|
+
setValue(data);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return () => clearTimeout(t);
|
|
16
|
+
}, []);
|
|
17
|
+
|
|
18
|
+
return value;
|
|
19
|
+
};
|
|
@@ -10,7 +10,9 @@ import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
|
|
|
10
10
|
export const useControlledValue = <TValue>(controlledValue: TValue): [TValue, Dispatch<SetStateAction<TValue>>] => {
|
|
11
11
|
const [value, setValue] = useState<TValue>(controlledValue);
|
|
12
12
|
useEffect(() => {
|
|
13
|
-
|
|
13
|
+
if (controlledValue !== undefined) {
|
|
14
|
+
setValue(controlledValue);
|
|
15
|
+
}
|
|
14
16
|
}, [controlledValue]);
|
|
15
17
|
|
|
16
18
|
return [value, setValue];
|