@yamada-ui/use-local-storage
Version:
Yamada UI useLocalStorage custom hook
99 lines (98 loc) • 3.24 kB
JavaScript
"use client"
// src/index.ts
import { useWindowEvent } from "@yamada-ui/use-window-event";
import { isFunction } from "@yamada-ui/utils";
import { useCallback, useEffect, useState } from "react";
var serializeJSON = (value, name) => {
try {
return JSON.stringify(value);
} catch {
throw new Error(`useLocalStorage ${name}: Failed to serialize the value`);
}
};
var deserializeJSON = (value) => {
if (!value) return value;
try {
return JSON.parse(value);
} catch {
return value;
}
};
var createStorage = (type, name) => {
const eventName = type === "localStorage" ? "ui-local-storage" : "ui-session-storage";
return ({
key,
defaultValue = void 0,
deserialize = deserializeJSON,
getInitialValueInEffect = true,
serialize = (value) => serializeJSON(value, name)
}) => {
const readStorageValue = useCallback(
(skipStorage) => {
if (typeof window === "undefined" || !(type in window) || // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
window[type] == null || skipStorage) {
return defaultValue != null ? defaultValue : "";
}
const storageValue = window[type].getItem(key);
return storageValue !== null ? deserialize(storageValue) : defaultValue != null ? defaultValue : "";
},
[key, deserialize, defaultValue]
);
const [value, setValue] = useState(
readStorageValue(getInitialValueInEffect)
);
const setStorageValue = useCallback(
(valOrFunc) => {
if (isFunction(valOrFunc)) {
setValue((current) => {
const result = valOrFunc(current);
window[type].setItem(key, serialize(result));
window.dispatchEvent(
new CustomEvent(eventName, {
detail: { key, value: valOrFunc(current) }
})
);
return result;
});
} else {
window[type].setItem(key, serialize(valOrFunc));
window.dispatchEvent(
new CustomEvent(eventName, { detail: { key, value: valOrFunc } })
);
setValue(valOrFunc);
}
},
[key, serialize]
);
const removeStorageValue = useCallback(() => {
window[type].removeItem(key);
setValue(defaultValue);
}, [defaultValue, key]);
useWindowEvent("storage", (ev) => {
var _a;
if (ev.storageArea === window[type] && ev.key === key)
setValue(deserialize((_a = ev.newValue) != null ? _a : void 0));
});
useWindowEvent(eventName, (ev) => {
if (ev.detail.key === key) setValue(ev.detail.value);
});
useEffect(() => {
if (defaultValue !== void 0 && value === void 0)
setStorageValue(defaultValue);
}, [defaultValue, value, setStorageValue]);
useEffect(() => {
if (getInitialValueInEffect) setValue(readStorageValue());
}, [getInitialValueInEffect, readStorageValue]);
return [
value === void 0 ? defaultValue : value,
setStorageValue,
removeStorageValue
];
};
};
var useLocalStorage = (props) => createStorage("localStorage", "use-local-storage")(props);
export {
createStorage,
useLocalStorage
};
//# sourceMappingURL=index.mjs.map