@dxos/react-hooks 0.8.4-main.dedc0f3 → 0.8.4-main.e250131250

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 (51) hide show
  1. package/README.md +1 -0
  2. package/dist/lib/browser/index.mjs +151 -162
  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 +151 -162
  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 -3
  9. package/dist/types/src/index.d.ts.map +1 -1
  10. package/dist/types/src/useControlledState.d.ts +2 -2
  11. package/dist/types/src/useControlledState.d.ts.map +1 -1
  12. package/dist/types/src/useDebugDeps.d.ts +1 -1
  13. package/dist/types/src/useDebugDeps.d.ts.map +1 -1
  14. package/dist/types/src/useDynamicRef.d.ts +3 -3
  15. package/dist/types/src/useDynamicRef.d.ts.map +1 -1
  16. package/dist/types/src/useForwardedRef.d.ts +23 -3
  17. package/dist/types/src/useForwardedRef.d.ts.map +1 -1
  18. package/dist/types/src/useId.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/useTransitions.d.ts +2 -1
  25. package/dist/types/src/useTransitions.d.ts.map +1 -1
  26. package/dist/types/src/useViewportResize.d.ts +3 -0
  27. package/dist/types/src/useViewportResize.d.ts.map +1 -0
  28. package/dist/types/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +17 -11
  30. package/src/index.ts +4 -3
  31. package/src/useControlledState.ts +22 -12
  32. package/src/useDebugDeps.ts +17 -8
  33. package/src/useDynamicRef.ts +5 -6
  34. package/src/useForwardedRef.ts +48 -13
  35. package/src/useId.ts +3 -2
  36. package/src/useIsFocused.ts +2 -2
  37. package/src/useMediaQuery.ts +8 -9
  38. package/src/{useMulticastObservable.test.tsx → useMulticastObservable.test.ts} +1 -3
  39. package/src/useTransitions.ts +3 -1
  40. package/src/{useResize.ts → useViewportResize.ts} +4 -4
  41. package/dist/types/src/useAsyncEffect.stories.d.ts +0 -9
  42. package/dist/types/src/useAsyncEffect.stories.d.ts.map +0 -1
  43. package/dist/types/src/useResize.d.ts +0 -3
  44. package/dist/types/src/useResize.d.ts.map +0 -1
  45. package/dist/types/src/useSignals.d.ts +0 -10
  46. package/dist/types/src/useSignals.d.ts.map +0 -1
  47. package/dist/types/src/useTrackProps.d.ts +0 -5
  48. package/dist/types/src/useTrackProps.d.ts.map +0 -1
  49. package/src/useAsyncEffect.stories.tsx +0 -34
  50. package/src/useSignals.ts +0 -27
  51. package/src/useTrackProps.ts +0 -40
