@dxos/react-hooks 0.8.4-main.b97322e → 0.8.4-main.f5c0578
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 +38 -28
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +38 -28
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/useAsyncEffect.d.ts +1 -31
- package/dist/types/src/useAsyncEffect.d.ts.map +1 -1
- package/dist/types/src/useIsFocused.d.ts.map +1 -1
- package/dist/types/src/useTimeout.d.ts +2 -1
- package/dist/types/src/useTimeout.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -3
- package/src/useAsyncEffect.ts +6 -54
- package/src/useDefaultValue.ts +1 -1
- package/src/useForwardedRef.ts +1 -1
- package/src/useIsFocused.ts +1 -1
- package/src/useTimeout.ts +28 -3
- package/src/useTrackProps.ts +1 -1
- package/src/useTransitions.ts +1 -1
- package/dist/types/src/useAsyncEffect.test.d.ts +0 -2
- package/dist/types/src/useAsyncEffect.test.d.ts.map +0 -1
- package/src/useAsyncEffect.test.tsx +0 -51
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-hooks",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.f5c0578",
|
|
4
4
|
"description": "React hooks supporting DXOS React primitives.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
13
|
+
"source": "./src/index.ts",
|
|
13
14
|
"types": "./dist/types/src/index.d.ts",
|
|
14
15
|
"browser": "./dist/lib/browser/index.mjs",
|
|
15
16
|
"node": "./dist/lib/node-esm/index.mjs"
|
|
@@ -27,8 +28,8 @@
|
|
|
27
28
|
"@preact-signals/safe-react": "^0.9.0",
|
|
28
29
|
"alea": "^1.0.1",
|
|
29
30
|
"lodash.defaultsdeep": "^4.6.1",
|
|
30
|
-
"@dxos/async": "0.8.4-main.
|
|
31
|
-
"@dxos/log": "0.8.4-main.
|
|
31
|
+
"@dxos/async": "0.8.4-main.f5c0578",
|
|
32
|
+
"@dxos/log": "0.8.4-main.f5c0578"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@types/lodash.defaultsdeep": "^4.6.6",
|
package/src/useAsyncEffect.ts
CHANGED
|
@@ -4,59 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
import { useEffect } from 'react';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Process async event with optional non-async destructor.
|
|
11
|
-
* Inspired by: https://github.com/rauldeheer/use-async-effect/blob/master/index.js
|
|
12
|
-
*
|
|
13
|
-
* ```tsx
|
|
14
|
-
* useAsyncEffect(async () => {
|
|
15
|
-
* await test();
|
|
16
|
-
* }, []);
|
|
17
|
-
* ```
|
|
18
|
-
*
|
|
19
|
-
* The callback may check of the component is still mounted before doing state updates.
|
|
20
|
-
*
|
|
21
|
-
* ```tsx
|
|
22
|
-
* const [value, setValue] = useState<string>();
|
|
23
|
-
* useAsyncEffect<string>(async (isMounted) => {
|
|
24
|
-
* const value = await test();
|
|
25
|
-
* if (!isMounted()) {
|
|
26
|
-
* setValue(value);
|
|
27
|
-
* }
|
|
28
|
-
* }, () => console.log('Unmounted'), []);
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @param callback Receives a getter function that determines if the component is still mounted.
|
|
32
|
-
* @param destructor Receives the value returned from the callback.
|
|
33
|
-
* @param deps
|
|
34
|
-
*
|
|
35
|
-
* NOTE: This effect does not cancel the async operation if the component is unmounted.
|
|
36
|
-
*
|
|
37
|
-
* @deprecated Use useTimeout.
|
|
38
|
-
*/
|
|
39
|
-
export const useAsyncEffect = <T>(
|
|
40
|
-
callback: (isMounted: () => boolean) => Promise<T> | undefined,
|
|
41
|
-
destructor?: ((value?: T) => void) | any[],
|
|
42
|
-
deps?: any[],
|
|
43
|
-
) => {
|
|
44
|
-
const [effectDestructor, effectDeps] =
|
|
45
|
-
typeof destructor === 'function' ? [destructor, deps] : [undefined, destructor];
|
|
46
|
-
|
|
7
|
+
export const useAsyncEffect = <T>(callback: () => Promise<T> | void, deps?: any[]) => {
|
|
47
8
|
useEffect(() => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
value = result;
|
|
54
|
-
})
|
|
55
|
-
.catch(log.catch);
|
|
56
|
-
|
|
57
|
-
return () => {
|
|
58
|
-
mounted = false;
|
|
59
|
-
effectDestructor?.(value);
|
|
60
|
-
};
|
|
61
|
-
}, effectDeps);
|
|
9
|
+
const t = setTimeout(() => {
|
|
10
|
+
void callback();
|
|
11
|
+
});
|
|
12
|
+
return () => clearTimeout(t);
|
|
13
|
+
}, deps);
|
|
62
14
|
};
|
package/src/useDefaultValue.ts
CHANGED
package/src/useForwardedRef.ts
CHANGED
package/src/useIsFocused.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// Based upon the useIsFocused hook which is part of the `rci` project:
|
|
6
6
|
/// https://github.com/leonardodino/rci/blob/main/packages/use-is-focused
|
|
7
7
|
|
|
8
|
-
import { useEffect, useRef, useState
|
|
8
|
+
import { type RefObject, useEffect, useRef, useState } from 'react';
|
|
9
9
|
|
|
10
10
|
export const useIsFocused = (inputRef: RefObject<HTMLInputElement>) => {
|
|
11
11
|
const [isFocused, setIsFocused] = useState<boolean | undefined>(undefined);
|
package/src/useTimeout.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { useEffect, useRef } from 'react';
|
|
6
6
|
|
|
7
|
-
export const useTimeout = (callback
|
|
7
|
+
export const useTimeout = (callback?: () => Promise<void>, delay = 0, deps: any[] = []) => {
|
|
8
8
|
const callbackRef = useRef(callback);
|
|
9
9
|
useEffect(() => {
|
|
10
10
|
callbackRef.current = callback;
|
|
@@ -15,7 +15,32 @@ export const useTimeout = (callback: (() => Promise<void>) | undefined, delay =
|
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const
|
|
19
|
-
return () => clearTimeout(
|
|
18
|
+
const t = setTimeout(() => callbackRef.current?.(), delay);
|
|
19
|
+
return () => clearTimeout(t);
|
|
20
|
+
}, [delay, ...deps]);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const useInterval = (
|
|
24
|
+
callback?: (() => Promise<void | boolean>) | (() => void | boolean),
|
|
25
|
+
delay = 0,
|
|
26
|
+
deps: any[] = [],
|
|
27
|
+
) => {
|
|
28
|
+
const callbackRef = useRef(callback);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
callbackRef.current = callback;
|
|
31
|
+
}, [callback]);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (delay == null) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const i = setInterval(async () => {
|
|
39
|
+
const result = await callbackRef.current?.();
|
|
40
|
+
if (result === false) {
|
|
41
|
+
clearInterval(i);
|
|
42
|
+
}
|
|
43
|
+
}, delay);
|
|
44
|
+
return () => clearInterval(i);
|
|
20
45
|
}, [delay, ...deps]);
|
|
21
46
|
};
|
package/src/useTrackProps.ts
CHANGED
package/src/useTransitions.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { useEffect, useRef, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
const isFunction = <T>(functionToCheck: any): functionToCheck is (value: T) => boolean => {
|
|
8
8
|
return functionToCheck instanceof Function;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useAsyncEffect.test.d.ts","sourceRoot":"","sources":["../../../src/useAsyncEffect.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2022 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import React, { useState } from 'react';
|
|
6
|
-
import { createRoot } from 'react-dom/client';
|
|
7
|
-
import { act } from 'react-dom/test-utils';
|
|
8
|
-
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
9
|
-
|
|
10
|
-
import { useAsyncEffect } from './useAsyncEffect';
|
|
11
|
-
|
|
12
|
-
const doAsync = async <T,>(value: T) =>
|
|
13
|
-
await new Promise<T>((resolve) => {
|
|
14
|
-
resolve(value);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
const Test = () => {
|
|
18
|
-
const [value, setValue] = useState<string>();
|
|
19
|
-
useAsyncEffect(async (isMounted) => {
|
|
20
|
-
const value = await doAsync('DXOS');
|
|
21
|
-
if (isMounted()) {
|
|
22
|
-
void act(() => {
|
|
23
|
-
setValue(value);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}, []);
|
|
27
|
-
|
|
28
|
-
return <h1>{value}</h1>;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
let rootContainer: HTMLElement;
|
|
32
|
-
|
|
33
|
-
describe('useAsyncEffect', () => {
|
|
34
|
-
beforeEach(() => {
|
|
35
|
-
rootContainer = document.createElement('div');
|
|
36
|
-
document.body.appendChild(rootContainer);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterEach(() => {
|
|
40
|
-
document.body.removeChild(rootContainer!);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test('gets async value.', async () => {
|
|
44
|
-
await act(() => {
|
|
45
|
-
createRoot(rootContainer).render(<Test />);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const h1 = rootContainer.querySelector('h1');
|
|
49
|
-
expect(h1?.textContent).toEqual('DXOS');
|
|
50
|
-
});
|
|
51
|
-
});
|