@dxos/react-hooks 0.8.4-main.406dc2a → 0.8.4-main.422d1c7879

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 (40) hide show
  1. package/README.md +1 -0
  2. package/dist/lib/browser/index.mjs +171 -141
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node-esm/index.mjs +171 -141
  6. package/dist/lib/node-esm/index.mjs.map +4 -4
  7. package/dist/lib/node-esm/meta.json +1 -1
  8. package/dist/types/src/index.d.ts +3 -2
  9. package/dist/types/src/index.d.ts.map +1 -1
  10. package/dist/types/src/useAtomState.d.ts +12 -0
  11. package/dist/types/src/useAtomState.d.ts.map +1 -0
  12. package/dist/types/src/useControlledState.d.ts +2 -3
  13. package/dist/types/src/useControlledState.d.ts.map +1 -1
  14. package/dist/types/src/useDebugDeps.d.ts +1 -1
  15. package/dist/types/src/useDebugDeps.d.ts.map +1 -1
  16. package/dist/types/src/useDynamicRef.d.ts +3 -3
  17. package/dist/types/src/useDynamicRef.d.ts.map +1 -1
  18. package/dist/types/src/useForwardedRef.d.ts +23 -3
  19. package/dist/types/src/useForwardedRef.d.ts.map +1 -1
  20. package/dist/types/src/useId.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/useViewportResize.d.ts +1 -1
  24. package/dist/types/src/useViewportResize.d.ts.map +1 -1
  25. package/dist/types/tsconfig.tsbuildinfo +1 -1
  26. package/package.json +17 -14
  27. package/src/index.ts +4 -3
  28. package/src/useAtomState.ts +23 -0
  29. package/src/useControlledState.ts +22 -13
  30. package/src/useDebugDeps.ts +17 -8
  31. package/src/useDynamicRef.ts +5 -6
  32. package/src/useForwardedRef.ts +45 -13
  33. package/src/useId.ts +3 -2
  34. package/src/useIsFocused.ts +1 -1
  35. package/src/useMediaQuery.ts +7 -7
  36. package/src/useMulticastObservable.test.ts +1 -1
  37. package/src/useViewportResize.ts +3 -3
  38. package/dist/types/src/useSignals.d.ts +0 -10
  39. package/dist/types/src/useSignals.d.ts.map +0 -1
  40. package/src/useSignals.ts +0 -27
@@ -1,5 +1,9 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
+ // src/index.ts
4
+ import { useComposedRefs } from "@radix-ui/react-compose-refs";
5
+ import { useSize, useScroller } from "mini-virtual-list";
6
+
3
7
  // src/useAsyncEffect.ts
4
8
  import { useEffect } from "react";
5
9
  var useAsyncEffect = (cb, deps) => {
@@ -19,10 +23,28 @@ var useAsyncEffect = (cb, deps) => {
19
23
  }, deps ?? []);
20
24
  };
21
25
 
26
+ // src/useAtomState.ts
27
+ import { Atom, useAtomSet, useAtomValue } from "@effect-atom/atom-react";
28
+ import { useMemo, useState } from "react";
29
+ var useAtomState = (initialValue) => {
30
+ const [atom] = useState(() => Atom.make(initialValue));
31
+ const value = useAtomValue(atom);
32
+ const set = useAtomSet(atom);
33
+ return useMemo(() => ({
34
+ atom,
35
+ value,
36
+ set
37
+ }), [
38
+ atom,
39
+ value,
40
+ set
41
+ ]);
42
+ };
43
+
22
44
  // src/useAsyncState.ts
