@vertigis/react-ui 11.1.0 → 11.2.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertigis/react-ui",
3
- "version": "11.1.0",
3
+ "version": "11.2.0",
4
4
  "description": "Utilities and React components used in VertiGIS applications.",
5
5
  "keywords": [
6
6
  "vertigis",
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Debounces a function, i.e. creates a wrapper that only invokes the original
3
+ * once a certain amount of time has elapsed without being invoked.
4
+ *
5
+ * @param func The original function.
6
+ * @param wait The amount of time to wait for inactivity (in milliseconds).
7
+ * @param immediate If true, trigger the function on the leading edge, instead
8
+ * of the trailing.
9
+ */
10
+ export declare function debounce<T extends unknown[]>(func: (...args: [...T]) => void, wait: number, immediate?: boolean): (...args: [...T]) => void;
11
+ /**
12
+ * Same as `debounce()`, but optimized for animation and rendering.
13
+ *
14
+ * @param func The function to debounce.
15
+ */
16
+ export declare function debounceAnimation<T extends unknown[]>(func: (...args: [...T]) => void): (...args: [...T]) => void;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Debounces a function, i.e. creates a wrapper that only invokes the original
3
+ * once a certain amount of time has elapsed without being invoked.
4
+ *
5
+ * @param func The original function.
6
+ * @param wait The amount of time to wait for inactivity (in milliseconds).
7
+ * @param immediate If true, trigger the function on the leading edge, instead
8
+ * of the trailing.
9
+ */
10
+ export function debounce(func, wait, immediate) {
11
+ // Taken from https://davidwalsh.name/function-debounce, originally from Underscore.js
12
+ let timeout;
13
+ return (...args) => {
14
+ const later = () => {
15
+ timeout = undefined;
16
+ if (!immediate) {
17
+ func(...args);
18
+ }
19
+ };
20
+ const callNow = immediate && !timeout;
21
+ clearTimeout(timeout);
22
+ timeout = window.setTimeout(later, wait);
23
+ if (callNow) {
24
+ func(...args);
25
+ }
26
+ };
27
+ }
28
+ /**
29
+ * Same as `debounce()`, but optimized for animation and rendering.
30
+ *
31
+ * @param func The function to debounce.
32
+ */
33
+ export function debounceAnimation(func) {
34
+ let token;
35
+ return (...args) => {
36
+ cancelAnimationFrame(token);
37
+ token = requestAnimationFrame(() => func(...args));
38
+ };
39
+ }
package/utils/react.d.ts CHANGED
@@ -13,3 +13,22 @@ export declare function useId(idProp?: string): string;
13
13
  * supports forwarding a ref from its parent component.
14
14
  */
15
15
  export declare function mergeRefs<T>(...refs: (RefCallback<T> | MutableRefObject<T | null> | null)[]): Ref<T>;
16
+ /**
17
+ * Returns the previous value of updated props or state.
18
+ *
19
+ * @param value The original value of the property.
20
+ */
21
+ export declare function usePrevious<T = unknown>(value: T | undefined): T | undefined;
22
+ /**
23
+ * A simple, unoptimized implementation of useResizeObserver.
24
+ *
25
+ * @param target The node to observe.
26
+ * @param callback Called when a change is observed.
27
+ */
28
+ export declare function useResizeObserver<T extends HTMLElement = HTMLElement>(target: T, callback: (entry: ResizeObserverEntry) => void): void;
29
+ /**
30
+ * Gets the dimensions of an element.
31
+ *
32
+ * @param target A ref to the target element.
33
+ */
34
+ export declare function useContentRect<T extends HTMLElement = HTMLElement>(target: React.RefObject<T | undefined> | React.MutableRefObject<T | undefined> | T): DOMRectReadOnly;
package/utils/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { useState } from "react";
1
+ import { useCallback, useLayoutEffect, useEffect, useRef, useState } from "react";
2
2
  /**
3
3
  * Generate a random 10 digit id.
4
4
  *
@@ -40,3 +40,59 @@ export function mergeRefs(...refs) {
40
40
  });
41
41
  };
42
42
  }
43
+ /**
44
+ * Returns the previous value of updated props or state.
45
+ *
46
+ * @param value The original value of the property.
47
+ */
48
+ export function usePrevious(value) {
49
+ const ref = useRef();
50
+ useEffect(() => {
51
+ ref.current = value;
52
+ }, [value]);
53
+ return ref.current;
54
+ }
55
+ /**
56
+ * A simple, unoptimized implementation of useResizeObserver.
57
+ *
58
+ * @param target The node to observe.
59
+ * @param callback Called when a change is observed.
60
+ */
61
+ export function useResizeObserver(target, callback) {
62
+ const observer = useRef();
63
+ const disconnect = useCallback(() => observer.current?.disconnect(), []);
64
+ const observe = useCallback(() => {
65
+ if (window.ResizeObserver) {
66
+ observer.current = new ResizeObserver(([entry]) => callback(entry));
67
+ if (target) {
68
+ observer.current.observe(target);
69
+ }
70
+ }
71
+ }, [callback, target]);
72
+ useLayoutEffect(() => {
73
+ observe();
74
+ return () => disconnect();
75
+ }, [disconnect, observe]);
76
+ }
77
+ /**
78
+ * Gets the dimensions of an element.
79
+ *
80
+ * @param target A ref to the target element.
81
+ */
82
+ export function useContentRect(target) {
83
+ const [rect, setRect] = useState();
84
+ const [element, setElement] = useState();
85
+ useLayoutEffect(() => {
86
+ const el = Object.prototype.hasOwnProperty.call(target, "current")
87
+ ? target.current
88
+ : target;
89
+ setRect(el?.getBoundingClientRect());
90
+ setElement(el);
91
+ }, [target]);
92
+ useResizeObserver(element, entry => {
93
+ if (entry.contentRect.height !== rect?.height || entry.contentRect.width !== rect?.width) {
94
+ setRect(entry.contentRect);
95
+ }
96
+ });
97
+ return rect ?? {};
98
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Throttles a function so it can only be fired once per given period of
3
+ * milliseconds. If the function is called during the throttling period, the
4
+ * last instance of the function being called will be run once the throttling
5
+ * period ends. The callback is always invoked asynchronously.
6
+ *
7
+ * @param func The function to be throttled.
8
+ * @param msBetweenRequests The minimum time between requests.
9
+ */
10
+ export declare function throttle<T extends unknown[]>(func: (...args: [...T]) => void | Promise<void>, msBetweenRequests: number): (...args: [...T]) => void | Promise<void>;
11
+ /**
12
+ * Same as `throttle()`, but optimized for animation and rendering.
13
+ *
14
+ * @param func The function to throttle.
15
+ */
16
+ export declare function throttleAnimation<T extends unknown[]>(func: (...args: [...T]) => void | Promise<void>): (...args: [...T]) => void | Promise<void>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Throttles a function so it can only be fired once per given period of
3
+ * milliseconds. If the function is called during the throttling period, the
4
+ * last instance of the function being called will be run once the throttling
5
+ * period ends. The callback is always invoked asynchronously.
6
+ *
7
+ * @param func The function to be throttled.
8
+ * @param msBetweenRequests The minimum time between requests.
9
+ */
10
+ export function throttle(func, msBetweenRequests) {
11
+ let isScheduled = false;
12
+ return (...args) => {
13
+ if (!isScheduled) {
14
+ window.setTimeout(() => {
15
+ isScheduled = false;
16
+ void func(...args);
17
+ }, msBetweenRequests);
18
+ isScheduled = true;
19
+ }
20
+ };
21
+ }
22
+ /**
23
+ * Same as `throttle()`, but optimized for animation and rendering.
24
+ *
25
+ * @param func The function to throttle.
26
+ */
27
+ export function throttleAnimation(func) {
28
+ let isScheduled = false;
29
+ return (...args) => {
30
+ if (!isScheduled) {
31
+ requestAnimationFrame(() => {
32
+ isScheduled = false;
33
+ void func(...args);
34
+ });
35
+ isScheduled = true;
36
+ }
37
+ };
38
+ }