@dxos/react-hooks 0.8.4-main.fd6878d → 0.8.4-main.fffef41

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 (54) hide show
  1. package/dist/lib/browser/index.mjs +196 -116
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +196 -116
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/index.d.ts +4 -3
  8. package/dist/types/src/index.d.ts.map +1 -1
  9. package/dist/types/src/useAsyncEffect.d.ts +7 -1
  10. package/dist/types/src/useAsyncEffect.d.ts.map +1 -1
  11. package/dist/types/src/useControlledState.d.ts +2 -1
  12. package/dist/types/src/useControlledState.d.ts.map +1 -1
  13. package/dist/types/src/useDebugDeps.d.ts +6 -0
  14. package/dist/types/src/useDebugDeps.d.ts.map +1 -0
  15. package/dist/types/src/useDynamicRef.d.ts +6 -1
  16. package/dist/types/src/useDynamicRef.d.ts.map +1 -1
  17. package/dist/types/src/useForwardedRef.d.ts +23 -3
  18. package/dist/types/src/useForwardedRef.d.ts.map +1 -1
  19. package/dist/types/src/useIsFocused.d.ts +1 -1
  20. package/dist/types/src/useIsFocused.d.ts.map +1 -1
  21. package/dist/types/src/useMediaQuery.d.ts +1 -1
  22. package/dist/types/src/useMediaQuery.d.ts.map +1 -1
  23. package/dist/types/src/useMulticastObservable.test.d.ts.map +1 -1
  24. package/dist/types/src/useSignals.d.ts +10 -0
  25. package/dist/types/src/useSignals.d.ts.map +1 -0
  26. package/dist/types/src/useTimeout.d.ts +2 -1
  27. package/dist/types/src/useTimeout.d.ts.map +1 -1
  28. package/dist/types/src/useTransitions.d.ts +2 -1
  29. package/dist/types/src/useTransitions.d.ts.map +1 -1
  30. package/dist/types/src/useViewportResize.d.ts +3 -0
  31. package/dist/types/src/useViewportResize.d.ts.map +1 -0
  32. package/dist/types/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +11 -9
  34. package/src/index.ts +5 -3
  35. package/src/useAsyncEffect.ts +24 -6
  36. package/src/useControlledState.ts +22 -11
  37. package/src/useDebugDeps.ts +26 -0
  38. package/src/useDynamicRef.ts +27 -5
  39. package/src/useForwardedRef.ts +48 -13
  40. package/src/useIsFocused.ts +1 -1
  41. package/src/useMediaQuery.ts +8 -9
  42. package/src/{useMulticastObservable.test.tsx → useMulticastObservable.test.ts} +1 -3
  43. package/src/useSignals.ts +27 -0
  44. package/src/useTimeout.ts +28 -3
  45. package/src/useTransitions.ts +3 -1
  46. package/src/{useResize.ts → useViewportResize.ts} +1 -1
  47. package/dist/types/src/useDebugReactDeps.d.ts +0 -6
  48. package/dist/types/src/useDebugReactDeps.d.ts.map +0 -1
  49. package/dist/types/src/useResize.d.ts +0 -3
  50. package/dist/types/src/useResize.d.ts.map +0 -1
  51. package/dist/types/src/useTrackProps.d.ts +0 -5
  52. package/dist/types/src/useTrackProps.d.ts.map +0 -1
  53. package/src/useDebugReactDeps.ts +0 -27
  54. package/src/useTrackProps.ts +0 -40
