@vertigis/react-ui 18.0.2 → 19.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vertigis/react-ui",
3
- "version": "18.0.2",
3
+ "version": "19.0.1",
4
4
  "description": "Utilities and React components used in VertiGIS applications.",
5
5
  "keywords": [
6
6
  "vertigis",
package/styles/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export type * from "../styles/themeAugmentation.js";
2
2
  export { alpha, ThemeProvider as GcxThemeProvider, createStyles, darken, decomposeColor, duration, easing, emphasize, getContrastRatio, getLuminance, hexToRgb, hslToRgb, lighten, recomposeColor, responsiveFontSizes, rgbToHex, styled, useTheme, } from "@mui/material/styles";
3
3
  export type { ColorFormat, ColorObject, ComponentsPropsList, CSSObject, Duration, Easing, PaletteColorOptions, SimplePaletteColorOptions, Transitions, TransitionsOptions, TypographyStyle, TypographyVariant, } from "@mui/material/styles";
4
+ export type { CSSProperties } from "@mui/material/styles/createMixins";
4
5
  export type { ThemeProviderProps } from "@mui/material/styles/ThemeProvider";
5
6
  export { default as CacheProvider, createCache } from "./CacheProvider.js";
6
7
  export { default as createTheme } from "./createTheme.js";
@@ -6,11 +6,24 @@
6
6
  * @param wait The amount of time to wait for inactivity (in milliseconds).
7
7
  * @param immediate If true, trigger the function on the leading edge, instead
8
8
  * of the trailing.
9
+ * @param abortSignal Optionally specify an abortSignal for the throttled
10
+ * function.
9
11
  */
10
- export declare function debounce<T extends unknown[]>(func: (...args: [...T]) => void, wait: number, immediate?: boolean): (...args: [...T]) => void;
12
+ export declare function debounce<T extends unknown[]>(func: (...args: [...T]) => void, wait: number, immediate?: boolean, abortSignal?: AbortSignal): (...args: [...T]) => void;
11
13
  /**
12
14
  * Same as `debounce()`, but optimized for animation and rendering.
13
15
  *
14
16
  * @param func The function to debounce.
17
+ * @param abortSignal Optionally specify an abortSignal for the throttled
18
+ * function.
15
19
  */
16
- export declare function debounceAnimation<T extends unknown[]>(func: (...args: [...T]) => void): (...args: [...T]) => void;
20
+ export declare function debounceAnimation<T extends unknown[]>(func: (...args: [...T]) => void, abortSignal?: AbortSignal): (...args: [...T]) => void;
21
+ /**
22
+ * Returns a debounced and memoized version of the callback that only changes if
23
+ * one of the `deps` has changed.
24
+ *
25
+ * @param callback The function to debounce and memoize.
26
+ * @param timeout The debounce delay.
27
+ * @param deps The dependencies of the callback.
28
+ */
29
+ export declare function useDebounce<T extends unknown[]>(callback: (...args: [...T]) => void, timeout: number, deps: unknown[]): (...args: [...T]) => void;
package/utils/debounce.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { useCallback, useEffect, useRef } from "react";
1
2
  /**
2
3
  * Debounces a function, i.e. creates a wrapper that only invokes the original
3
4
  * once a certain amount of time has elapsed without being invoked.
@@ -6,34 +7,82 @@
6
7
  * @param wait The amount of time to wait for inactivity (in milliseconds).
7
8
  * @param immediate If true, trigger the function on the leading edge, instead
8
9
  * of the trailing.
10
+ * @param abortSignal Optionally specify an abortSignal for the throttled
11
+ * function.
9
12
  */
10
- export function debounce(func, wait, immediate) {
11
- // Taken from https://davidwalsh.name/function-debounce, originally from Underscore.js
13
+ export function debounce(func, wait, immediate, abortSignal) {
12
14
  let timeout;
15
+ const cleanup = () => {
16
+ window.clearTimeout(timeout);
17
+ abortSignal?.removeEventListener("abort", cleanup);
18
+ timeout = undefined;
19
+ };
13
20
  return (...args) => {
14
21
  const later = () => {
15
- timeout = undefined;
16
- if (!immediate) {
22
+ cleanup();
23
+ // Do not execute here if 'immediate=true` this function is just a
24
+ // timer to block execution until completed.
25
+ if (!immediate && !abortSignal?.aborted) {
17
26
  func(...args);
18
27
  }
19
28
  };
29
+ if (abortSignal?.aborted) {
30
+ return;
31
+ }
20
32
  const callNow = immediate && !timeout;
21
- clearTimeout(timeout);
22
- timeout = window.setTimeout(later, wait);
33
+ cleanup();
23
34
  if (callNow) {
24
35
  func(...args);
25
36
  }
37
+ abortSignal?.addEventListener("abort", cleanup);
38
+ timeout = window.setTimeout(later, wait);
26
39
  };
27
40
  }
28
41
  /**
29
42
  * Same as `debounce()`, but optimized for animation and rendering.
30
43
  *
31
44
  * @param func The function to debounce.
45
+ * @param abortSignal Optionally specify an abortSignal for the throttled
46
+ * function.
32
47
  */
33
- export function debounceAnimation(func) {
34
- let token;
48
+ export function debounceAnimation(func, abortSignal) {
49
+ let animationFrame;
50
+ const cleanup = () => {
51
+ cancelAnimationFrame(animationFrame);
52
+ abortSignal?.removeEventListener("abort", cleanup);
53
+ };
35
54
  return (...args) => {
36
- cancelAnimationFrame(token);
37
- token = requestAnimationFrame(() => func(...args));
55
+ cleanup();
56
+ if (abortSignal?.aborted) {
57
+ return;
58
+ }
59
+ animationFrame = requestAnimationFrame(() => {
60
+ abortSignal?.removeEventListener("abort", cleanup);
61
+ if (!abortSignal?.aborted) {
62
+ func(...args);
63
+ }
64
+ });
65
+ abortSignal?.addEventListener("abort", cleanup);
38
66
  };
39
67
  }
68
+ /**
69
+ * Returns a debounced and memoized version of the callback that only changes if
70
+ * one of the `deps` has changed.
71
+ *
72
+ * @param callback The function to debounce and memoize.
73
+ * @param timeout The debounce delay.
74
+ * @param deps The dependencies of the callback.
75
+ */
76
+ export function useDebounce(callback, timeout, deps) {
77
+ // Abort any debounced calls on unmount.
78
+ const abortController = useRef(new AbortController());
79
+ useEffect(() => () => {
80
+ abortController.current.abort();
81
+ // `React.StrictMode` causes all components to mount twice in
82
+ // development. This will break debounced functions unless
83
+ // we refresh the abort controller here.
84
+ abortController.current = new AbortController();
85
+ }, []);
86
+ // eslint-disable-next-line react-hooks/exhaustive-deps
87
+ return useCallback(debounce(callback, timeout, false, abortController.current.signal), deps);
88
+ }