87 lines
2.0 KiB
TypeScript
87 lines
2.0 KiB
TypeScript
import { useNavigate } from "@remix-run/react";
|
|
import { useOptimisticLocation } from "./useOptimisticLocation";
|
|
import { useCallback } from "react";
|
|
|
|
type Values = Record<string, string | string[] | undefined>;
|
|
|
|
export function useSearchParams() {
|
|
const navigate = useNavigate();
|
|
const location = useOptimisticLocation();
|
|
|
|
const replace = useCallback(
|
|
(values: Values) => {
|
|
const s = set(new URLSearchParams(location.search), values);
|
|
navigate(`${location.pathname}?${s.toString()}`, { replace: true });
|
|
},
|
|
[location, navigate]
|
|
);
|
|
|
|
const del = useCallback(
|
|
(keys: string | string[]) => {
|
|
const search = new URLSearchParams(location.search);
|
|
if (!Array.isArray(keys)) {
|
|
keys = [keys];
|
|
}
|
|
for (const key of keys) {
|
|
search.delete(key);
|
|
}
|
|
navigate(`${location.pathname}?${search.toString()}`, { replace: true });
|
|
},
|
|
[location, navigate]
|
|
);
|
|
|
|
const value = useCallback(
|
|
(param: string) => {
|
|
const search = new URLSearchParams(location.search);
|
|
return search.get(param) ?? undefined;
|
|
},
|
|
[location]
|
|
);
|
|
|
|
const values = useCallback(
|
|
(param: string) => {
|
|
const search = new URLSearchParams(location.search);
|
|
return search.getAll(param);
|
|
},
|
|
[location]
|
|
);
|
|
|
|
const has = useCallback(
|
|
(param: string) => {
|
|
const search = new URLSearchParams(location.search);
|
|
return search.has(param);
|
|
},
|
|
[location]
|
|
);
|
|
|
|
return {
|
|
value,
|
|
values,
|
|
replace,
|
|
del,
|
|
has,
|
|
};
|
|
}
|
|
|
|
function set(searchParams: URLSearchParams, values: Values) {
|
|
const search = new URLSearchParams(searchParams);
|
|
for (const [param, value] of Object.entries(values)) {
|
|
if (value === undefined) {
|
|
search.delete(param);
|
|
continue;
|
|
}
|
|
|
|
if (typeof value === "string") {
|
|
search.set(param, value);
|
|
continue;
|
|
}
|
|
|
|
search.delete(param);
|
|
for (const v of value) {
|
|
search.append(param, v);
|
|
}
|
|
}
|
|
|
|
return search;
|
|
}
|