mirror of https://github.com/mkrhere/pw2
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
1.2 KiB
57 lines
1.2 KiB
import { useState } from "react";
|
|
import useLocation from "wouter/use-location";
|
|
|
|
export type HookSet<T> = {
|
|
set: Set<T>;
|
|
size: number;
|
|
add: (value: T) => void;
|
|
remove: (value: T) => void;
|
|
clear: () => void;
|
|
has: (value: T) => boolean;
|
|
};
|
|
|
|
const flatten = (set: Set<string>, key: string) =>
|
|
Array.from(set)
|
|
.map(param => `${key}=${encodeURIComponent(param)}`)
|
|
.join("&");
|
|
|
|
export function useSearchParams(key: string): HookSet<string> {
|
|
const [, navigate] = useLocation();
|
|
const [params, setParams] = useState(
|
|
() => new Set(new URLSearchParams(window.location.search).getAll(key)),
|
|
);
|
|
|
|
const add = (value: string) => {
|
|
setParams(prevSet => {
|
|
const newSet = new Set(prevSet);
|
|
newSet.add(value);
|
|
navigate("?" + flatten(newSet, key), { replace: true });
|
|
return newSet;
|
|
});
|
|
};
|
|
|
|
const remove = (value: string) => {
|
|
setParams(prevSet => {
|
|
const newSet = new Set(prevSet);
|
|
newSet.delete(value);
|
|
navigate("?" + flatten(newSet, key), { replace: true });
|
|
return newSet;
|
|
});
|
|
};
|
|
|
|
const clear = () => {
|
|
setParams(new Set());
|
|
navigate("?", { replace: true });
|
|
};
|
|
|
|
return {
|
|
set: params,
|
|
size: params.size,
|
|
add,
|
|
remove,
|
|
clear,
|
|
has: (value: string) => params.has(value),
|
|
};
|
|
}
|
|
|
|
export default useSearchParams;
|
|
|