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