kitzo 2.5.2 → 2.5.4

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/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
+ import { Dispatch } from 'react';
1
2
  import { JSX } from 'react/jsx-runtime';
2
3
  import { PropsWithChildren } from 'react';
3
4
  import { ReactNode } from 'react';
5
+ import { SetStateAction } from 'react';
4
6
 
5
7
  declare type AnimationOptions = {
6
8
  duration?: number;
@@ -13,6 +15,40 @@ declare type AnimationOptions = {
13
15
 
14
16
  declare type CopyStatus = 'standby' | 'copying' | 'copied' | 'error';
15
17
 
18
+ declare type DebouncedFunction<Args extends unknown[]> = {
19
+ /**
20
+ * The debounced version of your callback.
21
+ * @param args - The arguments passed to the original callback.
22
+ */
23
+ (...args: Args): void;
24
+ /**
25
+ * Cancels any scheduled execution of the debounced callback.
26
+ */
27
+ cancel: () => void;
28
+ /**
29
+ * Immediately invokes the pending execution of the debounced callback and cancels the timer.
30
+ */
31
+ flush: () => void;
32
+ };
33
+
34
+ declare type DebounceOptions = {
35
+ /**
36
+ * If true, the callback is invoked on the leading edge of the timeout (immediately on the first call).
37
+ * @default false
38
+ */
39
+ leading?: boolean;
40
+ /**
41
+ * If true, the callback is invoked on the trailing edge of the timeout (after the delay has passed).
42
+ * @default true
43
+ */
44
+ trailing?: boolean;
45
+ /**
46
+ * The number of milliseconds to delay execution.
47
+ * @default 300
48
+ */
49
+ delay?: number;
50
+ };
51
+
16
52
  declare type Options = ToastOptionsWithoutType;
17
53
 
18
54
  declare type PromiseToastFn = <T, E = unknown>(promise: Promise<T>, msgs: PromiseToastMsgs<T, E>, options?: PromiseToastOptions) => Promise<T>;
@@ -114,6 +150,30 @@ declare type UseCopyReturn = {
114
150
 
115
151
  export declare function useDebounce<T>(value: T, delay?: number): T;
116
152
 
153
+ /**
154
+ * A hook that returns a memoized debounced function to limit the execution rate of a callback.
155
+ * * @template Args - The type of arguments accepted by the callback.
156
+ * @param callback - The function to debounce.
157
+ * @param options - Configuration for leading/trailing edges and delay.
158
+ * @returns A debounced function with `.cancel()` and `.flush()` methods.
159
+ */
160
+ export declare function useDebouncedCallback<Args extends unknown[]>(callback: (...args: Args) => void, options?: DebounceOptions): DebouncedFunction<Args>;
161
+
162
+ /**
163
+ * A custom hook that manages a stateful value in `localStorage`,
164
+ * with full SSR safety and cross-tab synchronization.
165
+ *
166
+ * The hook uses a two-phase approach: the server and first client render
167
+ * always use `initialValue` (preventing hydration mismatches), and the
168
+ * real localStorage value is synced in after mount.
169
+ *
170
+ * @example
171
+ * const [theme, setTheme] = useLocalStorage<'light' | 'dark'>('ui-theme', 'light');
172
+ * // Supports functional updates:
173
+ * setTheme(prev => prev === 'light' ? 'dark' : 'light');
174
+ */
175
+ export declare function useLocalStorage<T>(key: string, initialValue: T): [T, Dispatch<SetStateAction<T>>];
176
+
117
177
  export declare function useThrottle<T>(value: T, delay?: number): T;
118
178
 
119
179
  export declare function useWindowSize(updateDelay?: number): {
package/dist/index.js CHANGED
@@ -2,15 +2,19 @@ import { Toaster as r } from "./react/components/toast/Toaster.js";
2
2
  import { Tooltip as p } from "./react/components/tooltip/Tooltip.js";
3
3
  import { toast as m } from "./react/components/toast/service/triggerToasts.js";
4
4
  import { useCopy as s } from "./react/hooks/useCopy.js";
5
- import { useDebounce as i } from "./react/hooks/useDebounce.js";
6
- import { useThrottle as a } from "./react/hooks/useThrottle.js";
7
- import { useWindowSize as n } from "./react/hooks/useWindowSize.js";
5
+ import { useDebounce as a } from "./react/hooks/useDebounce.js";
6
+ import { useDebouncedCallback as c } from "./react/hooks/useDebouncedCallback.js";
7
+ import { useLocalStorage as i } from "./react/hooks/useLocalStorage.js";
8
+ import { useThrottle as T } from "./react/hooks/useThrottle.js";
9
+ import { useWindowSize as C } from "./react/hooks/useWindowSize.js";
8
10
  export {
9
11
  r as Toaster,
10
12
  p as Tooltip,
11
13
  m as toast,
12
14
  s as useCopy,
13
- i as useDebounce,
14
- a as useThrottle,
15
- n as useWindowSize
15
+ a as useDebounce,
16
+ c as useDebouncedCallback,
17
+ i as useLocalStorage,
18
+ T as useThrottle,
19
+ C as useWindowSize
16
20
  };
@@ -0,0 +1,33 @@
1
+ import { useRef as l, useEffect as g, useMemo as p } from "react";
2
+ function b(s, m = {}) {
3
+ const { leading: i = !1, trailing: f = !0, delay: a = 300 } = m, t = l(s), r = l(null), e = l(null), n = l(!1);
4
+ g(() => {
5
+ t.current = s;
6
+ }, [s]);
7
+ const o = p(() => {
8
+ const u = (...c) => {
9
+ r.current = c;
10
+ const T = () => {
11
+ t.current(...c);
12
+ };
13
+ e.current && clearTimeout(e.current), i && !e.current ? (T(), n.current = !0) : n.current = !1, e.current = setTimeout(() => {
14
+ const d = r.current, k = f && !n.current && d;
15
+ e.current = null, n.current = !1, r.current = null, k && t.current(...d);
16
+ }, a);
17
+ };
18
+ return u.cancel = () => {
19
+ e.current && (clearTimeout(e.current), e.current = null), r.current = null, n.current = !1;
20
+ }, u.flush = () => {
21
+ if (e.current && r.current) {
22
+ const c = r.current;
23
+ u.cancel(), t.current(...c);
24
+ }
25
+ }, u;
26
+ }, [a, i, f]);
27
+ return g(() => () => {
28
+ o.cancel();
29
+ }, [o]), o;
30
+ }
31
+ export {
32
+ b as useDebouncedCallback
33
+ };
@@ -0,0 +1,33 @@
1
+ import n from "react";
2
+ function w(t, r) {
3
+ const [a, s] = n.useState(r), c = n.useCallback(() => {
4
+ try {
5
+ const e = window.localStorage.getItem(t);
6
+ return e ? JSON.parse(e) : r;
7
+ } catch (e) {
8
+ return console.warn(`Error reading localStorage key "${t}":`, e), r;
9
+ }
10
+ }, [t, r]), d = n.useCallback(
11
+ (e) => {
12
+ try {
13
+ const o = e instanceof Function ? e(a) : e;
14
+ s(o), typeof window < "u" && (window.localStorage.setItem(t, JSON.stringify(o)), window.dispatchEvent(new Event("local-storage-update")));
15
+ } catch (o) {
16
+ console.warn(`Error setting localStorage key "${t}":`, o);
17
+ }
18
+ },
19
+ [t, a]
20
+ );
21
+ return n.useEffect(() => {
22
+ s(c());
23
+ const e = (o) => {
24
+ o.key && o.key !== t || s(c());
25
+ };
26
+ return window.addEventListener("storage", e), window.addEventListener("local-storage-update", e), () => {
27
+ window.removeEventListener("storage", e), window.removeEventListener("local-storage-update", e);
28
+ };
29
+ }, [t, c]), [a, d];
30
+ }
31
+ export {
32
+ w as useLocalStorage
33
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kitzo",
3
- "version": "2.5.2",
3
+ "version": "2.5.4",
4
4
  "description": "A lightweight React micro-utility.",
5
5
  "type": "module",
6
6
  "files": [