extra-react-hooks 0.7.1 → 0.8.1

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 (39) hide show
  1. package/README.md +32 -6
  2. package/lib/index.d.ts +2 -0
  3. package/lib/index.js +2 -0
  4. package/lib/index.js.map +1 -1
  5. package/lib/use-abortable-callback.d.ts +1 -2
  6. package/lib/use-abortable-callback.js.map +1 -1
  7. package/lib/use-debounce.d.ts +1 -0
  8. package/lib/use-debounce.js +18 -0
  9. package/lib/use-debounce.js.map +1 -0
  10. package/lib/use-effect-async.d.ts +1 -2
  11. package/lib/use-effect-async.js.map +1 -1
  12. package/lib/use-get-set.js.map +1 -1
  13. package/lib/use-iife.d.ts +0 -1
  14. package/lib/use-iife.js.map +1 -1
  15. package/lib/use-intersection-observer.d.ts +3 -3
  16. package/lib/use-intersection-observer.js +2 -1
  17. package/lib/use-intersection-observer.js.map +1 -1
  18. package/lib/use-is-first-render.js.map +1 -1
  19. package/lib/use-memo-with-cleanup.d.ts +0 -1
  20. package/lib/use-memo-with-cleanup.js.map +1 -1
  21. package/lib/use-multiple-selection.js.map +1 -1
  22. package/lib/use-number-input.d.ts +7 -0
  23. package/lib/use-number-input.js +49 -0
  24. package/lib/use-number-input.js.map +1 -0
  25. package/lib/use-resize-observer.d.ts +2 -2
  26. package/lib/use-resize-observer.js +2 -1
  27. package/lib/use-resize-observer.js.map +1 -1
  28. package/lib/use-state-cycle.js.map +1 -1
  29. package/lib/use-step.js.map +1 -1
  30. package/lib/use-update-effect.js.map +1 -1
  31. package/package.json +26 -23
  32. package/src/index.ts +2 -0
  33. package/src/use-abortable-callback.ts +2 -2
  34. package/src/use-debounce.ts +25 -0
  35. package/src/use-effect-async.ts +2 -2
  36. package/src/use-intersection-observer.ts +8 -11
  37. package/src/use-memo-with-cleanup.ts +5 -1
  38. package/src/use-number-input.ts +76 -0
  39. package/src/use-resize-observer.ts +4 -3
package/README.md CHANGED
@@ -63,7 +63,7 @@ function useUnmount(effect: () => void): void
63
63
  ```ts
64
64
  function useEffectAsync(
65
65
  effect: (signal: AbortSignal) => Promise<void>
66
- , deps?: DependencyList
66
+ , deps?: React.DependencyList
67
67
  ): void
68
68
  ```
69
69
 
