aboutsummaryrefslogtreecommitdiff
path: root/packages/web-util/src/hooks/useLocalStorage.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/web-util/src/hooks/useLocalStorage.ts')
-rw-r--r--packages/web-util/src/hooks/useLocalStorage.ts105
1 files changed, 34 insertions, 71 deletions
diff --git a/packages/web-util/src/hooks/useLocalStorage.ts b/packages/web-util/src/hooks/useLocalStorage.ts
index ab786db13..264919d37 100644
--- a/packages/web-util/src/hooks/useLocalStorage.ts
+++ b/packages/web-util/src/hooks/useLocalStorage.ts
@@ -19,92 +19,55 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { StateUpdater, useEffect, useState } from "preact/hooks";
+import { useEffect, useState } from "preact/hooks";
+import { localStorageMap, memoryMap } from "../utils/observable.js";
+export interface LocalStorageState {
+ value?: string;
+ update: (s: string) => void;
+ reset: () => void;
+}
+
+const supportLocalStorage = typeof window !== "undefined";
+
+const storage = supportLocalStorage ? localStorageMap() : memoryMap<string>();
+
+export function useLocalStorage(
+ key: string,
+ initialValue: string,
+): Required<LocalStorageState>;
+export function useLocalStorage(key: string): LocalStorageState;
export function useLocalStorage(
key: string,
initialValue?: string,
-): [string | undefined, StateUpdater<string | undefined>] {
+): LocalStorageState {
const [storedValue, setStoredValue] = useState<string | undefined>(
(): string | undefined => {
- return typeof window !== "undefined"
- ? window.localStorage.getItem(key) || initialValue
- : initialValue;
+ return storage.get(key) ?? initialValue;
},
);
useEffect(() => {
- const listener = buildListenerForKey(key, (newValue) => {
+ return storage.onUpdate(key, () => {
+ const newValue = storage.get(key);
+ console.log("new value", key, newValue);
setStoredValue(newValue ?? initialValue);
});
- window.addEventListener("storage", listener);
- return () => {
- window.removeEventListener("storage", listener);
- };
}, []);
- const setValue = (
- value?: string | ((val?: string) => string | undefined),
- ): void => {
- setStoredValue((p) => {
- const toStore = value instanceof Function ? value(p) : value;
- if (typeof window !== "undefined") {
- if (!toStore) {
- window.localStorage.removeItem(key);
- } else {
- window.localStorage.setItem(key, toStore);
- }
- }
- return toStore;
- });
- };
-
- return [storedValue, setValue];
-}
-
-function buildListenerForKey(
- key: string,
- onUpdate: (newValue: string | undefined) => void,
-): () => void {
- return function listenKeyChange() {
- const value = window.localStorage.getItem(key);
- onUpdate(value ?? undefined);
- };
-}
-
-//TODO: merge with the above function
-export function useNotNullLocalStorage(
- key: string,
- initialValue: string,
-): [string, StateUpdater<string>, boolean] {
- const [storedValue, setStoredValue] = useState<string>((): string => {
- return typeof window !== "undefined"
- ? window.localStorage.getItem(key) || initialValue
- : initialValue;
- });
-
- useEffect(() => {
- const listener = buildListenerForKey(key, (newValue) => {
- setStoredValue(newValue ?? initialValue);
- });
- window.addEventListener("storage", listener);
- return () => {
- window.removeEventListener("storage", listener);
- };
- });
-
- const setValue = (value: string | ((val: string) => string)): void => {
- const valueToStore = value instanceof Function ? value(storedValue) : value;
- setStoredValue(valueToStore);
- if (typeof window !== "undefined") {
- if (!valueToStore) {
- window.localStorage.removeItem(key);
- } else {
- window.localStorage.setItem(key, valueToStore);
- }
+ const setValue = (value?: string): void => {
+ if (!value) {
+ storage.delete(key);
+ } else {
+ storage.set(key, value);
}
};
- const isSaved = window.localStorage.getItem(key) !== null;
- return [storedValue, setValue, isSaved];
+ return {
+ value: storedValue,
+ update: setValue,
+ reset: () => {
+ setValue(initialValue);
+ },
+ };
}