@dxos/react-hooks 0.8.4-main.ead640a → 0.8.4-main.f466a3d56e

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 (49) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -0
  3. package/dist/lib/browser/index.mjs +188 -146
  4. package/dist/lib/browser/index.mjs.map +4 -4
  5. package/dist/lib/browser/meta.json +1 -1
  6. package/dist/lib/node-esm/index.mjs +188 -146
  7. package/dist/lib/node-esm/index.mjs.map +4 -4
  8. package/dist/lib/node-esm/meta.json +1 -1
  9. package/dist/types/src/index.d.ts +3 -2
  10. package/dist/types/src/index.d.ts.map +1 -1
  11. package/dist/types/src/useAsyncEffect.d.ts.map +1 -1
  12. package/dist/types/src/useAsyncState.d.ts.map +1 -1
  13. package/dist/types/src/useAtomState.d.ts +12 -0
  14. package/dist/types/src/useAtomState.d.ts.map +1 -0
  15. package/dist/types/src/useControlledState.d.ts +2 -3
  16. package/dist/types/src/useControlledState.d.ts.map +1 -1
  17. package/dist/types/src/useDebugDeps.d.ts +1 -1
  18. package/dist/types/src/useDebugDeps.d.ts.map +1 -1
  19. package/dist/types/src/useDefaultValue.d.ts.map +1 -1
  20. package/dist/types/src/useDefaults.d.ts.map +1 -1
  21. package/dist/types/src/useDynamicRef.d.ts +3 -3
  22. package/dist/types/src/useDynamicRef.d.ts.map +1 -1
  23. package/dist/types/src/useForwardedRef.d.ts +23 -3
  24. package/dist/types/src/useForwardedRef.d.ts.map +1 -1
  25. package/dist/types/src/useId.d.ts.map +1 -1
  26. package/dist/types/src/useIsFocused.d.ts.map +1 -1
  27. package/dist/types/src/useMediaQuery.d.ts +1 -1
  28. package/dist/types/src/useMediaQuery.d.ts.map +1 -1
  29. package/dist/types/src/useMulticastObservable.d.ts.map +1 -1
  30. package/dist/types/src/useTimeout.d.ts.map +1 -1
  31. package/dist/types/src/useTransitions.d.ts.map +1 -1
  32. package/dist/types/src/useViewportResize.d.ts +1 -1
  33. package/dist/types/src/useViewportResize.d.ts.map +1 -1
  34. package/dist/types/tsconfig.tsbuildinfo +1 -1
  35. package/package.json +18 -15
  36. package/src/index.ts +4 -3
  37. package/src/useAtomState.ts +23 -0
  38. package/src/useControlledState.ts +22 -13
  39. package/src/useDebugDeps.ts +17 -8
  40. package/src/useDynamicRef.ts +5 -6
  41. package/src/useForwardedRef.ts +47 -13
  42. package/src/useId.ts +3 -2
  43. package/src/useIsFocused.ts +1 -1
  44. package/src/useMediaQuery.ts +7 -7
  45. package/src/useMulticastObservable.test.ts +1 -1
  46. package/src/useViewportResize.ts +29 -11
  47. package/dist/types/src/useSignals.d.ts +0 -10
  48. package/dist/types/src/useSignals.d.ts.map +0 -1
  49. 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,43 +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
- updateRef(ref, innerRef.current);
200
+ setRef(forwardedRef, localRef.current);
168
201
  }, [
169
- ref
202
+ forwardedRef
170
203
  ]);
171
- return innerRef;
204
+ return localRef;
172
205
  };
173
- var updateRef = (ref, value) => {
174
- if (!ref) {
175
- return;
176
- }
206
+ function setRef(ref, value) {
177
207
  if (typeof ref === "function") {
178
- ref(value);
179
- } else {
208
+ return ref(value);
209
+ } else if (ref) {
180
210
  ref.current = value;
181
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));
219
+ }
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
+ ]);
182
231
  };
183
232
 
184
233
  // src/useId.ts
185
234
  import alea from "alea";
186
- import { useMemo as useMemo4 } from "react";
235
+ import { useMemo as useMemo6 } from "react";
187
236
  var Alea = alea;
188
237
  var prng = new Alea("@dxos/react-hooks");
189
238
  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
- ]);
239
+ var useId = (namespace, propsId, opts) => {
240
+ return useMemo6(() => makeId(namespace, propsId, opts), [
241
+ propsId
242
+ ]);
243
+ };
193
244
  var makeId = (namespace, propsId, opts) => propsId ?? `${namespace}-${randomString(opts?.n ?? 4)}`;
