kitzo 2.5.3 → 2.5.5
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 +22 -3
- package/dist/react/hooks/useLocalStorage.js +29 -21
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,13 @@ declare type DebounceOptions = {
|
|
|
51
51
|
|
|
52
52
|
declare type Options = ToastOptionsWithoutType;
|
|
53
53
|
|
|
54
|
+
declare type Options_2<T> = {
|
|
55
|
+
/** Milliseconds to debounce writes to localStorage (default: 0 — no debounce). */
|
|
56
|
+
debounceMs?: number;
|
|
57
|
+
/** Called once after the first value is read from localStorage on mount. */
|
|
58
|
+
onMount?: (value: T) => void;
|
|
59
|
+
};
|
|
60
|
+
|
|
54
61
|
declare type PromiseToastFn = <T, E = unknown>(promise: Promise<T>, msgs: PromiseToastMsgs<T, E>, options?: PromiseToastOptions) => Promise<T>;
|
|
55
62
|
|
|
56
63
|
declare type PromiseToastMsgs<T, E = unknown> = {
|
|
@@ -161,13 +168,25 @@ export declare function useDebouncedCallback<Args extends unknown[]>(callback: (
|
|
|
161
168
|
|
|
162
169
|
/**
|
|
163
170
|
* A custom hook that manages a stateful value in `localStorage`,
|
|
164
|
-
*
|
|
171
|
+
* with full SSR safety and cross-tab synchronization.
|
|
172
|
+
*
|
|
173
|
+
* The hook uses a two-phase approach: the server and first client render
|
|
174
|
+
* always use `initialValue` (preventing hydration mismatches), and the
|
|
175
|
+
* real localStorage value is synced in after mount.
|
|
176
|
+
*
|
|
177
|
+
* - State is updated immediately on every `setValue` call for a responsive UI.
|
|
178
|
+
* - Writes to `localStorage` are debounced by `options.debounceMs` ms.
|
|
179
|
+
* - `options.onMount` is called exactly once with the first value read from storage.
|
|
180
|
+
*
|
|
165
181
|
* @example
|
|
166
|
-
* const [theme, setTheme] = useLocalStorage<'light' | 'dark'>('ui-theme', 'light'
|
|
182
|
+
* const [theme, setTheme] = useLocalStorage<'light' | 'dark'>('ui-theme', 'light', {
|
|
183
|
+
* debounceMs: 300,
|
|
184
|
+
* onMount: (v) => console.log('loaded from storage:', v),
|
|
185
|
+
* });
|
|
167
186
|
* // Supports functional updates:
|
|
168
187
|
* setTheme(prev => prev === 'light' ? 'dark' : 'light');
|
|
169
188
|
*/
|
|
170
|
-
export declare function useLocalStorage<T>(key: string, initialValue: T): [T, Dispatch<SetStateAction<T>>];
|
|
189
|
+
export declare function useLocalStorage<T>(key: string, initialValue: T, options?: Options_2<T>): [T, Dispatch<SetStateAction<T>>];
|
|
171
190
|
|
|
172
191
|
export declare function useThrottle<T>(value: T, delay?: number): T;
|
|
173
192
|
|
|
@@ -1,34 +1,42 @@
|
|
|
1
|
-
import
|
|
2
|
-
function
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import o from "react";
|
|
2
|
+
function E(r, c, f) {
|
|
3
|
+
const g = f ?? {}, { debounceMs: s = 0, onMount: l } = g, i = o.useRef(l);
|
|
4
|
+
o.useEffect(() => {
|
|
5
|
+
i.current = l;
|
|
6
|
+
});
|
|
7
|
+
const [a, u] = o.useState(c), d = o.useCallback(() => {
|
|
6
8
|
try {
|
|
7
|
-
const e = window.localStorage.getItem(
|
|
8
|
-
return e ? JSON.parse(e) :
|
|
9
|
+
const e = window.localStorage.getItem(r);
|
|
10
|
+
return e ? JSON.parse(e) : c;
|
|
9
11
|
} catch (e) {
|
|
10
|
-
return console.warn(`Error reading localStorage key
|
|
12
|
+
return console.warn(`Error reading localStorage key "${r}":`, e), c;
|
|
11
13
|
}
|
|
12
|
-
}, [
|
|
14
|
+
}, [r, c]), n = o.useRef(
|
|
15
|
+
null
|
|
16
|
+
), S = o.useCallback(
|
|
13
17
|
(e) => {
|
|
14
18
|
try {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
const t = e instanceof Function ? e(a) : e;
|
|
20
|
+
u(t), typeof window < "u" && (n.current !== null && clearTimeout(n.current), s > 0 ? n.current = setTimeout(() => {
|
|
21
|
+
window.localStorage.setItem(r, JSON.stringify(t)), window.dispatchEvent(new Event("local-storage-update")), n.current = null;
|
|
22
|
+
}, s) : (window.localStorage.setItem(r, JSON.stringify(t)), window.dispatchEvent(new Event("local-storage-update"))));
|
|
23
|
+
} catch (t) {
|
|
24
|
+
console.warn(`Error setting localStorage key "${r}":`, t);
|
|
19
25
|
}
|
|
20
26
|
},
|
|
21
|
-
[
|
|
27
|
+
[r, a, s]
|
|
22
28
|
);
|
|
23
|
-
return
|
|
24
|
-
const e = (
|
|
25
|
-
|
|
29
|
+
return o.useEffect(() => {
|
|
30
|
+
const e = d();
|
|
31
|
+
u(e), i.current?.(e);
|
|
32
|
+
const t = (w) => {
|
|
33
|
+
w.key && w.key !== r || u(d());
|
|
26
34
|
};
|
|
27
|
-
return window.addEventListener("storage",
|
|
28
|
-
window.removeEventListener("storage",
|
|
35
|
+
return window.addEventListener("storage", t), window.addEventListener("local-storage-update", t), () => {
|
|
36
|
+
n.current !== null && clearTimeout(n.current), window.removeEventListener("storage", t), window.removeEventListener("local-storage-update", t);
|
|
29
37
|
};
|
|
30
|
-
}, [
|
|
38
|
+
}, [r]), [a, S];
|
|
31
39
|
}
|
|
32
40
|
export {
|
|
33
|
-
|
|
41
|
+
E as useLocalStorage
|
|
34
42
|
};
|