@@ -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) => {
@@ -43,58 +47,107 @@ var useAsyncState = (cb, deps = []) => {
43
47
  };
44
48
 
45
49
  // 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);
50
+ import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2, useState as useState3 } from "react";
51
+
52
+ // src/useDynamicRef.ts
53
+ import { useCallback, useEffect as useEffect3, useRef, useState as useState2 } from "react";
54
+ var useStateWithRef = (valueProp) => {
55
+ const [value, setValue] = useState2(valueProp);
56
+ const valueRef = useRef(valueProp);
57
+ const setter = useCallback((value2) => {
58
+ if (typeof value2 === "function") {
59
+ setValue((current) => {
60
+ valueRef.current = value2(current);
61
+ return valueRef.current;
62
+ });
63
+ } else {
64
+ valueRef.current = value2;
65
+ setValue(value2);
52
66
  }
67
+ }, []);
68
+ return [
69
+ value,
70
+ setter,
71
+ valueRef
72
+ ];
73
+ };
74
+ var useDynamicRef = (value) => {
75
+ const valueRef = useRef(value);
76
+ useEffect3(() => {
77
+ valueRef.current = value;
53
78
  }, [
54
- controlledValue,
55
- ...deps
79
+ value
56
80
  ]);
57
- useEffect3(() => {
58
- onChange?.(value);
81
+ return valueRef;
82
+ };
83
+
84
+ // src/useControlledState.ts
85
+ var useControlledState = (valueProp, onChange) => {
86
+ const [value, setControlledValue] = useState3(valueProp);
87
+ useEffect4(() => {
88
+ setControlledValue(valueProp);
59
89
  }, [
60
- value,
61
- onChange
90
+ valueProp
91
+ ]);
92
+ const onChangeRef = useRef2(onChange);
93
+ const valueRef = useDynamicRef(valueProp);
94
+ const setValue = useCallback2((nextValue) => {
95
+ const value2 = isFunction(nextValue) ? nextValue(valueRef.current) : nextValue;
96
+ setControlledValue(value2);
97
+ onChangeRef.current?.(value2);
98
+ }, [
99
+ valueRef,
100
+ onChangeRef
62
101
  ]);
63
102
  return [
64
103
  value,
65
104
  setValue
66
105
  ];
67
106
  };
107
+ function isFunction(value) {
108
+ return typeof value === "function";
109
+ }
68
110
 
69
111
  // src/useDebugDeps.ts
70
- import { useEffect as useEffect4, useRef } from "react";
71
- var useDebugDeps = (deps = []) => {
72
- const lastDeps = useRef([]);
73
- useEffect4(() => {
74
- console.group("deps changed", {
75
- previous: lastDeps.current.length,
76
- current: deps.length
77
- });
112
+ import { useEffect as useEffect5, useRef as useRef3 } from "react";
113
+ import { log } from "@dxos/log";
114
+ var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-primitives/react-hooks/src/useDebugDeps.ts";
115
+ var useDebugDeps = (deps = [], label = "useDebugDeps", active = true) => {
116
+ const lastDeps = useRef3([]);
117
+ useEffect5(() => {
118
+ if (!active) {
119
+ return;
120
+ }
121
+ const diff = {};
78
122
  for (let i = 0; i < Math.max(lastDeps.current.length ?? 0, deps.length ?? 0); i++) {
79
- if (lastDeps.current[i] !== deps[i]) {
80
- console.log("changed", {
81
- index: i,
123
+ if (lastDeps.current[i] !== deps[i] || i > lastDeps.current.length) {
124
+ diff[i] = {
82
125
  previous: lastDeps.current[i],
83
126
  current: deps[i]
84
- });
127
+ };
85
128
  }
86
129
  }
87
- console.groupEnd();
130
+ if (Object.keys(diff).length > 0) {
131
+ log.warn(`Updated: ${label} [${lastDeps.current.length}/${deps.length}]`, diff, {
132
+ F: __dxlog_file,
133
+ L: 30,
134
+ S: void 0,
135
+ C: (f, a) => f(...a)
136
+ });
137
+ }
88
138
  lastDeps.current = deps;
89
- }, deps);
139
+ }, [
140
+ ...deps,
141
+ active
142
+ ]);
90
143
  };
91
144
 
92
145
  // src/useDefaultValue.ts
93
- import { useEffect as useEffect5, useMemo, useState as useState3 } from "react";
146
+ import { useEffect as useEffect6, useMemo, useState as useState4 } from "react";
94
147
  var useDefaultValue = (reactiveValue, getDefaultValue) => {
95
148
  const stableDefaultValue = useMemo(getDefaultValue, []);
96
- const [value, setValue] = useState3(reactiveValue ?? stableDefaultValue);
97
- useEffect5(() => {
149
+ const [value, setValue] = useState4(reactiveValue ?? stableDefaultValue);
150
+ useEffect6(() => {
98
151
  setValue(reactiveValue ?? stableDefaultValue);
99
152
  }, [
100
153
  reactiveValue,
@@ -113,39 +166,6 @@ var useDefaults = (value, defaults) => {
113
166
  ]);
114
167
  };
115
168
 
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 = (value$) => {
120
- const [value, setValue] = useState4(value$);
121
- const valueRef = useRef2(value$);
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
169
  // src/useFileDownload.ts
150
170
  import { useMemo as useMemo3 } from "react";
151
171
  var useFileDownload = () => {
@@ -160,38 +180,59 @@ var useFileDownload = () => {
160
180
  };
161
181
 
162
182
  // src/useForwardedRef.ts
163
- import { useEffect as useEffect7, useRef as useRef3 } from "react";
164
- var useForwardedRef = (ref) => {
165
- const innerRef = useRef3(null);
183
+ import { useEffect as useEffect7, useMemo as useMemo4, useRef as useRef4 } from "react";
184
+ var useForwardedRef = (forwardedRef) => {
185
+ const localRef = useRef4(null);
166
186
  useEffect7(() => {
167
- if (!ref) {
168
- return;
169
- }
170
- if (typeof ref === "function") {
171
- ref(innerRef.current);
172
- } else {
173
- ref.current = innerRef.current;
187
+ setRef(forwardedRef, localRef.current);
188
+ }, [
189
+ forwardedRef
190
+ ]);
191
+ return localRef;
192
+ };
193
+ function setRef(ref, value) {
194
+ if (typeof ref === "function") {
195
+ return ref(value);
196
+ } else if (ref) {
197
+ ref.current = value;
198
+ }
199
+ }
200
+ var mergeRefs = (refs) => {
201
+ return (value) => {
202
+ const cleanups = [];
203
+ for (const ref of refs) {
204
+ const cleanup = setRef(ref, value);
205
+ cleanups.push(typeof cleanup === "function" ? cleanup : () => setRef(ref, null));
174
206
  }
175
- });
176
- return innerRef;
207
+ return () => {
208
+ for (const cleanup of cleanups) cleanup();
209
+ };
210
+ };
211
+ };
212
+ var useMergeRefs = (refs) => {
213
+ return useMemo4(() => mergeRefs(refs), [
214
+ ...refs
215
+ ]);
177
216
  };
178
217
 
179
218
  // src/useId.ts
180
219
  import alea from "alea";
181
- import { useMemo as useMemo4 } from "react";
220
+ import { useMemo as useMemo5 } from "react";
182
221
  var Alea = alea;
183
222
  var prng = new Alea("@dxos/react-hooks");
184
223
  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
- ]);
224
+ var useId = (namespace, propsId, opts) => {
225
+ return useMemo5(() => makeId(namespace, propsId, opts), [
226
+ propsId
227
+ ]);
228
+ };
188
229
  var makeId = (namespace, propsId, opts) => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`;
189
230
 
190
231
  // src/useIsFocused.ts
191
- import { useEffect as useEffect8, useRef as useRef4, useState as useState5 } from "react";
232
+ import { useEffect as useEffect8, useRef as useRef5, useState as useState5 } from "react";
192
233
  var useIsFocused = (inputRef) => {
193
234
  const [isFocused, setIsFocused] = useState5(void 0);
194
- const isFocusedRef = useRef4(isFocused);
235
+ const isFocusedRef = useRef5(isFocused);
195
236
  isFocusedRef.current = isFocused;
196
237
  useEffect8(() => {
197
238
  const input = inputRef.current;
@@ -226,7 +267,7 @@ var breakpointMediaQueries = {
226
267
  "2xl": "(min-width: 1536px)"
227
268
  };
228
269
  var useMediaQuery = (query, options = {}) => {
229
- const { ssr = true, fallback } = options;
270
+ const { ssr = false, fallback } = options;
230
271
  const queries = (Array.isArray(query) ? query : [
231
272
  query
232
273
  ]).map((query2) => query2 in breakpointMediaQueries ? breakpointMediaQueries[query2] : query2);
@@ -282,9 +323,9 @@ var useMediaQuery = (query, options = {}) => {
282
323
  };
283
324
 
284
325
  // src/useMulticastObservable.ts
285
- import { useMemo as useMemo5, useSyncExternalStore } from "react";
326
+ import { useMemo as useMemo6, useSyncExternalStore } from "react";
286
327
  var useMulticastObservable = (observable) => {
287
- const subscribeFn = useMemo5(() => (listener) => {
328
+ const subscribeFn = useMemo6(() => (listener) => {
288
329
  const subscription = observable.subscribe(listener);
289
330
  return () => subscription.unsubscribe();
290
331
  }, [
@@ -303,19 +344,19 @@ var useRefCallback = () => {
303
344
  };
304
345
  };
305
346
 
306
- // src/useResize.ts
307
- import { useLayoutEffect, useMemo as useMemo6 } from "react";
308
- var useResize = (handler, deps = [], delay = 800) => {
309
- const debouncedHandler = useMemo6(() => {
347
+ // src/useViewportResize.ts
348
+ import { useLayoutEffect, useMemo as useMemo7 } from "react";
349
+ var useViewportResize = (cb, deps = [], delay = 800) => {
350
+ const debouncedHandler = useMemo7(() => {
310
351
  let timeout;
311
352
  return (event) => {
312
353
  clearTimeout(timeout);
313
354
  timeout = setTimeout(() => {
314
- handler(event);
355
+ cb(event);
315
356
  }, delay);
316
357
  };
317
358
  }, [
318
- handler,
359
+ cb,
319
360
  delay
320
361
  ]);
321
362
  return useLayoutEffect(() => {
@@ -328,39 +369,16 @@ var useResize = (handler, deps = [], delay = 800) => {
328
369
  ]);
329
370
  };
330
371
 
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
372
  // src/useTimeout.ts
355
- import { useEffect as useEffect11, useRef as useRef6 } from "react";
373
+ import { useEffect as useEffect10, useRef as useRef6 } from "react";
356
374
  var useTimeout = (callback, delay = 0, deps = []) => {
357
375
  const callbackRef = useRef6(callback);
358
- useEffect11(() => {
376
+ useEffect10(() => {
359
377
  callbackRef.current = callback;
360
378
  }, [
361
379
  callback
362
380
  ]);
363
- useEffect11(() => {
381
+ useEffect10(() => {
364
382
  if (delay == null) {
365
383
  return;
366
384
  }
@@ -373,12 +391,12 @@ var useTimeout = (callback, delay = 0, deps = []) => {
373
391
  };
374
392
  var useInterval = (callback, delay = 0, deps = []) => {
375
393
  const callbackRef = useRef6(callback);
376
- useEffect11(() => {
394
+ useEffect10(() => {
377
395
  callbackRef.current = callback;
378
396
  }, [
379
397
  callback
380
398
  ]);
381
- useEffect11(() => {
399
+ useEffect10(() => {
382
400
  if (delay == null) {
383
401
  return;
384
402
  }
@@ -395,49 +413,17 @@ var useInterval = (callback, delay = 0, deps = []) => {
395
413
  ]);
396
414
  };
397
415
 
398
- // src/useTrackProps.ts
399
- import { useEffect as useEffect12, useRef as useRef7 } from "react";
400
- import { log } from "@dxos/log";
401
- var __dxlog_file = "/__w/dxos/dxos/packages/ui/primitives/react-hooks/src/useTrackProps.ts";
402
- var useTrackProps = (props, componentName = "Component", active = true) => {
403
- const prevProps = useRef7(props);
404
- useEffect12(() => {
405
- const changes = Object.entries(props).filter(([key]) => props[key] !== prevProps.current[key]);
406
- if (changes.length > 0) {
407
- if (active) {
408
- log.info("props changed", {
409
- componentName,
410
- keys: changes.map(([key]) => key).join(","),
411
- props: Object.fromEntries(changes.map(([key]) => [
412
- key,
413
- {
414
- from: prevProps.current[key],
415
- to: props[key]
416
- }
417
- ]))
418
- }, {
419
- F: __dxlog_file,
420
- L: 22,
421
- S: void 0,
422
- C: (f, a) => f(...a)
423
- });
424
- }
425
- }
426
- prevProps.current = props;
427
- });
428
- };
429
-
430
416
  // src/useTransitions.ts
431
- import { useEffect as useEffect13, useRef as useRef8, useState as useState8 } from "react";
432
- var isFunction = (functionToCheck) => {
417
+ import { useEffect as useEffect11, useRef as useRef7, useState as useState8 } from "react";
418
+ var isFunction2 = (functionToCheck) => {
433
419
  return functionToCheck instanceof Function;
434
420
  };
435
421
  var useDidTransition = (currentValue, fromValue, toValue) => {
436
422
  const [hasTransitioned, setHasTransitioned] = useState8(false);
437
- const previousValue = useRef8(currentValue);
438
- useEffect13(() => {
439
- const toValueValid = isFunction(toValue) ? toValue(currentValue) : toValue === currentValue;
440
- const fromValueValid = isFunction(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
423
+ const previousValue = useRef7(currentValue);
424
+ useEffect11(() => {
425
+ const toValueValid = isFunction2(toValue) ? toValue(currentValue) : toValue === currentValue;
426
+ const fromValueValid = isFunction2(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
441
427
  if (fromValueValid && toValueValid && !hasTransitioned) {
442
428
  setHasTransitioned(true);
443
429
  } else if ((!fromValueValid || !toValueValid) && hasTransitioned) {
@@ -453,15 +439,15 @@ var useDidTransition = (currentValue, fromValue, toValue) => {
453
439
  return hasTransitioned;
454
440
  };
455
441
  var useOnTransition = (currentValue, fromValue, toValue, callback) => {
456
- const dirty = useRef8(false);
442
+ const dirty = useRef7(false);
457
443
  const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);
458
- useEffect13(() => {
444
+ useEffect11(() => {
459
445
  dirty.current = false;
460
446
  }, [
461
447
  currentValue,
462
448
  dirty
463
449
  ]);
464
- useEffect13(() => {
450
+ useEffect11(() => {
465
451
  if (hasTransitioned && !dirty.current) {
466
452
  callback();
467
453
  dirty.current = true;
@@ -474,9 +460,12 @@ var useOnTransition = (currentValue, fromValue, toValue, callback) => {
474
460
  };
475
461
  export {
476
462
  makeId,
463
+ mergeRefs,
477
464
  randomString,
465
+ setRef,
478
466
  useAsyncEffect,
479
467
  useAsyncState,
468
+ useComposedRefs,
480
469
  useControlledState,
481
470
  useDebugDeps,
482
471
  useDefaultValue,
@@ -489,14 +478,14 @@ export {
489
478
  useInterval,
490
479
  useIsFocused,
491
480
  useMediaQuery,
481
+ useMergeRefs,
492
482
  useMulticastObservable,
493
483
  useOnTransition,
494
484
  useRefCallback,
495
- useResize,
496
- useSignalsEffect,
497
- useSignalsMemo,
485
+ useScroller,
486
+ useSize,
498
487
  useStateWithRef,
499
488
  useTimeout,
500
- useTrackProps
489
+ useViewportResize
501
490
  };
502
491
  //# sourceMappingURL=index.mjs.map