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