@dxos/react-hooks 0.7.5-main.9d2a38b → 0.7.5-main.c41020f

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.
Files changed (37) hide show
  1. package/dist/lib/browser/index.mjs +64 -18
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +63 -18
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +64 -18
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/index.d.ts +2 -1
  11. package/dist/types/src/index.d.ts.map +1 -1
  12. package/dist/types/src/useAsyncEffect.d.ts +2 -0
  13. package/dist/types/src/useAsyncEffect.d.ts.map +1 -1
  14. package/dist/types/src/useAsyncState.d.ts.map +1 -1
  15. package/dist/types/src/useControlledState.d.ts +6 -0
  16. package/dist/types/src/useControlledState.d.ts.map +1 -0
  17. package/dist/types/src/useDynamicRef.d.ts +3 -0
  18. package/dist/types/src/useDynamicRef.d.ts.map +1 -1
  19. package/dist/types/src/useForwardedRef.d.ts +4 -0
  20. package/dist/types/src/useForwardedRef.d.ts.map +1 -1
  21. package/dist/types/src/useMediaQuery.d.ts.map +1 -1
  22. package/dist/types/src/useResize.d.ts +1 -1
  23. package/dist/types/src/useResize.d.ts.map +1 -1
  24. package/dist/types/src/useTrackProps.d.ts +5 -0
  25. package/dist/types/src/useTrackProps.d.ts.map +1 -0
  26. package/package.json +4 -3
  27. package/src/index.ts +2 -1
  28. package/src/useAsyncEffect.ts +2 -1
  29. package/src/useAsyncState.ts +1 -0
  30. package/src/{useControlledValue.ts → useControlledState.ts} +2 -5
  31. package/src/useDynamicRef.ts +3 -0
  32. package/src/useForwardedRef.ts +4 -1
  33. package/src/useMediaQuery.ts +1 -0
  34. package/src/useResize.ts +18 -7
  35. package/src/useTrackProps.ts +40 -0
  36. package/dist/types/src/useControlledValue.d.ts +0 -6
  37. package/dist/types/src/useControlledValue.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useAsyncState.d.ts","sourceRoot":"","sources":["../../../src/useAsyncState.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,MACzB,MAAM,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,SAC1B,GAAG,EAAE,KACV,CAAC,CAAC,GAAG,SAAS,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAYzD,CAAC"}
