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