@@ -2,13 +2,21 @@ import { createRequire } from 'node:module';const require = createRequire(import
2
2
 
3
3
  // src/useAsyncEffect.ts
4
4
  import { useEffect } from "react";
5
- var useAsyncEffect = (callback, deps) => {
5
+ var useAsyncEffect = (cb, deps) => {
6
6
  useEffect(() => {
7
- const t = setTimeout(() => {
8
- void callback();
7
+ const controller = new AbortController();
8
+ let cleanup;
9
+ const t = setTimeout(async () => {
10
+ if (!controller.signal.aborted) {
11
+ cleanup = await cb(controller);
12
+ }
9
13
  });
10
- return () => clearTimeout(t);
11
- }, deps);
14
+ return () => {
15
+ clearTimeout(t);
16
+ controller.abort();
17
+ cleanup?.();
18
+ };
19
+ }, deps ?? []);
12
20
  };
13
21
 
14
22
  // src/useAsyncState.ts
@@ -35,43 +43,85 @@ var useAsyncState = (cb, deps = []) => {
35
43
  };
36
44
 
37
45
  // src/useControlledState.ts
38
- import { useEffect as useEffect3, useState as useState2 } from "react";
39
- var useControlledState = (controlledValue, onChange, ...deps) => {
40
- const [value, setValue] = useState2(controlledValue);
41
- useEffect3(() => {
42
- if (controlledValue !== void 0) {
43
- setValue(controlledValue);
46
+ import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2, useState as useState3 } from "react";
47
+
48
+ // src/useDynamicRef.ts
49
+ import { useCallback } from "@preact-signals/safe-react/react";
50
+ import { useEffect as useEffect3, useRef, useState as useState2 } from "react";
51
+ var useStateWithRef = (valueParam) => {
52
+ const [value, setValue] = useState2(valueParam);
53
+ const valueRef = useRef(valueParam);
54
+ const setter = useCallback((value2) => {
55
+ if (typeof value2 === "function") {
56
+ setValue((current) => {
57
+ valueRef.current = value2(current);
58
+ return valueRef.current;
59
+ });
60
+ } else {
61
+ valueRef.current = value2;
62
+ setValue(value2);
44
63
  }
64
+ }, []);
65
+ return [
66
+ value,
67
+ setter,
68
+ valueRef
69
+ ];
70
+ };
71
+ var useDynamicRef = (value) => {
72
+ const valueRef = useRef(value);
73
+ useEffect3(() => {
74
+ valueRef.current = value;
45
75
  }, [
46
- controlledValue,
47
- ...deps
76
+ value
48
77
  ]);
49
- useEffect3(() => {
50
- onChange?.(value);
78
+ return valueRef;
79
+ };
80
+
81
+ // src/useControlledState.ts
82
+ var useControlledState = (valueParam, onChange) => {
83
+ const [value, setControlledValue] = useState3(valueParam);
84
+ useEffect4(() => {
85
+ setControlledValue(valueParam);
51
86
  }, [
52
- value,
53
- onChange
87
+ valueParam
88
+ ]);
89
+ const onChangeRef = useRef2(onChange);
90
+ const valueRef = useDynamicRef(valueParam);
91
+ const setValue = useCallback2((nextValue) => {
92
+ const value2 = isFunction(nextValue) ? nextValue(valueRef.current) : nextValue;
93
+ setControlledValue(value2);
94
+ onChangeRef.current?.(value2);
95
+ }, [
96
+ valueRef,
97
+ onChangeRef
54
98
  ]);
55
99
  return [
56
100
  value,
57
101
  setValue
58
102
  ];
59
103
  };
104
+ function isFunction(value) {
105
+ return typeof value === "function";
106
+ }
60
107
 
61
- // src/useDebugReactDeps.ts
62
- import { useEffect as useEffect4, useRef } from "react";
63
- var useDebugReactDeps = (deps = []) => {
64
- const lastDeps = useRef([]);
65
- useEffect4(() => {
108
+ // src/useDebugDeps.ts
109
+ import { useEffect as useEffect5, useRef as useRef3 } from "react";
110
+ var useDebugDeps = (deps = [], active = true) => {
111
+ const lastDeps = useRef3([]);
112
+ useEffect5(() => {
66
113
  console.group("deps changed", {
67
- old: lastDeps.current.length,
68
- new: deps.length
114
+ previous: lastDeps.current.length,
115
+ current: deps.length
69
116
  });
70
117
  for (let i = 0; i < Math.max(lastDeps.current.length ?? 0, deps.length ?? 0); i++) {
71
- console.log(i, lastDeps.current[i] === deps[i] ? "SAME" : "CHANGED", {
72
- previous: lastDeps.current[i],
73
- current: deps[i]
74
- });
118
+ if (lastDeps.current[i] !== deps[i] && active) {
119
+ console.log("changed", {
120
+ index: i,
121
+ previous: lastDeps.current[i],
122
+ current: deps[i]
123
+ });
124
+ }
75
125
  }
76
126
  console.groupEnd();
77
127
  lastDeps.current = deps;
@@ -79,11 +129,11 @@ var useDebugReactDeps = (deps = []) => {
79
129
  };
80
130
 
81
131
  // src/useDefaultValue.ts
82
- import { useEffect as useEffect5, useMemo, useState as useState3 } from "react";
132
+ import { useEffect as useEffect6, useMemo, useState as useState4 } from "react";
83
133
  var useDefaultValue = (reactiveValue, getDefaultValue) => {
84
134
  const stableDefaultValue = useMemo(getDefaultValue, []);
85
- const [value, setValue] = useState3(reactiveValue ?? stableDefaultValue);
86
- useEffect5(() => {
135
+ const [value, setValue] = useState4(reactiveValue ?? stableDefaultValue);
136
+ useEffect6(() => {
87
137
  setValue(reactiveValue ?? stableDefaultValue);
88
138
  }, [
89
139
  reactiveValue,
@@ -102,18 +152,6 @@ var useDefaults = (value, defaults) => {
102
152
  ]);
103
153
  };
104
154
 
105
- // src/useDynamicRef.ts
106
- import { useEffect as useEffect6, useRef as useRef2 } from "react";
107
- var useDynamicRef = (value) => {
108
- const ref = useRef2(value);
109
- useEffect6(() => {
110
- ref.current = value;
111
- }, [
112
- value
113
- ]);
114
- return ref;
115
- };
116
-
117
155
  // src/useFileDownload.ts
118
156
  import { useMemo as useMemo3 } from "react";
119
157
  var useFileDownload = () => {
@@ -128,38 +166,55 @@ var useFileDownload = () => {
128
166
  };
129
167
 
130
168
  // src/useForwardedRef.ts
131
- import { useEffect as useEffect7, useRef as useRef3 } from "react";
132
- var useForwardedRef = (ref) => {
133
- const innerRef = useRef3(null);
169
+ import { useEffect as useEffect7, useMemo as useMemo4, useRef as useRef4 } from "react";
170
+ var useForwardedRef = (forwardedRef) => {
171
+ const localRef = useRef4(null);
134
172
  useEffect7(() => {
135
- if (!ref) {
136
- return;
137
- }
138
- if (typeof ref === "function") {
139
- ref(innerRef.current);
140
- } else {
141
- ref.current = innerRef.current;
173
+ setRef(forwardedRef, localRef.current);
174
+ }, [
175
+ forwardedRef
176
+ ]);
177
+ return localRef;
178
+ };
179
+ function setRef(ref, value) {
180
+ if (typeof ref === "function") {
181
+ return ref(value);
182
+ } else if (ref) {
183
+ ref.current = value;
184
+ }
185
+ }
186
+ var mergeRefs = (refs) => {
187
+ return (value) => {
188
+ const cleanups = [];
189
+ for (const ref of refs) {
190
+ const cleanup = setRef(ref, value);
191
+ cleanups.push(typeof cleanup === "function" ? cleanup : () => setRef(ref, null));
142
192
  }
143
- });
144
- return innerRef;
193
+ return () => {
194
+ for (const cleanup of cleanups) cleanup();
195
+ };
196
+ };
197
+ };
198
+ var useMergeRefs = (refs) => {
199
+ return useMemo4(() => mergeRefs(refs), refs);
145
200
  };
146
201
 
147
202
  // src/useId.ts
148
203
  import alea from "alea";
149
- import { useMemo as useMemo4 } from "react";
204
+ import { useMemo as useMemo5 } from "react";
150
205
  var Alea = alea;
151
206
  var prng = new Alea("@dxos/react-hooks");
152
207
  var randomString = (n = 4) => prng().toString(16).slice(2, n + 2);
153
- var useId = (namespace, propsId, opts) => useMemo4(() => makeId(namespace, propsId, opts), [
208
+ var useId = (namespace, propsId, opts) => useMemo5(() => makeId(namespace, propsId, opts), [
154
209
  propsId
155
210
  ]);
156
211
  var makeId = (namespace, propsId, opts) => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`;
157
212
 
158
213
  // src/useIsFocused.ts
159
- import { useEffect as useEffect8, useRef as useRef4, useState as useState4 } from "react";
214
+ import { useEffect as useEffect8, useRef as useRef5, useState as useState5 } from "react";
160
215
  var useIsFocused = (inputRef) => {
161
- const [isFocused, setIsFocused] = useState4(void 0);
162
- const isFocusedRef = useRef4(isFocused);
216
+ const [isFocused, setIsFocused] = useState5(void 0);
217
+ const isFocusedRef = useRef5(isFocused);
163
218
  isFocusedRef.current = isFocused;
164
219
  useEffect8(() => {
165
220
  const input = inputRef.current;
@@ -185,7 +240,7 @@ var useIsFocused = (inputRef) => {
185
240
  };
186
241
 
187
242
  // src/useMediaQuery.ts
188
- import { useEffect as useEffect9, useState as useState5 } from "react";
243
+ import { useEffect as useEffect9, useState as useState6 } from "react";
189
244
  var breakpointMediaQueries = {
190
245
  sm: "(min-width: 640px)",
191
246
  md: "(min-width: 768px)",
@@ -194,7 +249,7 @@ var breakpointMediaQueries = {
194
249
  "2xl": "(min-width: 1536px)"
195
250
  };
196
251
  var useMediaQuery = (query, options = {}) => {
197
- const { ssr = true, fallback } = options;
252
+ const { ssr = false, fallback } = options;
198
253
  const queries = (Array.isArray(query) ? query : [
199
254
  query
200
255
  ]).map((query2) => query2 in breakpointMediaQueries ? breakpointMediaQueries[query2] : query2);
@@ -202,7 +257,7 @@ var useMediaQuery = (query, options = {}) => {
202
257
  fallback
203
258
  ];
204
259
  fallbackValues = fallbackValues.filter((v) => v != null);
205
- const [value, setValue] = useState5(() => {
260
+ const [value, setValue] = useState6(() => {
206
261
  return queries.map((query2, index) => ({
207
262
  media: query2,
208
263
  matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query2).matches
@@ -250,9 +305,9 @@ var useMediaQuery = (query, options = {}) => {
250
305
  };
251
306
 
252
307
  // src/useMulticastObservable.ts
253
- import { useMemo as useMemo5, useSyncExternalStore } from "react";
308
+ import { useMemo as useMemo6, useSyncExternalStore } from "react";
254
309
  var useMulticastObservable = (observable) => {
255
- const subscribeFn = useMemo5(() => (listener) => {
310
+ const subscribeFn = useMemo6(() => (listener) => {
256
311
  const subscription = observable.subscribe(listener);
257
312
  return () => subscription.unsubscribe();
258
313
  }, [
@@ -262,19 +317,19 @@ var useMulticastObservable = (observable) => {
262
317
  };
263
318
 
264
319
  // src/useRefCallback.ts
265
- import { useState as useState6 } from "react";
320
+ import { useState as useState7 } from "react";
266
321
  var useRefCallback = () => {
267
- const [value, setValue] = useState6(null);
322
+ const [value, setValue] = useState7(null);
268
323
  return {
269
324
  refCallback: (value2) => setValue(value2),
270
325
  value
271
326
  };
272
327
  };
273
328
 
274
- // src/useResize.ts
275
- import { useLayoutEffect, useMemo as useMemo6 } from "react";
276
- var useResize = (handler, deps = [], delay = 800) => {
277
- const debouncedHandler = useMemo6(() => {
329
+ // src/useViewportResize.ts
330
+ import { useLayoutEffect, useMemo as useMemo7 } from "react";
331
+ var useViewportResize = (handler, deps = [], delay = 800) => {
332
+ const debouncedHandler = useMemo7(() => {
278
333
  let timeout;
279
334
  return (event) => {
280
335
  clearTimeout(timeout);
@@ -296,70 +351,84 @@ var useResize = (handler, deps = [], delay = 800) => {
296
351
  ]);
297
352
  };
298
353
 
354
+ // src/useSignals.ts
355
+ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
356
+ import { computed, effect } from "@preact-signals/safe-react";
357
+ import { useRef as useRef6 } from "@preact-signals/safe-react/react";
358
+ import { useEffect as useEffect10, useMemo as useMemo8 } from "react";
359
+ var useSignalsEffect = (cb, deps) => {
360
+ const callback = useRef6(cb);
361
+ callback.current = cb;
362
+ useEffect10(() => {
363
+ return effect(() => {
364
+ return callback.current();
365
+ });
366
+ }, deps ?? []);
367
+ };
368
+ var useSignalsMemo = (cb, deps) => {
369
+ var _effect = _useSignals();
370
+ try {
371
+ return useMemo8(() => computed(cb), deps ?? []).value;
372
+ } finally {
373
+ _effect.f();
374
+ }
375
+ };
376
+
299
377
  // src/useTimeout.ts
300
- import { useEffect as useEffect10, useRef as useRef5 } from "react";
378
+ import { useEffect as useEffect11, useRef as useRef7 } from "react";
301
379
  var useTimeout = (callback, delay = 0, deps = []) => {
302
- const callbackRef = useRef5(callback);
303
- useEffect10(() => {
380
+ const callbackRef = useRef7(callback);
381
+ useEffect11(() => {
304
382
  callbackRef.current = callback;
305
383
  }, [
306
384
  callback
307
385
  ]);
308
- useEffect10(() => {
386
+ useEffect11(() => {
309
387
  if (delay == null) {
310
388
  return;
311
389
  }
312
- const timeout = setTimeout(() => callbackRef.current?.(), delay);
313
- return () => clearTimeout(timeout);
390
+ const t = setTimeout(() => callbackRef.current?.(), delay);
391
+ return () => clearTimeout(t);
314
392
  }, [
315
393
  delay,
316
394
  ...deps
317
395
  ]);
318
396
  };
319
-
320
- // src/useTrackProps.ts
321
- import { useEffect as useEffect11, useRef as useRef6 } from "react";
322
- import { log } from "@dxos/log";
323
- var __dxlog_file = "/__w/dxos/dxos/packages/ui/primitives/react-hooks/src/useTrackProps.ts";
324
- var useTrackProps = (props, componentName = "Component", active = true) => {
325
- const prevProps = useRef6(props);
397
+ var useInterval = (callback, delay = 0, deps = []) => {
398
+ const callbackRef = useRef7(callback);
326
399
  useEffect11(() => {
327
- const changes = Object.entries(props).filter(([key]) => props[key] !== prevProps.current[key]);
328
- if (changes.length > 0) {
329
- if (active) {
330
- log.info("props changed", {
331
- componentName,
332
- keys: changes.map(([key]) => key).join(","),
333
- props: Object.fromEntries(changes.map(([key]) => [
334
- key,
335
- {
336
- from: prevProps.current[key],
337
- to: props[key]
338
- }
339
- ]))
340
- }, {
341
- F: __dxlog_file,
342
- L: 22,
343
- S: void 0,
344
- C: (f, a) => f(...a)
345
- });
346
- }
400
+ callbackRef.current = callback;
401
+ }, [
402
+ callback
403
+ ]);
404
+ useEffect11(() => {
405
+ if (delay == null) {
406
+ return;
347
407
  }
348
- prevProps.current = props;
349
- });
408
+ const i = setInterval(async () => {
409
+ const result = await callbackRef.current?.();
410
+ if (result === false) {
411
+ clearInterval(i);
412
+ }
413
+ }, delay);
414
+ return () => clearInterval(i);
415
+ }, [
416
+ delay,
417
+ ...deps
418
+ ]);
350
419
  };
351
420
 
352
421
  // src/useTransitions.ts
353
- import { useEffect as useEffect12, useRef as useRef7, useState as useState7 } from "react";
354
- var isFunction = (functionToCheck) => {
422
+ import { useEffect as useEffect12, useRef as useRef8, useState as useState8 } from "react";
423
+ var isFunction2 = (functionToCheck) => {
355
424
  return functionToCheck instanceof Function;
356
425
  };
357
426
  var useDidTransition = (currentValue, fromValue, toValue) => {
358
- const [hasTransitioned, setHasTransitioned] = useState7(false);
359
- const previousValue = useRef7(currentValue);
427
+ const [hasTransitioned, setHasTransitioned] = useState8(false);
428
+ const previousValue = useRef8(currentValue);
360
429
  useEffect12(() => {
361
- const toValueValid = isFunction(toValue) ? toValue(currentValue) : toValue === currentValue;
362
- const fromValueValid = isFunction(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
430
+ const toValueValid = isFunction2(toValue) ? toValue(currentValue) : toValue === currentValue;
431
+ const fromValueValid = isFunction2(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
363
432
  if (fromValueValid && toValueValid && !hasTransitioned) {
364
433
  setHasTransitioned(true);
365
434
  } else if ((!fromValueValid || !toValueValid) && hasTransitioned) {
@@ -375,7 +444,7 @@ var useDidTransition = (currentValue, fromValue, toValue) => {
375
444
  return hasTransitioned;
376
445
  };
377
446
  var useOnTransition = (currentValue, fromValue, toValue, callback) => {
378
- const dirty = useRef7(false);
447
+ const dirty = useRef8(false);
379
448
  const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);
380
449
  useEffect12(() => {
381
450
  dirty.current = false;
@@ -394,13 +463,18 @@ var useOnTransition = (currentValue, fromValue, toValue, callback) => {
394
463
  callback
395
464
  ]);
396
465
  };
466
+
467
+ // src/index.ts
468
+ import { useSize, useScroller } from "mini-virtual-list";
397
469
  export {
398
470
  makeId,
471
+ mergeRefs,
399
472
  randomString,
473
+ setRef,
400
474
  useAsyncEffect,
401
475
  useAsyncState,
402
476
  useControlledState,
403
- useDebugReactDeps,
477
+ useDebugDeps,
404
478
  useDefaultValue,
405
479
  useDefaults,
406
480
  useDidTransition,
@@ -408,13 +482,19 @@ export {
408
482
  useFileDownload,
409
483
  useForwardedRef,
410
484
  useId,
485
+ useInterval,
411
486
  useIsFocused,
412
487
  useMediaQuery,
488
+ useMergeRefs,
413
489
  useMulticastObservable,
414
490
  useOnTransition,
415
491
  useRefCallback,
416
- useResize,
492
+ useScroller,
493
+ useSignalsEffect,
494
+ useSignalsMemo,
495
+ useSize,
496
+ useStateWithRef,
417
497
  useTimeout,
418
- useTrackProps
498
+ useViewportResize
419
499
  };
420
500
  //# sourceMappingURL=index.mjs.map