1
+ {"version":3,"file":"useAsyncState.d.ts","sourceRoot":"","sources":["../../../src/useAsyncState.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,MACzB,MAAM,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,SAC1B,GAAG,EAAE,KACV,CAAC,CAAC,GAAG,SAAS,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAazD,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { type Dispatch, type SetStateAction } from 'react';
2
+ /**
3
+ * A stateful hook with a controlled value.
4
+ */
5
+ export declare const useControlledState: <T>(controlledValue: T, ...deps: any[]) => [T, Dispatch<SetStateAction<T>>];
6
+ //# sourceMappingURL=useControlledState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useControlledState.d.ts","sourceRoot":"","sources":["../../../src/useControlledState.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,mBAAmB,CAAC,WAAW,GAAG,EAAE,KAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CASzG,CAAC"}
@@ -1,2 +1,5 @@
1
+ /**
2
+ * Ref that is updated by a dependency.
3
+ */
1
4
  export declare const useDynamicRef: <T>(value: T) => import("react").MutableRefObject<T>;
2
5
  //# sourceMappingURL=useDynamicRef.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useDynamicRef.d.ts","sourceRoot":"","sources":["../../../src/useDynamicRef.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,CAAC,wCAOxC,CAAC"}
1
+ {"version":3,"file":"useDynamicRef.d.ts","sourceRoot":"","sources":["../../../src/useDynamicRef.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,CAAC,wCAOxC,CAAC"}
@@ -1,3 +1,7 @@
1
1
  import { type ForwardedRef } from 'react';
2
+ /**
3
+ * Combines a possibly undefined forwarded ref with a locally defined ref.
4
+ * See also: react-merge-refs
5
+ */
2
6
  export declare const useForwardedRef: <T>(ref: ForwardedRef<T>) => import("react").RefObject<T>;
3
7
  //# sourceMappingURL=useForwardedRef.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useForwardedRef.d.ts","sourceRoot":"","sources":["../../../src/useForwardedRef.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,OAAO,CAAC;AAE7D,eAAO,MAAM,eAAe,GAAI,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,iCAgBtD,CAAC"}
1
+ {"version":3,"file":"useForwardedRef.d.ts","sourceRoot":"","sources":["../../../src/useForwardedRef.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAqB,MAAM,OAAO,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,iCAetD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useMediaQuery.d.ts","sourceRoot":"","sources":["../../../src/useMediaQuery.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAWF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,UAAW,MAAM,GAAG,MAAM,EAAE,YAAW,oBAAoB,KAAQ,OAAO,EA0DnG,CAAC"}
1
+ {"version":3,"file":"useMediaQuery.d.ts","sourceRoot":"","sources":["../../../src/useMediaQuery.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAWF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,UAAW,MAAM,GAAG,MAAM,EAAE,YAAW,oBAAoB,KAAQ,OAAO,EA2DnG,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { useLayoutEffect } from 'react';
2
- export declare const useResize: (handler: (event?: Event) => void, deps?: Parameters<typeof useLayoutEffect>[1]) => void;
2
+ export declare const useResize: (handler: (event?: Event) => void, deps?: Parameters<typeof useLayoutEffect>[1], delay?: number) => void;
3
3
  //# sourceMappingURL=useResize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useResize.d.ts","sourceRoot":"","sources":["../../../src/useResize.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAExC,eAAO,MAAM,SAAS,YACX,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,SAC1B,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,SAO5C,CAAC"}
1
+ {"version":3,"file":"useResize.d.ts","sourceRoot":"","sources":["../../../src/useResize.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAW,MAAM,OAAO,CAAC;AAEjD,eAAO,MAAM,SAAS,YACX,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,SAC1B,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,UACpC,MAAM,SAiBd,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Use to debug which props have changed to trigger re-renders in a React component.
3
+ */
4
+ export declare const useTrackProps: <T extends Record<string, unknown>>(props: T, componentName?: string, active?: boolean) => void;
5
+ //# sourceMappingURL=useTrackProps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTrackProps.d.ts","sourceRoot":"","sources":["../../../src/useTrackProps.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SACtD,CAAC,mDA2BT,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@dxos/react-hooks",
3
- "version": "0.7.5-main.9d2a38b",
3
+ "version": "0.7.5-main.c41020f",
4
4
  "description": "React hooks supporting DXOS React primitives.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
7
7
  "license": "MIT",
8
8
  "author": "DXOS.org",
9
9
  "sideEffects": true,
10
+ "type": "module",
10
11
  "exports": {
11
12
  ".": {
12
13
  "types": "./dist/types/src/index.d.ts",
@@ -24,8 +25,8 @@
24
25
  ],
25
26
  "dependencies": {
26
27
  "alea": "^1.0.1",
27
- "@dxos/async": "0.7.5-main.9d2a38b",
28
- "@dxos/log": "0.7.5-main.9d2a38b"
28
+ "@dxos/async": "0.7.5-main.c41020f",
29
+ "@dxos/log": "0.7.5-main.c41020f"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@types/react": "~18.2.0",
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  export * from './useAsyncEffect';
6
6
  export * from './useAsyncState';
7
- export * from './useControlledValue';
7
+ export * from './useControlledState';
8
8
  export * from './useDebugReactDeps';
9
9
  export * from './useDefaultValue';
10
10
  export * from './useDynamicRef';
@@ -16,4 +16,5 @@ export * from './useMediaQuery';
16
16
  export * from './useMulticastObservable';
17
17
  export * from './useRefCallback';
18
18
  export * from './useResize';
19
+ export * from './useTrackProps';
19
20
  export * from './useTransitions';
@@ -33,6 +33,8 @@ import { log } from '@dxos/log';
33
33
  * @param deps
34
34
  *
35
35
  * NOTE: This effect does not cancel the async operation if the component is unmounted.
36
+ *
37
+ * @deprecated
36
38
  */
37
39
  export const useAsyncEffect = <T>(
38
40
  callback: (isMounted: () => boolean) => Promise<T> | undefined,
@@ -46,7 +48,6 @@ export const useAsyncEffect = <T>(
46
48
  let mounted = true;
47
49
  let value: T | undefined;
48
50
  const asyncResult = callback(() => mounted);
49
-
50
51
  void Promise.resolve(asyncResult)
51
52
  .then((result) => {
52
53
  value = result;
@@ -15,6 +15,7 @@ export const useAsyncState = <T>(
15
15
  useEffect(() => {
16
16
  const t = setTimeout(async () => {
17
17
  const data = await cb();
18
+ // TODO(dmaretskyi): Potential race condition here.
18
19
  setValue(data);
19
20
  });
20
21
 
@@ -7,11 +7,8 @@ import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
7
7
  /**
8
8
  * A stateful hook with a controlled value.
9
9
  */
10
- export const useControlledValue = <TValue>(
11
- controlledValue: TValue,
12
- ...deps: any[]
13
- ): [TValue, Dispatch<SetStateAction<TValue>>] => {
14
- const [value, setValue] = useState<TValue>(controlledValue);
10
+ export const useControlledState = <T>(controlledValue: T, ...deps: any[]): [T, Dispatch<SetStateAction<T>>] => {
11
+ const [value, setValue] = useState<T>(controlledValue);
15
12
  useEffect(() => {
16
13
  if (controlledValue !== undefined) {
17
14
  setValue(controlledValue);
@@ -4,6 +4,9 @@
4
4
 
5
5
  import { useEffect, useRef } from 'react';
6
6
 
7
+ /**
8
+ * Ref that is updated by a dependency.
9
+ */
7
10
  export const useDynamicRef = <T>(value: T) => {
8
11
  const ref = useRef<T>(value);
9
12
  useEffect(() => {
@@ -4,9 +4,12 @@
4
4
 
5
5
  import { type ForwardedRef, useRef, useEffect } from 'react';
6
6
 
7
+ /**
8
+ * Combines a possibly undefined forwarded ref with a locally defined ref.
9
+ * See also: react-merge-refs
10
+ */
7
11
  export const useForwardedRef = <T>(ref: ForwardedRef<T>) => {
8
12
  const innerRef = useRef<T>(null);
9
-
10
13
  useEffect(() => {
11
14
  if (!ref) {
12
15
  return;
@@ -29,6 +29,7 @@ const breakpointMediaQueries: Record<string, string> = {
29
29
  * @see Docs https://chakra-ui.com/docs/hooks/use-media-query
30
30
  */
31
31
  export const useMediaQuery = (query: string | string[], options: UseMediaQueryOptions = {}): boolean[] => {
32
+ // TODO(wittjosiah): Why is the default here true?
32
33
  const { ssr = true, fallback } = options;
33
34
 
34
35
  const queries = (Array.isArray(query) ? query : [query]).map((query) =>
package/src/useResize.ts CHANGED
@@ -1,16 +1,27 @@
1
1
  //
2
- // Copyright 2023 DXOS.org
2
+ // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { useLayoutEffect } from 'react';
5
+ import { useLayoutEffect, useMemo } from 'react';
6
6
 
7
7
  export const useResize = (
8
8
  handler: (event?: Event) => void,
9
- deps: Parameters<typeof useLayoutEffect>[1] = [handler],
9
+ deps: Parameters<typeof useLayoutEffect>[1] = [],
10
+ delay: number = 800,
10
11
  ) => {
12
+ const debouncedHandler = useMemo(() => {
13
+ let timeout: ReturnType<typeof setTimeout>;
14
+ return (event?: Event) => {
15
+ clearTimeout(timeout);
16
+ timeout = setTimeout(() => {
17
+ handler(event);
18
+ }, delay);
19
+ };
20
+ }, [handler, delay]);
21
+
11
22
  return useLayoutEffect(() => {
12
- window.visualViewport?.addEventListener('resize', handler);
13
- handler();
14
- return () => window.visualViewport?.removeEventListener('resize', handler);
15
- }, deps);
23
+ window.visualViewport?.addEventListener('resize', debouncedHandler);
24
+ debouncedHandler();
25
+ return () => window.visualViewport?.removeEventListener('resize', debouncedHandler);
26
+ }, [debouncedHandler, ...deps]);
16
27
  };
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { useRef, useEffect } from 'react';
6
+
7
+ import { log } from '@dxos/log';
8
+
9
+ /**
10
+ * Use to debug which props have changed to trigger re-renders in a React component.
11
+ */
12
+ export const useTrackProps = <T extends Record<string, unknown>>(
13
+ props: T,
14
+ componentName = 'Component',
15
+ active = true,
16
+ ) => {
17
+ const prevProps = useRef<T>(props);
18
+ useEffect(() => {
19
+ const changes = Object.entries(props).filter(([key]) => props[key] !== prevProps.current[key]);
20
+ if (changes.length > 0) {
21
+ if (active) {
22
+ log.info('props changed', {
23
+ componentName,
24
+ keys: changes.map(([key]) => key).join(','),
25
+ props: Object.fromEntries(
26
+ changes.map(([key]) => [
27
+ key,
28
+ {
29
+ from: prevProps.current[key],
30
+ to: props[key],
31
+ },
32
+ ]),
33
+ ),
34
+ });
35
+ }
36
+ }
37
+
38
+ prevProps.current = props;
39
+ });
40
+ };
@@ -1,6 +0,0 @@
1
- import { type Dispatch, type SetStateAction } from 'react';
2
- /**
3
- * A stateful hook with a controlled value.
4
- */
5
- export declare const useControlledValue: <TValue>(controlledValue: TValue, ...deps: any[]) => [TValue, Dispatch<SetStateAction<TValue>>];
6
- //# sourceMappingURL=useControlledValue.d.ts.map
@@ -1 +0,0 @@
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,mBACtB,MAAM,WACd,GAAG,EAAE,KACb,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAS3C,CAAC"}