194
245
 
195
246
  // src/useIsFocused.ts
196
- 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";
197
248
  var useIsFocused = (inputRef) => {
198
- const [isFocused, setIsFocused] = useState5(void 0);
199
- const isFocusedRef = useRef4(isFocused);
249
+ const [isFocused, setIsFocused] = useState6(void 0);
250
+ const isFocusedRef = useRef5(isFocused);
200
251
  isFocusedRef.current = isFocused;
201
252
  useEffect8(() => {
202
253
  const input = inputRef.current;
@@ -222,7 +273,7 @@ var useIsFocused = (inputRef) => {
222
273
  };
223
274
 
224
275
  // src/useMediaQuery.ts
225
- import { useEffect as useEffect9, useState as useState6 } from "react";
276
+ import { useEffect as useEffect9, useState as useState7 } from "react";
226
277
  var breakpointMediaQueries = {
227
278
  sm: "(min-width: 640px)",
228
279
  md: "(min-width: 768px)",
@@ -239,7 +290,7 @@ var useMediaQuery = (query, options = {}) => {
239
290
  fallback
240
291
  ];
241
292
  fallbackValues = fallbackValues.filter((v) => v != null);
242
- const [value, setValue] = useState6(() => {
293
+ const [value, setValue] = useState7(() => {
243
294
  return queries.map((query2, index) => ({
244
295
  media: query2,
245
296
  matches: ssr ? !!fallbackValues[index] : document.defaultView?.matchMedia(query2).matches
@@ -287,9 +338,9 @@ var useMediaQuery = (query, options = {}) => {
287
338
  };
288
339
 
289
340
  // src/useMulticastObservable.ts
290
- import { useMemo as useMemo5, useSyncExternalStore } from "react";
341
+ import { useMemo as useMemo7, useSyncExternalStore } from "react";
291
342
  var useMulticastObservable = (observable) => {
292
- const subscribeFn = useMemo5(() => (listener) => {
343
+ const subscribeFn = useMemo7(() => (listener) => {
293
344
  const subscription = observable.subscribe(listener);
294
345
  return () => subscription.unsubscribe();
295
346
  }, [
@@ -299,9 +350,9 @@ var useMulticastObservable = (observable) => {
299
350
  };
300
351
 
301
352
  // src/useRefCallback.ts
302
- import { useState as useState7 } from "react";
353
+ import { useState as useState8 } from "react";
303
354
  var useRefCallback = () => {
304
- const [value, setValue] = useState7(null);
355
+ const [value, setValue] = useState8(null);
305
356
  return {
306
357
  refCallback: (value2) => setValue(value2),
307
358
  value
@@ -309,63 +360,55 @@ var useRefCallback = () => {
309
360
  };
310
361
 
311
362
  // src/useViewportResize.ts
312
- import { useLayoutEffect, useMemo as useMemo6 } from "react";
313
- var useViewportResize = (handler, deps = [], delay = 800) => {
314
- const debouncedHandler = useMemo6(() => {
363
+ import { useLayoutEffect, useMemo as useMemo8 } from "react";
364
+ var useViewportResize = (cb, deps = [], delay = 800) => {
365
+ const { handler: debouncedHandler, cancel } = useMemo8(() => {
315
366
  let timeout;
316
- return (event) => {
317
- clearTimeout(timeout);
318
- timeout = setTimeout(() => {
319
- handler(event);
320
- }, delay);
367
+ return {
368
+ handler: (event) => {
369
+ if (timeout !== void 0) {
370
+ clearTimeout(timeout);
371
+ }
372
+ timeout = setTimeout(() => {
373
+ timeout = void 0;
374
+ cb(event);
375
+ }, delay);
376
+ },
377
+ cancel: () => {
378
+ if (timeout !== void 0) {
379
+ clearTimeout(timeout);
380
+ timeout = void 0;
381
+ }
382
+ }
321
383
  };
322
384
  }, [
323
- handler,
385
+ cb,
324
386
  delay
325
387
  ]);
326
388
  return useLayoutEffect(() => {
327
389
  window.visualViewport?.addEventListener("resize", debouncedHandler);
328
390
  debouncedHandler();
329
- return () => window.visualViewport?.removeEventListener("resize", debouncedHandler);
391
+ return () => {
392
+ window.visualViewport?.removeEventListener("resize", debouncedHandler);
393
+ cancel();
394
+ };
330
395
  }, [
331
396
  debouncedHandler,
397
+ cancel,
332
398
  ...deps
333
399
  ]);
334
400
  };
335
401
 
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
402
  // src/useTimeout.ts
360
- import { useEffect as useEffect11, useRef as useRef6 } from "react";
403
+ import { useEffect as useEffect10, useRef as useRef6 } from "react";
361
404
  var useTimeout = (callback, delay = 0, deps = []) => {
362
405
  const callbackRef = useRef6(callback);
363
- useEffect11(() => {
406
+ useEffect10(() => {
364
407
  callbackRef.current = callback;
365
408
  }, [
366
409
  callback
367
410
  ]);
368
- useEffect11(() => {
411
+ useEffect10(() => {
369
412
  if (delay == null) {
370
413
  return;
371
414
  }
@@ -378,12 +421,12 @@ var useTimeout = (callback, delay = 0, deps = []) => {
378
421
  };
379
422
  var useInterval = (callback, delay = 0, deps = []) => {
380
423
  const callbackRef = useRef6(callback);
381
- useEffect11(() => {
424
+ useEffect10(() => {
382
425
  callbackRef.current = callback;
383
426
  }, [
384
427
  callback
385
428
  ]);
386
- useEffect11(() => {
429
+ useEffect10(() => {
387
430
  if (delay == null) {
388
431
  return;
389
432
  }
@@ -401,16 +444,16 @@ var useInterval = (callback, delay = 0, deps = []) => {
401
444
  };
402
445
 
403
446
  // src/useTransitions.ts
404
- import { useEffect as useEffect12, useRef as useRef7, useState as useState8 } from "react";
405
- var isFunction = (functionToCheck) => {
447
+ import { useEffect as useEffect11, useRef as useRef7, useState as useState9 } from "react";
448
+ var isFunction2 = (functionToCheck) => {
406
449
  return functionToCheck instanceof Function;
407
450
  };
408
451
  var useDidTransition = (currentValue, fromValue, toValue) => {
409
- const [hasTransitioned, setHasTransitioned] = useState8(false);
452
+ const [hasTransitioned, setHasTransitioned] = useState9(false);
410
453
  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;
454
+ useEffect11(() => {
455
+ const toValueValid = isFunction2(toValue) ? toValue(currentValue) : toValue === currentValue;
456
+ const fromValueValid = isFunction2(fromValue) ? fromValue(previousValue.current) : fromValue === previousValue.current;
414
457
  if (fromValueValid && toValueValid && !hasTransitioned) {
415
458
  setHasTransitioned(true);
416
459
  } else if ((!fromValueValid || !toValueValid) && hasTransitioned) {
@@ -428,13 +471,13 @@ var useDidTransition = (currentValue, fromValue, toValue) => {
428
471
  var useOnTransition = (currentValue, fromValue, toValue, callback) => {
429
472
  const dirty = useRef7(false);
430
473
  const hasTransitioned = useDidTransition(currentValue, fromValue, toValue);
431
- useEffect12(() => {
474
+ useEffect11(() => {
432
475
  dirty.current = false;
433
476
  }, [
434
477
  currentValue,
435
478
  dirty
436
479
  ]);
437
- useEffect12(() => {
480
+ useEffect11(() => {
438
481
  if (hasTransitioned && !dirty.current) {
439
482
  callback();
440
483
  dirty.current = true;
@@ -445,15 +488,15 @@ var useOnTransition = (currentValue, fromValue, toValue, callback) => {
445
488
  callback
446
489
  ]);
447
490
  };
448
-
449
- // src/index.ts
450
- import { useSize, useScroller } from "mini-virtual-list";
451
491
  export {
452
492
  makeId,
493
+ mergeRefs,
453
494
  randomString,
454
- updateRef,
495
+ setRef,
455
496
  useAsyncEffect,
456
497
  useAsyncState,
498
+ useAtomState,
499
+ useComposedRefs,
457
500
  useControlledState,
458
501
  useDebugDeps,
459
502
  useDefaultValue,
@@ -466,12 +509,11 @@ export {
466
509
  useInterval,
467
510
  useIsFocused,
468
511
  useMediaQuery,
512
+ useMergeRefs,
469
513
  useMulticastObservable,
470
514
  useOnTransition,
471
515
  useRefCallback,
472
516
  useScroller,
473
- useSignalsEffect,
474
- useSignalsMemo,
475
517
  useSize,
476
518
  useStateWithRef,
477
519
  useTimeout,