@dxos/react-hooks 0.8.4-main.a4bbb77 → 0.8.4-main.abd8ff62ef

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 (52) hide show
  1. package/README.md +1 -0
  2. package/dist/lib/browser/index.mjs +179 -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 +179 -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 +4 -2
  9. package/dist/types/src/index.d.ts.map +1 -1
  10. package/dist/types/src/useAsyncEffect.d.ts.map +1 -1
  11. package/dist/types/src/useAsyncState.d.ts.map +1 -1
  12. package/dist/types/src/useAtomState.d.ts +12 -0
  13. package/dist/types/src/useAtomState.d.ts.map +1 -0
  14. package/dist/types/src/useControlledState.d.ts +2 -2
  15. package/dist/types/src/useControlledState.d.ts.map +1 -1
  16. package/dist/types/src/useDebugDeps.d.ts +1 -1
  17. package/dist/types/src/useDebugDeps.d.ts.map +1 -1
  18. package/dist/types/src/useDefaultValue.d.ts.map +1 -1
  19. package/dist/types/src/useDefaults.d.ts.map +1 -1
  20. package/dist/types/src/useDynamicRef.d.ts +3 -3
  21. package/dist/types/src/useDynamicRef.d.ts.map +1 -1
  22. package/dist/types/src/useForwardedRef.d.ts +23 -3
  23. package/dist/types/src/useForwardedRef.d.ts.map +1 -1
  24. package/dist/types/src/useId.d.ts.map +1 -1
  25. package/dist/types/src/useIsFocused.d.ts.map +1 -1
  26. package/dist/types/src/useMediaQuery.d.ts +1 -1
  27. package/dist/types/src/useMediaQuery.d.ts.map +1 -1
  28. package/dist/types/src/useMulticastObservable.d.ts.map +1 -1
  29. package/dist/types/src/useTimeout.d.ts.map +1 -1
  30. package/dist/types/src/useTransitions.d.ts +2 -1
  31. package/dist/types/src/useTransitions.d.ts.map +1 -1
  32. package/dist/types/src/useViewportResize.d.ts +3 -0
  33. package/dist/types/src/useViewportResize.d.ts.map +1 -0
  34. package/dist/types/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +18 -14
  36. package/src/index.ts +5 -2
  37. package/src/useAtomState.ts +23 -0
  38. package/src/useControlledState.ts +22 -12
  39. package/src/useDebugDeps.ts +17 -8
  40. package/src/useDynamicRef.ts +5 -6
  41. package/src/useForwardedRef.ts +50 -13
  42. package/src/useId.ts +3 -2
  43. package/src/useIsFocused.ts +1 -1
  44. package/src/useMediaQuery.ts +8 -9
  45. package/src/useMulticastObservable.test.ts +1 -1
  46. package/src/useTransitions.ts +3 -1
  47. package/src/{useResize.ts → useViewportResize.ts} +4 -4
  48. package/dist/types/src/useResize.d.ts +0 -3
  49. package/dist/types/src/useResize.d.ts.map +0 -1
  50. package/dist/types/src/useSignals.d.ts +0 -10
  51. package/dist/types/src/useSignals.d.ts.map +0 -1
  52. 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,102 @@ 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, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 24, S: void 0 });
150
+ }
88
151
  lastDeps.current = deps;
89
- }, deps);
152
+ }, [
153
+ ...deps,
154
+ active
155
+ ]);
90
156
  };
91
157
 
92
158
  // src/useDefaultValue.ts
