feat(app): banner, style tweaks
This commit is contained in:
@@ -2,9 +2,10 @@ export { default as useCSSVariables } from "./useCSSVariables";
|
||||
export { default as useDebounce } from "./useDebounce";
|
||||
export { default as useEvent } from "./useEvent";
|
||||
export { default as useIconParameters } from "./useIconParameters";
|
||||
export { default as useLocalStorage } from "./useLocalStorage";
|
||||
export { default as useMediaQuery } from "./useMediaQuery";
|
||||
export { default as usePersistSettings } from "./usePersistSettings";
|
||||
export { default as useSessionState } from "./useSessionState";
|
||||
export { default as useSessionStorage } from "./useSessionStorage";
|
||||
export { default as useThrottle } from "./useThrottle";
|
||||
export { default as useThrottled } from "./useThrottled";
|
||||
export { default as useTimeoutFn } from "./useTimeoutFn";
|
||||
|
||||
40
src/hooks/useLocalStorage.ts
Normal file
40
src/hooks/useLocalStorage.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { useCallback, useState, Dispatch, SetStateAction } from "react";
|
||||
import { STORAGE_KEY } from "@/state";
|
||||
|
||||
type Initializer<S> = () => S;
|
||||
type Setter<S> = (prev: S) => S;
|
||||
type Action<S> = S | Setter<S> | Initializer<S>;
|
||||
|
||||
function expand<S extends object>(action: Action<S>, prev?: S) {
|
||||
if (typeof action === "function") {
|
||||
return (action as Setter<S>)(prev!);
|
||||
} else {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
export default function useLocalStorage<S extends object>(
|
||||
key: string,
|
||||
fallbackState: S | (() => S)
|
||||
): [S, Dispatch<SetStateAction<S>>, (partial: Partial<S>) => void] {
|
||||
const [value, setValue] = useState<S>(() => {
|
||||
let val = localStorage.getItem(STORAGE_KEY + key);
|
||||
if (val) return JSON.parse(val) as S;
|
||||
return expand(fallbackState);
|
||||
});
|
||||
|
||||
const set: Dispatch<SetStateAction<S>> = useCallback((val) => {
|
||||
setValue((prev) => {
|
||||
const next = expand(val, prev);
|
||||
localStorage.setItem(STORAGE_KEY + key, JSON.stringify(next));
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const insert = useCallback(
|
||||
(partial: Partial<S>) => set((value) => ({ ...value, ...partial })),
|
||||
[]
|
||||
);
|
||||
|
||||
return [value, set, insert];
|
||||
}
|
||||
@@ -13,10 +13,10 @@ function expand<S extends object>(action: Action<S>, prev?: S) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function useSessionState<S extends object>(
|
||||
export default function useSessionStorage<S extends object>(
|
||||
key: string,
|
||||
fallbackState: S | (() => S)
|
||||
): [S, Dispatch<SetStateAction<S>>] {
|
||||
): [S, Dispatch<SetStateAction<S>>, (partial: Partial<S>) => void] {
|
||||
const [value, setValue] = useState<S>(() => {
|
||||
let val = sessionStorage.getItem(STORAGE_KEY + key);
|
||||
if (val) return JSON.parse(val) as S;
|
||||
@@ -31,5 +31,10 @@ export default function useSessionState<S extends object>(
|
||||
});
|
||||
}, []);
|
||||
|
||||
return [value, set];
|
||||
const insert = useCallback(
|
||||
(partial: Partial<S>) => set((value) => ({ ...value, ...partial })),
|
||||
[]
|
||||
);
|
||||
|
||||
return [value, set, insert];
|
||||
}
|
||||
Reference in New Issue
Block a user