@@ -71,7 +71,7 @@ function useEffectAsync(
71
71
  ```ts
72
72
  function useAbortableCallback<Args extends unknown[], Result>(
73
73
  callback: (...args: [...args: Args, signal: AbortSignal]) => PromiseLike<Result>
74
- , deps: DependencyList
74
+ , deps: React.DependencyList
75
75
  ): (...args: [...args: Args, signal: AbortSignal | Falsy]) => Promise<Result>
76
76
  ```
77
77
 
@@ -112,7 +112,7 @@ function useIncrement(
112
112
  ```ts
113
113
  function useResizeObserver(
114
114
  callback: ResizeObserverCallback
115
- , refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
115
+ , refs: Array<RefObject<HTMLElement | null | undefined>>
116
116
  , deps?: React.DependencyList
117
117
  ): void
118
118
  ```
@@ -122,12 +122,12 @@ function useResizeObserver(
122
122
  function useIntersectionObserver(
123
123
  callback: IntersectionObserverCallback
124
124
  , options: IntersectionObserverInit | undefined
125
- , refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
125
+ , refs: Array<RefObject<HTMLElement | null | undefined>>
126
126
  , deps?: React.DependencyList
127
127
  ): void
128
128
  function useIntersectionObserver(
129
129
  callback: IntersectionObserverCallback
130
- , refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
130
+ , refs: Array<RefObject<HTMLElement | null | undefined>>
131
131
  , deps?: React.DependencyList
132
132
  ): void
133
133
  ```
@@ -190,6 +190,32 @@ function useGetSet<T>(
190
190
  ```ts
191
191
  function useIsomorphicLayoutEffect(
192
192
  effect: EffectCallback
193
- , deps?: DependencyList
193
+ , deps?: React.DependencyList
194
194
  ): void
195
195
  ```
196
+
197
+ ### useDebounce
198
+ ```ts
199
+ function useDebounce<Args extends unknown[]>(
200
+ fn: (...args: Args) => void
201
+ , timeout: number
202
+ , deps?: React.DependencyList
203
+ ): (...args: Args) => void
204
+ ```
205
+
206
+ ### useNumberInput
207
+ ```ts
208
+ function useNumberInput(params: {
209
+ value: number
210
+ lazy?: boolean
211
+
212
+ onChange(value: number): void
213
+ }): {
214
+ getInputProps(): Required<Pick<
215
+ React.ComponentPropsWithoutRef<'input'>
216
+ , 'value'
217
+ | 'onChange'
218
+ | 'onBlur'
219
+ >>
220
+ }
221
+ ```
package/lib/index.d.ts CHANGED
@@ -21,3 +21,5 @@ export * from './use-iife.js';
21
21
  export * from './use-memo-with-cleanup.js';
22
22
  export * from './use-get-set.js';
23
23
  export * from './use-isomorphic-layout-effect.js';
24
+ export * from './use-debounce.js';
25
+ export * from './use-number-input.js';
package/lib/index.js CHANGED
@@ -21,4 +21,6 @@ export * from './use-iife.js';
21
21
  export * from './use-memo-with-cleanup.js';
22
22
  export * from './use-get-set.js';
23
23
  export * from './use-isomorphic-layout-effect.js';
24
+ export * from './use-debounce.js';
25
+ export * from './use-number-input.js';
24
26
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA;AAC7B,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kBAAkB,CAAA;AAChC,cAAc,mCAAmC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,yBAAyB,CAAA;AACvC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,wBAAwB,CAAA;AACtC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sBAAsB,CAAA;AACpC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,eAAe,CAAA;AAC7B,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kBAAkB,CAAA;AAChC,cAAc,mCAAmC,CAAA;AACjD,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA"}
@@ -1,3 +1,2 @@
1
- import { DependencyList } from 'react';
2
1
  import { Falsy } from '@blackglory/prelude';
3
- export declare function useAbortableCallback<Args extends unknown[], Result>(callback: (...args: [...args: Args, signal: AbortSignal]) => PromiseLike<Result>, deps: DependencyList): (...args: [...args: Args, signal: AbortSignal | Falsy]) => Promise<Result>;
2
+ export declare function useAbortableCallback<Args extends unknown[], Result>(callback: (...args: [...args: Args, signal: AbortSignal]) => PromiseLike<Result>, deps: React.DependencyList): (...args: [...args: Args, signal: AbortSignal | Falsy]) => Promise<Result>;
@@ -1 +1 @@
1
- {"version":3,"file":"use-abortable-callback.js","sourceRoot":"","sources":["../src/use-abortable-callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAG/D,MAAM,UAAU,oBAAoB,CAClC,QAAgF,EAChF,IAAoB;IAEpB,MAAM,UAAU,GAAG,kBAAkB,CACnC,GAAG,EAAE,CAAC,IAAI,eAAe,EAAE,EAC3B,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAChC,IAAI,CACL,CAAA;IAED,OAAO,WAAW,CAAC,KAAK,EAAE,GAAG,IAAkD,EAAE,EAAE;QACjF,MAAM,MAAM,GAAG,gBAAgB,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAwB;YAC5C,UAAU,CAAC,MAAM;SAClB,CAAC,CAAA;QACF,MAAM,CAAC,cAAc,EAAE,CAAA;QAEvB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAS,CAAA;QAE1C,OAAO,MAAM,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAA;IAC5C,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC,CAAA;AAC3B,CAAC"}
1
+ {"version":3,"file":"use-abortable-callback.js","sourceRoot":"","sources":["../src/use-abortable-callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAG/D,MAAM,UAAU,oBAAoB,CAClC,QAAgF,EAChF,IAA0B;IAE1B,MAAM,UAAU,GAAG,kBAAkB,CACnC,GAAG,EAAE,CAAC,IAAI,eAAe,EAAE,EAC3B,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAChC,IAAI,CACL,CAAA;IAED,OAAO,WAAW,CAAC,KAAK,EAAE,GAAG,IAAkD,EAAE,EAAE;QACjF,MAAM,MAAM,GAAG,gBAAgB,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAwB;YAC5C,UAAU,CAAC,MAAM;SAClB,CAAC,CAAA;QACF,MAAM,CAAC,cAAc,EAAE,CAAA;QAEvB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAS,CAAA;QAE1C,OAAO,MAAM,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAA;IAC5C,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC,CAAA;AAC3B,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function useDebounce<Args extends unknown[]>(fn: (...args: Args) => void, timeout: number, deps?: React.DependencyList): (...args: Args) => void;
@@ -0,0 +1,18 @@
1
+ import { useRef, useEffect } from 'react';
2
+ import { setTimeout } from 'extra-timers';
3
+ export function useDebounce(fn, timeout, deps) {
4
+ const fnRef = useRef(fn);
5
+ const cancelTimeoutRef = useRef(undefined);
6
+ useEffect(() => {
7
+ fnRef.current = fn;
8
+ }, deps);
9
+ return (...args) => {
10
+ var _a;
11
+ (_a = cancelTimeoutRef.current) === null || _a === void 0 ? void 0 : _a.call(cancelTimeoutRef);
12
+ cancelTimeoutRef.current = setTimeout(timeout, () => {
13
+ fnRef.current(...args);
14
+ cancelTimeoutRef.current = undefined;
15
+ });
16
+ };
17
+ }
18
+ //# sourceMappingURL=use-debounce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-debounce.js","sourceRoot":"","sources":["../src/use-debounce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,MAAM,UAAU,WAAW,CACzB,EAA2B,EAC3B,OAAe,EACf,IAA2B;IAE3B,MAAM,KAAK,GAAG,MAAM,CAA0B,EAAE,CAAC,CAAA;IACjD,MAAM,gBAAgB,GAAG,MAAM,CAAa,SAAS,CAAC,CAAA;IAEtD,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,CAAC,OAAO,GAAG,EAAE,CAAA;IACpB,CAAC,EAAE,IAAI,CAAC,CAAA;IAER,OAAO,CAAC,GAAG,IAAU,EAAQ,EAAE;;QAC7B,MAAA,gBAAgB,CAAC,OAAO,gEAAI,CAAA;QAE5B,gBAAgB,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,GAAG,EAAE;YAClD,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;YAEtB,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAA;QACtC,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
@@ -1,2 +1 @@
1
- import { DependencyList } from 'react';
2
- export declare function useEffectAsync(effect: (signal: AbortSignal) => Promise<void>, deps?: DependencyList): void;
1
+ export declare function useEffectAsync(effect: (signal: AbortSignal) => Promise<void>, deps?: React.DependencyList): void;
@@ -1 +1 @@
1
- {"version":3,"file":"use-effect-async.js","sourceRoot":"","sources":["../src/use-effect-async.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAA;AACjD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,MAAM,kBAAmB,SAAQ,WAAW;CAAG;AAE/C,MAAM,UAAU,cAAc,CAC5B,MAA8C,EAC9C,IAAqB;IAErB,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QAExC,EAAE,CAAC,KAAK,IAAI,EAAE;YACZ,IAAI;gBACF,UAAU,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;gBAElC,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;aAChC;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,GAAG,YAAY,kBAAkB,EAAE;oBACrC,IAAI,EAAE,CAAA;iBACP;qBAAM;oBACL,MAAM,GAAG,CAAA;iBACV;aACF;QACH,CAAC,CAAC,CAAA;QAEF,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAA;IACzD,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
1
+ {"version":3,"file":"use-effect-async.js","sourceRoot":"","sources":["../src/use-effect-async.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,MAAM,kBAAmB,SAAQ,WAAW;CAAG;AAE/C,MAAM,UAAU,cAAc,CAC5B,MAA8C,EAC9C,IAA2B;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QAExC,EAAE,CAAC,KAAK,IAAI,EAAE;YACZ,IAAI,CAAC;gBACH,UAAU,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;gBAElC,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;YACjC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,kBAAkB,EAAE,CAAC;oBACtC,IAAI,EAAE,CAAA;gBACR,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,CAAA;gBACX,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAA;QAEF,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAA;IACzD,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-get-set.js","sourceRoot":"","sources":["../src/use-get-set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,UAAU,SAAS,CACvB,YAAe;IAEf,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,GAAG,GAAG,MAAM,CAAI,YAAY,CAAC,CAAA;IAEnC,OAAO;QACL,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;QAClC,WAAW,CAAC,CAAC,KAAQ,EAAE,EAAE;YACvB,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE;gBACzB,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;gBACnB,WAAW,EAAE,CAAA;aACd;QACH,CAAC,EAAE,EAAE,CAAC;KACP,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"use-get-set.js","sourceRoot":"","sources":["../src/use-get-set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,UAAU,SAAS,CACvB,YAAe;IAEf,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,GAAG,GAAG,MAAM,CAAI,YAAY,CAAC,CAAA;IAEnC,OAAO;QACL,WAAW,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;QAClC,WAAW,CAAC,CAAC,KAAQ,EAAE,EAAE;YACvB,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;gBAC1B,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;gBACnB,WAAW,EAAE,CAAA;YACf,CAAC;QACH,CAAC,EAAE,EAAE,CAAC;KACP,CAAA;AACH,CAAC"}
package/lib/use-iife.d.ts CHANGED
@@ -1,2 +1 @@
1
- /// <reference types="react" />
2
1
  export declare function useIIFE(iife: () => void, deps: React.DependencyList): void;
@@ -1 +1 @@
1
- {"version":3,"file":"use-iife.js","sourceRoot":"","sources":["../src/use-iife.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,gBAAgB,EAAE,iCAAmC;AAE9D,MAAM,UAAU,OAAO,CAAC,IAAgB,EAAE,IAA0B;IAClE,MAAM,OAAO,GAAG,MAAM,CAAuB,EAAE,CAAC,CAAA;IAChD,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAA;IAExC,IAAI,aAAa,EAAE,EAAE;QACnB,IAAI,EAAE,CAAA;KACP;SAAM;QACL,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE;YAC1C,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;gBACjD,IAAI,EAAE,CAAA;aACP;SACF;aAAM;YACL,IAAI,EAAE,CAAA;SACP;KACF;IAED,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACpC,CAAC"}
1
+ {"version":3,"file":"use-iife.js","sourceRoot":"","sources":["../src/use-iife.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,gBAAgB,EAAE,iCAAmC;AAE9D,MAAM,UAAU,OAAO,CAAC,IAAgB,EAAE,IAA0B;IAClE,MAAM,OAAO,GAAG,MAAM,CAAuB,EAAE,CAAC,CAAA;IAChD,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAA;IAExC,IAAI,aAAa,EAAE,EAAE,CAAC;QACpB,IAAI,EAAE,CAAA;IACR,CAAC;SAAM,CAAC;QACN,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAC3C,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,IAAI,EAAE,CAAA;YACR,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,EAAE,CAAA;QACR,CAAC;IACH,CAAC;IAED,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACpC,CAAC"}
@@ -1,3 +1,3 @@
1
- import { RefObject, MutableRefObject } from 'react';
2
- export declare function useIntersectionObserver(callback: IntersectionObserverCallback, options: IntersectionObserverInit | undefined, refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>, deps?: React.DependencyList): void;
3
- export declare function useIntersectionObserver(callback: IntersectionObserverCallback, refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>, deps?: React.DependencyList): void;
1
+ import { RefObject } from 'react';
2
+ export declare function useIntersectionObserver(callback: IntersectionObserverCallback, options: IntersectionObserverInit | undefined, refs: Array<RefObject<HTMLElement | undefined | null>>, deps?: React.DependencyList): void;
3
+ export declare function useIntersectionObserver(callback: IntersectionObserverCallback, refs: Array<RefObject<HTMLElement | undefined | null>>, deps?: React.DependencyList): void;
@@ -1,5 +1,5 @@
1
1
  import { useEffect } from 'react';
2
- import { isArray, isntNull } from '@blackglory/prelude';
2
+ import { isArray, isntNull, isntUndefined } from '@blackglory/prelude';
3
3
  export function useIntersectionObserver(...args) {
4
4
  switch (args.length) {
5
5
  case 2: {
@@ -26,6 +26,7 @@ export function useIntersectionObserver(...args) {
26
26
  refs
27
27
  .map(x => x.current)
28
28
  .filter(isntNull)
29
+ .filter(isntUndefined)
29
30
  .forEach(x => observer.observe(x));
30
31
  return () => observer.disconnect();
31
32
  }, deps);
@@ -1 +1 @@
1
- {"version":3,"file":"use-intersection-observer.js","sourceRoot":"","sources":["../src/use-intersection-observer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA+B,MAAM,OAAO,CAAA;AAC9D,OAAO,EAAU,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAa/D,MAAM,UAAU,uBAAuB,CAAC,GAAG,IAWxC;IAED,QAAQ,IAAI,CAAC,MAAM,EAAE;QACnB,KAAK,CAAC,CAAC,CAAC;YACN,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,IAAI,CAAA;YAG7B,OAAO,uBAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;SAC1D;QACD,KAAK,CAAC,CAAC,CAAC;YACN,MAAM,CAAC,QAAQ,EAAE,aAAa,EAAE,UAAU,CAAC,GAAG,IAAI,CAAA;YAClD,IAAI,OAAO,CAAC,aAAa,CAAC,EAAE;gBAC1B,MAAM,IAAI,GAAG,aAAa,CAAA;gBAC1B,MAAM,IAAI,GAAG,UAA8C,CAAA;gBAG3D,OAAO,uBAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;aAChE;iBAAM;gBACL,MAAM,OAAO,GAAG,aAAa,CAAA;gBAC7B,MAAM,IAAI,GAAG,UAA2E,CAAA;gBAGxF,OAAO,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;aACxD;SACF;KACF;IAED,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAA;IAG5C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,IAAI,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAE5D,IAAI;aACD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;aACnB,MAAM,CAAC,QAAQ,CAAC;aAChB,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;QAEpC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAA;IACpC,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
1
+ {"version":3,"file":"use-intersection-observer.js","sourceRoot":"","sources":["../src/use-intersection-observer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,OAAO,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAatE,MAAM,UAAU,uBAAuB,CAAC,GAAG,IAWxC;IAED,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;QACpB,KAAK,CAAC,CAAC,CAAC,CAAC;YACP,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,IAAI,CAAA;YAE7B,OAAO,uBAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAA;QAC3D,CAAC;QACD,KAAK,CAAC,CAAC,CAAC,CAAC;YACP,MAAM,CAAC,QAAQ,EAAE,aAAa,EAAE,UAAU,CAAC,GAAG,IAAI,CAAA;YAClD,IAAI,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,aAAa,CAAA;gBAC1B,MAAM,IAAI,GAAG,UAA8C,CAAA;gBAE3D,OAAO,uBAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;YACjE,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,GAAG,aAAa,CAAA;gBAC7B,MAAM,IAAI,GAAG,UAA2C,CAAA;gBAExD,OAAO,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;YACzD,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAA;IAE5C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,IAAI,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAE5D,IAAI;aACD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;aACnB,MAAM,CAAC,QAAQ,CAAC;aAChB,MAAM,CAAC,aAAa,CAAC;aACrB,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;QAEpC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAA;IACpC,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-is-first-render.js","sourceRoot":"","sources":["../src/use-is-first-render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAE3C,IAAK,KAIJ;AAJD,WAAK,KAAK;IACR,iDAAY,CAAA;IACZ,mCAAK,CAAA;IACL,yCAAQ,CAAA;AACV,CAAC,EAJI,KAAK,KAAL,KAAK,QAIT;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAExC,QAAQ,KAAK,CAAC,OAAO,EAAE;QACrB,KAAK,KAAK,CAAC,YAAY;YACrB,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAA;YAC3B,MAAK;QACP,KAAK,KAAK,CAAC,KAAK;YACd,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAA;YAC9B,MAAK;QACP,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAK;KAC3B;IAED,OAAO,WAAW,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;IAErC,SAAS,aAAa;QACpB,OAAO,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,KAAK,CAAA;IACtC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"use-is-first-render.js","sourceRoot":"","sources":["../src/use-is-first-render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAE3C,IAAK,KAIJ;AAJD,WAAK,KAAK;IACR,iDAAY,CAAA;IACZ,mCAAK,CAAA;IACL,yCAAQ,CAAA;AACV,CAAC,EAJI,KAAK,KAAL,KAAK,QAIT;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAExC,QAAQ,KAAK,CAAC,OAAO,EAAE,CAAC;QACtB,KAAK,KAAK,CAAC,YAAY;YACrB,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,CAAA;YAC3B,MAAK;QACP,KAAK,KAAK,CAAC,KAAK;YACd,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAA;YAC9B,MAAK;QACP,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAK;IAC5B,CAAC;IAED,OAAO,WAAW,CAAC,aAAa,EAAE,EAAE,CAAC,CAAA;IAErC,SAAS,aAAa;QACpB,OAAO,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,KAAK,CAAA;IACtC,CAAC;AACH,CAAC"}
@@ -1,2 +1 @@
1
- /// <reference types="react" />
2
1
  export declare function useMemoWithCleanup<T>(factory: () => T, cleanup: (value: T) => void, deps?: React.DependencyList): T;
@@ -1 +1 @@
1
- {"version":3,"file":"use-memo-with-cleanup.js","sourceRoot":"","sources":["../src/use-memo-with-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAE1C,MAAM,UAAU,kBAAkB,CAChC,OAAgB,EAChB,OAA2B,EAC3B,IAA2B;IAE3B,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAEpC,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC,EAAE,IAAI,CAAC,CAAA;IAER,OAAO,KAAK,CAAA;AACd,CAAC"}
1
+ {"version":3,"file":"use-memo-with-cleanup.js","sourceRoot":"","sources":["../src/use-memo-with-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAE1C,MAAM,UAAU,kBAAkB,CAChC,OAAgB,EAChB,OAA2B,EAC3B,IAA2B;IAE3B,MAAM,KAAK,GAAG,OAAO,CACnB,OAAO,EAEP,IAAI,CACL,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC,EAAE,IAAI,CAAC,CAAA;IAER,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-multiple-selection.js","sourceRoot":"","sources":["../src/use-multiple-selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAiB,MAAM,qBAAqB,CAAA;AAEpE,OAAO,EAAE,OAAO,EAAE,sBAAwB;AAE1C,MAAM,UAAU,oBAAoB,CAClC,OAAyB,EACzB,yBAAmC,EAAE;IAQrC,OAAO,CAAC,GAAG,EAAE;QACX,KAAK,MAAM,KAAK,IAAI,sBAAsB,EAAE;YAC1C,MAAM,CACJ,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,EACpC,0FAA0F,CAC3F,CAAA;SACF;IACH,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAE5B,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,IAAI,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAEvF,OAAO;QACL,eAAe,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;QAC3E,YAAY,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QACrE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,eAAe,CAAC,CAAC;QAC9C,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;QAC/B,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC;KACpC,CAAA;IAED,SAAS,kBAAkB;QACzB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;YAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;YAClC,OAAO,EAAE,QAAQ,EAAE,CAAA;QACrB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,UAAU,CAAC,KAAa;QAC/B,OAAO,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC;IAED,SAAS,MAAM,CAAC,KAAa;QAC3B,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE;YACrB,QAAQ,CAAC,KAAK,CAAC,CAAA;SAChB;aAAM;YACL,MAAM,CAAC,KAAK,CAAC,CAAA;SACd;IACH,CAAC;IAED,SAAS,MAAM,CAAC,KAAa;QAC3B,kBAAkB,CAAC,eAAe,CAAC,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAA;YACvC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACjB,OAAO,MAAM,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,QAAQ,CAAC,KAAa;QAC7B,kBAAkB,CAAC,eAAe,CAAC,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAA;YACvC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACpB,OAAO,MAAM,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"use-multiple-selection.js","sourceRoot":"","sources":["../src/use-multiple-selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAiB,MAAM,qBAAqB,CAAA;AAEpE,OAAO,EAAE,OAAO,EAAE,sBAAwB;AAE1C,MAAM,UAAU,oBAAoB,CAClC,OAAyB,EACzB,yBAAmC,EAAE;IAQrC,OAAO,CAAC,GAAG,EAAE;QACX,KAAK,MAAM,KAAK,IAAI,sBAAsB,EAAE,CAAC;YAC3C,MAAM,CACJ,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,OAAO,CAAC,MAAM,EACpC,0FAA0F,CAC3F,CAAA;QACH,CAAC;IACH,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAE5B,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,IAAI,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAA;IAEvF,OAAO;QACL,eAAe,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;QAC3E,YAAY,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QACrE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,eAAe,CAAC,CAAC;QAC9C,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;QAC/B,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC;KACpC,CAAA;IAED,SAAS,kBAAkB;QACzB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;YAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;YAClC,OAAO,EAAE,QAAQ,EAAE,CAAA;QACrB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,UAAU,CAAC,KAAa;QAC/B,OAAO,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC;IAED,SAAS,MAAM,CAAC,KAAa;QAC3B,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACtB,QAAQ,CAAC,KAAK,CAAC,CAAA;QACjB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,CAAA;QACf,CAAC;IACH,CAAC;IAED,SAAS,MAAM,CAAC,KAAa;QAC3B,kBAAkB,CAAC,eAAe,CAAC,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAA;YACvC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACjB,OAAO,MAAM,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,QAAQ,CAAC,KAAa;QAC7B,kBAAkB,CAAC,eAAe,CAAC,EAAE;YACnC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,CAAA;YACvC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACpB,OAAO,MAAM,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function useNumberInput({ value, lazy, onChange }: {
2
+ value: number;
3
+ lazy?: boolean;
4
+ onChange(value: number): void;
5
+ }): {
6
+ getInputProps(): Required<Pick<React.ComponentPropsWithoutRef<'input'>, 'value' | 'onChange' | 'onBlur'>>;
7
+ };
@@ -0,0 +1,49 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { isntNaN } from 'extra-utils';
3
+ export function useNumberInput({ value, lazy, onChange }) {
4
+ const [displayValue, setDisplayValue] = useState(() => value.toString());
5
+ useEffect(() => {
6
+ if (!lazy) {
7
+ const oldValue = Number(displayValue);
8
+ if (oldValue !== value)
9
+ setDisplayValue(value.toString());
10
+ }
11
+ }, [value, displayValue]);
12
+ useEffect(() => {
13
+ if (lazy) {
14
+ setDisplayValue(value.toString());
15
+ }
16
+ }, [value]);
17
+ return {
18
+ getInputProps() {
19
+ return {
20
+ value: displayValue,
21
+ onChange(e) {
22
+ setDisplayValue(e.target.value);
23
+ if (e.target.reportValidity()) {
24
+ if (!lazy) {
25
+ const newValue = e.target.valueAsNumber;
26
+ if (isntNaN(newValue) && newValue !== value) {
27
+ onChange(newValue);
28
+ }
29
+ }
30
+ }
31
+ },
32
+ onBlur(e) {
33
+ if (e.target.checkValidity()) {
34
+ if (lazy) {
35
+ const newValue = e.target.valueAsNumber;
36
+ if (isntNaN(newValue) && newValue !== value) {
37
+ onChange(newValue);
38
+ setDisplayValue(newValue.toString());
39
+ return;
40
+ }
41
+ }
42
+ }
43
+ setDisplayValue(value.toString());
44
+ }
45
+ };
46
+ }
47
+ };
48
+ }
49
+ //# sourceMappingURL=use-number-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-number-input.js","sourceRoot":"","sources":["../src/use-number-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC,MAAM,UAAU,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAKrD;IAQC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAS,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;IAEhF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;YAGrC,IAAI,QAAQ,KAAK,KAAK;gBAAE,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAA;IAEzB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,IAAI,EAAE,CAAC;YAGT,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;QACnC,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,OAAO;QACL,aAAa;YACX,OAAO;gBACL,KAAK,EAAE,YAAY;gBACnB,QAAQ,CAAC,CAAC;oBACR,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;oBAE/B,IAAI,CAAC,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;wBAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;4BACV,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAA;4BAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gCAC5C,QAAQ,CAAC,QAAQ,CAAC,CAAA;4BACpB,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,MAAM,CAAC,CAAC;oBACN,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,CAAC;wBAC7B,IAAI,IAAI,EAAE,CAAC;4BACT,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAA;4BAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gCAC5C,QAAQ,CAAC,QAAQ,CAAC,CAAA;gCAIlB,eAAe,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;gCAEpC,OAAM;4BACR,CAAC;wBACH,CAAC;oBACH,CAAC;oBAGD,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAA;gBACnC,CAAC;aACF,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -1,2 +1,2 @@
1
- import { RefObject, MutableRefObject } from 'react';
2
- export declare function useResizeObserver(callback: ResizeObserverCallback, refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>, deps?: React.DependencyList): void;
1
+ import { RefObject } from 'react';
2
+ export declare function useResizeObserver(callback: ResizeObserverCallback, refs: Array<RefObject<HTMLElement | null | undefined>>, deps?: React.DependencyList): void;
@@ -1,11 +1,12 @@
1
1
  import { useEffect } from 'react';
2
- import { isntNull } from '@blackglory/prelude';
2
+ import { isntNull, isntUndefined } from '@blackglory/prelude';
3
3
  export function useResizeObserver(callback, refs, deps) {
4
4
  useEffect(() => {
5
5
  const observer = new ResizeObserver(callback);
6
6
  refs
7
7
  .map(x => x.current)
8
8
  .filter(isntNull)
9
+ .filter(isntUndefined)
9
10
  .forEach(x => observer.observe(x));
10
11
  return () => observer.disconnect();
11
12
  }, deps);
@@ -1 +1 @@
1
- {"version":3,"file":"use-resize-observer.js","sourceRoot":"","sources":["../src/use-resize-observer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA+B,MAAM,OAAO,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE9C,MAAM,UAAU,iBAAiB,CAC/B,QAAgC,EAChC,IAAmE,EACnE,IAA2B;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAA;QAE7C,IAAI;aACD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;aACnB,MAAM,CAAC,QAAQ,CAAC;aAChB,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;QAEpC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAA;IACpC,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
1
+ {"version":3,"file":"use-resize-observer.js","sourceRoot":"","sources":["../src/use-resize-observer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,OAAO,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAE7D,MAAM,UAAU,iBAAiB,CAC/B,QAAgC,EAChC,IAAsD,EACtD,IAA2B;IAE3B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAA;QAE7C,IAAI;aACD,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;aACnB,MAAM,CAAC,QAAQ,CAAC;aAChB,MAAM,CAAC,aAAa,CAAC;aACrB,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;QAEpC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAA;IACpC,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-state-cycle.js","sourceRoot":"","sources":["../src/use-state-cycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAG7C,MAAM,UAAU,aAAa,CAC3B,aAA+B,EAC/B,oBAA4B,CAAC;IAE7B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAA;IAErD,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;IAEjE,SAAS,IAAI;QACX,QAAQ,CAAC,KAAK,CAAC,EAAE;YACf,IAAI,KAAK,GAAG,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE;gBACpC,OAAO,KAAK,GAAG,CAAC,CAAA;aACjB;iBAAM;gBACL,OAAO,CAAC,CAAA;aACT;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"use-state-cycle.js","sourceRoot":"","sources":["../src/use-state-cycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAG7C,MAAM,UAAU,aAAa,CAC3B,aAA+B,EAC/B,oBAA4B,CAAC;IAE7B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAA;IAErD,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;IAEjE,SAAS,IAAI;QACX,QAAQ,CAAC,KAAK,CAAC,EAAE;YACf,IAAI,KAAK,GAAG,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;gBACrC,OAAO,KAAK,GAAG,CAAC,CAAA;YAClB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,CAAA;YACV,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-step.js","sourceRoot":"","sources":["../src/use-step.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAG7C,MAAM,UAAU,OAAO,CACrB,KAAuB,EACvB,mBAA2B,CAAC;IAE5B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAA;IAEpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IAE5E,SAAS,IAAI;QACX,QAAQ,CAAC,KAAK,CAAC,EAAE;YACf,IAAI,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC9B,OAAO,KAAK,CAAA;aACb;iBAAM;gBACL,OAAO,KAAK,GAAG,CAAC,CAAA;aACjB;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,QAAQ;QACf,QAAQ,CAAC,KAAK,CAAC,EAAE;YACf,IAAI,KAAK,KAAK,CAAC,EAAE;gBACf,OAAO,KAAK,CAAA;aACb;iBAAM;gBACL,OAAO,KAAK,GAAG,CAAC,CAAA;aACjB;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"use-step.js","sourceRoot":"","sources":["../src/use-step.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAG7C,MAAM,UAAU,OAAO,CACrB,KAAuB,EACvB,mBAA2B,CAAC;IAE5B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAA;IAEpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAA;IAE5E,SAAS,IAAI;QACX,QAAQ,CAAC,KAAK,CAAC,EAAE;YACf,IAAI,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,OAAO,KAAK,CAAA;YACd,CAAC;iBAAM,CAAC;gBACN,OAAO,KAAK,GAAG,CAAC,CAAA;YAClB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,SAAS,QAAQ;QACf,QAAQ,CAAC,KAAK,CAAC,EAAE;YACf,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,OAAO,KAAK,CAAA;YACd,CAAC;iBAAM,CAAC;gBACN,OAAO,KAAK,GAAG,CAAC,CAAA;YAClB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-update-effect.js","sourceRoot":"","sources":["../src/use-update-effect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE3D,MAAM,UAAU,eAAe,CAC7B,MAAsB,EACtB,IAA2B;IAE3B,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAA;IAExC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,EAAE,EAAE;YACpB,OAAO,MAAM,EAAE,CAAA;SAChB;IACH,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
1
+ {"version":3,"file":"use-update-effect.js","sourceRoot":"","sources":["../src/use-update-effect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAkB,MAAM,OAAO,CAAA;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE3D,MAAM,UAAU,eAAe,CAC7B,MAAsB,EACtB,IAA2B;IAE3B,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAA;IAExC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YACrB,OAAO,MAAM,EAAE,CAAA;QACjB,CAAC;IACH,CAAC,EAAE,IAAI,CAAC,CAAA;AACV,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "extra-react-hooks",
3
- "version": "0.7.1",
3
+ "version": "0.8.1",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "files": [
@@ -19,7 +19,7 @@
19
19
  "license": "MIT",
20
20
  "scripts": {
21
21
  "prepare": "ts-patch install -s",
22
- "lint": "eslint --ext .js,.jsx,.ts,.tsx --quiet src __tests__",
22
+ "lint": "eslint --quiet src __tests__",
23
23
  "test": "karma start karma.config.cjs --single-run",
24
24
  "test:dev": "karma start karma.config.cjs",
25
25
  "prepublishOnly": "run-s prepare clean build",
@@ -37,43 +37,46 @@
37
37
  "@blackglory/wait-for": "^0.7.4",
38
38
  "@commitlint/cli": "^17.6.5",
39
39
  "@commitlint/config-conventional": "^17.6.5",
40
- "@testing-library/react": "^14.0.0",
41
- "@types/jasmine": "^4.3.2",
42
- "@types/react": "^18.2.11",
43
- "@typescript-eslint/eslint-plugin": "^5.59.9",
44
- "@typescript-eslint/parser": "^5.59.9",
45
- "eslint": "^8.42.0",
46
- "eslint-plugin-react": "^7.32.2",
47
- "eslint-plugin-react-hooks": "^4.6.0",
40
+ "@eslint/js": "^9.18.0",
41
+ "@testing-library/dom": "^10.4.0",
42
+ "@testing-library/react": "^16.1.0",
43
+ "@testing-library/user-event": "^14.6.1",
44
+ "@types/jasmine": "^5.1.5",
45
+ "@types/react": "^19.0.7",
46
+ "eslint": "^9.18.0",
47
+ "eslint-plugin-react": "^7.37.4",
48
+ "eslint-plugin-react-hooks": "^5.1.0",
48
49
  "husky": "4",
49
- "karma": "^6.4.2",
50
+ "karma": "^6.4.4",
50
51
  "karma-chrome-launcher": "^3.2.0",
51
52
  "karma-jasmine": "^5.1.0",
52
- "karma-webpack": "^5.0.0",
53
+ "karma-webpack": "^5.0.1",
53
54
  "npm-run-all": "^4.1.5",
54
- "react": "^18.2.0",
55
- "react-dom": "^18.2.0",
56
- "react-test-renderer": "^18.2.0",
55
+ "react": "^19.0.0",
56
+ "react-dom": "^19.0.0",
57
+ "react-test-renderer": "^19.0.0",
57
58
  "return-style": "^3.0.1",
58
59
  "rimraf": "^4.3.0",
59
60
  "standard-version": "^9.3.2",
60
- "ts-loader": "^9.4.3",
61
- "ts-patch": "^2.1.0",
62
- "tsconfig-paths-webpack-plugin": "^4.0.1",
63
- "tslib": "^2.5.3",
64
- "typescript": "4.9.5",
65
- "typescript-transform-paths": "^3.4.6",
66
- "webpack": "^5.86.0"
61
+ "ts-loader": "^9.5.2",
62
+ "ts-patch": "^3.3.0",
63
+ "tsconfig-paths-webpack-plugin": "^4.2.0",
64
+ "tslib": "^2.8.1",
65
+ "typescript": "5.7.3",
66
+ "typescript-eslint": "^8.20.0",
67
+ "typescript-transform-paths": "^3.5.3",
68
+ "webpack": "^5.97.1"
67
69
  },
68
70
  "dependencies": {
69
71
  "@blackglory/errors": "^3.0.3",
70
72
  "@blackglory/prelude": "^0.4.0",
71
73
  "extra-abort": "^0.4.0",
72
74
  "extra-fsm": "^0.2.1",
75
+ "extra-timers": "^0.2.6",
73
76
  "extra-utils": "^5.17.0",
74
77
  "rxjs": "^7.8.1"
75
78
  },
76
79
  "peerDependencies": {
77
- "react": "^17 || ^18"
80
+ "react": "^19"
78
81
  }
79
82
  }
package/src/index.ts CHANGED
@@ -21,3 +21,5 @@ export * from './use-iife.js'
21
21
  export * from './use-memo-with-cleanup.js'
22
22
  export * from './use-get-set.js'
23
23
  export * from './use-isomorphic-layout-effect.js'
24
+ export * from './use-debounce.js'
25
+ export * from './use-number-input.js'
@@ -1,11 +1,11 @@
1
- import { useCallback, DependencyList } from 'react'
1
+ import { useCallback } from 'react'
2
2
  import { AbortController, raceAbortSignals } from 'extra-abort'
3
3
  import { useMemoWithCleanup } from './use-memo-with-cleanup.js'
4
4
  import { Falsy } from '@blackglory/prelude'
5
5
 
6
6
  export function useAbortableCallback<Args extends unknown[], Result>(
7
7
  callback: (...args: [...args: Args, signal: AbortSignal]) => PromiseLike<Result>
8
- , deps: DependencyList
8
+ , deps: React.DependencyList
9
9
  ): (...args: [...args: Args, signal: AbortSignal | Falsy]) => Promise<Result> {
10
10
  const controller = useMemoWithCleanup(
11
11
  () => new AbortController()
@@ -0,0 +1,25 @@
1
+ import { useRef, useEffect } from 'react'
2
+ import { setTimeout } from 'extra-timers'
3
+
4
+ export function useDebounce<Args extends unknown[]>(
5
+ fn: (...args: Args) => void
6
+ , timeout: number
7
+ , deps?: React.DependencyList
8
+ ): (...args: Args) => void {
9
+ const fnRef = useRef<(...args: Args) => void>(fn)
10
+ const cancelTimeoutRef = useRef<() => void>(undefined)
11
+
12
+ useEffect(() => {
13
+ fnRef.current = fn
14
+ }, deps)
15
+
16
+ return (...args: Args): void => {
17
+ cancelTimeoutRef.current?.()
18
+
19
+ cancelTimeoutRef.current = setTimeout(timeout, () => {
20
+ fnRef.current(...args)
21
+
22
+ cancelTimeoutRef.current = undefined
23
+ })
24
+ }
25
+ }
@@ -1,4 +1,4 @@
1
- import { useEffect, DependencyList } from 'react'
1
+ import { useEffect } from 'react'
2
2
  import { go, pass } from '@blackglory/prelude'
3
3
  import { AbortController } from 'extra-abort'
4
4
  import { CustomError } from '@blackglory/errors'
@@ -7,7 +7,7 @@ class InternalAbortError extends CustomError {}
7
7
 
8
8
  export function useEffectAsync(
9
9
  effect: (signal: AbortSignal) => Promise<void>
10
- , deps?: DependencyList
10
+ , deps?: React.DependencyList
11
11
  ): void {
12
12
  useEffect(() => {
13
13
  const controller = new AbortController()
@@ -1,27 +1,27 @@
1
- import { useEffect, RefObject, MutableRefObject } from 'react'
2
- import { assert, isArray, isntNull } from '@blackglory/prelude'
1
+ import { useEffect, RefObject } from 'react'
2
+ import { isArray, isntNull, isntUndefined } from '@blackglory/prelude'
3
3
 
4
4
  export function useIntersectionObserver(
5
5
  callback: IntersectionObserverCallback
6
6
  , options: IntersectionObserverInit | undefined
7
- , refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
7
+ , refs: Array<RefObject<HTMLElement | undefined | null>>
8
8
  , deps?: React.DependencyList
9
9
  ): void
10
10
  export function useIntersectionObserver(
11
11
  callback: IntersectionObserverCallback
12
- , refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
12
+ , refs: Array<RefObject<HTMLElement | undefined | null>>
13
13
  , deps?: React.DependencyList
14
14
  ): void
15
15
  export function useIntersectionObserver(...args:
16
16
  | [
17
17
  callback: IntersectionObserverCallback
18
18
  , options: IntersectionObserverInit | undefined
19
- , refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
19
+ , refs: Array<RefObject<HTMLElement | undefined | null>>
20
20
  , deps?: React.DependencyList
21
21
  ]
22
22
  | [
23
23
  callback: IntersectionObserverCallback
24
- , refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
24
+ , refs: Array<RefObject<HTMLElement | undefined | null>>
25
25
  , deps?: React.DependencyList
26
26
  ]
27
27
  ): void {
@@ -29,7 +29,6 @@ export function useIntersectionObserver(...args:
29
29
  case 2: {
30
30
  const [callback, refs] = args
31
31
 
32
- // eslint-disable-next-line react-hooks/rules-of-hooks
33
32
  return useIntersectionObserver(callback, undefined, refs)
34
33
  }
35
34
  case 3: {
@@ -38,13 +37,11 @@ export function useIntersectionObserver(...args:
38
37
  const refs = optionsOrRefs
39
38
  const deps = refsOrDeps as React.DependencyList | undefined
40
39
 
41
- // eslint-disable-next-line react-hooks/rules-of-hooks
42
40
  return useIntersectionObserver(callback, undefined, refs, deps)
43
41
  } else {
44
42
  const options = optionsOrRefs
45
- const refs = refsOrDeps as Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
43
+ const refs = refsOrDeps as Array<RefObject<HTMLElement>>
46
44
 
47
- // eslint-disable-next-line react-hooks/rules-of-hooks
48
45
  return useIntersectionObserver(callback, options, refs)
49
46
  }
50
47
  }
@@ -52,13 +49,13 @@ export function useIntersectionObserver(...args:
52
49
 
53
50
  const [callback, options, refs, deps] = args
54
51
 
55
- // eslint-disable-next-line react-hooks/rules-of-hooks
56
52
  useEffect(() => {
57
53
  const observer = new IntersectionObserver(callback, options)
58
54
 
59
55
  refs
60
56
  .map(x => x.current)
61
57
  .filter(isntNull)
58
+ .filter(isntUndefined)
62
59
  .forEach(x => observer.observe(x))
63
60
 
64
61
  return () => observer.disconnect()
@@ -5,7 +5,11 @@ export function useMemoWithCleanup<T>(
5
5
  , cleanup: (value: T) => void
6
6
  , deps?: React.DependencyList
7
7
  ): T {
8
- const value = useMemo(factory, deps)
8
+ const value = useMemo(
9
+ factory
10
+ // @ts-ignore
11
+ , deps
12
+ )
9
13
 
10
14
  useEffect(() => {
11
15
  return () => cleanup(value)
@@ -0,0 +1,76 @@
1
+ import { useEffect, useState } from 'react'
2
+ import { isntNaN } from 'extra-utils'
3
+
4
+ export function useNumberInput({ value, lazy, onChange }: {
5
+ value: number
6
+ lazy?: boolean
7
+
8
+ onChange(value: number): void
9
+ }): {
10
+ getInputProps(): Required<Pick<
11
+ React.ComponentPropsWithoutRef<'input'>
12
+ , 'value'
13
+ | 'onChange'
14
+ | 'onBlur'
15
+ >>
16
+ } {
17
+ const [displayValue, setDisplayValue] = useState<string>(() => value.toString())
18
+
19
+ useEffect(() => {
20
+ if (!lazy) {
21
+ const oldValue = Number(displayValue)
22
+
23
+ // 以传入的值为准, 但只有在实际代表的值不同时, 才更新.
24
+ if (oldValue !== value) setDisplayValue(value.toString())
25
+ }
26
+ }, [value, displayValue])
27
+
28
+ useEffect(() => {
29
+ if (lazy) {
30
+ // 以传入的值为准.
31
+ // 由于onChange是惰性调用, 不需要检查值的相等性.
32
+ setDisplayValue(value.toString())
33
+ }
34
+ }, [value])
35
+
36
+ return {
37
+ getInputProps() {
38
+ return {
39
+ value: displayValue
40
+ , onChange(e) {
41
+ setDisplayValue(e.target.value)
42
+
43
+ if (e.target.reportValidity()) {
44
+ if (!lazy) {
45
+ const newValue = e.target.valueAsNumber
46
+
47
+ if (isntNaN(newValue) && newValue !== value) {
48
+ onChange(newValue)
49
+ }
50
+ }
51
+ }
52
+ }
53
+ , onBlur(e) {
54
+ if (e.target.checkValidity()) {
55
+ if (lazy) {
56
+ const newValue = e.target.valueAsNumber
57
+
58
+ if (isntNaN(newValue) && newValue !== value) {
59
+ onChange(newValue)
60
+
61
+ // 使用格式化后的新值.
62
+ // 若hook的调用方决定不接受新值, 则displayValue的值会被覆盖.
63
+ setDisplayValue(newValue.toString())
64
+
65
+ return
66
+ }
67
+ }
68
+ }
69
+
70
+ // 继续使用旧值, 但对旧值格式化.
71
+ setDisplayValue(value.toString())
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
@@ -1,9 +1,9 @@
1
- import { useEffect, RefObject, MutableRefObject } from 'react'
2
- import { isntNull } from '@blackglory/prelude'
1
+ import { useEffect, RefObject } from 'react'
2
+ import { isntNull, isntUndefined } from '@blackglory/prelude'
3
3
 
4
4
  export function useResizeObserver(
5
5
  callback: ResizeObserverCallback
6
- , refs: Array<RefObject<HTMLElement> | MutableRefObject<HTMLElement>>
6
+ , refs: Array<RefObject<HTMLElement | null | undefined>>
7
7
  , deps?: React.DependencyList
8
8
  ): void {
9
9
  useEffect(() => {
@@ -12,6 +12,7 @@ export function useResizeObserver(
12
12
  refs
13
13
  .map(x => x.current)
14
14
  .filter(isntNull)
15
+ .filter(isntUndefined)
15
16
  .forEach(x => observer.observe(x))
16
17
 
17
18
  return () => observer.disconnect()