93
- import { useEffect as useEffect5, useMemo, useState as useState3 } from "react";
159
+ import { useEffect as useEffect6, useMemo as useMemo2, useState as useState5 } from "react";
94
160
  var useDefaultValue = (reactiveValue, getDefaultValue) => {
95
- const stableDefaultValue = useMemo(getDefaultValue, []);
96
- const [value, setValue] = useState3(reactiveValue ?? stableDefaultValue);
97
- useEffect5(() => {
161
+ const stableDefaultValue = useMemo2(getDefaultValue, []);
162
+ const [value, setValue] = useState5(reactiveValue ?? stableDefaultValue);
163
+ useEffect6(() => {
98
164
  setValue(reactiveValue ?? stableDefaultValue);
99
165
  }, [
100
166
  reactiveValue,
@@ -105,51 +171,18 @@ var useDefaultValue = (reactiveValue, getDefaultValue) => {
105
171
 
106
172
  // src/useDefaults.ts
107
173
  import defaultsDeep from "lodash.defaultsdeep";
108
- import { useMemo as useMemo2 } from "react";
174
+ import { useMemo as useMemo3 } from "react";
109
175
  var useDefaults = (value, defaults) => {
110
- return useMemo2(() => defaultsDeep({}, defaults, value), [
176
+ return useMemo3(() => defaultsDeep({}, defaults, value), [
111
177
  value,
112
178
  defaults
113
179
  ]);
114
180
  };
115
181
 
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
182
  // src/useFileDownload.ts
150
- import { useMemo as useMemo3 } from "react";
183
+ import { useMemo as useMemo4 } from "react";
151
184
  var useFileDownload = () => {
152
- return useMemo3(() => (data, filename) => {
185
+ return useMemo4(() => (data, filename) => {
153
186
  const url = typeof data === "string" ? data : URL.createObjectURL(data);
154
187
  const element = document.createElement("a");
155
188
  element.setAttribute("href", url);
@@ -160,38 +193,61 @@ var useFileDownload = () => {
160
193
  };
161
194
 
162
195
  // src/useForwardedRef.ts
163
- import { useEffect as useEffect7, useRef as useRef3 } from "react";
164
- var useForwardedRef = (ref) => {
165
- const innerRef = useRef3(null);
196
+ import { useEffect as useEffect7, useMemo as useMemo5, useRef as useRef4 } from "react";
197
+ var useForwardedRef = (forwardedRef) => {
198
+ const localRef = useRef4(null);
166
199
  useEffect7(() => {
167
- if (!ref) {
168
- return;
169
- }
170
- if (typeof ref === "function") {
171
- ref(innerRef.current);
172
- } else {
173
- ref.current = innerRef.current;
200
+ setRef(forwardedRef, localRef.current);
201
+ }, [
202
+ forwardedRef
203
+ ]);
204
+ return localRef;
205
+ };
206
+ function setRef(ref, value) {
207
+ if (typeof ref === "function") {
208
+ return ref(value);
209
+ } else if (ref) {
210
+ ref.current = value;
211
+ }
212
+ }
213
+ var mergeRefs = (refs) => {
214
+ return (value) => {
215
+ const cleanups = [];
216
+ for (const ref of refs) {
217
+ const cleanup = setRef(ref, value);
218
+ cleanups.push(typeof cleanup === "function" ? cleanup : () => setRef(ref, null));
174
219
  }
175
- });
176
- return innerRef;
220
+ return () => {
221
+ for (const cleanup of cleanups) {
222
+ cleanup();
223
+ }
224
+ };
225
+ };
226
+ };
227
+ var useMergeRefs = (refs) => {
228
+ return useMemo5(() => mergeRefs(refs), [
229
+ ...refs
230
+ ]);
177
231
  };
178
232
 
179
233
  // src/useId.ts
180
234
  import alea from "alea";
181
- import { useMemo as useMemo4 } from "react";
235
+ import { useMemo as useMemo6 } from "react";
182
236
  var Alea = alea;
183
237
  var prng = new Alea("@dxos/react-hooks");
184
238
  var randomString = (n = 4) => prng().toString(16).slice(2, n + 2);
185
- var useId = (namespace, propsId, opts) => useMemo4(() => makeId(namespace, propsId, opts), [
186
- propsId
187
- ]);
239
+ var useId = (namespace, propsId, opts) => {
240
+ return useMemo6(() => makeId(namespace, propsId, opts), [
241
+ propsId
242
+ ]);
243
+ };
188
244
  var makeId = (namespace, propsId, opts) => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`;
189
245
 
190
246
  // src/useIsFocused.ts
191
- import { useEffect as useEffect8, useRef as useRef4, useState as useState5 } from "react";
247
+ import { useEffect as useEffect8, useRef as useRef5, useState as useState6 } from "react";
192
248
  var useIsFocused = (inputRef) => {
193
- const [isFocused, setIsFocused] = useState5(void 0);
194
- const isFocusedRef = useRef4(isFocused);
249
+ const [isFocused, setIsFocused] = useState6(void 0);
250
+ const isFocusedRef = useRef5(isFocused);
195
251
  isFocusedRef.current = isFocused;
196
252
  useEffect8(() => {
197
253
  const input = inputRef.current;
@@ -217,7 +273,7 @@ var useIsFocused = (inputRef) => {
217
273
  };
218
274
 
219
275
  // src/useMediaQuery.ts
220
- import { useEffect as useEffect9, useState as useState6 } from "react";
276
+ import { useEffect as useEffect9, useState as useState7 } from "react";
221
277
  var breakpointMediaQueries = {
222
278
  sm: "(min-width: 640px)",
223
279
  md: "(min-width: 768px)",
@@ -226,7 +282,7 @@ var breakpointMediaQueries = {
226
282
  "2xl": "(min-width: 1536px)"
227
283
  };
228
284
  var useMediaQuery = (query, options = {}) => {
229
- const { ssr = true, fallback } = options;
285
+ const { ssr = false, fallback } = options;
230
286
  const queries = (Array.isArray(query) ? query : [
231
287
  query
232
288
  ]).map((query2) => query2 in breakpointMediaQueries ? breakpointMediaQueries[query2] : query2);
@@ -234,7 +290,7 @@ var useMediaQuery = (query, options = {}) => {
234
290
  fallback
235
291
  ];
236
292
  fallbackValues = fallbackValues.filter((v) => v != null);
237
- const [value, setValue] = useState6(() => {
293
+ const [value, setValue] = useState7(() => {
238
294
  return queries.map((query2, index) => ({
239
295
  media: query2,
240
296
  matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query2).matches
@@ -282,9 +338,9 @@ var useMediaQuery = (query, options = {}) => {
282
338
  };
283
339
 
284
340
  // src/useMulticastObservable.ts
285
- import { useMemo as useMemo5, useSyncExternalStore } from "react";
341
+ import { useMemo as useMemo7, useSyncExternalStore } from "react";
286
342
  var useMulticastObservable = (observable) => {
287
- const subscribeFn = useMemo5(() => (listener) => {
343
+ const subscribeFn = useMemo7(() => (listener) => {
288
344
  const subscription = observable.subscribe(listener);
289
345
  return () => subscription.unsubscribe();
290
346
  }, [
@@ -294,28 +350,28 @@ var useMulticastObservable = (observable) => {
294
350
  };
295
351
 
296
352
  // src/useRefCallback.ts
297
- import { useState as useState7 } from "react";
353
+ import { useState as useState8 } from "react";
298
354
  var useRefCallback = () => {
299
- const [value, setValue] = useState7(null);
355
+ const [value, setValue] = useState8(null);
300
356
  return {
301
357
  refCallback: (value2) => setValue(value2),
302
358
  value
303
359
  };
304
360
  };
305
361
 
306
- // src/useResize.ts
307
- import { useLayoutEffect, useMemo as useMemo6 } from "react";
308
- var useResize = (handler, deps = [], delay = 800) => {
309
- const debouncedHandler = useMemo6(() => {
362
+ // src/useViewportResize.ts
363
+ import { useLayoutEffect, useMemo as useMemo8 } from "react";
364
+ var useViewportResize = (cb, deps = [], delay = 800) => {
365
+ const debouncedHandler = useMemo8(() => {
310
366
  let timeout;
311
367
  return (event) => {
312
368
  clearTimeout(timeout);
313
369
  timeout = setTimeout(() => {
314
- handler(event);
370
+ cb(event);
315
371
  }, delay);
316
372
  };
317
373
  }, [
318
- handler,
374
+ cb,
319
375
  delay
320
376
  ]);
321
377
  return useLayoutEffect(() => {
@@ -328,39 +384,16 @@ var useResize = (handler, deps = [], delay = 800) => {
328
384
  ]);
329
385
  };
330
386
 
331
- // src/useSignals.ts
332
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
333
- import { computed, effect } from "@preact-signals/safe-react";
334
- import { useRef as useRef5 } from "@preact-signals/safe-react/react";
335
- import { useEffect as useEffect10, useMemo as useMemo7 } from "react";
336
- var useSignalsEffect = (cb, deps) => {
337
- const callback = useRef5(cb);
338
- callback.current = cb;
339
- useEffect10(() => {
340
- return effect(() => {
341
- return callback.current();
342
- });
343
- }, deps ?? []);
344
- };
345
- var useSignalsMemo = (cb, deps) => {
346
- var _effect = _useSignals();
347
- try {
348
- return useMemo7(() => computed(cb), deps ?? []).value;
349
- } finally {
350
- _effect.f();
351
- }
352
- };
353
-
354
387
  // src/useTimeout.ts
355
- import { useEffect as useEffect11, useRef as useRef6 } from "react";
388
+ import { useEffect as useEffect10, useRef as useRef6 } from "react";
356
389
  var useTimeout = (callback, delay = 0, deps = []) => {
357
390
  const callbackRef = useRef6(callback);
358
- useEffect11(() => {
391
+ useEffect10(() => {
359
392
  callbackRef.current = callback;
360
393
  }, [
361
394
  callback
362
395
  ]);
363
- useEffect11(() => {
396
+ useEffect10(() => {
364
397
  if (delay == null) {
365
398
  return;
366
399
  }
@@ -373,12 +406,12 @@ var useTimeout = (callback, delay = 0, deps = []) => {
373
406
  };
374
407
  var useInterval = (callback, delay = 0, deps = []) => {
375
408
  const callbackRef = useRef6(callback);
376
- useEffect11(() => {
409
+ useEffect10(() => {
377
410
  callbackRef.current = callback;
378
411
  }, [
379
412
  callback
380
413
  ]);
381
- useEffect11(() => {
414
+ useEffect10(() => {
382
415
  if (delay == null) {
383
416
  return;
384
417
  }
@@ -396,16 +429,16 @@ var useInterval = (callback, delay = 0, deps = []) => {
396
429
  };
397
430
 
398
431
  // src/useTransitions.ts
399
- import { useEffect as useEffect12, useRef as useRef7, useState as useState8 } from "react";
400
- var isFunction = (functionToCheck) => {
432
+ import { useEffect as useEffect11, useRef as useRef7, useState as useState9 } from "react";
433
+ var isFunction2 = (functionToCheck) => {
401
434
  return functionToCheck instanceof Function;
402
435
  };
403
436
  var useDidTransition = (currentValue, fromValue, toValue) => {
404
- const [hasTransitioned, setHasTransitioned] = useState8(false);
437
+ const [hasTransitioned, setHasTransitioned] = useState9(false);
405
438
  const previousValue = useRef7(currentValue);
406
- useEffect12(() => {
407
- const toValueValid = isFunction(toValue) ? toValue(currentValue) : toValue === currentValue;
408
- const fromValueValid = isFunction(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
439
+ useEffect11(() => {
440
+ const toValueValid = isFunction2(toValue) ? toValue(currentValue) : toValue === currentValue;
441
+ const fromValueValid = isFunction2(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
409
442
  if (fromValueValid && toValueValid && !hasTransitioned) {
410
443
  setHasTransitioned(true);
411
444
  } else if ((!fromValueValid || !toValueValid) && hasTransitioned) {
@@ -423,13 +456,13 @@ var useDidTransition = (currentValue, fromValue, toValue) => {
423
456
  var useOnTransition = (currentValue, fromValue, toValue, callback) => {
424
457
  const dirty = useRef7(false);
425
458
  const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);
426
- useEffect12(() => {
459
+ useEffect11(() => {
427
460
  dirty.current = false;
428
461
  }, [
429
462
  currentValue,
430
463
  dirty
431
464
  ]);
432
- useEffect12(() => {
465
+ useEffect11(() => {
433
466
  if (hasTransitioned && !dirty.current) {
434
467
  callback();
435
468
  dirty.current = true;
@@ -442,9 +475,13 @@ var useOnTransition = (currentValue, fromValue, toValue, callback) => {
442
475
  };
443
476
  export {
444
477
  makeId,
478
+ mergeRefs,
445
479
  randomString,
480
+ setRef,
446
481
  useAsyncEffect,
447
482
  useAsyncState,
483
+ useAtomState,
484
+ useComposedRefs,
448
485
  useControlledState,
449
486
  useDebugDeps,
450
487
  useDefaultValue,
@@ -457,13 +494,14 @@ export {
457
494
  useInterval,
458
495
  useIsFocused,
459
496
  useMediaQuery,
497
+ useMergeRefs,
460
498
  useMulticastObservable,
461
499
  useOnTransition,
462
500
  useRefCallback,
463
- useResize,
464
- useSignalsEffect,
465
- useSignalsMemo,
501
+ useScroller,
502
+ useSize,
466
503
  useStateWithRef,
467
- useTimeout
504
+ useTimeout,
505
+ useViewportResize
468
506
  };
469
507
  //# sourceMappingURL=index.mjs.map