23
- import { useEffect as useEffect2, useState } from "react";
45
+ import { useEffect as useEffect2, useState as useState2 } from "react";
24
46
  var useAsyncState = (cb, deps = []) => {
25
- const [value, setValue] = useState();
47
+ const [value, setValue] = useState2();
26
48
  useEffect2(() => {
27
49
  let disposed = false;
28
50
  const t = setTimeout(async () => {
@@ -43,58 +65,107 @@ var useAsyncState = (cb, deps = []) => {
43
65
  };
44
66
 
45
67
  // src/useControlledState.ts
46
- import { useEffect as useEffect3, useState as useState2 } from "react";
47
- var useControlledState = (controlledValue, onChange, ...deps) => {
48
- const [value, setValue] = useState2(controlledValue);
49
- useEffect3(() => {
50
- if (controlledValue !== void 0) {
51
- setValue(controlledValue);
68
+ import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2, useState as useState4 } from "react";
69
+
70
+ // src/useDynamicRef.ts
71
+ import { useCallback, useEffect as useEffect3, useRef, useState as useState3 } from "react";
72
+ var useStateWithRef = (valueProp) => {
73
+ const [value, setValue] = useState3(valueProp);
74
+ const valueRef = useRef(valueProp);
75
+ const setter = useCallback((value2) => {
76
+ if (typeof value2 === "function") {
77
+ setValue((current) => {
78
+ valueRef.current = value2(current);
79
+ return valueRef.current;
80
+ });
81
+ } else {
82
+ valueRef.current = value2;
83
+ setValue(value2);
52
84
  }
85
+ }, []);
86
+ return [
87
+ value,
88
+ setter,
89
+ valueRef
90
+ ];
91
+ };
92
+ var useDynamicRef = (value) => {
93
+ const valueRef = useRef(value);
94
+ useEffect3(() => {
95
+ valueRef.current = value;
53
96
  }, [
54
- controlledValue,
55
- ...deps
97
+ value
56
98
  ]);
57
- useEffect3(() => {
58
- onChange?.(value);
99
+ return valueRef;
100
+ };
101
+
102
+ // src/useControlledState.ts
103
+ var useControlledState = (valueProp, onChange) => {
104
+ const [value, setControlledValue] = useState4(valueProp);
105
+ useEffect4(() => {
106
+ setControlledValue(valueProp);
59
107
  }, [
60
- value,
61
- onChange
108
+ valueProp
109
+ ]);
110
+ const onChangeRef = useRef2(onChange);
111
+ const valueRef = useDynamicRef(valueProp);
112
+ const setValue = useCallback2((nextValue) => {
113
+ const value2 = isFunction(nextValue) ? nextValue(valueRef.current) : nextValue;
114
+ setControlledValue(value2);
115
+ onChangeRef.current?.(value2);
116
+ }, [
117
+ valueRef,
118
+ onChangeRef
62
119
  ]);
63
120
  return [
64
121
  value,
65
122
  setValue
66
123
  ];
67
124
  };
125
+ function isFunction(value) {
126
+ return typeof value === "function";
127
+ }
68
128
 
69
129
  // src/useDebugDeps.ts
70
- import { useEffect as useEffect4, useRef } from "react";
71
- var useDebugDeps = (deps = [], active = true) => {
72
- const lastDeps = useRef([]);
73
- useEffect4(() => {
74
- console.group("deps changed", {
75
- previous: lastDeps.current.length,
76
- current: deps.length
77
- });
130
+ import { useEffect as useEffect5, useRef as useRef3 } from "react";
131
+ import { log } from "@dxos/log";
132
+ var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-primitives/react-hooks/src/useDebugDeps.ts";
133
+ var useDebugDeps = (deps = [], label = "useDebugDeps", active = true) => {
134
+ const lastDeps = useRef3([]);
135
+ useEffect5(() => {
136
+ if (!active) {
137
+ return;
138
+ }
139
+ const diff = {};
78
140
  for (let i = 0; i < Math.max(lastDeps.current.length ?? 0, deps.length ?? 0); i++) {
79
- if (lastDeps.current[i] !== deps[i] && active) {
80
- console.log("changed", {
81
- index: i,
141
+ if (lastDeps.current[i] !== deps[i] || i > lastDeps.current.length) {
142
+ diff[i] = {
82
143
  previous: lastDeps.current[i],
83
144
  current: deps[i]
84
- });
145
+ };
85
146
  }
86
147
  }
87
- console.groupEnd();
148
+ if (Object.keys(diff).length > 0) {
149
+ log.warn(`Updated: ${label} [${lastDeps.current.length}/${deps.length}]`, diff, {
150
+ F: __dxlog_file,
151
+ L: 30,
152
+ S: void 0,
153
+ C: (f, a) => f(...a)
154
+ });
155
+ }
88
156
  lastDeps.current = deps;
89
- }, deps);
157
+ }, [
158
+ ...deps,
159
+ active
160
+ ]);
90
161
  };
91
162
 
92
163
  // src/useDefaultValue.ts
93
- import { useEffect as useEffect5, useMemo, useState as useState3 } from "react";
164
+ import { useEffect as useEffect6, useMemo as useMemo2, useState as useState5 } from "react";
94
165
  var useDefaultValue = (reactiveValue, getDefaultValue) => {
95
- const stableDefaultValue = useMemo(getDefaultValue, []);
96
- const [value, setValue] = useState3(reactiveValue ?? stableDefaultValue);
97
- useEffect5(() => {
166
+ const stableDefaultValue = useMemo2(getDefaultValue, []);
167
+ const [value, setValue] = useState5(reactiveValue ?? stableDefaultValue);
168
+ useEffect6(() => {
98
169
  setValue(reactiveValue ?? stableDefaultValue);
99
170
  }, [
100
171
  reactiveValue,
@@ -105,51 +176,18 @@ var useDefaultValue = (reactiveValue, getDefaultValue) => {
105
176
 
106
177
  // src/useDefaults.ts
107
178
  import defaultsDeep from "lodash.defaultsdeep";
108
- import { useMemo as useMemo2 } from "react";
179
+ import { useMemo as useMemo3 } from "react";
109
180
  var useDefaults = (value, defaults) => {
110
- return useMemo2(() => defaultsDeep({}, defaults, value), [
181
+ return useMemo3(() => defaultsDeep({}, defaults, value), [
111
182
  value,
112
183
  defaults
113
184
  ]);
114
185
  };
115
186
 
116
- // src/useDynamicRef.ts
117
- import { useCallback } from "@preact-signals/safe-react/react";
118
- import { useEffect as useEffect6, useRef as useRef2, useState as useState4 } from "react";
119
- var useStateWithRef = (valueParam) => {
120
- const [value, setValue] = useState4(valueParam);
121
- const valueRef = useRef2(valueParam);
122
- const setter = useCallback((value2) => {
123
- if (typeof value2 === "function") {
124
- setValue((current) => {
125
- valueRef.current = value2(current);
126
- return valueRef.current;
127
- });
128
- } else {
129
- valueRef.current = value2;
130
- setValue(value2);
131
- }
132
- }, []);
133
- return [
134
- value,
135
- setter,
136
- valueRef
137
- ];
138
- };
139
- var useDynamicRef = (value) => {
140
- const valueRef = useRef2(value);
141
- useEffect6(() => {
142
- valueRef.current = value;
143
- }, [
144
- value
145
- ]);
146
- return valueRef;
147
- };
148
-
149
187
  // src/useFileDownload.ts
150
- import { useMemo as useMemo3 } from "react";
188
+ import { useMemo as useMemo4 } from "react";
151
189
  var useFileDownload = () => {
152
- return useMemo3(() => (data, filename) => {
190
+ return useMemo4(() => (data, filename) => {
153
191
  const url = typeof data === "string" ? data : URL.createObjectURL(data);
154
192
  const element = document.createElement("a");
155
193
  element.setAttribute("href", url);
@@ -160,43 +198,59 @@ var useFileDownload = () => {
160
198
  };
161
199
 
162
200
  // src/useForwardedRef.ts
163
- import { useEffect as useEffect7, useRef as useRef3 } from "react";
164
- var useForwardedRef = (ref) => {
165
- const innerRef = useRef3(null);
201
+ import { useEffect as useEffect7, useMemo as useMemo5, useRef as useRef4 } from "react";
202
+ var useForwardedRef = (forwardedRef) => {
203
+ const localRef = useRef4(null);
166
204
  useEffect7(() => {
167
- updateRef(ref, innerRef.current);
205
+ setRef(forwardedRef, localRef.current);
168
206
  }, [
169
- ref
207
+ forwardedRef
170
208
  ]);
171
- return innerRef;
209
+ return localRef;
172
210
  };
173
- var updateRef = (ref, value) => {
174
- if (!ref) {
175
- return;
176
- }
211
+ function setRef(ref, value) {
177
212
  if (typeof ref === "function") {
178
- ref(value);
179
- } else {
213
+ return ref(value);
214
+ } else if (ref) {
180
215
  ref.current = value;
181
216
  }
217
+ }
218
+ var mergeRefs = (refs) => {
219
+ return (value) => {
220
+ const cleanups = [];
221
+ for (const ref of refs) {
222
+ const cleanup = setRef(ref, value);
223
+ cleanups.push(typeof cleanup === "function" ? cleanup : () => setRef(ref, null));
224
+ }
225
+ return () => {
226
+ for (const cleanup of cleanups) cleanup();
227
+ };
228
+ };
229
+ };
230
+ var useMergeRefs = (refs) => {
231
+ return useMemo5(() => mergeRefs(refs), [
232
+ ...refs
233
+ ]);
182
234
  };
183
235
 
184
236
  // src/useId.ts
185
237
  import alea from "alea";
186
- import { useMemo as useMemo4 } from "react";
238
+ import { useMemo as useMemo6 } from "react";
187
239
  var Alea = alea;
188
240
  var prng = new Alea("@dxos/react-hooks");
189
241
  var randomString = (n = 4) => prng().toString(16).slice(2, n + 2);
190
- var useId = (namespace, propsId, opts) => useMemo4(() => makeId(namespace, propsId, opts), [
191
- propsId
192
- ]);
242
+ var useId = (namespace, propsId, opts) => {
243
+ return useMemo6(() => makeId(namespace, propsId, opts), [
244
+ propsId
245
+ ]);
246
+ };
193
247
  var makeId = (namespace, propsId, opts) => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`;
194
248
 
195
249
  // src/useIsFocused.ts
196
- import { useEffect as useEffect8, useRef as useRef4, useState as useState5 } from "react";
250
+ import { useEffect as useEffect8, useRef as useRef5, useState as useState6 } from "react";
197
251
  var useIsFocused = (inputRef) => {
198
- const [isFocused, setIsFocused] = useState5(void 0);
199
- const isFocusedRef = useRef4(isFocused);
252
+ const [isFocused, setIsFocused] = useState6(void 0);
253
+ const isFocusedRef = useRef5(isFocused);
200
254
  isFocusedRef.current = isFocused;
201
255
  useEffect8(() => {
202
256
  const input = inputRef.current;
@@ -222,7 +276,7 @@ var useIsFocused = (inputRef) => {
222
276
  };
223
277
 
224
278
  // src/useMediaQuery.ts
225
- import { useEffect as useEffect9, useState as useState6 } from "react";
279
+ import { useEffect as useEffect9, useState as useState7 } from "react";
226
280
  var breakpointMediaQueries = {
227
281
  sm: "(min-width: 640px)",
228
282
  md: "(min-width: 768px)",
@@ -239,7 +293,7 @@ var useMediaQuery = (query, options = {}) => {
239
293
  fallback
240
294
  ];
241
295
  fallbackValues = fallbackValues.filter((v) => v != null);
242
- const [value, setValue] = useState6(() => {
296
+ const [value, setValue] = useState7(() => {
243
297
  return queries.map((query2, index) => ({
244
298
  media: query2,
245
299
  matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query2).matches
@@ -287,9 +341,9 @@ var useMediaQuery = (query, options = {}) => {
287
341
  };
288
342
 
289
343
  // src/useMulticastObservable.ts
290
- import { useMemo as useMemo5, useSyncExternalStore } from "react";
344
+ import { useMemo as useMemo7, useSyncExternalStore } from "react";
291
345
  var useMulticastObservable = (observable) => {
292
- const subscribeFn = useMemo5(() => (listener) => {
346
+ const subscribeFn = useMemo7(() => (listener) => {
293
347
  const subscription = observable.subscribe(listener);
294
348
  return () => subscription.unsubscribe();
295
349
  }, [
@@ -299,9 +353,9 @@ var useMulticastObservable = (observable) => {
299
353
  };
300
354
 
301
355
  // src/useRefCallback.ts
302
- import { useState as useState7 } from "react";
356
+ import { useState as useState8 } from "react";
303
357
  var useRefCallback = () => {
304
- const [value, setValue] = useState7(null);
358
+ const [value, setValue] = useState8(null);
305
359
  return {
306
360
  refCallback: (value2) => setValue(value2),
307
361
  value
@@ -309,18 +363,18 @@ var useRefCallback = () => {
309
363
  };
310
364
 
311
365
  // src/useViewportResize.ts
312
- import { useLayoutEffect, useMemo as useMemo6 } from "react";
313
- var useViewportResize = (handler, deps = [], delay = 800) => {
314
- const debouncedHandler = useMemo6(() => {
366
+ import { useLayoutEffect, useMemo as useMemo8 } from "react";
367
+ var useViewportResize = (cb, deps = [], delay = 800) => {
368
+ const debouncedHandler = useMemo8(() => {
315
369
  let timeout;
316
370
  return (event) => {
317
371
  clearTimeout(timeout);
318
372
  timeout = setTimeout(() => {
319
- handler(event);
373
+ cb(event);
320
374
  }, delay);
321
375
  };
322
376
  }, [
323
- handler,
377
+ cb,
324
378
  delay
325
379
  ]);
326
380
  return useLayoutEffect(() => {
@@ -333,39 +387,16 @@ var useViewportResize = (handler, deps = [], delay = 800) => {
333
387
  ]);
334
388
  };
335
389
 
336
- // src/useSignals.ts
337
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
338
- import { computed, effect } from "@preact-signals/safe-react";
339
- import { useRef as useRef5 } from "@preact-signals/safe-react/react";
340
- import { useEffect as useEffect10, useMemo as useMemo7 } from "react";
341
- var useSignalsEffect = (cb, deps) => {
342
- const callback = useRef5(cb);
343
- callback.current = cb;
344
- useEffect10(() => {
345
- return effect(() => {
346
- return callback.current();
347
- });
348
- }, deps ?? []);
349
- };
350
- var useSignalsMemo = (cb, deps) => {
351
- var _effect = _useSignals();
352
- try {
353
- return useMemo7(() => computed(cb), deps ?? []).value;
354
- } finally {
355
- _effect.f();
356
- }
357
- };
358
-
359
390
  // src/useTimeout.ts
360
- import { useEffect as useEffect11, useRef as useRef6 } from "react";
391
+ import { useEffect as useEffect10, useRef as useRef6 } from "react";
361
392
  var useTimeout = (callback, delay = 0, deps = []) => {
362
393
  const callbackRef = useRef6(callback);
363
- useEffect11(() => {
394
+ useEffect10(() => {
364
395
  callbackRef.current = callback;
365
396
  }, [
366
397
  callback
367
398
  ]);
368
- useEffect11(() => {
399
+ useEffect10(() => {
369
400
  if (delay == null) {
370
401
  return;
371
402
  }
@@ -378,12 +409,12 @@ var useTimeout = (callback, delay = 0, deps = []) => {
378
409
  };
379
410
  var useInterval = (callback, delay = 0, deps = []) => {
380
411
  const callbackRef = useRef6(callback);
381
- useEffect11(() => {
412
+ useEffect10(() => {
382
413
  callbackRef.current = callback;
383
414
  }, [
384
415
  callback
385
416
  ]);
386
- useEffect11(() => {
417
+ useEffect10(() => {
387
418
  if (delay == null) {
388
419
  return;
389
420
  }
@@ -401,16 +432,16 @@ var useInterval = (callback, delay = 0, deps = []) => {
401
432
  };
402
433
 
403
434
  // src/useTransitions.ts
404
- import { useEffect as useEffect12, useRef as useRef7, useState as useState8 } from "react";
405
- var isFunction = (functionToCheck) => {
435
+ import { useEffect as useEffect11, useRef as useRef7, useState as useState9 } from "react";
436
+ var isFunction2 = (functionToCheck) => {
406
437
  return functionToCheck instanceof Function;
407
438
  };
408
439
  var useDidTransition = (currentValue, fromValue, toValue) => {
409
- const [hasTransitioned, setHasTransitioned] = useState8(false);
440
+ const [hasTransitioned, setHasTransitioned] = useState9(false);
410
441
  const previousValue = useRef7(currentValue);
411
- useEffect12(() => {
412
- const toValueValid = isFunction(toValue) ? toValue(currentValue) : toValue === currentValue;
413
- const fromValueValid = isFunction(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
442
+ useEffect11(() => {
443
+ const toValueValid = isFunction2(toValue) ? toValue(currentValue) : toValue === currentValue;
444
+ const fromValueValid = isFunction2(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
414
445
  if (fromValueValid && toValueValid && !hasTransitioned) {
415
446
  setHasTransitioned(true);
416
447
  } else if ((!fromValueValid || !toValueValid) && hasTransitioned) {
@@ -428,13 +459,13 @@ var useDidTransition = (currentValue, fromValue, toValue) => {
428
459
  var useOnTransition = (currentValue, fromValue, toValue, callback) => {
429
460
  const dirty = useRef7(false);
430
461
  const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);
431
- useEffect12(() => {
462
+ useEffect11(() => {
432
463
  dirty.current = false;
433
464
  }, [
434
465
  currentValue,
435
466
  dirty
436
467
  ]);
437
- useEffect12(() => {
468
+ useEffect11(() => {
438
469
  if (hasTransitioned && !dirty.current) {
439
470
  callback();
440
471
  dirty.current = true;
@@ -445,15 +476,15 @@ var useOnTransition = (currentValue, fromValue, toValue, callback) => {
445
476
  callback
446
477
  ]);
447
478
  };
448
-
449
- // src/index.ts
450
- import { useSize, useScroller } from "mini-virtual-list";
451
479
  export {
452
480
  makeId,
481
+ mergeRefs,
453
482
  randomString,
454
- updateRef,
483
+ setRef,
455
484
  useAsyncEffect,
456
485
  useAsyncState,
486
+ useAtomState,
487
+ useComposedRefs,
457
488
  useControlledState,
458
489
  useDebugDeps,
459
490
  useDefaultValue,
@@ -466,12 +497,11 @@ export {
466
497
  useInterval,
467
498
  useIsFocused,
468
499
  useMediaQuery,
500
+ useMergeRefs,
469
501
  useMulticastObservable,
470
502
  useOnTransition,
471
503
  useRefCallback,
472
504
  useScroller,
473
- useSignalsEffect,
474
- useSignalsMemo,
475
505
  useSize,
476
506
  useStateWithRef,
477
507
  useTimeout,